diff options
100 files changed, 4380 insertions, 3189 deletions
diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES index b03c666643..b924571db6 100644 --- a/libs/libcurl/docs/CHANGES +++ b/libs/libcurl/docs/CHANGES @@ -6,6 +6,1665 @@ Changelog +Version 7.64.1 (27 Mar 2019) + +Daniel Stenberg (27 Mar 2019) +- RELEASE: 7.64.1 + +- Revert "ntlm: remove USE_WIN32_CRYPTO check to get USE_NTLM2SESSION set" + + This reverts commit 9130ead9fcabdb6b8fbdb37c0b38be2d326adb00. + + Fixes #3708 + +- [Christian Schmitz brought this change] + + ntlm: remove USE_WIN32_CRYPTO check to get USE_NTLM2SESSION set + + Closes #3704 + +Jay Satiro (26 Mar 2019) +- tool_cb_wrt: fix writing to Windows null device NUL + + - Improve console detection. + + Prior to this change WriteConsole could be called to write to a handle + that may not be a console, which would cause an error. This issue is + limited to character devices that are not also consoles such as the null + device NUL. + + Bug: https://github.com/curl/curl/issues/3175#issuecomment-439068724 + Reported-by: Gisle Vanem + +- CURLMOPT_PIPELINING.3: fix typo + +Daniel Stenberg (25 Mar 2019) +- TODO: config file parsing + + Closes #3698 + +Jay Satiro (24 Mar 2019) +- os400: Disable Alt-Svc by default since it's experimental + + Follow-up to 520f0b4 which added Alt-Svc support and enabled it by + default for OS400. Since the feature is experimental, it should be + disabled by default. + + Ref: https://github.com/curl/curl/commit/520f0b4#commitcomment-32792332 + Ref: https://curl.haxx.se/mail/lib-2019-02/0008.html + + Closes https://github.com/curl/curl/pull/3688 + +Dan Fandrich (24 Mar 2019) +- tests: Fixed XML validation errors in some test files. + +- tests: Fix some incorrect precheck error messages. + + [ci skip] + +Daniel Stenberg (22 Mar 2019) +- curl_url.3: this is not experimental anymore + +- travis: bump the used wolfSSL version to 4.0.0 + + Test 311 is now fine, leaving only 313 (CRL) disabled. + + Test 313 details can be found here: + https://github.com/wolfSSL/wolfssl/issues/1546 + + Closes #3697 + +Daniel Gustafsson (22 Mar 2019) +- lib: Fix typos in comments + +David Woodhouse (20 Mar 2019) +- openssl: if cert type is ENG and no key specified, key is ENG too + + Fixes #3692 + Closes #3692 + +Daniel Stenberg (20 Mar 2019) +- sectransp: tvOS 11 is required for ALPN support + + Reported-by: nianxuejie on github + Assisted-by: Nick Zitzmann + Assisted-by: Jay Satiro + Fixes #3689 + Closes #3690 + +- test1541: threaded connection sharing + + The threaded-shared-conn.c example turned into test case. Only works if + pthread was detected. + + An attempt to detect future regressions such as e3a53e3efb942a5 + + Closes #3687 + +Patrick Monnerat (17 Mar 2019) +- os400: alt-svc support. + + Although experimental, enable it in the platform config file. + Upgrade ILE/RPG binding. + +Daniel Stenberg (17 Mar 2019) +- conncache: use conn->data to know if a transfer owns it + + - make sure an already "owned" connection isn't returned unless + multiplexed. + + - clear ->data when returning the connection to the cache again + + Regression since 7.62.0 (probably in commit 1b76c38904f0) + + Bug: https://curl.haxx.se/mail/lib-2019-03/0064.html + + Closes #3686 + +- RELEASE-NOTES: synced + +- [Chris Young brought this change] + + configure: add --with-amissl + + AmiSSL is an Amiga native library which provides a wrapper over OpenSSL. + It also requires all programs using it to use bsdsocket.library + directly, rather than accessing socket functions through clib, which + libcurl was not necessarily doing previously. Configure will now check + for the headers and ensure they are included if found. + + Closes #3677 + +- [Chris Young brought this change] + + vtls: rename some of the SSL functions + + ... in the SSL structure as AmiSSL is using macros for the socket API + functions. + +- [Chris Young brought this change] + + tool_getpass: termios.h is present on AmigaOS 3, but no tcgetattr/tcsetattr + +- [Chris Young brought this change] + + tool_operate: build on AmigaOS + +- makefile: make checksrc and hugefile commands "silent" + + ... to match the style already used for compiling, linking + etc. Acknowledges 'make V=1' to enable verbose. + + Closes #3681 + +- curl.1: --user and --proxy-user are hidden from ps output + + Suggested-by: Eric Curtin + Improved-by: Dan Fandrich + Ref: #3680 + + Closes #3683 + +- curl.1: mark the argument to --cookie as <data|filename> + + From a discussion in #3676 + + Suggested-by: Tim Rühsen + + Closes #3682 + +Dan Fandrich (14 Mar 2019) +- fuzzer: Only clone the latest fuzzer code, for speed. + +Daniel Stenberg (14 Mar 2019) +- [Dominik Hölzl brought this change] + + Negotiate: fix for HTTP POST with Negotiate + + * Adjusted unit tests 2056, 2057 + * do not generally close connections with CURLAUTH_NEGOTIATE after every request + * moved negotiatedata from UrlState to connectdata + * Added stream rewind logic for CURLAUTH_NEGOTIATE + * introduced negotiatedata::GSS_AUTHDONE and negotiatedata::GSS_AUTHSUCC + * Consider authproblem state for CURLAUTH_NEGOTIATE + * Consider reuse_forbid for CURLAUTH_NEGOTIATE + * moved and adjusted negotiate authentication state handling from + output_auth_headers into Curl_output_negotiate + * Curl_output_negotiate: ensure auth done is always set + * Curl_output_negotiate: Set auth done also if result code is + GSS_S_CONTINUE_NEEDED/SEC_I_CONTINUE_NEEDED as this result code may + also indicate the last challenge request (only works with disabled + Expect: 100-continue and CURLOPT_KEEP_SENDING_ON_ERROR -> 1) + * Consider "Persistent-Auth" header, detect if not present; + Reset/Cleanup negotiate after authentication if no persistent + authentication + * apply changes introduced with #2546 for negotiate rewind logic + + Fixes #1261 + Closes #1975 + +- [Marc Schlatter brought this change] + + http: send payload when (proxy) authentication is done + + The check that prevents payload from sending in case of authentication + doesn't check properly if the authentication is done or not. + + They're cases where the proxy respond "200 OK" before sending + authentication challenge. This change takes care of that. + + Fixes #2431 + Closes #3669 + +- file: fix "Checking if unsigned variable 'readcount' is less than zero." + + Pointed out by codacy + + Closes #3672 + +- memdebug: log pointer before freeing its data + + Coverity warned for two potentional "Use after free" cases. Both are false + positives because the memory wasn't used, it was only the actual pointer + value that was logged. + + The fix still changes the order of execution to avoid the warnings. + + Coverity CID 1443033 and 1443034 + + Closes #3671 + +- RELEASE-NOTES: synced + +Marcel Raad (12 Mar 2019) +- travis: actually use updated compiler versions + + For the Linux builds, GCC 8 and 7 and clang 7 were installed, but the + new GCC versions were only used for the coverage build and for building + nghttp2, while the new clang version was not used at all. + + BoringSSL needs to use the default GCC as it respects CC, but not CXX, + so it would otherwise pass gcc 8 options to g++ 4.8 and fail. + + Also remove GCC 7, it's not needed anymore. + + Ref: https://docs.travis-ci.com/user/languages/c/#c11c11-and-beyond-and-toolchain-versioning + + Closes https://github.com/curl/curl/pull/3670 + +- travis: update clang to version 7 + + Closes https://github.com/curl/curl/pull/3670 + +Jay Satiro (11 Mar 2019) +- [Andre Guibert de Bruet brought this change] + + examples/externalsocket: add missing close socket calls + + .. and for Windows also call WSACleanup since we call WSAStartup. + + The example is to demonstrate handling the socket independently of + libcurl. In this case libcurl is not responsible for creating, opening + or closing the socket, it is handled by the application (our example). + + Fixes https://github.com/curl/curl/pull/3663 + +Daniel Stenberg (11 Mar 2019) +- multi: removed unused code for request retries + + This code was once used for the non multi-interface using code path, but + ever since easy_perform was turned into a wrapper around the multi + interface, this code path never runs. + + Closes #3666 + +Jay Satiro (11 Mar 2019) +- doh: inherit some SSL options from user's easy handle + + - Inherit SSL options for the doh handle but not SSL client certs, + SSL ALPN/NPN, SSL engine, SSL version, SSL issuer cert, + SSL pinned public key, SSL ciphers, SSL id cache setting, + SSL kerberos or SSL gss-api settings. + + - Fix inheritance of verbose setting. + + - Inherit NOSIGNAL. + + There is no way for the user to set options for the doh (DNS-over-HTTPS) + handles and instead we inherit some options from the user's easy handle. + + My thinking for the SSL options not inherited is they are most likely + not intended by the user for the DOH transfer. I did inherit insecure + because I think that should still be in control of the user. + + Prior to this change doh did not work for me because CAINFO was not + inherited. Also verbose was set always which AFAICT was a bug (#3660). + + Fixes https://github.com/curl/curl/issues/3660 + Closes https://github.com/curl/curl/pull/3661 + +Daniel Stenberg (9 Mar 2019) +- test331: verify set-cookie for dotless host name + + Reproduced bug #3649 + Closes #3659 + +- Revert "cookies: extend domain checks to non psl builds" + + This reverts commit 3773de378d48b06c09931e44dca4d274d0bfdce0. + + Regression shipped in 7.64.0 + Fixes #3649 + +- memdebug: make debug-specific functions use curl_dbg_ prefix + + To not "collide" or use up the regular curl_ name space. Also makes them + easier to detect in helper scripts. + + Closes #3656 + +- cmdline-opts/proxytunnel.d: the option tunnnels all protocols + + Clarify the language and simplify. + + Reported-by: Daniel Lublin + Closes #3658 + +- KNOWN_BUGS: Client cert (MTLS) issues with Schannel + + Closes #3145 + +- ROADMAP: updated to some more current things to work on + +- tests: fix multiple may be used uninitialized warnings + +- RELEASE-NOTES: synced + +- source: fix two 'nread' may be used uninitialized warnings + + Both seem to be false positives but we don't like warnings. + + Closes #3646 + +- gopher: remove check for path == NULL + + Since it can't be NULL and it makes Coverity believe we lack proper NULL + checks. Verified by test 659, landed in commit 15401fa886b. + + Pointed out by Coverity CID 1442746. + + Assisted-by: Dan Fandrich + Fixes #3617 + Closes #3642 + +- examples: only include <curl/curl.h> + + That's the only public curl header we should encourage use of. + + Reviewed-by: Marcel Raad + Closes #3645 + +- ssh: loop the state machine if not done and not blocking + + If the state machine isn't complete, didn't fail and it didn't return + due to blocking it can just as well loop again. + + This addresses the problem with SFTP directory listings where we would + otherwise return back to the parent and as the multi state machine + doesn't have any code for using CURLM_CALL_MULTI_PERFORM for as long the + doing phase isn't complete, it would return out when in reality there + was more data to deal with. + + Fixes #3506 + Closes #3644 + +Jay Satiro (5 Mar 2019) +- multi: support verbose conncache closure handle + + - Change closure handle to receive verbose setting from the easy handle + most recently added via curl_multi_add_handle. + + The closure handle is a special easy handle used for closing cached + connections. It receives limited settings from the easy handle most + recently added to the multi handle. Prior to this change that did not + include verbose which was a problem because on connection shutdown + verbose mode was not acknowledged. + + Ref: https://github.com/curl/curl/pull/3598 + + Co-authored-by: Daniel Stenberg + + Closes https://github.com/curl/curl/pull/3618 + +Daniel Stenberg (4 Mar 2019) +- CURLU: fix NULL dereference when used over proxy + + Test 659 verifies + + Also fixed the test 658 name + + Closes #3641 + +- altsvc_out: check the return code from Curl_gmtime + + Pointed out by Coverity, CID 1442956. + + Closes #3640 + +- docs/ALTSVC.md: docs describing the approach + + Closes #3498 + +- alt-svc: add a travis build + +- alt-svc: add test 355 and 356 to verify with command line curl + +- alt-svc: the curl command line bits + +- alt-svc: the libcurl bits + +- travis: add build using gnutls + + Closes #3637 + +- RELEASE-NOTES: synced + +- [Simon Legner brought this change] + + scripts/completion.pl: also generate fish completion file + + This is the renamed script formerly known as zsh.pl + + Closes #3545 + +- gnutls: remove call to deprecated gnutls_compression_get_name + + It has been deprecated by GnuTLS since a year ago and now causes build + warnings. + + Ref: https://gitlab.com/gnutls/gnutls/commit/b0041897d2846737f5fb0f + Docs: https://www.gnutls.org/manual/html_node/Compatibility-API.html + + Closes #3636 + +Jay Satiro (2 Mar 2019) +- system_win32: move win32_init here from easy.c + + .. since system_win32 is a more appropriate location for the functions + and to extern the globals. + + Ref: https://github.com/curl/curl/commit/ca597ad#r32446578 + Reported-by: Gisle Vanem + + Closes https://github.com/curl/curl/pull/3625 + +Daniel Stenberg (1 Mar 2019) +- curl_easy_duphandle.3: clarify that a duped handle has no shares + + Reported-by: Sara Golemon + + Fixes #3592 + Closes #3634 + +- 10-at-a-time.c: fix too long line + +- [Arnaud Rebillout brought this change] + + examples: various fixes in ephiperfifo.c + + The main change here is the timer value that was wrong, it was given in + usecs (ms * 1000), while the itimerspec struct wants nsecs (ms * 1000 * + 1000). This resulted in the callback being invoked WAY TOO OFTEN. + + As a quick check you can run this command before and after applying this + commit: + + # shell 1 + ./ephiperfifo 2>&1 | tee ephiperfifo.log + # shell 2 + echo http://hacking.elboulangero.com > hiper.fifo + + Then just compare the size of the logs files. + + Closes #3633 + Fixes #3632 + Signed-off-by: Arnaud Rebillout <arnaud.rebillout@collabora.com> + +- urldata: simplify bytecounters + + - no need to have them protocol specific + + - no need to set pointers to them with the Curl_setup_transfer() call + + - make Curl_setup_transfer() operate on a transfer pointer, not + connection + + - switch some counters from long to the more proper curl_off_t type + + Closes #3627 + +- examples/10-at-a-time.c: improve readability and simplify + + - use better variable names to explain their purposes + - convert logic to curl_multi_wait() + +- threaded-resolver: shutdown the resolver thread without error message + + When a transfer is done, the resolver thread will be brought down. That + could accidentally generate an error message in the error buffer even + though this is not an error situationand the transfer would still return + OK. An application that still reads the error buffer could find a + "Could not resolve host: [host name]" message there and get confused. + + Reported-by: Michael Schmid + Fixes #3629 + Closes #3630 + +- [Ԝеѕ brought this change] + + docs: update max-redirs.d phrasing + + clarify redir - "in absurdum" doesn't seem to make sense in this context + + Closes #3631 + +- ssh: fix Condition '!status' is always true + + in the same sftp_done function in both SSH backends. Simplify them + somewhat. + + Pointed out by Codacy. + + Closes #3628 + +- test578: make it read data from the correct test + +- Curl_easy: remove req.maxfd - never used! + + Introduced in 8b6314ccfb, but not used anymore in current code. Unclear + since when. + + Closes #3626 + +- http: set state.infilesize when sending formposts + + Without it set, we would unwillingly triger the "HTTP error before end + of send, stop sending" condition even if the entire POST body had been + sent (since it wouldn't know the expected size) which would + unnecessarily log that message and close the connection when it didn't + have to. + + Reported-by: Matt McClure + Bug: https://curl.haxx.se/mail/archive-2019-02/0023.html + Closes #3624 + +- INSTALL: refer to the current TLS library names and configure options + +- FAQ: minor updates and spelling fixes + +- GOVERNANCE.md: minor spelling fixes + +- Secure Transport: no more "darwinssl" + + Everyone calls it Secure Transport, now we do too. + + Reviewed-by: Nick Zitzmann + + Closes #3619 + +Marcel Raad (27 Feb 2019) +- AppVeyor: add classic MinGW build + + But use the MSYS2 shell rather than the default MSYS shell because of + POSIX path conversion issues. Classic MinGW is only available on the + Visual Studio 2015 image. + + Closes https://github.com/curl/curl/pull/3623 + +- AppVeyor: add MinGW-w64 build + + Add a MinGW-w64 build using CMake's MSYS Makefiles generator. + Use the Visual Studio 2015 image as it has GCC 8, while the + Visual Studio 2017 image only has GCC 7.2. + + Closes https://github.com/curl/curl/pull/3623 + +Daniel Stenberg (27 Feb 2019) +- cookies: only save the cookie file if the engine is enabled + + Follow-up to 8eddb8f4259. + + If the cookieinfo pointer is NULL there really is nothing to save. + + Without this fix, we got a problem when a handle was using shared object + with cookies and is told to "FLUSH" it to file (which worked) and then + the share object was removed and when the easy handle was closed just + afterwards it has no cookieinfo and no cookies so it decided to save an + empty jar (overwriting the file just flushed). + + Test 1905 now verifies that this works. + + Assisted-by: Michael Wallner + Assisted-by: Marcel Raad + + Closes #3621 + +- [DaVieS brought this change] + + cacertinmem.c: use multiple certificates for loading CA-chain + + Closes #3421 + +- urldata: convert bools to bitfields and move to end + + This allows the compiler to pack and align the structs better in + memory. For a rather feature-complete build on x86_64 Linux, gcc 8.1.2 + makes the Curl_easy struct 4.9% smaller. From 6312 bytes to 6000. + + Removed an unused struct field. + + No functionality changes. + + Closes #3610 + +- [Don J Olmstead brought this change] + + curl.h: use __has_declspec_attribute for shared builds + + Closes #3616 + +- curl: display --version features sorted alphabetically + + Closes #3611 + +- runtests: detect "schannel" as an alias for "winssl" + + Follow-up to 180501cb02 + + Reported-by: Marcel Raad + Fixes #3609 + Closes #3620 + +Marcel Raad (26 Feb 2019) +- AppVeyor: update to Visual Studio 2017 + + Switch all Visual Studio 2015 builds to Visual Studio 2017. It's not a + moving target anymore as the last update, Update 9, has been released. + + Closes https://github.com/curl/curl/pull/3606 + +- AppVeyor: switch VS 2015 builds to VS 2017 image + + The Visual Studio 2017 image has Visual Studio 2015 and 2017 installed. + + Closes https://github.com/curl/curl/pull/3606 + +- AppVeyor: explicitly select worker image + + Currently, we're using the default Visual Studio 2015 image for + everything. + + Closes https://github.com/curl/curl/pull/3606 + +Daniel Stenberg (26 Feb 2019) +- strerror: make the strerror function use local buffers + + Instead of using a fixed 256 byte buffer in the connectdata struct. + + In my build, this reduces the size of the connectdata struct by 11.8%, + from 2160 to 1904 bytes with no functionality or performance loss. + + This also fixes a bug in schannel's Curl_verify_certificate where it + called Curl_sspi_strerror when it should have called Curl_strerror for + string from GetLastError. the only effect would have been no text or the + wrong text being shown for the error. + + Co-authored-by: Jay Satiro + + Closes #3612 + +- [Michael Wallner brought this change] + + cookies: fix NULL dereference if flushing cookies with no CookieInfo set + + Regression brought by a52e46f3900fb0 (shipped in 7.63.0) + + Closes #3613 + +Marcel Raad (26 Feb 2019) +- AppVeyor: re-enable test 500 + + It's passing now. + + Closes https://github.com/curl/curl/pull/3615 + +- AppVeyor: remove redundant builds + + Remove the Visual Studio 2012 and 2013 builds as they add little value. + + Ref: https://github.com/curl/curl/pull/3606 + Closes https://github.com/curl/curl/pull/3614 + +Daniel Stenberg (25 Feb 2019) +- RELEASE-NOTES: synced + +- [Bernd Mueller brought this change] + + OpenSSL: add support for TLS ASYNC state + + Closes #3591 + +Jay Satiro (25 Feb 2019) +- [Michael Felt brought this change] + + acinclude: add additional libraries to check for LDAP support + + - Add an additional check for LDAP that also checks for OpenSSL since + on AIX those libraries may be required to link LDAP properly. + + Fixes https://github.com/curl/curl/issues/3595 + Closes https://github.com/curl/curl/pull/3596 + +- [georgeok brought this change] + + schannel: support CALG_ECDH_EPHEM algorithm + + Add support for Ephemeral elliptic curve Diffie-Hellman key exchange + algorithm option when selecting ciphers. This became available on the + Win10 SDK. + + Closes https://github.com/curl/curl/pull/3608 + +Daniel Stenberg (24 Feb 2019) +- multi: call multi_done on connect timeouts + + Failing to do so would make the CURLINFO_TOTAL_TIME timeout to not get + updated correctly and could end up getting reported to the application + completely wrong (way too small). + + Reported-by: accountantM on github + Fixes #3602 + Closes #3605 + +- examples: remove recursive calls to curl_multi_socket_action + + From within the timer callbacks. Recursive is problematic for several + reasons. They should still work, but this way the examples and the + documentation becomes simpler. I don't think we need to encourage + recursive calls. + + Discussed in #3537 + Closes #3601 + +Marcel Raad (23 Feb 2019) +- configure: remove CURL_CHECK_FUNC_FDOPEN call + + The macro itself has been removed in commit + 11974ac859c5d82def59e837e0db56fef7f6794e. + + Closes https://github.com/curl/curl/pull/3604 + +Daniel Stenberg (23 Feb 2019) +- wolfssl: stop custom-adding curves + + since wolfSSL PR https://github.com/wolfSSL/wolfssl/pull/717 (shipped in + wolfSSL 3.10.2 and later) it sends these curves by default already. + + Pointed-out-by: David Garske + + Closes #3599 + +- configure: remove the unused fdopen macro + + and the two remaining #ifdefs for it + + Closes #3600 + +Jay Satiro (22 Feb 2019) +- url: change conn shutdown order to unlink data as last step + + - Split off connection shutdown procedure from Curl_disconnect into new + function conn_shutdown. + + - Change the shutdown procedure to close the sockets before + disassociating the transfer. + + Prior to this change the sockets were closed after disassociating the + transfer so SOCKETFUNCTION wasn't called since the transfer was already + disassociated. That likely came about from recent work started in + Jan 2019 (#3442) to separate transfers from connections. + + Bug: https://curl.haxx.se/mail/lib-2019-02/0101.html + Reported-by: Pavel Löbl + + Closes https://github.com/curl/curl/issues/3597 + Closes https://github.com/curl/curl/pull/3598 + +Marcel Raad (22 Feb 2019) +- Fix strict-prototypes GCC warning + + As seen in the MinGW autobuilds. Caused by commit + f26bc29cfec0be84c67cf74065cf8e5e78fd68b7. + +Dan Fandrich (21 Feb 2019) +- tests: Fixed XML validation errors in some test files. + +Daniel Stenberg (20 Feb 2019) +- TODO: Allow SAN names in HTTP/2 server push + + Suggested-by: Nicolas Grekas + +- RELEASE-NOTES: synced + +- curl: remove MANUAL from -M output + + ... and remove it from the dist tarball. It has served its time, it + barely gets updated anymore and "everything curl" is now convering all + this document once tried to include, and does it more and better. + + In the compressed scenario, this removes ~15K data from the binary, + which is 25% of the -M output. + + It remains in the git repo for now for as long as the web site builds a + page using that as source. It renders poorly on the site (especially for + mobile users) so its not even good there. + + Closes #3587 + +- http2: verify :athority in push promise requests + + RFC 7540 says we should verify that the push is for an "authoritative" + server. We make sure of this by only allowing push with an :athority + header that matches the host that was asked for in the URL. + + Fixes #3577 + Reported-by: Nicolas Grekas + Bug: https://curl.haxx.se/mail/lib-2019-02/0057.html + Closes #3581 + +- singlesocket: fix the 'sincebefore' placement + + The variable wasn't properly reset within the loop and thus could remain + set for sockets that hadn't been set before and miss notifying the app. + + This is a follow-up to 4c35574 (shipped in curl 7.64.0) + + Reported-by: buzo-ffm on github + Detected-by: Jan Alexander Steffens + Fixes #3585 + Closes #3589 + +- connection: never reuse CONNECT_ONLY conections + + and make CONNECT_ONLY conections never reuse any existing ones either. + + Reported-by: Pavel Löbl + Bug: https://curl.haxx.se/mail/lib-2019-02/0064.html + Closes #3586 + +Patrick Monnerat (19 Feb 2019) +- cli tool: fix mime post with --disable-libcurl-option configure option + + Reported-by: Marcel Raad + Fixes #3576 + Closes #3583 + +Daniel Stenberg (19 Feb 2019) +- x509asn1: cleanup and unify code layout + + - rename 'n' to buflen in functions, and use size_t for them. Don't pass + in negative buffer lengths. + + - move most function comments to above the function starts like we use + to + + - remove several unnecessary typecasts (especially of NULL) + + Reviewed-by: Patrick Monnerat + Closes #3582 + +- curl_multi_remove_handle.3: use at any time, just not from within callbacks + + [ci skip] + +- http: make adding a blank header thread-safe + + Previously the function would edit the provided header in-place when a + semicolon is used to signify an empty header. This made it impossible to + use the same set of custom headers in multiple threads simultaneously. + + This approach now makes a local copy when it needs to edit the string. + + Reported-by: d912e3 on github + Fixes #3578 + Closes #3579 + +- unit1651: survive curl_easy_init() fails + +- [Frank Gevaerts brought this change] + + rand: Fix a mismatch between comments in source and header. + + Reported-by: Björn Stenberg <bjorn@haxx.se> + Closes #3584 + +Patrick Monnerat (18 Feb 2019) +- x509asn1: replace single char with an array + + Although safe in this context, using a single char as an array may + cause invalid accesses to adjacent memory locations. + + Detected by Coverity. + +Daniel Stenberg (18 Feb 2019) +- examples/http2-serverpush: add some sensible error checks + + To avoid NULL pointer dereferences etc in the case of problems. + + Closes #3580 + +Jay Satiro (18 Feb 2019) +- easy: fix win32 init to work without CURL_GLOBAL_WIN32 + + - Change the behavior of win32_init so that the required initialization + procedures are not affected by CURL_GLOBAL_WIN32 flag. + + libcurl via curl_global_init supports initializing for win32 with an + optional flag CURL_GLOBAL_WIN32, which if omitted was meant to stop + Winsock initialization. It did so internally by skipping win32_init() + when that flag was set. Since then win32_init() has been expanded to + include required initialization routines that are separate from + Winsock and therefore must be called in all cases. This commit fixes + it so that CURL_GLOBAL_WIN32 only controls the optional win32 + initialization (which is Winsock initialization, according to our doc). + + The only users affected by this change are those that don't pass + CURL_GLOBAL_WIN32 to curl_global_init. For them this commit removes the + risk of a potential crash. + + Ref: https://github.com/curl/curl/pull/3573 + + Fixes https://github.com/curl/curl/issues/3313 + Closes https://github.com/curl/curl/pull/3575 + +Daniel Gustafsson (17 Feb 2019) +- cookie: Add support for cookie prefixes + + The draft-ietf-httpbis-rfc6265bis-02 draft, specify a set of prefixes + and how they should affect cookie initialization, which has been + adopted by the major browsers. This adds support for the two prefixes + defined, __Host- and __Secure, and updates the testcase with the + supplied examples from the draft. + + Closes #3554 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +- mbedtls: release sessionid resources on error + + If mbedtls_ssl_get_session() fails, it may still have allocated + memory that needs to be freed to avoid leaking. Call the library + API function to release session resources on this errorpath as + well as on Curl_ssl_addsessionid() errors. + + Closes: #3574 + Reported-by: Michał Antoniak <M.Antoniak@posnet.com> + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +Patrick Monnerat (16 Feb 2019) +- cli tool: refactor encoding conversion sequence for switch case fallthrough. + +- version.c: silent scan-build even when librtmp is not enabled + +Daniel Stenberg (15 Feb 2019) +- RELEASE-NOTES: synced + +- Curl_now: figure out windows version in win32_init + + ... and avoid use of static variables that aren't thread safe. + + Fixes regression from e9ababd4f5a (present in the 7.64.0 release) + + Reported-by: Paul Groke + Fixes #3572 + Closes #3573 + +Marcel Raad (15 Feb 2019) +- unit1307: just fail without FTP support + + I missed to check this in with commit + 71786c0505926aaf7e9b2477b2fb7ee16a915ec6, which only disabled the test. + This fixes the actual linker error. + + Closes https://github.com/curl/curl/pull/3568 + +Daniel Stenberg (15 Feb 2019) +- travis: enable valgrind for the iconv tests too + + Closes #3571 + +- travis: add scan-build + + Closes #3564 + +- examples/sftpuploadresume: Value stored to 'result' is never read + + Detected by scan-build + +- examples/http2-upload: cleaned up + + Fix scan-build warnings, no globals, no silly handle scan. Also remove + handles from the multi before cleaning up. + +- examples/http2-download: cleaned up + + To avoid scan-build warnings and global variables. + +- examples/postinmemory: Potential leak of memory pointed to by 'chunk.memory' + + Detected by scan-build + +- examples/httpcustomheader: Value stored to 'res' is never read + + Detected by scan-build + +- examples: remove superfluous null-pointer checks + + in ftpget, ftpsget and sftpget, so that scan-build stops warning for + potential NULL pointer dereference below! + + Detected by scan-build + +- strip_trailing_dot: make sure NULL is never used for strlen + + scan-build warning: Null pointer passed as an argument to a 'nonnull' + parameter + +- [Jay Satiro brought this change] + + connection_check: restore original conn->data after the check + + - Save the original conn->data before it's changed to the specified + data transfer for the connection check and then restore it afterwards. + + This is a follow-up to 38d8e1b 2019-02-11. + + History: + + It was discovered a month ago that before checking whether to extract a + dead connection that that connection should be associated with a "live" + transfer for the check (ie original conn->data ignored and set to the + passed in data). A fix was landed in 54b201b which did that and also + cleared conn->data after the check. The original conn->data was not + restored, so presumably it was thought that a valid conn->data was no + longer needed. + + Several days later it was discovered that a valid conn->data was needed + after the check and follow-up fix was landed in bbae24c which partially + reverted the original fix and attempted to limit the scope of when + conn->data was changed to only when pruning dead connections. In that + case conn->data was not cleared and the original conn->data not + restored. + + A month later it was discovered that the original fix was somewhat + correct; a "live" transfer is needed for the check in all cases + because original conn->data could be null which could cause a bad deref + at arbitrary points in the check. A fix was landed in 38d8e1b which + expanded the scope to all cases. conn->data was not cleared and the + original conn->data not restored. + + A day later it was discovered that not restoring the original conn->data + may lead to busy loops in applications that use the event interface, and + given this observation it's a pretty safe assumption that there is some + code path that still needs the original conn->data. This commit is the + follow-up fix for that, it restores the original conn->data after the + connection check. + + Assisted-by: tholin@users.noreply.github.com + Reported-by: tholin@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/3542 + Closes #3559 + +- memdebug: bring back curl_mark_sclose + + Used by debug builds with NSS. + + Reverted from 05b100aee247bb + +Patrick Monnerat (14 Feb 2019) +- transfer.c: do not compute length of undefined hex buffer. + + On non-ascii platforms, the chunked hex header was measured for char code + conversion length, even for chunked trailers that do not have an hex header. + In addition, the efective length is already known: use it. + Since the hex length can be zero, only convert if needed. + + Reported by valgrind. + +Daniel Stenberg (14 Feb 2019) +- KNOWN_BUGS: Cannot compile against a static build of OpenLDAP + + Closes #2367 + +Patrick Monnerat (14 Feb 2019) +- x509asn1: "Dereference of null pointer" + + Detected by scan-build (false positive). + +Daniel Stenberg (14 Feb 2019) +- configure: show features as well in the final summary + + Closes #3569 + +- KNOWN_BUGS: curl compiled on OSX 10.13 failed to run on OSX 10.10 + + Closes #2905 + +- KNOWN_BUGS: Deflate error after all content was received + + Closes #2719 + +- gssapi: fix deprecated header warnings + + Heimdal includes on FreeBSD spewed out lots of them. Less so now. + + Closes #3566 + +- TODO: Upgrade to websockets + + Closes #3523 + +- TODO: cmake test suite improvements + + Closes #3109 + +Patrick Monnerat (13 Feb 2019) +- curl: "Dereference of null pointer" + + Rephrase to satisfy scan-build. + +Marcel Raad (13 Feb 2019) +- unit1307: require FTP support + + This test doesn't link without FTP support after + fc7ab4835b5fd09d0a6f57000633bb6bb6edfda1, which made Curl_fnmatch + unavailable without FTP support. + + Closes https://github.com/curl/curl/pull/3565 + +Daniel Stenberg (13 Feb 2019) +- TODO: TFO support on Windows + + Nobody works on this now. + + Closes #3378 + +- multi: Dereference of null pointer + + Mostly a false positive, but this makes the code easier to read anyway. + + Detected by scan-build. + + Closes #3563 + +- urlglob: Argument with 'nonnull' attribute passed null + + Detected by scan-build. + +Jay Satiro (12 Feb 2019) +- schannel: restore some debug output but only for debug builds + + Follow-up to 84c10dc from earlier today which wrapped a lot of the noisy + debug output in DEBUGF but omitted a few lines. + + Ref: https://github.com/curl/curl/commit/84c10dc#r32292900 + +- examples/crawler: Fix the Accept-Encoding setting + + - Pass an empty string to CURLOPT_ACCEPT_ENCODING to use the default + supported encodings. + + Prior to this change the specific encodings of gzip and deflate were set + but there's no guarantee they'd be supported by the user's libcurl. + +Daniel Stenberg (12 Feb 2019) +- mime: put the boundary buffer into the curl_mime struct + + ... instead of allocating it separately and point to it. It is + fixed-size and always used for each part. + + Closes #3561 + +- schannel: be quiet + + Convert numerous infof() calls into debug-build only messages since they + are annoyingly verbose for regular applications. Removed a few. + + Bug: https://curl.haxx.se/mail/lib-2019-02/0027.html + Reported-by: Volker Schmid + Closes #3552 + +- [Romain Geissler brought this change] + + Curl_resolv: fix a gcc -Werror=maybe-uninitialized warning + + Closes #3562 + +- http2: multi_connchanged() moved from multi.c, only used for h2 + + Closes #3557 + +- curl: "Function call argument is an uninitialized value" + + Follow-up to cac0e4a6ad14b42471eb + + Detected by scan-build + Closes #3560 + +- pretransfer: don't strlen() POSTFIELDS set for GET requests + + ... since that data won't be used in the request anyway. + + Fixes #3548 + Reported-by: Renaud Allard + Close #3549 + +- multi: remove verbose "Expire in" ... messages + + Reported-by: James Brown + Bug: https://curl.haxx.se/mail/archive-2019-02/0013.html + Closes #3558 + +- mbedtls: make it build even if MBEDTLS_VERSION_C isn't set + + Reported-by: MAntoniak on github + Fixes #3553 + Closes #3556 + +Daniel Gustafsson (12 Feb 2019) +- non-ascii.c: fix typos in comments + + Fix two occurrences of s/convers/converts/ spotted while reading code. + +Daniel Stenberg (12 Feb 2019) +- fnmatch: disable if FTP is disabled + + Closes #3551 + +- curl_path: only enabled for SSH builds + +- [Frank Gevaerts brought this change] + + tests: add stderr comparison to the test suite + + The code is more or less copied from the stdout comparison code, maybe + some better reuse is possible. + + test 1457 is adjusted to make the output actually match (by using --silent) + test 506 used <stderr> without actually needing it, so that <stderr> block is removed + + Closes #3536 + +Patrick Monnerat (11 Feb 2019) +- cli tool: do not use mime.h private structures. + + Option -F generates an intermediate representation of the mime structure + that is used later to create the libcurl mime structure and generate + the --libcurl statements. + + Reported-by: Daniel Stenberg + Fixes #3532 + Closes #3546 + +Daniel Stenberg (11 Feb 2019) +- curlver: bump to 7.64.1-dev + +- RELEASE-NOTES: synced + + and bump the version in progress to 7.64.1. If we merge any "change" + before the cut-off date, we update again. + +Daniel Gustafsson (11 Feb 2019) +- curl: follow-up to 3f16990ec84 + + Commit 3f16990ec84cc4b followed-up a bug in b49652ac66cc0 but was + inadvertently introducing a new bug in the ternary expression. + + Close #3555 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +- dns: release sharelock as soon as possible + + There is no benefit to holding the data sharelock when freeing the + addrinfo in case it fails, so ensure releaseing it as soon as we can + rather than holding on to it. This also aligns the code with other + consumers of sharelocks. + + Closes #3516 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +Daniel Stenberg (11 Feb 2019) +- curl: follow-up to b49652ac66cc0 + + On FreeBSD, return non-zero on error otherwise zero. + + Reported-by: Marcel Raad + +- multi: (void)-prefix when ignoring return values + + ... and added braces to two function calls which fixes warnings if they + are replace by empty macros at build-time. + +- curl: fix FreeBSD compiler warning in the --xattr code + + Closes #3550 + +- connection_check: set ->data to the transfer doing the check + + The http2 code for connection checking needs a transfer to use. Make + sure a working one is set before handler->connection_check() is called. + + Reported-by: jnbr on github + Fixes #3541 + Closes #3547 + +- hostip: make create_hostcache_id avoid alloc + free + + Closes #3544 + +- scripts/singleuse: script to use to track single-use functions + + That is functions that are declared global but are not used from outside + of the file in which it is declared. Such functions should be made + static or even at times be removed. + + It also verifies that all used curl_ prefixed functions are "blessed" + + Closes #3538 + +- cleanup: make local functions static + + urlapi: turn three local-only functions into statics + + conncache: make conncache_find_first_connection static + + multi: make detach_connnection static + + connect: make getaddressinfo static + + curl_ntlm_core: make hmac_md5 static + + http2: make two functions static + + http: make http_setup_conn static + + connect: make tcpnodelay static + + tests: make UNITTEST a thing to mark functions with, so they can be static for + normal builds and non-static for unit test builds + + ... and mark Curl_shuffle_addr accordingly. + + url: make up_free static + + setopt: make vsetopt static + + curl_endian: make write32_le static + + rtsp: make rtsp_connisdead static + + warnless: remove unused functions + + memdebug: remove one unused function, made another static + +Dan Fandrich (10 Feb 2019) +- cirrus: Added FreeBSD builds using Cirrus CI. + + The build logs will be at https://cirrus-ci.com/github/curl/curl + + Some tests are currently failing and so disabled for now. The SSH server + isn't starting for the SSH tests due to unsupported options used in its + config file. The DICT server also is failing on startup. + +Daniel Stenberg (9 Feb 2019) +- url/idnconvert: remove scan for <= 32 ascii values + + The check was added back in fa939220df before the URL parser would catch + these problems and therefore these will never trigger now. + + Closes #3539 + +- urlapi: reduce variable scope, remove unreachable 'break' + + Both nits pointed out by codacy.com + + Closes #3540 + +Alessandro Ghedini (7 Feb 2019) +- zsh.pl: escape ':' character + + ':' is interpreted as separator by zsh, so if used as part of the argument + or option's description it needs to be escaped. + + The problem can be reproduced as follows: + + % curl --reso<TAB> + % curl -E <TAB> + + Bug: https://bugs.debian.org/921452 + +- zsh.pl: update regex to better match curl -h output + + The current regex fails to match '<...>' arguments properly (e.g. those + with spaces in them), which causes an completion script with wrong + descriptions for some options. + + Here's a diff of the generated completion script, comparing the previous + version to the one with this fix: + + --- /usr/share/zsh/vendor-completions/_curl 2019-01-15 20:47:40.000000000 +0000 + +++ _curl 2019-02-05 20:57:29.453349040 +0000 + @@ -9,48 +9,48 @@ + + _arguments -C -S \ + --happy-eyeballs-timeout-ms'[How long to wait in milliseconds for IPv6 before trying IPv4]':'<milliseconds>' \ + + --resolve'[Resolve the host+port to this address]':'<host:port:address[,address]...>' \ + {-c,--cookie-jar}'[Write cookies to <filename> after operation]':'<filename>':_files \ + {-D,--dump-header}'[Write the received headers to <filename>]':'<filename>':_files \ + {-y,--speed-time}'[Trigger '\''speed-limit'\'' abort after this time]':'<seconds>' \ + --proxy-cacert'[CA certificate to verify peer against for proxy]':'<file>':_files \ + - --tls13-ciphers'[of TLS 1.3 ciphersuites> TLS 1.3 cipher suites to use]':'<list' \ + + --tls13-ciphers'[TLS 1.3 cipher suites to use]':'<list of TLS 1.3 ciphersuites>' \ + {-E,--cert}'[Client certificate file and password]':'<certificate[:password]>' \ + --libcurl'[Dump libcurl equivalent code of this command line]':'<file>':_files \ + --proxy-capath'[CA directory to verify peer against for proxy]':'<dir>':_files \ + - --proxy-negotiate'[HTTP Negotiate (SPNEGO) authentication on the proxy]':'Use' \ + --proxy-pinnedpubkey'[FILE/HASHES public key to verify proxy with]':'<hashes>' \ + --crlfile'[Get a CRL list in PEM format from the given file]':'<file>':_files \ + - --proxy-insecure'[HTTPS proxy connections without verifying the proxy]':'Do' \ + - --proxy-ssl-allow-beast'[security flaw for interop for HTTPS proxy]':'Allow' \ + + --proxy-negotiate'[Use HTTP Negotiate (SPNEGO) authentication on the proxy]' \ + --abstract-unix-socket'[Connect via abstract Unix domain socket]':'<path>' \ + --pinnedpubkey'[FILE/HASHES Public key to verify peer against]':'<hashes>' \ + + --proxy-insecure'[Do HTTPS proxy connections without verifying the proxy]' \ + --proxy-pass'[Pass phrase for the private key for HTTPS proxy]':'<phrase>' \ + + --proxy-ssl-allow-beast'[Allow security flaw for interop for HTTPS proxy]' \ + {-p,--proxytunnel}'[Operate through an HTTP proxy tunnel (using CONNECT)]' \ + --socks5-hostname'[SOCKS5 proxy, pass host name to proxy]':'<host[:port]>' \ + --proto-default'[Use PROTOCOL for any URL missing a scheme]':'<protocol>' \ + - --proxy-tls13-ciphers'[list> TLS 1.3 proxy cipher suites]':'<ciphersuite' \ + + --proxy-tls13-ciphers'[TLS 1.3 proxy cipher suites]':'<ciphersuite list>' \ + --socks5-gssapi-service'[SOCKS5 proxy service name for GSS-API]':'<name>' \ + --ftp-alternative-to-user'[String to replace USER \[name\]]':'<command>' \ + - --ftp-ssl-control'[SSL/TLS for FTP login, clear for transfer]':'Require' \ + {-T,--upload-file}'[Transfer local FILE to destination]':'<file>':_files \ + --local-port'[Force use of RANGE for local port numbers]':'<num/range>' \ + --proxy-tlsauthtype'[TLS authentication type for HTTPS proxy]':'<type>' \ + {-R,--remote-time}'[Set the remote file'\''s time on the local output]' \ + - --retry-connrefused'[on connection refused (use with --retry)]':'Retry' \ + - --suppress-connect-headers'[proxy CONNECT response headers]':'Suppress' \ + - {-j,--junk-session-cookies}'[session cookies read from file]':'Ignore' \ + - --location-trusted'[--location, and send auth to other hosts]':'Like' \ + + --ftp-ssl-control'[Require SSL/TLS for FTP login, clear for transfer]' \ + --proxy-cert-type'[Client certificate type for HTTPS proxy]':'<type>' \ + {-O,--remote-name}'[Write output to a file named as the remote file]' \ + + --retry-connrefused'[Retry on connection refused (use with --retry)]' \ + + --suppress-connect-headers'[Suppress proxy CONNECT response headers]' \ + --trace-ascii'[Like --trace, but without hex output]':'<file>':_files \ + --connect-timeout'[Maximum time allowed for connection]':'<seconds>' \ + --expect100-timeout'[How long to wait for 100-continue]':'<seconds>' \ + {-g,--globoff}'[Disable URL sequences and ranges using {} and \[\]]' \ + + {-j,--junk-session-cookies}'[Ignore session cookies read from file]' \ + {-m,--max-time}'[Maximum time allowed for the transfer]':'<seconds>' \ + --dns-ipv4-addr'[IPv4 address to use for DNS requests]':'<address>' \ + --dns-ipv6-addr'[IPv6 address to use for DNS requests]':'<address>' \ + - --ignore-content-length'[the size of the remote resource]':'Ignore' \ + {-k,--insecure}'[Allow insecure server connections when using SSL]' \ + + --location-trusted'[Like --location, and send auth to other hosts]' \ + --mail-auth'[Originator address of the original email]':'<address>' \ + --noproxy'[List of hosts which do not use proxy]':'<no-proxy-list>' \ + --proto-redir'[Enable/disable PROTOCOLS on redirect]':'<protocols>' \ + @@ -62,18 +62,19 @@ + --socks5-basic'[Enable username/password auth for SOCKS5 proxies]' \ + --cacert'[CA certificate to verify peer against]':'<file>':_files \ + {-H,--header}'[Pass custom header(s) to server]':'<header/@file>' \ + + --ignore-content-length'[Ignore the size of the remote resource]' \ + {-i,--include}'[Include protocol response headers in the output]' \ + --proxy-header'[Pass custom header(s) to proxy]':'<header/@file>' \ + --unix-socket'[Connect through this Unix domain socket]':'<path>' \ + {-w,--write-out}'[Use output FORMAT after completion]':'<format>' \ + - --http2-prior-knowledge'[HTTP 2 without HTTP/1.1 Upgrade]':'Use' \ + {-o,--output}'[Write to file instead of stdout]':'<file>':_files \ + - {-J,--remote-header-name}'[the header-provided filename]':'Use' \ + + --preproxy'[\[protocol://\]host\[:port\] Use this proxy first]' \ + --socks4a'[SOCKS4a proxy on given host + port]':'<host[:port]>' \ + {-Y,--speed-limit}'[Stop transfers slower than this]':'<speed>' \ + {-z,--time-cond}'[Transfer based on a time condition]':'<time>' \ + --capath'[CA directory to verify peer against]':'<dir>':_files \ + {-f,--fail}'[Fail silently (no output at all) on HTTP errors]' \ + + --http2-prior-knowledge'[Use HTTP 2 without HTTP/1.1 Upgrade]' \ + --proxy-tlspassword'[TLS password for HTTPS proxy]':'<string>' \ + {-U,--proxy-user}'[Proxy user and password]':'<user:password>' \ + --proxy1.0'[Use HTTP/1.0 proxy on given port]':'<host[:port]>' \ + @@ -81,52 +82,49 @@ + {-A,--user-agent}'[Send User-Agent <name> to server]':'<name>' \ + --egd-file'[EGD socket path for random data]':'<file>':_files \ + --fail-early'[Fail on first transfer error, do not continue]' \ + - --haproxy-protocol'[HAProxy PROXY protocol v1 header]':'Send' \ + - --preproxy'[Use this proxy first]':'[protocol://]host[:port]' \ + + {-J,--remote-header-name}'[Use the header-provided filename]' \ + --retry-max-time'[Retry only within this period]':'<seconds>' \ + --socks4'[SOCKS4 proxy on given host + port]':'<host[:port]>' \ + --socks5'[SOCKS5 proxy on given host + port]':'<host[:port]>' \ + - --socks5-gssapi-nec'[with NEC SOCKS5 server]':'Compatibility' \ + - --ssl-allow-beast'[security flaw to improve interop]':'Allow' \ + --cert-status'[Verify the status of the server certificate]' \ + - --ftp-create-dirs'[the remote dirs if not present]':'Create' \ + {-:,--next}'[Make next URL use its separate set of options]' \ + --proxy-key-type'[Private key file type for proxy]':'<type>' \ + - --remote-name-all'[the remote file name for all URLs]':'Use' \ + {-X,--request}'[Specify request command to use]':'<command>' \ + --retry'[Retry request if transient problems occur]':'<num>' \ + - --ssl-no-revoke'[cert revocation checks (WinSSL)]':'Disable' \ + --cert-type'[Certificate file type (DER/PEM/ENG)]':'<type>' \ + --connect-to'[Connect to host]':'<HOST1:PORT1:HOST2:PORT2>' \ + --create-dirs'[Create necessary local directory hierarchy]' \ + + --haproxy-protocol'[Send HAProxy PROXY protocol v1 header]' \ + --max-redirs'[Maximum number of redirects allowed]':'<num>' \ + {-n,--netrc}'[Must read .netrc for user name and password]' \ + + {-x,--proxy}'[\[protocol://\]host\[:port\] Use this proxy]' \ + --proxy-crlfile'[Set a CRL list for proxy]':'<file>':_files \ + --sasl-ir'[Enable initial response in SASL authentication]' \ + - --socks5-gssapi'[GSS-API auth for SOCKS5 proxies]':'Enable' \ + + --socks5-gssapi-nec'[Compatibility with NEC SOCKS5 server]' \ + + --ssl-allow-beast'[Allow security flaw to improve interop]' \ + + --ftp-create-dirs'[Create the remote dirs if not present]' \ + --interface'[Use network INTERFACE (or address)]':'<name>' \ + --key-type'[Private key file type (DER/PEM/ENG)]':'<type>' \ + --netrc-file'[Specify FILE for netrc]':'<filename>':_files \ + {-N,--no-buffer}'[Disable buffering of the output stream]' \ + --proxy-service-name'[SPNEGO proxy service name]':'<name>' \ + - --styled-output'[styled output for HTTP headers]':'Enable' \ + + --remote-name-all'[Use the remote file name for all URLs]' \ + + --ssl-no-revoke'[Disable cert revocation checks (WinSSL)]' \ + --max-filesize'[Maximum file size to download]':'<bytes>' \ + --negotiate'[Use HTTP Negotiate (SPNEGO) authentication]' \ + --no-keepalive'[Disable TCP keepalive on the connection]' \ + {-#,--progress-bar}'[Display transfer progress as a bar]' \ + - {-x,--proxy}'[Use this proxy]':'[protocol://]host[:port]' \ + - --proxy-anyauth'[any proxy authentication method]':'Pick' \ + {-Q,--quote}'[Send command(s) to server before transfer]' \ + - --request-target'[the target for this request]':'Specify' \ + + --socks5-gssapi'[Enable GSS-API auth for SOCKS5 proxies]' \ + {-u,--user}'[Server user and password]':'<user:password>' \ + {-K,--config}'[Read config from a file]':'<file>':_files \ + {-C,--continue-at}'[Resumed transfer offset]':'<offset>' \ + --data-raw'[HTTP POST data, '\''@'\'' allowed]':'<data>' \ + - --disallow-username-in-url'[username in url]':'Disallow' \ + --krb'[Enable Kerberos with security <level>]':'<level>' \ + --proxy-ciphers'[SSL ciphers to use for proxy]':'<list>' \ + --proxy-digest'[Use Digest authentication on the proxy]' \ + --proxy-tlsuser'[TLS username for HTTPS proxy]':'<name>' \ + + --styled-output'[Enable styled output for HTTP headers]' \ + {-b,--cookie}'[Send cookies from string/file]':'<data>' \ + --data-urlencode'[HTTP POST data url encoded]':'<data>' \ + --delegation'[GSS-API delegation permission]':'<LEVEL>' \ + @@ -134,7 +132,10 @@ + --post301'[Do not switch to GET after following a 301]' \ + --post302'[Do not switch to GET after following a 302]' \ + --post303'[Do not switch to GET after following a 303]' \ + + --proxy-anyauth'[Pick any proxy authentication method]' \ + + --request-target'[Specify the target for this request]' \ + --trace-time'[Add time stamps to trace/verbose output]' \ + + --disallow-username-in-url'[Disallow username in url]' \ + --dns-servers'[DNS server addrs to use]':'<addresses>' \ + {-G,--get}'[Put the post data in the URL and use GET]' \ + --limit-rate'[Limit transfer speed to RATE]':'<speed>' \ + @@ -148,21 +149,21 @@ + --metalink'[Process given URLs as metalink XML file]' \ + --tr-encoding'[Request compressed transfer encoding]' \ + --xattr'[Store metadata in extended file attributes]' \ + - --ftp-skip-pasv-ip'[the IP address for PASV]':'Skip' \ + --pass'[Pass phrase for the private key]':'<phrase>' \ + --proxy-ntlm'[Use NTLM authentication on the proxy]' \ + {-S,--show-error}'[Show error even when -s is used]' \ + - --ciphers'[of ciphers> SSL ciphers to use]':'<list' \ + + --ciphers'[SSL ciphers to use]':'<list of ciphers>' \ + --form-string'[Specify multipart MIME data]':'<name=string>' \ + --login-options'[Server login options]':'<options>' \ + --tftp-blksize'[Set TFTP BLKSIZE option]':'<value>' \ + - --tftp-no-options'[not send any TFTP options]':'Do' \ + {-v,--verbose}'[Make the operation more talkative]' \ + + --ftp-skip-pasv-ip'[Skip the IP address for PASV]' \ + --proxy-key'[Private key for HTTPS proxy]':'<key>' \ + {-F,--form}'[Specify multipart MIME data]':'<name=content>' \ + --mail-from'[Mail from this address]':'<address>' \ + --oauth2-bearer'[OAuth 2 Bearer Token]':'<token>' \ + --proto'[Enable/disable PROTOCOLS]':'<protocols>' \ + + --tftp-no-options'[Do not send any TFTP options]' \ + --tlsauthtype'[TLS authentication type]':'<type>' \ + --doh-url'[Resolve host names over DOH]':'<URL>' \ + --no-sessionid'[Disable SSL session-ID reusing]' \ + @@ -173,14 +174,13 @@ + --ftp-ssl-ccc'[Send CCC after authenticating]' \ + {-4,--ipv4}'[Resolve names to IPv4 addresses]' \ + {-6,--ipv6}'[Resolve names to IPv6 addresses]' \ + - --netrc-optional'[either .netrc or URL]':'Use' \ + --service-name'[SPNEGO service name]':'<name>' \ + {-V,--version}'[Show version number and quit]' \ + --data-ascii'[HTTP POST ASCII data]':'<data>' \ + --ftp-account'[Account data string]':'<data>' \ + - --compressed-ssh'[SSH compression]':'Enable' \ + --disable-eprt'[Inhibit using EPRT or LPRT]' \ + --ftp-method'[Control CWD usage]':'<method>' \ + + --netrc-optional'[Use either .netrc or URL]' \ + --pubkey'[SSH Public key file name]':'<key>' \ + --raw'[Do HTTP "raw"; no transfer decoding]' \ + --anyauth'[Pick any authentication method]' \ + @@ -189,6 +189,7 @@ + --no-alpn'[Disable the ALPN TLS extension]' \ + --tcp-nodelay'[Use the TCP_NODELAY option]' \ + {-B,--use-ascii}'[Use ASCII/text transfer]' \ + + --compressed-ssh'[Enable SSH compression]' \ + --digest'[Use HTTP Digest Authentication]' \ + --proxy-tlsv1'[Use TLSv1 for HTTPS proxy]' \ + --engine'[Crypto engine to use]':'<name>' \ + +Marcel Raad (7 Feb 2019) +- tool_operate: fix typecheck warning + + Use long for CURLOPT_HTTP09_ALLOWED to fix the following warning: + tool_operate.c: In function 'operate_do': + ../include/curl/typecheck-gcc.h:47:9: error: call to + '_curl_easy_setopt_err_long' declared with attribute warning: + curl_easy_setopt expects a long argument for this option [-Werror] + + Closes https://github.com/curl/curl/pull/3534 + +Jay Satiro (6 Feb 2019) +- [Chris Araman brought this change] + + url: close TLS before removing conn from cache + + - Fix potential crashes in schannel shutdown. + + Ensure any TLS shutdown messages are sent before removing the + association between the connection and the easy handle. Reverts + @bagder's previous partial fix for #3412. + + Fixes https://github.com/curl/curl/issues/3412 + Fixes https://github.com/curl/curl/issues/3505 + Closes https://github.com/curl/curl/pull/3531 + +Daniel Gustafsson (6 Feb 2019) +- INTERNALS.md: fix subsection depth and link + + The Kerberos subsection was mistakenly a subsubsection under FTP, and + the curlx subsection was missing an anchor for the TOC link. + + Closes #3529 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + Version 7.64.0 (6 Feb 2019) Daniel Stenberg (6 Feb 2019) @@ -6351,1399 +8010,3 @@ Daniel Stenberg (12 May 2018) Detected by OSS-Fuzz Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8245 - -- setup_transfer: deal with both sockets being -1 - - Detected by Coverity; CID 1435559. Follow-up to f8d608f38d00. It would - index the array with -1 if neither index was a socket. - -- travis: add build using NSS - - Closes #2558 - -- [Sunny Purushe brought this change] - - openssl: change FILE ops to BIO ops - - To make builds with VS2015 work. Recent changes in VS2015 _IOB_ENTRIES - handling is causing problems. This fix changes the OpenSSL backend code - to use BIO functions instead of FILE I/O functions to circumvent those - problems. - - Closes #2512 - -- travis: add a build using WolfSSL - - Assisted-by: Dan Fandrich - - Closes #2528 - -- RELEASE-NOTES: typo - -- RELEASE-NOTES: synced - -- [Daniel Gustafsson brought this change] - - URLs: fix one more http url - - This file wasn't included in commit 4af40b3646d3b09 which updated all - haxx.se http urls to https. The file was committed prior to that update, - but may have been merged after it and hence didn't get updated. - - Closes #2550 - -- github/lock: auto-lock closed issues after 90 days of inactivity - -- vtls: fix missing commas - - follow-up to e66cca046cef - -- vtls: use unified "supports" bitfield member in backends - - ... instead of previous separate struct fields, to make it easier to - extend and change individual backends without having to modify them all. - - closes #2547 - -- transfer: don't unset writesockfd on setup of multiplexed conns - - Curl_setup_transfer() can be called to setup a new individual transfer - over a multiplexed connection so it shouldn't unset writesockfd. - - Bug: #2520 - Closes #2549 - -- [Frank Gevaerts brought this change] - - configure: put CURLDEBUG and DEBUGBUILD in lib/curl_config.h - - They are removed from the compiler flags. - - This ensures that make dependency tracking will force a rebuild whenever - configure --enable-debug or --enable-curldebug changes. - - Closes #2548 - -- http: don't set the "rewind" flag when not uploading anything - - It triggers an assert. - - Detected by OSS-Fuzz - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8144 - Closes #2546 - -- travis: add an mbedtls build - - Closes #2531 - -- configure: only check for CA bundle for file-using SSL backends - - When only building with SSL backends that don't use the CA bundle file - (by default), skip the check. - - Fixes #2543 - Fixes #2180 - Closes #2545 - -- ssh-libssh.c: fix left shift compiler warning - - ssh-libssh.c:2429:21: warning: result of '1 << 31' requires 33 bits to - represent, but 'int' only has 32 bits [-Wshift-overflow=] - - 'len' will never be that big anyway so I converted the run-time check to - a regular assert. - -- [Stephan Mühlstrasser brought this change] - - URL: fix ASCII dependency in strcpy_url and strlen_url - - Commit 3c630f9b0af097663a64e5c875c580aa9808a92b partially reverted the - changes from commit dd7521bcc1b7a6fcb53c31f9bd1192fcc884bd56 because of - the problem that strcpy_url() was modified unilaterally without also - modifying strlen_url(). As a consequence strcpy_url() was again - depending on ASCII encoding. - - This change fixes strlen_url() and strcpy_url() in parallel to use a - common host-encoding independent criterion for deciding whether an URL - character must be %-escaped. - - Closes #2535 - -- [Denis Ollier brought this change] - - docs: remove extraneous commas in man pages - - Closes #2544 - -- RELEASE-NOTES: synced - -- Revert "TODO: remove configure --disable-pthreads" - - This reverts commit d5d683a97f9765bddfd964fe32e137aa6e703ed3. - - --disable-pthreads can be used to disable pthreads and get the threaded - resolver to use the windows threading when building with mingw. - -- vtls: don't define MD5_DIGEST_LENGTH for wolfssl - - ... as it defines it (too) - -- TODO: remove configure --disable-pthreads - -Jay Satiro (2 May 2018) -- [David Garske brought this change] - - wolfssl: Fix non-blocking connect - - Closes https://github.com/curl/curl/pull/2542 - -Daniel Stenberg (30 Apr 2018) -- CURLOPT_URL.3: add ENCODING section [ci skip] - - Feedback-by: Michael Kilburn - -- KNOWN_BUGS: Client cert with Issuer DN differs between backends - - Closes #1411 - -- KNOWN_BUGS: Passive transfer tries only one IP address - - Closes #1508 - -- KNOWN_BUGS: --upload-file . hang if delay in STDIN - - Closes #2051 - -- KNOWN_BUGS: Connection information when using TCP Fast Open - - Closes #1332 - -- travis: enable libssh2 on both macos and Linux - - It seems to not be detected by default anymore (which is a bug I - believe) - - Closes #2541 - -- TODO: Support the clienthello extension - - Closes #2299 - -- TODO: CLOEXEC - - Closes #2252 - -- tests: provide 'manual' as a feature to optionally require - - ... and make test 1026 rely on that feature so that --disable-manual - builds don't cause test failures. - - Reported-by: Max Dymond and Anders Roxell - Fixes #2533 - Closes #2540 - -- CURLINFO_PROTOCOL.3: mention the existing defined names - -Jay Satiro (27 Apr 2018) -- [Daniel Gustafsson brought this change] - - cookies: remove unused macro - - Commit 2bc230de63 made the macro MAX_COOKIE_LINE_TXT become unused, - so remove as it's not part of the published API. - - Closes https://github.com/curl/curl/pull/2537 - -Daniel Stenberg (27 Apr 2018) -- [Daniel Gustafsson brought this change] - - checksrc: force indentation of lines after an else - - This extends the INDENTATION case to also handle 'else' statements - and require proper indentation on the following line. Also fixes the - offending cases found in the codebase. - - Closes #2532 - -- http2: fix null pointer dereference in http2_connisdead - - This function can get called on a connection that isn't setup enough to - have the 'recv_underlying' function pointer initialized so it would try - to call the NULL pointer. - - Reported-by: Dario Weisser - - Follow-up to db1b2c7fe9b093f8 (never shipped in a release) - Closes #2536 - -- http2: get rid of another strstr() - - Follow-up to 1514c44655e12e: replace another strstr() call done on a - buffer that might not be zero terminated - with a memchr() call, even if - we know the substring will be found. - - Assisted-by: Max Dymond - - Detected by OSS-Fuzz - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8021 - - Closes #2534 - -- cyassl: adapt to libraries without TLS 1.0 support built-in - - WolfSSL doesn't enable it by default anymore - -- configure: provide --with-wolfssl as an alias for --with-cyassl - -- RELEASE-NOTES: synced - -- [Daniel Gustafsson brought this change] - - os400.c: fix ASSIGNWITHINCONDITION checksrc warnings - - All occurrences of assignment within conditional expression in - os400sys.c rewritten into two steps: first assignment and then the check - on the success of the assignment. Also adjust related incorrect brace - positions to match project indentation style. - - This was spurred by seeing "if((inp = input_token))", but while in there - all warnings were fixed. - - There should be no functional change from these changes. - - Closes #2525 - -- [Daniel Gustafsson brought this change] - - cookies: ensure that we have cookies before writing jar - - The jar should be written iff there are cookies, so ensure that we still - have cookies after expiration to avoid creating an empty file. - - Closes #2529 - -- strcpy_url: only %-encode values >= 0x80 - - OSS-Fuzz detected - - https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8000 - - Broke in dd7521bcc1b7 - -- mime: avoid NULL pointer dereference risk - - Coverity detected, CID 1435120 - - Closes #2527 - -- [Stephan Mühlstrasser brought this change] - - ctype: restore character classification for non-ASCII platforms - - With commit 4272a0b0fc49a1ac0ceab5c4a365c9f6ab8bf8e2 curl-speficic - character classification macros and functions were introduced in - curl_ctype.[ch] to avoid dependencies on the locale. This broke curl on - non-ASCII, e.g. EBCDIC platforms. This change restores the previous set - of character classification macros when CURL_DOES_CONVERSIONS is - defined. - - Closes #2494 - -- ftplistparser: keep state between invokes - - Fixes FTP wildcard parsing when done over a number of read buffers. - - Regression from f786d1f14 - - Reported-by: wncboy on github - Fixes #2445 - Closes #2526 - -- examples/http2-upload: expand buffer to avoid silly warning - - http2-upload.c:135:44: error: ‘%02d’ directive output may be truncated - writing between 2 and 11 bytes into a region of size between 8 and 17 - -- examples/sftpuploadresume: typecast fseek argument to long - - /docs/examples/sftpuploadresume.c:102:12: warning: conversion to 'long - int' from 'curl_off_t {aka long long int}' may alter its value - -- Revert "ftplistparser: keep state between invokes" - - This reverts commit abbc8457d85aca74b7cfda1d394b0844932b2934. - - Caused fuzzer problems on travis not seen when this was a PR! - -- Curl_memchr: zero length input can't match - - Avoids undefined behavior. - - Reported-by: Geeknik Labs - -- ftplistparser: keep state between invokes - - Fixes FTP wildcard parsing when doing over a number of read buffers. - - Regression from f786d1f14 - - Reported-by: wncboy on github - Fixes #2445 - Closes #2519 - -- ftplistparser: renamed some members and variables - - ... to make them better spell out what they're for. - -- RELEASE-NOTES: synced - -- [Christian Schmitz brought this change] - - curl_global_sslset: always provide available backends - - Closes #2499 - -- http2: convert an assert to run-time check - - Fuzzing has proven we can reach code in on_frame_recv with status_code - not having been set, so let's detect that in run-time (instead of with - assert) and error error accordingly. - - (This should no longer happen with the latest nghttp2) - - Detected by OSS-Fuzz - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7903 - Closes #2514 - -- curl.1: clarify that options and URLs can be mixed - - Fixes #2515 - Closes #2517 - -Jay Satiro (23 Apr 2018) -- [Archangel_SDY brought this change] - - CURLOPT_SSLCERT.3: improve WinSSL-specific usage info - - Ref: https://github.com/curl/curl/pull/2376#issuecomment-381858780 - - Closes https://github.com/curl/curl/pull/2504 - -- [Archangel_SDY brought this change] - - schannel: fix build error on targets <= XP - - - Use CRYPT_STRING_HEX instead of CRYPT_STRING_HEXRAW since XP doesn't - support the latter. - - Ref: https://github.com/curl/curl/pull/2376#issuecomment-382153668 - - Closes https://github.com/curl/curl/pull/2504 - -Daniel Stenberg (23 Apr 2018) -- Revert "ftplistparser: keep state between invokes" - - This reverts commit 8fb78f9ddc6d858d630600059b8ad84a80892fd9. - - Unfortunately this fix introduces memory leaks I've not been able to fix - in several days. Reverting this for now to get the leaks fixed. - -Jay Satiro (21 Apr 2018) -- tool_help: clarify --max-time unit of time is seconds - - Before: - -m, --max-time <time> Maximum time allowed for the transfer - - After: - -m, --max-time <seconds> Maximum time allowed for the transfer - -Daniel Stenberg (20 Apr 2018) -- http2: handle GOAWAY properly - - When receiving REFUSED_STREAM, mark the connection for close and retry - streams accordingly on another/fresh connection. - - Reported-by: Terry Wu - Fixes #2416 - Fixes #1618 - Closes #2510 - -- http2: clear the "drain counter" when a stream is closed - - This fixes the notorious "httpc->drain_total >= data->state.drain" - assert. - - Reported-by: Anders Bakken - - Fixes #1680 - Closes #2509 - -- http2: avoid strstr() on data not zero terminated - - It's not strictly clear if the API contract allows us to call strstr() - on a string that isn't zero terminated even when we know it will find - the substring, and clang's ASAN check dislikes us for it. - - Also added a check of the return code in case it fails, even if I can't - think of a situation how that can trigger. - - Detected by OSS-Fuzz - Closes #2513 - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7760 - -- [Stephan Mühlstrasser brought this change] - - openssl: fix subjectAltName check on non-ASCII platforms - - Curl_cert_hostcheck operates with the host character set, therefore the - ASCII subjectAltName string retrieved with OpenSSL must be converted to - the host encoding before comparison. - - Closes #2493 - -Jay Satiro (20 Apr 2018) -- openssl: Add support for OpenSSL 1.1.1 verbose-mode trace messages - - - Support handling verbose-mode trace messages of type - SSL3_RT_INNER_CONTENT_TYPE, SSL3_MT_ENCRYPTED_EXTENSIONS, - SSL3_MT_END_OF_EARLY_DATA, SSL3_MT_KEY_UPDATE, SSL3_MT_NEXT_PROTO, - SSL3_MT_MESSAGE_HASH - - Reported-by: iz8mbw@users.noreply.github.com - - Fixes https://github.com/curl/curl/issues/2403 - -Daniel Stenberg (19 Apr 2018) -- ftplistparser: keep state between invokes - - Regression from f786d1f14 - - Reported-by: wncboy on github - Fixes #2445 - Closes #2508 - -- detect_proxy: only show proxy use if it had contents - -- http2: handle on_begin_headers() called more than once - - This triggered an assert if called more than once in debug mode (and a - memory leak if not debug build). With the right sequence of HTTP/2 - headers incoming it can happen. - - Detected by OSS-Fuzz - - Closes #2507 - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7764 - -Jay Satiro (18 Apr 2018) -- [Dan McNulty brought this change] - - schannel: add support for CURLOPT_CAINFO - - - Move verify_certificate functionality in schannel.c into a new - file called schannel_verify.c. Additionally, some structure defintions - from schannel.c have been moved to schannel.h to allow them to be - used in schannel_verify.c. - - - Make verify_certificate functionality for Schannel available on - all versions of Windows instead of just Windows CE. verify_certificate - will be invoked on Windows CE or when the user specifies - CURLOPT_CAINFO and CURLOPT_SSL_VERIFYPEER. - - - In verify_certificate, create a custom certificate chain engine that - exclusively trusts the certificate store backed by the CURLOPT_CAINFO - file. - - - doc updates of --cacert/CAINFO support for schannel - - - Use CERT_NAME_SEARCH_ALL_NAMES_FLAG when invoking CertGetNameString - when available. This implements a TODO in schannel.c to improve - handling of multiple SANs in a certificate. In particular, all SANs - will now be searched instead of just the first name. - - - Update tool_operate.c to not search for the curl-ca-bundle.crt file - when using Schannel to maintain backward compatibility. Previously, - any curl-ca-bundle.crt file found in that search would have been - ignored by Schannel. But, with CAINFO support, the file found by - that search would have been used as the certificate store and - could cause issues for any users that have curl-ca-bundle.crt in - the search path. - - - Update url.c to not set the build time CURL_CA_BUNDLE if the selected - SSL backend is Schannel. We allow setting CA location for schannel - only when explicitly specified by the user via CURLOPT_CAINFO / - --cacert. - - - Add new test cases 3000 and 3001. These test cases check that the first - and last SAN, respectively, matches the connection hostname. New test - certificates have been added for these cases. For 3000, the certificate - prefix is Server-localhost-firstSAN and for 3001, the certificate - prefix is Server-localhost-secondSAN. - - - Remove TODO 15.2 (Add support for custom server certificate - validation), this commit addresses it. - - Closes https://github.com/curl/curl/pull/1325 - -- schannel: fix warning - - - Fix warning 'integer from pointer without a cast' on 3rd arg in - CertOpenStore. The arg type HCRYPTPROV may be a pointer or integer - type of the same size. - - Follow-up to e35b025. - - Caught by Marc's CI builds. - -- [Jakub Wilk brought this change] - - docs: fix typos - - Closes https://github.com/curl/curl/pull/2503 - -Daniel Stenberg (17 Apr 2018) -- RELEASE-NOTES: synced - -Jay Satiro (17 Apr 2018) -- [Kees Dekker brought this change] - - winbuild: Support custom devel paths for each dependency - - - Support custom devel paths for c-ares, mbedTLS, nghttp2, libSSH2, - OpenSSL and zlib. Respectively: CARES_PATH, MBEDTLS_PATH, - NGHTTP2_PATH, SSH2_PATH, SSL_PATH and ZLIB_PATH. - - - Use lib.exe for making the static library instead of link.exe /lib. - The latter is undocumented and could cause problems as noted in the - comments. - - - Remove a dangling URL that no longer worked. (I was not able to find - the IDN download at MSDN/microsoft.com, so it seems to be removed.) - - - Remove custom override for release-ssh2-ssl-dll-zlib configuration. - Nobody knows why it was there and as far as we can see is unnecessary. - - Closes https://github.com/curl/curl/pull/2474 - -Daniel Stenberg (17 Apr 2018) -- [Jess brought this change] - - README.md: add backers and sponsors - - Closes #2484 - -- [Archangel_SDY brought this change] - - schannel: add client certificate authentication - - Users can now specify a client certificate in system certificates store - explicitly using expression like `--cert "CurrentUser\MY\<thumbprint>"` - - Closes #2376 - -Marcel Raad (16 Apr 2018) -- [toughengineer brought this change] - - ntlm_sspi: fix authentication using Credential Manager - - If you pass empty user/pass asking curl to use Windows Credential - Storage (as stated in the docs) and it has valid credentials for the - domain, e.g. - curl -v -u : --ntlm example.com - currently authentication fails. - This change fixes it by providing proper SPN string to the SSPI API - calls. - - Fixes https://github.com/curl/curl/issues/1622 - Closes https://github.com/curl/curl/pull/1660 - -Daniel Stenberg (16 Apr 2018) -- configure: keep LD_LIBRARY_PATH changes local - - ... only set it when we actually have to run tests to reduce its impact - on for example build commands etc. - - Fixes #2490 - Closes #2492 - - Reported-by: Dmitry Mikhirev - -Marcel Raad (16 Apr 2018) -- urldata: make service names unconditional - - The ifdefs have become quite long. Also, the condition for the - definition of CURLOPT_SERVICE_NAME and for setting it from - CURLOPT_SERVICE_NAME have diverged. We will soon also need the two - options for NTLM, at least when using SSPI, for - https://github.com/curl/curl/pull/1660. - Just make the definitions unconditional to make that easier. - - Closes https://github.com/curl/curl/pull/2479 - -Daniel Stenberg (16 Apr 2018) -- test1148: tolerate progress updates better - - Fixes #2446 - Closes #2488 - -- [Christian Schmitz brought this change] - - ssh: show libSSH2 error code when closing fails - - Closes #2500 - -Jay Satiro (15 Apr 2018) -- [Daniel Gustafsson brought this change] - - vauth: Fix typo - - Address various spellings of "credentials". - - Closes https://github.com/curl/curl/pull/2496 - -- [Dagobert Michelsen brought this change] - - system.h: Add sparcv8plus to oracle/sunpro 32-bit detection - - With specific compiler options selecting the arch like -xarch=sparc on - newer compilers like Oracle Studio 12.4 there is no definition of - __sparcv8 but __sparcv8plus which means the V9 ISA, but limited to the - 32ÎíÎñbit subset defined by the V8plus ISA specification, without the - Visual Instruction Set (VIS), and without other implementation-specific - ISA extensions. So it should be the same as __sparcv8. - - Closes https://github.com/curl/curl/pull/2491 - -- [Daniel Gustafsson brought this change] - - checksrc: Fix typo - - Fix typo in "semicolon" spelling and remove stray tab character. - - Closes https://github.com/curl/curl/pull/2498 - -- [Daniel Gustafsson brought this change] - - all: Refactor malloc+memset to use calloc - - When a zeroed out allocation is required, use calloc() rather than - malloc() followed by an explicit memset(). The result will be the - same, but using calloc() everywhere increases consistency in the - codebase and avoids the risk of subtle bugs when code is injected - between malloc and memset by accident. - - Closes https://github.com/curl/curl/pull/2497 - -Daniel Stenberg (12 Apr 2018) -- duphandle: make sure CURLOPT_RESOLVE is duplicated fine too - - Verified in test 1502 now - - Fixes #2485 - Closes #2486 - Reported-by: Ernst Sjöstrand - -- mailmap: add a monnerat fixup [ci skip] - -- proxy: show getenv proxy use in verbose output - - ... to aid debugging etc as it sometimes isn't immediately obvious why - curl uses or doesn't use a proxy. - - Inspired by #2477 - - Closes #2480 - -- travis: build libpsl and make builds use it - - closes #2471 - -- travis: bump to clang 6 and gcc 7 - - Extra-eye-on-this-by: Marcel Raad - - Closes #2478 - -Marcel Raad (10 Apr 2018) -- travis: use trusty for coverage build - - This works now and precise is in the process of being decommissioned. - - Closes https://github.com/curl/curl/pull/2476 - -- lib: silence null-dereference warnings - - In debug mode, MingGW-w64's GCC 7.3 issues null-dereference warnings - when dereferencing pointers after DEBUGASSERT-ing that they are not - NULL. - Fix this by removing the DEBUGASSERTs. - - Suggested-by: Daniel Stenberg - Ref: https://github.com/curl/curl/pull/2463 - -- [Kees Dekker brought this change] - - winbuild: fix URL - - Follow up on https://github.com/curl/curl/pull/2472. - Now using en-us instead of nl-nl as language code in the URL. - - Closes https://github.com/curl/curl/pull/2475 - -Daniel Stenberg (9 Apr 2018) -- [Kees Dekker brought this change] - - winbuild: updated the documentation - - The setenv command no longer exists and visual studio build prompts got - changed. Used Visual Studio 2015/2017 as reference. - - Closes #2472 - -- test1136: fix cookie order after commit c990eadd1277 - -- build: cleanup to fix clang warnings/errors - - unit1309 and vtls/gtls: error: arithmetic on a null pointer treated as a - cast from integer to pointer is a GNU extension - - Reported-by: Rikard Falkeborn - - Fixes #2466 - Closes #2468 - -Jay Satiro (7 Apr 2018) -- examples/sftpuploadresmue: Fix Windows large file seek - - - Use _fseeki64 instead of fseek (long) to seek curl_off_t in Windows. - - - Use CURL_FORMAT_CURL_OFF_T specifier instead of %ld to print - curl_off_t. - - Caught by Marc's CI builds. - -Daniel Stenberg (7 Apr 2018) -- curl_setup: provide a CURL_SA_FAMILY_T type if none exists - - ... and use this type instead of 'sa_family_t' in the code since several - platforms don't have it. - - Closes #2463 - -- [Eric Gallager brought this change] - - build: add picky compiler warning flags for gcc 6 and 7 - -- configure: detect sa_family_t - -Jay Satiro (7 Apr 2018) -- [Stefan Agner brought this change] - - tool_operate: Fix retry on FTP 4xx to ignore other protocols - - Only treat response code as FTP response codes in case the - protocol type is FTP. - - This fixes an issue where an HTTP download was treated as FTP - in case libcurl returned with 33. This happens when the - download has already finished and the server responses 416: - HTTP/1.1 416 Requested Range Not Satisfiable - - This should not be treated as an FTP error. - - Fixes #2464 - Closes #2465 - -Daniel Stenberg (6 Apr 2018) -- hash: calculate sizes with size_t instead of longs - - ... since they return size_t anyway! - - closes #2462 - -- RELEASE-NOTES: synced - -- [Jay Satiro brought this change] - - build-openssl.bat: Refer to VS2017 as VC14.1 instead of VC15 - - .. and do the same for build-wolfssl.bat. - - Because MS calls it VC14.1. - - Closes https://github.com/curl/curl/pull/2189 - -- [Kees Dekker brought this change] - - winbuild: make the clean target work without build-type - - Due to the check in Makefile.vc and MakefileBuild.vc, no make call can - be invoked unless a build-type was specified. However, a clean target - only existed when a build type was specified. As a result, the clean - target was unreachable. Made clean target unconditional. - - Closes #2455 - -- [patelvivekv1993 brought this change] - - build-openssl.bat: allow custom paths for VS and perl - - Fixes #2430 - Closes #2457 - -- [Laurie Clark-Michalek brought this change] - - FTP: allow PASV on IPv6 connections when a proxy is being used - - In the situation of a client connecting to an FTP server using an IPv6 - tunnel proxy, the connection info will indicate that the connection is - IPv6. However, because the server behing the proxy is IPv4, it is - permissable to attempt PSV mode. In the case of the FTP server being - IPv4 only, EPSV will always fail, and with the current logic curl will - be unable to connect to the server, as the IPv6 fwdproxy causes curl to - think that EPSV is impossible. - - Closes #2432 - -- [Jon DeVree brought this change] - - file: restore old behavior for file:////foo/bar URLs - - curl 7.57.0 and up interpret this according to Appendix E.3.2 of RFC - 8089 but then returns an error saying this is unimplemented. This is - actually a regression in behavior on both Windows and Unix. - - Before curl 7.57.0 this URL was treated as a path of "//foo/bar" and - then passed to the relevant OS API. This means that the behavior of this - case is actually OS dependent. - - The Unix path resolution rules say that the OS must handle swallowing - the extra "/" and so this path is the same as "/foo/bar" - - The Windows path resolution rules say that this is a UNC path and - automatically handles the SMB access for the program. So curl on Windows - was already doing Appendix E.3.2 without any special code in curl. - - Regression - - Closes #2438 - -- [Gaurav Malhotra brought this change] - - Revert "openssl: Don't add verify locations when verifypeer==0" - - This reverts commit dc85437736e1fc90e689bb1f6c51c8f1aa9430eb. - - libcurl (with the OpenSSL backend) performs server certificate verification - even if verifypeer == 0 and the verification result is available using - CURLINFO_SSL_VERIFYRESULT. The commit that is being reverted caused the - CURLINFO_SSL_VERIFYRESULT to not have useful information for the - verifypeer == 0 use case (it would always have - X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY). - - Closes #2451 - -- [Wyatt O'Day brought this change] - - tls: fix mbedTLS 2.7.0 build + handle sha256 failures - - (mbedtls 2.70 compiled with MBEDTLS_DEPRECATED_REMOVED) - - Closes #2453 - -- [Lauri Kasanen brought this change] - - cookie: case-insensitive hashing for the domains - - closes #2458 - -Patrick Monnerat (4 Apr 2018) -- cookie: fix and optimize 2nd top level domain name extraction - - This fixes a segfault occurring when a name of the (invalid) form "domain..tld" - is processed. - - test46 updated to cover this case. - - Follow-up to commit c990ead. - - Ref: https://github.com/curl/curl/pull/2440 - -Daniel Stenberg (4 Apr 2018) -- openssl: provide defines for argument typecasts to build warning-free - - ... as OpenSSL >= 1.1.0 and libressl >= 2.7.0 use different argument types. - -- [Bernard Spil brought this change] - - openssl: fix build with LibreSSL 2.7 - - - LibreSSL 2.7 implements (most of) OpenSSL 1.1 API - - Fixes #2319 - Closes #2447 - Closes #2448 - - Signed-off-by: Bernard Spil <brnrd@FreeBSD.org> - -- [Lauri Kasanen brought this change] - - cookie: store cookies per top-level-domain-specific hash table - - This makes libcurl handle thousands of cookies much better and speedier. - - Closes #2440 - -- [Lauri Kasanen brought this change] - - cookies: when reading from a file, only remove_expired once - - This drops the cookie load time for 8k cookies from 178ms to 15ms. - - Closes #2441 - -- test1148: set a fixed locale for the test - - ...as otherwise it might use a different decimal sign. - - Bug: #2436 - Reported-by: Oumph on github - -Jay Satiro (31 Mar 2018) -- docs: fix CURLINFO_*_T examples use of CURL_FORMAT_CURL_OFF_T - - - Put a percent sign before each CURL_FORMAT_CURL_OFF_T in printf. - - For example "%" CURL_FORMAT_CURL_OFF_T becomes %lld or similar. - - Bug: https://curl.haxx.se/mail/lib-2018-03/0140.html - Reported-by: David L. - -Sergei Nikulov (27 Mar 2018) -- [Michał Janiszewski brought this change] - - cmake: Add advapi32 as explicit link library for win32 - - ARM targets need advapi32 explicitly. - - Closes #2363 - -Daniel Stenberg (27 Mar 2018) -- TODO: connection cache sharing is now supporte - -Jay Satiro (26 Mar 2018) -- travis: enable apt retry on fail - - This is a workaround for an unsolved travis issue that is causing CI - instances to sporadically fail due to 'unable to connect' issues during - apt stage. - - Ref: https://github.com/travis-ci/travis-ci/issues/8507 - Ref: https://github.com/travis-ci/travis-ci/issues/9112#issuecomment-376305909 - -Michael Kaufmann (26 Mar 2018) -- runtests.pl: fix warning 'use of uninitialized value' - - follow-up to a9a7b60 - - Closes #2428 - -Daniel Stenberg (24 Mar 2018) -- gitignore: ignore more generated files - -- threaded resolver: track resolver time and set suitable timeout values - - In order to make curl_multi_timeout() return suitable "sleep" times even - when there's no socket to wait for while the name is being resolved in a - helper thread. - - It will increases the timeouts as time passes. - - Closes #2419 - -- [Howard Chu brought this change] - - openldap: fix for NULL return from ldap_get_attribute_ber() - - Closes #2399 - -GitHub (22 Mar 2018) -- [Sergei Nikulov brought this change] - - travis-ci: enable -Werror for CMake builds (#2418) - -- [Sergei Nikulov brought this change] - - cmake: avoid warn-as-error during config checks (#2411) - - - Move the CURL_WERROR option processing after the configuration checks - to avoid failures in case of warnings during the configuration checks. - - This is a partial fix for #2358 - -- [Sergei Nikulov brought this change] - - timeval: remove compilation warning by casting (#2417) - - This is fixes #2358 - -Daniel Stenberg (22 Mar 2018) -- http2: read pending frames (including GOAWAY) in connection-check - - If a connection has received a GOAWAY frame while not being used, the - function now reads frames off the connection before trying to reuse it - to avoid reusing connections the server has told us not to use. - - Reported-by: Alex Baines - Fixes #1967 - Closes #2402 - -- [Bas van Schaik brought this change] - - CI: add lgtm.yml for tweaking lgtm.com analysis - - Closes #2414 - -- CURLINFO_SSL_VERIFYRESULT.3: fix the example, add some text - - Reported-by: Michal Trybus - - Fixes #2400 - -- TODO: expand ~/ in config files - - Closes #2317 - -- cookie.d: mention that "-" as filename means stdin - - Reported-by: Dongliang Mu - Fixes #2410 - -- CURLINFO_COOKIELIST.3: made the example not leak memory - - Reported-by: Muz Dima - -- vauth/cleartext: fix integer overflow check - - Make the integer overflow check not rely on the undefined behavior that - a size_t wraps around on overflow. - - Detected by lgtm.com - Closes #2408 - -- lib/curl_path.h: add #ifdef header guard - - Detected by lgtm.com - -- vauth/ntlm.h: fix the #ifdef header guard - - Detected by lgtm.com - -Jay Satiro (20 Mar 2018) -- examples/hiperfifo: checksrc compliance - -Daniel Stenberg (19 Mar 2018) -- [Nikos Tsipinakis brought this change] - - parsedate: support UT timezone - - RFC822 section 5.2 mentions Universal Time, 'UT', to be synonymous with - GMT. - - Closes #2401 - -- RELEASE-NOTES: synced - -- [Don brought this change] - - cmake: add support for brotli - - Currently CMake cannot detect Brotli support. This adds detection of the - libraries and associated header files. It also adds this to the - generated config. - - Closes #2392 - -- [Chris Araman brought this change] - - darwinssl: fix iOS build - -Patrick Monnerat (18 Mar 2018) -- ILE/RPG binding: Add CURLOPT_HAPROXYPROTOCOL/Fix CURLOPT_DNS_SHUFFLE_ADDRESSES - -Daniel Stenberg (17 Mar 2018) -- [Rick Deist brought this change] - - resolve: add CURLOPT_DNS_SHUFFLE_ADDRESSES - - This patch adds CURLOPT_DNS_SHUFFLE_ADDRESSES to explicitly request - shuffling of IP addresses returned for a hostname when there is more - than one. This is useful when the application knows that a round robin - approach is appropriate and is willing to accept the consequences of - potentially discarding some preference order returned by the system's - implementation. - - Closes #1694 - -- add_handle/easy_perform: clear errorbuffer on start if set - - To offer applications a more defined behavior, we clear the buffer as - early as possible. - - Assisted-by: Jay Satiro - - Fixes #2190 - Closes #2377 - -- [Lawrence Matthews brought this change] - - CURLOPT_HAPROXYPROTOCOL: support the HAProxy PROXY protocol - - Add --haproxy-protocol for the command line tool - - Closes #2162 - -- curl_version_info.3: fix ssl_version description - - Reported-by: Vincas Razma - Fixes #2364 - -- multi: improved pending transfers handling => improved performance - - When a transfer is requested to get done and it is put in the pending - queue when limited by number of connections, total or per-host, libcurl - would previously very aggressively retry *ALL* pending transfers to get - them transferring. That was very time consuming. - - By reducing the aggressiveness in how pending are being retried, we - waste MUCH less time on putting transfers back into pending again. - - Some test cases got a factor 30(!) speed improvement with this change. - - Reported-by: Cyril B - Fixes #2369 - Closes #2383 - -- pause: when changing pause state, update socket state - - Especially unpausing a transfer might have to move the socket back to the - "currently used sockets" hash to get monitored. Otherwise it would never get - any more data and get stuck. Easily triggered with pausing using the - multi_socket API. - - Reported-by: Philip Prindeville - Bug: https://curl.haxx.se/mail/lib-2018-03/0048.html - Fixes #2393 - Closes #2391 - -- [Philip Prindeville brought this change] - - examples/hiperfifo.c: improved - - * use member struct event’s instead of pointers to alloc’d struct - events - - * simplify the cases for the mcode_or_die() function via macros; - - * make multi_timer_cb() actually do what the block comment says it - should; - - * accept a “stop” command on the FIFO to shut down the service; - - * use cleaner notation for unused variables than the (void) hack; - - * allow following redirections (304’s); - -- rate-limit: use three second window to better handle high speeds - - Due to very frequent updates of the rate limit "window", it could - attempt to rate limit within the same milliseconds and that then made - the calculations wrong, leading to it not behaving correctly on very - fast transfers. - - This new logic updates the rate limit "window" to be no shorter than the - last three seconds and only updating the timestamps for this when - switching between the states TOOFAST/PERFORM. - - Reported-by: 刘佩东 - Fixes #2386 - Closes #2388 - -- [luz.paz brought this change] - - cleanup: misc typos in strings and comments - - Found via `codespell` - - Closes #2389 - -- RELEASE-NOTES: toward 7.60.0 - -- [Kobi Gurkan brought this change] - - http2: fixes typo - - Closes #2387 - -- user-agent.d:: mention --proxy-header as well - - Bug: https://github.com/curl/curl/issues/2381 - -- transfer: make HTTP without headers count correct body size - - This is what "HTTP/0.9" basically looks like. - - Reported on IRC - - Closes #2382 - -- test1208: marked flaky - - It fails somewhere between every 3rd to 10th travis-CI run - -- SECURITY-PROCESS: mention how we write/add advisories - -- [dasimx brought this change] - - FTP: fix typo in recursive callback detection for seeking - - Fixes #2380 - -Version 7.59.0 (13 Mar 2018) - -Daniel Stenberg (13 Mar 2018) -- release: 7.59.0 - -Kamil Dudka (13 Mar 2018) -- tests/.../spnego.py: fix identifier typo - - Detected by Coverity Analysis: - - Error: IDENTIFIER_TYPO: - curl-7.58.0/tests/python_dependencies/impacket/spnego.py:229: identifier_typo: Using "SuportedMech" appears to be a typo: - * Identifier "SuportedMech" is only known to be referenced here, or in copies of this code. - * Identifier "SupportedMech" is referenced elsewhere at least 4 times. - curl-7.58.0/tests/python_dependencies/impacket/smbserver.py:2651: identifier_use: Example 1: Using identifier "SupportedMech". - curl-7.58.0/tests/python_dependencies/impacket/smbserver.py:2308: identifier_use: Example 2: Using identifier "SupportedMech". - curl-7.58.0/tests/python_dependencies/impacket/spnego.py:252: identifier_use: Example 3: Using identifier "SupportedMech" (2 total uses in this function). - curl-7.58.0/tests/python_dependencies/impacket/spnego.py:229: remediation: Should identifier "SuportedMech" be replaced by "SupportedMech"? - - Closes #2379 - -Daniel Stenberg (13 Mar 2018) -- CURLOPT_COOKIEFILE.3: "-" as file name means stdin - - Reported-by: Aron Bergman - Bug: https://curl.haxx.se/mail/lib-2018-03/0049.html - - [ci skip] - -- Revert "hostip: fix compiler warning: 'variable set but not used'" - - This reverts commit a577059f92fc65bd6b81717f0737f897a5b34248. - - The assignment really needs to be there or we risk working with an - uninitialized pointer. - -Michael Kaufmann (12 Mar 2018) -- limit-rate: fix compiler warning - - follow-up to 72a0f62 - -Viktor Szakats (12 Mar 2018) -- checksrc.pl: add -i and -m options - - To sync it with changes made for the libssh2 project. - Also cleanup some whitespace. - -- curl-openssl.m4: fix spelling [ci skip] - -- FAQ: fix a broken URL [ci skip] - -Daniel Stenberg (12 Mar 2018) -- http2: mark the connection for close on GOAWAY - - ... don't consider it an error! - - Assisted-by: Jay Satiro - Reported-by: Łukasz Domeradzki - Fixes #2365 - Closes #2375 - -- credits: Viktor prefers without accent - -- openldap: white space changes, fixed up the copyright years - -- openldap: check ldap_get_attribute_ber() results for NULL before using - - CVE-2018-1000121 - Reported-by: Dario Weisser - Bug: https://curl.haxx.se/docs/adv_2018-97a2.html - -- FTP: reject path components with control codes - - Refuse to operate when given path components featuring byte values lower - than 32. - - Previously, inserting a %00 sequence early in the directory part when - using the 'singlecwd' ftp method could make curl write a zero byte - outside of the allocated buffer. - - Test case 340 verifies. - - CVE-2018-1000120 - Reported-by: Duy Phan Thanh - Bug: https://curl.haxx.se/docs/adv_2018-9cd6.html - -- readwrite: make sure excess reads don't go beyond buffer end - - CVE-2018-1000122 - Bug: https://curl.haxx.se/docs/adv_2018-b047.html - - Detected by OSS-fuzz - -- BUGS: updated link to security process - -- limit-rate: kick in even before "limit" data has been received - - ... and make sure to avoid integer overflows with really large values. - - Reported-by: 刘佩东 - Fixes #2371 - Closes #2373 - -- docs/SECURITY.md -> docs/SECURITY-PROCESS.md - -- SECURITY.md: call it the security process - -Michael Kaufmann (11 Mar 2018) -- Curl_range: fix FTP-only and FILE-only builds - - follow-up to e04417d - -- hostip: fix compiler warning: 'variable set but not used' - -Daniel Stenberg (11 Mar 2018) -- HTTP: allow "header;" to replace an internal header with a blank one - - Reported-by: Michael Kaufmann - Fixes #2357 - Closes #2362 - -- http2: verbose output new MAX_CONCURRENT_STREAMS values - - ... as it is interesting for many users. - -- SECURITY: distros' max embargo time is 14 days now - -Patrick Monnerat (8 Mar 2018) -- curl tool: accept --compressed also if Brotli is enabled and zlib is not. - -Daniel Stenberg (5 Mar 2018) -- THANKS + mailmap: remove duplicates, fixup full names - -- [sergii.kavunenko brought this change] - - WolfSSL: adding TLSv1.3 - - Closes #2349 diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS index 58a8322ba5..bf6ad755c2 100644 --- a/libs/libcurl/docs/THANKS +++ b/libs/libcurl/docs/THANKS @@ -152,6 +152,7 @@ Arkadiusz Miskiewicz Armel Asselin Arnaud Compan Arnaud Ebalard +Arnaud Rebillout Aron Bergman Artak Galoyan Arthur Murray @@ -193,6 +194,7 @@ Benoit Neil Benoit Sigoure Bernard Leak Bernard Spil +Bernd Mueller Bernhard Iselborn Bernhard M. Wiedemann Bernhard Reutner-Fischer @@ -358,6 +360,7 @@ Daniel Johnson Daniel Kahn Gillmor Daniel Krügler Daniel Lee Hwang +Daniel Lublin Daniel Melani Daniel Mentz Daniel Romero @@ -508,6 +511,7 @@ Enrico Scholz Enrik Berkhan Eramoto Masaya Eric Cooper +Eric Curtin Eric Gallager Eric Hu Eric Landes @@ -726,6 +730,7 @@ Jaime Fullaondo Jakub Wilk Jakub Zakrzewski James Atwill +James Brown James Bursa James Cheng James Clancy @@ -1040,6 +1045,7 @@ Luz Paz Luật Nguyễn Lyman Epp Lyndon Hill +MAntoniak on github Maciej Karpiuk Maciej Puzio Maciej W. Rozycki @@ -1060,6 +1066,7 @@ Marc Hesse Marc Hörsken Marc Kleine-Budde Marc Renault +Marc Schlatter Marc-Antoine Perennou Marcel Raad Marcel Roelofs @@ -1126,6 +1133,7 @@ Mats Lidell Matt Arsenault Matt Ford Matt Kraai +Matt McClure Matt Veenstra Matt Witherspoon Matt Wixson @@ -1176,6 +1184,7 @@ Michael Maltese Michael Mealling Michael Mueller Michael Osipov +Michael Schmid Michael Smith Michael Stapelberg Michael Steuer @@ -1184,6 +1193,7 @@ Michael Wallner Michal Bonino Michal Marek Michal Trybus +Michał Antoniak Michał Fita Michał Górny Michał Janiszewski @@ -1250,6 +1260,7 @@ Nico Baggus Nicolas Berloquin Nicolas Croiset Nicolas François +Nicolas Grekas Nicolas Morey-Chaisemartin Niels van Tongeren Nikita Schmidt @@ -1312,6 +1323,7 @@ Patrick Watson Patrik Thunstrom Pau Garcia i Quiles Paul Donohue +Paul Groke Paul Harrington Paul Harris Paul Howarth @@ -1325,6 +1337,7 @@ Paul Querna Paul Saab Pavel Cenek Pavel Gushchin +Pavel Löbl Pavel Orehov Pavel Pavlov Pavel Raiskup @@ -1426,6 +1439,7 @@ Remco van Hooff Remi Gacogne Remo E Renato Botelho +Renaud Allard Renaud Chaillat Renaud Duhaut Renaud Guillard @@ -1499,6 +1513,7 @@ Roland Zimmermann Rolland Dudemaine Romain Coltel Romain Fliedel +Romain Geissler Roman Koifman Roman Mamedov Romulo A. Ceccon @@ -1588,6 +1603,7 @@ Siegfried Gyuricsko Simon Dick Simon H. Simon Josefsson +Simon Legner Simon Liu Simon Warta Somnath Kundu @@ -1783,6 +1799,7 @@ Vladimir Lazarenko Vojtech Janota Vojtech Minarik Vojtěch Král +Volker Schmid Vsevolod Novikov W. Mark Kubacki Waldek Kozba @@ -1837,6 +1854,7 @@ Zhibiao Wu Zhouyihai Ding Zmey Petroff Zvi Har'El +accountantM on github adnn on github afrind on github ahodesuka on github @@ -1846,9 +1864,11 @@ asavah on github baumanj on github bobmitchell1956 on github bsammon on github +buzo-ffm on github cbartl on github clbr on github cmfrolick on github +d912e3 on github daboul on github dasimx on github destman on github @@ -1866,6 +1886,7 @@ infinnovation-dev on github iz8mbw on github jakirkham on github jasal82 on github +jnbr on github jonrumsey on github joshhe on github jungle-boogie on github @@ -1880,8 +1901,10 @@ masbug on github mccormickt12 on github mkzero on github moohoorama on github +nedres on github neex on github neheb on github +nianxuejie on github nk nopjmp on github olesteban on github @@ -1895,10 +1918,12 @@ steini2000 on github stootill on github swalkaus at yahoo.com tarek112 on github +tholin on github tommink[at]post.pl tonystz on Github tpaukrt on github vanillajonathan on github +wesinator on github wmsch on github wncboy on github youngchopin on github diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h index 88e1f39e87..86a24184aa 100644 --- a/libs/libcurl/include/curl/curl.h +++ b/libs/libcurl/include/curl/curl.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -91,6 +91,11 @@ #include <support/SupportDefs.h> #endif +/* Compatibility for non-Clang compilers */ +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif + #ifdef __cplusplus extern "C" { #endif @@ -109,7 +114,9 @@ typedef void CURLSH; #ifdef CURL_STATICLIB # define CURL_EXTERN -#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) +#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) || \ + (__has_declspec_attribute(dllexport) && \ + __has_declspec_attribute(dllimport)) # if defined(BUILDING_LIBCURL) # define CURL_EXTERN __declspec(dllexport) # else @@ -144,7 +151,7 @@ typedef enum { CURLSSLBACKEND_POLARSSL = 6, CURLSSLBACKEND_WOLFSSL = 7, CURLSSLBACKEND_SCHANNEL = 8, - CURLSSLBACKEND_DARWINSSL = 9, + CURLSSLBACKEND_SECURETRANSPORT = 9, CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */ CURLSSLBACKEND_MBEDTLS = 11, CURLSSLBACKEND_MESALINK = 12 @@ -153,7 +160,10 @@ typedef enum { /* aliases for library clones and renames */ #define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL #define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL + +/* deprecated names: */ #define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL +#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT struct curl_httppost { struct curl_httppost *next; /* next entry in the list */ @@ -871,6 +881,14 @@ typedef enum { #define CURLHEADER_UNIFIED 0 #define CURLHEADER_SEPARATE (1<<0) +/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */ +#define CURLALTSVC_IMMEDIATELY (1<<0) +#define CURLALTSVC_ALTUSED (1<<1) +#define CURLALTSVC_READONLYFILE (1<<2) +#define CURLALTSVC_H1 (1<<3) +#define CURLALTSVC_H2 (1<<4) +#define CURLALTSVC_H3 (1<<5) + /* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ #define CURLPROTO_HTTP (1<<0) #define CURLPROTO_HTTPS (1<<1) @@ -1894,6 +1912,12 @@ typedef enum { /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */ CINIT(HTTP09_ALLOWED, LONG, 285), + /* alt-svc control bitmask */ + CINIT(ALTSVC_CTRL, LONG, 286), + + /* alt-svc cache file name to possibly read from/write to */ + CINIT(ALTSVC, STRINGPOINT, 287), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -2756,6 +2780,7 @@ typedef struct { #define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ #define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */ #define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */ +#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */ /* * NAME curl_version_info() diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h index 3b043345d7..9a4b9b02df 100644 --- a/libs/libcurl/include/curl/curlver.h +++ b/libs/libcurl/include/curl/curlver.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,17 +26,17 @@ a script at release-time. This was made its own header file in 7.11.2 */ /* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "1996 - 2018 Daniel Stenberg, <daniel@haxx.se>." +#define LIBCURL_COPYRIGHT "1996 - 2019 Daniel Stenberg, <daniel@haxx.se>." /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.64.0" +#define LIBCURL_VERSION "7.64.1" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 #define LIBCURL_VERSION_MINOR 64 -#define LIBCURL_VERSION_PATCH 0 +#define LIBCURL_VERSION_PATCH 1 /* This is the numeric version of the libcurl version number, meant for easier parsing and comparions by programs. The LIBCURL_VERSION_NUM define will @@ -57,7 +57,7 @@ CURL_VERSION_BITS() macro since curl's own configure script greps for it and needs it to contain the full number. */ -#define LIBCURL_VERSION_NUM 0x074000 +#define LIBCURL_VERSION_NUM 0x074001 /* * This is the date and time when the full source package was created. The @@ -68,7 +68,7 @@ * * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "2019-02-06" +#define LIBCURL_TIMESTAMP "2019-03-27" #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) #define CURL_AT_LEAST_VERSION(x,y,z) \ diff --git a/libs/libcurl/include/curl/typecheck-gcc.h b/libs/libcurl/include/curl/typecheck-gcc.h index 01df7b15f9..8018ea37fe 100644 --- a/libs/libcurl/include/curl/typecheck-gcc.h +++ b/libs/libcurl/include/curl/typecheck-gcc.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -256,6 +256,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t, #define _curl_is_string_option(option) \ ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \ (option) == CURLOPT_ACCEPT_ENCODING || \ + (option) == CURLOPT_ALTSVC || \ (option) == CURLOPT_CAINFO || \ (option) == CURLOPT_CAPATH || \ (option) == CURLOPT_COOKIE || \ diff --git a/libs/libcurl/src/Makefile.am b/libs/libcurl/src/Makefile.am index f2034a2f24..7c258b3fa7 100644 --- a/libs/libcurl/src/Makefile.am +++ b/libs/libcurl/src/Makefile.am @@ -131,9 +131,14 @@ include Makefile.inc libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS) libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS) +CHECKSRC = $(CS_$(V)) +CS_0 = @echo " RUN " $@; +CS_1 = +CS_ = $(CS_0) + checksrc: - @PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \ - $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch] + $(CHECKSRC)(@PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \ + $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch]) if CURLDEBUG # for debug builds, we scan the sources on all regular make invokes diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in index 14c1c73afa..6b3fcfa87d 100644 --- a/libs/libcurl/src/Makefile.in +++ b/libs/libcurl/src/Makefile.in @@ -21,7 +21,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -229,7 +229,7 @@ am__objects_1 = libcurl_la-file.lo libcurl_la-timeval.lo \ libcurl_la-sha256.lo libcurl_la-setopt.lo \ libcurl_la-curl_path.lo libcurl_la-curl_ctype.lo \ libcurl_la-curl_range.lo libcurl_la-psl.lo libcurl_la-doh.lo \ - libcurl_la-urlapi.lo + libcurl_la-urlapi.lo libcurl_la-altsvc.lo am__dirstamp = $(am__leading_dot)dirstamp am__objects_2 = vauth/libcurl_la-vauth.lo \ vauth/libcurl_la-cleartext.lo vauth/libcurl_la-cram.lo \ @@ -244,7 +244,7 @@ am__objects_3 = vtls/libcurl_la-openssl.lo vtls/libcurl_la-gtls.lo \ vtls/libcurl_la-polarssl_threadlock.lo \ vtls/libcurl_la-cyassl.lo vtls/libcurl_la-schannel.lo \ vtls/libcurl_la-schannel_verify.lo \ - vtls/libcurl_la-darwinssl.lo vtls/libcurl_la-gskit.lo \ + vtls/libcurl_la-sectransp.lo vtls/libcurl_la-gskit.lo \ vtls/libcurl_la-mbedtls.lo vtls/libcurl_la-mesalink.lo am__objects_4 = $(am__objects_1) $(am__objects_2) $(am__objects_3) am__objects_5 = @@ -311,7 +311,7 @@ am__objects_7 = libcurlu_la-file.lo libcurlu_la-timeval.lo \ libcurlu_la-sha256.lo libcurlu_la-setopt.lo \ libcurlu_la-curl_path.lo libcurlu_la-curl_ctype.lo \ libcurlu_la-curl_range.lo libcurlu_la-psl.lo \ - libcurlu_la-doh.lo libcurlu_la-urlapi.lo + libcurlu_la-doh.lo libcurlu_la-urlapi.lo libcurlu_la-altsvc.lo am__objects_8 = vauth/libcurlu_la-vauth.lo \ vauth/libcurlu_la-cleartext.lo vauth/libcurlu_la-cram.lo \ vauth/libcurlu_la-digest.lo vauth/libcurlu_la-digest_sspi.lo \ @@ -326,7 +326,7 @@ am__objects_9 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.lo \ vtls/libcurlu_la-polarssl_threadlock.lo \ vtls/libcurlu_la-cyassl.lo vtls/libcurlu_la-schannel.lo \ vtls/libcurlu_la-schannel_verify.lo \ - vtls/libcurlu_la-darwinssl.lo vtls/libcurlu_la-gskit.lo \ + vtls/libcurlu_la-sectransp.lo vtls/libcurlu_la-gskit.lo \ vtls/libcurlu_la-mbedtls.lo vtls/libcurlu_la-mesalink.lo am__objects_10 = $(am__objects_7) $(am__objects_8) $(am__objects_9) am_libcurlu_la_OBJECTS = $(am__objects_10) $(am__objects_6) @@ -350,7 +350,8 @@ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/libcurl_la-amigaos.Plo \ +am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ + ./$(DEPDIR)/libcurl_la-amigaos.Plo \ ./$(DEPDIR)/libcurl_la-asyn-ares.Plo \ ./$(DEPDIR)/libcurl_la-asyn-thread.Plo \ ./$(DEPDIR)/libcurl_la-base64.Plo \ @@ -457,6 +458,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-amigaos.Plo \ ./$(DEPDIR)/libcurl_la-warnless.Plo \ ./$(DEPDIR)/libcurl_la-wildcard.Plo \ ./$(DEPDIR)/libcurl_la-x509asn1.Plo \ + ./$(DEPDIR)/libcurlu_la-altsvc.Plo \ ./$(DEPDIR)/libcurlu_la-amigaos.Plo \ ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo \ ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo \ @@ -593,7 +595,6 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-amigaos.Plo \ vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo \ vauth/$(DEPDIR)/libcurlu_la-vauth.Plo \ vtls/$(DEPDIR)/libcurl_la-cyassl.Plo \ - vtls/$(DEPDIR)/libcurl_la-darwinssl.Plo \ vtls/$(DEPDIR)/libcurl_la-gskit.Plo \ vtls/$(DEPDIR)/libcurl_la-gtls.Plo \ vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo \ @@ -604,9 +605,9 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-amigaos.Plo \ vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo \ vtls/$(DEPDIR)/libcurl_la-schannel.Plo \ vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo \ + vtls/$(DEPDIR)/libcurl_la-sectransp.Plo \ vtls/$(DEPDIR)/libcurl_la-vtls.Plo \ vtls/$(DEPDIR)/libcurlu_la-cyassl.Plo \ - vtls/$(DEPDIR)/libcurlu_la-darwinssl.Plo \ vtls/$(DEPDIR)/libcurlu_la-gskit.Plo \ vtls/$(DEPDIR)/libcurlu_la-gtls.Plo \ vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo \ @@ -617,6 +618,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-amigaos.Plo \ vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo \ vtls/$(DEPDIR)/libcurlu_la-schannel.Plo \ vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo \ + vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo \ vtls/$(DEPDIR)/libcurlu_la-vtls.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -726,6 +728,7 @@ ENABLE_SHARED = @ENABLE_SHARED@ ENABLE_STATIC = @ENABLE_STATIC@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@ GCOV = @GCOV@ GREP = @GREP@ HAVE_BROTLI = @HAVE_BROTLI@ @@ -733,6 +736,7 @@ HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ HAVE_LIBZ = @HAVE_LIBZ@ HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ +HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ IDN_ENABLED = @IDN_ENABLED@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ @@ -796,7 +800,6 @@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ USE_ARES = @USE_ARES@ USE_CYASSL = @USE_CYASSL@ -USE_DARWINSSL = @USE_DARWINSSL@ USE_GNUTLS = @USE_GNUTLS@ USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@ USE_LIBRTMP = @USE_LIBRTMP@ @@ -809,6 +812,7 @@ USE_NSS = @USE_NSS@ USE_OPENLDAP = @USE_OPENLDAP@ USE_POLARSSL = @USE_POLARSSL@ USE_SCHANNEL = @USE_SCHANNEL@ +USE_SECTRANSP = @USE_SECTRANSP@ USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@ USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@ VERSION = @VERSION@ @@ -952,11 +956,11 @@ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ vtls/polarssl.c vtls/polarssl_threadlock.c \ vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \ - vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c + vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \ - vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h \ + vtls/cyassl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \ vtls/mbedtls.h vtls/mesalink.h LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ @@ -977,7 +981,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \ x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \ mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \ - doh.c urlapi.c + doh.c urlapi.c altsvc.c LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \ @@ -997,7 +1001,8 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \ x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \ curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \ - curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h + curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \ + altsvc.h LIB_RCFILES = libcurl.rc CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) @@ -1006,6 +1011,10 @@ HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) # Makefile.inc provides the CSOURCES and HHEADERS defines libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS) libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS) +CHECKSRC = $(CS_$(V)) +CS_0 = @echo " RUN " $@; +CS_1 = +CS_ = $(CS_0) # disable the tests that are mostly causing false positives TIDYFLAGS = -checks=-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-optin.performance.Padding,-clang-analyzer-valist.Uninitialized,-clang-analyzer-core.NonNullParamChecker,-clang-analyzer-core.NullDereference -quiet @@ -1162,7 +1171,7 @@ vtls/libcurl_la-schannel.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-schannel_verify.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) -vtls/libcurl_la-darwinssl.lo: vtls/$(am__dirstamp) \ +vtls/libcurl_la-sectransp.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-gskit.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) @@ -1215,7 +1224,7 @@ vtls/libcurlu_la-schannel.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-schannel_verify.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) -vtls/libcurlu_la-darwinssl.lo: vtls/$(am__dirstamp) \ +vtls/libcurlu_la-sectransp.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-gskit.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) @@ -1237,6 +1246,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-altsvc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-amigaos.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-asyn-ares.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-asyn-thread.Plo@am__quote@ # am--include-marker @@ -1348,6 +1358,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-warnless.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-wildcard.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-x509asn1.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-altsvc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-amigaos.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-asyn-ares.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-asyn-thread.Plo@am__quote@ # am--include-marker @@ -1484,7 +1495,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-vauth.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-cyassl.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-darwinssl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gskit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo@am__quote@ # am--include-marker @@ -1495,9 +1505,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-sectransp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-vtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-cyassl.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-darwinssl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gskit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo@am__quote@ # am--include-marker @@ -1508,6 +1518,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-vtls.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @@ -2317,6 +2328,13 @@ libcurl_la-urlapi.lo: urlapi.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-urlapi.lo `test -f 'urlapi.c' || echo '$(srcdir)/'`urlapi.c +libcurl_la-altsvc.lo: altsvc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-altsvc.lo -MD -MP -MF $(DEPDIR)/libcurl_la-altsvc.Tpo -c -o libcurl_la-altsvc.lo `test -f 'altsvc.c' || echo '$(srcdir)/'`altsvc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-altsvc.Tpo $(DEPDIR)/libcurl_la-altsvc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='altsvc.c' object='libcurl_la-altsvc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-altsvc.lo `test -f 'altsvc.c' || echo '$(srcdir)/'`altsvc.c + vauth/libcurl_la-vauth.lo: vauth/vauth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-vauth.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-vauth.Tpo -c -o vauth/libcurl_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-vauth.Tpo vauth/$(DEPDIR)/libcurl_la-vauth.Plo @@ -2464,12 +2482,12 @@ vtls/libcurl_la-schannel_verify.lo: vtls/schannel_verify.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c -vtls/libcurl_la-darwinssl.lo: vtls/darwinssl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-darwinssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-darwinssl.Tpo -c -o vtls/libcurl_la-darwinssl.lo `test -f 'vtls/darwinssl.c' || echo '$(srcdir)/'`vtls/darwinssl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-darwinssl.Tpo vtls/$(DEPDIR)/libcurl_la-darwinssl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/darwinssl.c' object='vtls/libcurl_la-darwinssl.lo' libtool=yes @AMDEPBACKSLASH@ +vtls/libcurl_la-sectransp.lo: vtls/sectransp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-sectransp.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-sectransp.Tpo -c -o vtls/libcurl_la-sectransp.lo `test -f 'vtls/sectransp.c' || echo '$(srcdir)/'`vtls/sectransp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-sectransp.Tpo vtls/$(DEPDIR)/libcurl_la-sectransp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/sectransp.c' object='vtls/libcurl_la-sectransp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-darwinssl.lo `test -f 'vtls/darwinssl.c' || echo '$(srcdir)/'`vtls/darwinssl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-sectransp.lo `test -f 'vtls/sectransp.c' || echo '$(srcdir)/'`vtls/sectransp.c vtls/libcurl_la-gskit.lo: vtls/gskit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-gskit.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-gskit.Tpo -c -o vtls/libcurl_la-gskit.lo `test -f 'vtls/gskit.c' || echo '$(srcdir)/'`vtls/gskit.c @@ -3269,6 +3287,13 @@ libcurlu_la-urlapi.lo: urlapi.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-urlapi.lo `test -f 'urlapi.c' || echo '$(srcdir)/'`urlapi.c +libcurlu_la-altsvc.lo: altsvc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-altsvc.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-altsvc.Tpo -c -o libcurlu_la-altsvc.lo `test -f 'altsvc.c' || echo '$(srcdir)/'`altsvc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-altsvc.Tpo $(DEPDIR)/libcurlu_la-altsvc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='altsvc.c' object='libcurlu_la-altsvc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-altsvc.lo `test -f 'altsvc.c' || echo '$(srcdir)/'`altsvc.c + vauth/libcurlu_la-vauth.lo: vauth/vauth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-vauth.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-vauth.Tpo -c -o vauth/libcurlu_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-vauth.Tpo vauth/$(DEPDIR)/libcurlu_la-vauth.Plo @@ -3416,12 +3441,12 @@ vtls/libcurlu_la-schannel_verify.lo: vtls/schannel_verify.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c -vtls/libcurlu_la-darwinssl.lo: vtls/darwinssl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-darwinssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-darwinssl.Tpo -c -o vtls/libcurlu_la-darwinssl.lo `test -f 'vtls/darwinssl.c' || echo '$(srcdir)/'`vtls/darwinssl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-darwinssl.Tpo vtls/$(DEPDIR)/libcurlu_la-darwinssl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/darwinssl.c' object='vtls/libcurlu_la-darwinssl.lo' libtool=yes @AMDEPBACKSLASH@ +vtls/libcurlu_la-sectransp.lo: vtls/sectransp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-sectransp.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-sectransp.Tpo -c -o vtls/libcurlu_la-sectransp.lo `test -f 'vtls/sectransp.c' || echo '$(srcdir)/'`vtls/sectransp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-sectransp.Tpo vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/sectransp.c' object='vtls/libcurlu_la-sectransp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-darwinssl.lo `test -f 'vtls/darwinssl.c' || echo '$(srcdir)/'`vtls/darwinssl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-sectransp.lo `test -f 'vtls/sectransp.c' || echo '$(srcdir)/'`vtls/sectransp.c vtls/libcurlu_la-gskit.lo: vtls/gskit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-gskit.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-gskit.Tpo -c -o vtls/libcurlu_la-gskit.lo `test -f 'vtls/gskit.c' || echo '$(srcdir)/'`vtls/gskit.c @@ -3585,7 +3610,8 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/libcurl_la-amigaos.Plo + -rm -f ./$(DEPDIR)/libcurl_la-altsvc.Plo + -rm -f ./$(DEPDIR)/libcurl_la-amigaos.Plo -rm -f ./$(DEPDIR)/libcurl_la-asyn-ares.Plo -rm -f ./$(DEPDIR)/libcurl_la-asyn-thread.Plo -rm -f ./$(DEPDIR)/libcurl_la-base64.Plo @@ -3696,6 +3722,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurl_la-warnless.Plo -rm -f ./$(DEPDIR)/libcurl_la-wildcard.Plo -rm -f ./$(DEPDIR)/libcurl_la-x509asn1.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-altsvc.Plo -rm -f ./$(DEPDIR)/libcurlu_la-amigaos.Plo -rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo -rm -f ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo @@ -3832,7 +3859,6 @@ distclean: distclean-am -rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-vauth.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-cyassl.Plo - -rm -f vtls/$(DEPDIR)/libcurl_la-darwinssl.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo @@ -3843,9 +3869,9 @@ distclean: distclean-am -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-schannel.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-vtls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-cyassl.Plo - -rm -f vtls/$(DEPDIR)/libcurlu_la-darwinssl.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo @@ -3856,6 +3882,7 @@ distclean: distclean-am -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-vtls.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ @@ -3902,7 +3929,8 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/libcurl_la-amigaos.Plo + -rm -f ./$(DEPDIR)/libcurl_la-altsvc.Plo + -rm -f ./$(DEPDIR)/libcurl_la-amigaos.Plo -rm -f ./$(DEPDIR)/libcurl_la-asyn-ares.Plo -rm -f ./$(DEPDIR)/libcurl_la-asyn-thread.Plo -rm -f ./$(DEPDIR)/libcurl_la-base64.Plo @@ -4013,6 +4041,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurl_la-warnless.Plo -rm -f ./$(DEPDIR)/libcurl_la-wildcard.Plo -rm -f ./$(DEPDIR)/libcurl_la-x509asn1.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-altsvc.Plo -rm -f ./$(DEPDIR)/libcurlu_la-amigaos.Plo -rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo -rm -f ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo @@ -4149,7 +4178,6 @@ maintainer-clean: maintainer-clean-am -rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-vauth.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-cyassl.Plo - -rm -f vtls/$(DEPDIR)/libcurl_la-darwinssl.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo @@ -4160,9 +4188,9 @@ maintainer-clean: maintainer-clean-am -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-schannel.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-vtls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-cyassl.Plo - -rm -f vtls/$(DEPDIR)/libcurlu_la-darwinssl.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo @@ -4173,6 +4201,7 @@ maintainer-clean: maintainer-clean-am -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-vtls.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -4214,8 +4243,8 @@ uninstall-am: uninstall-libLTLIBRARIES checksrc: - @PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \ - $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch] + $(CHECKSRC)(@PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \ + $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch]) # for debug builds, we scan the sources on all regular make invokes @CURLDEBUG_TRUE@all-local: checksrc diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc index 54acd6cea1..6c47bcda55 100644 --- a/libs/libcurl/src/Makefile.inc +++ b/libs/libcurl/src/Makefile.inc @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -30,11 +30,11 @@ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ vtls/polarssl.c vtls/polarssl_threadlock.c \ vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \ - vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c + vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \ - vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h \ + vtls/cyassl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \ vtls/mbedtls.h vtls/mesalink.h LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ @@ -55,7 +55,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \ x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \ mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \ - doh.c urlapi.c + doh.c urlapi.c altsvc.c LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \ @@ -75,7 +75,8 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \ x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \ curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \ - curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h + curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \ + altsvc.h LIB_RCFILES = libcurl.rc diff --git a/libs/libcurl/src/altsvc.c b/libs/libcurl/src/altsvc.c new file mode 100644 index 0000000000..1643466456 --- /dev/null +++ b/libs/libcurl/src/altsvc.c @@ -0,0 +1,571 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + * The Alt-Svc: header is defined in RFC 7838: + * https://tools.ietf.org/html/rfc7838 + */ +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC) +#include <curl/curl.h> +#include "urldata.h" +#include "altsvc.h" +#include "cookie.h" /* for Curl_get_line() */ +#include "strcase.h" +#include "parsedate.h" +#include "sendf.h" +#include "warnless.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define MAX_ALTSVC_LINE 4095 +#define MAX_ALTSVC_DATELENSTR "64" +#define MAX_ALTSVC_DATELEN 64 +#define MAX_ALTSVC_HOSTLENSTR "512" +#define MAX_ALTSVC_HOSTLEN 512 +#define MAX_ALTSVC_ALPNLENSTR "10" +#define MAX_ALTSVC_ALPNLEN 10 + +static enum alpnid alpn2alpnid(char *name) +{ + if(strcasecompare(name, "h1")) + return ALPN_h1; + if(strcasecompare(name, "h2")) + return ALPN_h2; + if(strcasecompare(name, "h2c")) + return ALPN_h2c; + if(strcasecompare(name, "h3")) + return ALPN_h3; + return ALPN_none; /* unknown, probably rubbish input */ +} + +/* Given the ALPN ID, return the name */ +const char *Curl_alpnid2str(enum alpnid id) +{ + switch(id) { + case ALPN_h1: + return "h1"; + case ALPN_h2: + return "h2"; + case ALPN_h2c: + return "h2c"; + case ALPN_h3: + return "h3"; + default: + return ""; /* bad */ + } +} + + +static void altsvc_free(struct altsvc *as) +{ + free(as->srchost); + free(as->dsthost); + free(as); +} + +static struct altsvc *altsvc_createid(const char *srchost, + const char *dsthost, + enum alpnid srcalpnid, + enum alpnid dstalpnid, + unsigned int srcport, + unsigned int dstport) +{ + struct altsvc *as = calloc(sizeof(struct altsvc), 1); + if(!as) + return NULL; + + as->srchost = strdup(srchost); + if(!as->srchost) + goto error; + as->dsthost = strdup(dsthost); + if(!as->dsthost) + goto error; + + as->srcalpnid = srcalpnid; + as->dstalpnid = dstalpnid; + as->srcport = curlx_ultous(srcport); + as->dstport = curlx_ultous(dstport); + + return as; + error: + altsvc_free(as); + return NULL; +} + +static struct altsvc *altsvc_create(char *srchost, + char *dsthost, + char *srcalpn, + char *dstalpn, + unsigned int srcport, + unsigned int dstport) +{ + enum alpnid dstalpnid = alpn2alpnid(dstalpn); + enum alpnid srcalpnid = alpn2alpnid(srcalpn); + if(!srcalpnid || !dstalpnid) + return NULL; + return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid, + srcport, dstport); +} + +/* only returns SERIOUS errors */ +static CURLcode altsvc_add(struct altsvcinfo *asi, char *line) +{ + /* Example line: + h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1 + */ + char srchost[MAX_ALTSVC_HOSTLEN + 1]; + char dsthost[MAX_ALTSVC_HOSTLEN + 1]; + char srcalpn[MAX_ALTSVC_ALPNLEN + 1]; + char dstalpn[MAX_ALTSVC_ALPNLEN + 1]; + char date[MAX_ALTSVC_DATELEN + 1]; + unsigned int srcport; + unsigned int dstport; + unsigned int prio; + unsigned int persist; + int rc; + + rc = sscanf(line, + "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u " + "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u " + "\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u", + srcalpn, srchost, &srcport, + dstalpn, dsthost, &dstport, + date, &persist, &prio); + if(9 == rc) { + struct altsvc *as; + time_t expires = curl_getdate(date, NULL); + as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport); + if(as) { + as->expires = expires; + as->prio = prio; + as->persist = persist ? 1 : 0; + Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node); + asi->num++; /* one more entry */ + } + } + + return CURLE_OK; +} + +/* + * Load alt-svc entries from the given file. The text based line-oriented file + * format is documented here: + * https://github.com/curl/curl/wiki/QUIC-implementation + * + * This function only returns error on major problems that prevents alt-svc + * handling to work completely. It will ignore individual syntactical errors + * etc. + */ +static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file) +{ + CURLcode result = CURLE_OK; + char *line = NULL; + FILE *fp = fopen(file, FOPEN_READTEXT); + if(fp) { + line = malloc(MAX_ALTSVC_LINE); + if(!line) + goto fail; + while(Curl_get_line(line, MAX_ALTSVC_LINE, fp)) { + char *lineptr = line; + while(*lineptr && ISBLANK(*lineptr)) + lineptr++; + if(*lineptr == '#') + /* skip commented lines */ + continue; + + altsvc_add(asi, lineptr); + } + free(line); /* free the line buffer */ + fclose(fp); + } + return result; + + fail: + free(line); + fclose(fp); + return CURLE_OUT_OF_MEMORY; +} + +/* + * Write this single altsvc entry to a single output line + */ + +static CURLcode altsvc_out(struct altsvc *as, FILE *fp) +{ + struct tm stamp; + CURLcode result = Curl_gmtime(as->expires, &stamp); + if(result) + return result; + + fprintf(fp, + "%s %s %u " + "%s %s %u " + "\"%d%02d%02d " + "%02d:%02d:%02d\" " + "%u %d\n", + Curl_alpnid2str(as->srcalpnid), as->srchost, as->srcport, + Curl_alpnid2str(as->dstalpnid), as->dsthost, as->dstport, + stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday, + stamp.tm_hour, stamp.tm_min, stamp.tm_sec, + as->persist, as->prio); + return CURLE_OK; +} + +/* ---- library-wide functions below ---- */ + +/* + * Curl_altsvc_init() creates a new altsvc cache. + * It returns the new instance or NULL if something goes wrong. + */ +struct altsvcinfo *Curl_altsvc_init(void) +{ + struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1); + if(!asi) + return NULL; + Curl_llist_init(&asi->list, NULL); + + /* set default behavior */ + asi->flags = CURLALTSVC_H1 +#ifdef USE_NGHTTP2 + | CURLALTSVC_H2 +#endif +#ifdef USE_HTTP3 + /* TODO: adjust when known */ + | CURLALTSVC_H3 +#endif + ; + return asi; +} + +/* + * Curl_altsvc_load() loads alt-svc from file. + */ +CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file) +{ + CURLcode result; + DEBUGASSERT(asi); + result = altsvc_load(asi, file); + return result; +} + +/* + * Curl_altsvc_ctrl() passes on the external bitmask. + */ +CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl) +{ + DEBUGASSERT(asi); + if(!ctrl) + /* unexpected */ + return CURLE_BAD_FUNCTION_ARGUMENT; + asi->flags = ctrl; + return CURLE_OK; +} + +/* + * Curl_altsvc_cleanup() frees an altsvc cache instance and all associated + * resources. + */ +void Curl_altsvc_cleanup(struct altsvcinfo *altsvc) +{ + struct curl_llist_element *e; + struct curl_llist_element *n; + if(altsvc) { + for(e = altsvc->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + altsvc_free(as); + } + free(altsvc); + } +} + +/* + * Curl_altsvc_save() writes the altsvc cache to a file. + */ +CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file) +{ + struct curl_llist_element *e; + struct curl_llist_element *n; + CURLcode result = CURLE_OK; + FILE *out; + + if(!altsvc) + /* no cache activated */ + return CURLE_OK; + + if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file[0]) + /* marked as read-only or zero length file name */ + return CURLE_OK; + out = fopen(file, FOPEN_WRITETEXT); + if(!out) + return CURLE_WRITE_ERROR; + fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n" + "# This file was generated by libcurl! Edit at your own risk.\n", + out); + for(e = altsvc->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + result = altsvc_out(as, out); + if(result) + break; + } + fclose(out); + return result; +} + +static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen) +{ + size_t len; + const char *protop; + const char *p = *ptr; + while(*p && ISBLANK(*p)) + p++; + protop = p; + while(*p && ISALNUM(*p)) + p++; + len = p - protop; + + if(!len || (len >= buflen)) + return CURLE_BAD_FUNCTION_ARGUMENT; /* TODO: improve error code */ + memcpy(alpnbuf, protop, len); + alpnbuf[len] = 0; + *ptr = p; + return CURLE_OK; +} + +/* altsvc_flush() removes all alternatives for this source origin from the + list */ +static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid, + const char *srchost, unsigned short srcport) +{ + struct curl_llist_element *e; + struct curl_llist_element *n; + for(e = asi->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + if((srcalpnid == as->srcalpnid) && + (srcport == as->srcport) && + strcasecompare(srchost, as->srchost)) { + Curl_llist_remove(&asi->list, e, NULL); + altsvc_free(as); + asi->num--; + } + } +} + +#ifdef DEBUGBUILD +/* to play well with debug builds, we can *set* a fixed time this will + return */ +static time_t debugtime(void *unused) +{ + char *timestr = getenv("CURL_TIME"); + (void)unused; + if(timestr) { + unsigned long val = strtol(timestr, NULL, 10); + return (time_t)val; + } + return time(NULL); +} +#define time(x) debugtime(x) +#endif + +/* + * Curl_altsvc_parse() takes an incoming alt-svc response header and stores + * the data correctly in the cache. + * + * 'value' points to the header *value*. That's contents to the right of the + * header name. + */ +CURLcode Curl_altsvc_parse(struct Curl_easy *data, + struct altsvcinfo *asi, const char *value, + enum alpnid srcalpnid, const char *srchost, + unsigned short srcport) +{ + const char *p = value; + size_t len; + enum alpnid dstalpnid = srcalpnid; /* the same by default */ + char namebuf[MAX_ALTSVC_HOSTLEN] = ""; + char alpnbuf[MAX_ALTSVC_ALPNLEN] = ""; + struct altsvc *as; + unsigned short dstport = srcport; /* the same by default */ + const char *semip; + time_t maxage = 24 * 3600; /* default is 24 hours */ + bool persist = FALSE; + CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf)); + if(result) + return result; + + DEBUGASSERT(asi); + + /* Flush all cached alternatives for this source origin, if any */ + altsvc_flush(asi, srcalpnid, srchost, srcport); + + /* "clear" is a magic keyword */ + if(strcasecompare(alpnbuf, "clear")) { + /* TODO: clear whatever it is it should clear */ + return CURLE_OK; + } + + /* The 'ma' and 'persist' flags are annoyingly meant for all alternatives + but are set after the list on the line. Scan for the semicolons and get + those fields first! */ + semip = p; + do { + semip = strchr(semip, ';'); + if(semip) { + char option[32]; + unsigned long num; + char *end_ptr; + semip++; /* pass the semicolon */ + result = getalnum(&semip, option, sizeof(option)); + if(result) + break; + while(*semip && ISBLANK(*semip)) + semip++; + if(*semip != '=') + continue; + semip++; + num = strtoul(semip, &end_ptr, 10); + if(num < ULONG_MAX) { + if(strcasecompare("ma", option)) + maxage = num; + else if(strcasecompare("persist", option) && (num == 1)) + persist = TRUE; + } + semip = end_ptr; + } + } while(semip); + + do { + if(*p == '=') { + /* [protocol]="[host][:port]" */ + dstalpnid = alpn2alpnid(alpnbuf); + if(!dstalpnid) { + infof(data, "Unknown alt-svc protocol \"%s\", ignoring...\n", alpnbuf); + return CURLE_OK; + } + p++; + if(*p == '\"') { + const char *dsthost; + p++; + if(*p != ':') { + /* host name starts here */ + const char *hostp = p; + while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-'))) + p++; + len = p - hostp; + if(!len || (len >= MAX_ALTSVC_HOSTLEN)) + return CURLE_BAD_FUNCTION_ARGUMENT; /* TODO: improve error code */ + memcpy(namebuf, hostp, len); + namebuf[len] = 0; + dsthost = namebuf; + } + else { + /* no destination name, use source host */ + dsthost = srchost; + } + if(*p == ':') { + /* a port number */ + char *end_ptr; + 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"); + return CURLE_OK; + } + p = end_ptr; + dstport = curlx_ultous(port); + } + if(*p++ != '\"') + return CURLE_BAD_FUNCTION_ARGUMENT; + as = altsvc_createid(srchost, dsthost, + srcalpnid, dstalpnid, + srcport, dstport); + if(as) { + /* TODO: the expires time also needs to take the Age: value (if any) + into account. [See RFC 7838 section 3.1] */ + as->expires = maxage + time(NULL); + as->persist = persist; + Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node); + asi->num++; /* one more entry */ + infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport, + Curl_alpnid2str(dstalpnid)); + } + } + /* after the double quote there can be a comma if there's another + string or a semicolon if no more */ + if(*p == ',') { + /* comma means another alternative is presented */ + p++; + result = getalnum(&p, alpnbuf, sizeof(alpnbuf)); + if(result) + /* failed to parse, but since we already did at least one host we + return OK */ + return CURLE_OK; + } + } + } while(*p && (*p != ';') && (*p != '\n') && (*p != '\r')); + + return CURLE_OK; +} + +/* + * Return TRUE on a match + */ +bool Curl_altsvc_lookup(struct altsvcinfo *asi, + enum alpnid srcalpnid, const char *srchost, + int srcport, + enum alpnid *dstalpnid, const char **dsthost, + int *dstport) +{ + struct curl_llist_element *e; + struct curl_llist_element *n; + time_t now = time(NULL); + DEBUGASSERT(asi); + DEBUGASSERT(srchost); + DEBUGASSERT(dsthost); + + for(e = asi->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + if(as->expires < now) { + /* an expired entry, remove */ + altsvc_free(as); + continue; + } + if((as->srcalpnid == srcalpnid) && + strcasecompare(as->srchost, srchost) && + as->srcport == srcport) { + /* match */ + *dstalpnid = as->dstalpnid; + *dsthost = as->dsthost; + *dstport = as->dstport; + return TRUE; + } + } + return FALSE; +} + +#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */ diff --git a/libs/libcurl/src/altsvc.h b/libs/libcurl/src/altsvc.h new file mode 100644 index 0000000000..eefb45bf61 --- /dev/null +++ b/libs/libcurl/src/altsvc.h @@ -0,0 +1,77 @@ +#ifndef HEADER_CURL_ALTSVC_H +#define HEADER_CURL_ALTSVC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC) +#include <curl/curl.h> +#include "llist.h" + +enum alpnid { + ALPN_none, + ALPN_h1, + ALPN_h2, + ALPN_h2c, + ALPN_h3 +}; + +struct altsvc { + char *srchost; + char *dsthost; + unsigned short srcport; + unsigned short dstport; + enum alpnid srcalpnid; + enum alpnid dstalpnid; + time_t expires; + bool persist; + int prio; + struct curl_llist_element node; +}; + +struct altsvcinfo { + char *filename; + struct curl_llist list; /* list of entries */ + size_t num; /* number of alt-svc entries */ + long flags; /* the publicly set bitmask */ +}; + +const char *Curl_alpnid2str(enum alpnid id); +struct altsvcinfo *Curl_altsvc_init(void); +CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file); +CURLcode Curl_altsvc_save(struct altsvcinfo *asi, const char *file); +CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl); +void Curl_altsvc_cleanup(struct altsvcinfo *altsvc); +CURLcode Curl_altsvc_parse(struct Curl_easy *data, + struct altsvcinfo *altsvc, const char *value, + enum alpnid srcalpn, const char *srchost, + unsigned short srcport); +bool Curl_altsvc_lookup(struct altsvcinfo *asi, + enum alpnid srcalpnid, const char *srchost, + int srcport, + enum alpnid *dstalpnid, const char **dsthost, + int *dstport); +#else +/* disabled */ +#define Curl_altsvc_save(a,b) +#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */ +#endif /* HEADER_CURL_ALTSVC_H */ diff --git a/libs/libcurl/src/amigaos.c b/libs/libcurl/src/amigaos.c index 4f55b30e76..cf44bdc8d1 100644 --- a/libs/libcurl/src/amigaos.c +++ b/libs/libcurl/src/amigaos.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -22,17 +22,26 @@ #include "curl_setup.h" -#if defined(__AMIGA__) && !defined(__ixemul__) - -#include <amitcp/socketbasetags.h> +#ifdef __AMIGA__ +# include "amigaos.h" +# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) +# include <amitcp/socketbasetags.h> +# endif +# ifdef __libnix__ +# include <stabs.h> +# endif +#endif -#include "amigaos.h" +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" +#ifdef __AMIGA__ +#if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) struct Library *SocketBase = NULL; extern int errno, h_errno; #ifdef __libnix__ -#include <stabs.h> void __request(const char *msg); #else # define __request(msg) Printf(msg "\n\a") @@ -74,4 +83,13 @@ bool Curl_amiga_init() ADD2EXIT(Curl_amiga_cleanup, -50); #endif -#endif /* __AMIGA__ && ! __ixemul__ */ +#endif /* HAVE_PROTO_BSDSOCKET_H */ + +#ifdef USE_AMISSL +void Curl_amiga_X509_free(X509 *a) +{ + X509_free(a); +} +#endif /* USE_AMISSL */ +#endif /* __AMIGA__ */ + diff --git a/libs/libcurl/src/amigaos.h b/libs/libcurl/src/amigaos.h index 7c0926cc35..c776c9c9bb 100644 --- a/libs/libcurl/src/amigaos.h +++ b/libs/libcurl/src/amigaos.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -23,7 +23,7 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(__AMIGA__) && !defined(__ixemul__) +#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL) bool Curl_amiga_init(); void Curl_amiga_cleanup(); @@ -35,4 +35,10 @@ void Curl_amiga_cleanup(); #endif +#ifdef USE_AMISSL +#include <openssl/x509v3.h> +void Curl_amiga_X509_free(X509 *a); +#endif /* USE_AMISSL */ + #endif /* HEADER_CURL_AMIGAOS_H */ + diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c index a9679d062e..55e0811c5c 100644 --- a/libs/libcurl/src/asyn-thread.c +++ b/libs/libcurl/src/asyn-thread.c @@ -461,6 +461,42 @@ static CURLcode resolver_error(struct connectdata *conn) return result; } +static CURLcode thread_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **entry, + bool report) +{ + struct thread_data *td = (struct thread_data*) conn->async.os_specific; + CURLcode result = CURLE_OK; + + DEBUGASSERT(conn && td); + DEBUGASSERT(td->thread_hnd != curl_thread_t_null); + + /* wait for the thread to resolve the name */ + if(Curl_thread_join(&td->thread_hnd)) { + if(entry) + result = getaddrinfo_complete(conn); + } + else + DEBUGASSERT(0); + + conn->async.done = TRUE; + + if(entry) + *entry = conn->async.dns; + + if(!conn->async.dns && report) + /* a name was not resolved, report error */ + result = resolver_error(conn); + + destroy_async_data(&conn->async); + + if(!conn->async.dns && report) + connclose(conn, "asynch resolve failed"); + + return result; +} + + /* * Until we gain a way to signal the resolver threads to stop early, we must * simply wait for them and ignore their results. @@ -473,7 +509,7 @@ void Curl_resolver_kill(struct connectdata *conn) unfortunately. Otherwise, we can simply cancel to clean up any resolver data. */ if(td && td->thread_hnd != curl_thread_t_null) - (void)Curl_resolver_wait_resolv(conn, NULL); + (void)thread_wait_resolv(conn, NULL, FALSE); else Curl_resolver_cancel(conn); } @@ -494,35 +530,7 @@ void Curl_resolver_kill(struct connectdata *conn) CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, struct Curl_dns_entry **entry) { - struct thread_data *td = (struct thread_data*) conn->async.os_specific; - CURLcode result = CURLE_OK; - - DEBUGASSERT(conn && td); - DEBUGASSERT(td->thread_hnd != curl_thread_t_null); - - /* wait for the thread to resolve the name */ - if(Curl_thread_join(&td->thread_hnd)) { - if(entry) - result = getaddrinfo_complete(conn); - } - else - DEBUGASSERT(0); - - conn->async.done = TRUE; - - if(entry) - *entry = conn->async.dns; - - if(!conn->async.dns) - /* a name was not resolved, report error */ - result = resolver_error(conn); - - destroy_async_data(&conn->async); - - if(!conn->async.dns) - connclose(conn, "asynch resolve failed"); - - return result; + return thread_wait_resolv(conn, entry, TRUE); } /* diff --git a/libs/libcurl/src/config-os400.h b/libs/libcurl/src/config-os400.h index 7844444feb..bde4f0b331 100644 --- a/libs/libcurl/src/config-os400.h +++ b/libs/libcurl/src/config-os400.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -425,6 +425,9 @@ /* Define if you can safely include both <sys/time.h> and <time.h>. */ #define TIME_WITH_SYS_TIME +/* Define to enable alt-svc support (experimental) */ +#undef USE_ALTSVC + /* Version number of package */ #undef VERSION diff --git a/libs/libcurl/src/config-vxworks.h b/libs/libcurl/src/config-vxworks.h index a03e341e62..8790f82669 100644 --- a/libs/libcurl/src/config-vxworks.h +++ b/libs/libcurl/src/config-vxworks.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -161,9 +161,6 @@ /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 -/* Define to 1 if you have the fdopen function. */ -#define HAVE_FDOPEN 1 - /* Define to 1 if you have the `fork' function. */ #define HAVE_FORK 1 diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index 76ff0d931e..76b00b9bbf 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -240,10 +240,6 @@ /* Define if you have the socket function. */ #define HAVE_SOCKET 1 -/* if libSSH2 is in use */ -#define USE_LIBSSH2 1 -#define HAVE_LIBSSH2_H 1 - /* Define if you have the strcasecmp function. */ /* #define HAVE_STRCASECMP 1 */ @@ -713,9 +709,6 @@ Vista /* Define to use the Windows crypto library. */ #define USE_WIN32_CRYPTO -/* if SSL is enabled */ -#define USE_OPENSSL 1 - /* Define to use Unix sockets. */ #if defined(_MSC_VER) && _MSC_VER >= 1900 /* #define USE_UNIX_SOCKETS */ diff --git a/libs/libcurl/src/conncache.c b/libs/libcurl/src/conncache.c index 78ad386c35..39302ba7ba 100644 --- a/libs/libcurl/src/conncache.c +++ b/libs/libcurl/src/conncache.c @@ -392,8 +392,8 @@ bool Curl_conncache_foreach(struct Curl_easy *data, NOTE: no locking is done here as this is presumably only done when cleaning up a cache! */ -struct connectdata * -Curl_conncache_find_first_connection(struct conncache *connc) +static struct connectdata * +conncache_find_first_connection(struct conncache *connc) { struct curl_hash_iterator iter; struct curl_hash_element *he; @@ -433,6 +433,7 @@ bool Curl_conncache_return_conn(struct connectdata *conn) data->multi->maxconnects; struct connectdata *conn_candidate = NULL; + conn->data = NULL; /* no owner anymore */ if(maxconnects > 0 && Curl_conncache_size(data) > maxconnects) { infof(data, "Connection cache is full, closing the oldest one.\n"); @@ -476,7 +477,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data, while(curr) { conn = curr->ptr; - if(!CONN_INUSE(conn)) { + if(!CONN_INUSE(conn) && !conn->data) { /* Set higher score for the age passed since the connection was used */ score = Curl_timediff(now, conn->now); @@ -534,7 +535,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data) while(curr) { conn = curr->ptr; - if(!CONN_INUSE(conn)) { + if(!CONN_INUSE(conn) && !conn->data) { /* Set higher score for the age passed since the connection was used */ score = Curl_timediff(now, conn->now); @@ -566,7 +567,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc) { struct connectdata *conn; - conn = Curl_conncache_find_first_connection(connc); + conn = conncache_find_first_connection(connc); while(conn) { SIGPIPE_VARIABLE(pipe_st); conn->data = connc->closure_handle; @@ -577,7 +578,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc) (void)Curl_disconnect(connc->closure_handle, conn, FALSE); sigpipe_restore(&pipe_st); - conn = Curl_conncache_find_first_connection(connc); + conn = conncache_find_first_connection(connc); } if(connc->closure_handle) { diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index ec3cd3a795..a53d79c214 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -446,9 +446,10 @@ static CURLcode bindlocal(struct connectdata *conn, curl_socklen_t size = sizeof(add); memset(&add, 0, sizeof(struct Curl_sockaddr_storage)); if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) { + char buffer[STRERROR_LEN]; data->state.os_errno = error = SOCKERRNO; failf(data, "getsockname() failed with errno %d: %s", - error, Curl_strerror(conn, error)); + error, Curl_strerror(error, buffer, sizeof(buffer))); return CURLE_INTERFACE_FAILED; } infof(data, "Local port: %hu\n", port); @@ -470,10 +471,12 @@ static CURLcode bindlocal(struct connectdata *conn, else break; } - - data->state.os_errno = error = SOCKERRNO; - failf(data, "bind failed with errno %d: %s", - error, Curl_strerror(conn, error)); + { + char buffer[STRERROR_LEN]; + data->state.os_errno = error = SOCKERRNO; + failf(data, "bind failed with errno %d: %s", + error, Curl_strerror(error, buffer, sizeof(buffer))); + } return CURLE_INTERFACE_FAILED; } @@ -617,10 +620,13 @@ void Curl_persistconninfo(struct connectdata *conn) conn->data->info.conn_local_port = conn->local_port; } +UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr, + long *port); + /* retrieves ip address and port from a sockaddr structure. note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ -bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, - long *port) +UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr, + long *port) { unsigned short us_port; struct sockaddr_in *si = NULL; @@ -683,11 +689,12 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) return; if(!conn->bits.reuse && !conn->bits.tcp_fastopen) { + char buffer[STRERROR_LEN]; len = sizeof(struct Curl_sockaddr_storage); if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) { int error = SOCKERRNO; failf(data, "getpeername() failed with errno %d: %s", - error, Curl_strerror(conn, error)); + error, Curl_strerror(error, buffer, sizeof(buffer))); return; } @@ -696,22 +703,22 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) { int error = SOCKERRNO; failf(data, "getsockname() failed with errno %d: %s", - error, Curl_strerror(conn, error)); + error, Curl_strerror(error, buffer, sizeof(buffer))); return; } - if(!Curl_getaddressinfo((struct sockaddr*)&ssrem, - conn->primary_ip, &conn->primary_port)) { + if(!getaddressinfo((struct sockaddr*)&ssrem, + conn->primary_ip, &conn->primary_port)) { failf(data, "ssrem inet_ntop() failed with errno %d: %s", - errno, Curl_strerror(conn, errno)); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); return; } memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); - if(!Curl_getaddressinfo((struct sockaddr*)&ssloc, - conn->local_ip, &conn->local_port)) { + if(!getaddressinfo((struct sockaddr*)&ssloc, + conn->local_ip, &conn->local_port)) { failf(data, "ssloc inet_ntop() failed with errno %d: %s", - errno, Curl_strerror(conn, errno)); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); return; } @@ -836,9 +843,11 @@ CURLcode Curl_is_connected(struct connectdata *conn, if(conn->tempaddr[i]) { CURLcode status; char ipaddress[MAX_IPADR_LEN]; + char buffer[STRERROR_LEN]; Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN); infof(data, "connect to %s port %ld failed: %s\n", - ipaddress, conn->port, Curl_strerror(conn, error)); + ipaddress, conn->port, + Curl_strerror(error, buffer, sizeof(buffer))); conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ? allow : allow / 2; @@ -854,8 +863,8 @@ CURLcode Curl_is_connected(struct connectdata *conn, if(result) { /* no more addresses to try */ - const char *hostname; + char buffer[STRERROR_LEN]; /* if the first address family runs out of addresses to try before the happy eyeball timeout, go ahead and try the next family now */ @@ -875,13 +884,14 @@ CURLcode Curl_is_connected(struct connectdata *conn, hostname = conn->host.name; failf(data, "Failed to connect to %s port %ld: %s", - hostname, conn->port, Curl_strerror(conn, error)); + hostname, conn->port, + Curl_strerror(error, buffer, sizeof(buffer))); } return result; } -void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) +static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) { #if defined(TCP_NODELAY) #if !defined(CURL_DISABLE_VERBOSE_STRINGS) @@ -889,6 +899,7 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) #endif curl_socklen_t onoff = (curl_socklen_t) 1; int level = IPPROTO_TCP; + char buffer[STRERROR_LEN]; #if defined(CURL_DISABLE_VERBOSE_STRINGS) (void) conn; @@ -897,7 +908,7 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff, sizeof(onoff)) < 0) infof(data, "Could not set TCP_NODELAY: %s\n", - Curl_strerror(conn, SOCKERRNO)); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); else infof(data, "TCP_NODELAY set\n"); #else @@ -917,9 +928,11 @@ static void nosigpipe(struct connectdata *conn, struct Curl_easy *data = conn->data; int onoff = 1; if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff, - sizeof(onoff)) < 0) + sizeof(onoff)) < 0) { + char buffer[STRERROR_LEN]; infof(data, "Could not set SO_NOSIGPIPE: %s\n", - Curl_strerror(conn, SOCKERRNO)); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + } } #else #define nosigpipe(x,y) Curl_nop_stmt @@ -995,6 +1008,7 @@ static CURLcode singleipconnect(struct connectdata *conn, #ifdef TCP_FASTOPEN_CONNECT int optval = 1; #endif + char buffer[STRERROR_LEN]; *sockp = CURL_SOCKET_BAD; @@ -1006,11 +1020,11 @@ static CURLcode singleipconnect(struct connectdata *conn, return CURLE_OK; /* store remote address and port used in this connection attempt */ - if(!Curl_getaddressinfo((struct sockaddr*)&addr.sa_addr, - ipaddress, &port)) { + if(!getaddressinfo((struct sockaddr*)&addr.sa_addr, + ipaddress, &port)) { /* malformed address or bug in inet_ntop, try next address */ failf(data, "sa_addr inet_ntop() failed with errno %d: %s", - errno, Curl_strerror(conn, errno)); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); Curl_closesocket(conn, sockfd); return CURLE_OK; } @@ -1023,7 +1037,7 @@ static CURLcode singleipconnect(struct connectdata *conn, is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM; #endif if(is_tcp && data->set.tcp_nodelay) - Curl_tcpnodelay(conn, sockfd); + tcpnodelay(conn, sockfd); nosigpipe(conn, sockfd); @@ -1146,7 +1160,7 @@ static CURLcode singleipconnect(struct connectdata *conn, default: /* unknown error, fallthrough and try another address! */ infof(data, "Immediate connect fail for %s: %s\n", - ipaddress, Curl_strerror(conn, error)); + ipaddress, Curl_strerror(error, buffer, sizeof(buffer))); data->state.os_errno = error; /* connect failed */ @@ -1420,7 +1434,7 @@ void Curl_conncontrol(struct connectdata *conn, if((ctrl == CONNCTRL_STREAM) && (conn->handler->flags & PROTOPT_STREAM)) DEBUGF(infof(conn->data, "Kill stream: %s\n", reason)); - else if(closeit != conn->bits.close) { + else if((bit)closeit != conn->bits.close) { DEBUGF(infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive", reason)); conn->bits.close = closeit; /* the only place in the source code that diff --git a/libs/libcurl/src/connect.h b/libs/libcurl/src/connect.h index 193dc63978..6a5c755cc1 100644 --- a/libs/libcurl/src/connect.h +++ b/libs/libcurl/src/connect.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -76,11 +76,6 @@ void Curl_persistconninfo(struct connectdata *conn); int Curl_closesocket(struct connectdata *conn, curl_socket_t sock); /* - * Get presentation format IP address and port from a sockaddr. - */ -bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, long *port); - -/* * The Curl_sockaddr_ex structure is basically libcurl's external API * curl_sockaddr structure with enough space available to directly hold any * protocol-specific address structures. The variable declared here will be @@ -111,8 +106,6 @@ CURLcode Curl_socket(struct connectdata *conn, struct Curl_sockaddr_ex *addr, curl_socket_t *sockfd); -void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd); - /* * Curl_conncontrol() marks the end of a connection/stream. The 'closeit' * argument specifies if it is the end of a connection or a stream. diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c index 4fb992ac9d..44851a52f5 100644 --- a/libs/libcurl/src/cookie.c +++ b/libs/libcurl/src/cookie.c @@ -528,6 +528,19 @@ Curl_cookie_add(struct Curl_easy *data, while(*whatptr && ISBLANK(*whatptr)) whatptr++; + /* + * Check if we have a reserved prefix set before anything else, as we + * otherwise have to test for the prefix in both the cookie name and + * "the rest". Prefixes must start with '__' and end with a '-', so + * only test for names where that can possibly be true. + */ + if(nlen > 3 && name[0] == '_' && name[1] == '_') { + if(strncasecompare("__Secure-", name, 9)) + co->prefix |= COOKIE_PREFIX__SECURE; + else if(strncasecompare("__Host-", name, 7)) + co->prefix |= COOKIE_PREFIX__HOST; + } + if(!co->name) { /* The very first name/value pair is the actual cookie name */ if(!sep) { @@ -803,8 +816,6 @@ Curl_cookie_add(struct Curl_easy *data, co->domain = strdup(ptr); if(!co->domain) badcookie = TRUE; - else if(bad_domain(co->domain)) - badcookie = TRUE; break; case 1: /* This field got its explanation on the 23rd of May 2001 by @@ -862,6 +873,11 @@ Curl_cookie_add(struct Curl_easy *data, co->name = strdup(ptr); if(!co->name) badcookie = TRUE; + /* For Netscape file format cookies we check prefix on the name */ + if(strncasecompare("__Secure-", co->name, 9)) + co->prefix |= COOKIE_PREFIX__SECURE; + else if(strncasecompare("__Host-", co->name, 7)) + co->prefix |= COOKIE_PREFIX__HOST; break; case 6: co->value = strdup(ptr); @@ -890,6 +906,26 @@ Curl_cookie_add(struct Curl_easy *data, } + if(co->prefix & COOKIE_PREFIX__SECURE) { + /* The __Secure- prefix only requires that the cookie be set secure */ + if(!co->secure) { + freecookie(co); + return NULL; + } + } + if(co->prefix & COOKIE_PREFIX__HOST) { + /* + * The __Host- prefix requires the cookie to be secure, have a "/" path + * and not have a domain set. + */ + if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch) + ; + else { + freecookie(co); + return NULL; + } + } + if(!c->running && /* read from a file */ c->newsession && /* clean session cookies */ !co->expires) { /* this is a session cookie since it doesn't expire! */ @@ -908,20 +944,18 @@ Curl_cookie_add(struct Curl_easy *data, if(!noexpire) remove_expired(c); - if(domain && co->domain && !isip(co->domain)) { - int acceptable; #ifdef USE_LIBPSL + /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */ + if(domain && co->domain && !isip(co->domain)) { const psl_ctx_t *psl = Curl_psl_use(data); + int acceptable; - /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */ if(psl) { acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain); Curl_psl_release(data); } else -#endif - /* Without libpsl, do the best we can. */ - acceptable = !bad_domain(co->domain); + acceptable = !bad_domain(domain); if(!acceptable) { infof(data, "cookie '%s' dropped, domain '%s' must not " @@ -930,6 +964,7 @@ Curl_cookie_add(struct Curl_easy *data, return NULL; } } +#endif myhash = cookiehash(co->domain); clist = c->cookies[myhash]; @@ -1054,7 +1089,7 @@ Curl_cookie_add(struct Curl_easy *data, * get_line() makes sure to only return complete whole lines that fit in 'len' * bytes and end with a newline. */ -static char *get_line(char *buf, int len, FILE *input) +char *Curl_get_line(char *buf, int len, FILE *input) { bool partial = FALSE; while(1) { @@ -1134,7 +1169,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, line = malloc(MAX_COOKIE_LINE); if(!line) goto fail; - while(get_line(line, MAX_COOKIE_LINE, fp)) { + while(Curl_get_line(line, MAX_COOKIE_LINE, fp)) { if(checkprefix("Set-Cookie:", line)) { /* This is a cookie line, get it! */ lineptr = &line[11]; @@ -1503,6 +1538,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) unsigned int j; struct Cookie **array; + if(!c) + /* no cookie engine alive */ + return 0; + /* at first, remove expired cookies */ remove_expired(c); diff --git a/libs/libcurl/src/cookie.h b/libs/libcurl/src/cookie.h index 3ee457c622..6ac4a6ac09 100644 --- a/libs/libcurl/src/cookie.h +++ b/libs/libcurl/src/cookie.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -44,8 +44,16 @@ struct Cookie { bool livecookie; /* updated from a server, not a stored file */ bool httponly; /* true if the httponly directive is present */ int creationtime; /* time when the cookie was written */ + unsigned char prefix; /* bitmap fields indicating which prefix are set */ }; +/* + * Available cookie prefixes, as defined in + * draft-ietf-httpbis-rfc6265bis-02 + */ +#define COOKIE_PREFIX__SECURE (1<<0) +#define COOKIE_PREFIX__HOST (1<<1) + #define COOKIE_HASH_SIZE 256 struct CookieInfo { @@ -93,6 +101,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *, void Curl_cookie_freelist(struct Cookie *cookies); void Curl_cookie_clearall(struct CookieInfo *cookies); void Curl_cookie_clearsess(struct CookieInfo *cookies); +char *Curl_get_line(char *buf, int len, FILE *input); #if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES) #define Curl_cookie_list(x) NULL diff --git a/libs/libcurl/src/curl_addrinfo.c b/libs/libcurl/src/curl_addrinfo.c index fd49679c93..16c4779c1e 100644 --- a/libs/libcurl/src/curl_addrinfo.c +++ b/libs/libcurl/src/curl_addrinfo.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -539,7 +539,7 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract) #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \ defined(HAVE_FREEADDRINFO) /* - * curl_dofreeaddrinfo() + * curl_dbg_freeaddrinfo() * * This is strictly for memory tracing and are using the same style as the * family otherwise present in memdebug.c. I put these ones here since they @@ -547,23 +547,23 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract) */ void -curl_dofreeaddrinfo(struct addrinfo *freethis, - int line, const char *source) +curl_dbg_freeaddrinfo(struct addrinfo *freethis, + int line, const char *source) { + curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n", + source, line, (void *)freethis); #ifdef USE_LWIPSOCK lwip_freeaddrinfo(freethis); #else (freeaddrinfo)(freethis); #endif - curl_memlog("ADDR %s:%d freeaddrinfo(%p)\n", - source, line, (void *)freethis); } #endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */ #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) /* - * curl_dogetaddrinfo() + * curl_dbg_getaddrinfo() * * This is strictly for memory tracing and are using the same style as the * family otherwise present in memdebug.c. I put these ones here since they @@ -571,11 +571,11 @@ curl_dofreeaddrinfo(struct addrinfo *freethis, */ int -curl_dogetaddrinfo(const char *hostname, - const char *service, - const struct addrinfo *hints, - struct addrinfo **result, - int line, const char *source) +curl_dbg_getaddrinfo(const char *hostname, + const char *service, + const struct addrinfo *hints, + struct addrinfo **result, + int line, const char *source) { #ifdef USE_LWIPSOCK int res = lwip_getaddrinfo(hostname, service, hints, result); @@ -584,11 +584,11 @@ curl_dogetaddrinfo(const char *hostname, #endif if(0 == res) /* success */ - curl_memlog("ADDR %s:%d getaddrinfo() = %p\n", - source, line, (void *)*result); + curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n", + source, line, (void *)*result); else - curl_memlog("ADDR %s:%d getaddrinfo() failed\n", - source, line); + curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n", + source, line); return res; } #endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */ diff --git a/libs/libcurl/src/curl_addrinfo.h b/libs/libcurl/src/curl_addrinfo.h index 8f6f3d1064..205e121ea6 100644 --- a/libs/libcurl/src/curl_addrinfo.h +++ b/libs/libcurl/src/curl_addrinfo.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -86,17 +86,14 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract); #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \ defined(HAVE_FREEADDRINFO) void -curl_dofreeaddrinfo(struct addrinfo *freethis, - int line, const char *source); +curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source); #endif #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) int -curl_dogetaddrinfo(const char *hostname, - const char *service, - const struct addrinfo *hints, - struct addrinfo **result, - int line, const char *source); +curl_dbg_getaddrinfo(const char *hostname, const char *service, + const struct addrinfo *hints, struct addrinfo **result, + int line, const char *source); #endif #ifdef HAVE_GETADDRINFO diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in index 7ab164b7b0..04ed02a566 100644 --- a/libs/libcurl/src/curl_config.h.in +++ b/libs/libcurl/src/curl_config.h.in @@ -190,9 +190,6 @@ /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #undef HAVE_FCNTL_O_NONBLOCK -/* Define to 1 if you have the fdopen function. */ -#undef HAVE_FDOPEN - /* Define to 1 if you have the `fnmatch' function. */ #undef HAVE_FNMATCH @@ -526,6 +523,9 @@ /* Define to 1 if you have a working POSIX-style strerror_r function. */ #undef HAVE_POSIX_STRERROR_R +/* Define to 1 if you have the <proto/bsdsocket.h> header file. */ +#undef HAVE_PROTO_BSDSOCKET_H + /* if you have <pthread.h> */ #undef HAVE_PTHREAD_H @@ -616,9 +616,6 @@ /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H -/* Define to 1 if you have the <stdio.h> header file. */ -#undef HAVE_STDIO_H - /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H @@ -766,9 +763,6 @@ /* Define to 1 if you have the `wolfSSLv3_client_method' function. */ #undef HAVE_WOLFSSLV3_CLIENT_METHOD -/* Define to 1 if you have the `wolfSSL_CTX_UseSupportedCurve' function. */ -#undef HAVE_WOLFSSL_CTX_USESUPPORTEDCURVE - /* Define to 1 if you have the `wolfSSL_get_peer_certificate' function. */ #undef HAVE_WOLFSSL_GET_PEER_CERTIFICATE @@ -925,15 +919,18 @@ /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ #undef TIME_WITH_SYS_TIME +/* to enable alt-svc */ +#undef USE_ALTSVC + +/* if AmiSSL is in use */ +#undef USE_AMISSL + /* Define to enable c-ares support */ #undef USE_ARES /* if CyaSSL/WolfSSL is enabled */ #undef USE_CYASSL -/* to enable Apple OS native SSL/TLS support */ -#undef USE_DARWINSSL - /* if GnuTLS is enabled */ #undef USE_GNUTLS @@ -982,6 +979,9 @@ /* to enable Windows native SSL/TLS support */ #undef USE_SCHANNEL +/* enable Secure Transport */ +#undef USE_SECTRANSP + /* if you want POSIX threaded DNS lookup */ #undef USE_THREADS_POSIX diff --git a/libs/libcurl/src/curl_endian.c b/libs/libcurl/src/curl_endian.c index c25db4956e..b7563b3ded 100644 --- a/libs/libcurl/src/curl_endian.c +++ b/libs/libcurl/src/curl_endian.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -82,7 +82,7 @@ unsigned short Curl_read16_be(const unsigned char *buf) } /* - * Curl_write32_le() + * write32_le() * * This function converts a 32-bit integer from the native endian format, * to little endian format ready for sending down the wire. @@ -92,7 +92,7 @@ unsigned short Curl_read16_be(const unsigned char *buf) * value [in] - The 32-bit integer value. * buffer [in] - A pointer to the output buffer. */ -void Curl_write32_le(const int value, unsigned char *buffer) +static void write32_le(const int value, unsigned char *buffer) { buffer[0] = (char)(value & 0x000000FF); buffer[1] = (char)((value & 0x0000FF00) >> 8); @@ -118,7 +118,7 @@ void Curl_write64_le(const long long value, unsigned char *buffer) void Curl_write64_le(const __int64 value, unsigned char *buffer) #endif { - Curl_write32_le((int)value, buffer); - Curl_write32_le((int)(value >> 32), buffer + 4); + write32_le((int)value, buffer); + write32_le((int)(value >> 32), buffer + 4); } #endif /* CURL_SIZEOF_CURL_OFF_T > 4 */ diff --git a/libs/libcurl/src/curl_fnmatch.c b/libs/libcurl/src/curl_fnmatch.c index fbfd85c438..846ecaec3a 100644 --- a/libs/libcurl/src/curl_fnmatch.c +++ b/libs/libcurl/src/curl_fnmatch.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -21,7 +21,7 @@ ***************************************************************************/ #include "curl_setup.h" - +#ifndef CURL_DISABLE_FTP #include <curl/curl.h> #include "curl_fnmatch.h" @@ -394,3 +394,5 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string) } #endif + +#endif /* if FTP is disabled */ diff --git a/libs/libcurl/src/curl_gssapi.h b/libs/libcurl/src/curl_gssapi.h index 9700a28174..88f68dbbbe 100644 --- a/libs/libcurl/src/curl_gssapi.h +++ b/libs/libcurl/src/curl_gssapi.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2011 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,19 +26,6 @@ #include "urldata.h" #ifdef HAVE_GSSAPI - -#ifdef HAVE_GSSGNU -# include <gss.h> -#elif defined HAVE_GSSMIT - /* MIT style */ -# include <gssapi/gssapi.h> -# include <gssapi/gssapi_generic.h> -# include <gssapi/gssapi_krb5.h> -#else - /* Heimdal-style */ -# include <gssapi.h> -#endif - extern gss_OID_desc Curl_spnego_mech_oid; extern gss_OID_desc Curl_krb5_mech_oid; @@ -71,5 +58,4 @@ void Curl_gss_log_error(struct Curl_easy *data, const char *prefix, #define GSSAUTH_P_PRIVACY 4 #endif /* HAVE_GSSAPI */ - #endif /* HEADER_CURL_GSSAPI_H */ diff --git a/libs/libcurl/src/curl_ntlm_core.c b/libs/libcurl/src/curl_ntlm_core.c index 9eb6c43c8c..e7060eb29a 100644 --- a/libs/libcurl/src/curl_ntlm_core.c +++ b/libs/libcurl/src/curl_ntlm_core.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -38,7 +38,7 @@ 3. USE_GNUTLS 4. USE_NSS 5. USE_MBEDTLS - 6. USE_DARWINSSL + 6. USE_SECTRANSP 7. USE_OS400CRYPTO 8. USE_WIN32_CRYPTO @@ -101,7 +101,7 @@ # include "curl_md4.h" # endif -#elif defined(USE_DARWINSSL) +#elif defined(USE_SECTRANSP) # include <CommonCrypto/CommonCryptor.h> # include <CommonCrypto/CommonDigest.h> @@ -290,7 +290,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out, return mbedtls_des_crypt_ecb(&ctx, in, out) == 0; } -#elif defined(USE_DARWINSSL) +#elif defined(USE_SECTRANSP) static bool encrypt_des(const unsigned char *in, unsigned char *out, const unsigned char *key_56) @@ -437,7 +437,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys, setup_des_key(keys + 14, &des); gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8); gcry_cipher_close(des); -#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_DARWINSSL) \ +#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) encrypt_des(plaintext, results, keys); encrypt_des(plaintext, results + 8, keys + 7); @@ -501,7 +501,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data, setup_des_key(pw + 7, &des); gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8); gcry_cipher_close(des); -#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_DARWINSSL) \ +#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) encrypt_des(magic, lmbuffer, pw); encrypt_des(magic, lmbuffer + 8, pw + 7); @@ -591,7 +591,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data, #else Curl_md4it(ntbuffer, pw, 2 * len); #endif -#elif defined(USE_DARWINSSL) +#elif defined(USE_SECTRANSP) (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer); #elif defined(USE_OS400CRYPTO) Curl_md4it(ntbuffer, pw, 2 * len); @@ -621,9 +621,9 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data, #if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI) /* This returns the HMAC MD5 digest */ -CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen, - const unsigned char *data, unsigned int datalen, - unsigned char *output) +static CURLcode hmac_md5(const unsigned char *key, unsigned int keylen, + const unsigned char *data, unsigned int datalen, + unsigned char *output) { HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen); @@ -668,9 +668,8 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen, ascii_uppercase_to_unicode_le(identity, user, userlen); ascii_to_unicode_le(identity + (userlen << 1), domain, domlen); - result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len), - ntlmv2hash); - + result = hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len), + ntlmv2hash); free(identity); return result; @@ -756,8 +755,8 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */ memcpy(ptr + 8, &ntlm->nonce[0], 8); - result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8, - NTLMv2_BLOB_LEN + 8, hmac_output); + result = hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8, + NTLMv2_BLOB_LEN + 8, hmac_output); if(result) { free(ptr); return result; @@ -799,7 +798,7 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash, memcpy(&data[0], challenge_server, 8); memcpy(&data[8], challenge_client, 8); - result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output); + result = hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output); if(result) return result; diff --git a/libs/libcurl/src/curl_ntlm_wb.c b/libs/libcurl/src/curl_ntlm_wb.c index a4791eb412..18ee75dd90 100644 --- a/libs/libcurl/src/curl_ntlm_wb.c +++ b/libs/libcurl/src/curl_ntlm_wb.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -124,6 +124,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) struct passwd pw, *pw_res; char pwbuf[1024]; #endif + char buffer[STRERROR_LEN]; /* Return if communication with ntlm_auth already set up */ if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD || @@ -179,13 +180,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) if(access(ntlm_auth, X_OK) != 0) { failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s", - ntlm_auth, errno, Curl_strerror(conn, errno)); + ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer))); goto done; } if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) { failf(conn->data, "Could not open socket pair. errno %d: %s", - errno, Curl_strerror(conn, errno)); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); goto done; } @@ -194,7 +195,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) sclose(sockfds[0]); sclose(sockfds[1]); failf(conn->data, "Could not fork. errno %d: %s", - errno, Curl_strerror(conn, errno)); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); goto done; } else if(!child_pid) { @@ -206,13 +207,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) sclose_nolog(sockfds[0]); if(dup2(sockfds[1], STDIN_FILENO) == -1) { failf(conn->data, "Could not redirect child stdin. errno %d: %s", - errno, Curl_strerror(conn, errno)); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); exit(1); } if(dup2(sockfds[1], STDOUT_FILENO) == -1) { failf(conn->data, "Could not redirect child stdout. errno %d: %s", - errno, Curl_strerror(conn, errno)); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); exit(1); } @@ -232,7 +233,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) sclose_nolog(sockfds[1]); failf(conn->data, "Could not execl(). errno %d: %s", - errno, Curl_strerror(conn, errno)); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); exit(1); } diff --git a/libs/libcurl/src/curl_path.c b/libs/libcurl/src/curl_path.c index 68f3e44ba8..ad386e7433 100644 --- a/libs/libcurl/src/curl_path.c +++ b/libs/libcurl/src/curl_path.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -22,6 +22,8 @@ #include "curl_setup.h" +#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) + #include <curl/curl.h> #include "curl_memory.h" #include "curl_path.h" @@ -193,3 +195,5 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) Curl_safefree(*path); return CURLE_QUOTE_ERROR; } + +#endif /* if SSH is used */ diff --git a/libs/libcurl/src/curl_rtmp.c b/libs/libcurl/src/curl_rtmp.c index f09f2f332d..16b1de1ae4 100644 --- a/libs/libcurl/src/curl_rtmp.c +++ b/libs/libcurl/src/curl_rtmp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com> * * This software is licensed as described in the file COPYING, which @@ -239,17 +239,18 @@ static CURLcode rtmp_connect(struct connectdata *conn, bool *done) static CURLcode rtmp_do(struct connectdata *conn, bool *done) { + struct Curl_easy *data = conn->data; RTMP *r = conn->proto.generic; if(!RTMP_ConnectStream(r, 0)) return CURLE_FAILED_INIT; if(conn->data->set.upload) { - Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize); - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); + Curl_pgrsSetUploadSize(data, data->state.infilesize); + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); } else - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); *done = TRUE; return CURLE_OK; } diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index f83e1ea4f7..4c3a173596 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -310,11 +310,12 @@ #endif #ifdef __AMIGA__ -# ifndef __ixemul__ -# include <exec/types.h> -# include <exec/execbase.h> -# include <proto/exec.h> -# include <proto/dos.h> +# include <exec/types.h> +# include <exec/execbase.h> +# include <proto/exec.h> +# include <proto/dos.h> +# ifdef HAVE_PROTO_BSDSOCKET_H +# include <proto/bsdsocket.h> /* ensure bsdsocket.library use */ # define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0) # endif #endif @@ -648,7 +649,7 @@ int netware_init(void); #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ defined(USE_POLARSSL) || defined(USE_MBEDTLS) || \ defined(USE_CYASSL) || defined(USE_SCHANNEL) || \ - defined(USE_DARWINSSL) || defined(USE_GSKIT) || defined(USE_MESALINK) + defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) #define USE_SSL /* SSL support has been enabled */ #endif @@ -667,7 +668,7 @@ int netware_init(void); /* Single point where USE_NTLM definition might be defined */ #if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH) #if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \ - defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \ + defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \ defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \ defined(USE_MBEDTLS) @@ -816,4 +817,10 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result); #endif +#ifdef DEBUGBUILD +#define UNITTEST +#else +#define UNITTEST static +#endif + #endif /* HEADER_CURL_SETUP_H */ diff --git a/libs/libcurl/src/dict.c b/libs/libcurl/src/dict.c index 78ef046d44..208a2336fd 100644 --- a/libs/libcurl/src/dict.c +++ b/libs/libcurl/src/dict.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -137,7 +137,6 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; char *path = data->state.up.path; - curl_off_t *bytecount = &data->req.bytecount; *done = TRUE; /* unconditionally */ @@ -200,8 +199,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) failf(data, "Failed sending DICT request"); return result; } - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, - -1, NULL); /* no upload */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); /* no upload */ } else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || @@ -247,8 +245,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) failf(data, "Failed sending DICT request"); return result; } - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, - -1, NULL); /* no upload */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); } else { @@ -270,7 +267,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) return result; } - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); } } diff --git a/libs/libcurl/src/doh.c b/libs/libcurl/src/doh.c index f06ed3311b..b5327c4aef 100644 --- a/libs/libcurl/src/doh.c +++ b/libs/libcurl/src/doh.c @@ -173,8 +173,12 @@ static int Curl_doh_done(struct Curl_easy *doh, CURLcode result) return 0; } -#define ERROR_CHECK_SETOPT(x,y) result = curl_easy_setopt(doh, x, y); \ - if(result) goto error +#define ERROR_CHECK_SETOPT(x,y) \ +do { \ + result = curl_easy_setopt(doh, x, y); \ + if(result) \ + goto error; \ +} WHILE_FALSE static CURLcode dohprobe(struct Curl_easy *data, struct dnsprobe *p, DNStype dnstype, @@ -242,7 +246,68 @@ static CURLcode dohprobe(struct Curl_easy *data, ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); #endif ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms); - ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); + if(data->set.verbose) + ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); + if(data->set.no_signal) + ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L); + + /* Inherit *some* SSL options from the user's transfer. This is a + best-guess as to which options are needed for compatibility. #3661 */ + if(data->set.ssl.falsestart) + ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L); + if(data->set.ssl.primary.verifyhost) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L); + if(data->set.proxy_ssl.primary.verifyhost) + ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L); + if(data->set.ssl.primary.verifypeer) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L); + if(data->set.proxy_ssl.primary.verifypeer) + ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYPEER, 1L); + if(data->set.ssl.primary.verifystatus) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L); + if(data->set.str[STRING_SSL_CAFILE_ORIG]) { + ERROR_CHECK_SETOPT(CURLOPT_CAINFO, + data->set.str[STRING_SSL_CAFILE_ORIG]); + } + if(data->set.str[STRING_SSL_CAFILE_PROXY]) { + ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO, + data->set.str[STRING_SSL_CAFILE_PROXY]); + } + if(data->set.str[STRING_SSL_CAPATH_ORIG]) { + ERROR_CHECK_SETOPT(CURLOPT_CAPATH, + data->set.str[STRING_SSL_CAPATH_ORIG]); + } + if(data->set.str[STRING_SSL_CAPATH_PROXY]) { + ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH, + data->set.str[STRING_SSL_CAPATH_PROXY]); + } + if(data->set.str[STRING_SSL_CRLFILE_ORIG]) { + ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, + data->set.str[STRING_SSL_CRLFILE_ORIG]); + } + if(data->set.str[STRING_SSL_CRLFILE_PROXY]) { + ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE, + data->set.str[STRING_SSL_CRLFILE_PROXY]); + } + if(data->set.ssl.certinfo) + ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); + if(data->set.str[STRING_SSL_RANDOM_FILE]) { + ERROR_CHECK_SETOPT(CURLOPT_RANDOM_FILE, + data->set.str[STRING_SSL_RANDOM_FILE]); + } + if(data->set.str[STRING_SSL_EGDSOCKET]) { + ERROR_CHECK_SETOPT(CURLOPT_EGDSOCKET, + data->set.str[STRING_SSL_EGDSOCKET]); + } + if(data->set.ssl.no_revoke) + ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); + if(data->set.proxy_ssl.no_revoke) + ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); + if(data->set.ssl.fsslctx) + ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); + if(data->set.ssl.fsslctxp) + ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp); + doh->set.fmultidone = Curl_doh_done; doh->set.dohfor = data; /* identify for which transfer this is done */ p->easy = doh; diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c index 6fcad3decd..ae6176f25b 100644 --- a/libs/libcurl/src/easy.c +++ b/libs/libcurl/src/easy.c @@ -75,6 +75,7 @@ #include "ssh.h" #include "setopt.h" #include "http_digest.h" +#include "system_win32.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -83,70 +84,6 @@ void Curl_version_init(void); -/* win32_cleanup() is for win32 socket cleanup functionality, the opposite - of win32_init() */ -static void win32_cleanup(void) -{ -#ifdef USE_WINSOCK - WSACleanup(); -#endif -#ifdef USE_WINDOWS_SSPI - Curl_sspi_global_cleanup(); -#endif -} - -/* win32_init() performs win32 socket initialization to properly setup the - stack to allow networking */ -static CURLcode win32_init(void) -{ -#ifdef USE_WINSOCK - WORD wVersionRequested; - WSADATA wsaData; - int res; - -#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2) - Error IPV6_requires_winsock2 -#endif - - wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); - - res = WSAStartup(wVersionRequested, &wsaData); - - if(res != 0) - /* Tell the user that we couldn't find a usable */ - /* winsock.dll. */ - return CURLE_FAILED_INIT; - - /* Confirm that the Windows Sockets DLL supports what we need.*/ - /* Note that if the DLL supports versions greater */ - /* than wVersionRequested, it will still return */ - /* wVersionRequested in wVersion. wHighVersion contains the */ - /* highest supported version. */ - - if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || - HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { - /* Tell the user that we couldn't find a usable */ - - /* winsock.dll. */ - WSACleanup(); - return CURLE_FAILED_INIT; - } - /* The Windows Sockets DLL is acceptable. Proceed. */ -#elif defined(USE_LWIPSOCK) - lwip_init(); -#endif - -#ifdef USE_WINDOWS_SSPI - { - CURLcode result = Curl_sspi_global_init(); - if(result) - return result; - } -#endif - - return CURLE_OK; -} - /* true globals -- for curl_global_init() and curl_global_cleanup() */ static unsigned int initialized; static long init_flags; @@ -223,11 +160,12 @@ static CURLcode global_init(long flags, bool memoryfuncs) return CURLE_FAILED_INIT; } - if(flags & CURL_GLOBAL_WIN32) - if(win32_init()) { - DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); - return CURLE_FAILED_INIT; - } +#ifdef WIN32 + if(Curl_win32_init(flags)) { + DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); + return CURLE_FAILED_INIT; + } +#endif #ifdef __AMIGA__ if(!Curl_amiga_init()) { @@ -331,8 +269,9 @@ void curl_global_cleanup(void) Curl_ssl_cleanup(); Curl_resolver_global_cleanup(); - if(init_flags & CURL_GLOBAL_WIN32) - win32_cleanup(); +#ifdef WIN32 + Curl_win32_cleanup(init_flags); +#endif Curl_amiga_cleanup(); diff --git a/libs/libcurl/src/file.c b/libs/libcurl/src/file.c index 8bba3b9165..d349cd9241 100644 --- a/libs/libcurl/src/file.c +++ b/libs/libcurl/src/file.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -311,7 +311,7 @@ static CURLcode file_upload(struct connectdata *conn) if(result) break; - if(readcount <= 0) /* fix questionable compare error. curlvms */ + if(!readcount) break; nread = readcount; diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c index c5f9540002..825aaaa1d7 100644 --- a/libs/libcurl/src/ftp.c +++ b/libs/libcurl/src/ftp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -448,7 +448,6 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received) static CURLcode InitiateTransfer(struct connectdata *conn) { struct Curl_easy *data = conn->data; - struct FTP *ftp = data->req.protop; CURLcode result = CURLE_OK; if(conn->bits.ftp_use_data_ssl) { @@ -461,24 +460,19 @@ static CURLcode InitiateTransfer(struct connectdata *conn) } if(conn->proto.ftpc.state_saved == FTP_STOR) { - *(ftp->bytecountp) = 0; - /* When we know we're uploading a specified file, we can get the file size prior to the actual upload. */ - Curl_pgrsSetUploadSize(data, data->state.infilesize); /* set the SO_SNDBUF for the secondary socket for those who need it */ Curl_sndbufset(conn->sock[SECONDARYSOCKET]); - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ - SECONDARYSOCKET, ftp->bytecountp); + Curl_setup_transfer(data, -1, -1, FALSE, SECONDARYSOCKET); } else { /* FTP download: */ - Curl_setup_transfer(conn, SECONDARYSOCKET, - conn->proto.ftpc.retr_size_saved, FALSE, - ftp->bytecountp, -1, NULL); /* no upload here */ + Curl_setup_transfer(data, SECONDARYSOCKET, + conn->proto.ftpc.retr_size_saved, FALSE, -1); } conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */ @@ -955,7 +949,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, unsigned short port_max = 0; unsigned short port; bool possibly_non_local = TRUE; - + char buffer[STRERROR_LEN]; char *addr = NULL; /* Step 1, figure out what is requested, @@ -1064,11 +1058,10 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, if(!host) { /* not an interface and not a host name, get default by extracting the IP from the control connection */ - sslen = sizeof(ss); if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { failf(data, "getsockname() failed: %s", - Curl_strerror(conn, SOCKERRNO) ); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); free(addr); return CURLE_FTP_PORT_FAILED; } @@ -1121,7 +1114,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, break; } if(!ai) { - failf(data, "socket failure: %s", Curl_strerror(conn, error)); + failf(data, "socket failure: %s", + Curl_strerror(error, buffer, sizeof(buffer))); return CURLE_FTP_PORT_FAILED; } @@ -1145,14 +1139,13 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, /* 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, - Curl_strerror(conn, error) ); + Curl_strerror(error, buffer, sizeof(buffer))); sslen = sizeof(ss); if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { failf(data, "getsockname() failed: %s", - Curl_strerror(conn, SOCKERRNO) ); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); Curl_closesocket(conn, portsock); return CURLE_FTP_PORT_FAILED; } @@ -1162,7 +1155,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, } if(error != EADDRINUSE && error != EACCES) { failf(data, "bind(port=%hu) failed: %s", port, - Curl_strerror(conn, error) ); + Curl_strerror(error, buffer, sizeof(buffer))); Curl_closesocket(conn, portsock); return CURLE_FTP_PORT_FAILED; } @@ -1185,7 +1178,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, sslen = sizeof(ss); if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) { failf(data, "getsockname() failed: %s", - Curl_strerror(conn, SOCKERRNO) ); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); Curl_closesocket(conn, portsock); return CURLE_FTP_PORT_FAILED; } @@ -1193,7 +1186,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, /* step 4, listen on the socket */ if(listen(portsock, 1)) { - failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO)); + failf(data, "socket failure: %s", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); Curl_closesocket(conn, portsock); return CURLE_FTP_PORT_FAILED; } @@ -1658,7 +1652,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn, infof(data, "File already completely uploaded\n"); /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); /* Set ->transfer so that we won't get any error in * ftp_done() because we didn't transfer anything! */ @@ -2230,7 +2224,7 @@ static CURLcode ftp_state_retr(struct connectdata *conn, if(ftp->downloadsize == 0) { /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); infof(data, "File already completely downloaded\n"); /* Set ->transfer so that we won't get any error in ftp_done() @@ -3308,33 +3302,33 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, ; else if(data->set.upload) { if((-1 != data->state.infilesize) && - (data->state.infilesize != *ftp->bytecountp) && + (data->state.infilesize != data->req.writebytecount) && !data->set.crlf && (ftp->transfer == FTPTRANSFER_BODY)) { failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T " out of %" CURL_FORMAT_CURL_OFF_T " bytes)", - *ftp->bytecountp, data->state.infilesize); + data->req.bytecount, data->state.infilesize); result = CURLE_PARTIAL_FILE; } } else { if((-1 != data->req.size) && - (data->req.size != *ftp->bytecountp) && + (data->req.size != data->req.bytecount) && #ifdef CURL_DO_LINEEND_CONV /* Most FTP servers don't adjust their file SIZE response for CRLFs, so * we'll check to see if the discrepancy can be explained by the number * of CRLFs we've changed to LFs. */ ((data->req.size + data->state.crlf_conversions) != - *ftp->bytecountp) && + data->req.bytecount) && #endif /* CURL_DO_LINEEND_CONV */ - (data->req.maxdownload != *ftp->bytecountp)) { + (data->req.maxdownload != data->req.bytecount)) { failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T - " bytes", *ftp->bytecountp); + " bytes", data->req.bytecount); result = CURLE_PARTIAL_FILE; } else if(!ftpc->dont_check && - !*ftp->bytecountp && + !data->req.bytecount && (data->req.size>0)) { failf(data, "No data was received!"); result = CURLE_FTP_COULDNT_RETR_FILE; @@ -3629,7 +3623,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep) if(!result && (ftp->transfer != FTPTRANSFER_BODY)) /* no data to transfer. FIX: it feels like a kludge to have this here too! */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); if(!ftpc->wait_data_conn) { /* no waiting for the data connection so this is now complete */ @@ -4308,7 +4302,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn, if(ftp->transfer != FTPTRANSFER_BODY) /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); else if(!connected) /* since we didn't connect now, we want do_more to get called */ conn->bits.do_more = TRUE; @@ -4395,7 +4389,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn) return CURLE_OUT_OF_MEMORY; ftp->path = &data->state.up.path[1]; /* don't include the initial slash */ - data->state.slash_removed = TRUE; /* we've skipped the slash */ /* FTP URLs support an extension like ";type=<typecode>" that * we'll try to get now! */ @@ -4428,7 +4421,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn) } /* get some initial data into the ftp struct */ - ftp->bytecountp = &conn->data->req.bytecount; ftp->transfer = FTPTRANSFER_BODY; ftp->downloadsize = 0; diff --git a/libs/libcurl/src/ftp.h b/libs/libcurl/src/ftp.h index 38d03223ca..828d69a21d 100644 --- a/libs/libcurl/src/ftp.h +++ b/libs/libcurl/src/ftp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -102,7 +102,6 @@ typedef enum { perhaps the Curl_easy is changed between the times the connection is used. */ struct FTP { - curl_off_t *bytecountp; char *user; /* user name string */ char *passwd; /* password string */ char *path; /* points to the urlpieces struct field */ diff --git a/libs/libcurl/src/getinfo.c b/libs/libcurl/src/getinfo.c index 19de657d8b..e118da80d4 100644 --- a/libs/libcurl/src/getinfo.c +++ b/libs/libcurl/src/getinfo.c @@ -163,10 +163,10 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, *param_longp = (long)data->info.filetime; break; case CURLINFO_HEADER_SIZE: - *param_longp = data->info.header_size; + *param_longp = (long)data->info.header_size; break; case CURLINFO_REQUEST_SIZE: - *param_longp = data->info.request_size; + *param_longp = (long)data->info.request_size; break; case CURLINFO_SSL_VERIFYRESULT: *param_longp = data->set.ssl.certverifyresult; diff --git a/libs/libcurl/src/gopher.c b/libs/libcurl/src/gopher.c index 485b4b79a0..b296c62d19 100644 --- a/libs/libcurl/src/gopher.c +++ b/libs/libcurl/src/gopher.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -78,8 +78,6 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - - curl_off_t *bytecount = &data->req.bytecount; char *gopherpath; char *path = data->state.up.path; char *query = data->state.up.query; @@ -90,7 +88,10 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) *done = TRUE; /* unconditionally */ - if(path && query) + /* path is guaranteed non-NULL */ + DEBUGASSERT(path); + + if(query) gopherpath = aprintf("%s?%s", path, query); else gopherpath = strdup(path); @@ -167,8 +168,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) if(result) return result; - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, - -1, NULL); /* no upload */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); return CURLE_OK; } #endif /*CURL_DISABLE_GOPHER*/ diff --git a/libs/libcurl/src/hostasyn.c b/libs/libcurl/src/hostasyn.c index 6ff60ba61a..99d872b352 100644 --- a/libs/libcurl/src/hostasyn.c +++ b/libs/libcurl/src/hostasyn.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -85,14 +85,14 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn, dns = Curl_cache_addr(data, ai, conn->async.hostname, conn->async.port); + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + if(!dns) { /* failed to store, cleanup and return error */ Curl_freeaddrinfo(ai); result = CURLE_OUT_OF_MEMORY; } - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); } else { result = CURLE_OUT_OF_MEMORY; diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c index 89b88e9323..7909141c17 100644 --- a/libs/libcurl/src/hostip.c +++ b/libs/libcurl/src/hostip.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -73,6 +73,8 @@ #define USE_ALARM_TIMEOUT #endif +#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */ + /* * hostip.c explained * ================== @@ -198,23 +200,19 @@ Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize) } /* - * Return a hostcache id string for the provided host + port, to be used by - * the DNS caching. + * Create a hostcache id string for the provided host + port, to be used by + * the DNS caching. Without alloc. */ -static char * -create_hostcache_id(const char *name, int port) +static void +create_hostcache_id(const char *name, int port, char *ptr, size_t buflen) { - /* create and return the new allocated entry */ - char *id = aprintf("%s:%d", name, port); - char *ptr = id; - if(ptr) { - /* lower case the name part */ - while(*ptr && (*ptr != ':')) { - *ptr = (char)TOLOWER(*ptr); - ptr++; - } - } - return id; + size_t len = strlen(name); + if(len > (buflen - 7)) + len = buflen - 7; + /* store and lower case the name */ + while(len--) + *ptr++ = (char)TOLOWER(*name++); + msnprintf(ptr, 7, ":%u", port); } struct hostcache_prune_data { @@ -296,17 +294,13 @@ fetch_addr(struct connectdata *conn, const char *hostname, int port) { - char *entry_id = NULL; struct Curl_dns_entry *dns = NULL; size_t entry_len; struct Curl_easy *data = conn->data; + char entry_id[MAX_HOSTCACHE_LEN]; /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) - return dns; - + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); /* See if its already in our dns cache */ @@ -314,18 +308,7 @@ fetch_addr(struct connectdata *conn, /* No entry found in cache, check if we might have a wildcard entry */ if(!dns && data->change.wildcard_resolve) { - /* - * Free the previous entry_id before requesting a new one to avoid leaking - * memory - */ - free(entry_id); - - entry_id = create_hostcache_id("*", port); - - /* If we can't create the entry id, fail */ - if(!entry_id) - return dns; - + create_hostcache_id("*", port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); /* See if it's already in our dns cache */ @@ -346,9 +329,6 @@ fetch_addr(struct connectdata *conn, } } - /* free the allocated entry_id again */ - free(entry_id); - return dns; } @@ -388,6 +368,9 @@ Curl_fetch_addr(struct connectdata *conn, return dns; } +UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, + Curl_addrinfo **addr); + /* * Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo' * struct by re-linking its linked list. @@ -400,7 +383,8 @@ Curl_fetch_addr(struct connectdata *conn, * * @unittest: 1608 */ -CURLcode Curl_shuffle_addr(struct Curl_easy *data, Curl_addrinfo **addr) +UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, + Curl_addrinfo **addr) { CURLcode result = CURLE_OK; const int num_addrs = Curl_num_addresses(*addr); @@ -467,7 +451,7 @@ Curl_cache_addr(struct Curl_easy *data, const char *hostname, int port) { - char *entry_id; + char entry_id[MAX_HOSTCACHE_LEN]; size_t entry_len; struct Curl_dns_entry *dns; struct Curl_dns_entry *dns2; @@ -479,20 +463,16 @@ Curl_cache_addr(struct Curl_easy *data, return NULL; } - /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) - return NULL; - entry_len = strlen(entry_id); - /* Create a new cache entry */ dns = calloc(1, sizeof(struct Curl_dns_entry)); if(!dns) { - free(entry_id); return NULL; } + /* Create an entry id, based upon the hostname and port */ + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + entry_len = strlen(entry_id); + dns->inuse = 1; /* the cache has the first reference */ dns->addr = addr; /* this is the address(es) */ time(&dns->timestamp); @@ -504,16 +484,11 @@ Curl_cache_addr(struct Curl_easy *data, (void *)dns); if(!dns2) { free(dns); - free(entry_id); return NULL; } dns = dns2; dns->inuse++; /* mark entry as in-use */ - - /* free the allocated entry_id */ - free(entry_id); - return dns; } @@ -568,7 +543,7 @@ int Curl_resolv(struct connectdata *conn, /* The entry was not in the cache. Resolve it to IP address */ Curl_addrinfo *addr; - int respwait; + int respwait = 0; /* Check what IP specifics the app has requested and if we can provide it. * If not, bail out. */ @@ -896,10 +871,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) data->change.wildcard_resolve = false; for(hostp = data->change.resolve; hostp; hostp = hostp->next) { + char entry_id[MAX_HOSTCACHE_LEN]; if(!hostp->data) continue; if(hostp->data[0] == '-') { - char *entry_id; size_t entry_len; if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) { @@ -909,12 +884,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) { - return CURLE_OUT_OF_MEMORY; - } - + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); if(data->share) @@ -925,14 +895,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - - /* free the allocated entry_id again */ - free(entry_id); } else { struct Curl_dns_entry *dns; Curl_addrinfo *head = NULL, *tail = NULL; - char *entry_id; size_t entry_len; char address[64]; #if !defined(CURL_DISABLE_VERBOSE_STRINGS) @@ -1028,12 +994,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) { - Curl_freeaddrinfo(head); - return CURLE_OUT_OF_MEMORY; - } + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); if(data->share) @@ -1054,8 +1015,6 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1); } - /* free the allocated entry_id again */ - free(entry_id); /* put this new host in the cache */ dns = Curl_cache_addr(data, head, hostname, port); diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h index 29fd1ef7cc..cd43882af6 100644 --- a/libs/libcurl/src/hostip.h +++ b/libs/libcurl/src/hostip.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -179,16 +179,6 @@ Curl_fetch_addr(struct connectdata *conn, int port); /* - * Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo' - * struct by re-linking its linked list. - * - * The addr argument should be the address of a pointer to the head node of a - * `Curl_addrinfo` list and it will be modified to point to the new head after - * shuffling. - */ -CURLcode Curl_shuffle_addr(struct Curl_easy *data, Curl_addrinfo **addr); - -/* * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. * * Returns the Curl_dns_entry entry pointer or NULL if the storage failed. diff --git a/libs/libcurl/src/hostip6.c b/libs/libcurl/src/hostip6.c index e06d0343a5..fb2f35ce3d 100644 --- a/libs/libcurl/src/hostip6.c +++ b/libs/libcurl/src/hostip6.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -101,14 +101,15 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai) { printf("dump_addrinfo:\n"); for(; ai; ai = ai->ai_next) { - char buf[INET6_ADDRSTRLEN]; - + char buf[INET6_ADDRSTRLEN]; + char buffer[STRERROR_LEN]; printf(" fam %2d, CNAME %s, ", ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>"); if(Curl_printable_address(ai, buf, sizeof(buf))) printf("%s\n", buf); else - printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO)); + printf("failed; %s\n", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); } } #else diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c index dd98e4a126..a0520b40ec 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.c @@ -77,6 +77,7 @@ #include "http2.h" #include "connect.h" #include "strdup.h" +#include "altsvc.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -102,13 +103,14 @@ static int https_getsock(struct connectdata *conn, #else #define https_connecting(x,y) CURLE_COULDNT_CONNECT #endif +static CURLcode http_setup_conn(struct connectdata *conn); /* * HTTP handler interface. */ const struct Curl_handler Curl_handler_http = { "HTTP", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ + http_setup_conn, /* setup_connection */ Curl_http, /* do_it */ Curl_http_done, /* done */ ZERO_NULL, /* do_more */ @@ -133,7 +135,7 @@ const struct Curl_handler Curl_handler_http = { */ const struct Curl_handler Curl_handler_https = { "HTTPS", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ + http_setup_conn, /* setup_connection */ Curl_http, /* do_it */ Curl_http_done, /* done */ ZERO_NULL, /* do_more */ @@ -153,7 +155,7 @@ const struct Curl_handler Curl_handler_https = { }; #endif -CURLcode Curl_http_setup_conn(struct connectdata *conn) +static CURLcode http_setup_conn(struct connectdata *conn) { /* allocate the HTTP-specific struct for the Curl_easy, only to survive during this request */ @@ -415,7 +417,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn) break; } - bytessent = http->writebytecount; + bytessent = data->req.writebytecount; if(conn->bits.authneg) { /* This is a state where we are known to be negotiating and we don't send @@ -479,8 +481,36 @@ static CURLcode http_perhapsrewind(struct connectdata *conn) (curl_off_t)(expectsend - bytessent)); } #endif +#if defined(USE_SPNEGO) + /* There is still data left to send */ + if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) || + (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) { + if(((expectsend - bytessent) < 2000) || + (conn->negotiate.state != GSS_AUTHNONE) || + (conn->proxyneg.state != GSS_AUTHNONE)) { + /* The NEGOTIATE-negotiation has started *OR* + there is just a little (<2K) data left to send, keep on sending. */ + + /* 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"); + } + + return CURLE_OK; + } + + if(conn->bits.close) + /* this is already marked to get closed */ + return CURLE_OK; - /* This is not NTLM or many bytes left to send: close */ + infof(data, "NEGOTIATE send, close instead of sending %" + CURL_FORMAT_CURL_OFF_T " bytes\n", + (curl_off_t)(expectsend - bytessent)); + } +#endif + + /* This is not NEGOTIATE/NTLM or many bytes left to send: close */ streamclose(conn, "Mid-auth HTTP and much data left to send"); data->req.size = 0; /* don't download any more than 0 bytes */ @@ -598,10 +628,6 @@ output_auth_headers(struct connectdata *conn, #if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO) struct Curl_easy *data = conn->data; #endif -#ifdef USE_SPNEGO - struct negotiatedata *negdata = proxy ? - &data->state.proxyneg : &data->state.negotiate; -#endif #ifdef CURL_DISABLE_CRYPTO_AUTH (void)request; @@ -609,15 +635,11 @@ output_auth_headers(struct connectdata *conn, #endif #ifdef USE_SPNEGO - negdata->state = GSS_AUTHNONE; - if((authstatus->picked == CURLAUTH_NEGOTIATE) && - negdata->context && !GSS_ERROR(negdata->status)) { + if((authstatus->picked == CURLAUTH_NEGOTIATE)) { auth = "Negotiate"; result = Curl_output_negotiate(conn, proxy); if(result) return result; - authstatus->done = TRUE; - negdata->state = GSS_AUTHSENT; } else #endif @@ -750,7 +772,7 @@ Curl_http_output_auth(struct connectdata *conn, #ifndef CURL_DISABLE_PROXY /* Send proxy authentication header if needed */ if(conn->bits.httpproxy && - (conn->bits.tunnel_proxy == proxytunnel)) { + (conn->bits.tunnel_proxy == (bit)proxytunnel)) { result = output_auth_headers(conn, authproxy, request, path, TRUE); if(result) return result; @@ -794,7 +816,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, #ifdef USE_SPNEGO struct negotiatedata *negdata = proxy? - &data->state.proxyneg:&data->state.negotiate; + &conn->proxyneg:&conn->negotiate; #endif unsigned long *availp; struct auth *authp; @@ -833,21 +855,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, authp->avail |= CURLAUTH_NEGOTIATE; if(authp->picked == CURLAUTH_NEGOTIATE) { - if(negdata->state == GSS_AUTHSENT || - negdata->state == GSS_AUTHNONE) { - CURLcode result = Curl_input_negotiate(conn, proxy, auth); - if(!result) { - DEBUGASSERT(!data->req.newurl); - data->req.newurl = strdup(data->change.url); - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - data->state.authproblem = FALSE; - /* we received a GSS auth token and we dealt with it fine */ - negdata->state = GSS_AUTHRECV; - } - else - data->state.authproblem = TRUE; + CURLcode result = Curl_input_negotiate(conn, proxy, auth); + if(!result) { + DEBUGASSERT(!data->req.newurl); + data->req.newurl = strdup(data->change.url); + if(!data->req.newurl) + return CURLE_OUT_OF_MEMORY; + data->state.authproblem = FALSE; + /* we received a GSS auth token and we dealt with it fine */ + negdata->state = GSS_AUTHRECV; } + else + data->state.authproblem = TRUE; } } } @@ -1117,14 +1136,13 @@ void Curl_add_buffer_free(Curl_send_buffer **inp) CURLcode Curl_add_buffer_send(Curl_send_buffer **inp, struct connectdata *conn, - /* add the number of sent bytes to this - counter */ - long *bytes_written, + /* add the number of sent bytes to this + counter */ + curl_off_t *bytes_written, - /* how much of the buffer contains body data */ + /* how much of the buffer contains body data */ size_t included_body_bytes, int socketindex) - { ssize_t amount; CURLcode result; @@ -1220,7 +1238,8 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp, if(http) { /* if we sent a piece of the body here, up the byte counter for it accordingly */ - http->writebytecount += bodylen; + data->req.writebytecount += bodylen; + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); if((size_t)amount != size) { /* The whole request could not be sent in one system call. We must @@ -1553,20 +1572,6 @@ CURLcode Curl_http_done(struct connectdata *conn, Curl_unencode_cleanup(conn); -#ifdef USE_SPNEGO - if(data->state.proxyneg.state == GSS_AUTHSENT || - data->state.negotiate.state == GSS_AUTHSENT) { - /* add forbid re-use if http-code != 401/407 as a WA only needed for - * 401/407 that signal auth failure (empty) otherwise state will be RECV - * with current code. - * Do not close CONNECT_ONLY connections. */ - if((data->req.httpcode != 401) && (data->req.httpcode != 407) && - !data->set.connect_only) - streamclose(conn, "Negotiate transfer completed"); - Curl_cleanup_negotiate(data); - } -#endif - /* set the proper values (possibly modified on POST) */ conn->seek_func = data->set.seek_func; /* restore */ conn->seek_client = data->set.seek_client; /* restore */ @@ -1582,16 +1587,6 @@ CURLcode Curl_http_done(struct connectdata *conn, Curl_mime_cleanpart(&http->form); - switch(data->set.httpreq) { - case HTTPREQ_PUT: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - data->req.bytecount = http->readbytecount + http->writebytecount; - break; - default: - break; - } - if(status) return status; @@ -1599,7 +1594,7 @@ CURLcode Curl_http_done(struct connectdata *conn, entire operation is complete */ !conn->bits.retry && !data->set.connect_only && - (http->readbytecount + + (data->req.bytecount + data->req.headerbytecount - data->req.deductheadercount) <= 0) { /* If this connection isn't simply closed to be retried, AND nothing was @@ -1789,9 +1784,16 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, } else { if(*(--ptr) == ';') { - /* send no-value custom header if terminated by semicolon */ - *ptr = ':'; - semicolonp = ptr; + /* copy the source */ + semicolonp = strdup(headers->data); + if(!semicolonp) { + Curl_add_buffer_free(&req_buffer); + return CURLE_OUT_OF_MEMORY; + } + /* put a colon where the semicolon is */ + semicolonp[ptr - headers->data] = ':'; + /* point at the colon */ + optr = &semicolonp [ptr - headers->data]; } } ptr = optr; @@ -1807,36 +1809,37 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, if(*ptr || semicolonp) { /* only send this if the contents was non-blank or done special */ CURLcode result = CURLE_OK; + char *compare = semicolonp ? semicolonp : headers->data; if(conn->allocptr.host && /* a Host: header was sent already, don't pass on any custom Host: header as that will produce *two* in the same request! */ - checkprefix("Host:", headers->data)) + checkprefix("Host:", compare)) ; else if(data->set.httpreq == HTTPREQ_POST_FORM && /* this header (extended by formdata.c) is sent later */ - checkprefix("Content-Type:", headers->data)) + checkprefix("Content-Type:", compare)) ; else if(data->set.httpreq == HTTPREQ_POST_MIME && /* this header is sent later */ - checkprefix("Content-Type:", headers->data)) + checkprefix("Content-Type:", compare)) ; else if(conn->bits.authneg && /* while doing auth neg, don't allow the custom length since we will force length zero then */ - checkprefix("Content-Length:", headers->data)) + checkprefix("Content-Length:", compare)) ; else if(conn->allocptr.te && /* when asking for Transfer-Encoding, don't pass on a custom Connection: */ - checkprefix("Connection:", headers->data)) + checkprefix("Connection:", compare)) ; else if((conn->httpversion == 20) && - checkprefix("Transfer-Encoding:", headers->data)) + checkprefix("Transfer-Encoding:", compare)) /* HTTP/2 doesn't support chunked requests */ ; - else if((checkprefix("Authorization:", headers->data) || - checkprefix("Cookie:", headers->data)) && + else if((checkprefix("Authorization:", compare) || + checkprefix("Cookie:", compare)) && /* be careful of sending this potentially sensitive header to other hosts */ (data->state.this_is_a_follow && @@ -1845,10 +1848,10 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, !strcasecompare(data->state.first_host, conn->host.name))) ; else { - result = Curl_add_bufferf(&req_buffer, "%s\r\n", headers->data); + result = Curl_add_bufferf(&req_buffer, "%s\r\n", compare); } if(semicolonp) - *semicolonp = ';'; /* put back the semicolon */ + free(semicolonp); if(result) return result; } @@ -2000,7 +2003,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) data->state.first_remote_port = conn->remote_port; } - http->writebytecount = http->readbytecount = 0; if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && data->set.upload) { @@ -2061,7 +2063,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; } - if((data->state.authhost.multipass || data->state.authproxy.multipass) && + if(((data->state.authhost.multipass && !data->state.authhost.done) + || (data->state.authproxy.multipass && !data->state.authproxy.done)) && (httpreq != HTTPREQ_GET) && (httpreq != HTTPREQ_HEAD)) { /* Auth is required and we are not authenticated yet. Make a PUT or POST @@ -2697,9 +2700,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) failf(data, "Failed sending PUT request"); else /* prepare for transfer */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, postsize?FIRSTSOCKET:-1, - postsize?&http->writebytecount:NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + postsize?FIRSTSOCKET:-1); if(result) return result; break; @@ -2719,12 +2721,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) failf(data, "Failed sending POST request"); else /* setup variables for the upcoming transfer */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount, - -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); break; } - postsize = http->postsize; + data->state.infilesize = postsize = http->postsize; /* We only set Content-Length and allow a custom Content-Length if we don't upload data chunked, as RFC2616 forbids us to set both @@ -2788,9 +2789,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) failf(data, "Failed sending POST request"); else /* prepare for transfer */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, postsize?FIRSTSOCKET:-1, - postsize?&http->writebytecount:NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + postsize?FIRSTSOCKET:-1); if(result) return result; @@ -2944,9 +2944,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if(result) failf(data, "Failed sending HTTP POST request"); else - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, http->postdata?FIRSTSOCKET:-1, - http->postdata?&http->writebytecount:NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + http->postdata?FIRSTSOCKET:-1); break; default: @@ -2962,33 +2961,30 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) failf(data, "Failed sending HTTP request"); else /* HTTP GET/HEAD download: */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount, - http->postdata?FIRSTSOCKET:-1, - http->postdata?&http->writebytecount:NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + http->postdata?FIRSTSOCKET:-1); } if(result) return result; - if(http->writebytecount) { + if(data->req.writebytecount) { /* if a request-body has been sent off, we make sure this progress is noted properly */ - Curl_pgrsSetUploadCounter(data, http->writebytecount); + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); if(Curl_pgrsUpdate(conn)) result = CURLE_ABORTED_BY_CALLBACK; - if(http->writebytecount >= postsize) { + if(data->req.writebytecount >= postsize) { /* 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", - http->writebytecount, postsize); + data->req.writebytecount, postsize); data->req.upload_done = TRUE; data->req.keepon &= ~KEEP_SEND; /* we're done writing */ data->req.exp100 = EXP100_SEND_DATA; /* already sent */ Curl_expire_done(data, EXPIRE_100_TIMEOUT); } - else - data->req.writebytecount = http->writebytecount; } if((conn->httpversion == 20) && data->req.upload_chunky) @@ -3383,7 +3379,24 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, data->state.authproblem = TRUE; } #endif - +#if defined(USE_SPNEGO) + if(conn->bits.close && + (((data->req.httpcode == 401) && + (conn->negotiate.state == GSS_AUTHRECV)) || + ((data->req.httpcode == 407) && + (conn->proxyneg.state == GSS_AUTHRECV)))) { + infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); + data->state.authproblem = TRUE; + } + if((conn->negotiate.state == GSS_AUTHDONE) && + (data->req.httpcode != 401)) { + conn->negotiate.state = GSS_AUTHSUCC; + } + if((conn->proxyneg.state == GSS_AUTHDONE) && + (data->req.httpcode != 407)) { + conn->proxyneg.state = GSS_AUTHSUCC; + } +#endif /* * When all the headers have been parsed, see if we should give * up and return an error. @@ -3960,6 +3973,22 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(result) return result; } + #ifdef USE_SPNEGO + else if(checkprefix("Persistent-Auth", k->p)) { + struct negotiatedata *negdata = &conn->negotiate; + struct auth *authp = &data->state.authhost; + if(authp->picked == CURLAUTH_NEGOTIATE) { + char *persistentauth = Curl_copy_header_value(k->p); + if(!persistentauth) + return CURLE_OUT_OF_MEMORY; + negdata->noauthpersist = checkprefix("false", persistentauth); + negdata->havenoauthpersist = TRUE; + infof(data, "Negotiate: noauthpersist -> %d, header part: %s", + negdata->noauthpersist, persistentauth); + free(persistentauth); + } + } + #endif else if((k->httpcode >= 300 && k->httpcode < 400) && checkprefix("Location:", k->p) && !data->req.location) { @@ -3987,6 +4016,27 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, } } } +#ifdef USE_ALTSVC + /* If enabled, the header is incoming and this is over HTTPS */ + else if(data->asi && checkprefix("Alt-Svc:", k->p) && + ((conn->handler->flags & PROTOPT_SSL) || +#ifdef CURLDEBUG + /* allow debug builds to circumvent the HTTPS restriction */ + getenv("CURL_ALTSVC_HTTP") +#else + 0 +#endif + )) { + /* the ALPN of the current request */ + enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1; + result = Curl_altsvc_parse(data, data->asi, + &k->p[ strlen("Alt-Svc:") ], + id, conn->host.name, + curlx_uitous(conn->remote_port)); + if(result) + return result; + } +#endif else if(conn->handler->protocol & CURLPROTO_RTSP) { result = Curl_rtsp_parseheader(conn, k->p); if(result) diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h index 7fa0471ad0..a59fe7af0e 100644 --- a/libs/libcurl/src/http.h +++ b/libs/libcurl/src/http.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -65,7 +65,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr, size_t size) WARN_UNUSED_RESULT; CURLcode Curl_add_buffer_send(Curl_send_buffer **inp, struct connectdata *conn, - long *bytes_written, + curl_off_t *bytes_written, size_t included_body_bytes, int socketindex); @@ -139,8 +139,6 @@ struct HTTP { const char *p_pragma; /* Pragma: string */ const char *p_accept; /* Accept: string */ - curl_off_t readbytecount; - curl_off_t writebytecount; /* For FORM posting */ curl_mimepart form; diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index 3b8088dffc..b5c53cdf60 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -357,7 +357,7 @@ int Curl_http2_ver(char *p, size_t len) https://tools.ietf.org/html/rfc7540#page-77 nghttp2_error_code enums are identical. */ -const char *Curl_http2_strerror(uint32_t err) +static const char *http2_strerror(uint32_t err) { #ifndef NGHTTP2_HAS_HTTP2_STRERROR const char *str[] = { @@ -618,6 +618,18 @@ static int push_promise(struct Curl_easy *data, return rv; } +/* + * multi_connchanged() is called to tell that there is a connection in + * this multi handle that has changed state (pipelining become possible, the + * number of allowed streams changed or similar), and a subsequent use of this + * multi handle should move CONNECT_PEND handles back to CONNECT to have them + * retry. + */ +static void multi_connchanged(struct Curl_multi *multi) +{ + multi->recheckstate = TRUE; +} + static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, void *userp) { @@ -650,7 +662,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, infof(conn->data, "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n", httpc->settings.max_concurrent_streams); - Curl_multi_connchanged(conn->data->multi); + multi_connchanged(conn->data->multi); } } return 0; @@ -837,7 +849,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, return 0; } H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n", - Curl_http2_strerror(error_code), error_code, stream_id)); + http2_strerror(error_code), error_code, stream_id)); stream = data_s->req.protop; if(!stream) return NGHTTP2_ERR_CALLBACK_FAILURE; @@ -957,6 +969,28 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(frame->hd.type == NGHTTP2_PUSH_PROMISE) { char *h; + if(!strcmp(":authority", (const char *)name)) { + /* psuedo headers are lower case */ + int rc = 0; + char *check = aprintf("%s:%d", conn->host.name, conn->remote_port); + if(!check) + /* no memory */ + return NGHTTP2_ERR_CALLBACK_FAILURE; + if(!Curl_strcasecompare(check, (const char *)value)) { + /* This is push is not for the same authority that was asked for in + * the URL. RFC 7540 section 8.2 says: "A client MUST treat a + * PUSH_PROMISE for which the server is not authoritative as a stream + * error of type PROTOCOL_ERROR." + */ + (void)nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, + stream_id, NGHTTP2_PROTOCOL_ERROR); + rc = NGHTTP2_ERR_CALLBACK_FAILURE; + } + free(check); + if(rc) + return rc; + } + if(!stream->push_headers) { stream->push_headers_alloc = 10; stream->push_headers = malloc(stream->push_headers_alloc * @@ -1197,7 +1231,7 @@ void Curl_http2_done(struct connectdata *conn, bool premature) /* * Initialize nghttp2 for a Curl connection */ -CURLcode Curl_http2_init(struct connectdata *conn) +static CURLcode http2_init(struct connectdata *conn) { if(!conn->proto.httpc.h2) { int rc; @@ -1431,7 +1465,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn, } else if(httpc->error_code != NGHTTP2_NO_ERROR) { failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)", - stream->stream_id, Curl_http2_strerror(httpc->error_code), + stream->stream_id, http2_strerror(httpc->error_code), httpc->error_code); *err = CURLE_HTTP2_STREAM; return -1; @@ -2141,7 +2175,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn) else conn->handler = &Curl_handler_http2; - result = Curl_http2_init(conn); + result = http2_init(conn); if(result) { Curl_add_buffer_free(&stream->header_recvbuf); return result; @@ -2163,7 +2197,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn) conn->bundle->multiuse = BUNDLE_MULTIPLEX; infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n"); - Curl_multi_connchanged(conn->data->multi); + multi_connchanged(conn->data->multi); return CURLE_OK; } diff --git a/libs/libcurl/src/http2.h b/libs/libcurl/src/http2.h index 67db3dffb0..db6217b11e 100644 --- a/libs/libcurl/src/http2.h +++ b/libs/libcurl/src/http2.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -63,7 +63,6 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data); /* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */ bool Curl_h2_http_1_1_error(struct connectdata *conn); #else /* USE_NGHTTP2 */ -#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL diff --git a/libs/libcurl/src/http_negotiate.c b/libs/libcurl/src/http_negotiate.c index 2a97707eba..9415236fb1 100644 --- a/libs/libcurl/src/http_negotiate.c +++ b/libs/libcurl/src/http_negotiate.c @@ -56,7 +56,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, service = data->set.str[STRING_PROXY_SERVICE_NAME] ? data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; host = conn->http_proxy.host.name; - neg_ctx = &data->state.proxyneg; + neg_ctx = &conn->proxyneg; } else { userp = conn->user; @@ -64,7 +64,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, service = data->set.str[STRING_SERVICE_NAME] ? data->set.str[STRING_SERVICE_NAME] : "HTTP"; host = conn->host.name; - neg_ctx = &data->state.negotiate; + neg_ctx = &conn->negotiate; } /* Not set means empty */ @@ -80,11 +80,16 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, header++; len = strlen(header); + neg_ctx->havenegdata = len != 0; if(!len) { - /* Is this the first call in a new negotiation? */ - if(neg_ctx->context) { - /* The server rejected our authentication and hasn't suppled any more + if(neg_ctx->state == GSS_AUTHSUCC) { + infof(conn->data, "Negotiate auth restarted\n"); + Curl_cleanup_negotiate(conn); + } + else if(neg_ctx->state != GSS_AUTHNONE) { + /* The server rejected our authentication and hasn't supplied any more negotiation mechanisms */ + Curl_cleanup_negotiate(conn); return CURLE_LOGIN_DENIED; } } @@ -106,38 +111,96 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) { - struct negotiatedata *neg_ctx = proxy ? &conn->data->state.proxyneg : - &conn->data->state.negotiate; + struct negotiatedata *neg_ctx = proxy ? &conn->proxyneg : + &conn->negotiate; + struct auth *authp = proxy ? &conn->data->state.authproxy : + &conn->data->state.authhost; char *base64 = NULL; size_t len = 0; char *userp; CURLcode result; - result = Curl_auth_create_spnego_message(conn->data, neg_ctx, &base64, &len); - if(result) - return result; + authp->done = FALSE; + + if(neg_ctx->state == GSS_AUTHRECV) { + if(neg_ctx->havenegdata) { + neg_ctx->havemultiplerequests = TRUE; + } + } + else if(neg_ctx->state == GSS_AUTHSUCC) { + if(!neg_ctx->havenoauthpersist) { + neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests; + } + } - userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "", - base64); + if(neg_ctx->noauthpersist || + (neg_ctx->state != GSS_AUTHDONE && neg_ctx->state != GSS_AUTHSUCC)) { - if(proxy) { - Curl_safefree(conn->allocptr.proxyuserpwd); - conn->allocptr.proxyuserpwd = userp; + if(neg_ctx->noauthpersist && neg_ctx->state == GSS_AUTHSUCC) { + infof(conn->data, "Curl_output_negotiate, " + "no persistent authentication: cleanup existing context"); + Curl_auth_spnego_cleanup(neg_ctx); + } + if(!neg_ctx->context) { + result = Curl_input_negotiate(conn, proxy, "Negotiate"); + if(result) + return result; + } + + result = Curl_auth_create_spnego_message(conn->data, + neg_ctx, &base64, &len); + if(result) + return result; + + userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "", + base64); + + if(proxy) { + Curl_safefree(conn->allocptr.proxyuserpwd); + conn->allocptr.proxyuserpwd = userp; + } + else { + Curl_safefree(conn->allocptr.userpwd); + conn->allocptr.userpwd = userp; + } + + free(base64); + + if(userp == NULL) { + return CURLE_OUT_OF_MEMORY; + } + + neg_ctx->state = GSS_AUTHSENT; + #ifdef HAVE_GSSAPI + if(neg_ctx->status == GSS_S_COMPLETE || + neg_ctx->status == GSS_S_CONTINUE_NEEDED) { + neg_ctx->state = GSS_AUTHDONE; + } + #else + #ifdef USE_WINDOWS_SSPI + if(neg_ctx->status == SEC_E_OK || + neg_ctx->status == SEC_I_CONTINUE_NEEDED) { + neg_ctx->state = GSS_AUTHDONE; + } + #endif + #endif } - else { - Curl_safefree(conn->allocptr.userpwd); - conn->allocptr.userpwd = userp; + + if(neg_ctx->state == GSS_AUTHDONE || neg_ctx->state == GSS_AUTHSUCC) { + /* connection is already authenticated, + * don't send a header in future requests */ + authp->done = TRUE; } - free(base64); + neg_ctx->havenegdata = FALSE; - return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; + return CURLE_OK; } -void Curl_cleanup_negotiate(struct Curl_easy *data) +void Curl_cleanup_negotiate(struct connectdata *conn) { - Curl_auth_spnego_cleanup(&data->state.negotiate); - Curl_auth_spnego_cleanup(&data->state.proxyneg); + Curl_auth_spnego_cleanup(&conn->negotiate); + Curl_auth_spnego_cleanup(&conn->proxyneg); } #endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */ diff --git a/libs/libcurl/src/http_negotiate.h b/libs/libcurl/src/http_negotiate.h index c64e548251..d4a7f09e09 100644 --- a/libs/libcurl/src/http_negotiate.h +++ b/libs/libcurl/src/http_negotiate.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -31,7 +31,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, /* this is for creating Negotiate header output */ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy); -void Curl_cleanup_negotiate(struct Curl_easy *data); +void Curl_cleanup_negotiate(struct connectdata *conn); #endif /* USE_SPNEGO */ diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c index 5d96900f89..075b3ad201 100644 --- a/libs/libcurl/src/imap.c +++ b/libs/libcurl/src/imap.c @@ -1177,11 +1177,11 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, if(data->req.bytecount == size) /* The entire data is already transferred! */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); else { /* IMAP download */ data->req.maxdownload = size; - Curl_setup_transfer(conn, FIRSTSOCKET, size, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, size, FALSE, -1); } } else { @@ -1231,7 +1231,7 @@ static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode, Curl_pgrsSetUploadSize(data, data->state.infilesize); /* IMAP upload */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); /* End of DO phase */ state(conn, IMAP_STOP); @@ -1660,7 +1660,7 @@ static CURLcode imap_dophase_done(struct connectdata *conn, bool connected) if(imap->transfer != FTPTRANSFER_BODY) /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); return CURLE_OK; } diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c index a149f8cbc3..79dc2f2ed8 100644 --- a/libs/libcurl/src/ldap.c +++ b/libs/libcurl/src/ldap.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -744,7 +744,7 @@ quit: #endif /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); connclose(conn, "LDAP connection always disable re-use"); return result; diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index 13f2cf742a..7d005b7955 100644 --- a/libs/libcurl/src/libcurl.plist +++ b/libs/libcurl/src/libcurl.plist @@ -15,7 +15,7 @@ <string>se.haxx.curl.libcurl</string> <key>CFBundleVersion</key> - <string>7.64.0</string> + <string>7.64.1</string> <key>CFBundleName</key> <string>libcurl</string> @@ -27,9 +27,9 @@ <string>????</string> <key>CFBundleShortVersionString</key> - <string>libcurl 7.64.0</string> + <string>libcurl 7.64.1</string> <key>CFBundleGetInfoString</key> - <string>libcurl.plist 7.64.0</string> + <string>libcurl.plist 7.64.1</string> </dict> </plist> diff --git a/libs/libcurl/src/md5.c b/libs/libcurl/src/md5.c index a17a58fa61..db4cc2656f 100644 --- a/libs/libcurl/src/md5.c +++ b/libs/libcurl/src/md5.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -83,7 +83,7 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx) gcry_md_close(*ctx); } -#elif defined(USE_OPENSSL) +#elif defined(USE_OPENSSL) && !defined(USE_AMISSL) /* When OpenSSL is available we use the MD5-function from OpenSSL */ #include <openssl/md5.h> #include "curl_memory.h" diff --git a/libs/libcurl/src/memdebug.c b/libs/libcurl/src/memdebug.c index 05590a8f83..e3ac8edf74 100644 --- a/libs/libcurl/src/memdebug.c +++ b/libs/libcurl/src/memdebug.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -100,19 +100,18 @@ struct memdebug { * Don't use these with multithreaded test programs! */ -#define logfile curl_debuglogfile -FILE *curl_debuglogfile = NULL; +FILE *curl_dbg_logfile = NULL; static bool memlimit = FALSE; /* enable memory limit */ static long memsize = 0; /* set number of mallocs allowed */ /* this sets the log file name */ -void curl_memdebug(const char *logname) +void curl_dbg_memdebug(const char *logname) { - if(!logfile) { + if(!curl_dbg_logfile) { if(logname && *logname) - logfile = fopen(logname, FOPEN_WRITETEXT); + curl_dbg_logfile = fopen(logname, FOPEN_WRITETEXT); else - logfile = stderr; + curl_dbg_logfile = stderr; #ifdef MEMDEBUG_LOG_SYNC /* Flush the log file after every line so the log isn't lost in a crash */ if(logfile) @@ -123,7 +122,7 @@ void curl_memdebug(const char *logname) /* This function sets the number of malloc() calls that should return successfully! */ -void curl_memlimit(long limit) +void curl_dbg_memlimit(long limit) { if(!memlimit) { memlimit = TRUE; @@ -140,12 +139,12 @@ static bool countcheck(const char *func, int line, const char *source) if(!memsize) { if(source) { /* log to file */ - curl_memlog("LIMIT %s:%d %s reached memlimit\n", - source, line, func); + curl_dbg_log("LIMIT %s:%d %s reached memlimit\n", + source, line, func); /* log to stderr also */ fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", source, line, func); - fflush(logfile); /* because it might crash now */ + fflush(curl_dbg_logfile); /* because it might crash now */ } errno = ENOMEM; return TRUE; /* RETURN ERROR! */ @@ -159,7 +158,7 @@ static bool countcheck(const char *func, int line, const char *source) return FALSE; /* allow this */ } -void *curl_domalloc(size_t wantedsize, int line, const char *source) +void *curl_dbg_malloc(size_t wantedsize, int line, const char *source) { struct memdebug *mem; size_t size; @@ -180,15 +179,15 @@ void *curl_domalloc(size_t wantedsize, int line, const char *source) } if(source) - curl_memlog("MEM %s:%d malloc(%zu) = %p\n", - source, line, wantedsize, - mem ? (void *)mem->mem : (void *)0); + curl_dbg_log("MEM %s:%d malloc(%zu) = %p\n", + source, line, wantedsize, + mem ? (void *)mem->mem : (void *)0); return (mem ? mem->mem : NULL); } -void *curl_docalloc(size_t wanted_elements, size_t wanted_size, - int line, const char *source) +void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, + int line, const char *source) { struct memdebug *mem; size_t size, user_size; @@ -208,14 +207,14 @@ void *curl_docalloc(size_t wanted_elements, size_t wanted_size, mem->size = user_size; if(source) - curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n", - source, line, wanted_elements, wanted_size, - mem ? (void *)mem->mem : (void *)0); + curl_dbg_log("MEM %s:%d calloc(%zu,%zu) = %p\n", + source, line, wanted_elements, wanted_size, + mem ? (void *)mem->mem : (void *)0); return (mem ? mem->mem : NULL); } -char *curl_dostrdup(const char *str, int line, const char *source) +char *curl_dbg_strdup(const char *str, int line, const char *source) { char *mem; size_t len; @@ -227,19 +226,19 @@ char *curl_dostrdup(const char *str, int line, const char *source) len = strlen(str) + 1; - mem = curl_domalloc(len, 0, NULL); /* NULL prevents logging */ + mem = curl_dbg_malloc(len, 0, NULL); /* NULL prevents logging */ if(mem) memcpy(mem, str, len); if(source) - curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n", - source, line, (const void *)str, len, (const void *)mem); + curl_dbg_log("MEM %s:%d strdup(%p) (%zu) = %p\n", + source, line, (const void *)str, len, (const void *)mem); return mem; } #if defined(WIN32) && defined(UNICODE) -wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source) +wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source) { wchar_t *mem; size_t wsiz, bsiz; @@ -252,12 +251,12 @@ wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source) wsiz = wcslen(str) + 1; bsiz = wsiz * sizeof(wchar_t); - mem = curl_domalloc(bsiz, 0, NULL); /* NULL prevents logging */ + mem = curl_dbg_malloc(bsiz, 0, NULL); /* NULL prevents logging */ if(mem) memcpy(mem, str, bsiz); if(source) - curl_memlog("MEM %s:%d wcsdup(%p) (%zu) = %p\n", + curl_dbg_log("MEM %s:%d wcsdup(%p) (%zu) = %p\n", source, line, (void *)str, bsiz, (void *)mem); return mem; @@ -266,8 +265,8 @@ wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source) /* We provide a realloc() that accepts a NULL as pointer, which then performs a malloc(). In order to work with ares. */ -void *curl_dorealloc(void *ptr, size_t wantedsize, - int line, const char *source) +void *curl_dbg_realloc(void *ptr, size_t wantedsize, + int line, const char *source) { struct memdebug *mem = NULL; @@ -293,7 +292,7 @@ void *curl_dorealloc(void *ptr, size_t wantedsize, mem = (Curl_crealloc)(mem, size); if(source) - curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n", + curl_dbg_log("MEM %s:%d realloc(%p, %zu) = %p\n", source, line, (void *)ptr, wantedsize, mem ? (void *)mem->mem : (void *)0); @@ -305,7 +304,7 @@ void *curl_dorealloc(void *ptr, size_t wantedsize, return NULL; } -void curl_dofree(void *ptr, int line, const char *source) +void curl_dbg_free(void *ptr, int line, const char *source) { struct memdebug *mem; @@ -331,11 +330,11 @@ void curl_dofree(void *ptr, int line, const char *source) } if(source) - curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr); + curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr); } -curl_socket_t curl_socket(int domain, int type, int protocol, - int line, const char *source) +curl_socket_t curl_dbg_socket(int domain, int type, int protocol, + int line, const char *source) { const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? "FD %s:%d socket() = %d\n" : @@ -351,44 +350,44 @@ curl_socket_t curl_socket(int domain, int type, int protocol, sockfd = socket(domain, type, protocol); if(source && (sockfd != CURL_SOCKET_BAD)) - curl_memlog(fmt, source, line, sockfd); + curl_dbg_log(fmt, source, line, sockfd); return sockfd; } -SEND_TYPE_RETV curl_dosend(SEND_TYPE_ARG1 sockfd, - SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, - SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line, - const char *source) +SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, + SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, + SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line, + const char *source) { SEND_TYPE_RETV rc; if(countcheck("send", line, source)) return -1; rc = send(sockfd, buf, len, flags); if(source) - curl_memlog("SEND %s:%d send(%lu) = %ld\n", + curl_dbg_log("SEND %s:%d send(%lu) = %ld\n", source, line, (unsigned long)len, (long)rc); return rc; } -RECV_TYPE_RETV curl_dorecv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf, - RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line, - const char *source) +RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf, + RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line, + const char *source) { RECV_TYPE_RETV rc; if(countcheck("recv", line, source)) return -1; rc = recv(sockfd, buf, len, flags); if(source) - curl_memlog("RECV %s:%d recv(%lu) = %ld\n", + curl_dbg_log("RECV %s:%d recv(%lu) = %ld\n", source, line, (unsigned long)len, (long)rc); return rc; } #ifdef HAVE_SOCKETPAIR -int curl_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], - int line, const char *source) +int curl_dbg_socketpair(int domain, int type, int protocol, + curl_socket_t socket_vector[2], + int line, const char *source) { const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? "FD %s:%d socketpair() = %d %d\n" : @@ -399,14 +398,14 @@ int curl_socketpair(int domain, int type, int protocol, int res = socketpair(domain, type, protocol, socket_vector); if(source && (0 == res)) - curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]); + curl_dbg_log(fmt, source, line, socket_vector[0], socket_vector[1]); return res; } #endif -curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen, - int line, const char *source) +curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, + int line, const char *source) { const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? "FD %s:%d accept() = %d\n" : @@ -420,13 +419,13 @@ curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen, curl_socket_t sockfd = accept(s, addr, addrlen); if(source && (sockfd != CURL_SOCKET_BAD)) - curl_memlog(fmt, source, line, sockfd); + curl_dbg_log(fmt, source, line, sockfd); return sockfd; } /* separate function to allow libcurl to mark a "faked" close */ -void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source) +void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source) { const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? "FD %s:%d sclose(%d)\n": @@ -435,54 +434,40 @@ void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source) "FD %s:%d sclose(%zd)\n"; if(source) - curl_memlog(fmt, source, line, sockfd); + curl_dbg_log(fmt, source, line, sockfd); } /* this is our own defined way to close sockets on *ALL* platforms */ -int curl_sclose(curl_socket_t sockfd, int line, const char *source) +int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source) { int res = sclose(sockfd); - curl_mark_sclose(sockfd, line, source); + curl_dbg_mark_sclose(sockfd, line, source); return res; } -FILE *curl_fopen(const char *file, const char *mode, - int line, const char *source) +FILE *curl_dbg_fopen(const char *file, const char *mode, + int line, const char *source) { FILE *res = fopen(file, mode); if(source) - curl_memlog("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", + curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", source, line, file, mode, (void *)res); return res; } -#ifdef HAVE_FDOPEN -FILE *curl_fdopen(int filedes, const char *mode, - int line, const char *source) -{ - FILE *res = fdopen(filedes, mode); - - if(source) - curl_memlog("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n", - source, line, filedes, mode, (void *)res); - - return res; -} -#endif - -int curl_fclose(FILE *file, int line, const char *source) +int curl_dbg_fclose(FILE *file, int line, const char *source) { int res; DEBUGASSERT(file != NULL); - res = fclose(file); - if(source) - curl_memlog("FILE %s:%d fclose(%p)\n", - source, line, (void *)file); + curl_dbg_log("FILE %s:%d fclose(%p)\n", + source, line, (void *)file); + + res = fclose(file); return res; } @@ -490,13 +475,13 @@ int curl_fclose(FILE *file, int line, const char *source) #define LOGLINE_BUFSIZE 1024 /* this does the writing to the memory tracking log file */ -void curl_memlog(const char *format, ...) +void curl_dbg_log(const char *format, ...) { char *buf; int nchars; va_list ap; - if(!logfile) + if(!curl_dbg_logfile) return; buf = (Curl_cmalloc)(LOGLINE_BUFSIZE); @@ -511,7 +496,7 @@ void curl_memlog(const char *format, ...) nchars = LOGLINE_BUFSIZE - 1; if(nchars > 0) - fwrite(buf, 1, (size_t)nchars, logfile); + fwrite(buf, 1, (size_t)nchars, curl_dbg_logfile); (Curl_cfree)(buf); } diff --git a/libs/libcurl/src/memdebug.h b/libs/libcurl/src/memdebug.h index 233de65a47..5236f60fa5 100644 --- a/libs/libcurl/src/memdebug.h +++ b/libs/libcurl/src/memdebug.h @@ -8,7 +8,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,97 +30,92 @@ #define CURL_MT_LOGFNAME_BUFSIZE 512 -#define logfile curl_debuglogfile - -extern FILE *logfile; +extern FILE *curl_dbg_logfile; /* memory functions */ -CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source); -CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line, - const char *source); -CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line, - const char *source); -CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source); -CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source); -#if defined(WIN32) && defined(UNICODE) -CURL_EXTERN wchar_t *curl_dowcsdup(const wchar_t *str, int line, +CURL_EXTERN void *curl_dbg_malloc(size_t size, int line, const char *source); +CURL_EXTERN void *curl_dbg_calloc(size_t elements, size_t size, int line, + const char *source); +CURL_EXTERN void *curl_dbg_realloc(void *ptr, size_t size, int line, const char *source); +CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source); +CURL_EXTERN char *curl_dbg_strdup(const char *str, int line, const char *src); +#if defined(WIN32) && defined(UNICODE) +CURL_EXTERN wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, + const char *source); #endif -CURL_EXTERN void curl_memdebug(const char *logname); -CURL_EXTERN void curl_memlimit(long limit); -CURL_EXTERN void curl_memlog(const char *format, ...); +CURL_EXTERN void curl_dbg_memdebug(const char *logname); +CURL_EXTERN void curl_dbg_memlimit(long limit); +CURL_EXTERN void curl_dbg_log(const char *format, ...); /* file descriptor manipulators */ -CURL_EXTERN curl_socket_t curl_socket(int domain, int type, int protocol, - int line, const char *source); -CURL_EXTERN void curl_mark_sclose(curl_socket_t sockfd, - int line, const char *source); -CURL_EXTERN int curl_sclose(curl_socket_t sockfd, - int line, const char *source); -CURL_EXTERN curl_socket_t curl_accept(curl_socket_t s, void *a, void *alen, +CURL_EXTERN curl_socket_t curl_dbg_socket(int domain, int type, int protocol, + int line, const char *source); +CURL_EXTERN void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source); -#ifdef HAVE_SOCKETPAIR -CURL_EXTERN int curl_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], +CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source); +CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, void *a, void *alen, + int line, const char *source); +#ifdef HAVE_SOCKETPAIR +CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol, + curl_socket_t socket_vector[2], + int line, const char *source); #endif /* send/receive sockets */ -CURL_EXTERN SEND_TYPE_RETV curl_dosend(SEND_TYPE_ARG1 sockfd, - SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, - SEND_TYPE_ARG3 len, - SEND_TYPE_ARG4 flags, int line, - const char *source); -CURL_EXTERN RECV_TYPE_RETV curl_dorecv(RECV_TYPE_ARG1 sockfd, - RECV_TYPE_ARG2 buf, RECV_TYPE_ARG3 len, - RECV_TYPE_ARG4 flags, int line, - const char *source); +CURL_EXTERN SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, + SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, + SEND_TYPE_ARG3 len, + SEND_TYPE_ARG4 flags, int line, + const char *source); +CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, + RECV_TYPE_ARG2 buf, + RECV_TYPE_ARG3 len, + RECV_TYPE_ARG4 flags, int line, + const char *source); /* FILE functions */ -CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line, - const char *source); -#ifdef HAVE_FDOPEN -CURL_EXTERN FILE *curl_fdopen(int filedes, const char *mode, int line, - const char *source); -#endif -CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source); +CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line, + const char *source); +CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); #ifndef MEMDEBUG_NODEFINES /* Set this symbol on the command-line, recompile all lib-sources */ #undef strdup -#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__) -#define malloc(size) curl_domalloc(size, __LINE__, __FILE__) -#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__) -#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__) -#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__) -#define send(a,b,c,d) curl_dosend(a,b,c,d, __LINE__, __FILE__) -#define recv(a,b,c,d) curl_dorecv(a,b,c,d, __LINE__, __FILE__) +#define strdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) +#define malloc(size) curl_dbg_malloc(size, __LINE__, __FILE__) +#define calloc(nbelem,size) curl_dbg_calloc(nbelem, size, __LINE__, __FILE__) +#define realloc(ptr,size) curl_dbg_realloc(ptr, size, __LINE__, __FILE__) +#define free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__) +#define send(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__) +#define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__) #ifdef WIN32 # ifdef UNICODE # undef wcsdup -# define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__) +# define wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) # undef _wcsdup -# define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__) +# define _wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) # undef _tcsdup -# define _tcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__) +# define _tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) # else # undef _tcsdup -# define _tcsdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__) +# define _tcsdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) # endif #endif #undef socket #define socket(domain,type,protocol)\ - curl_socket(domain, type, protocol, __LINE__, __FILE__) + curl_dbg_socket(domain, type, protocol, __LINE__, __FILE__) #undef accept /* for those with accept as a macro */ #define accept(sock,addr,len)\ - curl_accept(sock, addr, len, __LINE__, __FILE__) + curl_dbg_accept(sock, addr, len, __LINE__, __FILE__) #ifdef HAVE_SOCKETPAIR #define socketpair(domain,type,protocol,socket_vector)\ - curl_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__) + curl_dbg_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__) #endif #ifdef HAVE_GETADDRINFO @@ -129,31 +124,31 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source); our macro as for other platforms. Instead, we redefine the new name they define getaddrinfo to become! */ #define ogetaddrinfo(host,serv,hint,res) \ - curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__) + curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) #else #undef getaddrinfo #define getaddrinfo(host,serv,hint,res) \ - curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__) + curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) #endif #endif /* HAVE_GETADDRINFO */ #ifdef HAVE_FREEADDRINFO #undef freeaddrinfo #define freeaddrinfo(data) \ - curl_dofreeaddrinfo(data, __LINE__, __FILE__) + curl_dbg_freeaddrinfo(data, __LINE__, __FILE__) #endif /* HAVE_FREEADDRINFO */ /* sclose is probably already defined, redefine it! */ #undef sclose -#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__) +#define sclose(sockfd) curl_dbg_sclose(sockfd,__LINE__,__FILE__) -#define fake_sclose(sockfd) curl_mark_sclose(sockfd,__LINE__,__FILE__) +#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd,__LINE__,__FILE__) #undef fopen -#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__) +#define fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__) #undef fdopen -#define fdopen(file,mode) curl_fdopen(file,mode,__LINE__,__FILE__) -#define fclose(file) curl_fclose(file,__LINE__,__FILE__) +#define fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__) +#define fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__) #endif /* MEMDEBUG_NODEFINES */ diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c index ca492d11ae..48147d4f59 100644 --- a/libs/libcurl/src/mime.c +++ b/libs/libcurl/src/mime.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1122,8 +1122,6 @@ void curl_mime_free(curl_mime *mime) Curl_mime_cleanpart(part); free(part); } - - free(mime->boundary); free(mime); } } @@ -1220,18 +1218,10 @@ curl_mime *curl_mime_init(struct Curl_easy *easy) mime->firstpart = NULL; mime->lastpart = NULL; - /* Get a part boundary. */ - mime->boundary = malloc(24 + MIME_RAND_BOUNDARY_CHARS + 1); - if(!mime->boundary) { - free(mime); - return NULL; - } - memset(mime->boundary, '-', 24); - if(Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24, + if(Curl_rand_hex(easy, (unsigned char *) &mime->boundary[24], MIME_RAND_BOUNDARY_CHARS + 1)) { /* failed to get random separator, bail out */ - free(mime->boundary); free(mime); return NULL; } diff --git a/libs/libcurl/src/mime.h b/libs/libcurl/src/mime.h index 4d5c70404d..0721c8ca45 100644 --- a/libs/libcurl/src/mime.h +++ b/libs/libcurl/src/mime.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -88,13 +88,16 @@ typedef struct { size_t offset; /* State-dependent offset. */ } mime_state; +/* minimum buffer size for the boundary string */ +#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1) + /* A mime multipart. */ struct curl_mime_s { struct Curl_easy *easy; /* The associated easy handle. */ curl_mimepart *parent; /* Parent part. */ curl_mimepart *firstpart; /* First part. */ curl_mimepart *lastpart; /* Last part. */ - char *boundary; /* The part boundary. */ + char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */ mime_state state; /* Current readback state. */ }; diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index 130226f561..cc16924a3c 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -80,6 +80,7 @@ static CURLMcode add_next_timeout(struct curltime now, static CURLMcode multi_timeout(struct Curl_multi *multi, long *timeout_ms); static void process_pending_handles(struct Curl_multi *multi); +static void detach_connnection(struct Curl_easy *data); #ifdef DEBUGBUILD static const char * const statename[]={ @@ -114,7 +115,7 @@ static void Curl_init_completed(struct Curl_easy *data) /* Important: reset the conn pointer so that we don't point to memory that could be freed anytime */ - Curl_detach_connnection(data); + detach_connnection(data); Curl_expire_clear(data); /* stop all timers */ } @@ -496,6 +497,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, data->set.server_response_timeout; data->state.conn_cache->closure_handle->set.no_signal = data->set.no_signal; + data->state.conn_cache->closure_handle->set.verbose = + data->set.verbose; update_timer(multi); return CURLM_OK; @@ -572,7 +575,7 @@ static CURLcode multi_done(struct Curl_easy *data, if(conn->send_pipe.size || conn->recv_pipe.size) { /* Stop if pipeline is not empty . */ - Curl_detach_connnection(data); + detach_connnection(data); DEBUGF(infof(data, "Connection still in use %zu/%zu, " "no more multi_done now!\n", conn->send_pipe.size, conn->recv_pipe.size)); @@ -597,7 +600,7 @@ static CURLcode multi_done(struct Curl_easy *data, /* if data->set.reuse_forbid is TRUE, it means the libcurl client has forced us to close this connection. This is ignored for requests taking - place in a NTLM authentication handshake + place in a NTLM/NEGOTIATE authentication handshake if conn->bits.close is TRUE, it means that the connection should be closed in spite of all our efforts to be nice, due to protocol @@ -615,6 +618,10 @@ static CURLcode multi_done(struct Curl_easy *data, && !(conn->ntlm.state == NTLMSTATE_TYPE2 || conn->proxyntlm.state == NTLMSTATE_TYPE2) #endif +#if defined(USE_SPNEGO) + && !(conn->negotiate.state == GSS_AUTHRECV || + conn->proxyneg.state == GSS_AUTHRECV) +#endif ) || conn->bits.close || (premature && !(conn->handler->flags & PROTOPT_STREAM))) { CURLcode res2 = Curl_disconnect(data, conn, premature); @@ -645,7 +652,7 @@ static CURLcode multi_done(struct Curl_easy *data, data->state.lastconnect = NULL; } - Curl_detach_connnection(data); + detach_connnection(data); Curl_free_request_state(data); return result; } @@ -752,7 +759,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, /* Remove the association between the connection and the handle */ if(data->conn) { data->conn->data = NULL; - Curl_detach_connnection(data); + detach_connnection(data); } #ifdef USE_LIBPSL @@ -804,7 +811,7 @@ bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits) /* This is the only function that should clear data->conn. This will occasionally be called with the pointer already cleared. */ -void Curl_detach_connnection(struct Curl_easy *data) +static void detach_connnection(struct Curl_easy *data) { data->conn = NULL; } @@ -998,11 +1005,11 @@ CURLMcode Curl_multi_wait(struct Curl_multi *multi, unsigned int i; unsigned int nfds = 0; unsigned int curlfds; - struct pollfd *ufds = NULL; bool ufds_malloc = FALSE; long timeout_internal; int retcode = 0; struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; + struct pollfd *ufds = &a_few_on_stack[0]; if(gotsocket) *gotsocket = FALSE; @@ -1047,19 +1054,15 @@ CURLMcode Curl_multi_wait(struct Curl_multi *multi, curlfds = nfds; /* number of internal file descriptors */ nfds += extra_nfds; /* add the externally provided ones */ - if(nfds) { - if(nfds > NUM_POLLS_ON_STACK) { - /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes - big, so at 2^29 sockets this value might wrap. When a process gets - the capability to actually handle over 500 million sockets this - calculation needs a integer overflow check. */ - ufds = malloc(nfds * sizeof(struct pollfd)); - if(!ufds) - return CURLM_OUT_OF_MEMORY; - ufds_malloc = TRUE; - } - else - ufds = &a_few_on_stack[0]; + if(nfds > NUM_POLLS_ON_STACK) { + /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes + big, so at 2^29 sockets this value might wrap. When a process gets + the capability to actually handle over 500 million sockets this + calculation needs a integer overflow check. */ + ufds = malloc(nfds * sizeof(struct pollfd)); + if(!ufds) + return CURLM_OUT_OF_MEMORY; + ufds_malloc = TRUE; } nfds = 0; @@ -1154,17 +1157,6 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi, { return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, NULL); } -/* - * Curl_multi_connchanged() is called to tell that there is a connection in - * this multi handle that has changed state (pipelining become possible, the - * number of allowed streams changed or similar), and a subsequent use of this - * multi handle should move CONNECT_PEND handles back to CONNECT to have them - * retry. - */ -void Curl_multi_connchanged(struct Curl_multi *multi) -{ - multi->recheckstate = TRUE; -} /* * multi_ischanged() is called @@ -1207,57 +1199,6 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, return rc; } -static CURLcode multi_reconnect_request(struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - - /* This was a re-use of a connection and we got a write error in the - * DO-phase. Then we DISCONNECT this connection and have another attempt to - * CONNECT and then DO again! The retry cannot possibly find another - * connection to re-use, since we only keep one possible connection for - * each. */ - - infof(data, "Re-used connection seems dead, get a new one\n"); - - connclose(conn, "Reconnect dead connection"); /* enforce close */ - result = multi_done(data, result, FALSE); /* we are so done with this */ - - /* data->conn was detached in multi_done() */ - - /* - * We need to check for CURLE_SEND_ERROR here as well. This could happen - * when the request failed on a FTP connection and thus multi_done() itself - * tried to use the connection (again). - */ - if(!result || (CURLE_SEND_ERROR == result)) { - bool async; - bool protocol_done = TRUE; - - /* Now, redo the connect and get a new connection */ - result = Curl_connect(data, &async, &protocol_done); - if(!result) { - /* We have connected or sent away a name resolve query fine */ - - conn = data->conn; /* in case it was updated */ - if(async) { - /* Now, if async is TRUE here, we need to wait for the name - to resolve */ - result = Curl_resolver_wait_resolv(conn, NULL); - if(result) - return result; - - /* Resolved, continue with the connection */ - result = Curl_once_resolved(conn, &protocol_done); - if(result) - return result; - } - } - } - - return result; -} - /* * do_complete is called when the DO actions are complete. * @@ -1267,8 +1208,6 @@ static CURLcode multi_reconnect_request(struct Curl_easy *data) static void do_complete(struct connectdata *conn) { conn->data->req.chunk = FALSE; - conn->data->req.maxfd = (conn->sockfd>conn->writesockfd? - conn->sockfd:conn->writesockfd) + 1; Curl_pgrsTime(conn->data, TIMER_PRETRANSFER); } @@ -1281,27 +1220,6 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done) /* generic protocol-specific function pointer set in curl_connect() */ result = conn->handler->do_it(conn, done); - /* This was formerly done in transfer.c, but we better do it here */ - if((CURLE_SEND_ERROR == result) && conn->bits.reuse) { - /* - * If the connection is using an easy handle, call reconnect - * to re-establish the connection. Otherwise, let the multi logic - * figure out how to re-establish the connection. - */ - if(!data->multi) { - result = multi_reconnect_request(data); - - if(!result) { - /* ... finally back to actually retry the DO phase */ - conn = data->conn; /* re-assign conn since multi_reconnect_request - creates a new connection */ - result = conn->handler->do_it(conn, done); - } - } - else - return result; - } - if(!result && *done) /* do_complete must be called after the protocol-specific DO function */ do_complete(conn); @@ -1549,7 +1467,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(result) /* if Curl_once_resolved() returns failure, the connection struct is already freed and gone */ - Curl_detach_connnection(data); /* no more connection */ + detach_connnection(data); /* no more connection */ else { /* call again please so that we get the next socket setup */ rc = CURLM_CALL_MULTI_PERFORM; @@ -1620,7 +1538,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } else if(result) { /* failure detected */ - /* Just break, the cleaning up is handled all in one place */ + Curl_posttransfer(data); + multi_done(data, result, TRUE); stream_error = TRUE; break; } @@ -1933,13 +1852,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, k = &data->req; - if(!(k->keepon & KEEP_RECV)) + if(!(k->keepon & KEEP_RECV)) { /* We're done receiving */ Curl_pipeline_leave_read(data->conn); + } - if(!(k->keepon & KEEP_SEND)) + if(!(k->keepon & KEEP_SEND)) { /* We're done sending */ Curl_pipeline_leave_write(data->conn); + } if(done || (result == CURLE_RECV_ERROR)) { /* If CURLE_RECV_ERROR happens early enough, we assume it was a race @@ -2087,7 +2008,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, * removed before we perform the processing in CURLM_STATE_COMPLETED */ if(data->conn) - Curl_detach_connnection(data); + detach_connnection(data); } if(data->state.wildcardmatch) { @@ -2145,7 +2066,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* This is where we make sure that the conn pointer is reset. We don't have to do this in every case block above where a failure is detected */ - Curl_detach_connnection(data); + detach_connnection(data); } } else if(data->mstate == CURLM_STATE_CONNECT) { @@ -2298,8 +2219,9 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) Curl_psl_destroy(&multi->psl); /* Free the blacklists by setting them to NULL */ - Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl); - Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl); + (void)Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl); + (void)Curl_pipeline_set_server_blacklist(NULL, + &multi->pipelining_server_bl); free(multi); @@ -2360,8 +2282,6 @@ static CURLMcode singlesocket(struct Curl_multi *multi, int num; unsigned int curraction; int actions[MAX_SOCKSPEREASYHANDLE]; - unsigned int comboaction; - bool sincebefore = FALSE; for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) socks[i] = CURL_SOCKET_BAD; @@ -2380,6 +2300,8 @@ static CURLMcode singlesocket(struct Curl_multi *multi, i++) { unsigned int action = CURL_POLL_NONE; unsigned int prevaction = 0; + unsigned int comboaction; + bool sincebefore = FALSE; s = socks[i]; @@ -3028,9 +2950,6 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id) DEBUGASSERT(id < EXPIRE_LAST); - infof(data, "Expire in %ld ms for %x (transfer %p)\n", - (long)milli, id, data); - set = Curl_now(); set.tv_sec += milli/1000; set.tv_usec += (unsigned int)(milli%1000)*1000; diff --git a/libs/libcurl/src/non-ascii.c b/libs/libcurl/src/non-ascii.c index 14143248fb..42beaec45d 100644 --- a/libs/libcurl/src/non-ascii.c +++ b/libs/libcurl/src/non-ascii.c @@ -78,7 +78,7 @@ CURLcode Curl_convert_clone(struct Curl_easy *data, /* * Curl_convert_to_network() is an internal function for performing ASCII - * conversions on non-ASCII platforms. It convers the buffer _in place_. + * conversions on non-ASCII platforms. It converts the buffer _in place_. */ CURLcode Curl_convert_to_network(struct Curl_easy *data, char *buffer, size_t length) @@ -144,7 +144,7 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data, /* * Curl_convert_from_network() is an internal function for performing ASCII - * conversions on non-ASCII platforms. It convers the buffer _in place_. + * conversions on non-ASCII platforms. It converts the buffer _in place_. */ CURLcode Curl_convert_from_network(struct Curl_easy *data, char *buffer, size_t length) diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c index bc007883e3..a98c50b460 100644 --- a/libs/libcurl/src/openldap.c +++ b/libs/libcurl/src/openldap.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2010, Howard Chu, <hyc@openldap.org> - * Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2011 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -414,7 +414,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done) return CURLE_OUT_OF_MEMORY; lr->msgid = msgid; data->req.protop = lr; - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); *done = TRUE; return CURLE_OK; } diff --git a/libs/libcurl/src/pop3.c b/libs/libcurl/src/pop3.c index 4f65f289b4..8dbd448b2c 100644 --- a/libs/libcurl/src/pop3.c +++ b/libs/libcurl/src/pop3.c @@ -912,7 +912,7 @@ static CURLcode pop3_state_command_resp(struct connectdata *conn, if(pop3->transfer == FTPTRANSFER_BODY) { /* POP3 download */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); if(pp->cache) { /* The header "cache" contains a bunch of data that is actually body diff --git a/libs/libcurl/src/rand.h b/libs/libcurl/src/rand.h index c6fae35537..5deb041613 100644 --- a/libs/libcurl/src/rand.h +++ b/libs/libcurl/src/rand.h @@ -39,8 +39,11 @@ */ CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num); -/* Same as above but outputs only random lowercase hex characters. - Does NOT terminate.*/ +/* + * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random + * hexadecimal digits PLUS a zero terminating byte. It must be an odd number + * size. + */ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, size_t num); diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c index 01dfce640c..b9a8ef5e86 100644 --- a/libs/libcurl/src/rtsp.c +++ b/libs/libcurl/src/rtsp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -80,8 +80,6 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data, bool *readmore); static CURLcode rtsp_setup_connection(struct connectdata *conn); - -bool rtsp_connisdead(struct connectdata *check); static unsigned int rtsp_conncheck(struct connectdata *check, unsigned int checks_to_perform); @@ -147,7 +145,7 @@ static CURLcode rtsp_setup_connection(struct connectdata *conn) * Instead, if it is readable, run Curl_connalive() to peek at the socket * and distinguish between closed and data. */ -bool rtsp_connisdead(struct connectdata *check) +static bool rtsp_connisdead(struct connectdata *check) { int sval; bool ret_val = TRUE; @@ -251,7 +249,6 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) CURLcode result = CURLE_OK; Curl_RtspReq rtspreq = data->set.rtspreq; struct RTSP *rtsp = data->req.protop; - struct HTTP *http; Curl_send_buffer *req_buffer; curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */ curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */ @@ -270,10 +267,6 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) *done = TRUE; - http = &(rtsp->http_wrapper); - /* Assert that no one has changed the RTSP struct in an evil way */ - DEBUGASSERT((void *)http == (void *)rtsp); - rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq; rtsp->CSeq_recv = 0; @@ -330,8 +323,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) } if(rtspreq == RTSPREQ_RECEIVE) { - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); return result; } @@ -599,17 +591,15 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) return result; } - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount, - putsize?FIRSTSOCKET:-1, - putsize?&http->writebytecount:NULL); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, putsize?FIRSTSOCKET:-1); /* Increment the CSeq on success */ data->state.rtsp_next_client_CSeq++; - if(http->writebytecount) { + if(data->req.writebytecount) { /* if a request-body has been sent off, we make sure this progress is noted properly */ - Curl_pgrsSetUploadCounter(data, http->writebytecount); + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); if(Curl_pgrsUpdate(conn)) result = CURLE_ABORTED_BY_CALLBACK; } diff --git a/libs/libcurl/src/security.c b/libs/libcurl/src/security.c index 7f13071f6f..eec6e6f446 100644 --- a/libs/libcurl/src/security.c +++ b/libs/libcurl/src/security.c @@ -10,7 +10,7 @@ * Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Hgskolan * (Royal Institute of Technology, Stockholm, Sweden). * - * Copyright (C) 2001 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2001 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * All rights reserved. * @@ -142,7 +142,7 @@ socket_read(curl_socket_t fd, void *to, size_t len) { char *to_p = to; CURLcode result; - ssize_t nread; + ssize_t nread = 0; while(len > 0) { result = Curl_read_plain(fd, to_p, len, &nread); diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index e8598e6173..5008d9333d 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -411,8 +411,9 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num, *code = CURLE_AGAIN; } else { + char buffer[STRERROR_LEN]; failf(conn->data, "Send failure: %s", - Curl_strerror(conn, err)); + Curl_strerror(err, buffer, sizeof(buffer))); conn->data->state.os_errno = err; *code = CURLE_SEND_ERROR; } @@ -476,8 +477,9 @@ ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, *code = CURLE_AGAIN; } else { + char buffer[STRERROR_LEN]; failf(conn->data, "Recv failure: %s", - Curl_strerror(conn, err)); + Curl_strerror(err, buffer, sizeof(buffer))); conn->data->state.os_errno = err; *code = CURLE_RECV_ERROR; } diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index d98ca66c91..b5f74a93db 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -44,6 +44,7 @@ #include "http2.h" #include "setopt.h" #include "multiif.h" +#include "altsvc.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -111,8 +112,8 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) #define C_SSLVERSION_VALUE(x) (x & 0xffff) #define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000) -CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, - va_list param) +static CURLcode vsetopt(struct Curl_easy *data, CURLoption option, + va_list param) { char *argptr; CURLcode result = CURLE_OK; @@ -682,7 +683,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, * Set header option. */ arg = va_arg(param, long); - data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE; + data->set.sep_headers = (bool)((arg & CURLHEADER_SEPARATE)? TRUE: FALSE); break; case CURLOPT_HTTP200ALIASES: @@ -884,7 +885,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE; + data->state.authhost.iestyle = + (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -967,7 +969,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE; + data->state.authproxy.iestyle = + (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -2076,13 +2079,15 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, case CURLOPT_SSL_OPTIONS: arg = va_arg(param, long); - data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE; + data->set.ssl.enable_beast = + (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); break; case CURLOPT_PROXY_SSL_OPTIONS: arg = va_arg(param, long); - data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE; + data->set.proxy_ssl.enable_beast = + (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); break; @@ -2651,6 +2656,31 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, data->set.trailer_data = va_arg(param, void *); #endif break; +#ifdef USE_ALTSVC + case CURLOPT_ALTSVC: + if(!data->asi) { + data->asi = Curl_altsvc_init(); + if(!data->asi) + return CURLE_OUT_OF_MEMORY; + } + argptr = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_ALTSVC], argptr); + if(result) + return result; + (void)Curl_altsvc_load(data->asi, argptr); + break; + case CURLOPT_ALTSVC_CTRL: + if(!data->asi) { + data->asi = Curl_altsvc_init(); + if(!data->asi) + return CURLE_OUT_OF_MEMORY; + } + arg = va_arg(param, long); + result = Curl_altsvc_ctrl(data->asi, arg); + if(result) + return result; + break; +#endif default: /* unknown tag and its companion, just ignore: */ result = CURLE_UNKNOWN_OPTION; @@ -2679,7 +2709,7 @@ CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...) va_start(arg, tag); - result = Curl_vsetopt(data, tag, arg); + result = vsetopt(data, tag, arg); va_end(arg); return result; diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c index d55647b12e..f3db714b5a 100644 --- a/libs/libcurl/src/smtp.c +++ b/libs/libcurl/src/smtp.c @@ -959,7 +959,7 @@ static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode, Curl_pgrsSetUploadSize(data, data->state.infilesize); /* SMTP upload */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); /* End of DO phase */ state(conn, SMTP_STOP); @@ -1388,7 +1388,7 @@ static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected) if(smtp->transfer != FTPTRANSFER_BODY) /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); return CURLE_OK; } diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c index d2209ad899..d0aba0605a 100644 --- a/libs/libcurl/src/socks.c +++ b/libs/libcurl/src/socks.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -54,7 +54,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */ ssize_t buffersize, /* max amount to read */ ssize_t *n) /* amount bytes read */ { - ssize_t nread; + ssize_t nread = 0; ssize_t allread = 0; int result; *n = 0; diff --git a/libs/libcurl/src/socks_sspi.c b/libs/libcurl/src/socks_sspi.c index bedb01ebbc..57027ef686 100644 --- a/libs/libcurl/src/socks_sspi.c +++ b/libs/libcurl/src/socks_sspi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com> * * This software is licensed as described in the file COPYING, which @@ -51,8 +51,9 @@ static int check_sspi_err(struct connectdata *conn, status != SEC_I_COMPLETE_AND_CONTINUE && status != SEC_I_COMPLETE_NEEDED && status != SEC_I_CONTINUE_NEEDED) { + char buffer[STRERROR_LEN]; failf(conn->data, "SSPI error: %s failed: %s", function, - Curl_sspi_strerror(conn, status)); + Curl_sspi_strerror(status, buffer, sizeof(buffer))); return 1; } return 0; diff --git a/libs/libcurl/src/ssh-libssh.c b/libs/libcurl/src/ssh-libssh.c index 333df03ef2..609da1e09b 100644 --- a/libs/libcurl/src/ssh-libssh.c +++ b/libs/libcurl/src/ssh-libssh.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2017 - 2018 Red Hat, Inc. + * Copyright (C) 2017 - 2019 Red Hat, Inc. * * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek, * Robert Kolcun, Andreas Schneider @@ -1200,7 +1200,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) Curl_pgrsSetUploadSize(data, data->state.infilesize); } /* upload data */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); /* not set by Curl_setup_transfer to preserve keepon bits */ conn->sockfd = conn->writesockfd; @@ -1462,7 +1462,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) sshc->sftp_dir = NULL; /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); state(conn, SSH_STOP); break; @@ -1603,13 +1603,12 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) /* Setup the actual download */ if(data->req.size == 0) { /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); infof(data, "File already completely downloaded\n"); state(conn, SSH_STOP); break; } - Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size, - FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1); /* not set by Curl_setup_transfer to preserve keepon bits */ conn->writesockfd = conn->sockfd; @@ -1731,8 +1730,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) } /* upload data */ - Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL, - FIRSTSOCKET, NULL); + Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET); /* not set by Curl_setup_transfer to preserve keepon bits */ conn->sockfd = conn->writesockfd; @@ -1775,8 +1773,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) /* download data */ bytecount = ssh_scp_request_get_size(sshc->scp_session); data->req.maxdownload = (curl_off_t) bytecount; - Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, - NULL); + Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1); /* not set by Curl_setup_transfer to preserve keepon bits */ conn->writesockfd = conn->sockfd; @@ -2398,13 +2395,9 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status, /* Post quote commands are executed after the SFTP_CLOSE state to avoid errors that could happen due to open file handles during POSTQUOTE operation */ - if(!status && !premature && conn->data->set.postquote && - !conn->bits.retry) { + if(!premature && conn->data->set.postquote && !conn->bits.retry) sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; - state(conn, SSH_SFTP_CLOSE); - } - else - state(conn, SSH_SFTP_CLOSE); + state(conn, SSH_SFTP_CLOSE); } return myssh_done(conn, status); } diff --git a/libs/libcurl/src/ssh.c b/libs/libcurl/src/ssh.c index 8c68adcc17..46f52eceb0 100644 --- a/libs/libcurl/src/ssh.c +++ b/libs/libcurl/src/ssh.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -81,11 +81,11 @@ #include "multiif.h" #include "select.h" #include "warnless.h" +#include "curl_path.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" -#include "curl_path.h" #include "memdebug.h" #if LIBSSH2_VERSION_NUM >= 0x010206 @@ -1808,7 +1808,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_pgrsSetUploadSize(data, data->state.infilesize); } /* upload data */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); /* not set by Curl_setup_transfer to preserve keepon bits */ conn->sockfd = conn->writesockfd; @@ -2105,7 +2105,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->readdir_longentry); /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); state(conn, SSH_STOP); break; @@ -2245,13 +2245,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* Setup the actual download */ if(data->req.size == 0) { /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); infof(data, "File already completely downloaded\n"); state(conn, SSH_STOP); break; } - Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size, - FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1); /* not set by Curl_setup_transfer to preserve keepon bits */ conn->writesockfd = conn->sockfd; @@ -2395,8 +2394,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } /* upload data */ - Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL, - FIRSTSOCKET, NULL); + Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET); /* not set by Curl_setup_transfer to preserve keepon bits */ conn->sockfd = conn->writesockfd; @@ -2467,7 +2465,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* download data */ bytecount = (curl_off_t)sb.st_size; data->req.maxdownload = (curl_off_t)sb.st_size; - Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1); /* not set by Curl_setup_transfer to preserve keepon bits */ conn->writesockfd = conn->sockfd; @@ -2791,9 +2789,12 @@ static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done) CURLcode result = CURLE_OK; bool block; /* we store the status and use that to provide a ssh_getsock() implementation */ - - result = ssh_statemach_act(conn, &block); - *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; + do { + result = ssh_statemach_act(conn, &block); + *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; + /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then + try again */ + } while(!result && !*done && !block); ssh_block2waitfor(conn, block); return result; @@ -3222,13 +3223,9 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status, /* Post quote commands are executed after the SFTP_CLOSE state to avoid errors that could happen due to open file handles during POSTQUOTE operation */ - if(!status && !premature && conn->data->set.postquote && - !conn->bits.retry) { + if(!premature && conn->data->set.postquote && !conn->bits.retry) sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; - state(conn, SSH_SFTP_CLOSE); - } - else - state(conn, SSH_SFTP_CLOSE); + state(conn, SSH_SFTP_CLOSE); } return ssh_done(conn, status); } diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c index bf30c89077..e273f3765c 100644 --- a/libs/libcurl/src/strerror.c +++ b/libs/libcurl/src/strerror.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2004 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2004 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -646,20 +646,18 @@ get_winsock_error (int err, char *buf, size_t len) * We don't do range checking (on systems other than Windows) since there is * no good reliable and portable way to do it. */ -const char *Curl_strerror(struct connectdata *conn, int err) +const char *Curl_strerror(int err, char *buf, size_t buflen) { #ifdef PRESERVE_WINDOWS_ERROR_CODE DWORD old_win_err = GetLastError(); #endif int old_errno = errno; - char *buf, *p; + char *p; size_t max; - DEBUGASSERT(conn); DEBUGASSERT(err >= 0); - buf = conn->syserr_buf; - max = sizeof(conn->syserr_buf)-1; + max = buflen - 1; *buf = '\0'; #ifdef USE_WINSOCK @@ -757,7 +755,7 @@ const char *Curl_strerror(struct connectdata *conn, int err) } #ifdef USE_WINDOWS_SSPI -const char *Curl_sspi_strerror (struct connectdata *conn, int err) +const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) { #ifdef PRESERVE_WINDOWS_ERROR_CODE DWORD old_win_err = GetLastError(); @@ -768,15 +766,13 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err) size_t outmax; #ifndef CURL_DISABLE_VERBOSE_STRINGS char txtbuf[80]; - char msgbuf[sizeof(conn->syserr_buf)]; + char msgbuf[256]; char *p, *str, *msg = NULL; bool msg_formatted = FALSE; #endif - DEBUGASSERT(conn); - - outbuf = conn->syserr_buf; - outmax = sizeof(conn->syserr_buf)-1; + outbuf = buf; + outmax = buflen - 1; *outbuf = '\0'; #ifndef CURL_DISABLE_VERBOSE_STRINGS diff --git a/libs/libcurl/src/strerror.h b/libs/libcurl/src/strerror.h index 627273eb26..683b5b4a3a 100644 --- a/libs/libcurl/src/strerror.h +++ b/libs/libcurl/src/strerror.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -24,14 +24,11 @@ #include "urldata.h" -const char *Curl_strerror (struct connectdata *conn, int err); - -#ifdef USE_LIBIDN2 -const char *Curl_idn_strerror (struct connectdata *conn, int err); -#endif +#define STRERROR_LEN 128 /* a suitable length */ +const char *Curl_strerror(int err, char *buf, size_t buflen); #ifdef USE_WINDOWS_SSPI -const char *Curl_sspi_strerror (struct connectdata *conn, int err); +const char *Curl_sspi_strerror(int err, char *buf, size_t buflen); #endif #endif /* HEADER_CURL_STRERROR_H */ diff --git a/libs/libcurl/src/system_win32.c b/libs/libcurl/src/system_win32.c index 6b8004e5bb..f7f817dd45 100644 --- a/libs/libcurl/src/system_win32.c +++ b/libs/libcurl/src/system_win32.c @@ -26,12 +26,94 @@ #include <curl/curl.h> #include "system_win32.h" +#include "curl_sspi.h" #include "warnless.h" /* The last #include files should be: */ #include "curl_memory.h" #include "memdebug.h" +LARGE_INTEGER Curl_freq; +bool Curl_isVistaOrGreater; + +/* Curl_win32_init() performs win32 global initialization */ +CURLcode Curl_win32_init(long flags) +{ + /* CURL_GLOBAL_WIN32 controls the *optional* part of the initialization which + is just for Winsock at the moment. Any required win32 initialization + should take place after this block. */ + if(flags & CURL_GLOBAL_WIN32) { +#ifdef USE_WINSOCK + WORD wVersionRequested; + WSADATA wsaData; + int res; + +#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2) +#error IPV6_requires_winsock2 +#endif + + wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); + + res = WSAStartup(wVersionRequested, &wsaData); + + if(res != 0) + /* Tell the user that we couldn't find a usable */ + /* winsock.dll. */ + return CURLE_FAILED_INIT; + + /* Confirm that the Windows Sockets DLL supports what we need.*/ + /* Note that if the DLL supports versions greater */ + /* than wVersionRequested, it will still return */ + /* wVersionRequested in wVersion. wHighVersion contains the */ + /* highest supported version. */ + + if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || + HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { + /* Tell the user that we couldn't find a usable */ + + /* winsock.dll. */ + WSACleanup(); + return CURLE_FAILED_INIT; + } + /* The Windows Sockets DLL is acceptable. Proceed. */ + #elif defined(USE_LWIPSOCK) + lwip_init(); + #endif + } /* CURL_GLOBAL_WIN32 */ + +#ifdef USE_WINDOWS_SSPI + { + CURLcode result = Curl_sspi_global_init(); + if(result) + return result; + } +#endif + + if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) { + Curl_isVistaOrGreater = TRUE; + QueryPerformanceFrequency(&Curl_freq); + } + else + Curl_isVistaOrGreater = FALSE; + + return CURLE_OK; +} + +/* Curl_win32_cleanup() is the opposite of Curl_win32_init() */ +void Curl_win32_cleanup(long init_flags) +{ +#ifdef USE_WINDOWS_SSPI + Curl_sspi_global_cleanup(); +#endif + + if(init_flags & CURL_GLOBAL_WIN32) { +#ifdef USE_WINSOCK + WSACleanup(); +#endif + } +} + #if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \ defined(USE_WINSOCK)) diff --git a/libs/libcurl/src/system_win32.h b/libs/libcurl/src/system_win32.h index 1e772856b2..926328a9aa 100644 --- a/libs/libcurl/src/system_win32.h +++ b/libs/libcurl/src/system_win32.h @@ -26,6 +26,12 @@ #if defined(WIN32) +extern LARGE_INTEGER Curl_freq; +extern bool Curl_isVistaOrGreater; + +CURLcode Curl_win32_init(long flags); +void Curl_win32_cleanup(long init_flags); + /* Version condition */ typedef enum { VERSION_LESS_THAN, diff --git a/libs/libcurl/src/telnet.c b/libs/libcurl/src/telnet.c index e4c0bac3dc..955255c36c 100644 --- a/libs/libcurl/src/telnet.c +++ b/libs/libcurl/src/telnet.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1692,7 +1692,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) } #endif /* mark this as "no further transfer wanted" */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); return result; } diff --git a/libs/libcurl/src/tftp.c b/libs/libcurl/src/tftp.c index 269b3cde4b..8b92b7bd68 100644 --- a/libs/libcurl/src/tftp.c +++ b/libs/libcurl/src/tftp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -540,7 +540,8 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event) state->conn->ip_addr->ai_addr, state->conn->ip_addr->ai_addrlen); if(senddata != (ssize_t)sbytes) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); + char buffer[STRERROR_LEN]; + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); } free(filename); break; @@ -590,6 +591,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) ssize_t sbytes; int rblock; struct Curl_easy *data = state->conn->data; + char buffer[STRERROR_LEN]; switch(event) { @@ -622,7 +624,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) (struct sockaddr *)&state->remote_addr, state->remote_addrlen); if(sbytes < 0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } @@ -647,7 +649,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) (struct sockaddr *)&state->remote_addr, state->remote_addrlen); if(sbytes < 0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } @@ -673,7 +675,7 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) (struct sockaddr *)&state->remote_addr, state->remote_addrlen); if(sbytes<0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } } @@ -713,6 +715,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) CURLcode result = CURLE_OK; struct SingleRequest *k = &data->req; size_t cb; /* Bytes currently read */ + char buffer[STRERROR_LEN]; switch(event) { @@ -747,7 +750,8 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) state->remote_addrlen); /* Check all sbytes were sent */ if(sbytes<0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); + failf(data, "%s", Curl_strerror(SOCKERRNO, + buffer, sizeof(buffer))); result = CURLE_SEND_ERROR; } } @@ -791,7 +795,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) state->remote_addrlen); /* Check all sbytes were sent */ if(sbytes<0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } /* Update the progress meter */ @@ -817,7 +821,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) state->remote_addrlen); /* Check all sbytes were sent */ if(sbytes<0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } /* since this was a re-send, we remain at the still byte position */ @@ -1030,8 +1034,9 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr, conn->ip_addr->ai_addrlen); if(rc) { + char buffer[STRERROR_LEN]; failf(conn->data, "bind() failed; %s", - Curl_strerror(conn, SOCKERRNO)); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_COULDNT_CONNECT; } conn->bits.bound = TRUE; @@ -1242,7 +1247,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done) *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE; if(*done) /* Tell curl we're done */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); } else { /* no timeouts to handle, check our socket */ @@ -1251,7 +1256,8 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done) if(rc == -1) { /* bail out */ int error = SOCKERRNO; - failf(data, "%s", Curl_strerror(conn, error)); + char buffer[STRERROR_LEN]; + failf(data, "%s", Curl_strerror(error, buffer, sizeof(buffer))); state->event = TFTP_EVENT_ERROR; } else if(rc != 0) { @@ -1264,7 +1270,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done) *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE; if(*done) /* Tell curl we're done */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + Curl_setup_transfer(data, -1, -1, FALSE, -1); } /* if rc == 0, then select() timed out */ } diff --git a/libs/libcurl/src/timeval.c b/libs/libcurl/src/timeval.c index 2569f175c3..ff8d8a69af 100644 --- a/libs/libcurl/src/timeval.c +++ b/libs/libcurl/src/timeval.c @@ -21,30 +21,22 @@ ***************************************************************************/ #include "timeval.h" -#include "system_win32.h" #if defined(WIN32) && !defined(MSDOS) +/* set in win32_init() */ +extern LARGE_INTEGER Curl_freq; +extern bool Curl_isVistaOrGreater; + struct curltime Curl_now(void) { struct curltime now; - static LARGE_INTEGER freq; - static int isVistaOrGreater = -1; - if(isVistaOrGreater == -1) { - if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) { - isVistaOrGreater = 1; - QueryPerformanceFrequency(&freq); - } - else - isVistaOrGreater = 0; - } - if(isVistaOrGreater == 1) { /* QPC timer might have issues pre-Vista */ + if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */ LARGE_INTEGER count; QueryPerformanceCounter(&count); - now.tv_sec = (time_t)(count.QuadPart / freq.QuadPart); - now.tv_usec = - (int)((count.QuadPart % freq.QuadPart) * 1000000 / freq.QuadPart); + now.tv_sec = (time_t)(count.QuadPart / Curl_freq.QuadPart); + now.tv_usec = (int)((count.QuadPart % Curl_freq.QuadPart) * 1000000 / + Curl_freq.QuadPart); } else { /* Disable /analyze warning that GetTickCount64 is preferred */ diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index 3a18c7bdd0..ca6031724b 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -296,10 +296,10 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, here, knowing they'll become CRLFs later on. */ - char hexbuffer[11]; + char hexbuffer[11] = ""; + int hexlen = 0; const char *endofline_native; const char *endofline_network; - int hexlen = 0; if( #ifdef CURL_DO_LINEEND_CONV @@ -354,12 +354,14 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, length = nread; else /* just translate the protocol portion */ - length = strlen(hexbuffer); - result = Curl_convert_to_network(data, data->req.upload_fromhere, - length); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) - return result; + length = hexlen; + if(length) { + result = Curl_convert_to_network(data, data->req.upload_fromhere, + length); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(result) + return result; + } } #endif /* CURL_DOES_CONVERSIONS */ @@ -1196,6 +1198,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, (size_t)bytes_written); k->writebytecount += bytes_written; + Curl_pgrsSetUploadCounter(data, k->writebytecount); if((!k->upload_chunky || k->forbidchunk) && (k->writebytecount == data->state.infilesize)) { @@ -1229,7 +1232,6 @@ static CURLcode readwrite_upload(struct Curl_easy *data, } } - Curl_pgrsSetUploadCounter(data, k->writebytecount); } WHILE_FALSE; /* just to break out from! */ @@ -1307,11 +1309,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, k->now = Curl_now(); if(didwhat) { - /* Update read/write counters */ - if(k->bytecountp) - *k->bytecountp = k->bytecount; /* read count */ - if(k->writebytecountp) - *k->writebytecountp = k->writebytecount; /* write count */ + ; } else { /* no read no write, this is a timeout? */ @@ -1526,11 +1524,14 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) if(data->set.httpreq == HTTPREQ_PUT) data->state.infilesize = data->set.filesize; - else { + else if((data->set.httpreq != HTTPREQ_GET) && + (data->set.httpreq != HTTPREQ_HEAD)) { data->state.infilesize = data->set.postfieldsize; if(data->set.postfields && (data->state.infilesize == -1)) data->state.infilesize = (curl_off_t)strlen(data->set.postfields); } + else + data->state.infilesize = 0; /* If there is a list of cookie files to read, do it now! */ if(data->change.cookielist) @@ -1852,8 +1853,7 @@ CURLcode Curl_retry_request(struct connectdata *conn, if(conn->handler->protocol&PROTO_FAMILY_HTTP) { - struct HTTP *http = data->req.protop; - if(http->writebytecount) { + if(data->req.writebytecount) { CURLcode result = Curl_readrewind(conn); if(result) { Curl_safefree(*url); @@ -1871,24 +1871,17 @@ CURLcode Curl_retry_request(struct connectdata *conn, */ void Curl_setup_transfer( - struct connectdata *conn, /* connection data */ + struct Curl_easy *data, /* transfer */ int sockindex, /* socket index to read from or -1 */ curl_off_t size, /* -1 if unknown at this point */ bool getheader, /* TRUE if header parsing is wanted */ - curl_off_t *bytecountp, /* return number of bytes read or NULL */ - int writesockindex, /* socket index to write to, it may very well be + int writesockindex /* socket index to write to, it may very well be the same we read from. -1 disables */ - curl_off_t *writecountp /* return number of bytes written or NULL */ ) { - struct Curl_easy *data; - struct SingleRequest *k; - + struct SingleRequest *k = &data->req; + struct connectdata *conn = data->conn; DEBUGASSERT(conn != NULL); - - data = conn->data; - k = &data->req; - DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); if(conn->bits.multiplex || conn->httpversion == 20) { @@ -1907,8 +1900,6 @@ Curl_setup_transfer( k->getheader = getheader; k->size = size; - k->bytecountp = bytecountp; - k->writebytecountp = writecountp; /* The code sequence below is placed in this function just because all necessary input is not always known in do_complete() as this function may diff --git a/libs/libcurl/src/transfer.h b/libs/libcurl/src/transfer.h index 9742455ae8..a9bff63486 100644 --- a/libs/libcurl/src/transfer.h +++ b/libs/libcurl/src/transfer.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -59,15 +59,13 @@ CURLcode Curl_get_upload_buffer(struct Curl_easy *data); /* This sets up a forthcoming transfer */ void -Curl_setup_transfer (struct connectdata *data, - int sockindex, /* socket index to read from or -1 */ - curl_off_t size, /* -1 if unknown at this point */ - bool getheader, /* TRUE if header parsing is wanted */ - curl_off_t *bytecountp, /* return number of bytes read */ - int writesockindex, /* socket index to write to, it may - very well be the same we read from. - -1 disables */ - curl_off_t *writecountp /* return number of bytes written */ -); +Curl_setup_transfer (struct Curl_easy *data, + int sockindex, /* socket index to read from or -1 */ + curl_off_t size, /* -1 if unknown at this point */ + bool getheader, /* TRUE if header parsing is wanted */ + int writesockindex /* socket index to write to. May be + the same we read from. -1 + disables */ + ); #endif /* HEADER_CURL_TRANSFER_H */ diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index d5a982008e..eb09a24be2 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -120,6 +120,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "dotdot.h" #include "strdup.h" #include "setopt.h" +#include "altsvc.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -292,7 +293,7 @@ void Curl_freeset(struct Curl_easy *data) } /* free the URL pieces */ -void Curl_up_free(struct Curl_easy *data) +static void up_free(struct Curl_easy *data) { struct urlpieces *up = &data->state.up; Curl_safefree(up->scheme); @@ -303,7 +304,8 @@ void Curl_up_free(struct Curl_easy *data) Curl_safefree(up->options); Curl_safefree(up->path); Curl_safefree(up->query); - curl_url_cleanup(data->state.uh); + if(data->set.uh != data->state.uh) + curl_url_cleanup(data->state.uh); data->state.uh = NULL; } @@ -369,11 +371,16 @@ CURLcode Curl_close(struct Curl_easy *data) } data->change.referer = NULL; - Curl_up_free(data); + up_free(data); Curl_safefree(data->state.buffer); Curl_safefree(data->state.headerbuff); Curl_safefree(data->state.ulbuf); Curl_flush_cookies(data, 1); +#ifdef USE_ALTSVC + Curl_altsvc_save(data->asi, data->set.str[STRING_ALTSVC]); + Curl_altsvc_cleanup(data->asi); + data->asi = NULL; +#endif Curl_digest_cleanup(data); Curl_safefree(data->info.contenttype); Curl_safefree(data->info.wouldredirect); @@ -660,11 +667,15 @@ static void conn_reset_all_postponed_data(struct connectdata *conn) #define conn_reset_all_postponed_data(c) do {} WHILE_FALSE #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ -static void conn_free(struct connectdata *conn) + +static void conn_shutdown(struct connectdata *conn) { if(!conn) return; + infof(conn->data, "Closing connection %ld\n", conn->connection_id); + DEBUGASSERT(conn->data); + /* possible left-overs from the async name resolvers */ Curl_resolver_cancel(conn); @@ -688,6 +699,21 @@ static void conn_free(struct connectdata *conn) Curl_ntlm_wb_cleanup(conn); #endif + /* unlink ourselves. this should be called last since other shutdown + procedures need a valid conn->data and this may clear it. */ + Curl_conncache_remove_conn(conn->data, conn, TRUE); +} + +static void conn_free(struct connectdata *conn) +{ + if(!conn) + return; + + free_idnconverted_hostname(&conn->host); + free_idnconverted_hostname(&conn->conn_to_host); + free_idnconverted_hostname(&conn->http_proxy.host); + free_idnconverted_hostname(&conn->socks_proxy.host); + Curl_safefree(conn->user); Curl_safefree(conn->passwd); Curl_safefree(conn->oauth_bearer); @@ -780,27 +806,20 @@ CURLcode Curl_disconnect(struct Curl_easy *data, /* Cleanup NTLM connection-related data */ Curl_http_ntlm_cleanup(conn); #endif +#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) + /* Cleanup NEGOTIATE connection-related data */ + Curl_cleanup_negotiate(conn); +#endif - /* the protocol specific disconnect handler needs a transfer for its - connection! */ + /* the protocol specific disconnect handler and conn_shutdown need a transfer + for the connection! */ conn->data = data; + if(conn->handler->disconnect) /* This is set if protocol-specific cleanups should be made */ conn->handler->disconnect(conn, dead_connection); - /* unlink ourselves! */ - infof(data, "Closing connection %ld\n", conn->connection_id); - Curl_conncache_remove_conn(data, conn, TRUE); - - free_idnconverted_hostname(&conn->host); - free_idnconverted_hostname(&conn->conn_to_host); - free_idnconverted_hostname(&conn->http_proxy.host); - free_idnconverted_hostname(&conn->socks_proxy.host); - - /* this assumes that the pointer is still there after the connection was - detected from the cache */ - Curl_ssl_close(conn, FIRSTSOCKET); - + conn_shutdown(conn); conn_free(conn); return CURLE_OK; } @@ -956,7 +975,7 @@ static bool extract_if_dead(struct connectdata *conn, struct Curl_easy *data) { size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size; - if(!pipeLen && !CONN_INUSE(conn)) { + if(!pipeLen && !CONN_INUSE(conn) && !conn->data) { /* The check for a dead socket makes sense only if there are no handles in pipeline and the connection isn't already marked in use */ @@ -965,7 +984,10 @@ static bool extract_if_dead(struct connectdata *conn, /* The protocol has a special method for checking the state of the connection. Use it to check if the connection is dead. */ unsigned int state; + struct Curl_easy *olddata = conn->data; + conn->data = data; /* use this transfer for now */ state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD); + conn->data = olddata; dead = (state & CONNRESULT_DEAD); } else { @@ -994,7 +1016,6 @@ struct prunedead { static int call_extract_if_dead(struct connectdata *conn, void *param) { struct prunedead *p = (struct prunedead *)param; - conn->data = p->data; /* transfer to use for this check */ if(extract_if_dead(conn, p->data)) { /* stop the iteration here, pass back the connection that was extracted */ p->extracted = conn; @@ -1132,6 +1153,10 @@ ConnectionExists(struct Curl_easy *data, check = curr->ptr; curr = curr->next; + if(check->bits.connect_only) + /* connect-only connections will not be reused */ + continue; + if(extract_if_dead(check, data)) { /* disconnect it */ (void)Curl_disconnect(data, check, /* dead_connection */TRUE); @@ -1262,14 +1287,15 @@ ConnectionExists(struct Curl_easy *data, } } - if(!canpipe && CONN_INUSE(check)) + if(!canpipe && check->data) /* this request can't be pipelined but the checked connection is already in use so we skip it */ continue; - if(CONN_INUSE(check) && (check->data->multi != needle->data->multi)) - /* this could be subject for pipeline/multiplex use, but only - if they belong to the same multi handle */ + if(CONN_INUSE(check) && check->data && + (check->data->multi != needle->data->multi)) + /* this could be subject for pipeline/multiplex use, but only if they + belong to the same multi handle */ continue; if(needle->localdev || needle->localport) { @@ -1685,6 +1711,8 @@ static bool is_ASCII_name(const char *hostname) static void strip_trailing_dot(struct hostname *host) { size_t len; + if(!host || !host->name) + return; len = strlen(host->name); if(len && (host->name[len-1] == '.')) host->name[len-1] = 0; @@ -1749,15 +1777,6 @@ static CURLcode idnconvert_hostname(struct connectdata *conn, infof(data, "IDN support not present, can't parse Unicode domains\n"); #endif } - { - char *hostp; - for(hostp = host->name; *hostp; hostp++) { - if(*hostp <= 32) { - failf(data, "Host name '%s' contains bad letter", host->name); - return CURLE_URL_MALFORMAT; - } - } - } return CURLE_OK; } @@ -1899,8 +1918,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) data->set.proxy_ssl.primary.verifystatus; conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer; conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost; - conn->ip_version = data->set.ipver; + conn->bits.connect_only = data->set.connect_only; #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ defined(NTLM_WB_ENABLED) @@ -2029,11 +2048,11 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, CURLUcode uc; char *hostname; - Curl_up_free(data); /* cleanup previous leftovers first */ + up_free(data); /* cleanup previous leftovers first */ /* parse the URL */ if(data->set.uh) { - uh = data->set.uh; + uh = data->state.uh = data->set.uh; } else { uh = data->state.uh = curl_url(); @@ -3361,6 +3380,34 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, conn_to_host = conn_to_host->next; } +#ifdef USE_ALTSVC + if(data->asi && !host && (port == -1) && + (conn->handler->protocol == CURLPROTO_HTTPS)) { + /* no connect_to match, try alt-svc! */ + const char *nhost; + int nport; + enum alpnid nalpnid; + bool hit; + host = conn->host.rawalloc; + hit = Curl_altsvc_lookup(data->asi, + ALPN_h1, host, conn->remote_port, /* from */ + &nalpnid, &nhost, &nport /* to */); + if(hit) { + char *hostd = strdup((char *)nhost); + if(!hostd) + return CURLE_OUT_OF_MEMORY; + conn->conn_to_host.rawalloc = hostd; + conn->conn_to_host.name = hostd; + conn->bits.conn_to_host = TRUE; + conn->conn_to_port = nport; + conn->bits.conn_to_port = TRUE; + infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d\n", + Curl_alpnid2str(ALPN_h1), host, conn->remote_port, + Curl_alpnid2str(nalpnid), hostd, nport); + } + } +#endif + return result; } @@ -3374,6 +3421,8 @@ static CURLcode resolve_server(struct Curl_easy *data, CURLcode result = CURLE_OK; timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + DEBUGASSERT(conn); + DEBUGASSERT(data); /************************************************************* * Resolve the name of the server or proxy *************************************************************/ @@ -3789,9 +3838,8 @@ static CURLcode create_conn(struct Curl_easy *data, (void)conn->handler->done(conn, result, FALSE); goto out; } - - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ - -1, NULL); /* no upload */ + Curl_attach_connnection(data, conn); + Curl_setup_transfer(data, -1, -1, FALSE, -1); } /* since we skip do_init() */ @@ -3877,8 +3925,9 @@ static CURLcode create_conn(struct Curl_easy *data, /* reuse_fresh is TRUE if we are told to use a new connection by force, but we only acknowledge this option if this is not a re-used connection already (which happens due to follow-location or during a HTTP - authentication phase). */ - if(data->set.reuse_fresh && !data->state.this_is_a_follow) + authentication phase). CONNECT_ONLY transfers also refuse reuse. */ + if((data->set.reuse_fresh && !data->state.this_is_a_follow) || + data->set.connect_only) reuse = FALSE; else reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe); @@ -4170,7 +4219,8 @@ CURLcode Curl_connect(struct Curl_easy *data, connectdata struct, free those here */ Curl_disconnect(data, conn, TRUE); } - else + else if(!data->conn) + /* FILE: transfers already have the connection attached */ Curl_attach_connnection(data, conn); return result; diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c index 3af8e9399f..a19867eb0f 100644 --- a/libs/libcurl/src/urlapi.c +++ b/libs/libcurl/src/urlapi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -67,12 +67,6 @@ struct Curl_URL { #define DEFAULT_SCHEME "https" -#ifdef DEBUGBUILD -#define UNITTEST -#else -#define UNITTEST static -#endif - static void free_urlhandle(struct Curl_URL *u) { free(u->scheme); @@ -141,7 +135,7 @@ static bool urlchar_needs_escaping(int c) * URL encoding should be skipped for host names, otherwise IDN resolution * will fail. */ -size_t Curl_strlen_url(const char *url, bool relative) +static size_t strlen_url(const char *url, bool relative) { const unsigned char *ptr; size_t newlen = 0; @@ -183,7 +177,7 @@ size_t Curl_strlen_url(const char *url, bool relative) * URL encoding should be skipped for host names, otherwise IDN resolution * will fail. */ -void Curl_strcpy_url(char *output, const char *url, bool relative) +static void strcpy_url(char *output, const char *url, bool relative) { /* we must add this with whitespace-replacing */ bool left = TRUE; @@ -268,7 +262,7 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) * The returned pointer must be freed by the caller unless NULL * (returns NULL on out of memory). */ -char *Curl_concat_url(const char *base, const char *relurl) +static char *concat_url(const char *base, const char *relurl) { /*** TRY to append this new path to the old URL @@ -392,7 +386,7 @@ char *Curl_concat_url(const char *base, const char *relurl) letter we replace each space with %20 while it is replaced with '+' on the right side of the '?' letter. */ - newlen = Curl_strlen_url(useurl, !host_changed); + newlen = strlen_url(useurl, !host_changed); urllen = strlen(url_clone); @@ -414,7 +408,7 @@ char *Curl_concat_url(const char *base, const char *relurl) newest[urllen++]='/'; /* then append the new piece on the right side */ - Curl_strcpy_url(&newest[urllen], useurl, !host_changed); + strcpy_url(&newest[urllen], useurl, !host_changed); free(url_clone); @@ -574,15 +568,15 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname) /* scan for byte values < 31 or 127 */ static CURLUcode junkscan(char *part) { - char badbytes[]={ - /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 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 /* zero terminate */ - }; if(part) { + static const char badbytes[]={ + /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 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 /* zero terminate */ + }; size_t n = strlen(part); size_t nfine = strcspn(part, badbytes); if(nfine != n) @@ -1083,10 +1077,10 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, return CURLUE_OUT_OF_MEMORY; *part = url; return CURLUE_OK; - break; } default: ptr = NULL; + break; } if(ptr) { *part = strdup(ptr); @@ -1252,7 +1246,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, } /* apply the relative part to create a new URL */ - redired_url = Curl_concat_url(oldurl, part); + redired_url = concat_url(oldurl, part); free(oldurl); if(!redired_url) return CURLUE_OUT_OF_MEMORY; diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index ff3cc9a655..24187a4c48 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -129,12 +129,14 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ #ifdef HAVE_GSSAPI # ifdef HAVE_GSSGNU # include <gss.h> -# elif defined HAVE_GSSMIT +# elif defined HAVE_GSSAPI_GSSAPI_H # include <gssapi/gssapi.h> -# include <gssapi/gssapi_generic.h> # else # include <gssapi.h> # endif +# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H +# include <gssapi/gssapi_generic.h> +# endif #endif #ifdef HAVE_LIBSSH2_H @@ -154,13 +156,16 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ #define GOOD_EASY_HANDLE(x) \ ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER)) +/* the type we use for storing a single boolean bit */ +typedef unsigned int bit; + #ifdef HAVE_GSSAPI /* Types needed for krb5-ftp connections */ struct krb5buffer { void *data; size_t size; size_t index; - int eof_flag; + bit eof_flag:1; }; enum protection_level { @@ -198,21 +203,17 @@ struct ssl_connect_data { /* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm but at least asked to or meaning to use it. See 'state' for the exact current state of the connection. */ - bool use; ssl_connection_state state; ssl_connect_state connecting_state; #if defined(USE_SSL) struct ssl_backend_data *backend; #endif + bit use:1; }; struct ssl_primary_config { long version; /* what version the client wants to use */ long version_max; /* max supported version the client wants to use*/ - bool verifypeer; /* set TRUE if this is desired */ - bool verifyhost; /* set TRUE if CN/SAN must match hostname */ - bool verifystatus; /* set TRUE if certificate status must be checked */ - bool sessionid; /* cache session IDs or not */ char *CApath; /* certificate dir (doesn't work on windows) */ char *CAfile; /* certificate to verify peer against */ char *clientcert; @@ -220,32 +221,33 @@ struct ssl_primary_config { char *egdsocket; /* path to file containing the EGD daemon socket */ char *cipher_list; /* list of ciphers to use */ char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ + bit verifypeer:1; /* set TRUE if this is desired */ + bit verifyhost:1; /* set TRUE if CN/SAN must match hostname */ + bit verifystatus:1; /* set TRUE if certificate status must be checked */ + bit sessionid:1; /* cache session IDs or not */ }; struct ssl_config_data { struct ssl_primary_config primary; - bool enable_beast; /* especially allow this flaw for interoperability's - sake*/ - bool no_revoke; /* disable SSL certificate revocation checks */ long certverifyresult; /* result from the certificate verification */ char *CRLfile; /* CRL to check certificate revocation */ char *issuercert;/* optional issuer certificate filename */ curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ void *fsslctxp; /* parameter for call back */ - bool certinfo; /* gather lots of certificate info */ - bool falsestart; - char *cert; /* client certificate file name */ char *cert_type; /* format for certificate (default: PEM)*/ char *key; /* private key file name */ char *key_type; /* format for private key (default: PEM) */ char *key_passwd; /* plain text private key password */ - #ifdef USE_TLS_SRP char *username; /* TLS username (for, e.g., SRP) */ char *password; /* TLS password (for, e.g., SRP) */ enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */ #endif + bit certinfo:1; /* gather lots of certificate info */ + bit falsestart:1; + bit enable_beast:1; /* allow this flaw for interoperability's sake*/ + bit no_revoke:1; /* disable SSL certificate revocation checks */ }; struct ssl_general_config { @@ -284,12 +286,12 @@ struct digestdata { char *cnonce; char *realm; int algo; - bool stale; /* set true for re-negotiation */ char *opaque; char *qop; char *algorithm; int nc; /* nounce count */ - bool userhash; + bit stale:1; /* set true for re-negotiation */ + bit userhash:1; #endif }; @@ -356,7 +358,9 @@ struct ntlmdata { struct negotiatedata { /* When doing Negotiate (SPNEGO) auth, we first need to send a token and then validate the received one. */ - enum { GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT } state; + enum { + GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT, GSS_AUTHDONE, GSS_AUTHSUCC + } state; #ifdef HAVE_GSSAPI OM_uint32 status; gss_ctx_id_t context; @@ -378,6 +382,10 @@ struct negotiatedata { size_t output_token_length; #endif #endif + bool noauthpersist; + bool havenoauthpersist; + bool havenegdata; + bool havemultiplerequests; }; #endif @@ -387,69 +395,65 @@ struct negotiatedata { */ struct ConnectBits { /* always modify bits.close with the connclose() and connkeep() macros! */ - bool close; /* if set, we close the connection after this request */ - bool reuse; /* if set, this is a re-used connection */ - bool conn_to_host; /* if set, this connection has a "connect to host" - that overrides the host in the URL */ - bool conn_to_port; /* if set, this connection has a "connect to port" - that overrides the port in the URL (remote port) */ - bool proxy; /* if set, this transfer is done through a proxy - any type */ - bool httpproxy; /* if set, this transfer is done through a http proxy */ - bool socksproxy; /* if set, this transfer is done through a socks proxy */ - bool user_passwd; /* do we use user+password for this connection? */ - bool proxy_user_passwd; /* user+password for the proxy? */ - bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6 - IP address */ - bool ipv6; /* we communicate with a site using an IPv6 address */ - - bool do_more; /* this is set TRUE if the ->curl_do_more() function is - supposed to be called, after ->curl_do() */ - bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set - the first time on the first connect function call */ - bool protoconnstart;/* the protocol layer has STARTED its operation after - the TCP layer connect */ - - bool retry; /* this connection is about to get closed and then - re-attempted at another connection. */ - bool tunnel_proxy; /* if CONNECT is used to "tunnel" through the proxy. - This is implicit when SSL-protocols are used through - proxies, but can also be enabled explicitly by - apps */ - bool authneg; /* TRUE when the auth phase has started, which means - that we are creating a request with an auth header, - but it is not the final request in the auth - negotiation. */ - bool rewindaftersend;/* TRUE when the sending couldn't be stopped even - though it will be discarded. When the whole send - operation is done, we must call the data rewind - callback. */ - bool ftp_use_epsv; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out - EPSV doesn't work we disable it for the forthcoming - requests */ - - bool ftp_use_eprt; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out - EPRT doesn't work we disable it for the forthcoming - requests */ - bool ftp_use_data_ssl; /* Enabled SSL for the data connection */ - bool netrc; /* name+password provided by netrc */ - bool userpwd_in_url; /* name+password found in url */ - bool stream_was_rewound; /* Indicates that the stream was rewound after a - request read past the end of its response byte - boundary */ - bool proxy_connect_closed; /* set true if a proxy disconnected the - connection in a CONNECT request with auth, so - that libcurl should reconnect and continue. */ - bool bound; /* set true if bind() has already been done on this socket/ - connection */ - bool type_set; /* type= was used in the URL */ - bool multiplex; /* connection is multiplexed */ - - bool tcp_fastopen; /* use TCP Fast Open */ - bool tls_enable_npn; /* TLS NPN extension? */ - bool tls_enable_alpn; /* TLS ALPN extension? */ bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy is complete */ - bool socksproxy_connecting; /* connecting through a socks proxy */ + bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set + the first time on the first connect function call */ + bit close:1; /* if set, we close the connection after this request */ + bit reuse:1; /* if set, this is a re-used connection */ + bit conn_to_host:1; /* if set, this connection has a "connect to host" + that overrides the host in the URL */ + bit conn_to_port:1; /* if set, this connection has a "connect to port" + that overrides the port in the URL (remote port) */ + bit proxy:1; /* if set, this transfer is done through a proxy - any type */ + bit httpproxy:1; /* if set, this transfer is done through a http proxy */ + bit socksproxy:1; /* if set, this transfer is done through a socks proxy */ + bit user_passwd:1; /* do we use user+password for this connection? */ + bit proxy_user_passwd:1; /* user+password for the proxy? */ + bit ipv6_ip:1; /* we communicate with a remote site specified with pure IPv6 + IP address */ + bit ipv6:1; /* we communicate with a site using an IPv6 address */ + bit do_more:1; /* this is set TRUE if the ->curl_do_more() function is + supposed to be called, after ->curl_do() */ + bit protoconnstart:1;/* the protocol layer has STARTED its operation after + the TCP layer connect */ + bit retry:1; /* this connection is about to get closed and then + re-attempted at another connection. */ + bit tunnel_proxy:1; /* if CONNECT is used to "tunnel" through the proxy. + This is implicit when SSL-protocols are used through + proxies, but can also be enabled explicitly by + apps */ + bit authneg:1; /* TRUE when the auth phase has started, which means + that we are creating a request with an auth header, + but it is not the final request in the auth + negotiation. */ + bit rewindaftersend:1;/* TRUE when the sending couldn't be stopped even + though it will be discarded. When the whole send + operation is done, we must call the data rewind + callback. */ + bit ftp_use_epsv:1; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out + EPSV doesn't work we disable it for the forthcoming + requests */ + bit ftp_use_eprt:1; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out + EPRT doesn't work we disable it for the forthcoming + requests */ + bit ftp_use_data_ssl:1; /* Enabled SSL for the data connection */ + bit netrc:1; /* name+password provided by netrc */ + bit userpwd_in_url:1; /* name+password found in url */ + bit stream_was_rewound:1; /* The stream was rewound after a request read + past the end of its response byte boundary */ + bit proxy_connect_closed:1; /* TRUE if a proxy disconnected the connection + in a CONNECT request with auth, so that + libcurl should reconnect and continue. */ + bit bound:1; /* set true if bind() has already been done on this socket/ + connection */ + bit type_set:1; /* type= was used in the URL */ + bit multiplex:1; /* connection is multiplexed */ + bit tcp_fastopen:1; /* use TCP Fast Open */ + bit tls_enable_npn:1; /* TLS NPN extension? */ + bit tls_enable_alpn:1; /* TLS ALPN extension? */ + bit socksproxy_connecting:1; /* connecting through a socks proxy */ + bit connect_only:1; }; struct hostname { @@ -476,14 +480,13 @@ struct hostname { #define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE) #define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE) - struct Curl_async { char *hostname; int port; struct Curl_dns_entry *dns; - bool done; /* set TRUE when the lookup is complete */ int status; /* if done is TRUE, this is the status from the callback */ void *os_specific; /* 'struct thread_data' for Windows */ + bit done:1; /* set TRUE when the lookup is complete */ }; #define FIRSTSOCKET 0 @@ -541,25 +544,21 @@ struct dohdata { */ struct SingleRequest { curl_off_t size; /* -1 if unknown at this point */ - curl_off_t *bytecountp; /* return number of bytes read or NULL */ - curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, -1 means unlimited */ - curl_off_t *writebytecountp; /* return number of bytes written or NULL */ - curl_off_t bytecount; /* total number of bytes read */ curl_off_t writebytecount; /* number of bytes written */ - long headerbytecount; /* only count received headers */ - long deductheadercount; /* this amount of bytes doesn't count when we check - if anything has been transferred at the end of a - connection. We use this counter to make only a - 100 reply (without a following second response - code) result in a CURLE_GOT_NOTHING error code */ + curl_off_t headerbytecount; /* only count received headers */ + curl_off_t deductheadercount; /* this amount of bytes doesn't count when we + check if anything has been transferred at + the end of a connection. We use this + counter to make only a 100 reply (without a + following second response code) result in a + CURLE_GOT_NOTHING error code */ struct curltime start; /* transfer started at this time */ struct curltime now; /* current time */ - bool header; /* incoming data has HTTP header */ enum { HEADER_NORMAL, /* no bad header at all */ HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest @@ -575,7 +574,6 @@ struct SingleRequest { char *str_start; /* within buf */ char *end_ptr; /* within buf */ char *p; /* within headerbuff */ - bool content_range; /* set TRUE if Content-Range: was found */ curl_off_t offset; /* possible resume offset read from the Content-Range: header */ int httpcode; /* error code from the 'HTTP/1.? XXX' or @@ -588,19 +586,8 @@ struct SingleRequest { /* See sec 3.5, RFC2616. */ time_t timeofdoc; long bodywrites; - char *buf; - curl_socket_t maxfd; - int keepon; - - bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload - and we're uploading the last chunk */ - - bool ignorebody; /* we read a response-body but we ignore it! */ - bool ignorecl; /* This HTTP response has no body so we ignore the Content- - Length: header */ - char *location; /* This points to an allocated version of the Location: header data */ char *newurl; /* Set to the new URL to use when a redirect or a retry is @@ -610,24 +597,28 @@ struct SingleRequest { still left in the buffer, aimed for upload. */ ssize_t upload_present; - /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a - buffer, so the next read should read from where this pointer points to, - and the 'upload_present' contains the number of bytes available at this - position */ + /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a + buffer, so the next read should read from where this pointer points to, + and the 'upload_present' contains the number of bytes available at this + position */ char *upload_fromhere; - - bool chunk; /* if set, this is a chunked transfer-encoding */ - bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding - on upload */ - bool getheader; /* TRUE if header parsing is wanted */ - - bool forbidchunk; /* used only to explicitly forbid chunk-upload for - specific upload buffers. See readmoredata() in - http.c for details. */ - void *protop; /* Allocated protocol-specific data. Each protocol handler makes sure this points to data it needs. */ struct dohdata doh; /* DoH specific data for this request */ + bit header:1; /* incoming data has HTTP header */ + bit content_range:1; /* set TRUE if Content-Range: was found */ + bit upload_done:1; /* set to TRUE when doing chunked transfer-encoding + upload and we're uploading the last chunk */ + bit ignorebody:1; /* we read a response-body but we ignore it! */ + bit ignorecl:1; /* This HTTP response has no body so we ignore the + Content-Length: header */ + bit chunk:1; /* if set, this is a chunked transfer-encoding */ + bit upload_chunky:1; /* set TRUE if we are doing chunked transfer-encoding + on upload */ + bit getheader:1; /* TRUE if header parsing is wanted */ + bit forbidchunk:1; /* used only to explicitly forbid chunk-upload for + specific upload buffers. See readmoredata() in http.c + for details. */ }; /* @@ -775,13 +766,13 @@ struct http_connect_state { char *line_start; char *ptr; /* where to store more data */ curl_off_t cl; /* size of content to read and ignore */ - bool chunked_encoding; enum { TUNNEL_INIT, /* init/default/no tunnel state */ TUNNEL_CONNECT, /* CONNECT has been sent off */ TUNNEL_COMPLETE /* CONNECT response received completely */ } tunnel_state; - bool close_connection; + bit chunked_encoding:1; + bit close_connection:1; }; /* @@ -898,8 +889,6 @@ struct connectdata { #endif struct ssl_primary_config ssl_config; struct ssl_primary_config proxy_ssl_config; - bool tls_upgraded; - struct ConnectBits bits; /* various state-flags for this connection */ /* connecttime: when connect() is called on the current IP address. Used to @@ -946,7 +935,7 @@ struct connectdata { } allocptr; #ifdef HAVE_GSSAPI - int sec_complete; /* if Kerberos is enabled for this connection */ + bit sec_complete:1; /* if Kerberos is enabled for this connection */ enum protection_level command_prot; enum protection_level data_prot; enum protection_level request_data_prot; @@ -961,14 +950,6 @@ struct connectdata { struct kerberos5data krb5; /* variables into the structure definition, */ #endif /* however, some of them are ftp specific. */ - /* the two following *_inuse fields are only flags, not counters in any way. - If TRUE it means the channel is in use, and if FALSE it means the channel - is up for grabs by one. */ - - bool readchannel_inuse; /* whether the read channel is in use by an easy - handle */ - bool writechannel_inuse; /* whether the write channel is in use by an easy - handle */ struct curl_llist send_pipe; /* List of handles waiting to send on this pipeline */ struct curl_llist recv_pipe; /* List of handles waiting to read their @@ -1002,7 +983,11 @@ struct connectdata { #endif #endif - char syserr_buf [256]; /* buffer for Curl_strerror() */ +#ifdef USE_SPNEGO + struct negotiatedata negotiate; /* state data for host Negotiate auth */ + struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */ +#endif + /* data used for the asynch name resolve callback */ struct Curl_async async; @@ -1045,8 +1030,16 @@ struct connectdata { #ifdef USE_UNIX_SOCKETS char *unix_domain_socket; - bool abstract_unix_socket; + bit abstract_unix_socket:1; #endif + bit tls_upgraded:1; + /* the two following *_inuse fields are only flags, not counters in any way. + If TRUE it means the channel is in use, and if FALSE it means the channel + is up for grabs by one. */ + bit readchannel_inuse:1; /* whether the read channel is in use by an easy + handle */ + bit writechannel_inuse:1; /* whether the write channel is in use by an easy + handle */ }; /* The end of connectdata. */ @@ -1061,10 +1054,8 @@ struct PureInfo { int httpversion; /* the http version number X.Y = X*10+Y */ time_t filetime; /* If requested, this is might get set. Set to -1 if the time was unretrievable. */ - bool timecond; /* set to TRUE if the time condition didn't match, which - thus made the document NOT get fetched */ - long header_size; /* size of read header(s) in bytes */ - long request_size; /* the amount of bytes sent in the request(s) */ + curl_off_t header_size; /* size of read header(s) in bytes */ + curl_off_t request_size; /* the amount of bytes sent in the request(s) */ unsigned long proxyauthavail; /* what proxy auth types were announced */ unsigned long httpauthavail; /* what host auth types were announced */ long numconnects; /* how many new connection did libcurl created */ @@ -1081,16 +1072,16 @@ struct PureInfo { char conn_primary_ip[MAX_IPADR_LEN]; long conn_primary_port; - char conn_local_ip[MAX_IPADR_LEN]; long conn_local_port; - const char *conn_scheme; unsigned int conn_protocol; - struct curl_certinfo certs; /* info about the certs, only populated in OpenSSL builds. Asked for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ + + bit timecond:1; /* set to TRUE if the time condition didn't match, which + thus made the document NOT get fetched */ }; @@ -1104,7 +1095,6 @@ struct Progress { curl_off_t current_speed; /* uses the currently fastest transfer */ - bool callback; /* set when progress callback is used */ int width; /* screen width at download start */ int flags; /* see progress.h */ @@ -1125,7 +1115,6 @@ struct Progress { struct curltime t_startop; struct curltime t_acceptdata; - bool is_t_startransfer_set; /* upload speed limit */ struct curltime ul_limit_start; @@ -1139,6 +1128,8 @@ struct Progress { curl_off_t speeder[ CURR_TIME ]; struct curltime speeder_time[ CURR_TIME ]; int speeder_c; + bit callback:1; /* set when progress callback is used */ + bit is_t_startransfer_set:1; }; typedef enum { @@ -1150,7 +1141,6 @@ typedef enum { HTTPREQ_PUT, HTTPREQ_HEAD, HTTPREQ_OPTIONS, - HTTPREQ_CUSTOM, HTTPREQ_LAST /* last in list */ } Curl_HttpReq; @@ -1187,12 +1177,12 @@ struct auth { unsigned long picked; unsigned long avail; /* Bitmask for what the server reports to support for this resource */ - bool done; /* TRUE when the auth phase is done and ready to do the *actual* - request */ - bool multipass; /* TRUE if this is not yet authenticated but within the - auth multipass negotiation */ - bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should - be RFC compliant */ + bit done:1; /* TRUE when the auth phase is done and ready to do the + *actual* request */ + bit multipass:1; /* TRUE if this is not yet authenticated but within the + auth multipass negotiation */ + bit iestyle:1; /* TRUE if digest should be done IE-style or FALSE if it + should be RFC compliant */ }; struct Curl_http2_dep { @@ -1263,11 +1253,6 @@ struct UrlState { /* Points to the connection cache */ struct conncache *conn_cache; - /* when curl_easy_perform() is called, the multi handle is "owned" by - the easy handle so curl_easy_cleanup() on such an easy handle will - also close the multi handle! */ - bool multi_owned_by_easy; - /* buffers to store authentication data in, as parsed from input options */ struct curltime keeps_speed; /* for the progress meter really */ @@ -1280,8 +1265,6 @@ struct UrlState { char *ulbuf; /* allocated upload buffer or NULL */ curl_off_t current_speed; /* the ProgressShow() function sets this, bytes / second */ - bool this_is_a_follow; /* this is a followed Location: request */ - bool refused_stream; /* this was refused, try again */ char *first_host; /* host name of the first (not followed) request. if set, this should be the host name that we will sent authorization to, no else. Used to make Location: @@ -1294,29 +1277,17 @@ struct UrlState { unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */ struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */ char *scratch; /* huge buffer[set.buffer_size*2] for upload CRLF replacing */ - bool errorbuf; /* Set to TRUE if the error buffer is already filled in. - This must be set to FALSE every time _easy_perform() is - called. */ int os_errno; /* filled in with errno whenever an error occurs */ #ifdef HAVE_SIGNAL /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */ void (*prev_signal)(int sig); #endif - bool allow_port; /* Is set.use_port allowed to take effect or not. This - is always set TRUE when curl_easy_perform() is called. */ struct digestdata digest; /* state data for host Digest auth */ struct digestdata proxydigest; /* state data for proxy Digest auth */ -#ifdef USE_SPNEGO - struct negotiatedata negotiate; /* state data for host Negotiate auth */ - struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */ -#endif - struct auth authhost; /* auth details for host */ struct auth authproxy; /* auth details for proxy */ - bool authproblem; /* TRUE if there's some problem authenticating */ - void *resolver; /* resolver state, if it is used in the URL state - ares_channel f.e. */ @@ -1332,27 +1303,18 @@ struct UrlState { /* a place to store the most recently set FTP entrypath */ char *most_recent_ftp_entrypath; - /* set after initial USER failure, to prevent an authentication loop */ - bool ftp_trying_alternative; - bool wildcardmatch; /* enable wildcard matching */ int httpversion; /* the lowest HTTP version*10 reported by any server involved in this request */ - bool expect100header; /* TRUE if we added Expect: 100-continue */ #if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \ !defined(__SYMBIAN32__) /* do FTP line-end conversions on most platforms */ #define CURL_DO_LINEEND_CONV /* for FTP downloads: track CRLF sequences that span blocks */ - bool prev_block_had_trailing_cr; + bit prev_block_had_trailing_cr:1; /* for FTP downloads: how many CRLFs did we converted to LFs? */ curl_off_t crlf_conversions; #endif - bool slash_removed; /* set TRUE if the 'path' points to a path where the - initial URL slash separator has been taken off */ - bool use_range; - bool rangestringalloc; /* the range string is malloc()'ed */ - char *range; /* range, if used. See README for detailed specification on this syntax. */ curl_off_t resume_from; /* continue [ftp] transfer from here */ @@ -1368,19 +1330,12 @@ struct UrlState { size_t drain; /* Increased when this stream has data to read, even if its socket is not necessarily is readable. Decreased when checked. */ - bool done; /* set to FALSE when Curl_init_do() is called and set to TRUE - when multi_done() is called, to prevent multi_done() to get - invoked twice when the multi interface is used. */ curl_read_callback fread_func; /* read callback/function */ void *in; /* CURLOPT_READDATA */ struct Curl_easy *stream_depends_on; - bool stream_depends_e; /* set or don't set the Exclusive bit */ int stream_weight; -#ifdef CURLDEBUG - bool conncache_lock; -#endif CURLU *uh; /* URL handle for the current parsed URL */ struct urlpieces up; #ifndef CURL_DISABLE_HTTP @@ -1390,6 +1345,32 @@ struct UrlState { #endif trailers_state trailers_state; /* whether we are sending trailers and what stage are we at */ +#ifdef CURLDEBUG + bit conncache_lock:1; +#endif + /* when curl_easy_perform() is called, the multi handle is "owned" by + the easy handle so curl_easy_cleanup() on such an easy handle will + also close the multi handle! */ + bit multi_owned_by_easy:1; + + bit this_is_a_follow:1; /* this is a followed Location: request */ + bit refused_stream:1; /* this was refused, try again */ + bit errorbuf:1; /* Set to TRUE if the error buffer is already filled in. + This must be set to FALSE every time _easy_perform() is + called. */ + bit allow_port:1; /* Is set.use_port allowed to take effect or not. This + is always set TRUE when curl_easy_perform() is called. */ + bit authproblem:1; /* TRUE if there's some problem authenticating */ + /* set after initial USER failure, to prevent an authentication loop */ + bit ftp_trying_alternative:1; + bit wildcardmatch:1; /* enable wildcard matching */ + bit expect100header:1; /* TRUE if we added Expect: 100-continue */ + bit use_range:1; + bit rangestringalloc:1; /* the range string is malloc()'ed */ + bit done:1; /* set to FALSE when Curl_init_do() is called and set to TRUE + when multi_done() is called, to prevent multi_done() to get + invoked twice when the multi interface is used. */ + bit stream_depends_e:1; /* set or don't set the Exclusive bit */ }; @@ -1402,14 +1383,15 @@ struct UrlState { struct DynamicStatic { char *url; /* work URL, copied from UserDefined */ - bool url_alloc; /* URL string is malloc()'ed */ char *referer; /* referer string */ - bool referer_alloc; /* referer string is malloc()ed */ struct curl_slist *cookielist; /* list of cookie files set by curl_easy_setopt(COOKIEFILE) calls */ struct curl_slist *resolve; /* set to point to the set.resolve list when this should be dealt with in pretransfer */ - bool wildcard_resolve; /* Set to true if any resolve change is a wildcard */ + bit url_alloc:1; /* URL string is malloc()'ed */ + bit referer_alloc:1; /* referer string is malloc()ed */ + bit wildcard_resolve:1; /* Set to true if any resolve change is a + wildcard */ }; /* @@ -1502,6 +1484,9 @@ enum dupstring { #endif STRING_TARGET, /* CURLOPT_REQUEST_TARGET */ STRING_DOH, /* CURLOPT_DOH_URL */ +#ifdef USE_ALTSVC + STRING_ALTSVC, /* CURLOPT_ALTSVC */ +#endif /* -- end of zero-terminated strings -- */ STRING_LASTZEROTERMINATED, @@ -1539,8 +1524,6 @@ struct UserDefined { int keep_post; /* keep POSTs as POSTs after a 30x request; each bit represents a request, from 301 to 303 */ - bool free_referer; /* set TRUE if 'referer' points to a string we - allocated */ void *postfields; /* if POST, set the fields' values here */ curl_seek_callback seek_func; /* function that seeks the input */ curl_off_t postfieldsize; /* if POST, this might have a size to use instead @@ -1553,8 +1536,6 @@ struct UserDefined { curl_write_callback fwrite_header; /* function that stores headers */ curl_write_callback fwrite_rtp; /* function that stores interleaved RTP */ curl_read_callback fread_func_set; /* function that reads the input */ - int is_fread_set; /* boolean, has read callback been set to non-NULL? */ - int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */ curl_progress_callback fprogress; /* OLD and deprecated progress callback */ curl_xferinfo_callback fxferinfo; /* progress callback */ curl_debug_callback fdebug; /* function that write informational data */ @@ -1586,7 +1567,6 @@ struct UserDefined { long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */ long server_response_timeout; /* in milliseconds, 0 means no timeout */ long tftp_blksize; /* in bytes, 0 means use default */ - bool tftp_no_options; /* do not send TFTP options requests */ curl_off_t filesize; /* size of file to upload, -1 means unknown */ long low_speed_limit; /* bytes/second */ long low_speed_time; /* number of seconds */ @@ -1598,9 +1578,6 @@ struct UserDefined { struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */ struct curl_httppost *httppost; /* linked list of old POST data */ curl_mimepart mimepost; /* MIME/POST data. */ - bool sep_headers; /* handle host and proxy headers separately */ - bool cookiesession; /* new cookie session? */ - bool crlf; /* convert crlf on ftp upload(?) */ struct curl_slist *quote; /* after connection is established */ struct curl_slist *postquote; /* after the transfer */ struct curl_slist *prequote; /* before the transfer, after type */ @@ -1619,7 +1596,6 @@ struct UserDefined { Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */ long httpversion; /* when non-zero, a specific HTTP version requested to be used in the library's request(s) */ - bool strip_path_slash; /* strip off initial slash from path */ struct ssl_config_data ssl; /* user defined SSL stuff */ struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */ struct ssl_general_config general_ssl; /* general user defined SSL stuff */ @@ -1629,87 +1605,33 @@ struct UserDefined { size_t upload_buffer_size; /* size of upload buffer to use, keep it >= CURL_MAX_WRITE_SIZE */ void *private_data; /* application-private data */ - struct curl_slist *http200aliases; /* linked list of aliases for http200 */ - long ipver; /* the CURL_IPRESOLVE_* defines in the public header file 0 - whatever, 1 - v2, 2 - v6 */ - curl_off_t max_filesize; /* Maximum file size to download */ - curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */ - int ftp_create_missing_dirs; /* 1 - create directories that don't exist 2 - the same but also allow MKD to fail once */ - curl_sshkeycallback ssh_keyfunc; /* key matching callback */ void *ssh_keyfunc_userp; /* custom pointer to callback */ - bool ssh_compression; /* enable SSH compression */ - -/* Here follows boolean settings that define how to behave during - this session. They are STATIC, set by libcurl users or at least initially - and they don't change during operations. */ - bool get_filetime; /* get the time and get of the remote file */ - bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */ - bool prefer_ascii; /* ASCII rather than binary */ - bool ftp_append; /* append, not overwrite, on upload */ - bool ftp_list_only; /* switch FTP command for listing directories */ - bool ftp_use_port; /* use the FTP PORT command */ - bool hide_progress; /* don't use the progress meter */ - bool http_fail_on_error; /* fail on HTTP error codes >= 400 */ - bool http_keep_sending_on_error; /* for HTTP status codes >= 300 */ - bool http_follow_location; /* follow HTTP redirects */ - bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */ - bool allow_auth_to_other_hosts; - bool include_header; /* include received protocol headers in data output */ - bool http_set_referer; /* is a custom referer used */ - bool http_auto_referer; /* set "correct" referer when following location: */ - bool opt_no_body; /* as set with CURLOPT_NOBODY */ - bool upload; /* upload request */ enum CURL_NETRC_OPTION use_netrc; /* defined in include/curl.h */ - bool verbose; /* output verbosity */ - bool krb; /* Kerberos connection requested */ - bool reuse_forbid; /* forbidden to be reused, close after use */ - bool reuse_fresh; /* do not re-use an existing connection */ - bool ftp_use_epsv; /* if EPSV is to be attempted or not */ - bool ftp_use_eprt; /* if EPRT is to be attempted or not */ - bool ftp_use_pret; /* if PRET is to be used before PASV or not */ - curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or IMAP or POP3 or others! */ curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */ curl_ftpccc ftp_ccc; /* FTP CCC options */ - bool no_signal; /* do not use any signal/alarm handler */ - bool global_dns_cache; /* subject for future removal */ - bool tcp_nodelay; /* whether to enable TCP_NODELAY or not */ - bool ignorecl; /* ignore content length */ - bool ftp_skip_ip; /* skip the IP address the FTP server passes on to - us */ - bool connect_only; /* make connection, let application use the socket */ - long ssh_auth_types; /* allowed SSH auth types */ - bool http_te_skip; /* pass the raw body data to the user, even when - transfer-encoded (chunked, compressed) */ - bool http_ce_skip; /* pass the raw body data to the user, even when - content-encoded (chunked, compressed) */ long new_file_perms; /* Permissions to use when creating remote files */ long new_directory_perms; /* Permissions to use when creating remote dirs */ - bool proxy_transfer_mode; /* set transfer mode (;type=<a|i>) when doing FTP - via an HTTP proxy */ + long ssh_auth_types; /* allowed SSH auth types */ char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */ unsigned int scope_id; /* Scope id for IPv6 */ long allowed_protocols; long redir_protocols; -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - bool socks5_gssapi_nec; /* Flag to support NEC SOCKS5 server */ -#endif struct curl_slist *mail_rcpt; /* linked list of mail recipients */ - bool sasl_ir; /* Enable/disable SASL initial response */ /* Common RTSP header options */ Curl_RtspReq rtspreq; /* RTSP request type */ long rtspversion; /* like httpversion, for RTSP */ - bool wildcard_enabled; /* enable wildcard matching */ curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer starts */ curl_chunk_end_callback chunk_end; /* called after part transferring @@ -1721,47 +1643,102 @@ struct UserDefined { long gssapi_delegation; /* GSS-API credential delegation, see the documentation of CURLOPT_GSSAPI_DELEGATION */ - bool tcp_keepalive; /* use TCP keepalives */ long tcp_keepidle; /* seconds in idle before sending keepalive probe */ long tcp_keepintvl; /* seconds between TCP keepalive probes */ - bool tcp_fastopen; /* use TCP Fast Open */ - size_t maxconnects; /* Max idle connections in the connection cache */ + size_t maxconnects; /* Max idle connections in the connection cache */ - bool ssl_enable_npn; /* TLS NPN extension? */ - bool ssl_enable_alpn; /* TLS ALPN extension? */ - bool path_as_is; /* allow dotdots? */ - bool pipewait; /* wait for pipe/multiplex status before starting a - new connection */ long expect_100_timeout; /* in milliseconds */ - bool suppress_connect_headers; /* suppress proxy CONNECT response headers - from user callbacks */ - - bool dns_shuffle_addresses; /* whether to shuffle addresses before use */ - struct Curl_easy *stream_depends_on; - bool stream_depends_e; /* set or don't set the Exclusive bit */ int stream_weight; - - bool haproxyprotocol; /* whether to send HAProxy PROXY protocol v1 header */ - struct Curl_http2_dep *stream_dependents; - bool abstract_unix_socket; - curl_resolver_start_callback resolver_start; /* optional callback called before resolver start */ void *resolver_start_client; /* pointer to pass to resolver start callback */ - bool disallow_username_in_url; /* disallow username in url */ long upkeep_interval_ms; /* Time between calls for connection upkeep. */ - bool doh; /* DNS-over-HTTPS enabled */ - bool doh_get; /* use GET for DoH requests, instead of POST */ - bool http09_allowed; /* allow HTTP/0.9 responses */ multidone_func fmultidone; struct Curl_easy *dohfor; /* this is a DoH request for that transfer */ CURLU *uh; /* URL handle for the current parsed URL */ void *trailer_data; /* pointer to pass to trailer data callback */ curl_trailer_callback trailer_callback; /* trailing data callback */ + bit is_fread_set:1; /* has read callback been set to non-NULL? */ + bit is_fwrite_set:1; /* has write callback been set to non-NULL? */ + bit free_referer:1; /* set TRUE if 'referer' points to a string we + allocated */ + bit tftp_no_options:1; /* do not send TFTP options requests */ + bit sep_headers:1; /* handle host and proxy headers separately */ + bit cookiesession:1; /* new cookie session? */ + bit crlf:1; /* convert crlf on ftp upload(?) */ + bit strip_path_slash:1; /* strip off initial slash from path */ + bit ssh_compression:1; /* enable SSH compression */ + +/* Here follows boolean settings that define how to behave during + this session. They are STATIC, set by libcurl users or at least initially + and they don't change during operations. */ + bit get_filetime:1; /* get the time and get of the remote file */ + bit tunnel_thru_httpproxy:1; /* use CONNECT through a HTTP proxy */ + bit prefer_ascii:1; /* ASCII rather than binary */ + bit ftp_append:1; /* append, not overwrite, on upload */ + bit ftp_list_only:1; /* switch FTP command for listing directories */ + bit ftp_use_port:1; /* use the FTP PORT command */ + bit hide_progress:1; /* don't use the progress meter */ + bit http_fail_on_error:1; /* fail on HTTP error codes >= 400 */ + bit http_keep_sending_on_error:1; /* for HTTP status codes >= 300 */ + bit http_follow_location:1; /* follow HTTP redirects */ + bit http_transfer_encoding:1; /* request compressed HTTP + transfer-encoding */ + bit allow_auth_to_other_hosts:1; + bit include_header:1; /* include received protocol headers in data output */ + bit http_set_referer:1; /* is a custom referer used */ + bit http_auto_referer:1; /* set "correct" referer when following + location: */ + bit opt_no_body:1; /* as set with CURLOPT_NOBODY */ + bit upload:1; /* upload request */ + bit verbose:1; /* output verbosity */ + bit krb:1; /* Kerberos connection requested */ + bit reuse_forbid:1; /* forbidden to be reused, close after use */ + bit reuse_fresh:1; /* do not re-use an existing connection */ + bit ftp_use_epsv:1; /* if EPSV is to be attempted or not */ + bit ftp_use_eprt:1; /* if EPRT is to be attempted or not */ + bit ftp_use_pret:1; /* if PRET is to be used before PASV or not */ + + bit no_signal:1; /* do not use any signal/alarm handler */ + bit global_dns_cache:1; /* subject for future removal */ + bit tcp_nodelay:1; /* whether to enable TCP_NODELAY or not */ + bit ignorecl:1; /* ignore content length */ + bit ftp_skip_ip:1; /* skip the IP address the FTP server passes on to + us */ + bit connect_only:1; /* make connection, let application use the socket */ + bit http_te_skip:1; /* pass the raw body data to the user, even when + transfer-encoded (chunked, compressed) */ + bit http_ce_skip:1; /* pass the raw body data to the user, even when + content-encoded (chunked, compressed) */ + bit proxy_transfer_mode:1; /* set transfer mode (;type=<a|i>) when doing + FTP via an HTTP proxy */ +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + bit socks5_gssapi_nec:1; /* Flag to support NEC SOCKS5 server */ +#endif + bit sasl_ir:1; /* Enable/disable SASL initial response */ + bit wildcard_enabled:1; /* enable wildcard matching */ + bit tcp_keepalive:1; /* use TCP keepalives */ + bit tcp_fastopen:1; /* use TCP Fast Open */ + bit ssl_enable_npn:1; /* TLS NPN extension? */ + bit ssl_enable_alpn:1;/* TLS ALPN extension? */ + bit path_as_is:1; /* allow dotdots? */ + bit pipewait:1; /* wait for pipe/multiplex status before starting a + new connection */ + bit suppress_connect_headers:1; /* suppress proxy CONNECT response headers + from user callbacks */ + bit dns_shuffle_addresses:1; /* whether to shuffle addresses before use */ + bit stream_depends_e:1; /* set or don't set the Exclusive bit */ + bit haproxyprotocol:1; /* whether to send HAProxy PROXY protocol v1 + header */ + bit abstract_unix_socket:1; + bit disallow_username_in_url:1; /* disallow username in url */ + bit doh:1; /* DNS-over-HTTPS enabled */ + bit doh_get:1; /* use GET for DoH requests, instead of POST */ + bit http09_allowed:1; /* allow HTTP/0.9 responses */ }; struct Names { @@ -1826,6 +1803,9 @@ struct Curl_easy { NOTE that the 'cookie' field in the UserDefined struct defines if the "engine" is to be used or not. */ +#ifdef USE_ALTSVC + struct altsvcinfo *asi; /* the alt-svc cache */ +#endif struct Progress progress; /* for all the progress meter data */ struct UrlState state; /* struct for fields used for state info and other dynamic purposes */ diff --git a/libs/libcurl/src/vauth/spnego_gssapi.c b/libs/libcurl/src/vauth/spnego_gssapi.c index 4a48bdd208..7c4bd4b595 100644 --- a/libs/libcurl/src/vauth/spnego_gssapi.c +++ b/libs/libcurl/src/vauth/spnego_gssapi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -273,6 +273,11 @@ void Curl_auth_spnego_cleanup(struct negotiatedata *nego) /* Reset any variables */ nego->status = 0; + nego->state = GSS_AUTHNONE; + nego->noauthpersist = FALSE; + nego->havenoauthpersist = FALSE; + nego->havenegdata = FALSE; + nego->havemultiplerequests = FALSE; } #endif /* HAVE_GSSAPI && USE_SPNEGO */ diff --git a/libs/libcurl/src/vauth/spnego_sspi.c b/libs/libcurl/src/vauth/spnego_sspi.c index 00d8404652..0171ec52b5 100644 --- a/libs/libcurl/src/vauth/spnego_sspi.c +++ b/libs/libcurl/src/vauth/spnego_sspi.c @@ -248,8 +248,9 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, free(chlg); if(GSS_ERROR(nego->status)) { + char buffer[STRERROR_LEN]; failf(data, "InitializeSecurityContext failed: %s", - Curl_sspi_strerror(data->conn, nego->status)); + Curl_sspi_strerror(nego->status, buffer, sizeof(buffer))); return CURLE_OUT_OF_MEMORY; } @@ -342,6 +343,11 @@ void Curl_auth_spnego_cleanup(struct negotiatedata *nego) /* Reset any variables */ nego->status = 0; nego->token_max = 0; + nego->state = GSS_AUTHNONE; + nego->noauthpersist = FALSE; + nego->havenoauthpersist = FALSE; + nego->havenegdata = FALSE; + nego->havemultiplerequests = FALSE; } #endif /* USE_WINDOWS_SSPI && USE_SPNEGO */ diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c index e553100c21..9369ae8e3f 100644 --- a/libs/libcurl/src/version.c +++ b/libs/libcurl/src/version.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -212,6 +212,10 @@ char *curl_version(void) } #endif + /* Silent scan-build even if librtmp is not enabled. */ + (void) left; + (void) ptr; + initialized = true; return version; } @@ -366,6 +370,9 @@ static curl_version_info_data version_info = { #if defined(HAVE_BROTLI) | CURL_VERSION_BROTLI #endif +#if defined(USE_ALTSVC) + | CURL_VERSION_ALTSVC +#endif , NULL, /* ssl_version */ 0, /* ssl_version_num, this is kept at zero */ diff --git a/libs/libcurl/src/vtls/cyassl.c b/libs/libcurl/src/vtls/cyassl.c index ea96cf65e5..c7a3268efa 100644 --- a/libs/libcurl/src/vtls/cyassl.c +++ b/libs/libcurl/src/vtls/cyassl.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -67,15 +67,6 @@ and that's a problem since options.h hasn't been included yet. */ #endif #endif -/* HAVE_SUPPORTED_CURVES is wolfSSL's build time symbol for enabling the ECC - supported curve extension in options.h. Note ECC is enabled separately. */ -#ifndef HAVE_SUPPORTED_CURVES -#if defined(HAVE_CYASSL_CTX_USESUPPORTEDCURVE) || \ - defined(HAVE_WOLFSSL_CTX_USESUPPORTEDCURVE) -#define HAVE_SUPPORTED_CURVES -#endif -#endif - #include <limits.h> #include "urldata.h" @@ -364,16 +355,6 @@ cyassl_connect_step1(struct connectdata *conn, } #endif -#ifdef HAVE_SUPPORTED_CURVES - /* CyaSSL/wolfSSL does not send the supported ECC curves ext automatically: - https://github.com/wolfSSL/wolfssl/issues/366 - The supported curves below are those also supported by OpenSSL 1.0.2 and - in the same order. */ - CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x17); /* secp256r1 */ - CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x19); /* secp521r1 */ - CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x18); /* secp384r1 */ -#endif - /* give application a chance to interfere with SSL set up. */ if(data->set.ssl.fsslctx) { CURLcode result = CURLE_OK; diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c index 9035ec483e..e224861c45 100644 --- a/libs/libcurl/src/vtls/gtls.c +++ b/libs/libcurl/src/vtls/gtls.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1423,11 +1423,6 @@ gtls_connect_step3(struct connectdata *conn, size = sizeof(certbuf); gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size); infof(data, "\t issuer: %s\n", certbuf); - - /* compression algorithm (if any) */ - ptr = gnutls_compression_get_name(gnutls_compression_get(session)); - /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */ - infof(data, "\t compression: %s\n", ptr); #endif gnutls_x509_crt_deinit(x509_cert); diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c index bb6a757bf2..27a9402cbc 100644 --- a/libs/libcurl/src/vtls/mbedtls.c +++ b/libs/libcurl/src/vtls/mbedtls.c @@ -716,6 +716,8 @@ mbed_connect_step3(struct connectdata *conn, ret = mbedtls_ssl_get_session(&BACKEND->ssl, our_ssl_sessionid); if(ret) { + if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED) + mbedtls_ssl_session_free(our_ssl_sessionid); free(our_ssl_sessionid); failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret); return CURLE_SSL_CONNECT_ERROR; @@ -729,6 +731,7 @@ mbed_connect_step3(struct connectdata *conn, retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex); Curl_ssl_sessionid_unlock(conn); if(retcode) { + mbedtls_ssl_session_free(our_ssl_sessionid); free(our_ssl_sessionid); failf(data, "failed to store ssl session"); return retcode; @@ -813,9 +816,14 @@ static void Curl_mbedtls_session_free(void *ptr) static size_t Curl_mbedtls_version(char *buffer, size_t size) { +#ifdef MBEDTLS_VERSION_C + /* if mbedtls_version_get_number() is available it is better */ unsigned int version = mbedtls_version_get_number(); return msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24, (version>>16)&0xff, (version>>8)&0xff); +#else + return msnprintf(buffer, size, "mbedTLS/%s", MBEDTLS_VERSION_STRING); +#endif } static CURLcode Curl_mbedtls_random(struct Curl_easy *data, diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c index 9d11b89e59..eff5c2106c 100644 --- a/libs/libcurl/src/vtls/openssl.c +++ b/libs/libcurl/src/vtls/openssl.c @@ -65,6 +65,10 @@ #include <openssl/buffer.h> #include <openssl/pkcs12.h> +#ifdef USE_AMISSL +#include "amigaos.h" +#endif + #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP) #include <openssl/ocsp.h> #endif @@ -820,8 +824,11 @@ int cert_stuff(struct connectdata *conn, fail: EVP_PKEY_free(pri); X509_free(x509); +#ifdef USE_AMISSL + sk_X509_pop_free(ca, Curl_amiga_X509_free); +#else sk_X509_pop_free(ca, X509_free); - +#endif if(!cert_done) return 0; /* failure! */ break; @@ -831,15 +838,15 @@ int cert_stuff(struct connectdata *conn, return 0; } - file_type = do_file_type(key_type); + if(!key_file) + key_file = cert_file; + else + file_type = do_file_type(key_type); switch(file_type) { case SSL_FILETYPE_PEM: if(cert_done) break; - if(!key_file) - /* cert & key can only be in PEM case in the same file */ - key_file = cert_file; /* FALLTHROUGH */ case SSL_FILETYPE_ASN1: if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) { @@ -2808,6 +2815,12 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) connssl->connecting_state = ssl_connect_2_writing; return CURLE_OK; } +#ifdef SSL_ERROR_WANT_ASYNC + if(SSL_ERROR_WANT_ASYNC == detail) { + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; + } +#endif else { /* untreated error */ unsigned long errdetail; diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index c8574f56c1..39ac080e80 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.c @@ -324,6 +324,9 @@ get_alg_id_by_name(char *name) #ifdef CALG_ECDSA CIPHEROPTION(CALG_ECDSA); #endif +#ifdef CALG_ECDH_EPHEM + CIPHEROPTION(CALG_ECDH_EPHEM); +#endif return 0; } @@ -433,8 +436,9 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; - infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", - hostname, conn->remote_port); + DEBUGF(infof(data, + "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", + hostname, conn->remote_port)); if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT, VERSION_LESS_THAN_EQUAL)) { @@ -494,12 +498,13 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) Curl_ssl_sessionid_lock(conn); if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) { BACKEND->cred = old_cred; - infof(data, "schannel: re-using existing credential handle\n"); + DEBUGF(infof(data, "schannel: re-using existing credential handle\n")); /* increment the reference counter of the credential/session handle */ BACKEND->cred->refcount++; - infof(data, "schannel: incremented credential handle refcount = %d\n", - BACKEND->cred->refcount); + DEBUGF(infof(data, + "schannel: incremented credential handle refcount = %d\n", + BACKEND->cred->refcount)); } Curl_ssl_sessionid_unlock(conn); } @@ -522,26 +527,28 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE; - infof(data, "schannel: disabled server certificate revocation " - "checks\n"); + DEBUGF(infof(data, "schannel: disabled server certificate revocation " + "checks\n")); } else { schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; - infof(data, "schannel: checking server certificate revocation\n"); + 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; - infof(data, "schannel: disabled server certificate revocation checks\n"); + DEBUGF(infof(data, + "schannel: disabled server cert revocation checks\n")); } if(!conn->ssl_config.verifyhost) { schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK; - infof(data, "schannel: verifyhost setting prevents Schannel from " - "comparing the supplied target name with the subject " - "names in server certificates.\n"); + DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from " + "comparing the supplied target name with the subject " + "names in server certificates.\n")); } switch(conn->ssl_config.version) { @@ -680,8 +687,9 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) CertFreeCertificateContext(client_certs[0]); if(sspi_status != SEC_E_OK) { + char buffer[STRERROR_LEN]; failf(data, "schannel: AcquireCredentialsHandle failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); Curl_safefree(BACKEND->cred); switch(sspi_status) { case SEC_E_INSUFFICIENT_MEMORY: @@ -796,15 +804,16 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) Curl_unicodefree(host_name); if(sspi_status != SEC_I_CONTINUE_NEEDED) { + char buffer[STRERROR_LEN]; Curl_safefree(BACKEND->ctxt); switch(sspi_status) { case SEC_E_INSUFFICIENT_MEMORY: failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_OUT_OF_MEMORY; case SEC_E_WRONG_PRINCIPAL: failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_PEER_FAILED_VERIFICATION; /* case SEC_E_INVALID_HANDLE: @@ -819,13 +828,13 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) */ default: failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_SSL_CONNECT_ERROR; } } - infof(data, "schannel: sending initial handshake data: " - "sending %lu bytes...\n", outbuf.cbBuffer); + DEBUGF(infof(data, "schannel: sending initial handshake data: " + "sending %lu bytes...\n", outbuf.cbBuffer)); /* send initial handshake data which is now stored in output buffer */ result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer, @@ -837,8 +846,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) return CURLE_SSL_CONNECT_ERROR; } - infof(data, "schannel: sent initial handshake data: " - "sent %zd bytes\n", written); + DEBUGF(infof(data, "schannel: sent initial handshake data: " + "sent %zd bytes\n", written)); BACKEND->recv_unrecoverable_err = CURLE_OK; BACKEND->recv_sspi_close_notify = false; @@ -874,8 +883,9 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; - infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n", - hostname, conn->remote_port); + DEBUGF(infof(data, + "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n", + hostname, conn->remote_port)); if(!BACKEND->cred || !BACKEND->ctxt) return CURLE_SSL_CONNECT_ERROR; @@ -934,8 +944,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) if(result == CURLE_AGAIN) { if(connssl->connecting_state != ssl_connect_2_writing) connssl->connecting_state = ssl_connect_2_reading; - infof(data, "schannel: failed to receive handshake, " - "need more data\n"); + DEBUGF(infof(data, "schannel: failed to receive handshake, " + "need more data\n")); return CURLE_OK; } else if((result != CURLE_OK) || (nread == 0)) { @@ -947,11 +957,12 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) /* increase encrypted data buffer offset */ BACKEND->encdata_offset += nread; BACKEND->encdata_is_incomplete = false; - infof(data, "schannel: encrypted data got %zd\n", nread); + DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); } - infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length); + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); /* setup input buffers */ InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset), @@ -994,7 +1005,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) { BACKEND->encdata_is_incomplete = true; connssl->connecting_state = ssl_connect_2_reading; - infof(data, "schannel: received incomplete message, need more data\n"); + DEBUGF(infof(data, + "schannel: received incomplete message, need more data\n")); return CURLE_OK; } @@ -1005,7 +1017,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) !(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) { BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; connssl->connecting_state = ssl_connect_2_writing; - infof(data, "schannel: a client certificate has been requested\n"); + DEBUGF(infof(data, + "schannel: a client certificate has been requested\n")); return CURLE_OK; } @@ -1014,8 +1027,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) for(i = 0; i < 3; i++) { /* search for handshake tokens that need to be send */ if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) { - infof(data, "schannel: sending next handshake data: " - "sending %lu bytes...\n", outbuf[i].cbBuffer); + DEBUGF(infof(data, "schannel: sending next handshake data: " + "sending %lu bytes...\n", outbuf[i].cbBuffer)); /* send handshake token to server */ result = Curl_write_plain(conn, conn->sock[sockindex], @@ -1036,14 +1049,15 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) } } else { + char buffer[STRERROR_LEN]; switch(sspi_status) { case SEC_E_INSUFFICIENT_MEMORY: failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_OUT_OF_MEMORY; case SEC_E_WRONG_PRINCIPAL: failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_PEER_FAILED_VERIFICATION; /* case SEC_E_INVALID_HANDLE: @@ -1058,14 +1072,15 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) */ default: failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_SSL_CONNECT_ERROR; } } /* check if there was additional remaining encrypted data */ if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) { - infof(data, "schannel: encrypted data length: %lu\n", inbuf[1].cbBuffer); + DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", + inbuf[1].cbBuffer)); /* There are two cases where we could be getting extra data here: 1) If we're renegotiating a connection and the handshake is already @@ -1104,7 +1119,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) /* check if the handshake is complete */ if(sspi_status == SEC_E_OK) { connssl->connecting_state = ssl_connect_3; - infof(data, "schannel: SSL/TLS handshake complete\n"); + DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n")); } pubkey_ptr = SSL_IS_PROXY() ? @@ -1190,7 +1205,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) struct ssl_connect_data *connssl = &conn->ssl[sockindex]; SECURITY_STATUS sspi_status = SEC_E_OK; CERT_CONTEXT *ccert_context = NULL; -#ifndef CURL_DISABLE_VERBOSE_STRINGS +#ifdef DEBUGBUILD const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; #endif @@ -1200,8 +1215,9 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n", - hostname, conn->remote_port); + DEBUGF(infof(data, + "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n", + hostname, conn->remote_port)); if(!BACKEND->cred) return CURLE_SSL_CONNECT_ERROR; @@ -1266,7 +1282,8 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) sockindex)); if(incache) { if(old_cred != BACKEND->cred) { - infof(data, "schannel: old credential handle is stale, removing\n"); + DEBUGF(infof(data, + "schannel: old credential handle is stale, removing\n")); /* we're not taking old_cred ownership here, no refcount++ is needed */ Curl_ssl_delsessionid(conn, (void *)old_cred); incache = FALSE; @@ -1284,7 +1301,8 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) else { /* this cred session is now also referenced by sessionid cache */ BACKEND->cred->refcount++; - infof(data, "schannel: stored credential handle in session cache\n"); + DEBUGF(infof(data, + "schannel: stored credential handle in session cache\n")); } } Curl_ssl_sessionid_unlock(conn); @@ -1615,7 +1633,7 @@ schannel_recv(struct connectdata *conn, int sockindex, * handled in the cleanup. */ - infof(data, "schannel: client wants to read %zu bytes\n", len); + DEBUGF(infof(data, "schannel: client wants to read %zu bytes\n", len)); *err = CURLE_OK; if(len && len <= BACKEND->decdata_offset) { @@ -1660,12 +1678,13 @@ schannel_recv(struct connectdata *conn, int sockindex, BACKEND->encdata_buffer = reallocated_buffer; BACKEND->encdata_length = reallocated_length; size = BACKEND->encdata_length - BACKEND->encdata_offset; - infof(data, "schannel: encdata_buffer resized %zu\n", - BACKEND->encdata_length); + DEBUGF(infof(data, "schannel: encdata_buffer resized %zu\n", + BACKEND->encdata_length)); } - infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length); + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); /* read encrypted data from socket */ *err = Curl_read_plain(conn->sock[sockindex], @@ -1675,7 +1694,8 @@ schannel_recv(struct connectdata *conn, int sockindex, if(*err) { nread = -1; if(*err == CURLE_AGAIN) - infof(data, "schannel: Curl_read_plain returned CURLE_AGAIN\n"); + DEBUGF(infof(data, + "schannel: Curl_read_plain returned CURLE_AGAIN\n")); else if(*err == CURLE_RECV_ERROR) infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n"); else @@ -1683,17 +1703,18 @@ schannel_recv(struct connectdata *conn, int sockindex, } else if(nread == 0) { BACKEND->recv_connection_closed = true; - infof(data, "schannel: server closed the connection\n"); + DEBUGF(infof(data, "schannel: server closed the connection\n")); } else if(nread > 0) { BACKEND->encdata_offset += (size_t)nread; BACKEND->encdata_is_incomplete = false; - infof(data, "schannel: encrypted data got %zd\n", nread); + DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); } } - infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length); + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); /* decrypt loop */ while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK && @@ -1721,8 +1742,8 @@ schannel_recv(struct connectdata *conn, int sockindex, /* check for successfully decrypted data, even before actual renegotiation or shutdown of the connection context */ if(inbuf[1].BufferType == SECBUFFER_DATA) { - infof(data, "schannel: decrypted data length: %lu\n", - inbuf[1].cbBuffer); + DEBUGF(infof(data, "schannel: decrypted data length: %lu\n", + inbuf[1].cbBuffer)); /* increase buffer in order to fit the received amount of data */ size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ? @@ -1754,15 +1775,16 @@ schannel_recv(struct connectdata *conn, int sockindex, BACKEND->decdata_offset += size; } - infof(data, "schannel: decrypted data added: %zu\n", size); - infof(data, "schannel: decrypted data cached: offset %zu length %zu\n", - BACKEND->decdata_offset, BACKEND->decdata_length); + DEBUGF(infof(data, "schannel: decrypted data added: %zu\n", size)); + DEBUGF(infof(data, + "schannel: decrypted cached: offset %zu length %zu\n", + BACKEND->decdata_offset, BACKEND->decdata_length)); } /* check for remaining encrypted data */ if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) { - infof(data, "schannel: encrypted data length: %lu\n", - inbuf[3].cbBuffer); + DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", + inbuf[3].cbBuffer)); /* check if the remaining data is less than the total amount * and therefore begins after the already processed data @@ -1776,8 +1798,9 @@ schannel_recv(struct connectdata *conn, int sockindex, BACKEND->encdata_offset = inbuf[3].cbBuffer; } - infof(data, "schannel: encrypted data cached: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length); + DEBUGF(infof(data, + "schannel: encrypted cached: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); } else { /* reset encrypted buffer offset, because there is no data remaining */ @@ -1831,22 +1854,25 @@ schannel_recv(struct connectdata *conn, int sockindex, goto cleanup; } else { + char buffer[STRERROR_LEN]; *err = CURLE_RECV_ERROR; infof(data, "schannel: failed to read data from server: %s\n", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); goto cleanup; } } - infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length); + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); - infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n", - BACKEND->decdata_offset, BACKEND->decdata_length); + DEBUGF(infof(data, + "schannel: decrypted data buffer: offset %zu length %zu\n", + BACKEND->decdata_offset, BACKEND->decdata_length)); cleanup: /* Warning- there is no guarantee the encdata state is valid at this point */ - infof(data, "schannel: schannel_recv cleanup\n"); + DEBUGF(infof(data, "schannel: schannel_recv cleanup\n")); /* Error if the connection has closed without a close_notify. Behavior here is a matter of debate. We don't want to be vulnerable to a @@ -1879,10 +1905,10 @@ cleanup: memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size, BACKEND->decdata_offset - size); BACKEND->decdata_offset -= size; - - infof(data, "schannel: decrypted data returned %zu\n", size); - infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n", - BACKEND->decdata_offset, BACKEND->decdata_length); + DEBUGF(infof(data, "schannel: decrypted data returned %zu\n", size)); + DEBUGF(infof(data, + "schannel: decrypted data buffer: offset %zu length %zu\n", + BACKEND->decdata_offset, BACKEND->decdata_length)); *err = CURLE_OK; return (ssize_t)size; } @@ -1960,6 +1986,8 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; + DEBUGASSERT(data); + infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n", hostname, conn->remote_port); @@ -1979,9 +2007,11 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle, &BuffDesc); - if(sspi_status != SEC_E_OK) + if(sspi_status != SEC_E_OK) { + char buffer[STRERROR_LEN]; failf(data, "schannel: ApplyControlToken failure: %s", - Curl_sspi_strerror(conn, sspi_status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + } host_name = Curl_convert_UTF8_to_tchar(hostname); if(!host_name) @@ -2023,7 +2053,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) /* free SSPI Schannel API security context handle */ if(BACKEND->ctxt) { - infof(data, "schannel: clear security context handle\n"); + DEBUGF(infof(data, "schannel: clear security context handle\n")); s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle); Curl_safefree(BACKEND->ctxt); } @@ -2035,11 +2065,9 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) * might not have an associated transfer so the check for conn->data is * necessary. */ - if(conn->data) - Curl_ssl_sessionid_lock(conn); + Curl_ssl_sessionid_lock(conn); Curl_schannel_session_free(BACKEND->cred); - if(conn->data) - Curl_ssl_sessionid_unlock(conn); + Curl_ssl_sessionid_unlock(conn); BACKEND->cred = NULL; } @@ -2101,7 +2129,7 @@ static CURLcode Curl_schannel_random(struct Curl_easy *data UNUSED_PARAM, static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, const char *pinnedpubkey) { - SECURITY_STATUS status; + SECURITY_STATUS sspi_status; struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; CERT_CONTEXT *pCertContextServer = NULL; @@ -2118,13 +2146,15 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, return CURLE_OK; do { - status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); - if((status != SEC_E_OK) || (pCertContextServer == NULL)) { + if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(conn, status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); break; /* failed */ } diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c index 680f6ec5d6..5a09e969e8 100644 --- a/libs/libcurl/src/vtls/schannel_verify.c +++ b/libs/libcurl/src/vtls/schannel_verify.c @@ -96,9 +96,10 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, ca_file_tstr = Curl_convert_UTF8_to_tchar((char *)ca_file); if(!ca_file_tstr) { + char buffer[STRERROR_LEN]; failf(data, "schannel: invalid path name for CA file '%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -116,17 +117,19 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, FILE_ATTRIBUTE_NORMAL, NULL); if(ca_file_handle == INVALID_HANDLE_VALUE) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to open CA file '%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } if(!GetFileSizeEx(ca_file_handle, &file_size)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to determine size of CA file '%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -153,10 +156,10 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read, bytes_to_read, &bytes_read, NULL)) { - + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to read from CA file '%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -215,11 +218,12 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, NULL, NULL, (const void **)&cert_context)) { - + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to extract certificate from CA file " "'%s': %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -243,10 +247,12 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, NULL); CertFreeCertificateContext(cert_context); if(!add_cert_result) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to add certificate from CA file '%s' " "to certificate store: %s", - ca_file, Curl_strerror(conn, GetLastError())); + ca_file, + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -408,7 +414,7 @@ cleanup: CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) { - SECURITY_STATUS status; + SECURITY_STATUS sspi_status; struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; CURLcode result = CURLE_OK; @@ -420,13 +426,15 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) conn->http_proxy.host.name : conn->host.name; - status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); - if((status != SEC_E_OK) || (pCertContextServer == NULL)) { + if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(conn, status)); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); result = CURLE_PEER_FAILED_VERIFICATION; } @@ -450,8 +458,9 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CERT_STORE_CREATE_NEW_FLAG, NULL); if(!trust_store) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate store: %s", - Curl_strerror(conn, GetLastError())); + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } else { @@ -477,9 +486,10 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CertCreateCertificateChainEngine( (CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine); if(!create_engine_result) { + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate chain engine: %s", - Curl_strerror(conn, GetLastError())); + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } } @@ -500,8 +510,9 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CERT_CHAIN_REVOCATION_CHECK_CHAIN), NULL, &pChainContext)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: CertGetCertificateChain failed: %s", - Curl_sspi_strerror(conn, GetLastError())); + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); pChainContext = NULL; result = CURLE_PEER_FAILED_VERIFICATION; } diff --git a/libs/libcurl/src/vtls/darwinssl.c b/libs/libcurl/src/vtls/sectransp.c index bb251cdb30..971dd78e6a 100644 --- a/libs/libcurl/src/vtls/darwinssl.c +++ b/libs/libcurl/src/vtls/sectransp.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>. - * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -32,7 +32,7 @@ #include "curl_base64.h" #include "strtok.h" -#ifdef USE_DARWINSSL +#ifdef USE_SECTRANSP #ifdef __clang__ #pragma clang diagnostic push @@ -59,7 +59,7 @@ #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 -#error "The darwinssl back-end requires Leopard or later." +#error "The Secure Transport back-end requires Leopard or later." #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */ #define CURL_BUILD_IOS 0 @@ -105,7 +105,7 @@ #define CURL_SUPPORT_MAC_10_9 0 #else -#error "The darwinssl back-end requires iOS or OS X." +#error "The Secure Transport back-end requires iOS or macOS." #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */ #if CURL_BUILD_MAC @@ -118,7 +118,7 @@ #include "connect.h" #include "select.h" #include "vtls.h" -#include "darwinssl.h" +#include "sectransp.h" #include "curl_printf.h" #include "strdup.h" @@ -144,20 +144,20 @@ struct ssl_backend_data { /* version 1 supports macOS 10.12+ and iOS 10+ */ #if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \ (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)) -#define DARWIN_SSL_PINNEDPUBKEY_V1 1 +#define SECTRANSP_PINNEDPUBKEY_V1 1 #endif /* version 2 supports MacOSX 10.7+ */ #if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) -#define DARWIN_SSL_PINNEDPUBKEY_V2 1 +#define SECTRANSP_PINNEDPUBKEY_V2 1 #endif -#if defined(DARWIN_SSL_PINNEDPUBKEY_V1) || defined(DARWIN_SSL_PINNEDPUBKEY_V2) +#if defined(SECTRANSP_PINNEDPUBKEY_V1) || defined(SECTRANSP_PINNEDPUBKEY_V2) /* this backend supports CURLOPT_PINNEDPUBLICKEY */ -#define DARWIN_SSL_PINNEDPUBKEY 1 -#endif /* DARWIN_SSL_PINNEDPUBKEY */ +#define SECTRANSP_PINNEDPUBKEY 1 +#endif /* SECTRANSP_PINNEDPUBKEY */ -#ifdef DARWIN_SSL_PINNEDPUBKEY +#ifdef SECTRANSP_PINNEDPUBKEY /* both new and old APIs return rsa keys missing the spki header (not DER) */ static const unsigned char rsa4096SpkiHeader[] = { 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, @@ -170,7 +170,7 @@ static const unsigned char rsa2048SpkiHeader[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00}; -#ifdef DARWIN_SSL_PINNEDPUBKEY_V1 +#ifdef SECTRANSP_PINNEDPUBKEY_V1 /* the *new* version doesn't return DER encoded ecdsa certs like the old... */ static const unsigned char ecDsaSecp256r1SpkiHeader[] = { 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, @@ -184,8 +184,8 @@ static const unsigned char ecDsaSecp384r1SpkiHeader[] = { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00}; -#endif /* DARWIN_SSL_PINNEDPUBKEY_V1 */ -#endif /* DARWIN_SSL_PINNEDPUBKEY */ +#endif /* SECTRANSP_PINNEDPUBKEY_V1 */ +#endif /* SECTRANSP_PINNEDPUBKEY */ /* The following two functions were ripped from Apple sample code, * with some modifications: */ @@ -1242,7 +1242,7 @@ CF_INLINE bool is_file(const char *filename) } #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS -static CURLcode darwinssl_version_from_curl(SSLProtocol *darwinver, +static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver, long ssl_version) { switch(ssl_version) { @@ -1312,13 +1312,13 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex) if(SSLSetProtocolVersionMax != NULL) { SSLProtocol darwin_ver_min = kTLSProtocol1; SSLProtocol darwin_ver_max = kTLSProtocol1; - CURLcode result = darwinssl_version_from_curl(&darwin_ver_min, + CURLcode result = sectransp_version_from_curl(&darwin_ver_min, ssl_version); if(result) { failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); return result; } - result = darwinssl_version_from_curl(&darwin_ver_max, + result = sectransp_version_from_curl(&darwin_ver_max, ssl_version_max >> 16); if(result) { failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); @@ -1361,12 +1361,12 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex) #endif /* CURL_SUPPORT_MAC_10_8 */ } #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - failf(data, "DarwinSSL: cannot set SSL protocol"); + failf(data, "Secure Transport: cannot set SSL protocol"); return CURLE_SSL_CONNECT_ERROR; } -static CURLcode darwinssl_connect_step1(struct connectdata *conn, +static CURLcode sectransp_connect_step1(struct connectdata *conn, int sockindex) { struct Curl_easy *data = conn->data; @@ -1577,7 +1577,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 if(conn->bits.tls_enable_alpn) { - if(__builtin_available(macOS 10.13.4, iOS 11, *)) { + if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) { CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); @@ -2234,7 +2234,7 @@ static int verify_cert(const char *cafile, struct Curl_easy *data, } } -#ifdef DARWIN_SSL_PINNEDPUBKEY +#ifdef SECTRANSP_PINNEDPUBKEY static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, SSLContextRef ctx, const char *pinnedpubkey) @@ -2266,14 +2266,14 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, if(keyRef == NULL) break; -#ifdef DARWIN_SSL_PINNEDPUBKEY_V1 +#ifdef SECTRANSP_PINNEDPUBKEY_V1 publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL); CFRelease(keyRef); if(publicKeyBits == NULL) break; -#elif DARWIN_SSL_PINNEDPUBKEY_V2 +#elif SECTRANSP_PINNEDPUBKEY_V2 OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, &publicKeyBits); @@ -2281,7 +2281,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, if(success != errSecSuccess || publicKeyBits == NULL) break; -#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */ +#endif /* SECTRANSP_PINNEDPUBKEY_V2 */ pubkeylen = CFDataGetLength(publicKeyBits); pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits); @@ -2295,7 +2295,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, /* 2048 bit RSA pubkeylen == 270 */ spkiHeader = rsa2048SpkiHeader; break; -#ifdef DARWIN_SSL_PINNEDPUBKEY_V1 +#ifdef SECTRANSP_PINNEDPUBKEY_V1 case 65: /* ecDSA secp256r1 pubkeylen == 65 */ spkiHeader = ecDsaSecp256r1SpkiHeader; @@ -2308,7 +2308,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, break; default: infof(data, "SSL: unhandled public key length: %d\n", pubkeylen); -#elif DARWIN_SSL_PINNEDPUBKEY_V2 +#elif SECTRANSP_PINNEDPUBKEY_V2 default: /* ecDSA secp256r1 pubkeylen == 91 header already included? * ecDSA secp384r1 header already included too @@ -2316,7 +2316,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, */ result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey, pubkeylen); -#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */ +#endif /* SECTRANSP_PINNEDPUBKEY_V2 */ continue; /* break from loop */ } @@ -2339,10 +2339,10 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, return result; } -#endif /* DARWIN_SSL_PINNEDPUBKEY */ +#endif /* SECTRANSP_PINNEDPUBKEY */ static CURLcode -darwinssl_connect_step2(struct connectdata *conn, int sockindex) +sectransp_connect_step2(struct connectdata *conn, int sockindex) { struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; @@ -2376,7 +2376,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) return res; } /* the documentation says we need to call SSLHandshake() again */ - return darwinssl_connect_step2(conn, sockindex); + return sectransp_connect_step2(conn, sockindex); /* Problem with encrypt / decrypt */ case errSSLPeerDecodeError: @@ -2578,7 +2578,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) /* we have been connected fine, we're not waiting for anything else. */ connssl->connecting_state = ssl_connect_3; -#ifdef DARWIN_SSL_PINNEDPUBKEY +#ifdef SECTRANSP_PINNEDPUBKEY if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) { CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx, data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]); @@ -2587,7 +2587,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) return result; } } -#endif /* DARWIN_SSL_PINNEDPUBKEY */ +#endif /* SECTRANSP_PINNEDPUBKEY */ /* Informational message */ (void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher); @@ -2628,7 +2628,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) #if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 if(conn->bits.tls_enable_alpn) { - if(__builtin_available(macOS 10.13.4, iOS 11, *)) { + if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) { CFArrayRef alpnArr = NULL; CFStringRef chosenProtocol = NULL; err = SSLCopyALPNProtocols(BACKEND->ssl_ctx, &alpnArr); @@ -2771,7 +2771,7 @@ show_verbose_server_cert(struct connectdata *conn, #endif /* !CURL_DISABLE_VERBOSE_STRINGS */ static CURLcode -darwinssl_connect_step3(struct connectdata *conn, +sectransp_connect_step3(struct connectdata *conn, int sockindex) { struct Curl_easy *data = conn->data; @@ -2789,11 +2789,11 @@ darwinssl_connect_step3(struct connectdata *conn, return CURLE_OK; } -static Curl_recv darwinssl_recv; -static Curl_send darwinssl_send; +static Curl_recv sectransp_recv; +static Curl_send sectransp_send; static CURLcode -darwinssl_connect_common(struct connectdata *conn, +sectransp_connect_common(struct connectdata *conn, int sockindex, bool nonblocking, bool *done) @@ -2821,7 +2821,7 @@ darwinssl_connect_common(struct connectdata *conn, return CURLE_OPERATION_TIMEDOUT; } - result = darwinssl_connect_step1(conn, sockindex); + result = sectransp_connect_step1(conn, sockindex); if(result) return result; } @@ -2875,7 +2875,7 @@ darwinssl_connect_common(struct connectdata *conn, * before step2 has completed while ensuring that a client using select() * or epoll() will always have a valid fdset to wait on. */ - result = darwinssl_connect_step2(conn, sockindex); + result = sectransp_connect_step2(conn, sockindex); if(result || (nonblocking && (ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state || @@ -2886,15 +2886,15 @@ darwinssl_connect_common(struct connectdata *conn, if(ssl_connect_3 == connssl->connecting_state) { - result = darwinssl_connect_step3(conn, sockindex); + result = sectransp_connect_step3(conn, sockindex); if(result) return result; } if(ssl_connect_done == connssl->connecting_state) { connssl->state = ssl_connection_complete; - conn->recv[sockindex] = darwinssl_recv; - conn->send[sockindex] = darwinssl_send; + conn->recv[sockindex] = sectransp_recv; + conn->send[sockindex] = sectransp_send; *done = TRUE; } else @@ -2906,18 +2906,18 @@ darwinssl_connect_common(struct connectdata *conn, return CURLE_OK; } -static CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn, +static CURLcode Curl_sectransp_connect_nonblocking(struct connectdata *conn, int sockindex, bool *done) { - return darwinssl_connect_common(conn, sockindex, TRUE, done); + return sectransp_connect_common(conn, sockindex, TRUE, done); } -static CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex) +static CURLcode Curl_sectransp_connect(struct connectdata *conn, int sockindex) { CURLcode result; bool done = FALSE; - result = darwinssl_connect_common(conn, sockindex, FALSE, &done); + result = sectransp_connect_common(conn, sockindex, FALSE, &done); if(result) return result; @@ -2927,7 +2927,7 @@ static CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex) return CURLE_OK; } -static void Curl_darwinssl_close(struct connectdata *conn, int sockindex) +static void Curl_sectransp_close(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; @@ -2948,7 +2948,7 @@ static void Curl_darwinssl_close(struct connectdata *conn, int sockindex) BACKEND->ssl_sockfd = 0; } -static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex) +static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct Curl_easy *data = conn->data; @@ -2963,7 +2963,7 @@ static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex) if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) return 0; - Curl_darwinssl_close(conn, sockindex); + Curl_sectransp_close(conn, sockindex); rc = 0; @@ -3001,18 +3001,18 @@ static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex) return rc; } -static void Curl_darwinssl_session_free(void *ptr) +static void Curl_sectransp_session_free(void *ptr) { /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a cached session ID inside the Security framework. There is a private function that does this, but I don't want to have to explain to you why I got your application rejected from the App Store due to the use of a private API, so the best we can do is free up our own char array that we - created way back in darwinssl_connect_step1... */ + created way back in sectransp_connect_step1... */ Curl_safefree(ptr); } -static size_t Curl_darwinssl_version(char *buffer, size_t size) +static size_t Curl_sectransp_version(char *buffer, size_t size) { return msnprintf(buffer, size, "SecureTransport"); } @@ -3025,7 +3025,7 @@ static size_t Curl_darwinssl_version(char *buffer, size_t size) * 0 means the connection has been closed * -1 means the connection status is unknown */ -static int Curl_darwinssl_check_cxn(struct connectdata *conn) +static int Curl_sectransp_check_cxn(struct connectdata *conn) { struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; OSStatus err; @@ -3040,7 +3040,7 @@ static int Curl_darwinssl_check_cxn(struct connectdata *conn) return 0; } -static bool Curl_darwinssl_data_pending(const struct connectdata *conn, +static bool Curl_sectransp_data_pending(const struct connectdata *conn, int connindex) { const struct ssl_connect_data *connssl = &conn->ssl[connindex]; @@ -3057,7 +3057,7 @@ static bool Curl_darwinssl_data_pending(const struct connectdata *conn, return false; } -static CURLcode Curl_darwinssl_random(struct Curl_easy *data UNUSED_PARAM, +static CURLcode Curl_sectransp_random(struct Curl_easy *data UNUSED_PARAM, unsigned char *entropy, size_t length) { /* arc4random_buf() isn't available on cats older than Lion, so let's @@ -3077,7 +3077,7 @@ static CURLcode Curl_darwinssl_random(struct Curl_easy *data UNUSED_PARAM, return CURLE_OK; } -static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ +static CURLcode Curl_sectransp_md5sum(unsigned char *tmp, /* input */ size_t tmplen, unsigned char *md5sum, /* output */ size_t md5len) @@ -3087,7 +3087,7 @@ static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ return CURLE_OK; } -static CURLcode Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */ +static CURLcode Curl_sectransp_sha256sum(const unsigned char *tmp, /* input */ size_t tmplen, unsigned char *sha256sum, /* output */ size_t sha256len) @@ -3097,7 +3097,7 @@ static CURLcode Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */ return CURLE_OK; } -static bool Curl_darwinssl_false_start(void) +static bool Curl_sectransp_false_start(void) { #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 if(SSLSetSessionOption != NULL) @@ -3106,7 +3106,7 @@ static bool Curl_darwinssl_false_start(void) return FALSE; } -static ssize_t darwinssl_send(struct connectdata *conn, +static ssize_t sectransp_send(struct connectdata *conn, int sockindex, const void *mem, size_t len, @@ -3172,7 +3172,7 @@ static ssize_t darwinssl_send(struct connectdata *conn, return (ssize_t)processed; } -static ssize_t darwinssl_recv(struct connectdata *conn, +static ssize_t sectransp_recv(struct connectdata *conn, int num, char *buf, size_t buffersize, @@ -3212,48 +3212,48 @@ static ssize_t darwinssl_recv(struct connectdata *conn, return (ssize_t)processed; } -static void *Curl_darwinssl_get_internals(struct ssl_connect_data *connssl, +static void *Curl_sectransp_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) { (void)info; return BACKEND->ssl_ctx; } -const struct Curl_ssl Curl_ssl_darwinssl = { - { CURLSSLBACKEND_DARWINSSL, "darwinssl" }, /* info */ +const struct Curl_ssl Curl_ssl_sectransp = { + { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */ -#ifdef DARWIN_SSL_PINNEDPUBKEY +#ifdef SECTRANSP_PINNEDPUBKEY SSLSUPP_PINNEDPUBKEY, #else 0, -#endif /* DARWIN_SSL_PINNEDPUBKEY */ +#endif /* SECTRANSP_PINNEDPUBKEY */ sizeof(struct ssl_backend_data), Curl_none_init, /* init */ Curl_none_cleanup, /* cleanup */ - Curl_darwinssl_version, /* version */ - Curl_darwinssl_check_cxn, /* check_cxn */ - Curl_darwinssl_shutdown, /* shutdown */ - Curl_darwinssl_data_pending, /* data_pending */ - Curl_darwinssl_random, /* random */ + Curl_sectransp_version, /* version */ + Curl_sectransp_check_cxn, /* check_cxn */ + Curl_sectransp_shutdown, /* shutdown */ + Curl_sectransp_data_pending, /* data_pending */ + Curl_sectransp_random, /* random */ Curl_none_cert_status_request, /* cert_status_request */ - Curl_darwinssl_connect, /* connect */ - Curl_darwinssl_connect_nonblocking, /* connect_nonblocking */ - Curl_darwinssl_get_internals, /* get_internals */ - Curl_darwinssl_close, /* close_one */ + Curl_sectransp_connect, /* connect */ + Curl_sectransp_connect_nonblocking, /* connect_nonblocking */ + Curl_sectransp_get_internals, /* get_internals */ + Curl_sectransp_close, /* close_one */ Curl_none_close_all, /* close_all */ - Curl_darwinssl_session_free, /* session_free */ + Curl_sectransp_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_darwinssl_false_start, /* false_start */ - Curl_darwinssl_md5sum, /* md5sum */ - Curl_darwinssl_sha256sum /* sha256sum */ + Curl_sectransp_false_start, /* false_start */ + Curl_sectransp_md5sum, /* md5sum */ + Curl_sectransp_sha256sum /* sha256sum */ }; #ifdef __clang__ #pragma clang diagnostic pop #endif -#endif /* USE_DARWINSSL */ +#endif /* USE_SECTRANSP */ diff --git a/libs/libcurl/src/vtls/darwinssl.h b/libs/libcurl/src/vtls/sectransp.h index 23c7f705cb..5cec797b33 100644 --- a/libs/libcurl/src/vtls/darwinssl.h +++ b/libs/libcurl/src/vtls/sectransp.h @@ -1,5 +1,5 @@ -#ifndef HEADER_CURL_DARWINSSL_H -#define HEADER_CURL_DARWINSSL_H +#ifndef HEADER_CURL_SECTRANSP_H +#define HEADER_CURL_SECTRANSP_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -8,7 +8,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>. - * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -24,9 +24,9 @@ ***************************************************************************/ #include "curl_setup.h" -#ifdef USE_DARWINSSL +#ifdef USE_SECTRANSP -extern const struct Curl_ssl Curl_ssl_darwinssl; +extern const struct Curl_ssl Curl_ssl_sectransp; -#endif /* USE_DARWINSSL */ -#endif /* HEADER_CURL_DARWINSSL_H */ +#endif /* USE_SECTRANSP */ +#endif /* HEADER_CURL_SECTRANSP_H */ diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c index 5e75f92e99..8a405c05cd 100644 --- a/libs/libcurl/src/vtls/vtls.c +++ b/libs/libcurl/src/vtls/vtls.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -248,7 +248,7 @@ Curl_ssl_connect(struct connectdata *conn, int sockindex) conn->ssl[sockindex].use = TRUE; conn->ssl[sockindex].state = ssl_connection_negotiating; - result = Curl_ssl->connect(conn, sockindex); + result = Curl_ssl->connect_blocking(conn, sockindex); if(!result) Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */ @@ -513,7 +513,7 @@ void Curl_ssl_close_all(struct Curl_easy *data) } #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ - defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \ + defined(USE_SECTRANSP) || defined(USE_POLARSSL) || defined(USE_NSS) || \ defined(USE_MBEDTLS) || defined(USE_CYASSL) int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks) @@ -546,7 +546,7 @@ int Curl_ssl_getsock(struct connectdata *conn, (void)numsocks; return GETSOCK_BLANK; } -/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_DARWINSSL || USE_NSS */ +/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_SECTRANSP || USE_NSS */ #endif void Curl_ssl_close(struct connectdata *conn, int sockindex) @@ -557,7 +557,7 @@ void Curl_ssl_close(struct connectdata *conn, int sockindex) CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex) { - if(Curl_ssl->shutdown(conn, sockindex)) + if(Curl_ssl->shut_down(conn, sockindex)) return CURLE_SSL_SHUTDOWN_FAILED; conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */ @@ -1114,7 +1114,7 @@ static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex) { if(multissl_init(NULL)) return CURLE_FAILED_INIT; - return Curl_ssl->connect(conn, sockindex); + return Curl_ssl->connect_blocking(conn, sockindex); } static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn, @@ -1172,8 +1172,8 @@ const struct Curl_ssl *Curl_ssl = &Curl_ssl_multi; #elif defined(USE_CYASSL) &Curl_ssl_cyassl; -#elif defined(USE_DARWINSSL) - &Curl_ssl_darwinssl; +#elif defined(USE_SECTRANSP) + &Curl_ssl_sectransp; #elif defined(USE_GNUTLS) &Curl_ssl_gnutls; #elif defined(USE_GSKIT) @@ -1198,8 +1198,8 @@ static const struct Curl_ssl *available_backends[] = { #if defined(USE_CYASSL) &Curl_ssl_cyassl, #endif -#if defined(USE_DARWINSSL) - &Curl_ssl_darwinssl, +#if defined(USE_SECTRANSP) + &Curl_ssl_sectransp, #endif #if defined(USE_GNUTLS) &Curl_ssl_gnutls, diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index 1f163631f7..2a87ca1f72 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -47,7 +47,7 @@ struct Curl_ssl { size_t (*version)(char *buffer, size_t size); int (*check_cxn)(struct connectdata *cxn); - int (*shutdown)(struct connectdata *conn, int sockindex); + int (*shut_down)(struct connectdata *conn, int sockindex); bool (*data_pending)(const struct connectdata *conn, int connindex); @@ -56,7 +56,7 @@ struct Curl_ssl { size_t length); bool (*cert_status_request)(void); - CURLcode (*connect)(struct connectdata *conn, int sockindex); + CURLcode (*connect_blocking)(struct connectdata *conn, int sockindex); CURLcode (*connect_nonblocking)(struct connectdata *conn, int sockindex, bool *done); void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info); @@ -105,7 +105,7 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, #include "polarssl.h" /* PolarSSL versions */ #include "cyassl.h" /* CyaSSL versions */ #include "schannel.h" /* Schannel SSPI version */ -#include "darwinssl.h" /* SecureTransport (Darwin) version */ +#include "sectransp.h" /* SecureTransport (Darwin) version */ #include "mbedtls.h" /* mbedTLS versions */ #include "mesalink.h" /* MesaLink versions */ diff --git a/libs/libcurl/src/warnless.c b/libs/libcurl/src/warnless.c index 05d9038dc3..cfd5e8e141 100644 --- a/libs/libcurl/src/warnless.c +++ b/libs/libcurl/src/warnless.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -401,44 +401,6 @@ unsigned short curlx_uitous(unsigned int uinum) } /* -** unsigned int to unsigned char -*/ - -unsigned char curlx_uitouc(unsigned int uinum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_UCHAR); - return (unsigned char) (uinum & (unsigned int) CURL_MASK_UCHAR); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned int to signed int -*/ - -int curlx_uitosi(unsigned int uinum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_SINT); - return (int) (uinum & (unsigned int) CURL_MASK_SINT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* ** signed int to unsigned size_t */ diff --git a/libs/libcurl/src/warnless.h b/libs/libcurl/src/warnless.h index 284ea1e752..ea4c4395dc 100644 --- a/libs/libcurl/src/warnless.h +++ b/libs/libcurl/src/warnless.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -57,10 +57,6 @@ int curlx_sztosi(ssize_t sznum); unsigned short curlx_uitous(unsigned int uinum); -unsigned char curlx_uitouc(unsigned int uinum); - -int curlx_uitosi(unsigned int uinum); - size_t curlx_sitouz(int sinum); #ifdef USE_WINSOCK diff --git a/libs/libcurl/src/x509asn1.c b/libs/libcurl/src/x509asn1.c index 746e1e8e8d..25231921c4 100644 --- a/libs/libcurl/src/x509asn1.c +++ b/libs/libcurl/src/x509asn1.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -120,7 +120,7 @@ static const char *getASN1Element(curl_asn1Element *elem, if an error occurs. */ if(!beg || !end || beg >= end || !*beg || (size_t)(end - beg) > CURL_ASN1_MAX) - return (const char *) NULL; + return NULL; /* Process header byte. */ elem->header = beg; @@ -129,12 +129,12 @@ static const char *getASN1Element(curl_asn1Element *elem, elem->class = (b >> 6) & 3; b &= 0x1F; if(b == 0x1F) - return (const char *) NULL; /* Long tag values not supported here. */ + return NULL; /* Long tag values not supported here. */ elem->tag = b; /* Process length. */ if(beg >= end) - return (const char *) NULL; + return NULL; b = (unsigned char) *beg++; if(!(b & 0x80)) len = b; @@ -142,69 +142,72 @@ static const char *getASN1Element(curl_asn1Element *elem, /* Unspecified length. Since we have all the data, we can determine the effective length by skipping element until an end element is found. */ if(!elem->constructed) - return (const char *) NULL; + return NULL; elem->beg = beg; while(beg < end && *beg) { beg = getASN1Element(&lelem, beg, end); if(!beg) - return (const char *) NULL; + return NULL; } if(beg >= end) - return (const char *) NULL; + return NULL; elem->end = beg; return beg + 1; } else if((unsigned)b > (size_t)(end - beg)) - return (const char *) NULL; /* Does not fit in source. */ + return NULL; /* Does not fit in source. */ else { /* Get long length. */ len = 0; do { if(len & 0xFF000000L) - return (const char *) NULL; /* Lengths > 32 bits are not supported. */ + return NULL; /* Lengths > 32 bits are not supported. */ len = (len << 8) | (unsigned char) *beg++; } while(--b); } if(len > (size_t)(end - beg)) - return (const char *) NULL; /* Element data does not fit in source. */ + return NULL; /* Element data does not fit in source. */ elem->beg = beg; elem->end = beg + len; return elem->end; } +/* + * Search the null terminated OID or OID identifier in local table. + * Return the table entry pointer or NULL if not found. + */ static const curl_OID * searchOID(const char *oid) { const curl_OID *op; - - /* Search the null terminated OID or OID identifier in local table. - Return the table entry pointer or NULL if not found. */ - for(op = OIDtable; op->numoid; op++) if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid)) return op; - return (const curl_OID *) NULL; + return NULL; } +/* + * Convert an ASN.1 Boolean value into its string representation. Return the + * dynamically allocated string, or NULL if source is not an ASN.1 Boolean + * value. + */ + static const char *bool2str(const char *beg, const char *end) { - /* Convert an ASN.1 Boolean value into its string representation. - Return the dynamically allocated string, or NULL if source is not an - ASN.1 Boolean value. */ - if(end - beg != 1) - return (const char *) NULL; + return NULL; return strdup(*beg? "TRUE": "FALSE"); } +/* + * Convert an ASN.1 octet string to a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *octet2str(const char *beg, const char *end) { size_t n = end - beg; char *buf = NULL; - /* Convert an ASN.1 octet string to a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - if(n <= (SIZE_T_MAX - 1) / 3) { buf = malloc(3 * n + 1); if(buf) @@ -220,21 +223,22 @@ static const char *bit2str(const char *beg, const char *end) Return the dynamically allocated string, or NULL if an error occurs. */ if(++beg > end) - return (const char *) NULL; + return NULL; return octet2str(beg, end); } +/* + * Convert an ASN.1 integer value into its string representation. + * Return the dynamically allocated string, or NULL if source is not an + * ASN.1 integer value. + */ static const char *int2str(const char *beg, const char *end) { unsigned long val = 0; size_t n = end - beg; - /* Convert an ASN.1 integer value into its string representation. - Return the dynamically allocated string, or NULL if source is not an - ASN.1 integer value. */ - if(!n) - return (const char *) NULL; + return NULL; if(n > 4) return octet2str(beg, end); @@ -249,6 +253,13 @@ static const char *int2str(const char *beg, const char *end) return curl_maprintf("%s%lx", val >= 10? "0x": "", val); } +/* + * Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the + * destination buffer dynamically. The allocation size will normally be too + * large: this is to avoid buffer overflows. + * Terminate the string with a nul byte and return the converted + * string length. + */ static ssize_t utf8asn1str(char **to, int type, const char *from, const char *end) { @@ -259,13 +270,7 @@ utf8asn1str(char **to, int type, const char *from, const char *end) unsigned int wc; char *buf; - /* Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the - destination buffer dynamically. The allocation size will normally be too - large: this is to avoid buffer overflows. - Terminate the string with a nul byte and return the converted - string length. */ - - *to = (char *) NULL; + *to = NULL; switch(type) { case CURL_ASN1_BMP_STRING: size = 2; @@ -341,96 +346,105 @@ utf8asn1str(char **to, int type, const char *from, const char *end) return outlength; } +/* + * Convert an ASN.1 String into its UTF-8 string representation. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *string2str(int type, const char *beg, const char *end) { char *buf; - - /* Convert an ASN.1 String into its UTF-8 string representation. - Return the dynamically allocated string, or NULL if an error occurs. */ - if(utf8asn1str(&buf, type, beg, end) < 0) - return (const char *) NULL; + return NULL; return buf; } -static int encodeUint(char *buf, int n, unsigned int x) +/* + * Decimal ASCII encode unsigned integer `x' into the buflen sized buffer at + * buf. Return the total number of encoded digits, even if larger than + * `buflen'. + */ +static size_t encodeUint(char *buf, size_t buflen, unsigned int x) { - int i = 0; + size_t i = 0; unsigned int y = x / 10; - /* Decimal ASCII encode unsigned integer `x' in the `n'-byte buffer at `buf'. - Return the total number of encoded digits, even if larger than `n'. */ - if(y) { - i += encodeUint(buf, n, y); + i = encodeUint(buf, buflen, y); x -= y * 10; } - if(i < n) + if(i < buflen) buf[i] = (char) ('0' + x); i++; - if(i < n) + if(i < buflen) buf[i] = '\0'; /* Store a terminator if possible. */ return i; } -static int encodeOID(char *buf, int n, const char *beg, const char *end) +/* + * Convert an ASN.1 OID into its dotted string representation. + * Store the result in th `n'-byte buffer at `buf'. + * Return the converted string length, or 0 on errors. + */ +static size_t encodeOID(char *buf, size_t buflen, + const char *beg, const char *end) { - int i = 0; + size_t i; unsigned int x; unsigned int y; - /* Convert an ASN.1 OID into its dotted string representation. - Store the result in th `n'-byte buffer at `buf'. - Return the converted string length, or -1 if an error occurs. */ - /* Process the first two numbers. */ y = *(const unsigned char *) beg++; x = y / 40; y -= x * 40; - i += encodeUint(buf + i, n - i, x); - if(i < n) + i = encodeUint(buf, buflen, x); + if(i < buflen) buf[i] = '.'; i++; - i += encodeUint(buf + i, n - i, y); + if(i >= buflen) + i += encodeUint(NULL, 0, y); + else + i += encodeUint(buf + i, buflen - i, y); /* Process the trailing numbers. */ while(beg < end) { - if(i < n) + if(i < buflen) buf[i] = '.'; i++; x = 0; do { if(x & 0xFF000000) - return -1; + return 0; y = *(const unsigned char *) beg++; x = (x << 7) | (y & 0x7F); } while(y & 0x80); - i += encodeUint(buf + i, n - i, x); + if(i >= buflen) + i += encodeUint(NULL, 0, x); + else + i += encodeUint(buf + i, buflen - i, x); } - if(i < n) + if(i < buflen) buf[i] = '\0'; return i; } +/* + * Convert an ASN.1 OID into its dotted or symbolic string representation. + * Return the dynamically allocated string, or NULL if an error occurs. + */ + static const char *OID2str(const char *beg, const char *end, bool symbolic) { - char *buf = (char *) NULL; - const curl_OID * op; - int n; - - /* Convert an ASN.1 OID into its dotted or symbolic string representation. - Return the dynamically allocated string, or NULL if an error occurs. */ - + char *buf = NULL; if(beg < end) { - n = encodeOID((char *) NULL, -1, beg, end); - if(n >= 0) { - buf = malloc(n + 1); + size_t buflen = encodeOID(NULL, 0, beg, end); + if(buflen) { + buf = malloc(buflen + 1); /* one extra for the zero byte */ if(buf) { - encodeOID(buf, n, beg, end); - buf[n] = '\0'; + encodeOID(buf, buflen, beg, end); + buf[buflen] = '\0'; if(symbolic) { - op = searchOID(buf); + const curl_OID *op = searchOID(buf); if(op) { free(buf); buf = strdup(op->textoid); @@ -470,7 +484,7 @@ static const char *GTime2str(const char *beg, const char *end) sec2 = fracp[-1]; break; default: - return (const char *) NULL; + return NULL; } /* Scan for timezone, measure fractional seconds. */ @@ -506,15 +520,16 @@ static const char *GTime2str(const char *beg, const char *end) sep, tzl, tzp); } +/* + * Convert an ASN.1 UTC time to a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *UTime2str(const char *beg, const char *end) { const char *tzp; size_t tzl; const char *sec; - /* Convert an ASN.1 UTC time to a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++) ; /* Get the seconds. */ @@ -525,12 +540,12 @@ static const char *UTime2str(const char *beg, const char *end) case 2: break; default: - return (const char *) NULL; + return NULL; } /* Process timezone. */ if(tzp >= end) - return (const char *) NULL; + return NULL; if(*tzp == 'Z') { tzp = "GMT"; end = tzp + 3; @@ -545,13 +560,14 @@ static const char *UTime2str(const char *beg, const char *end) tzl, tzp); } +/* + * Convert an ASN.1 element to a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *ASN1tostr(curl_asn1Element *elem, int type) { - /* Convert an ASN.1 element to a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - if(elem->constructed) - return (const char *) NULL; /* No conversion of structured elements. */ + return NULL; /* No conversion of structured elements. */ if(!type) type = elem->tag; /* Type not forced: use element tag as type. */ @@ -585,10 +601,14 @@ static const char *ASN1tostr(curl_asn1Element *elem, int type) return string2str(type, elem->beg, elem->end); } - return (const char *) NULL; /* Unsupported. */ + return NULL; /* Unsupported. */ } -static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn) +/* + * ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at + * `buf'. Return the total string length, even if larger than `buflen'. + */ +static ssize_t encodeDN(char *buf, size_t buflen, curl_asn1Element *dn) { curl_asn1Element rdn; curl_asn1Element atv; @@ -600,9 +620,6 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn) const char *p3; const char *str; - /* ASCII encode distinguished name at `dn' into the `n'-byte buffer at `buf'. - Return the total string length, even if larger than `n'. */ - for(p1 = dn->beg; p1 < dn->end;) { p1 = getASN1Element(&rdn, p1, dn->end); if(!p1) @@ -626,7 +643,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn) for(p3 = str; isupper(*p3); p3++) ; for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) { - if(l < n) + if(l < buflen) buf[l] = *p3; l++; } @@ -634,14 +651,14 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn) /* Encode attribute name. */ for(p3 = str; *p3; p3++) { - if(l < n) + if(l < buflen) buf[l] = *p3; l++; } free((char *) str); /* Generate equal sign. */ - if(l < n) + if(l < buflen) buf[l] = '='; l++; @@ -650,7 +667,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn) if(!str) return -1; for(p3 = str; *p3; p3++) { - if(l < n) + if(l < buflen) buf[l] = *p3; l++; } @@ -661,28 +678,30 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn) return l; } +/* + * Convert an ASN.1 distinguished name into a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *DNtostr(curl_asn1Element *dn) { - char *buf = (char *) NULL; - ssize_t n = encodeDN(buf, 0, dn); - - /* Convert an ASN.1 distinguished name into a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ + char *buf = NULL; + ssize_t buflen = encodeDN(NULL, 0, dn); - if(n >= 0) { - buf = malloc(n + 1); + if(buflen >= 0) { + buf = malloc(buflen + 1); if(buf) { - encodeDN(buf, n + 1, dn); - buf[n] = '\0'; + encodeDN(buf, buflen + 1, dn); + buf[buflen] = '\0'; } } - return (const char *) buf; + return buf; } /* - * X509 parser. + * ASN.1 parse an X509 certificate into structure subfields. + * Syntax is assumed to have already been checked by the SSL backend. + * See RFC 5280. */ - int Curl_parseX509(curl_X509certificate *cert, const char *beg, const char *end) { @@ -691,10 +710,6 @@ int Curl_parseX509(curl_X509certificate *cert, const char *ccp; static const char defaultVersion = 0; /* v1. */ - /* ASN.1 parse an X509 certificate into structure subfields. - Syntax is assumed to have already been checked by the SSL backend. - See RFC 5280. */ - cert->certificate.header = NULL; cert->certificate.beg = beg; cert->certificate.end = end; @@ -801,13 +816,14 @@ int Curl_parseX509(curl_X509certificate *cert, return 0; } + +/* + * Copy at most 64-characters, terminate with a newline and returns the + * effective number of stored characters. + */ static size_t copySubstring(char *to, const char *from) { size_t i; - - /* Copy at most 64-characters, terminate with a newline and returns the - effective number of stored characters. */ - for(i = 0; i < 64; i++) { to[i] = *from; if(!*from++) @@ -1104,15 +1120,15 @@ static const char *checkOID(const char *beg, const char *end, ccp = getASN1Element(&e, beg, end); if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER) - return (const char *) NULL; + return NULL; p = OID2str(e.beg, e.end, FALSE); if(!p) - return (const char *) NULL; + return NULL; matched = !strcmp(p, oid); free((char *) p); - return matched? ccp: (const char *) NULL; + return matched? ccp: NULL; } CURLcode Curl_verifyhost(struct connectdata *conn, |