summaryrefslogtreecommitdiff
path: root/libs/libcurl
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl')
-rw-r--r--libs/libcurl/docs/CHANGES3232
-rw-r--r--libs/libcurl/docs/THANKS44
-rw-r--r--libs/libcurl/include/curl/curl.h29
-rw-r--r--libs/libcurl/include/curl/curlver.h10
-rw-r--r--libs/libcurl/libcurl.vcxproj4
-rw-r--r--libs/libcurl/libcurl.vcxproj.filters6
-rw-r--r--libs/libcurl/src/CMakeLists.txt6
-rw-r--r--libs/libcurl/src/Makefile.in110
-rw-r--r--libs/libcurl/src/Makefile.inc2
-rw-r--r--libs/libcurl/src/amigaos.c29
-rw-r--r--libs/libcurl/src/asyn-ares.c53
-rw-r--r--libs/libcurl/src/asyn-thread.c23
-rw-r--r--libs/libcurl/src/bufref.c127
-rw-r--r--libs/libcurl/src/bufref.h46
-rw-r--r--libs/libcurl/src/c-hyper.c19
-rw-r--r--libs/libcurl/src/checksrc.pl19
-rw-r--r--libs/libcurl/src/config-amigaos.h7
-rw-r--r--libs/libcurl/src/config-dos.h9
-rw-r--r--libs/libcurl/src/config-mac.h7
-rw-r--r--libs/libcurl/src/config-os400.h22
-rw-r--r--libs/libcurl/src/config-plan9.h7
-rw-r--r--libs/libcurl/src/config-riscos.h21
-rw-r--r--libs/libcurl/src/config-tpf.h36
-rw-r--r--libs/libcurl/src/config-vxworks.h21
-rw-r--r--libs/libcurl/src/config-win32.h29
-rw-r--r--libs/libcurl/src/config-win32ce.h18
-rw-r--r--libs/libcurl/src/connect.c29
-rw-r--r--libs/libcurl/src/content_encoding.c9
-rw-r--r--libs/libcurl/src/cookie.c411
-rw-r--r--libs/libcurl/src/curl_addrinfo.c8
-rw-r--r--libs/libcurl/src/curl_config.h.cmake39
-rw-r--r--libs/libcurl/src/curl_config.h.in9
-rw-r--r--libs/libcurl/src/curl_get_line.c4
-rw-r--r--libs/libcurl/src/curl_gssapi.c2
-rw-r--r--libs/libcurl/src/curl_krb5.h1
-rw-r--r--libs/libcurl/src/curl_path.c10
-rw-r--r--libs/libcurl/src/curl_rtmp.c6
-rw-r--r--libs/libcurl/src/curl_sasl.c265
-rw-r--r--libs/libcurl/src/curl_sasl.h12
-rw-r--r--libs/libcurl/src/curl_setup.h36
-rw-r--r--libs/libcurl/src/dict.c11
-rw-r--r--libs/libcurl/src/doh.c27
-rw-r--r--libs/libcurl/src/easy.c8
-rw-r--r--libs/libcurl/src/easyoptions.c4
-rw-r--r--libs/libcurl/src/file.c13
-rw-r--r--libs/libcurl/src/ftp.c17
-rw-r--r--libs/libcurl/src/ftplistparser.c2
-rw-r--r--libs/libcurl/src/gopher.c2
-rw-r--r--libs/libcurl/src/hash.c4
-rw-r--r--libs/libcurl/src/hostcheck.c8
-rw-r--r--libs/libcurl/src/hostip.c29
-rw-r--r--libs/libcurl/src/hostip.h9
-rw-r--r--libs/libcurl/src/hostip6.c19
-rw-r--r--libs/libcurl/src/hsts.c19
-rw-r--r--libs/libcurl/src/hsts.h8
-rw-r--r--libs/libcurl/src/http.c70
-rw-r--r--libs/libcurl/src/http.h5
-rw-r--r--libs/libcurl/src/http2.c98
-rw-r--r--libs/libcurl/src/http2.h2
-rw-r--r--libs/libcurl/src/http_digest.c2
-rw-r--r--libs/libcurl/src/http_negotiate.c2
-rw-r--r--libs/libcurl/src/http_ntlm.c90
-rw-r--r--libs/libcurl/src/http_proxy.c109
-rw-r--r--libs/libcurl/src/http_proxy.h24
-rw-r--r--libs/libcurl/src/imap.c4
-rw-r--r--libs/libcurl/src/inet_ntop.c4
-rw-r--r--libs/libcurl/src/krb5.c22
-rw-r--r--libs/libcurl/src/ldap.c30
-rw-r--r--libs/libcurl/src/libcurl.plist6
-rw-r--r--libs/libcurl/src/llist.c6
-rw-r--r--libs/libcurl/src/md4.c2
-rw-r--r--libs/libcurl/src/mime.c4
-rw-r--r--libs/libcurl/src/mprintf.c4
-rw-r--r--libs/libcurl/src/mqtt.c1
-rw-r--r--libs/libcurl/src/multi.c172
-rw-r--r--libs/libcurl/src/multihandle.h4
-rw-r--r--libs/libcurl/src/non-ascii.c8
-rw-r--r--libs/libcurl/src/openldap.c81
-rw-r--r--libs/libcurl/src/pop3.c17
-rw-r--r--libs/libcurl/src/progress.c86
-rw-r--r--libs/libcurl/src/rtsp.c5
-rw-r--r--libs/libcurl/src/select.c2
-rw-r--r--libs/libcurl/src/sendf.c19
-rw-r--r--libs/libcurl/src/setopt.c60
-rw-r--r--libs/libcurl/src/setup-vms.h8
-rw-r--r--libs/libcurl/src/share.c4
-rw-r--r--libs/libcurl/src/sigpipe.h4
-rw-r--r--libs/libcurl/src/smb.c7
-rw-r--r--libs/libcurl/src/smtp.c6
-rw-r--r--libs/libcurl/src/socks.c6
-rw-r--r--libs/libcurl/src/socks_gssapi.c2
-rw-r--r--libs/libcurl/src/socks_sspi.c2
-rw-r--r--libs/libcurl/src/splay.c18
-rw-r--r--libs/libcurl/src/strerror.c5
-rw-r--r--libs/libcurl/src/system_win32.c4
-rw-r--r--libs/libcurl/src/telnet.c3
-rw-r--r--libs/libcurl/src/tftp.c7
-rw-r--r--libs/libcurl/src/timeval.c8
-rw-r--r--libs/libcurl/src/transfer.c15
-rw-r--r--libs/libcurl/src/url.c25
-rw-r--r--libs/libcurl/src/urlapi.c96
-rw-r--r--libs/libcurl/src/urldata.h36
-rw-r--r--libs/libcurl/src/vauth/cleartext.c70
-rw-r--r--libs/libcurl/src/vauth/cram.c65
-rw-r--r--libs/libcurl/src/vauth/digest.c62
-rw-r--r--libs/libcurl/src/vauth/digest_sspi.c54
-rw-r--r--libs/libcurl/src/vauth/gsasl.c33
-rw-r--r--libs/libcurl/src/vauth/krb5_gssapi.c100
-rw-r--r--libs/libcurl/src/vauth/krb5_sspi.c115
-rw-r--r--libs/libcurl/src/vauth/ntlm.c152
-rw-r--r--libs/libcurl/src/vauth/ntlm_sspi.c58
-rw-r--r--libs/libcurl/src/vauth/oauth2.c53
-rw-r--r--libs/libcurl/src/vauth/vauth.c25
-rw-r--r--libs/libcurl/src/vauth/vauth.h66
-rw-r--r--libs/libcurl/src/version.c42
-rw-r--r--libs/libcurl/src/vquic/ngtcp2.c27
-rw-r--r--libs/libcurl/src/vquic/quiche.c29
-rw-r--r--libs/libcurl/src/vssh/libssh.c146
-rw-r--r--libs/libcurl/src/vssh/libssh2.c79
-rw-r--r--libs/libcurl/src/vssh/ssh.h3
-rw-r--r--libs/libcurl/src/vssh/wolfssh.c6
-rw-r--r--libs/libcurl/src/vtls/bearssl.c17
-rw-r--r--libs/libcurl/src/vtls/gskit.c37
-rw-r--r--libs/libcurl/src/vtls/gtls.c85
-rw-r--r--libs/libcurl/src/vtls/mbedtls.c38
-rw-r--r--libs/libcurl/src/vtls/mesalink.c7
-rw-r--r--libs/libcurl/src/vtls/nss.c53
-rw-r--r--libs/libcurl/src/vtls/openssl.c361
-rw-r--r--libs/libcurl/src/vtls/rustls.c271
-rw-r--r--libs/libcurl/src/vtls/schannel.c122
-rw-r--r--libs/libcurl/src/vtls/schannel.h3
-rw-r--r--libs/libcurl/src/vtls/schannel_verify.c283
-rw-r--r--libs/libcurl/src/vtls/sectransp.c1741
-rw-r--r--libs/libcurl/src/vtls/vtls.c32
-rw-r--r--libs/libcurl/src/vtls/vtls.h20
-rw-r--r--libs/libcurl/src/vtls/wolfssl.c65
-rw-r--r--libs/libcurl/src/x509asn1.c6
137 files changed, 5729 insertions, 4749 deletions
diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES
index 62dce2ee97..e7a462b50e 100644
--- a/libs/libcurl/docs/CHANGES
+++ b/libs/libcurl/docs/CHANGES
@@ -6,6 +6,1698 @@
Changelog
+Version 7.77.0 (26 May 2021)
+
+Daniel Stenberg (26 May 2021)
+- RELEASE-NOTES: synced
+
+- THANKS: added contributors from 7.77.0 cycle
+
+- copyright: update copyright year ranges to 2021
+
+- [Radek Zajic brought this change]
+
+ hostip: fix broken macOS/CMake/GCC builds
+
+ Follow-up to 31f631a142d855f06
+
+ Fixes #7128
+ Closes #7129
+
+- TODO: netrc caching and sharing
+
+ URL: https://curl.se/mail/archive-2021-05/0018.html
+
+- [Orgad Shaneh brought this change]
+
+ setopt: streamline ssl option code
+
+ Make it use the same style as the code next to it
+
+ Closes #7123
+
+- [Radek Zajic brought this change]
+
+ lib/hostip6.c: make NAT64 address synthesis on macOS work
+
+ Closes #7121
+
+- [ejanchivdorj brought this change]
+
+ sectransp: fix EXC_BAD_ACCESS caused by uninitialized buffer
+
+ When the SecCertificateCopyCommonName function fails, it leaves
+ common_name in a invalid state so CFStringCompare uses the invalid
+ result, causing EXC_BAD_ACCESS.
+
+ The fix is to check the return value of the function before using the
+ name.
+
+ Closes #7126
+
+- [Paweł Wegner brought this change]
+
+ CMake: add CURL_ENABLE_EXPORT_TARGET option
+
+ install(EXPORT ...) causes trouble when embedding curl dependencies
+ which don't provide install(EXPORT ...) targets (e.g libressl and
+ nghttp2) with cmake's add_subdirectory.
+
+ Reviewed-by: Jakub Zakrzewski
+ Closes #7060
+
+- [Alessandro Ghedini brought this change]
+
+ quiche: update for network path aware API
+
+ Latest version of quiche requires the application to pass the peer
+ address of received packets, and it provides the address for outgoing
+ packets back.
+
+ Closes #7120
+
+- [Jacob Hoffman-Andrews brought this change]
+
+ rustls: switch read_tls and write_tls to callbacks
+
+ And update to 0.6.0, including a rename from session to connection for
+ many fields.
+
+ Closes #7071
+
+- [Koichi Shiraishi brought this change]
+
+ sectransp: fix 7f4a9a9b2a49 commit about missing comma
+
+ Follow-up to 7f4a9a9b2a495
+
+ Closes #7119
+
+- [Harry Sintonen brought this change]
+
+ openssl: associate/detach the transfer from connection
+
+ CVE-2021-22901
+
+ Bug: https://curl.se/docs/CVE-2021-22901.html
+
+- [Harry Sintonen brought this change]
+
+ telnet: check sscanf() for correct number of matches
+
+ CVE-2021-22898
+
+ Bug: https://curl.se/docs/CVE-2021-22898.html
+
+- schannel: don't use static to store selected ciphers
+
+ CVE-2021-22897
+
+ Bug: https://curl.se/docs/CVE-2021-22897.html
+
+- docs/tests: remove freenode references
+
+- RELEASE-NOTES: synced
+
+- [Sergey Markelov brought this change]
+
+ NSS: make colons, commas and spaces valid separators in cipher list
+
+ Fixes #7110
+ Closes #7115
+
+- curl: include libmetalink version in --version output
+
+ Closes #7112
+
+Jay Satiro (21 May 2021)
+- [Matias N. Goldberg brought this change]
+
+ cmake: Use multithreaded compilation on VS 2008+
+
+ Multithreaded compilation has been supported since at least VS 2005 and
+ been robustly stable since at least VS 2008
+
+ Closes https://github.com/curl/curl/pull/7109
+
+Daniel Stenberg (21 May 2021)
+- [Matias N. Goldberg brought this change]
+
+ cmake: fix two invokes result in different curl_config.h
+
+ Fixes #7100
+ Closes #7101
+
+ Reviewed-by: Jakub Zakrzewski
+ Signed-off-by: Matias N. Goldberg <dark_sylinc@yahoo.com.ar>
+
+- [Peng-Yu Chen brought this change]
+
+ cmake: detect CURL_SA_FAMILY_T
+
+ Fixes #7049
+ Closes #7065
+
+- [Lucas Clemente Vella brought this change]
+
+ CURLOPT_IPRESOLVE: preventing wrong IP version from being used
+
+ In some situations, it was possible that a transfer was setup to
+ use an specific IP version, but due do DNS caching or connection
+ reuse, it ended up using a different IP version from requested.
+
+ This commit changes the effect of CURLOPT_IPRESOLVE from simply
+ restricting address resolution to preventing the wrong connection
+ type being used, when choosing a connection from the pool, and
+ to restricting what addresses could be used when establishing
+ a new connection.
+
+ It is important that all addresses versions are resolved, even if
+ not used in that transfer in particular, because the result is
+ cached, and could be useful for a different transfer with a
+ different CURLOPT_IPRESOLVE setting.
+
+ Closes #6853
+
+- [Oliver Urbann brought this change]
+
+ AmigaOS: add functions definitions for SHA256
+
+ AmiSSL replaces many functions with macros. Curl requires pointer
+ to some of these functions. Thus, we have to encapsulate these macros:
+ SHA256_Init, SHA256_Update, SHA256_Final, X509_INFO_free.
+
+ Bug: https://github.com/jens-maus/amissl/issues/15
+ Co-authored-by: Daniel Stenberg <daniel@haxx.se>
+
+ Closes #7099
+
+- test2100: make it run with and require IPv6
+
+ Closes #7083
+
+- tests/getpart: generate output URL encoded for better diffs
+
+ Closes #7083
+
+- [Ryan Beck-Buysse brought this change]
+
+ docs/TheArtOfHttpScripting: fix markdown links
+
+ extra parens cause the links to be incorrectly formatted
+ and inconsistent with the rest of the document.
+
+ Signed-off-by: Ryan Beck-Buysse <rbuysse@gmail.com>
+ Closes #7097
+
+- RELEASE-NOTES: synced
+
+- [Emil Engler brought this change]
+
+ docs: replace dots with dashes in markdown enums
+
+ We use dashes instead of dots nearly everywhere except for those few
+ cases. This commit addresses this issues and brings more coherency into
+ it.
+
+ Closes #7093
+
+- [Emil Engler brought this change]
+
+ docs: improve INTERNALS.md regarding getsock cb
+
+ This adds the I/O prefix to indicate that those "actions" are kind-of
+ related to those found in select(2) or poll(2) (reading/writing).
+
+ It also adds a note where the prototypes of those functions can be found
+ in the source code.
+
+ Closes #7092
+
+- [Emil Engler brought this change]
+
+ docs: document attach in INTERNALS.md
+
+ The new field in the Curl_handler struct still lacks documentation. This
+ adds it it from the information extracted from lib/urldata.h:797
+
+ Closes #7091
+
+- [Marc Aldorasi brought this change]
+
+ config: remove now-unused macros
+
+ Closes #7094
+
+- [Marc Aldorasi brought this change]
+
+ hostip.h: remove declaration of unimplemented function
+
+ Closes #7094
+
+- h3: add 'attach' callback to protocol handlers
+
+ Follow-up to 0c55fbab45be
+
+ Reviewed-by: Emil Engler
+ Closes #7090
+
+- wolfssl: remove SSLv3 support leftovers
+
+ Closes #7088
+
+- curl-wolfssl.m4: without custom include path, assume /usr/include
+
+ ... so that we can point out the root of the OpenSSL emulation headers.
+ Previously this used the '$includedir' variable which is wrong since
+ that defaults to the dir where the current configure invoke will install
+ the built libcurl headers: /usr/local by default.
+
+ Fixes #7085
+ Reported-by: Joel Jakobsson
+ Closes #7087
+
+- [Joel Depooter brought this change]
+
+ data_pending: check only SECONDARY socket for FTP(S) transfers
+
+ Check the FIRST for all other protocols.
+
+ This fixes a timeout in an ftps download. The server sends a TLS
+ close_notify message in the same packet as the file data. The
+ close_notify seems to not be handled in the schannel_recv function, so
+ libcurl is not aware that the server has closed the connection. Thus
+ libcurl ends up waiting for action on the socket until a timeout is
+ reached. With the secondary socket check added to the data_pending
+ function, the close_notify is properly handled, and the ftps transfer
+ terminates as expected.
+
+ Fixes #7068
+ Closes #7069
+
+- github: inhibit deprecated declarations for clang on macOS
+
+ ... as they otherwise cause ldap build errors in the CI.
+
+ Fixes #7081
+ Closes #7082
+
+- conn: add 'attach' to protocol handler, make libssh2 use it
+
+ The libssh2 backend has SSH session associated with the connection but
+ the callback context is the easy handle, so when a connection gets
+ attached to a transfer, the protocol handler now allows for a custom
+ function to get used to set things up correctly.
+
+ Reported-by: Michael O'Farrell
+ Fixes #6898
+ Closes #7078
+
+- http2: make sure pause is done on HTTP
+
+ Since the function is called for any protocol, we can't assume that the
+ HTTP struct is there without first making sure it is HTTP.
+
+ Reported-by: Denis Goleshchikhin
+ Fixes #7079
+ Closes #7080
+
+- docs: cookies from HTTP headers need domain set
+
+ ... or the cookies won't get sent. Push users to using the "Netscape"
+ format instead, which curl uses when saving a cookie "jar".
+
+ Reported-by: Martin Dorey
+ Reviewed-by: Daniel Gustafsson
+ Fixes #6723
+ Closes #7077
+
+- RELEASE-NOTES: synced
+
+- github: add a workflow with libssh2 on macOS using cmake
+
+ Closes #7047
+
+- sws: allow HTTP requests up to 2MB in size
+
+ To allow tests with slightly larger payloads. Like #7071 ...
+
+ Closes #7075
+
+Marc Hoersken (16 May 2021)
+- CI/azure: increase verbosity and fix outdated task names
+
+ Closes #7063
+
+- CI/cirrus: add shared and static Windows release builds
+
+ Azure Pipelines is currently being used for debug builds,
+ let's also run some non-debug (release) Windows builds and
+ make use of previously underutilized Cirrus CI for that.
+
+ Reviewed-by: Marcel Raad
+
+ Closes #6991
+
+Daniel Stenberg (16 May 2021)
+- CURLOPT_CAPATH.3: defaults to a path, not NULL
+
+ Reported-by: Andrew Barnert
+
+ Closes #7062
+
+- [Jacob Hoffman-Andrews brought this change]
+
+ c-hyper: handle body on HYPER_TASK_EMPTY
+
+ Some of the time, we get a HYPER_TASK_EMPTY response before the status
+ line, headers, and body have been read. Previously, that would cause us
+ to poll again, leading to a 1 second timeout.
+
+ The HYPER_TASK_EMPTY docs say:
+
+ The value of this task is null (does not imply an error).
+
+ So, if we receive a HYPER_TASK_EMPTY, continue on with processing the
+ response.
+
+ Reported-by: Kevin Burke
+ Fixes #7064
+ Closes #7070
+
+- [Ikko Ashimine brought this change]
+
+ tool_getparam: fix comment typo in tool_getparam.c
+
+ enfore -> enforce
+
+ Closes #7074
+
+- mem-include-scan.pl: require a non-word letter before memory funcs
+
+ ... so that ldap_memfree() for example doesn't match the scan for free.
+
+ Closes #7061
+
+- version: free the openldap info correctly
+
+ ... to avoid memory leaks.
+
+ Follow-up to: bf0feae7768d9
+ Closes #7061
+
+- dupset: remove totally off comment
+
+ Closes #7067
+
+- configure: if asked for, fail if ldap is not found
+
+ Reported-by: Jakub Zakrzewski
+ Fixes #7053
+ Closes #7055
+
+- version: add OpenLDAP version in the output
+
+ Assisted-by: Howard Chu
+ Closes #7054
+
+Jay Satiro (13 May 2021)
+- [Joel Depooter brought this change]
+
+ schannel: Ensure the security context request flags are always set
+
+ As of commit 54e7475, these flags would only be set when using a new
+ credential handle. When re-using an existing credential handle, the
+ flags would not be set.
+
+ Closes https://github.com/curl/curl/pull/7051
+
+Dan Fandrich (12 May 2021)
+- tests: Fix some tag matching issues in a number of tests
+
+Daniel Stenberg (12 May 2021)
+- sasl: use 'unsigned short' to store mechanism
+
+ ... saves a few bytes of struct size in memory and it only uses
+ 10 bits anyway.
+
+ Closes #7045
+
+- hostip: remove the debug code for LocalHost
+
+ The Curl_resolv() had special code (when built in debug mode) for when
+ resolving the host name "LocalHost" (using that exact casing). It would
+ then get the host name from the --interface option instead.
+
+ This development-only feature was not used by anything (anymore) and we
+ have the --resolve feature if we want to play similar tricks properly
+ going forward.
+
+ Closes #7044
+
+- progress: reset limit_size variables at transfer start
+
+ Otherwise the old value would linger from a previous use and would mess
+ up the network speed cap logic.
+
+ Reported-by: Ymir1711 on github
+
+ Fixes #7042
+ Closes #7043
+
+- RELEASE-NOTES: synced
+
+- [Daniel Gustafsson brought this change]
+
+ cookies: use CURLcode for cookie_output reporting
+
+ Writing the cookie file has multiple error conditions, and was using an
+ int with magic numbers to report the different error (which in turn were
+ disregarded anyways). This moves reporting to use a CURLcode value.
+
+ Lightly-touched-by: Daniel Stenberg
+
+ Closes #7037
+ Closes #6749
+
+- [Daniel Gustafsson brought this change]
+
+ cookies: make use of string duplication function
+
+ strstore() is defined as a strdup which ensures to free the target
+ pointer before duping the source char * into it. Make use of it in
+ two more cases where it can simplify the code.
+
+- [Daniel Gustafsson brought this change]
+
+ cookies: refactor comments
+
+ Comments in the cookie code were a bit all over the place in terms of
+ style and wording. This takes a stab at cleaning them up by keeping to
+ a single style and overall shape. Some comments are moved a little and
+ some removed alltogether due to being redundant. No functional changes
+ have been made,
+
+- [Peng-Yu Chen brought this change]
+
+ http2: skip immediate parsing of payload following protocol switch
+
+ This is considered not harmful as a following http2_recv shall be
+ called very soon.
+
+ This is considered helpful in the specific situation where some
+ servers (e.g. nghttpx v1.43.0) may fulfill stream 1 immediately
+ following the return of HTTP status 101, other than waiting for
+ the client-side connection preface to arrive.
+
+ Fixes #7036
+ Closes #7040
+
+- [Peng-Yu Chen brought this change]
+
+ http2: use nghttp2_session_upgrade2 instead of nghttp2_session_upgrade
+
+ Following the upstream deprecation of nghttp2_session_upgrade.
+
+ Also provides further checks for requests with the HEAD method.
+
+ Closes #7041
+
+- progress/trspeed: use a local convenient pointer to beautify code
+
+ The function becomes easier to read and understand with less repetition.
+
+- trspeed: use long double for transfer speed calculation
+
+- progress: move transfer speed calc into function
+
+ This silences two scan-build-11 warnings: "The result of the '/'
+ expression is undefined"
+
+ Bug: https://curl.se/mail/lib-2021-05/0022.html
+ Closes #7035
+
+- [Cameron Cawley brought this change]
+
+ openssl: remove unneeded cast for CertOpenSystemStore()
+
+ Closes #7025
+
+- travis: disable the libssh build
+
+ It can't run on focal and causes warnings on bionic. Since the focal
+ failure started rather suddenly a while ago, we can suspect it might be
+ temporary.
+
+ Added "bring back the build" to the TODO document.
+
+ Fixes #7011
+ Closes #7012
+
+- [Peng-Yu Chen brought this change]
+
+ http: use calculated offsets inst of integer literals for header parsing
+
+ Assumed to be a minor coding style improvement with no behavior change.
+
+ A modern compiler is expected to have the calculation optimized during
+ compilation. It may be deemed okay even if that's not the case, since
+ the added overhead is considered very low.
+
+ Closes #7032
+
+- [Peng-Yu Chen brought this change]
+
+ GIT-INFO: suggest using autoreconf instead of buildconf
+
+ Follow-up to 85868537d
+
+ Closes #7033
+
+- http: deal with partial CONNECT sends
+
+ Also added 'CURL_SMALLSENDS' to make Curl_write() send short packets,
+ which helped verifying this even more.
+
+ Add test 363 to verify.
+
+ Reported-by: ustcqidi on github
+ Fixes #6950
+ Closes #7024
+
+- HTTP3: make the ngtcp2 build use the quictls fork
+
+ ... as ngtcp2 itself documents the build this way.
+
+ Closes #7031
+
+- http: limit the initial send amount to used upload buffer size
+
+ Previously this logic would cap the send to CURL_MAX_WRITE_SIZE bytes,
+ but for the situations where a larger upload buffer has been set, this
+ function can benefit from sending more bytes. With default size used,
+ this does the same as before.
+
+ Also changed the storage of the size to an 'unsigned int' as it is not
+ allowed to be set larger than 2M.
+
+ Also added cautions to the man pages about changing buffer sizes in
+ run-time.
+
+ Closes #7022
+
+- RELEASE-NOTES: synced
+
+- ngtcp2: fix the cb_acked_stream_data_offset proto
+
+ The 'datalen' value should be 64 bit, not size_t!
+
+ Reported-by: Dmitry Karpov
+ Bug: https://curl.se/mail/lib-2021-05/0019.html
+ Closes #7027
+
+- progress: when possible, calculate transfer speeds with microseconds
+
+ ... this improves precision, especially for transfers in the few or even
+ sub millisecond range.
+
+ Reported-by: J. Bromley
+ Fixes #7017
+ Closes #7020
+
+- http: reset the header buffer when sending the request
+
+ A reused transfer handle could otherwise reuse the previous leftover
+ buffer and havoc would ensue.
+
+ Reported-by: sergio-nsk on github
+ Fixes #7018
+ Closes #7021
+
+- curl_mprintf.3: add description
+
+ These functions have existed in the API since the dawn of time. It is
+ about time we describe how they work, even if we discourage users from
+ using them.
+
+ Closes #7010
+
+- [Timothy Gu brought this change]
+
+ URL-SYNTAX: update IDNA section for WHATWG spec changes
+
+ WHATWG URL has dictated the use of Nontransitional Processing (IDNA
+ 2008) for several years now. Chrome (and derivatives) still use
+ Transitional Processing, but Firefox and Safari have both switched.
+
+ Also document the fact that winidn functions differently from libidn2
+ here.
+
+ Closes #7026
+
+- [Calvin Buckley brought this change]
+
+ INSTALL: add IBM i specific quirks
+
+ Fixes #6830
+ Closes #7013
+
+- libcurl.3: mention the URL API
+
+ To make it easier to find. Also a minor polish of libcurl-url.3
+
+ Closes #7009
+
+- GnuTLS: don't allow TLS 1.3 for versions that don't support it
+
+ Follow-up to 781864bedbc5
+
+ ... as they don't understand it and will return error at us!
+
+ Closes #7014
+
+Kamil Dudka (6 May 2021)
+- tool_getparam: handle failure of curlx_convert_tchar_to_UTF8()
+
+ Reported by GCC analyzer:
+
+ Error: GCC_ANALYZER_WARNING (CWE-476):
+ src/tool_getparam.c: scope_hint: In function 'parse_args'
+ src/tool_getparam.c:2318:38: warning[-Wanalyzer-possible-null-dereference]: dereference of possibly-NULL 'orig_opt'
+ lib/curlx.h:56: included_from: Included from here.
+ src/tool_getparam.c:28: included_from: Included from here.
+ lib/curl_multibyte.h:70:51: note: in definition of macro 'curlx_convert_tchar_to_UTF8'
+ src/tool_getparam.c:2316:16: note: in expansion of macro 'curlx_convert_tchar_to_UTF8'
+
+ Reviewed-by: Marcel Raad
+ Reviewed-by: Daniel Stenberg
+ Closes #7023
+
+Daniel Stenberg (6 May 2021)
+- scripts/delta: also show total number of days
+
+Marc Hoersken (5 May 2021)
+- sockfilt: fix invalid increment of handles index variable nfd
+
+ Only increment the array index if we actually stored a handle.
+
+ Follow up to e917492048f4b85a0fd58a033d10072fc7666c3b
+ Closes #6992
+
+- sockfilt: avoid getting stuck waiting for writable socket
+
+ Reset FD_WRITE event using the same approach as in multi.c
+
+ Follow up to b36442b24305f3cda7c13cc64b46838995a4985b
+ Closes #6992
+
+Jay Satiro (5 May 2021)
+- test678: Fix for Windows multibyte builds
+
+ Follow-up to 77fc385 from yesterday.
+
+ Bug: https://github.com/curl/curl/pull/6662#issuecomment-832966557
+ Reported-by: Marc Hörsken
+
+- [Dmitry Kostjuchenko brought this change]
+
+ build: fix compilation for Windows UWP platform
+
+ - Include afunix.h which is necessary for sockaddr_un when
+ USE_UNIX_SOCKETS is defined on Windows.
+
+ Closes https://github.com/curl/curl/pull/7006
+
+Daniel Stenberg (5 May 2021)
+- gnutls: make setting only the MAX TLS allowed version work
+
+ Previously, settting only the max allowed TLS version, leaving the
+ minimum one at default, didn't actually set it and left it to default
+ (TLS 1.3) too!
+
+ As a bonus, this change also removes the dead code handling of SSLv3
+ since that version can't be set anymore (since eff614fb0242cb).
+
+ Reported-by: Daniel Carpenter
+ Fixes #6998
+ Closes #7000
+
+- openldap: replace ldap_ prefix on private functions
+
+ Since openldap itself uses that prefix and with OpenĹDAP 2.5.4 (at
+ least) there's a symbol collision because of that.
+
+ The private functions now use the 'oldap_' prefix where it previously
+ used 'ldap_'.
+
+ Reported-by: 3eka on github
+ Fixes #7004
+ Closes #7005
+
+Jay Satiro (5 May 2021)
+- http2: fix potentially uninitialized variable
+
+ introduced several days ago in 3193170. caught by visual studio linker.
+
+- [Gilles Vollant brought this change]
+
+ SSL: support in-memory CA certs for some backends
+
+ - New options CURLOPT_CAINFO_BLOB and CURLOPT_PROXY_CAINFO_BLOB to
+ specify in-memory PEM certificates for OpenSSL, Schannel (Windows)
+ and Secure Transport (Apple) SSL backends.
+
+ Prior to this change PEM certificates could only be imported from a file
+ and not from memory.
+
+ Co-authored-by: moparisthebest@users.noreply.github.com
+
+ Ref: https://github.com/curl/curl/pull/4679
+ Ref: https://github.com/curl/curl/pull/5677
+ Ref: https://github.com/curl/curl/pull/6109
+
+ Closes https://github.com/curl/curl/pull/6662
+
+Daniel Stenberg (4 May 2021)
+- [David Cook brought this change]
+
+ tests: ignore case of chunked hex numbers in tests
+
+ When hyper is used, it emits uppercase hexadecimal numbers for chunked
+ encoding lengths. Without hyper, lowercase hexadecimal numbers are used.
+ This change adds preprocessor statements to tests where this is an
+ issue, and adapts the fixtures to match.
+
+ Closes #6987
+
+- cmake: check for getppid and utimes
+
+ ... as they're checked for in the configure script and are used by
+ source code.
+
+ Removed checks for perror, setvbuf and strlcat since those defines are
+ not checked for in source code.
+
+ Bonus: removed HAVE_STRLCPY from a few config-*.h files since that
+ symbol is not used in source code.
+
+ Closes #6997
+
+- libtest: remove lib530.c
+
+ Follow up from e50a877df when test 530 was removed. Since then this
+ source file has not been used/needed.
+
+ Closes #6999
+
+- FILEFORMAT: mention sectransp as a feature
+
+ Been supported since at least 40259ca65
+
+ Closes #7001
+
+- RELEASE-NOTES: synced
+
+- libssh2: ignore timeout during disconnect
+
+ ... to avoid memory leaks!
+
+ libssh2 is tricky as we have to deal with the non-blockiness even in
+ close and shutdown cases. In the cases when we shutdown after a timeout
+ already expired, it is crucial that curl doen't let the timeout abort
+ the shutdown process as that then leaks memory!
+
+ Reported-by: Benjamin Riefenstahl
+ Fixes #6990
+
+- KNOWN_BUGS: add two HTTP/2 bugs
+
+- KNOWN_BUGS: add three HTTP/3 issues
+
+ ... and moved the HTTP/2 issues to its own section
+
+ Closes #6606
+ Closes #6510
+ Closes #6494
+
+- [ejanchivdorj brought this change]
+
+ CURLcode: add CURLE_SSL_CLIENTCERT
+
+ When a TLS server requests a client certificate during handshake and
+ none can be provided, libcurl now returns this new error code
+ CURLE_SSL_CLIENTCERT
+
+ Only supported by Secure Transport and OpenSSL for TLS 1.3 so far.
+
+ Closes #6721
+
+- [Tobias Gabriel brought this change]
+
+ .github/FUNDING: add link to GitHub sponsors
+
+ Closes #6985
+
+- [Harry Sintonen brought this change]
+
+ krb5/name_to_level: replace checkprefix with curl_strequal
+
+ Closes #6993
+
+- [Harry Sintonen brought this change]
+
+ Curl_input_digest: require space after Digest
+
+ Closes #6993
+
+- [Harry Sintonen brought this change]
+
+ Curl_http_header: check for colon when matching Persistent-Auth
+
+ Closes #6993
+
+- [Harry Sintonen brought this change]
+
+ Curl_http_input_auth: require valid separator after negotiation type
+
+ Closes #6993
+
+- http: fix the check for 'Authorization' with Bearer
+
+ The code would wrongly check for it using an additional colon.
+
+ Reported-by: Blake Burkhart
+ Closes #6988
+
+- [Kamil Dudka brought this change]
+
+ http2: fix a resource leak in push_promise()
+
+ ... detected by Coverity:
+
+ Error: RESOURCE_LEAK (CWE-772):
+ lib/http2.c:532: alloc_fn: Storage is returned from allocation function "duphandle".
+ lib/http2.c:532: var_assign: Assigning: "newhandle" = storage returned from "duphandle(data)".
+ lib/http2.c:552: noescape: Resource "newhandle" is not freed or pointed-to in "set_transfer_url".
+ lib/http2.c:555: leaked_storage: Variable "newhandle" going out of scope leaks the storage it points to.
+
+ Closes #6986
+
+- [Kamil Dudka brought this change]
+
+ http2: fix resource leaks in set_transfer_url()
+
+ ... detected by Coverity:
+
+ Error: RESOURCE_LEAK (CWE-772):
+ lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
+ lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
+ lib/http2.c:486: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.]
+ lib/http2.c:488: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
+
+ Error: RESOURCE_LEAK (CWE-772):
+ lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
+ lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
+ lib/http2.c:493: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.]
+ lib/http2.c:495: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
+
+ Error: RESOURCE_LEAK (CWE-772):
+ lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
+ lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
+ lib/http2.c:500: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.]
+ lib/http2.c:502: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
+
+ Error: RESOURCE_LEAK (CWE-772):
+ lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
+ lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
+ lib/http2.c:505: noescape: Resource "u" is not freed or pointed-to in "curl_url_get". [Note: The source code implementation of the function has been overridden by a builtin model.]
+ lib/http2.c:507: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
+
+ Closes #6986
+
+- [Jacob Hoffman-Andrews brought this change]
+
+ rustls: use ALPN
+
+ Update required rustls to 0.5.0
+
+ Closes #6960
+
+- [MAntoniak brought this change]
+
+ gskit: fix CURL_DISABLE_PROXY build
+
+ Removed localfd and remotefd from ssl_backend_data (ued only with proxy
+ connection). Function pipe_ssloverssl return always 0, when proxy is not
+ used.
+
+ Closes #6981
+
+- [MAntoniak brought this change]
+
+ gskit: fix undefined reference to 'conn'
+
+ Closes #6980
+
+- [Jacob Hoffman-Andrews brought this change]
+
+ tls: add USE_HTTP2 define
+
+ This abstracts across the two HTTP/2 backends: nghttp2 and Hyper.
+
+ Add our own define for the "h2" ALPN protocol, so TLS backends can use
+ it without depending on a specific HTTP backend.
+
+ Closes #6959
+
+- [Jacob Hoffman-Andrews brought this change]
+
+ lib: fix 0-length Curl_client_write calls
+
+ Closes #6954
+
+- [Jacob Hoffman-Andrews brought this change]
+
+ lib: remove strlen call from Curl_client_write
+
+ At all call sites with an explicit 0 len, pass an appropriate nonzero
+ len.
+
+ Closes #6954
+
+- [Ayushman Singh Chauhan brought this change]
+
+ docs: camelcase it like GitHub everywhere
+
+ Closes #6979
+
+Jay Satiro (27 Apr 2021)
+- [Lucas Servén Marín brought this change]
+
+ docs: fix typo in fail-with-body doc
+
+ This commit fixes a small typo in the documentation for the
+ --fail-with-body flag.
+
+ Closes https://github.com/curl/curl/pull/6977
+
+- lib: fix some misuse of curlx_convert_UTF8_to_tchar
+
+ curlx_convert_UTF8_to_tchar must be freed by curlx_unicodefree, but
+ prior to this change some uses mistakenly called free.
+
+ I've reviewed all other uses of curlx_convert_UTF8_to_tchar and
+ curlx_convert_tchar_to_UTF8.
+
+ Bug: https://github.com/curl/curl/pull/6602#issuecomment-825236763
+ Reported-by: sergio-nsk@users.noreply.github.com
+
+ Closes https://github.com/curl/curl/pull/6938
+
+Daniel Stenberg (27 Apr 2021)
+- ntlm: precaution against super huge type2 offsets
+
+ ... which otherwise caused an integer overflow and circumvented the if()
+ conditional size check.
+
+ Detected by OSS-Fuzz
+ Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33720
+ Assisted-by: Max Dymond
+ Closes #6975
+
+- c-hyper: fix unused variable ‘wrote’
+
+- libcurl-security.3: be careful of setuid
+
+ Reported-by: Harry Sintonen
+ Closes #6970
+
+- [Kevin Burke brought this change]
+
+ c-hyper: don't write to set.writeheader if null
+
+ Previously if a caller set CURLOPT_WRITEFUNCTION but did not set a
+ CURLOPT_HEADERDATA buffer, Hyper would still attempt to write headers to
+ the data->set.writeheader header buffer, even though it is null. This
+ led to NPE segfaults attempting to use libcurl+Hyper with Git, for
+ example.
+
+ Instead, process the client write for the status line using the same
+ logic we use to process the client write for the later HTTP headers,
+ which contains the appropriate guard logic. As a side benefit,
+ data->set.writeheader is now only read in one file instead of two.
+
+ Fixes #6619
+ Fixes abetterinternet/crustls#49
+ Fixes hyperium/hyper#2438
+ Closes #6971
+
+- wolfssl: handle SSL_write() returns 0 for error
+
+ Reported-by: Timo Lange
+
+ Closes #6967
+
+- easy: ignore sigpipe in curl_easy_send
+
+ Closes #6965
+
+- sigpipe: ignore SIGPIPE when using wolfSSL as well
+
+ Closes #6966
+
+- libcurl-security.3: don't try to filter IPv4 hosts based on the URL
+
+ Closes #6942
+
+- [Harry Sintonen brought this change]
+
+ nss_set_blocking: avoid static for sock_opt
+
+ Reviewed-by: Kamil Dudka
+ Closes #6945
+
+- RELEASE-NOTES: synced
+
+- [Yusuke Nakamura brought this change]
+
+ docs/HTTP3.md: fix nghttp2's HTTP/3 server port
+
+ Port 8443 does not work now.
+ Correct origin is in the quicwg's wiki.
+ https://github.com/quicwg/base-drafts/wiki/Implementations#ngtcp2
+
+ Closes #6964
+
+- krb5: don't use 'static' to store PBSZ size response
+
+ ... because it makes the knowledge and usage cross-transfer in funny and
+ unexpected ways.
+
+ Reported-by: Harry Sintonen
+ Closes #6963
+
+- [Kevin Burke brought this change]
+
+ m4: add security frameworks on Mac when compiling rustls
+
+ Previously compiling rustls on Mac would only complete if you also
+ compiled the SecureTransport TLS backend, which curl would prefer to
+ the Rust backend.
+
+ Appending these flags to LDFLAGS makes it possible to compile the
+ Rustls backend on Mac without the SecureTransport backend, which means
+ this patch will make it possible for Mac users to use the Rustls
+ backend for TLS.
+
+ Reviewed-by: Jacob Hoffman-Andrews
+
+ Fixes #6955
+ Cloes #6956
+
+- krb5: remove the unused 'overhead' function
+
+ Closes #6947
+
+- [Johann150 brought this change]
+
+ curl_url_set.3: add memory management information
+
+ wording taken from man page for CURLOPT_URL.3
+
+ As far as I can see, the URL part is either malloc'ed before due to
+ encoding or it is strdup'ed.
+
+ Closes #6953
+
+- [Jacob Hoffman-Andrews brought this change]
+
+ c-hpyer: fix handling of zero-byte chunk from hyper
+
+ Closes #6951
+
+- CURLOPT_POSTFIELDS.3: clarify how it gets the size of the data
+
+ Ref: https://curl.se/mail/lib-2021-04/0085.html
+ Closes #6943
+
+- [Ralph Langendam brought this change]
+
+ cmake: make libcurl output filename configurable
+
+ Reviewed-by: Jakub Zakrzewski
+ Closes #6933
+
+- [Patrick Monnerat brought this change]
+
+ vtls: reset ssl use flag upon negotiation failure
+
+ Fixes the segfault in ldaps disconnect.
+
+ Reported-by: Illarion Taev
+ Fixes #6934
+ Closes #6937
+
+- configure: fix typo in TLS error message
+
+ Reported-by: Pontus Lundkvist
+
+- README: link to the commercial support option
+
+Jay Satiro (22 Apr 2021)
+- [Martin Halle brought this change]
+
+ version: add gsasl_version to curl_version_info_data
+
+ - Add gsasl_version string and bump to CURLVERSION_TENTH.
+
+ Ref: https://curl.se/mail/lib-2021-04/0003.html
+
+ Closes https://github.com/curl/curl/pull/6843
+
+- [Morten Minde Neergaard brought this change]
+
+ schannel: Support strong crypto option
+
+ - Support enabling strong crypto via optional user cipher list when
+ USE_STRONG_CRYPTO or SCH_USE_STRONG_CRYPTO is in the list.
+
+ MSDN says SCH_USE_STRONG_CRYPTO "Instructs Schannel to disable known
+ weak cryptographic algorithms, cipher suites, and SSL/TLS protocol
+ versions that may be otherwise enabled for better interoperability."
+
+ Ref: https://curl.se/mail/lib-2021-02/0066.html
+ Ref: https://curl.se/docs/manpage.html#--ciphers
+ Ref: https://curl.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html
+ Ref: https://docs.microsoft.com/en-us/windows/win32/api/schannel/ns-schannel-schannel_cred
+
+ Closes https://github.com/curl/curl/pull/6734
+
+Daniel Stenberg (22 Apr 2021)
+- RELEASE-NOTES: synced
+
+- ci: adapt to configure requiring an explicit TLS choice
+
+- configure: split out each TLS library detector into its own function
+
+ ... and put those functions in separate m4 files per TLS library.
+
+- configure: make the TLS library choice(s) explicit
+
+ configure no longer tries to find a TLS library by default, but all
+ libraries are now equal: the user needs to explicitly ask what TLS
+ library or libraries to use.
+
+ If no TLS library is selected, configure will error out unless
+ --without-ssl is explicitly used to request a built without TLS (as that
+ is very rare these days).
+
+ Removes: --with-winssl, --with-darwinssl and all --without-* options for
+ TLS libraries.
+
+ Closes #6897
+
+- tests/disable-scan.pl: also scan all m4 files
+
+ Fixes test 1165 when functions are moved from configure.ac to files in
+ m4/
+
+Jay Satiro (22 Apr 2021)
+- schannel: Disable auto credentials; add an option to enable it
+
+ - Disable auto credentials by default. This is a breaking change
+ for clients that are using it, wittingly or not.
+
+ - New libcurl ssl option value CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl
+ to automatically locate and use a client certificate for
+ authentication, when requested by the server.
+
+ - New curl tool options --ssl-auto-client-cert and
+ --proxy-ssl-auto-client-cert map to CURLSSLOPT_AUTO_CLIENT_CERT.
+
+ This option is only supported for Schannel (the native Windows SSL
+ library). Prior to this change Schannel would, with no notification to
+ the client, attempt to locate a client certificate and send it to the
+ server, when requested by the server. Since the server can request any
+ certificate that supports client authentication in the OS certificate
+ store it could be a privacy violation and unexpected.
+
+ Fixes https://github.com/curl/curl/issues/2262
+ Reported-by: Jeroen Ooms
+ Assisted-by: Wes Hinsley
+ Assisted-by: Rich FitzJohn
+
+ Ref: https://curl.se/mail/lib-2021-02/0066.html
+ Reported-by: Morten Minde Neergaard
+
+ Closes https://github.com/curl/curl/pull/6673
+
+Daniel Stenberg (22 Apr 2021)
+- [Michał Antoniak brought this change]
+
+ vtls: deduplicate some DISABLE_PROXY ifdefs
+
+ continue from #5735
+
+ - using SSL_HOST_NAME, SSL_HOST_DISPNAME, SSL_PINNED_PUB_KEY for other
+ tls backend
+
+ - create SSL_HOST_PORT
+
+ Closes #6660
+
+Jay Satiro (22 Apr 2021)
+- OS400: fix typo
+
+ CURLVERSION_HEIGHTH -> CURLVERSION_EIGHTH
+
+Daniel Stenberg (22 Apr 2021)
+- checksrc: complain on == NULL or != 0 checks in conditions
+
+ ... to make them all consistenly use if(!var) and if(var)
+
+ Also added a few missing warnings to the documentation.
+
+ Closes #6912
+
+- tidy-up: make conditional checks more consistent
+
+ ... remove '== NULL' and '!= 0'
+
+ Closes #6912
+
+- [Patrick Monnerat brought this change]
+
+ vauth: factor base64 conversions out of authentication procedures
+
+ Input challenges and returned messages are now in binary.
+ Conversions from/to base64 are performed by callers (currently curl_sasl.c
+ and http_ntlm.c).
+
+ Closes #6654
+
+- [Patrick Monnerat brought this change]
+
+ bufref: buffer reference support
+
+ A struct bufref holds a buffer pointer, a data size and a destructor.
+ When freed or its contents are changed, the previous buffer is implicitly
+ released by the associated destructor. The data size, although not used
+ internally, allows binary data support.
+
+ A unit test checks its handling methods: test 1661
+
+ Closes #6654
+
+- [Patrick Monnerat brought this change]
+
+ os400: additional support for options metadata
+
+ New functions curl_easy_option_by_name_ccsid() and
+ curl_easy_option_get_name_ccsid() allows accessing metadata in alternate
+ character encoding.
+
+ This commit also updates curl_version_info_ccsid() to handle info version 9
+ and adds recent definitions to the ILE/RPG include file.
+
+ Documentation updated accordingly.
+
+ Reviewed-by: Jon Rumsey
+ Closes #6574
+
+- [Patrick Monnerat brought this change]
+
+ test server: take care of siginterrupt() deprecation
+
+ Closes #6529
+
+Marc Hoersken (21 Apr 2021)
+- lib1564.c: enable last wakeup test part on Windows
+
+ Suggested-by: Gergely Nagy
+ Reviewed-by: Jay Satiro
+ Reviewed-by: Marcel Raad
+
+ Closes #6245
+
+- multi: fix slow write/upload performance on Windows
+
+ Reset FD_WRITE by sending zero bytes which is permissible
+ and will be treated by implementations as successful send.
+
+ Without this we won't be notified in case a socket is still
+ writable if we already received such a notification and did
+ not send any data afterwards on the socket. This would lead
+ to waiting forever on a writable socket being writable again.
+
+ Assisted-by: Tommy Odom
+ Reviewed-by: Jay Satiro
+ Reviewed-by: Marcel Raad
+ Tested-by: tmkk on github
+
+ Bug: #6146
+ Closes #6245
+
+- multi: reduce Win32 API calls to improve performance
+
+ 1. Consolidate pre-checks into a single Curl_poll call:
+
+ This is an attempt to restructure the code in Curl_multi_wait
+ in such a way that less syscalls are made by removing individual
+ calls to Curl_socket_check via SOCKET_READABLE/SOCKET_WRITABLE.
+
+ 2. Avoid resetting the WinSock event multiple times:
+
+ We finally call WSAResetEvent anyway, so specifying it as
+ an optional parameter to WSAEnumNetworkEvents is redundant.
+
+ 3. Wakeup directly in case no sockets are being monitoring:
+
+ Fix the WinSock based implementation to skip extra waiting by
+ not sleeping in case no sockets are to be waited on and just
+ the WinSock event is being monitored for wakeup functionality.
+
+ Assisted-by: Tommy Odom
+ Reviewed-by: Jay Satiro
+ Reviewed-by: Marcel Raad
+
+ Bug: #6146
+ Closes #6245
+
+- Revert "Revert 'multi: implement wait using winsock events'"
+
+ This reverts commit 2260e0ebe6d45529495231b3e37a0c58fb92a6a2,
+ also restoring previous follow up changes which were reverted.
+
+ Authored-by: rcombs on github
+ Authored-by: Marc Hörsken
+ Reviewed-by: Jay Satiro
+ Reviewed-by: Marcel Raad
+
+ Restores #5634
+ Reverts #6281
+ Part of #6245
+
+Daniel Stenberg (21 Apr 2021)
+- Revert "cmake: make libcurl library output name configurable"
+
+ This reverts commit 1cba36d2166c396f987eea587cf92671b27acb92.
+
+ CMake provides properties that can be set on a target to rename the
+ output artifact without changing the name of a target.
+
+ Ref: #6899
+
+- [Michael Kolechkin brought this change]
+
+ sectransp: allow cipher name to be specified
+
+ Add parser for CURLOPT_SSL_CIPHER_LIST option for Secure Transport (ST)
+ back-end. Similar to NSS and GSKit back-ends, new code parses string
+ value and configures ST library to use those ciphers for communication.
+ Create cipher spec data structure and initialize the array of specs with
+ cipher number, name, alias, and 'weak' flag.
+
+ Mark triple-DES ciphers as 'weak', and exclude them from the default
+ ciphers list.
+
+ Closes #6464
+
+- [Michael Kolechkin brought this change]
+
+ NSS: add ciphers to map
+
+ Add cipher names to the `cipherlist` map, based on the list of ciphers
+ implemented by the NSS in the source code file
+ https://github.com/nss-dev/nss/blob/master/lib/ssl/sslenum.c
+
+ Closes #6670
+
+- http2: remove DEBUG_HTTP2
+
+ Accidentally committed in 605e84235
+
+- [Ralph Langendam brought this change]
+
+ cmake: make libcurl library output name configurable
+
+ Closes #6899
+
+- sws: #ifdef S_IFSOCK use
+
+ SCO OpenServer 5.0.7 does not define S_IFSOCK.
+
+ Reported-by: Kevin R. Bulgrien
+ Bug: https://curl.se/mail/lib-2021-04/0074.html
+ Closes #6926
+
+- curl_setup: provide the shutdown flags wider
+
+ By using #ifdef on the symbol names to work on anything that don't
+ provide them. SCO OpenServer 5.0.7, sys/socket.h does not define either
+ SHUT_RDWR, SHUT_RD, and SHUT_WR.
+
+ Reported-by: Kevin R. Bulgrien
+ Bug: https://curl.se/mail/lib-2021-04/0073.html
+ Closes #6925
+
+- connect: use CURL_SA_FAMILY_T for portability
+
+ Reported-by: Kevin R. Bulgrien
+ Bug: https://curl.se/mail/lib-2021-04/0071.html
+
+ Closes #6918
+
+- urlapi: make sure no +/- signs are accepted in IPv4 numericals
+
+ Follow-up to 56a037cc0ad1b2. Extends test 1560 to verify.
+
+ Reported-by: Tuomas Siipola
+ Fixes #6916
+ Closes #6917
+
+- ConnectionExists: respect requests for h1 connections better
+
+ ... for situations when multiplexing isn't enabled on the h2 connection
+ and h1 is explicitly requested for the transfer.
+
+ Assisted-by: Gergely Nagy
+
+- multi: don't close connection HTTP_1_1_REQUIRED
+
+ The ConnectionExists() function will note that the new transfer wants
+ less then h2 and that it can't multiplex it and therefor opt to open a
+ new connection instead.
+
+- http2: move the stream error field to the per-transfer storage
+
+ Storing a stream error in the per-connection struct was an error that lead to
+ race conditions as subsequent stream handling could overwrite the error code
+ before it was used for the stream with the actual problem.
+
+ Closes #6910
+
+- http2: call the handle-closed function correctly on closed stream
+
+ This was this one condition where the stream could be closed due to an
+ error and the function would still wrongly just return 0 for it.
+
+ Reported-by: Gergely Nagy
+ Fixes #6862
+ Closes #6910
+
+- test1660: check the created HSTS file as text mode
+
+ Closes #6922
+
+- RELEASE-NOTES: synced
+
+- test 493: require https in curl to run
+
+ Closes #6927
+
+Jay Satiro (20 Apr 2021)
+- tool_operate: don't discard failed parallel transfer result
+
+ - Save a parallel transfer's result code only when it fails and the
+ transfer is not being retried.
+
+ Prior to this change the result code was always set which meant that a
+ failed result could be erroneously discarded if a different transfer
+ later had a successful result (CURLE_OK).
+
+ Before:
+
+ > curl --fail -Z https://httpbin.org/status/404 https://httpbin.org/delay/10
+ > echo %ERRORLEVEL%
+ 0
+
+ After:
+
+ > curl --fail -Z https://httpbin.org/status/404 https://httpbin.org/delay/10
+ > echo %ERRORLEVEL%
+ 22
+
+ Closes #xxxx
+
+- [Georeth Zhou brought this change]
+
+ openssl: fix build error with OpenSSL < 1.0.2
+
+ Closes https://github.com/curl/curl/pull/6920
+
+Viktor Szakats (19 Apr 2021)
+- README.md: delete Codacy UTM parameters & follow permanent redirect [ci skip]
+
+ UTM parameters leak referrer and various marketing/tracking information
+ even if these would normally be stripped by website or client policy.
+ This link also works fine without them. Also took the opportunity to
+ update the URL to the one pointed to by the previous one via permanent
+ redirect.
+
+ Reviewed-by: Daniel Stenberg
+ Closes #6919
+
+Daniel Stenberg (19 Apr 2021)
+- urlapi: "normalize" numerical IPv4 host names
+
+ When the host name in a URL is given as an IPv4 numerical address, the
+ address can be specified with dotted numericals in four different ways:
+ a32, a.b24, a.b.c16 or a.b.c.d and each part can be specified in
+ decimal, octal (0-prefixed) or hexadecimal (0x-prefixed).
+
+ Instead of passing on the name as-is and leaving the handling to the
+ underlying name functions, which made them not work with c-ares but work
+ with getaddrinfo, this change now makes the curl URL API itself detect
+ and "normalize" host names specified as IPv4 numericals.
+
+ The WHATWG URL Spec says this is an okay way to specify a host name in a
+ URL. RFC 3896 does not allow them, but curl didn't prevent them before
+ and it seems other RFC 3896-using tools have not either. Host names used
+ like this are widely supported by other tools as well due to the
+ handling being done by getaddrinfo and friends.
+
+ I decided to add the functionality into the URL API itself so that all
+ users of these functions get the benefits, when for example wanting to
+ compare two URLs. Also, it makes curl built to use c-ares now support
+ them as well and make curl builds more consistent.
+
+ The normalization makes HTTPS and virtual hosted HTTP work fine even
+ when curl gets the address specified using one of the "obscure" formats.
+
+ Test 1560 is extended to verify.
+
+ Fixes #6863
+ Closes #6871
+
+- libssh: fix "empty expression statement has no effect" warnings
+
+ ... by fixing macros to do-while constructs and moving out the calls to
+ "break" outside of the actual macro. It also fixes the problem where the
+ macro was used witin a loop and the break didn't do right.
+
+ Reported-by: Emil Engler
+ Fixes #6847
+ Closes #6909
+
+- hsts: enable by default
+
+ No longer considered experimental.
+
+ Closes #6700
+
+- vtls: refuse setting any SSL version
+
+ ... previously they were supported if a TLS library would (unexpectedly)
+ still support them, but from this change they will be refused already in
+ curl_easy_setopt(). SSLv2 and SSLv3 have been known to be insecure for
+ many years now.
+
+ Closes #6773
+
+- curl: ignore options asking for SSLv2 or SSLv3
+
+ Instead output a warning about it and continue with the defaults.
+
+ These SSL versions are typically not supported by the TLS libraries since a
+ long time back already since they are inherently insecure and broken. Asking
+ for them to be used will just cause an error to be returned slightly later.
+
+ In the unlikely event that a user's TLS library actually still supports these
+ protocol versions, this change might make the request a little less insecure.
+
+ Closes #6772
+
+- test972: verify the json output with jsonlint
+
+ Make sure one of the azure jobs has jsonlint installed so that the test
+ runs there.
+
+ Ref: #6905
+
+- [Jay Satiro brought this change]
+
+ tool_writeout: fix the HTTP_CODE json output
+
+ Update test 970 accordingly.
+
+ Reported-by: Michal Rus
+ Fixes #6905
+ Closes #6906
+
+- openldap: protect SSL-specific code with proper #ifdef
+
+ Closes #6901
+
+- libssh2: fix Value stored to 'sshp' is never read
+
+ Pointed out by scan-build
+
+ Closes #6900
+
+- [Victor Vieux brought this change]
+
+ tool_getparam: replace (in-place) '%20' by '+' according to RFC1866
+
+ Signed-off-by: Victor Vieux <victorvieux@gmail.com>
+
+ Closes #6895
+
+- configure: provide --with-openssl, deprecate --with-ssl
+
+ Makes the option more explicit.
+
+ Closes #6887
+
+- RELEASE-NOTES: synced
+
+ and bumped curlver to 7.77.0
+
+- [Javier Blazquez brought this change]
+
+ rustls: only return CURLE_AGAIN when TLS session is fully drained
+
+ The code in cr_recv was returning prematurely as soon as the socket
+ reported no more data to read. However, this could be leaving some
+ unread plaintext data in the rustls session from a previous call,
+ causing causing the transfer to hang if the socket never receives
+ further data.
+
+ We need to ensure that the session is fully drained of plaintext data
+ before returning CURLE_AGAIN to the caller.
+
+ Reviewed-by: Jacob Hoffman-Andrews
+ Closes #6894
+
+- cookie: CURLOPT_COOKIEFILE set to NULL switches off cookies
+
+ Add test 676 to verify that setting CURLOPT_COOKIEFILE to NULL again clears
+ the cookiejar from memory.
+
+ Reported-by: Stefan Karpinski
+ Fixes #6889
+ Closes #6891
+
Version 7.76.1 (14 Apr 2021)
Daniel Stenberg (14 Apr 2021)
@@ -6136,1543 +7828,3 @@ Daniel Stenberg (16 Sep 2020)
- dynbuf: make sure Curl_dyn_tail() zero terminates
Closes #5959
-
-- tests: add test1912 to the dist
-
- Follow-up to 70984ce1be4cab6c
-
-- docs/LICENSE-MIXING: remove
-
- This document is not maintained and I feel that it doesn't provide much
- value to users anymore (if it ever did).
-
- Closes #5955
-
-- [Laramie Leavitt brought this change]
-
- http: consolidate nghttp2_session_mem_recv() call paths
-
- Previously there were several locations that called
- nghttp2_session_mem_recv and handled responses slightly differently.
- Those have been converted to call the existing
- h2_process_pending_input() function.
-
- Moved the end-of-session check to h2_process_pending_input() since the
- only place the end-of-session state can change is after nghttp2
- processes additional input frames.
-
- This will likely fix the fuzzing error. While I don't have a root cause
- the out-of-bounds read seems like a use after free, so moving the
- nghttp2_session_check_request_allowed() call to a location with a
- guaranteed nghttp2 session seems reasonable.
-
- Also updated a few nghttp2 callsites to include error messages and added
- a few additional error checks.
-
- Closes #5648
-
-- HISTORY: mention alt-svc added in 2019
-
- ... and make 1996 the first year subtitle
-
-- base64: also build for pop3 and imap
-
- Follow-up to the fix in 20417a13fb8f83
-
- Reported-by: Michael Olbrich
- Fixes #5937
- Closes #5948
-
-- base64: enable in build with SMTP
-
- The oauth2 support is used with SMTP and it uses base64 functions.
-
- Reported-by: Michael Olbrich
- Fixes #5937
- Closes #5938
-
-- curl_mime_headers.3: fix the example's use of curl_slist_append
-
- Reported-by: sofaboss on github
- Fixes #5942
- Closes #5943
-
-- lib583: fix enum mixup
-
- grrr the previous follow-up to 17fcdf6a31 was wrong
-
-- libtest: fix build errors
-
- Follow-up from 17fcdf6a310d4c8076
-
-- lib: fix -Wassign-enum warnings
-
- configure --enable-debug now enables -Wassign-enum with clang,
- identifying several enum "abuses" also fixed.
-
- Reported-by: Gisle Vanem
- Bug: https://github.com/curl/curl/commit/879007f8118771f4896334731aaca5850a154675#commitcomment-42087553
-
- Closes #5929
-
-- RELEASE-NOTES: synced
-
-- [Diven Qi brought this change]
-
- url: use blank credentials when using proxy w/o username and password
-
- Fixes proxy regression brought in commit ad829b21ae (7.71.0)
-
- Fixed #5911
- Closes #5914
-
-- travis: add a build using libressl (from git master)
-
- The v3.2.1 tag (latest release atm) results in a broken build.
-
- Closes #5932
-
-- configure: let --enable-debug set -Wenum-conversion with gcc >= 10
-
- Unfortunately, this option is not detecting the same issues as clang's
- -Wassign-enum flag, but should still be useful to detect future
- mistakes.
-
- Closes #5930
-
-- openssl: consider ALERT_CERTIFICATE_EXPIRED a failed verification
-
- If the error reason from the lib is
- SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED, libcurl will return
- CURLE_PEER_FAILED_VERIFICATION and not CURLE_SSL_CONNECT_ERROR.
-
- This unifies the libcurl return code and makes libressl run test 313
- (CRL testing) fine.
-
- Closes #5934
-
-- FAQ: refreshed some very old language
-
-- cmake: make HTTP_ONLY also disable MQTT
-
- ... and alphasort the order of disabling protocols to make it easier to
- browse.
-
- Closes #5931
-
-- libtest: remove lib1541 leftovers
-
- Caused automake errors.
-
- Follow-up to 8ca54a03ea08a
-
-- tests/libtests: remove test 1900 and 2033
-
- We already remove the test files, now remove the libtest codes as well.
-
- Follow-up to e50a877df74
-
-Marc Hoersken (7 Sep 2020)
-- CI/azure: add test number to title for display in analytics
-
- To ease identification of tests the test number is added to
- the test case title in order to have it on the Azure DevOps
- Analytics pages and reports which currently do not show it.
-
- Bump test case revision to make Azure DevOps update titles.
-
- Closes #5927
-
-Daniel Stenberg (6 Sep 2020)
-- altsvc: clone setting in curl_easy_duphandle
-
- The cache content is not duplicated, like other caches, but the setting
- and specified file name are.
-
- Test 1908 is extended to verify this somewhat. Since the duplicated
- handle gets the same file name, the test unfortunately overwrites the
- same file twice (with different contents) which makes it hard to check
- automatically.
-
- Closes #5923
-
-- test1541: remove since it is a known bug
-
- A shared connection cache is not thread-safe is a known issue. Stop
- testing this until we believe this issue is addressed. Reduces
- occasional test failures we don't care about.
-
- The test code in lib1541.c is left in git to allow us to restore it when
- we get to fix this.
-
- Closes #5922
-
-- tests: remove pipelining tests
-
- Remove the tests 530, 584, 1900, 1901, 1902, 1903 and 2033. They were
- previously disabled.
-
- The Pipelining code was removed from curl in commit 2f44e94efb3df8e,
- April 2019.
-
- Closes #5921
-
-- curl: retry delays in parallel mode no longer sleeps blocking
-
- The previous sleep for retries would block all other concurrent
- transfers. Starting now, the retry will instead be properly marked to
- not get restarted until after the delay time but other transfers can
- still continue in the mean time.
-
- Closes #5917
-
-- curl:parallel_transfers: make sure retry readds the transfer
-
- Reported-by: htasta on github
- Fixes #5905
- Closes #5917
-
-- build: drop support for building with Watcom
-
- These files are not maintained, they seem to have no users, Watcom
- compilers look like not having users nor releases anymore.
-
- Closes #5918
-
-- winbuild/rundebug.cmd: remove
-
- Seems to have been added by mistake? Not included in dists.
-
- Closes #5919
-
-- curl: in retry output don't call all problems "transient"
-
- ... because when --retry-all-errors is used, the error isn't necessarily
- transient at all.
-
- Closes #5916
-
-- easygetopt: pass a valid enum to avoid compiler warning
-
- "integer constant not in range of enumerated type 'CURLoption'"
-
- Reported-by: Gisle Vanem
- Bug: https://github.com/curl/curl/commit/6ebe63fac23f38df911edc348e8ccc72280f9434#commitcomment-42042843
-
- Closes #5915
-
-- [Emil Engler brought this change]
-
- tests: Add tests for new --help
-
- This commit is a part of "--help me if you can"
-
- Closes #5680
-
-- [Emil Engler brought this change]
-
- tool: update --help with categories
-
- This commit is a part of "--help me if you can"
-
- Closes #5680
-
-- [Emil Engler brought this change]
-
- docs: add categories to all cmdline opts
-
- Adapted gen.pl with 'listcats'
-
- This commit is a part of "--help me if you can"
-
- Closes #5680
-
-- RELEASE-NOTES: synced
-
-- [ihsinme brought this change]
-
- connect.c: remove superfluous 'else' in Curl_getconnectinfo
-
- Closes #5912
-
-- [Samuel Marks brought this change]
-
- CMake: remove explicit `CMAKE_ANSI_CFLAGS`
-
- This variable was removed from cmake in commit
- https://gitlab.kitware.com/cmake/cmake/commit/5a834b0bb0bc288. A later
- CMake commit removes the variable from the tests, claiming that it was
- removed in CMake 2.6
-
- Reviewed-By: Peter Wu
- Closes #5439
-
-- [cbe brought this change]
-
- libssh2: pass on the error from ssh_force_knownhost_key_type
-
- Closes #5909
-
-- scripts/delta: add diffstat summary
-
- ... and make output more table-like
-
-- [Martin Bašti brought this change]
-
- http_proxy: do not crash with HTTPS_PROXY and NO_PROXY set
-
- ... in case NO_PROXY takes an effect
-
- Without this patch, the following command crashes:
-
- $ GIT_CURL_VERBOSE=1 NO_PROXY=github.com HTTPS_PROXY=https://example.com \
- git clone https://github.com/curl/curl.git
-
- Minimal libcurl-based reproducer:
-
- #include <curl/curl.h>
-
- int main() {
- CURL *curl = curl_easy_init();
- if(curl) {
- CURLcode ret;
- curl_easy_setopt(curl, CURLOPT_URL, "https://github.com/");
- curl_easy_setopt(curl, CURLOPT_PROXY, "example.com");
- /* set the proxy type */
- curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS);
- curl_easy_setopt(curl, CURLOPT_NOPROXY, "github.com");
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
- ret = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
- return ret;
- }
- return -1;
- }
-
- Assisted-by: Kamil Dudka
- Bug: https://bugzilla.redhat.com/1873327
- Closes #5902
-
-- travis: add a CI job with openssl3 (from git master)
-
- Closes #5908
-
-- openssl: avoid error conditions when importing native CA
-
- The code section that is OpenSSL 3+ specific now uses the same logic as
- is used in the version < 3 section. It caused a compiler error without
- it.
-
- Closes #5907
-
-- setopt: avoid curl_ on local variable
-
- Closes #5906
-
-- mqtt.c: avoid curl_ prefix on local variable
-
- Closes #5906
-
-- wildcard: strip "curl_" prefix from private symbols
-
- Closes #5906
-
-- vtls: make it 'struct Curl_ssl_session'
-
- Use uppercase C for internal symbols.
-
- Closes #5906
-
-- curl_threads: make it 'struct Curl_actual_call'
-
- Internal names should not be prefixed "curl_"
-
- Closes #5906
-
-- schannel: make it 'struct Curl_schannel*'
-
- As internal global names should use captical C.
-
- Closes #5906
-
-- hash: make it 'struct Curl_hash'
-
- As internal global names should use captical C.
-
- Closes #5906
-
-- llist: make it "struct Curl_llist"
-
- As internal global names should use captical C.
-
- Closes #5906
-
-Marc Hoersken (2 Sep 2020)
-- telnet.c: depend on static requirement of WinSock version 2
-
- Drop dynamic loading of ws2_32.dll and instead rely on the
- imported version which is now required to be at least 2.2.
-
- Reviewed-by: Marcel Raad
- Reviewed-by: Jay Satiro
- Reviewed-by: Daniel Stenberg
- Reviewed-by: Viktor Szakats
-
- Closes #5854
-
-- win32: drop support for WinSock version 1, require version 2
-
- IPv6, telnet and now also the multi API require WinSock
- version 2 which is available starting with Windows 95.
-
- Therefore we think it is time to drop support for version 1.
-
- Reviewed-by: Marcel Raad
- Reviewed-by: Jay Satiro
- Reviewed-by: Daniel Stenberg
- Reviewed-by: Viktor Szakats
-
- Follow up to #5634
- Closes #5854
-
-- select: align poll emulation to return all relevant events
-
- The poll emulation via select already consumes POLLRDNORM,
- POLLWRNORM and POLLRDBAND as input events. Therefore it
- should also return them as output events if signaled.
-
- Also fix indentation in input event handling block.
-
- Assisted-by: Jay Satiro
- Reviewed-by: Daniel Stenberg
-
- Replaces #5852
- Closes #5883
-
-- CI/azure: MQTT is now enabled by default
-
- Reviewed-by: Daniel Stenberg
-
- Follow up to #5858
- Closes #5903
-
-Daniel Stenberg (2 Sep 2020)
-- copyright.pl: ignore buildconf
-
-- test971: show test mismatches "inline"
-
-- lib/Makefile.am: bump VERSIONINFO due to new functions
-
- ... we're generally bad at this, but we are adding new functions for
- this release.
-
- Closes #5899
-
-- optiontable: use DEBUGBUILD
-
- Follow-up to commit 6e18568ba38 (#5877)
-
-- cmdline-opts/gen.pl: generate nicer "See Also" in curl.1
-
- If there are more than two items in the list, use commas for all but the
- last separator which is set to 'and'. Reads better.
-
- Closes #5898
-
-- curl.1: add see also no-progress-meter on two spots
-
- Ref: #5894
-
- Closes #5897
-
-- RELEASE-NOTES: synced
-
-- mqtt: enable by default
-
- No longer considered experimental.
-
- Closes #5858
-
-- [Michael Baentsch brought this change]
-
- tls: add CURLOPT_SSL_EC_CURVES and --curves
-
- Closes #5892
-
-- url: remove funny embedded comments in Curl_disonnect calls
-
-- [Chris Paulson-Ellis brought this change]
-
- conn: check for connection being dead before reuse
-
- Prevents incorrect reuse of an HTTP connection that has been prematurely
- shutdown() by the server.
-
- Partial revert of 755083d00deb16
-
- Fixes #5884
- Closes #5893
-
-Marc Hoersken (29 Aug 2020)
-- buildconf: exec autoreconf to avoid additional process
-
- Also make buildconf exit with the return code of autoreconf.
-
- Reviewed-by: Daniel Stenberg
-
- Follow up to #5853
- Closes #5890
-
-- CI/azure: no longer ignore results of test 1013
-
- Follow up to #5771
- Closes #5889
-
-- docs: add description about CI platforms to CONTRIBUTE.md
-
- Reviewed-by: Daniel Stenberg
- Reviewed-by: Marcel Raad
- Reviewed-by: Jay Satiro
-
- Closes #5882
-
-Daniel Stenberg (29 Aug 2020)
-- tests/getpart: use MIME::Base64 instead of home-cooked
-
- Since we already use the base64 package since a while back, we can just
- as well switch to that here too.
-
- It also happens to use the exact same function name, which otherwise
- causes a run-time warning.
-
- Reported-by: Marc Hörsken
- Fixes #5885
- Closes #5887
-
-Marcel Raad (29 Aug 2020)
-- ntlm: fix condition for curl_ntlm_core usage
-
- `USE_WINDOWS_SSPI` without `USE_WIN32_CRYPTO` but with any other DES
- backend is fine, but was excluded before.
-
- This also fixes test 1013 as the condition for SMB support in
- configure.ac didn't match the condition in the source code. Now it
- does.
-
- Fixes https://github.com/curl/curl/issues/1262
- Closes https://github.com/curl/curl/pull/5771
-
-- AppVeyor: switch 64-bit Schannel Debug CMake builds to Unicode
-
- The Schannel builds are the most useful to verify as they make the most
- use of the Windows API. Classic MinGW doesn't support Unicode at all,
- only MinGW-w64 and MSVC do.
-
- Closes https://github.com/curl/curl/pull/5843
-
-- CMake: add option to enable Unicode on Windows
-
- As already existing for winbuild.
-
- Closes https://github.com/curl/curl/pull/5843
-
-Marc Hoersken (29 Aug 2020)
-- select: simplify return code handling for poll and select
-
- poll and select already return -1 on error according to POSIX,
- so there is no need to perform a <0 to -1 conversion in code.
-
- Also we can just use one check with <= 0 on the return code.
-
- Assisted-by: Daniel Stenberg
- Reviewed-by: Jay Satiro
-
- Replaces #5852
- Closes #5880
-
-Daniel Stenberg (28 Aug 2020)
-- RELEASE-NOTES: synced
-
-- [Jeroen Ooms brought this change]
-
- tests: add test1912 with typechecks
-
- Validates that gcc-typecheck macros match the new option type API.
-
- Closes #5873
-
-- easyoptions: provide debug function when DEBUGBUILD
-
- ... not CURLDEBUG as they're not always set in conjunction.
-
- Follow-up to 6ebe63fac23f38df
-
- Fixes #5877
- Closes #5878
-
-Marc Hoersken (28 Aug 2020)
-- sockfilt: handle FD_CLOSE winsock event on write socket
-
- Learn from the way Cygwin handles and maps the WinSock events
- to simulate correct and complete poll and select behaviour
- according to Richard W. Stevens Network Programming book.
-
- Follow up to #5867
- Closes #5879
-
-- multi: handle connection state winsock events
-
- Learn from the way Cygwin handles and maps the WinSock events
- to simulate correct and complete poll and select behaviour
- according to Richard W. Stevens Network Programming book.
-
- Reviewed-by: Jay Satiro
- Reviewed-by: Marcel Raad
-
- Follow up to #5634
- Closes #5867
-
-Daniel Stenberg (28 Aug 2020)
-- Curl_pgrsTime - return new time to avoid timeout integer overflow
-
- Setting a timeout to INT_MAX could cause an immediate error to get
- returned as timeout because of an overflow when different values of
- 'now' were used.
-
- This is primarily fixed by having Curl_pgrsTime() return the "now" when
- TIMER_STARTSINGLE is set so that the parent function will continue using
- that time.
-
- Reported-by: IonuÈ›-Francisc Oancea
- Fixes #5583
- Closes #5847
-
-- TLS: fix SRP detection by using the proper #ifdefs
-
- USE_TLS_SRP will be true if *any* selected TLS backend can use SRP
-
- HAVE_OPENSSL_SRP is defined when OpenSSL can use it
-
- HAVE_GNUTLS_SRP is defined when GnuTLS can use it
-
- Clarify in the curl_verison_info docs that CURL_VERSION_TLSAUTH_SRP is
- set if at least one of the supported backends offers SRP.
-
- Reported-by: Stefan Strogin
- Fixes #5865
- Closes #5870
-
-- [Dan Kenigsberg brought this change]
-
- docs: SSLCERTS: fix English syntax
-
- Signed-off-by: Dan Kenigsberg <danken@redhat.com>
-
- Closes #5876
-
-- [Alessandro Ghedini brought this change]
-
- docs: non-existing macros in man pages
-
- As reported by man(1) when invoked as:
-
- man --warnings -E UTF-8 -l -Tutf8 -Z <file> >/dev/null
-
- Closes #5846
-
-- [Alessandro Ghedini brought this change]
-
- curl.1: fix typo invokved -> invoked
-
- Closes #5846
-
-- buildconf: invoke 'autoreconf -fi' instead
-
- The custom script isn't necessary anymore - but remains for simplicity
- and just invokes autoreconf.
-
- Closes #5853
-
-- [Emil Engler brought this change]
-
- lib: make Curl_gethostname accept a const pointer
-
- The address of that variable never gets changed, only the data in it so
- why not make it a "char * const"?
-
- Closes #5866
-
-- docs/libcurl: update "Added in" version for curl_easy_option*
-
- Follow-up to 6ebe63fac23f38
-
-- scripts: improve the "get latest curl release tag" logic
-
- ... by insiting on it matching "^curl-".
-
-- configure: added --disable-get-easy-options
-
- To allow disabling of the curl_easy_option APIs in a build.
-
- Closes #5365
-
-- options: API for meta-data about easy options
-
- const struct curl_easyoption *curl_easy_option_by_name(const char *name);
-
- const struct curl_easyoption *curl_easy_option_by_id (CURLoption id);
-
- const struct curl_easyoption *
- curl_easy_option_next(const struct curl_easyoption *prev);
-
- The purpose is to provide detailed enough information to allow for
- example libcurl bindings to get option information at run-time about
- what easy options that exist and what arguments they expect.
-
- Assisted-by: Jeroen Ooms
- Closes #5365
-
-- [Eric Curtin brought this change]
-
- HTTP/3: update to OpenSSL_1_1_1g-quic-draft-29
-
- Closes #5871
-
-- RELEASE-NOTES: synced
-
-Jay Satiro (26 Aug 2020)
-- openssl: Fix wincrypt symbols conflict with BoringSSL
-
- OpenSSL undefines the conflicting symbols but BoringSSL does not so we
- must do it ourselves.
-
- Reported-by: Samuel Tranchet
- Assisted-by: Javier Blazquez
-
- Ref: https://bugs.chromium.org/p/boringssl/issues/detail?id=371
- Ref: https://github.com/openssl/openssl/blob/OpenSSL_1_1_1g/include/openssl/ossl_typ.h#L66-L73
-
- Fixes https://github.com/curl/curl/issues/5669
- Closes https://github.com/curl/curl/pull/5857
-
-Daniel Stenberg (26 Aug 2020)
-- socketpair: allow CURL_DISABLE_SOCKETPAIR
-
- ... to completely disable the use of socketpair
-
- Closes #5850
-
-- curl_get_line: build only if cookies or alt-svc are enabled
-
- Closes #5851
-
-- [fullincome brought this change]
-
- schannel: fix memory leak when using get_cert_location
-
- The get_cert_location function allocates memory only on success.
- Previously get_cert_location was able to allocate memory and return
- error. It wasn't obvious and in this case the memory wasn't
- released.
-
- Fixes #5855
- Closes #5860
-
-- [Emil Engler brought this change]
-
- git: ignore libtests in 3XXX area
-
- Currently the file tests/libtest/lib3010 is not getting
- ignored by git. This fixes it by adding the 3XXX area to
- the according .gitignore file.
-
- Closes #5859
-
-- [Emil Engler brought this change]
-
- doh: add error message for DOH_DNS_NAME_TOO_LONG
-
- When this error code was introduced in b6a53fff6c1d07e8a9, it was
- forgotten to be added in the errors array and doh_strerror function.
-
- Closes #5863
-
-- ngtcp2: adapt to the new pkt_info arguments
-
- Guidance-by: Tatsuhiro Tsujikawa
-
- Closes #5864
-
-- winbuild/README.md: make <options> visible
-
- Follow-up to be753add31c2d8c
-
-- winbuild: convert the instruction text to README.md
-
- Closes #5861
-
-- lib1560: verify "redirect" to double-slash leading URL
-
- Closes #5849
-
-Marc Hoersken (25 Aug 2020)
-- multi: expand pre-check for socket readiness
-
- Check readiness of all sockets before waiting on them
- to avoid locking in case the one-time event FD_WRITE
- was already consumed by a previous wait operation.
-
- More information about WinSock network events:
- https://docs.microsoft.com/en-us/windows/win32/api/
- winsock2/nf-winsock2-wsaeventselect#return-value
-
- Closes #5634
-
-- [rcombs brought this change]
-
- multi: implement wait using winsock events
-
- This avoids using a pair of TCP ports to provide wakeup functionality
- for every multi instance on Windows, where socketpair() is emulated
- using a TCP socket on loopback which could in turn lead to socket
- resource exhaustion.
-
- A previous version of this patch failed to account for how in WinSock,
- FD_WRITE is set only once when writing becomes possible and not again
- until after a send has failed due to the buffer filling. This contrasts
- to how FD_READ and FD_OOB continue to be set until the conditions they
- refer to no longer apply. This meant that if a user wrote some data to
- a socket, but not enough data to completely fill its send buffer, then
- waited on that socket to become writable, we'd erroneously stall until
- their configured timeout rather than returning immediately.
-
- This version of the patch addresses that issue by checking each socket
- we're waiting on to become writable with select() before the wait, and
- zeroing the timeout if it's already writable.
-
- Assisted-by: Marc Hörsken
- Reviewed-by: Marcel Raad
- Reviewed-by: Daniel Stenberg
- Tested-by: Gergely Nagy
- Tested-by: Rasmus Melchior Jacobsen
- Tested-by: Tomas Berger
-
- Replaces #5397
- Reverts #5632
- Closes #5634
-
-- select: reduce duplication of Curl_poll in Curl_socket_check
-
- Change Curl_socket_check to use select-fallback in Curl_poll
- instead of implementing it in Curl_socket_check and Curl_poll.
-
- Reviewed-by: Daniel Stenberg
- Reviewed-by: Jay Satiro
-
- Replaces #5262 and #5492
- Closes #5707
-
-- select: fix poll-based check not detecting connect failure
-
- This commit changes Curl_socket_check to use POLLPRI to
- check for connect failure on the write socket, because
- POLLPRI maps to fds_err. This is in line with select(2).
-
- The select-based socket check correctly checks for connect
- failures by adding the write socket also to fds_err.
-
- The poll-based implementation (which internally can itself
- fallback to select again) did not previously check for
- connect failure by using POLLPRI with the write socket.
-
- See the follow up commit to this for more information.
-
- This commit makes sure connect failures can be detected
- and handled if HAVE_POLL_FINE is defined, eg. on msys2-devel.
-
- Reviewed-by: Daniel Stenberg
- Reviewed-by: Jay Satiro
-
- Replaces #5509
- Prepares #5707
-
-- select.h: make socket validation macros test for INVALID_SOCKET
-
- With Winsock the valid range is [0..INVALID_SOCKET-1] according to
- https://docs.microsoft.com/en-us/windows/win32/winsock/socket-data-type-2
-
- Reviewed-by: Jay Satiro
- Reviewed-by: Marcel Raad
- Reviewed-by: Daniel Stenberg
-
- Closes #5760
-
-Daniel Stenberg (24 Aug 2020)
-- docs: --output-dir is added in 7.73.0, nothing else
-
- Follow-up to 5620d2cc78c0
-
-- curl: add --output-dir
-
- Works with --create-dirs and with -J
-
- Add test 3008, 3009, 3011, 3012 and 3013 to verify.
-
- Closes #5637
-
-- configure: fix pkg-config detecting wolfssl
-
- When amending the include path with "/wolfssl", this now properly strips
- off all whitespace from the path variable! Previously this would lead to
- pkg-config builds creating bad command lines.
-
- Closes #5848
-
-- [Michael Musset brought this change]
-
- sftp: add the option CURLKHSTAT_FINE_REPLACE
-
- Replace the old fingerprint of the host with a new.
-
- Closes #5685
-
-- RELEASE-NOTES: synced
-
- The next release is now to become 7.73.0
-
-- checksrc: verify do-while and spaces between the braces
-
- Updated mprintf.c to comply
-
- Closes #5845
-
-- curl: support XDG_CONFIG_HOME to find .curlrc
-
- Added test433 to verify. Updated documentation.
-
- Reviewed-by: Jay Satiro
- Suggested-by: Eli Schwartz
- Fixes #5829
- Closes #5837
-
-- etag: save and use the full received contents
-
- ... which makes it support weak tags and non-standard etags too!
-
- Added test case 347 to verify blank incoming ETag:
-
- Fixes #5610
- Closes #5833
-
-- setopt: if the buffer exists, refuse the new BUFFERSIZE
-
- The buffer only exists during transfer and then we shouldn't change the
- size (the setopt is not documented to work then).
-
- Reported-by: Harry Sintonen
- Closes #5842
-
-- [COFFEETALES brought this change]
-
- sftp: add new quote commands 'atime' and 'mtime'
-
- Closes #5810
-
-- CURLE_PROXY: new error code
-
- Failures clearly returned from a (SOCKS) proxy now causes this return
- code. Previously the situation was not very clear as what would be
- returned and when.
-
- In addition: when this error code is returned, an application can use
- CURLINFO_PROXY_ERROR to query libcurl for the detailed error, which then
- returns a value from the new 'CURLproxycode' enum.
-
- Closes #5770
-
-- runtests: make cleardir() erase dot files too
-
- Because test cases might use dot files.
-
- Closes #5838
-
-- KNOWN_BUGS: 'no_proxy' string-matches IPv6 numerical addreses
-
- Also: the current behavior is now documented in the curl.1 and
- CURLOPT_NOPROXY.3 man pages.
-
- Reported-by: Andrew Barnes
- Closes #5745
- Closes #5841
-
-Viktor Szakats (22 Aug 2020)
-- Makefile.m32: add ability to override zstd libs [ci skip]
-
- Similarly to brotli, where this was already possible.
- E.g. it allows to link zstd statically to libcurl.dll.
-
- Ref: https://github.com/curl/curl-for-win/issues/12
- Ref: https://github.com/curl/curl-for-win/commit/d9b266afd2e5d3f5604483010ef62340b5918c89
-
- Closes https://github.com/curl/curl/pull/5840
-
-Daniel Stenberg (21 Aug 2020)
-- runtests: avoid 'fail to start' repeated messages in attempt loops
-
- Closes #5834
-
-- runtests: clear pid variables when failing to start a server
-
- ... as otherwise the parent doesn't detect the failure and believe it
- actually worked to start.
-
- Reported-by: Christian Weisgerber
- Bug: https://curl.haxx.se/mail/lib-2020-08/0018.html
- Closes #5834
-
-- TODO: Virtual external sockets
-
- Closes #5835
-
-- [Don J Olmstead brought this change]
-
- dist: add missing CMake Find modules to the distribution
-
- Closes #5836
-
-- RELEASE-NOTES: synced
-
- ... and version bumped to 7.72.1
-
-- tls: provide the CApath verbose log on its own line
-
- ... not newline separated from the previous line. This makes it output
- asterisk prefixed properly like other verbose putput!
-
- Reported-by: jmdavitt on github
- Fixes #5826
- Closes #5827
-
-Version 7.72.0 (19 Aug 2020)
-
-Daniel Stenberg (19 Aug 2020)
-- RELEASE-NOTES: synced
-
- The curl 7.72.0 release
-
-- THANKS: add names from curl 7.72.0 release
-
-Jay Satiro (18 Aug 2020)
-- KNOWN_BUGS: Schannel TLS 1.2 handshake bug in old Windows versions
-
- Reported-by: plujon@users.noreply.github.com
-
- Closes https://github.com/curl/curl/issues/5488
-
-Daniel Stenberg (17 Aug 2020)
-- Curl_easy: remember last connection by id, not by pointer
-
- CVE-2020-8231
-
- Bug: https://curl.haxx.se/docs/CVE-2020-8231.html
-
- Reported-by: Marc Aldorasi
- Closes #5824
-
-- examples/rtsp.c: correct the copyright year
-
-- RELEASE-PROCEDURE.md: add more future release dates
-
-- [H3RSKO brought this change]
-
- docs: change "web site" to "website"
-
- According to wikipedia:
-
- While "web site" was the original spelling, this variant has become
- rarely used, and "website" has become the standard spelling
-
- Closes #5822
-
-- [Bevan Weiss brought this change]
-
- CMake: don't complain about missing nroff
-
- The curl_nroff_check() was always being called, and complaining if
- *NROFF wasn't found, even when not making the manual.
-
- Only check for nroff (and complain) if actually making the manual
-
- Closes #5817
-
-- [Brian Inglis brought this change]
-
- libtest/Makefile.am: add -no-undefined for libstubgss for Cygwin
-
- copy the LDFLAGS approach for adding same option with `libhostname` in
- `libtest/Makefile.am`:
-
- - init `libstubgss_la_LDFLAGS_EXTRA` variable,
- - add option to variable inside conditional,
- - use variable in `libstubgss_la_LDFLAGS`
-
- Fixes #5819
- Closes #5820
-
-- docs: clarify MAX_SEND/RECV_SPEED functionality
-
- ... in particular what happens if the maximum speed limit is set to a
- value that's smaller than the transfer buffer size in use.
-
- Reported-by: Tomas Berger
- Fixes #5788
- Closes #5813
-
-- test1140: compare stdout
-
- To make problems more immediately obvious when tests fail.
-
- Closes #5814
-
-- asyn-ares: correct some bad comments
-
- Closes #5812
-
-- [Emil Engler brought this change]
-
- docs: Add video link to docs/CONTRIBUTE.md
-
- Closes #5811
-
-- curl-config: ignore REQUIRE_LIB_DEPS in --libs output
-
- Fixes a curl-config issue on cygwin by making sure REQUIRE_LIB_DEPS is
- not considered for the --libs output.
-
- Reported-by: ramsay-jones on github
- Assisted-by: Brian Inglis and Ken Brown
- Fixes #5793
- Closes #5808
-
-- copyright: update/correct the year range on a few files
-
-- scripts/copyright.pl: ignore .muse files
-
-- [Emil Engler brought this change]
-
- multi: Remove 10-year old out-commented code
-
- The code hasn't been touched since 2010-08-18
-
- Closes #5805
-
-- KNOWN_BUGS: A shared connection cache is not thread-safe
-
- Closes #4915
- Closes #5802
-
-- CONTRIBUTE: extend git commit message description
-
- In particular how the first line works.
-
- Closes #5803
-
-- RELEASE-NOTES: synced
-
-- [Stefan Yohansson brought this change]
-
- transfer: move retrycount from connect struct to easy handle
-
- This flag was applied to the connection struct that is released on
- retry. These changes move the retry counter into Curl_easy struct that
- lives across retries and retains the new connection.
-
- Reported-by: Cherish98 on github
- Fixes #5794
- Closes #5800
-
-- libssh2: s/ssherr/sftperr/
-
- The debug output used ssherr instead of sftperr which not only outputs
- the wrong error code but also casues a warning on Windows.
-
- Follow-up to 7370b4e39f1
-
- Reported-by: Gisle Vanem
- Bug: https://github.com/curl/curl/commit/7370b4e39f1390e701f5b68d910c619151daf72b#r41334700
- Closes #5799
-
-- ftp: don't do ssl_shutdown instead of ssl_close
-
- The shutdown function is for downgrading a connection from TLS to plain,
- and this is not requested here.
-
- Have ssl_close reset the TLS connection state.
-
- This partially reverts commit f002c850d98d
-
- Reported-by: Rasmus Melchior Jacobsen
- Reported-by: Denis Goleshchikhin
- Fixes #5797
-
-Marc Hoersken (9 Aug 2020)
-- CI/azure: fix test outcome values and use latest API version
-
- This makes sure that tests ignored or skipped are not shown
- just in the category "Other", but with their correct state.
-
- Closes #5796
-
-- CI/azure: show runtime stats to investigate slowness
-
- Also avoid naming conflict of TFLAGS env and tflags variables.
-
- Closes #5776
-
-Daniel Stenberg (8 Aug 2020)
-- TLS naming: fix more Winssl and Darwinssl leftovers
-
- The CMake option is now called CMAKE_USE_SCHANNEL
-
- The winbuild flag is USE_SCHANNEL
-
- The CI jobs and build scripts only use the new names and the new name
- options
-
- Tests now require 'Schannel' (when necessary)
-
- Closes #5795
-
-- smtp_parse_address: handle blank input string properly
-
- Closes #5792
-
-- runtests: run the DICT server on a random port number
-
- Removed support for -b (base port number)
-
- Closes #5783
-
-- RELEASE-NOTES: synced
-
-- runtests: move the TELNET server to a dynamic port
-
- Rename the port variable to TELNETPORT to better match the existing
- pattern.
-
- Closes #5785
-
-- ngtcp2: adapt to error code rename
-
- Closes #5786
-
-- runtests: move the smbserver to use a dynamic port number
-
- Closes #5782
-
-- runtests: run the http2 tests on a random port number
-
- Closes #5779
-
-- gtls: survive not being able to get name/issuer
-
- Closes #5778
-
-- runtests: move the gnutls-serv tests to a dynamic port
-
- Affects test 320, 321, 322 and 324.
-
- Closes #5778
-
-- runtests: support dynamicly base64 encoded sections in tests
-
- This allows us to make test cases to use base64 at run-time and still
- use and verify information determined at run-time, such as the IMAP test
- server's port number in test 842.
-
- This change makes 12 tests run again that basically never ran since we
- moved to dynamic port numbers.
-
- ftpserver.pl is adjusted to load test instructions and test number from
- the preprocessed test file.
-
- FILEFORMAT.md now documents the new base64 encoding syntax.
-
- Reported-by: Marcel Raad
- Fixes #5761
- Closes #5775
-
-- curl.1: add a few missing valid exit codes
-
- 93 - 96 can be returned as well.
-
- Closes #5777
-
-- TODO: Use multiple parallel transfers for a single download
-
- Closes #5774
-
-- TODO: Set the modification date on an uploaded file
-
- Closes #5768
-
-- [Thomas M. DuBuisson brought this change]
-
- CI: Add muse CI config
-
- Closes #5772
-
-- [Thomas M. DuBuisson brought this change]
-
- travis/script.sh: fix use of `-n' with unquoted envvar
-
- Shellcheck tells us "-n doesn't work with unquoted arguments. quote or
- use [[ ]]."
-
- And testing shows:
-
- ```
- docker run --rm -it ubuntu bash
- root@fe85ce156856:/# [ -n $DOES_NOT_EXIST ] && echo "I ran"
- I ran
- root@fe85ce156856:/# [ -n "$DOES_NOT_EXIST" ] && echo "I ran"
- root@fe85ce156856:/#
- ```
-
- Closes #5773
-
-- h2: repair trailer handling
-
- The previous h2 trailer fix in 54a2b63 was wrong and caused a
- regression: it cannot deal with trailers immediately when read since
- they may be read off the connection by the wrong 'data' owner.
-
- This change reverts the logic back to gathering all trailers into a
- single buffer, like before 54a2b63.
-
- Reported-by: Tadej Vengust
- Fixes #5663
- Closes #5769
-
-Viktor Szakats (3 Aug 2020)
-- windows: disable Unix Sockets for old mingw
-
- Classic mingw and 10y+ old versions of mingw-w64 don't ship with
- Windows headers having the typedef necessary for Unix Sockets
- support, so try detecting these environments to disable this
- feature.
-
- Ref: https://sourceforge.net/p/mingw-w64/mingw-w64/ci/cf6afc57179a5910621215f8f4037d406892072c/
-
- Reviewed-by: Daniel Stenberg
-
- Fixes #5674
- Closes #5758
-
-Marcel Raad (3 Aug 2020)
-- test1908: treat file as text
-
- Fixes the line endings on Windows.
-
- Closes https://github.com/curl/curl/pull/5767
-
-- TrackMemory tests: ignore realloc and free in getenv.c
-
- These are only called for WIN32.
-
- Closes https://github.com/curl/curl/pull/5767
-
-Daniel Stenberg (3 Aug 2020)
-- tests/FILEFORMAT.md: mention %HTTP2PORT
-
-- RELEASE-NOTES: synced
-
-- tlsv1.3.d. only for TLS-using connections
-
- ... and rephrase that "not all" TLS backends support it.
-
- Closes #5764
-
-- tls-max.d: this option is only for TLS-using connections
-
- Ref: #5763
- Closes #5764
-
-Marcel Raad (2 Aug 2020)
-- [Cameron Cawley brought this change]
-
- tool_doswin: Simplify Windows version detection
-
- Closes https://github.com/curl/curl/pull/5754
-
-- [Cameron Cawley brought this change]
-
- win32: Add Curl_verify_windows_version() to curlx
-
- Closes https://github.com/curl/curl/pull/5754
-
-- runtests.pl: treat LibreSSL and BoringSSL as OpenSSL
-
- This makes the tests that require the OpenSSL feature also run for
- those two compatible libraries.
-
- Closes https://github.com/curl/curl/pull/5762
-
-Daniel Stenberg (1 Aug 2020)
-- multi: Condition 'extrawait' is always true
-
- Reported by Codacy.
-
- Reviewed-by: Marcel Raad
- Closes #5759
-
-Marcel Raad (1 Aug 2020)
-- openssl: fix build with LibreSSL < 2.9.1
-
- `SSL_CTX_add0_chain_cert` and `SSL_CTX_clear_chain_certs` were
- introduced in LibreSSL 2.9.1 [0].
-
- [0] https://github.com/libressl-portable/openbsd/commit/0db809ee178457c8170abfae3931d7bd13abf3ef
-
- Closes https://github.com/curl/curl/pull/5757
-
-Daniel Stenberg (1 Aug 2020)
-- [Marc Aldorasi brought this change]
-
- multi_remove_handle: close unused connect-only connections
-
- Previously any connect-only connections in a multi handle would be kept
- alive until the multi handle was closed. Since these connections cannot
- be re-used, they can be marked for closure when the associated easy
- handle is removed from the multi handle.
-
- Closes #5749
-
-- checksrc: invoke script with -D to find .checksrc proper
-
- Without the -D command line option, checksrc.pl won't know which
- directory to load the ".checksrc" file from when building out of the
- source tree.
-
- Reported-by: Marcel Raad
- Fixes #5715
- Closes #5755
-
-- [Carlo Marcelo Arenas Belón brought this change]
-
- buildconf: retire ares buildconf invocation
-
- no longer needed after 4259d2df7dd95637a4b1e3fb174fe5e5aef81069
-
-- [Carlo Marcelo Arenas Belón brought this change]
-
- buildconf: excempt defunct reference to ACLOCAL_FLAGS
-
- retired with 09f278121e815028adb24d228d8092fc6cb022aa but kept around as
- the name is generic enough that it might be in use and relied upon from
- the environment.
-
-- [Carlo Marcelo Arenas Belón brought this change]
-
- buildconf: avoid array concatenation in die()
-
- reported as error SC2145[1] by shellcheck, but not expected to cause
- any behavioural differences otherwise.
-
- [1] https://github.com/koalaman/shellcheck/wiki/SC2145
-
- Closes #5701
-
-- travis: add ppc64le and s390x builds
-
- Closes #5752
-
-Marc Hoersken (31 Jul 2020)
-- connect: remove redundant message about connect failure
-
- Reviewed-by: Daniel Stenberg
-
- Closes #5708
-
-- tests/sshserver.pl: fix compatibility with OpenSSH for Windows
-
- Follow up to #5721
-
-- CI/azure: install libssh2 for use with msys2-based builds
-
- This enables building and running the SFTP tests.
- Unfortunately OpenSSH for Windows does not support SCP (yet).
-
- Reviewed-by: Daniel Stenberg
-
- Closes #5721
-
-- CI/azure: increase Windows job timeout once again
-
- Avoid aborted jobs due to performance issues on Azure DevOps.
-
- Reviewed-by: Daniel Stenberg
- Reviewed-by: Jay Satiro
-
- Closes #5738
-
-Jay Satiro (30 Jul 2020)
-- TODO: Schannel: 'Add option to allow abrupt server closure'
-
- We should offer an option to allow abrupt server closures (server closes
- SSL transfer without sending a known termination point such as length of
- transfer or close_notify alert). Abrupt server closures are usually
- because of misconfigured or very old servers.
-
- Closes https://github.com/curl/curl/issues/4427
-
-- url: fix CURLU and location following
-
- Prior to this change if the user set a URL handle (CURLOPT_CURLU) it was
- incorrectly used for the location follow, resulting in infinite requests
- to the original location.
-
- Reported-by: sspiri@users.noreply.github.com
-
- Fixes https://github.com/curl/curl/issues/5709
- Closes https://github.com/curl/curl/pull/5713
-
-Daniel Stenberg (30 Jul 2020)
-- RELEASE-NOTES: synced
-
-- [divinity76 brought this change]
-
- docs: add date of 7.20 to CURLM_CALL_MULTI_PERFORM mentions
-
- it helps make it obvious that most developers don't have to care about
- the CURLM_CALL_MULTI_PERFORM value (last release using it is nearly 11
- years old, November 4 2009)
-
- Closes #5744
-
-Jay Satiro (29 Jul 2020)
-- tool_cb_wrt: fix outfile mode flags for Windows
-
- - Use S_IREAD and S_IWRITE mode permission flags to create the file
- on Windows instead of S_IRUSR, S_IWUSR, etc.
-
- Windows only accepts a combination of S_IREAD and S_IWRITE. It does not
- acknowledge other combinations, for which it may generate an assertion.
-
- This is a follow-up to 81b4e99 from yesterday, which improved the
- existing file check with -J.
-
- Ref: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/open-wopen#remarks
- Ref: https://github.com/curl/curl/pull/5731
-
- Closes https://github.com/curl/curl/pull/5742
-
-Daniel Stenberg (28 Jul 2020)
-- checksrc: ban gmtime/localtime
-
- They're not thread-safe so they should not be used in libcurl code.
-
- Explictly enabled when deemed necessary and in examples and tests
-
- Reviewed-by: Nicolas Sterchele
- Closes #5732
diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS
index 6f164a9adf..2844ef1564 100644
--- a/libs/libcurl/docs/THANKS
+++ b/libs/libcurl/docs/THANKS
@@ -7,6 +7,7 @@
0xflotus on github
1ocalhost on github
3dyd on github
+3eka on github
Aaro Koskinen
Aaron Oneal
Aaron Orenstein
@@ -141,6 +142,7 @@ Andrei Sedoi
Andrei Valeriu BICA
Andrei Virtosu
Andrej E Baranov
+Andrew Barnert
Andrew Barnes
Andrew Benham
Andrew Biggs
@@ -212,6 +214,7 @@ Avery Fay
awesomenode on github
Axel Tillequin
Ayoub Boudhar
+Ayushman Singh Chauhan
b9a1 on github
Balaji Parasuram
Balaji S Rao
@@ -243,6 +246,7 @@ Benjamin Gerard
Benjamin Gilbert
Benjamin Johnson
Benjamin Kircher
+Benjamin Riefenstahl
Benjamin Ritcey
Benjamin Sergeant
Benoit Neil
@@ -272,6 +276,7 @@ Bjorn Augustsson
Bjorn Reese
Björn Stenberg
Blaise Potard
+Blake Burkhart
bnfp on github
Bob Relyea
Bob Richmond
@@ -460,6 +465,7 @@ Dan Zitter
Daniel at touchtunes
Daniel Bankhead
Daniel Black
+Daniel Carpenter
Daniel Cater
Daniel Egger
Daniel Gustafsson
@@ -503,6 +509,7 @@ David Binderman
David Blaikie
David Byron
David Cohen
+David Cook
David Demelier
David E. Narváez
David Earl
@@ -583,6 +590,7 @@ dmitrmax on github
Dmitry Bartsevich
Dmitry Eremin-Solenikov
Dmitry Falko
+Dmitry Karpov
Dmitry Kostjuchenko
Dmitry Kurochkin
Dmitry Mikhirev
@@ -769,6 +777,7 @@ Gaz Iqbal
Gaël Portay
Geeknik Labs
Geoff Beier
+Georeth Zhou
Georg Horn
Georg Huettenegger
Georg Lippitsch
@@ -899,6 +908,7 @@ Iida Yosiaki
Ikko Ashimine
Ilguiz Latypov
Ilja van Sprundel
+Illarion Taev
Ilya Kosarev
imilli on github
Immanuel Gregoire
@@ -919,6 +929,7 @@ Ivan Avdeev
IvanoG on github
Ivo Bellin Salarin
iz8mbw on github
+J. Bromley
Jack Boos Yu
Jack Zhang
Jackarain on github
@@ -1047,6 +1058,7 @@ Joe Malicki
Joe Mason
Joel Chen
Joel Depooter
+Joel Jakobsson
Joel Teichroeb
joey-l-us on github
Jofell Gallardo
@@ -1054,6 +1066,7 @@ Johan Anderson
Johan Lantz
Johan Nilsson
Johan van Selst
+Johann150 on github
Johannes Bauer
Johannes Ernst
Johannes G. Kristinsson
@@ -1202,6 +1215,7 @@ Kenny To
Kent Boortz
Keshav Krity
Kevin Baughman
+Kevin Burke
Kevin Fisk
Kevin Ji
Kevin Lussier
@@ -1222,6 +1236,7 @@ Klaus Stein
Klevtsov Vadim
Kobi Gurkan
Koen Dergent
+Koichi Shiraishi
kokke on github
Konstantin Isakov
Konstantin Kushnir
@@ -1311,7 +1326,9 @@ Luan Cestari
Luca Altea
Luca Boccassi
Lucas Adamski
+Lucas Clemente Vella
Lucas Pardue
+Lucas Servén Marín
Lucas Severo
Lucien Zürcher
Ludek Finstrle
@@ -1401,12 +1418,14 @@ Martijn Koster
Martin Ankerl
Martin Bašti
Martin C. Martin
+Martin Dorey
Martin Drasar
Martin Dreher
Martin Frodl
Martin Galvan
Martin Gartner
Martin Hager
+Martin Halle
Martin Hedenfalk
Martin Jansen
Martin Kammerhofer
@@ -1428,6 +1447,7 @@ Mateusz Loskot
Mathias Axelsson
Mathias Gumz
Mathieu Legare
+Matias N. Goldberg
Mats Lidell
Matt Arsenault
Matt Ford
@@ -1490,6 +1510,7 @@ Michael Jerris
Michael Kalinin
Michael Kaufmann
Michael Kilburn
+Michael Kolechkin
Michael Kujawa
Michael König
Michael Lee
@@ -1497,6 +1518,7 @@ Michael Maltese
Michael Mealling
Michael Mueller
Michael Musset
+Michael O'Farrell
Michael Olbrich
Michael Osipov
Michael Schmid
@@ -1508,6 +1530,7 @@ Michael Vittiglio
Michael Wallner
Michal Bonino
Michal Marek
+Michal Rus
Michal Trybus
Michal ÄŒaplygin
Michał Antoniak
@@ -1557,6 +1580,7 @@ Mohammad Hasbini
Mohun Biswas
momala454 on github
moohoorama on github
+Morten Minde Neergaard
Mostyn Bramley-Moore
Moti Avrahami
MrdUkk on github
@@ -1717,11 +1741,13 @@ Pavel Volgarev
Pavol Markovic
Pawel A. Gajda
Pawel Kierski
+Paweł Wegner
Pedro Larroy
Pedro Monreal
Pedro Neves
pendrek at hackerone
Peng Li
+Peng-Yu Chen
Per Jensen
Per Lundberg
Per Malmberg
@@ -1781,6 +1807,7 @@ Pierre-Yves Bigourdan
Piotr Dobrogost
Piotr Komborski
Po-Chuan Hsieh
+Pontus Lundkvist
Pooyan McSporran
Poul T Lomholt
Pramod Sharma
@@ -1797,6 +1824,7 @@ Quanah Gibson-Mount
Quentin Balland
Quinn Slack
R. Dennis Steed
+Radek Zajic
Radoslav Georgiev
Radu Simionescu
Rafa Muyo
@@ -1812,6 +1840,7 @@ Rajesh Naganathan
Rajkumar Mandal
Ralf S. Engelschall
Ralph Beckmann
+Ralph Langendam
Ralph Mitchell
Ram Krushna Mishra
ramsay-jones on github
@@ -1846,6 +1875,7 @@ Reza Arbab
Ricardo Cadime
Ricardo Gomes
Rich Burridge
+Rich FitzJohn
Rich Gray
Rich Mirch
Rich Rauenzahn
@@ -1942,6 +1972,7 @@ Ruslan Gazizov
Rutger Hofman
Ruurd Beerstra
RuurdBeerstra on github
+Ryan Beck-Buysse
Ryan Braud
Ryan Chan
Ryan Nelson
@@ -1998,6 +2029,7 @@ Sebastian Rasmussen
Senthil Raja Velu
Sergei Kuzmin
Sergei Nikulov
+Sergey Markelov
Sergey Ogryzkov
Sergey Tatarincev
Sergii Kavunenko
@@ -2005,6 +2037,7 @@ Sergii Pylypenko
Sergio Ballestrero
Sergio Barresi
Sergio Borghese
+sergio-nsk on github
Serj Kalichev
Seshubabu Pasam
Seth Mos
@@ -2060,6 +2093,7 @@ Stefan Eissing
Stefan Esser
Stefan Grether
Stefan Kanthak
+Stefan Karpinski
Stefan Krause
Stefan Neis
Stefan Strogin
@@ -2171,14 +2205,17 @@ Tim Stack
Tim Starling
Tim Tassonis
Tim Verhoeven
+Timo Lange
Timo Sirainen
Timotej Lazar
Timothe Litt
+Timothy Gu
Timothy Polich
Tinus van den Berg
TJ Saunders
tmkk on github
Tobias Blomberg
+Tobias Gabriel
Tobias Hieta
Tobias Hintze
Tobias Lindgren
@@ -2218,6 +2255,7 @@ Tomasz Kojm
Tomasz Lacki
Tommie Gannert
tommink[at]post.pl
+Tommy Odom
Tommy Petty
Tommy Tam
Ton Voon
@@ -2238,6 +2276,7 @@ Trivikram Kamat
Troels Walsted Hansen
Troy Engel
Tseng Jun
+Tuomas Siipola
Tuomo Rinne
Tupone Alfredo
Tyler Hall
@@ -2248,6 +2287,7 @@ Ulrich Doehner
Ulrich Telle
Ulrich Zadow
UrsusArctos on github
+ustcqidi on github
Valentin David
Valentyn Korniienko
Valerii Zapodovnikov
@@ -2261,6 +2301,7 @@ Venkataramana Mokkapati
Vicente Garcia
Victor Magierski
Victor Snezhko
+Victor Vieux
Vijay Panghal
Vikram Saxena
Viktor Szakats
@@ -2298,6 +2339,7 @@ Wenchao Li
Wenxiang Qian
Werner Koch
Werner Stolz
+Wes Hinsley
wesinator on github
Wesley Laxton
Wesley Miaw
@@ -2336,6 +2378,7 @@ ygthien on github
Yi Huang
Yiming Jing
Yingwei Liu
+Ymir1711 on github
Yonggang Luo
youngchopin on github
Yousuke Kimoto
@@ -2344,6 +2387,7 @@ Yukihiro Kawada
Yun SangHo
Yuri Slobodyanyuk
Yuriy Sosov
+Yusuke Nakamura
Yves Arrouye
Yves Lejeune
Zachary Seguin
diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h
index bed8068b0b..97de8c88ae 100644
--- a/libs/libcurl/include/curl/curl.h
+++ b/libs/libcurl/include/curl/curl.h
@@ -612,6 +612,7 @@ typedef enum {
CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */
CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */
CURLE_PROXY, /* 97 - proxy handshake error */
+ CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */
CURL_LAST /* never use! */
} CURLcode;
@@ -888,6 +889,10 @@ typedef enum {
operating system. Currently implemented under MS-Windows. */
#define CURLSSLOPT_NATIVE_CA (1<<4)
+/* - CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl to automatically locate and use
+ a client certificate for authentication. (Schannel) */
+#define CURLSSLOPT_AUTO_CLIENT_CERT (1<<5)
+
/* The default connection attempt delay in milliseconds for happy eyeballs.
CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
this value, keep them in sync. */
@@ -1461,8 +1466,8 @@ typedef enum {
#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
/* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
- tell libcurl to resolve names to those IP versions only. This only has
- affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
+ tell libcurl to use those IP versions only. This only has effect on
+ systems with support for more than one, i.e IPv4 _and_ IPv6. */
CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_VALUES, 113),
/* Set this option to limit the size of a file that will be downloaded from
@@ -2088,6 +2093,14 @@ typedef enum {
/* Same as CURLOPT_SSL_VERIFYSTATUS but for DOH (DNS-over-HTTPS) servers. */
CURLOPT(CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 308),
+ /* The CA certificates as "blob" used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_CAINFO_BLOB, CURLOPTTYPE_BLOB, 309),
+
+ /* The CA certificates as "blob" used to validate the proxy certificate
+ this option is used only if PROXY_SSL_VERIFYPEER is true */
+ CURLOPT(CURLOPT_PROXY_CAINFO_BLOB, CURLOPTTYPE_BLOB, 310),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -2122,10 +2135,10 @@ typedef enum {
/* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
name resolves addresses using more than one IP protocol version, this
option might be handy to force libcurl to use a specific IP version. */
-#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, uses addresses to all IP
versions that your system allows */
-#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */
-#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */
+#define CURL_IPRESOLVE_V4 1 /* uses only IPv4 addresses/connections */
+#define CURL_IPRESOLVE_V6 2 /* uses only IPv6 addresses/connections */
/* three convenient "aliases" that follow the name scheme better */
#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
@@ -2866,6 +2879,7 @@ typedef enum {
CURLVERSION_SEVENTH,
CURLVERSION_EIGHTH,
CURLVERSION_NINTH,
+ CURLVERSION_TENTH,
CURLVERSION_LAST /* never actually use this */
} CURLversion;
@@ -2874,7 +2888,7 @@ typedef enum {
meant to be a built-in version number for what kind of struct the caller
expects. If the struct ever changes, we redefine the NOW to another enum
from above. */
-#define CURLVERSION_NOW CURLVERSION_NINTH
+#define CURLVERSION_NOW CURLVERSION_TENTH
struct curl_version_info_data {
CURLversion age; /* age of the returned struct */
@@ -2927,6 +2941,9 @@ struct curl_version_info_data {
/* These fields were added in CURLVERSION_NINTH */
const char *hyper_version; /* human readable string. */
+
+ /* These fields were added in CURLVERSION_TENTH */
+ const char *gsasl_version; /* human readable string. */
};
typedef struct curl_version_info_data curl_version_info_data;
diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h
index b74cdc1170..98f7d0cdf4 100644
--- a/libs/libcurl/include/curl/curlver.h
+++ b/libs/libcurl/include/curl/curlver.h
@@ -30,13 +30,13 @@
/* This is the version number of the libcurl package from which this header
file origins: */
-#define LIBCURL_VERSION "7.76.1"
+#define LIBCURL_VERSION "7.77.0"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 76
-#define LIBCURL_VERSION_PATCH 1
+#define LIBCURL_VERSION_MINOR 77
+#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparisons 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 0x074c01
+#define LIBCURL_VERSION_NUM 0x074d00
/*
* This is the date and time when the full source package was created. The
@@ -68,7 +68,7 @@
*
* "2007-11-23"
*/
-#define LIBCURL_TIMESTAMP "2021-04-14"
+#define LIBCURL_TIMESTAMP "2021-05-26"
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
#define CURL_AT_LEAST_VERSION(x,y,z) \
diff --git a/libs/libcurl/libcurl.vcxproj b/libs/libcurl/libcurl.vcxproj
index d601dbdd21..49e6a66c28 100644
--- a/libs/libcurl/libcurl.vcxproj
+++ b/libs/libcurl/libcurl.vcxproj
@@ -41,6 +41,9 @@
<ClCompile Include="src\base64.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="src\bufref.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="src\c-hyper.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@@ -444,6 +447,7 @@
<ClInclude Include="src\amigaos.h" />
<ClInclude Include="src\arpa_telnet.h" />
<ClInclude Include="src\asyn.h" />
+ <ClInclude Include="src\bufref.h" />
<ClInclude Include="src\c-hyper.h" />
<ClInclude Include="src\config-amigaos.h" />
<ClInclude Include="src\config-dos.h" />
diff --git a/libs/libcurl/libcurl.vcxproj.filters b/libs/libcurl/libcurl.vcxproj.filters
index 9a6fcc2b65..4ade79b333 100644
--- a/libs/libcurl/libcurl.vcxproj.filters
+++ b/libs/libcurl/libcurl.vcxproj.filters
@@ -17,6 +17,9 @@
<ClCompile Include="src\base64.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\bufref.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="src\c-hyper.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -463,6 +466,9 @@
<ClInclude Include="src\asyn.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\bufref.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="src\c-hyper.h">
<Filter>Header Files</Filter>
</ClInclude>
diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt
index a58b47b865..2575288f70 100644
--- a/libs/libcurl/src/CMakeLists.txt
+++ b/libs/libcurl/src/CMakeLists.txt
@@ -20,6 +20,7 @@
#
###########################################################################
set(LIB_NAME libcurl)
+set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library")
if(BUILD_SHARED_LIBS)
set(CURL_STATICLIB NO)
@@ -98,7 +99,10 @@ if(WIN32)
add_definitions(-D_USRDLL)
endif()
-set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
+set_target_properties(${LIB_NAME} PROPERTIES
+ COMPILE_DEFINITIONS BUILDING_LIBCURL
+ OUTPUT_NAME ${LIBCURL_OUTPUT_NAME}
+ )
if(HIDES_CURL_PRIVATE_SYMBOLS)
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in
index c17ae17a51..d89f375a14 100644
--- a/libs/libcurl/src/Makefile.in
+++ b/libs/libcurl/src/Makefile.in
@@ -125,12 +125,22 @@ host_triplet = @host@
subdir = lib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compile_check_sizeof.m4 \
+ $(top_srcdir)/m4/curl-amissl.m4 \
+ $(top_srcdir)/m4/curl-bearssl.m4 \
$(top_srcdir)/m4/curl-compilers.m4 \
$(top_srcdir)/m4/curl-confopts.m4 \
$(top_srcdir)/m4/curl-functions.m4 \
+ $(top_srcdir)/m4/curl-gnutls.m4 \
+ $(top_srcdir)/m4/curl-mbedtls.m4 \
+ $(top_srcdir)/m4/curl-mesalink.m4 $(top_srcdir)/m4/curl-nss.m4 \
$(top_srcdir)/m4/curl-openssl.m4 \
$(top_srcdir)/m4/curl-override.m4 \
- $(top_srcdir)/m4/curl-reentrant.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/curl-reentrant.m4 \
+ $(top_srcdir)/m4/curl-rustls.m4 \
+ $(top_srcdir)/m4/curl-schannel.m4 \
+ $(top_srcdir)/m4/curl-sectransp.m4 \
+ $(top_srcdir)/m4/curl-sysconfig.m4 \
+ $(top_srcdir)/m4/curl-wolfssl.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/xc-am-iface.m4 \
@@ -181,22 +191,23 @@ LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
libcurl_la_LIBADD =
am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \
libcurl_la-asyn-ares.lo libcurl_la-asyn-thread.lo \
- libcurl_la-base64.lo libcurl_la-c-hyper.lo \
- libcurl_la-conncache.lo libcurl_la-connect.lo \
- libcurl_la-content_encoding.lo libcurl_la-cookie.lo \
- libcurl_la-curl_addrinfo.lo libcurl_la-curl_ctype.lo \
- libcurl_la-curl_des.lo libcurl_la-curl_endian.lo \
- libcurl_la-curl_fnmatch.lo libcurl_la-curl_get_line.lo \
- libcurl_la-curl_gethostname.lo libcurl_la-curl_gssapi.lo \
- libcurl_la-curl_memrchr.lo libcurl_la-curl_multibyte.lo \
- libcurl_la-curl_ntlm_core.lo libcurl_la-curl_ntlm_wb.lo \
- libcurl_la-curl_path.lo libcurl_la-curl_range.lo \
- libcurl_la-curl_rtmp.lo libcurl_la-curl_sasl.lo \
- libcurl_la-curl_sspi.lo libcurl_la-curl_threads.lo \
- libcurl_la-dict.lo libcurl_la-doh.lo libcurl_la-dotdot.lo \
- libcurl_la-dynbuf.lo libcurl_la-easy.lo \
- libcurl_la-easygetopt.lo libcurl_la-easyoptions.lo \
- libcurl_la-escape.lo libcurl_la-file.lo libcurl_la-fileinfo.lo \
+ libcurl_la-base64.lo libcurl_la-bufref.lo \
+ libcurl_la-c-hyper.lo libcurl_la-conncache.lo \
+ libcurl_la-connect.lo libcurl_la-content_encoding.lo \
+ libcurl_la-cookie.lo libcurl_la-curl_addrinfo.lo \
+ libcurl_la-curl_ctype.lo libcurl_la-curl_des.lo \
+ libcurl_la-curl_endian.lo libcurl_la-curl_fnmatch.lo \
+ libcurl_la-curl_get_line.lo libcurl_la-curl_gethostname.lo \
+ libcurl_la-curl_gssapi.lo libcurl_la-curl_memrchr.lo \
+ libcurl_la-curl_multibyte.lo libcurl_la-curl_ntlm_core.lo \
+ libcurl_la-curl_ntlm_wb.lo libcurl_la-curl_path.lo \
+ libcurl_la-curl_range.lo libcurl_la-curl_rtmp.lo \
+ libcurl_la-curl_sasl.lo libcurl_la-curl_sspi.lo \
+ libcurl_la-curl_threads.lo libcurl_la-dict.lo \
+ libcurl_la-doh.lo libcurl_la-dotdot.lo libcurl_la-dynbuf.lo \
+ libcurl_la-easy.lo libcurl_la-easygetopt.lo \
+ libcurl_la-easyoptions.lo libcurl_la-escape.lo \
+ libcurl_la-file.lo libcurl_la-fileinfo.lo \
libcurl_la-formdata.lo libcurl_la-ftp.lo \
libcurl_la-ftplistparser.lo libcurl_la-getenv.lo \
libcurl_la-getinfo.lo libcurl_la-gopher.lo libcurl_la-hash.lo \
@@ -269,26 +280,27 @@ libcurl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
libcurlu_la_LIBADD =
am__objects_9 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \
libcurlu_la-asyn-ares.lo libcurlu_la-asyn-thread.lo \
- libcurlu_la-base64.lo libcurlu_la-c-hyper.lo \
- libcurlu_la-conncache.lo libcurlu_la-connect.lo \
- libcurlu_la-content_encoding.lo libcurlu_la-cookie.lo \
- libcurlu_la-curl_addrinfo.lo libcurlu_la-curl_ctype.lo \
- libcurlu_la-curl_des.lo libcurlu_la-curl_endian.lo \
- libcurlu_la-curl_fnmatch.lo libcurlu_la-curl_get_line.lo \
- libcurlu_la-curl_gethostname.lo libcurlu_la-curl_gssapi.lo \
- libcurlu_la-curl_memrchr.lo libcurlu_la-curl_multibyte.lo \
- libcurlu_la-curl_ntlm_core.lo libcurlu_la-curl_ntlm_wb.lo \
- libcurlu_la-curl_path.lo libcurlu_la-curl_range.lo \
- libcurlu_la-curl_rtmp.lo libcurlu_la-curl_sasl.lo \
- libcurlu_la-curl_sspi.lo libcurlu_la-curl_threads.lo \
- libcurlu_la-dict.lo libcurlu_la-doh.lo libcurlu_la-dotdot.lo \
- libcurlu_la-dynbuf.lo libcurlu_la-easy.lo \
- libcurlu_la-easygetopt.lo libcurlu_la-easyoptions.lo \
- libcurlu_la-escape.lo libcurlu_la-file.lo \
- libcurlu_la-fileinfo.lo libcurlu_la-formdata.lo \
- libcurlu_la-ftp.lo libcurlu_la-ftplistparser.lo \
- libcurlu_la-getenv.lo libcurlu_la-getinfo.lo \
- libcurlu_la-gopher.lo libcurlu_la-hash.lo libcurlu_la-hmac.lo \
+ libcurlu_la-base64.lo libcurlu_la-bufref.lo \
+ libcurlu_la-c-hyper.lo libcurlu_la-conncache.lo \
+ libcurlu_la-connect.lo libcurlu_la-content_encoding.lo \
+ libcurlu_la-cookie.lo libcurlu_la-curl_addrinfo.lo \
+ libcurlu_la-curl_ctype.lo libcurlu_la-curl_des.lo \
+ libcurlu_la-curl_endian.lo libcurlu_la-curl_fnmatch.lo \
+ libcurlu_la-curl_get_line.lo libcurlu_la-curl_gethostname.lo \
+ libcurlu_la-curl_gssapi.lo libcurlu_la-curl_memrchr.lo \
+ libcurlu_la-curl_multibyte.lo libcurlu_la-curl_ntlm_core.lo \
+ libcurlu_la-curl_ntlm_wb.lo libcurlu_la-curl_path.lo \
+ libcurlu_la-curl_range.lo libcurlu_la-curl_rtmp.lo \
+ libcurlu_la-curl_sasl.lo libcurlu_la-curl_sspi.lo \
+ libcurlu_la-curl_threads.lo libcurlu_la-dict.lo \
+ libcurlu_la-doh.lo libcurlu_la-dotdot.lo libcurlu_la-dynbuf.lo \
+ libcurlu_la-easy.lo libcurlu_la-easygetopt.lo \
+ libcurlu_la-easyoptions.lo libcurlu_la-escape.lo \
+ libcurlu_la-file.lo libcurlu_la-fileinfo.lo \
+ libcurlu_la-formdata.lo libcurlu_la-ftp.lo \
+ libcurlu_la-ftplistparser.lo libcurlu_la-getenv.lo \
+ libcurlu_la-getinfo.lo libcurlu_la-gopher.lo \
+ libcurlu_la-hash.lo libcurlu_la-hmac.lo \
libcurlu_la-hostasyn.lo libcurlu_la-hostcheck.lo \
libcurlu_la-hostip.lo libcurlu_la-hostip4.lo \
libcurlu_la-hostip6.lo libcurlu_la-hostsyn.lo \
@@ -373,6 +385,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
./$(DEPDIR)/libcurl_la-asyn-ares.Plo \
./$(DEPDIR)/libcurl_la-asyn-thread.Plo \
./$(DEPDIR)/libcurl_la-base64.Plo \
+ ./$(DEPDIR)/libcurl_la-bufref.Plo \
./$(DEPDIR)/libcurl_la-c-hyper.Plo \
./$(DEPDIR)/libcurl_la-conncache.Plo \
./$(DEPDIR)/libcurl_la-connect.Plo \
@@ -488,6 +501,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
./$(DEPDIR)/libcurlu_la-asyn-ares.Plo \
./$(DEPDIR)/libcurlu_la-asyn-thread.Plo \
./$(DEPDIR)/libcurlu_la-base64.Plo \
+ ./$(DEPDIR)/libcurlu_la-bufref.Plo \
./$(DEPDIR)/libcurlu_la-c-hyper.Plo \
./$(DEPDIR)/libcurlu_la-conncache.Plo \
./$(DEPDIR)/libcurlu_la-connect.Plo \
@@ -1088,6 +1102,7 @@ LIB_CFILES = \
asyn-ares.c \
asyn-thread.c \
base64.c \
+ bufref.c \
c-hyper.c \
conncache.c \
connect.c \
@@ -1208,6 +1223,7 @@ LIB_HFILES = \
amigaos.h \
arpa_telnet.h \
asyn.h \
+ bufref.h \
c-hyper.h \
conncache.h \
connect.h \
@@ -1626,6 +1642,7 @@ distclean-compile:
@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
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-base64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-bufref.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-c-hyper.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-conncache.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-connect.Plo@am__quote@ # am--include-marker
@@ -1745,6 +1762,7 @@ distclean-compile:
@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
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-base64.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-bufref.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-c-hyper.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-conncache.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-connect.Plo@am__quote@ # am--include-marker
@@ -1993,6 +2011,13 @@ libcurl_la-base64.lo: base64.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-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c
+libcurl_la-bufref.lo: bufref.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-bufref.lo -MD -MP -MF $(DEPDIR)/libcurl_la-bufref.Tpo -c -o libcurl_la-bufref.lo `test -f 'bufref.c' || echo '$(srcdir)/'`bufref.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-bufref.Tpo $(DEPDIR)/libcurl_la-bufref.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bufref.c' object='libcurl_la-bufref.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-bufref.lo `test -f 'bufref.c' || echo '$(srcdir)/'`bufref.c
+
libcurl_la-c-hyper.lo: c-hyper.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-c-hyper.lo -MD -MP -MF $(DEPDIR)/libcurl_la-c-hyper.Tpo -c -o libcurl_la-c-hyper.lo `test -f 'c-hyper.c' || echo '$(srcdir)/'`c-hyper.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-c-hyper.Tpo $(DEPDIR)/libcurl_la-c-hyper.Plo
@@ -3064,6 +3089,13 @@ libcurlu_la-base64.lo: base64.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-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c
+libcurlu_la-bufref.lo: bufref.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-bufref.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-bufref.Tpo -c -o libcurlu_la-bufref.lo `test -f 'bufref.c' || echo '$(srcdir)/'`bufref.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-bufref.Tpo $(DEPDIR)/libcurlu_la-bufref.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bufref.c' object='libcurlu_la-bufref.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-bufref.lo `test -f 'bufref.c' || echo '$(srcdir)/'`bufref.c
+
libcurlu_la-c-hyper.lo: c-hyper.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-c-hyper.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-c-hyper.Tpo -c -o libcurlu_la-c-hyper.lo `test -f 'c-hyper.c' || echo '$(srcdir)/'`c-hyper.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-c-hyper.Tpo $(DEPDIR)/libcurlu_la-c-hyper.Plo
@@ -4252,6 +4284,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libcurl_la-asyn-ares.Plo
-rm -f ./$(DEPDIR)/libcurl_la-asyn-thread.Plo
-rm -f ./$(DEPDIR)/libcurl_la-base64.Plo
+ -rm -f ./$(DEPDIR)/libcurl_la-bufref.Plo
-rm -f ./$(DEPDIR)/libcurl_la-c-hyper.Plo
-rm -f ./$(DEPDIR)/libcurl_la-conncache.Plo
-rm -f ./$(DEPDIR)/libcurl_la-connect.Plo
@@ -4371,6 +4404,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-base64.Plo
+ -rm -f ./$(DEPDIR)/libcurlu_la-bufref.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-c-hyper.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-conncache.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-connect.Plo
@@ -4603,6 +4637,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libcurl_la-asyn-ares.Plo
-rm -f ./$(DEPDIR)/libcurl_la-asyn-thread.Plo
-rm -f ./$(DEPDIR)/libcurl_la-base64.Plo
+ -rm -f ./$(DEPDIR)/libcurl_la-bufref.Plo
-rm -f ./$(DEPDIR)/libcurl_la-c-hyper.Plo
-rm -f ./$(DEPDIR)/libcurl_la-conncache.Plo
-rm -f ./$(DEPDIR)/libcurl_la-connect.Plo
@@ -4722,6 +4757,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-base64.Plo
+ -rm -f ./$(DEPDIR)/libcurlu_la-bufref.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-c-hyper.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-conncache.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-connect.Plo
diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc
index 90ec6aa05c..3e9ddec12c 100644
--- a/libs/libcurl/src/Makefile.inc
+++ b/libs/libcurl/src/Makefile.inc
@@ -97,6 +97,7 @@ LIB_CFILES = \
asyn-ares.c \
asyn-thread.c \
base64.c \
+ bufref.c \
c-hyper.c \
conncache.c \
connect.c \
@@ -217,6 +218,7 @@ LIB_HFILES = \
amigaos.h \
arpa_telnet.h \
asyn.h \
+ bufref.h \
c-hyper.h \
conncache.h \
connect.h \
diff --git a/libs/libcurl/src/amigaos.c b/libs/libcurl/src/amigaos.c
index d3b00d9083..78bb22c7e2 100644
--- a/libs/libcurl/src/amigaos.c
+++ b/libs/libcurl/src/amigaos.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -90,6 +90,33 @@ void Curl_amiga_X509_free(X509 *a)
{
X509_free(a);
}
+
+/* AmiSSL replaces many functions with macros. Curl requires pointer
+ * to some of these functions. Thus, we have to encapsulate these macros.
+ */
+
+#include "warnless.h"
+
+int (SHA256_Init)(SHA256_CTX *c)
+{
+ return SHA256_Init(c);
+};
+
+int (SHA256_Update)(SHA256_CTX *c, const void *data, size_t len)
+{
+ return SHA256_Update(c, data, curlx_uztoui(len));
+};
+
+int (SHA256_Final)(unsigned char *md, SHA256_CTX *c)
+{
+ return SHA256_Final(md, c);
+};
+
+void (X509_INFO_free)(X509_INFO *a)
+{
+ X509_INFO_free(a);
+};
+
#endif /* USE_AMISSL */
#endif /* __AMIGA__ */
diff --git a/libs/libcurl/src/asyn-ares.c b/libs/libcurl/src/asyn-ares.c
index c9bd9d16a5..7827847350 100644
--- a/libs/libcurl/src/asyn-ares.c
+++ b/libs/libcurl/src/asyn-ares.c
@@ -309,7 +309,7 @@ static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
pfd[i].fd = socks[i];
pfd[i].events |= POLLWRNORM|POLLOUT;
}
- if(pfd[i].events != 0)
+ if(pfd[i].events)
num++;
else
break;
@@ -620,28 +620,9 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
int *waitp)
{
char *bufp;
- int family = PF_INET;
*waitp = 0; /* default to synchronous response */
-#ifdef ENABLE_IPV6
- switch(data->set.ipver) {
- default:
-#if ARES_VERSION >= 0x010601
- family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older
- c-ares versions this just falls through and defaults
- to PF_INET */
- break;
-#endif
- case CURL_IPRESOLVE_V4:
- family = PF_INET;
- break;
- case CURL_IPRESOLVE_V6:
- family = PF_INET6;
- break;
- }
-#endif /* ENABLE_IPV6 */
-
bufp = strdup(hostname);
if(bufp) {
struct thread_data *res = NULL;
@@ -661,33 +642,27 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
/* initial status - failed */
res->last_status = ARES_ENOTFOUND;
-#ifdef ENABLE_IPV6
- if(family == PF_UNSPEC) {
- if(Curl_ipv6works(data)) {
- res->num_pending = 2;
-
- /* areschannel is already setup in the Curl_open() function */
- ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
- PF_INET, query_completed_cb, data);
- ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
- PF_INET6, query_completed_cb, data);
- }
- else {
- res->num_pending = 1;
- /* areschannel is already setup in the Curl_open() function */
- ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
- PF_INET, query_completed_cb, data);
- }
+#if ARES_VERSION >= 0x010601
+ /* IPv6 supported by c-ares since 1.6.1 */
+ if(Curl_ipv6works(data)) {
+ /* The stack seems to be IPv6-enabled */
+ res->num_pending = 2;
+
+ /* areschannel is already setup in the Curl_open() function */
+ ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
+ PF_INET, query_completed_cb, data);
+ ares_gethostbyname((ares_channel)data->state.async.resolver, hostname,
+ PF_INET6, query_completed_cb, data);
}
else
-#endif /* ENABLE_IPV6 */
+#endif /* ARES_VERSION >= 0x010601 */
{
res->num_pending = 1;
/* areschannel is already setup in the Curl_open() function */
ares_gethostbyname((ares_channel)data->state.async.resolver,
- hostname, family,
+ hostname, PF_INET,
query_completed_cb, data);
}
diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c
index c453203f75..36f68cb493 100644
--- a/libs/libcurl/src/asyn-thread.c
+++ b/libs/libcurl/src/asyn-thread.c
@@ -238,7 +238,7 @@ int init_thread_sync_data(struct thread_data *td,
#endif
tsd->mtx = malloc(sizeof(curl_mutex_t));
- if(tsd->mtx == NULL)
+ if(!tsd->mtx)
goto err_exit;
Curl_mutex_init(tsd->mtx);
@@ -305,7 +305,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
- if(rc != 0) {
+ if(rc) {
tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
if(tsd->sock_error == 0)
tsd->sock_error = RESOLVER_ENOMEM;
@@ -701,24 +701,9 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
*waitp = 0; /* default to synchronous response */
#ifdef CURLRES_IPV6
- /*
- * Check if a limited name resolve has been requested.
- */
- switch(data->set.ipver) {
- case CURL_IPRESOLVE_V4:
- pf = PF_INET;
- break;
- case CURL_IPRESOLVE_V6:
- pf = PF_INET6;
- break;
- default:
+ if(Curl_ipv6works(data))
+ /* The stack seems to be IPv6-enabled */
pf = PF_UNSPEC;
- break;
- }
-
- if((pf != PF_INET) && !Curl_ipv6works(data))
- /* The stack seems to be a non-IPv6 one */
- pf = PF_INET;
#endif /* CURLRES_IPV6 */
memset(&hints, 0, sizeof(hints));
diff --git a/libs/libcurl/src/bufref.c b/libs/libcurl/src/bufref.c
new file mode 100644
index 0000000000..b84511e185
--- /dev/null
+++ b/libs/libcurl/src/bufref.c
@@ -0,0 +1,127 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "urldata.h"
+#include "bufref.h"
+
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define SIGNATURE 0x5c48e9b2 /* Random pattern. */
+
+/*
+ * Init a bufref struct.
+ */
+void Curl_bufref_init(struct bufref *br)
+{
+ DEBUGASSERT(br);
+ br->dtor = NULL;
+ br->ptr = NULL;
+ br->len = 0;
+
+#ifdef DEBUGBUILD
+ br->signature = SIGNATURE;
+#endif
+}
+
+/*
+ * Free the buffer and re-init the necessary fields. It doesn't touch the
+ * 'signature' field and thus this buffer reference can be reused.
+ */
+
+void Curl_bufref_free(struct bufref *br)
+{
+ DEBUGASSERT(br);
+ DEBUGASSERT(br->signature == SIGNATURE);
+ DEBUGASSERT(br->ptr || !br->len);
+
+ if(br->ptr && br->dtor)
+ br->dtor((void *) br->ptr);
+
+ br->dtor = NULL;
+ br->ptr = NULL;
+ br->len = 0;
+}
+
+/*
+ * Set the buffer reference to new values. The previously referenced buffer
+ * is released before assignment.
+ */
+void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
+ void (*dtor)(void *))
+{
+ DEBUGASSERT(ptr || !len);
+ DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH);
+
+ Curl_bufref_free(br);
+ br->ptr = (const unsigned char *) ptr;
+ br->len = len;
+ br->dtor = dtor;
+}
+
+/*
+ * Get a pointer to the referenced buffer.
+ */
+const unsigned char *Curl_bufref_ptr(const struct bufref *br)
+{
+ DEBUGASSERT(br);
+ DEBUGASSERT(br->signature == SIGNATURE);
+ DEBUGASSERT(br->ptr || !br->len);
+
+ return br->ptr;
+}
+
+/*
+ * Get the length of the referenced buffer data.
+ */
+size_t Curl_bufref_len(const struct bufref *br)
+{
+ DEBUGASSERT(br);
+ DEBUGASSERT(br->signature == SIGNATURE);
+ DEBUGASSERT(br->ptr || !br->len);
+
+ return br->len;
+}
+
+CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len)
+{
+ unsigned char *cpy = NULL;
+
+ DEBUGASSERT(br);
+ DEBUGASSERT(br->signature == SIGNATURE);
+ DEBUGASSERT(br->ptr || !br->len);
+ DEBUGASSERT(ptr || !len);
+ DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH);
+
+ if(ptr) {
+ cpy = malloc(len + 1);
+ if(!cpy)
+ return CURLE_OUT_OF_MEMORY;
+ if(len)
+ memcpy(cpy, ptr, len);
+ cpy[len] = '\0';
+ }
+
+ Curl_bufref_set(br, cpy, len, curl_free);
+ return CURLE_OK;
+}
diff --git a/libs/libcurl/src/bufref.h b/libs/libcurl/src/bufref.h
new file mode 100644
index 0000000000..25f65d894d
--- /dev/null
+++ b/libs/libcurl/src/bufref.h
@@ -0,0 +1,46 @@
+#ifndef HEADER_CURL_BUFREF_H
+#define HEADER_CURL_BUFREF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Generic buffer reference.
+ */
+struct bufref {
+ void (*dtor)(void *); /* Associated destructor. */
+ const unsigned char *ptr; /* Referenced data buffer. */
+ size_t len; /* The data size in bytes. */
+#ifdef DEBUGBUILD
+ int signature; /* Detect API use mistakes. */
+#endif
+};
+
+
+void Curl_bufref_init(struct bufref *br);
+void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
+ void (*dtor)(void *));
+const unsigned char *Curl_bufref_ptr(const struct bufref *br);
+size_t Curl_bufref_len(const struct bufref *br);
+CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len);
+void Curl_bufref_free(struct bufref *br);
+
+#endif
diff --git a/libs/libcurl/src/c-hyper.c b/libs/libcurl/src/c-hyper.c
index 5d370d7bda..81f589eb9e 100644
--- a/libs/libcurl/src/c-hyper.c
+++ b/libs/libcurl/src/c-hyper.c
@@ -175,6 +175,8 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk)
}
if(k->ignorebody)
return HYPER_ITER_CONTINUE;
+ if(0 == len)
+ return HYPER_ITER_CONTINUE;
Curl_debug(data, CURLINFO_DATA_IN, buf, len);
if(!data->set.http_ce_skip && k->writer_stack)
/* content-encoded data */
@@ -203,11 +205,8 @@ static CURLcode status_line(struct Curl_easy *data,
const uint8_t *reason, size_t rlen)
{
CURLcode result;
- size_t wrote;
size_t len;
const char *vstr;
- curl_write_callback writeheader =
- data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
vstr = http_version == HYPER_HTTP_VERSION_1_1 ? "1.1" :
(http_version == HYPER_HTTP_VERSION_2 ? "2" : "1.0");
conn->httpversion =
@@ -230,12 +229,12 @@ static CURLcode status_line(struct Curl_easy *data,
len = Curl_dyn_len(&data->state.headerb);
Curl_debug(data, CURLINFO_HEADER_IN, Curl_dyn_ptr(&data->state.headerb),
len);
- Curl_set_in_callback(data, true);
- wrote = writeheader(Curl_dyn_ptr(&data->state.headerb), 1, len,
- data->set.writeheader);
- Curl_set_in_callback(data, false);
- if(wrote != len)
- return CURLE_WRITE_ERROR;
+ result = Curl_client_write(data, CLIENTWRITE_HEADER,
+ Curl_dyn_ptr(&data->state.headerb), len);
+ if(result) {
+ data->state.hresult = CURLE_ABORTED_BY_CALLBACK;
+ return HYPER_ITER_BREAK;
+ }
data->info.header_size += (long)len;
data->req.headerbytecount += (long)len;
@@ -332,7 +331,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
infof(data, "hyperstream is done!\n");
break;
}
- else if(t != HYPER_TASK_RESPONSE) {
+ else if(t != HYPER_TASK_RESPONSE && t != HYPER_TASK_EMPTY) {
*didwhat = KEEP_RECV;
break;
}
diff --git a/libs/libcurl/src/checksrc.pl b/libs/libcurl/src/checksrc.pl
index 13f86ecd5a..a35535c191 100644
--- a/libs/libcurl/src/checksrc.pl
+++ b/libs/libcurl/src/checksrc.pl
@@ -6,7 +6,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 2011 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -86,6 +86,8 @@ my %warnings = (
'BRACEWHILE' => 'A single space between open brace and while',
'EXCLAMATIONSPACE' => 'Whitespace after exclamation mark in expression',
'EMPTYLINEBRACE' => 'Empty line before the open brace',
+ 'EQUALSNULL' => 'if/while comparison with == NULL',
+ 'NOTEQUALSZERO' => 'if/while comparison with != 0'
);
sub readskiplist {
@@ -471,6 +473,21 @@ sub scanfile {
"$2 with space");
}
}
+ # check for '== NULL' in if/while conditions but not if the thing on
+ # the left of it is a function call
+ if($nostr =~ /^(.*)(if|while)(\(.*[^)]) == NULL/) {
+ checkwarn("EQUALSNULL", $line,
+ length($1) + length($2) + length($3),
+ $file, $l, "we prefer !variable instead of \"== NULL\" comparisons");
+ }
+
+ # check for '!= 0' in if/while conditions but not if the thing on
+ # the left of it is a function call
+ if($nostr =~ /^(.*)(if|while)(\(.*[^)]) != 0[^x]/) {
+ checkwarn("NOTEQUALSZERO", $line,
+ length($1) + length($2) + length($3),
+ $file, $l, "we prefer if(rc) instead of \"rc != 0\" comparisons");
+ }
# check spaces in 'do {'
if($nostr =~ /^( *)do( *)\{/ && length($2) != 1) {
diff --git a/libs/libcurl/src/config-amigaos.h b/libs/libcurl/src/config-amigaos.h
index 381bf302c9..c2f5bd20b0 100644
--- a/libs/libcurl/src/config-amigaos.h
+++ b/libs/libcurl/src/config-amigaos.h
@@ -128,13 +128,6 @@
# define LONG_MIN (-0x7fffffffL-1)
#endif
-#define HAVE_GETNAMEINFO 1
-#define GETNAMEINFO_QUAL_ARG1 const
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-#define GETNAMEINFO_TYPE_ARG2 int
-#define GETNAMEINFO_TYPE_ARG46 size_t
-#define GETNAMEINFO_TYPE_ARG7 int
-
#define HAVE_RECV 1
#define RECV_TYPE_ARG1 long
#define RECV_TYPE_ARG2 char *
diff --git a/libs/libcurl/src/config-dos.h b/libs/libcurl/src/config-dos.h
index 0fb98e385d..6859208ab3 100644
--- a/libs/libcurl/src/config-dos.h
+++ b/libs/libcurl/src/config-dos.h
@@ -45,7 +45,6 @@
#define HAVE_FCNTL_H 1
#define HAVE_FREEADDRINFO 1
#define HAVE_GETADDRINFO 1
-#define HAVE_GETNAMEINFO 1
#define HAVE_GETPROTOBYNAME 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_IO_H 1
@@ -93,7 +92,7 @@
#define STDC_HEADERS 1
#define TIME_WITH_SYS_TIME 1
-/* Qualifiers for send(), recv(), recvfrom() and getnameinfo(). */
+/* Qualifiers for send(), recv(), and recvfrom() */
#define SEND_TYPE_ARG1 int
#define SEND_QUAL_ARG2 const
@@ -117,12 +116,6 @@
#define RECVFROM_TYPE_RETV int
#define RECVFROM_TYPE_ARG2_IS_VOID 1
-#define GETNAMEINFO_QUAL_ARG1 const
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-#define GETNAMEINFO_TYPE_ARG2 int
-#define GETNAMEINFO_TYPE_ARG46 int
-#define GETNAMEINFO_TYPE_ARG7 int
-
#define BSD
/* CURLDEBUG definition enables memory tracking */
diff --git a/libs/libcurl/src/config-mac.h b/libs/libcurl/src/config-mac.h
index 163686ec94..c8833e3006 100644
--- a/libs/libcurl/src/config-mac.h
+++ b/libs/libcurl/src/config-mac.h
@@ -85,13 +85,6 @@
#define SIZEOF_SHORT 2
#define SIZEOF_SIZE_T 4
-#define HAVE_GETNAMEINFO 1
-#define GETNAMEINFO_QUAL_ARG1 const
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-#define GETNAMEINFO_TYPE_ARG2 socklen_t
-#define GETNAMEINFO_TYPE_ARG46 size_t
-#define GETNAMEINFO_TYPE_ARG7 int
-
#define HAVE_RECV 1
#define RECV_TYPE_ARG1 int
#define RECV_TYPE_ARG2 void *
diff --git a/libs/libcurl/src/config-os400.h b/libs/libcurl/src/config-os400.h
index b5a9823fd1..366db983f4 100644
--- a/libs/libcurl/src/config-os400.h
+++ b/libs/libcurl/src/config-os400.h
@@ -310,9 +310,6 @@
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H
-/* Define if you have the `strlcpy' function. */
-#undef HAVE_STRLCPY
-
/* Define if you have the <stropts.h> header file. */
#undef HAVE_STROPTS_H
@@ -452,25 +449,6 @@
/* Define if you have the ldap_url_parse procedure. */
/* #define HAVE_LDAP_URL_PARSE */ /* Disabled because of an IBM bug. */
-/* Define if you have the getnameinfo function. */
-/* OS400 has no ASCII version of this procedure: wrapped in setup-os400.h. */
-#define HAVE_GETNAMEINFO
-
-/* Define to the type qualifier of arg 1 for getnameinfo. */
-#define GETNAMEINFO_QUAL_ARG1 const
-
-/* Define to the type of arg 1 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-
-/* Define to the type of arg 2 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG2 socklen_t
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG46 socklen_t
-
-/* Define to the type of arg 7 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG7 int
-
/* Define if you have the recv function. */
#define HAVE_RECV
diff --git a/libs/libcurl/src/config-plan9.h b/libs/libcurl/src/config-plan9.h
index ecfc273722..ce89309bc1 100644
--- a/libs/libcurl/src/config-plan9.h
+++ b/libs/libcurl/src/config-plan9.h
@@ -54,13 +54,6 @@
#define SIZEOF_TIME_T 4
#endif
-#define HAVE_GETNAMEINFO 1
-#define GETNAMEINFO_QUAL_ARG1 const
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-#define GETNAMEINFO_TYPE_ARG2 int
-#define GETNAMEINFO_TYPE_ARG46 long
-#define GETNAMEINFO_TYPE_ARG7 int
-
#define HAVE_RECV 1
#define RECV_TYPE_ARG1 int
#define RECV_TYPE_ARG2 void *
diff --git a/libs/libcurl/src/config-riscos.h b/libs/libcurl/src/config-riscos.h
index 2dc3c66311..13287e0a4c 100644
--- a/libs/libcurl/src/config-riscos.h
+++ b/libs/libcurl/src/config-riscos.h
@@ -296,9 +296,6 @@
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H
-/* Define if you have the `strlcpy' function. */
-#undef HAVE_STRLCPY
-
/* Define if you have the `strstr' function. */
#define HAVE_STRSTR
@@ -408,24 +405,6 @@
/* to disable LDAP */
#define CURL_DISABLE_LDAP
-/* Define if you have the getnameinfo function. */
-#define HAVE_GETNAMEINFO 1
-
-/* Define to the type qualifier of arg 1 for getnameinfo. */
-#define GETNAMEINFO_QUAL_ARG1 const
-
-/* Define to the type of arg 1 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-
-/* Define to the type of arg 2 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG2 socklen_t
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG46 size_t
-
-/* Define to the type of arg 7 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG7 int
-
/* Define if you have the recv function. */
#define HAVE_RECV 1
diff --git a/libs/libcurl/src/config-tpf.h b/libs/libcurl/src/config-tpf.h
index 3fdb8924c5..12c34e18e3 100644
--- a/libs/libcurl/src/config-tpf.h
+++ b/libs/libcurl/src/config-tpf.h
@@ -77,18 +77,6 @@
/* Define if struct sockaddr_in6 has the sin6_scope_id member */
/* #undef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID */
-/* Define to the type of arg 1 for getnameinfo. */
-/* #undef GETNAMEINFO_TYPE_ARG1 */
-
-/* Define to the type of arg 2 for getnameinfo. */
-/* #undef GETNAMEINFO_TYPE_ARG2 */
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-/* #undef GETNAMEINFO_TYPE_ARG46 */
-
-/* Define to the type of arg 7 for getnameinfo. */
-/* #undef GETNAMEINFO_TYPE_ARG7 */
-
/* Define to 1 if you have the alarm function. */
#define HAVE_ALARM 1
@@ -162,9 +150,6 @@
/* gethostbyname_r() takes 6 args */
/* #undef HAVE_GETHOSTBYNAME_R_6 1 */
-/* Define to 1 if you have the getnameinfo function. */
-/* #undef HAVE_GETNAMEINFO */
-
/* Define to 1 if you have the `getpass_r' function. */
/* #undef HAVE_GETPASS_R */
@@ -450,9 +435,6 @@
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
-/* Define to 1 if you have the `strlcpy' function. */
-/* #undef HAVE_STRLCPY */
-
/* Define to 1 if you have the `strstr' function. */
#define HAVE_STRSTR 1
@@ -660,24 +642,6 @@
/* the signed version of size_t */
/* #undef ssize_t */
-/* Define to 1 if you have the getnameinfo function. */
-/* #undef HAVE_GETNAMEINFO 1 */
-
-/* Define to the type qualifier of arg 1 for getnameinfo. */
-/* #undef GETNAMEINFO_QUAL_ARG1 const */
-
-/* Define to the type of arg 1 for getnameinfo. */
-/* #undef GETNAMEINFO_TYPE_ARG1 struct sockaddr * */
-
-/* Define to the type of arg 2 for getnameinfo. */
-/* #undef GETNAMEINFO_TYPE_ARG2 socklen_t */
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-/* #undef GETNAMEINFO_TYPE_ARG46 size_t */
-
-/* Define to the type of arg 7 for getnameinfo. */
-/* #undef GETNAMEINFO_TYPE_ARG7 int */
-
/* Define to 1 if you have the recv function. */
#define HAVE_RECV 1
diff --git a/libs/libcurl/src/config-vxworks.h b/libs/libcurl/src/config-vxworks.h
index 916d023383..8911b05e24 100644
--- a/libs/libcurl/src/config-vxworks.h
+++ b/libs/libcurl/src/config-vxworks.h
@@ -80,21 +80,6 @@
/* Define if you want to enable IPv6 support */
#define ENABLE_IPV6 1
-/* Define to the type qualifier of arg 1 for getnameinfo. */
-#define GETNAMEINFO_QUAL_ARG1 const
-
-/* Define to the type of arg 1 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-
-/* Define to the type of arg 2 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG2 socklen_t
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG46 size_t
-
-/* Define to the type of arg 7 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG7 unsigned int
-
/* Specifies the number of arguments to getservbyport_r */
#define GETSERVBYPORT_R_ARGS 6
@@ -206,9 +191,6 @@
/* Define to 1 if you have a working getifaddrs function. */
/* #undef HAVE_GETIFADDRS */
-/* Define to 1 if you have the getnameinfo function. */
-#define HAVE_GETNAMEINFO 1
-
/* Define to 1 if you have the `getpass_r' function. */
/* #undef HAVE_GETPASS_R */
@@ -553,9 +535,6 @@
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
-/* Define to 1 if you have the `strlcpy' function. */
-/* #undef HAVE_STRLCPY */
-
/* Define to 1 if you have the strncmpi function. */
/* #undef HAVE_STRNCMPI */
diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h
index 98267a8033..fc81536835 100644
--- a/libs/libcurl/src/config-win32.h
+++ b/libs/libcurl/src/config-win32.h
@@ -246,10 +246,6 @@
/* Define if you have the socket function. */
#define HAVE_SOCKET 1
-/* Define if libSSH2 is in use */
-#define USE_LIBSSH2 1
-#define HAVE_LIBSSH2_H 1
-
/* Define if you have the strcasecmp function. */
#ifdef __MINGW32__
#define HAVE_STRCASECMP 1
@@ -281,21 +277,6 @@
#define HAVE_UTIME 1
#endif
-/* Define to the type qualifier of arg 1 for getnameinfo. */
-#define GETNAMEINFO_QUAL_ARG1 const
-
-/* Define to the type of arg 1 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-
-/* Define to the type of arg 2 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG2 socklen_t
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG46 DWORD
-
-/* Define to the type of arg 7 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG7 int
-
/* Define if you have the recv function. */
#define HAVE_RECV 1
@@ -423,7 +404,6 @@
# undef HAVE_WS2TCPIP_H
# undef HAVE_ERRNO_H
# undef HAVE_GETHOSTNAME
-# undef HAVE_GETNAMEINFO
# undef LWIP_POSIX_SOCKETS_IO_NAMES
# undef RECV_TYPE_ARG1
# undef RECV_TYPE_ARG3
@@ -454,7 +434,6 @@
#undef HAVE_WINSOCK2_H
#undef HAVE_WS2TCPIP_H
#define HAVE_GETADDRINFO
- #define HAVE_GETNAMEINFO
#define HAVE_SYS_IOCTL_H
#define HAVE_SYS_SOCKET_H
#define HAVE_NETINET_IN_H
@@ -584,7 +563,7 @@ Vista
# endif
#endif
-/* Availability of freeaddrinfo, getaddrinfo, getnameinfo and if_nametoindex
+/* Availability of freeaddrinfo, getaddrinfo, and if_nametoindex
functions is quite convoluted, compiler dependent and even build target
dependent. */
#if defined(HAVE_WS2TCPIP_H)
@@ -592,17 +571,14 @@ Vista
# define HAVE_FREEADDRINFO 1
# define HAVE_GETADDRINFO 1
# define HAVE_GETADDRINFO_THREADSAFE 1
-# define HAVE_GETNAMEINFO 1
# elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
# define HAVE_FREEADDRINFO 1
# define HAVE_GETADDRINFO 1
# define HAVE_GETADDRINFO_THREADSAFE 1
-# define HAVE_GETNAMEINFO 1
# elif defined(_MSC_VER) && (_MSC_VER >= 1200)
# define HAVE_FREEADDRINFO 1
# define HAVE_GETADDRINFO 1
# define HAVE_GETADDRINFO_THREADSAFE 1
-# define HAVE_GETNAMEINFO 1
# endif
#endif
@@ -712,9 +688,6 @@ Vista
# define CURL_DISABLE_LDAP 1
#endif
-/* if SSL is enabled */
-#define USE_OPENSSL 1
-
/* Define to use the Windows crypto library. */
#if !defined(CURL_WINDOWS_APP)
#define USE_WIN32_CRYPTO
diff --git a/libs/libcurl/src/config-win32ce.h b/libs/libcurl/src/config-win32ce.h
index fb29e088f6..44cc028874 100644
--- a/libs/libcurl/src/config-win32ce.h
+++ b/libs/libcurl/src/config-win32ce.h
@@ -219,24 +219,6 @@
/* Define if you have the utime function */
#define HAVE_UTIME 1
-/* Define if you have the getnameinfo function. */
-#define HAVE_GETNAMEINFO 1
-
-/* Define to the type qualifier of arg 1 for getnameinfo. */
-#define GETNAMEINFO_QUAL_ARG1 const
-
-/* Define to the type of arg 1 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-
-/* Define to the type of arg 2 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG2 socklen_t
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG46 DWORD
-
-/* Define to the type of arg 7 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG7 int
-
/* Define if you have the recv function. */
#define HAVE_RECV 1
diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c
index 296fb62503..d9317f3783 100644
--- a/libs/libcurl/src/connect.c
+++ b/libs/libcurl/src/connect.c
@@ -660,7 +660,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
#endif
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
case AF_UNIX:
- if(salen > (curl_socklen_t)sizeof(sa_family_t)) {
+ if(salen > (curl_socklen_t)sizeof(CURL_SA_FAMILY_T)) {
su = (struct sockaddr_un*)sa;
msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
}
@@ -1367,14 +1367,31 @@ CURLcode Curl_connecthost(struct Curl_easy *data,
conn->timeoutms_per_addr[1] =
conn->tempaddr[1]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
- conn->tempfamily[0] = conn->tempaddr[0]?
- conn->tempaddr[0]->ai_family:0;
+ if(conn->ip_version == CURL_IPRESOLVE_WHATEVER) {
+ /* any IP version is allowed */
+ conn->tempfamily[0] = conn->tempaddr[0]?
+ conn->tempaddr[0]->ai_family:0;
#ifdef ENABLE_IPV6
- conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ?
- AF_INET : AF_INET6;
+ conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ?
+ AF_INET : AF_INET6;
#else
- conn->tempfamily[1] = AF_UNSPEC;
+ conn->tempfamily[1] = AF_UNSPEC;
#endif
+ }
+ else {
+ /* only one IP version is allowed */
+ conn->tempfamily[0] = (conn->ip_version == CURL_IPRESOLVE_V4) ?
+ AF_INET :
+#ifdef ENABLE_IPV6
+ AF_INET6;
+#else
+ AF_UNSPEC;
+#endif
+ conn->tempfamily[1] = AF_UNSPEC;
+
+ ainext(conn, 0, FALSE); /* find first address of the right type */
+ }
+
ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */
DEBUGF(infof(data, "family0 == %s, family1 == %s\n",
diff --git a/libs/libcurl/src/content_encoding.c b/libs/libcurl/src/content_encoding.c
index f179b81796..a84ff543b9 100644
--- a/libs/libcurl/src/content_encoding.c
+++ b/libs/libcurl/src/content_encoding.c
@@ -178,7 +178,7 @@ static CURLcode inflate_stream(struct Curl_easy *data,
/* Dynamically allocate a buffer for decompression because it's uncommonly
large to hold on the stack */
decomp = malloc(DSIZ);
- if(decomp == NULL)
+ if(!decomp)
return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
/* because the buffer size is fixed, iteratively decompress and transfer to
@@ -487,7 +487,7 @@ static CURLcode gzip_unencode_write(struct Curl_easy *data,
*/
z->avail_in = (uInt) nbytes;
z->next_in = malloc(z->avail_in);
- if(z->next_in == NULL) {
+ if(!z->next_in) {
return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
}
memcpy(z->next_in, buf, z->avail_in);
@@ -509,7 +509,7 @@ static CURLcode gzip_unencode_write(struct Curl_easy *data,
ssize_t hlen;
z->avail_in += (uInt) nbytes;
z->next_in = Curl_saferealloc(z->next_in, z->avail_in);
- if(z->next_in == NULL) {
+ if(!z->next_in) {
return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
}
/* Append the new block of data to the previous one */
@@ -985,7 +985,8 @@ new_unencoding_writer(struct Curl_easy *data,
return writer;
}
-/* Write data using an unencoding writer stack. */
+/* Write data using an unencoding writer stack. "nbytes" is not
+ allowed to be 0. */
CURLcode Curl_unencode_write(struct Curl_easy *data,
struct contenc_writer *writer,
const char *buf, size_t nbytes)
diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c
index b85e5e921c..941623f9d2 100644
--- a/libs/libcurl/src/cookie.c
+++ b/libs/libcurl/src/cookie.c
@@ -105,6 +105,8 @@ Example set of cookies:
#include "curl_memory.h"
#include "memdebug.h"
+static void strstore(char **str, const char *newstr);
+
static void freecookie(struct Cookie *co)
{
free(co->expirestr);
@@ -129,12 +131,13 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
if(!strcasecompare(cooke_domain, hostname + hostname_len-cookie_domain_len))
return FALSE;
- /* A lead char of cookie_domain is not '.'.
- RFC6265 4.1.2.3. The Domain Attribute says:
- For example, if the value of the Domain attribute is
- "example.com", the user agent will include the cookie in the Cookie
- header when making HTTP requests to example.com, www.example.com, and
- www.corp.example.com.
+ /*
+ * A lead char of cookie_domain is not '.'.
+ * RFC6265 4.1.2.3. The Domain Attribute says:
+ * For example, if the value of the Domain attribute is
+ * "example.com", the user agent will include the cookie in the Cookie
+ * header when making HTTP requests to example.com, www.example.com, and
+ * www.corp.example.com.
*/
if(hostname_len == cookie_domain_len)
return TRUE;
@@ -144,7 +147,10 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
}
/*
- * Return true if the given string is an IP(v4|v6) address.
+ * isip
+ *
+ * Returns true if the given string is an IPv4 or IPv6 address (if IPv6 has
+ * been enabled while building libcurl, and false otherwise.
*/
static bool isip(const char *domain)
{
@@ -193,19 +199,19 @@ static bool pathmatch(const char *cookie_path, const char *request_uri)
/* #-fragments are already cut off! */
if(0 == strlen(uri_path) || uri_path[0] != '/') {
- free(uri_path);
- uri_path = strdup("/");
+ strstore(&uri_path, "/");
if(!uri_path)
return FALSE;
}
- /* here, RFC6265 5.1.4 says
- 4. Output the characters of the uri-path from the first character up
- to, but not including, the right-most %x2F ("/").
- but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site
- without redirect.
- Ignore this algorithm because /hoge is uri path for this case
- (uri path is not /).
+ /*
+ * here, RFC6265 5.1.4 says
+ * 4. Output the characters of the uri-path from the first character up
+ * to, but not including, the right-most %x2F ("/").
+ * but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site
+ * without redirect.
+ * Ignore this algorithm because /hoge is uri path for this case
+ * (uri path is not /).
*/
uri_path_len = strlen(uri_path);
@@ -328,8 +334,7 @@ static char *sanitize_cookie_path(const char *cookie_path)
/* RFC6265 5.2.4 The Path Attribute */
if(new_path[0] != '/') {
/* Let cookie-path be the default-path. */
- free(new_path);
- new_path = strdup("/");
+ strstore(&new_path, "/");
return new_path;
}
@@ -357,7 +362,8 @@ void Curl_cookie_loadfiles(struct Curl_easy *data)
data->cookies,
data->set.cookiesession);
if(!newcookies)
- /* Failure may be due to OOM or a bad cookie; both are ignored
+ /*
+ * Failure may be due to OOM or a bad cookie; both are ignored
* but only the first should be
*/
infof(data, "ignoring failed cookie_init for %s\n", list->data);
@@ -372,10 +378,13 @@ void Curl_cookie_loadfiles(struct Curl_easy *data)
}
/*
- * strstore() makes a strdup() on the 'newstr' and if '*str' is non-NULL
- * that will be freed before the allocated string is stored there.
+ * strstore
*
- * It is meant to easily replace strdup()
+ * A thin wrapper around strdup which ensures that any memory allocated at
+ * *str will be freed before the string allocated by strdup is stored there.
+ * The intended usecase is repeated assignments to the same variable during
+ * parsing in a last-wins scenario. The caller is responsible for checking
+ * for OOM errors.
*/
static void strstore(char **str, const char *newstr)
{
@@ -384,7 +393,11 @@ static void strstore(char **str, const char *newstr)
}
/*
- * remove_expired() removes expired cookies.
+ * remove_expired
+ *
+ * Remove expired cookies from the hash by inspecting the expires timestamp on
+ * each cookie in the hash, freeing and deleting any where the timestamp is in
+ * the past.
*/
static void remove_expired(struct CookieInfo *cookies)
{
@@ -421,25 +434,23 @@ static bool bad_domain(const char *domain)
return !strchr(domain, '.') && !strcasecompare(domain, "localhost");
}
-/****************************************************************************
- *
- * Curl_cookie_add()
- *
- * Add a single cookie line to the cookie keeping object.
+/*
+ * Curl_cookie_add
*
- * Be aware that sometimes we get an IP-only host name, and that might also be
- * a numerical IPv6 address.
+ * Add a single cookie line to the cookie keeping object. Be aware that
+ * sometimes we get an IP-only host name, and that might also be a numerical
+ * IPv6 address.
*
* Returns NULL on out of memory or invalid cookie. This is suboptimal,
* as they should be treated separately.
- ***************************************************************************/
-
+ */
struct Cookie *
Curl_cookie_add(struct Curl_easy *data,
- /* The 'data' pointer here may be NULL at times, and thus
- must only be used very carefully for things that can deal
- with data being NULL. Such as infof() and similar */
-
+ /*
+ * The 'data' pointer here may be NULL at times, and thus
+ * must only be used very carefully for things that can deal
+ * with data being NULL. Such as infof() and similar
+ */
struct CookieInfo *c,
bool httpheader, /* TRUE if HTTP header-style line */
bool noexpire, /* if TRUE, skip remove_expired() */
@@ -493,9 +504,11 @@ Curl_cookie_add(struct Curl_easy *data,
if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n=] =%"
MAX_NAME_TXT "[^;\r\n]",
name, what)) {
- /* Use strstore() below to properly deal with received cookie
- headers that have the same string property set more than once,
- and then we use the last one. */
+ /*
+ * Use strstore() below to properly deal with received cookie
+ * headers that have the same string property set more than once,
+ * and then we use the last one.
+ */
const char *whatptr;
bool done = FALSE;
bool sep;
@@ -503,11 +516,13 @@ Curl_cookie_add(struct Curl_easy *data,
size_t nlen = strlen(name);
const char *endofn = &ptr[ nlen ];
+ /*
+ * Check for too long individual name or contents, or too long
+ * combination of name + contents. Chrome and Firefox support 4095 or
+ * 4096 bytes combo
+ */
if(nlen >= (MAX_NAME-1) || len >= (MAX_NAME-1) ||
((nlen + len) > MAX_NAME)) {
- /* too long individual name or contents, or too long combination of
- name + contents. Chrome and Firefox support 4095 or 4096 bytes
- combo. */
freecookie(co);
infof(data, "oversized cookie dropped, name/val %zu + %zu bytes\n",
nlen, len);
@@ -569,8 +584,10 @@ Curl_cookie_add(struct Curl_easy *data,
}
}
else if(!len) {
- /* this was a "<name>=" with no content, and we must allow
- 'secure' and 'httponly' specified this weirdly */
+ /*
+ * this was a "<name>=" with no content, and we must allow
+ * 'secure' and 'httponly' specified this weirdly
+ */
done = TRUE;
/*
* secure cookies are only allowed to be set when the connection is
@@ -610,8 +627,10 @@ Curl_cookie_add(struct Curl_easy *data,
else if(strcasecompare("domain", name)) {
bool is_ip;
- /* Now, we make sure that our host is within the given domain,
- or the given domain is not valid and thus cannot be set. */
+ /*
+ * Now, we make sure that our host is within the given domain, or
+ * the given domain is not valid and thus cannot be set.
+ */
if('.' == whatptr[0])
whatptr++; /* ignore preceding dot */
@@ -641,9 +660,10 @@ Curl_cookie_add(struct Curl_easy *data,
given */
}
else {
- /* we did not get a tailmatch and then the attempted set domain
- is not a domain to which the current host belongs. Mark as
- bad. */
+ /*
+ * We did not get a tailmatch and then the attempted set domain is
+ * not a domain to which the current host belongs. Mark as bad.
+ */
badcookie = TRUE;
infof(data, "skipped cookie with bad tailmatch domain: %s\n",
whatptr);
@@ -657,15 +677,15 @@ Curl_cookie_add(struct Curl_easy *data,
}
}
else if(strcasecompare("max-age", name)) {
- /* Defined in RFC2109:
-
- Optional. The Max-Age attribute defines the lifetime of the
- cookie, in seconds. The delta-seconds value is a decimal non-
- negative integer. After delta-seconds seconds elapse, the
- client should discard the cookie. A value of zero means the
- cookie should be discarded immediately.
-
- */
+ /*
+ * Defined in RFC2109:
+ *
+ * Optional. The Max-Age attribute defines the lifetime of the
+ * cookie, in seconds. The delta-seconds value is a decimal non-
+ * negative integer. After delta-seconds seconds elapse, the
+ * client should discard the cookie. A value of zero means the
+ * cookie should be discarded immediately.
+ */
strstore(&co->maxage, whatptr);
if(!co->maxage) {
badcookie = TRUE;
@@ -679,9 +699,10 @@ Curl_cookie_add(struct Curl_easy *data,
break;
}
}
+
/*
- else this is the second (or more) name we don't know
- about! */
+ * Else, this is the second (or more) name we don't know about!
+ */
}
else {
/* this is an "illegal" <what>=<this> pair */
@@ -699,8 +720,10 @@ Curl_cookie_add(struct Curl_easy *data,
semiptr = strchr(ptr, ';'); /* now, find the next semicolon */
if(!semiptr && *ptr)
- /* There are no more semicolons, but there's a final name=value pair
- coming up */
+ /*
+ * There are no more semicolons, but there's a final name=value pair
+ * coming up
+ */
semiptr = strchr(ptr, '\0');
} while(semiptr);
@@ -724,13 +747,16 @@ Curl_cookie_add(struct Curl_easy *data,
}
}
else if(co->expirestr) {
- /* Note that if the date couldn't get parsed for whatever reason,
- the cookie will be treated as a session cookie */
+ /*
+ * Note that if the date couldn't get parsed for whatever reason, the
+ * cookie will be treated as a session cookie
+ */
co->expires = Curl_getdate_capped(co->expirestr);
- /* Session cookies have expires set to 0 so if we get that back
- from the date parser let's add a second to make it a
- non-session cookie */
+ /*
+ * Session cookies have expires set to 0 so if we get that back from the
+ * date parser let's add a second to make it a non-session cookie
+ */
if(co->expires == 0)
co->expires = 1;
else if(co->expires < 0)
@@ -747,13 +773,17 @@ Curl_cookie_add(struct Curl_easy *data,
}
if(!badcookie && !co->path && path) {
- /* No path was given in the header line, set the default.
- Note that the passed-in path to this function MAY have a '?' and
- following part that MUST not be stored as part of the path. */
+ /*
+ * No path was given in the header line, set the default. Note that the
+ * passed-in path to this function MAY have a '?' and following part that
+ * MUST NOT be stored as part of the path.
+ */
char *queryp = strchr(path, '?');
- /* queryp is where the interesting part of the path ends, so now we
- want to the find the last */
+ /*
+ * queryp is where the interesting part of the path ends, so now we
+ * want to the find the last
+ */
char *endslash;
if(!queryp)
endslash = strrchr(path, '/');
@@ -774,29 +804,34 @@ Curl_cookie_add(struct Curl_easy *data,
}
}
+ /*
+ * If we didn't get a cookie name, or a bad one, the this is an illegal
+ * line so bail out.
+ */
if(badcookie || !co->name) {
- /* we didn't get a cookie name or a bad one,
- this is an illegal line, bail out */
freecookie(co);
return NULL;
}
}
else {
- /* This line is NOT a HTTP header style line, we do offer support for
- reading the odd netscape cookies-file format here */
+ /*
+ * This line is NOT a HTTP header style line, we do offer support for
+ * reading the odd netscape cookies-file format here
+ */
char *ptr;
char *firstptr;
char *tok_buf = NULL;
int fields;
- /* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies
- marked with httpOnly after the domain name are not accessible
- from javascripts, but since curl does not operate at javascript
- level, we include them anyway. In Firefox's cookie files, these
- lines are preceded with #HttpOnly_ and then everything is
- as usual, so we skip 10 characters of the line..
- */
+ /*
+ * IE introduced HTTP-only cookies to prevent XSS attacks. Cookies marked
+ * with httpOnly after the domain name are not accessible from javascripts,
+ * but since curl does not operate at javascript level, we include them
+ * anyway. In Firefox's cookie files, these lines are preceded with
+ * #HttpOnly_ and then everything is as usual, so we skip 10 characters of
+ * the line..
+ */
if(strncmp(lineptr, "#HttpOnly_", 10) == 0) {
lineptr += 10;
co->httponly = TRUE;
@@ -817,8 +852,10 @@ Curl_cookie_add(struct Curl_easy *data,
firstptr = strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
- /* Now loop through the fields and init the struct we already have
- allocated */
+ /*
+ * Now loop through the fields and init the struct we already have
+ * allocated
+ */
for(ptr = firstptr, fields = 0; ptr && !badcookie;
ptr = strtok_r(NULL, "\t", &tok_buf), fields++) {
switch(fields) {
@@ -830,10 +867,11 @@ Curl_cookie_add(struct Curl_easy *data,
badcookie = TRUE;
break;
case 1:
- /* flag: A TRUE/FALSE value indicating if all machines within a given
- domain can access the variable. Set TRUE when the cookie says
- .domain.com and to false when the domain is complete www.domain.com
- */
+ /*
+ * flag: A TRUE/FALSE value indicating if all machines within a given
+ * domain can access the variable. Set TRUE when the cookie says
+ * .domain.com and to false when the domain is complete www.domain.com
+ */
co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
break;
case 2:
@@ -942,9 +980,11 @@ Curl_cookie_add(struct Curl_easy *data,
co->livecookie = c->running;
co->creationtime = ++c->lastct;
- /* now, we have parsed the incoming line, we must now check if this
- supersedes an already existing cookie, which it may if the previous have
- the same domain and path as this */
+ /*
+ * Now we have parsed the incoming line, we must now check if this supersedes
+ * an already existing cookie, which it may if the previous have the same
+ * domain and path as this.
+ */
/* at first, remove expired cookies */
if(!noexpire)
@@ -1032,12 +1072,12 @@ Curl_cookie_add(struct Curl_easy *data,
}
if(replace_old && !co->livecookie && clist->livecookie) {
- /* Both cookies matched fine, except that the already present
- cookie is "live", which means it was set from a header, while
- the new one isn't "live" and thus only read from a file. We let
- live cookies stay alive */
-
- /* Free the newcomer and get out of here! */
+ /*
+ * Both cookies matched fine, except that the already present cookie is
+ * "live", which means it was set from a header, while the new one was
+ * read from a file and thus isn't "live". "live" cookies are preferred
+ * so the new cookie is freed.
+ */
freecookie(co);
return NULL;
}
@@ -1063,8 +1103,10 @@ Curl_cookie_add(struct Curl_easy *data,
free(co); /* free the newly allocated memory */
co = clist; /* point to the previous struct instead */
- /* We have replaced a cookie, now skip the rest of the list but
- make sure the 'lastc' pointer is properly set */
+ /*
+ * We have replaced a cookie, now skip the rest of the list but make
+ * sure the 'lastc' pointer is properly set
+ */
do {
lastc = clist;
clist = clist->next;
@@ -1096,19 +1138,19 @@ Curl_cookie_add(struct Curl_easy *data,
}
-/*****************************************************************************
- *
+/*
* Curl_cookie_init()
*
* Inits a cookie struct to read data from a local file. This is always
- * called before any cookies are set. File may be NULL.
+ * called before any cookies are set. File may be NULL in which case only the
+ * struct is initialized. Is file is "-" then STDIN is read.
*
* If 'newsession' is TRUE, discard all "session cookies" on read from file.
*
* Note that 'data' might be called as NULL pointer.
*
* Returns NULL on out of memory. Invalid cookies are ignored.
- ****************************************************************************/
+ */
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
const char *file,
struct CookieInfo *inc,
@@ -1170,7 +1212,12 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
Curl_cookie_add(data, c, headerline, TRUE, lineptr, NULL, NULL, TRUE);
}
free(line); /* free the line buffer */
- remove_expired(c); /* run this once, not on every cookie */
+
+ /*
+ * Remove expired cookies from the hash. We must make sure to run this
+ * after reading the file, and not not on every cookie.
+ */
+ remove_expired(c);
if(fromfile)
fclose(fp);
@@ -1184,16 +1231,24 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
fail:
free(line);
+ /*
+ * Only clean up if we allocated it here, as the original could still be in
+ * use by a share handle.
+ */
if(!inc)
- /* Only clean up if we allocated it here, as the original could still be in
- * use by a share handle */
Curl_cookie_cleanup(c);
if(fromfile && fp)
fclose(fp);
return NULL; /* out of memory */
}
-/* sort this so that the longest path gets before the shorter path */
+/*
+ * cookie_sort
+ *
+ * Helper function to sort cookies such that the longest path gets before the
+ * shorter path. Path, domain and name lengths are considered in that order,
+ * with tge creationtime as the tiebreaker.
+ */
static int cookie_sort(const void *p1, const void *p2)
{
struct Cookie *c1 = *(struct Cookie **)p1;
@@ -1225,7 +1280,11 @@ static int cookie_sort(const void *p1, const void *p2)
return (c2->creationtime > c1->creationtime) ? 1 : -1;
}
-/* sort cookies only according to creation time */
+/*
+ * cookie_sort_ct
+ *
+ * Helper function to sort cookies according to creation time.
+ */
static int cookie_sort_ct(const void *p1, const void *p2)
{
struct Cookie *c1 = *(struct Cookie **)p1;
@@ -1269,18 +1328,15 @@ static struct Cookie *dup_cookie(struct Cookie *src)
return NULL;
}
-/*****************************************************************************
- *
- * Curl_cookie_getlist()
+/*
+ * Curl_cookie_getlist
*
- * For a given host and path, return a linked list of cookies that the
- * client should send to the server if used now. The secure boolean informs
- * the cookie if a secure connection is achieved or not.
+ * For a given host and path, return a linked list of cookies that the client
+ * should send to the server if used now. The secure boolean informs the cookie
+ * if a secure connection is achieved or not.
*
* It shall only return cookies that haven't expired.
- *
- ****************************************************************************/
-
+ */
struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
const char *host, const char *path,
bool secure)
@@ -1311,15 +1367,21 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
if(!co->domain ||
(co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
- /* the right part of the host matches the domain stuff in the
- cookie data */
+ /*
+ * the right part of the host matches the domain stuff in the
+ * cookie data
+ */
- /* now check the left part of the path with the cookies path
- requirement */
+ /*
+ * now check the left part of the path with the cookies path
+ * requirement
+ */
if(!co->spath || pathmatch(co->spath, path) ) {
- /* and now, we know this is a match and we should create an
- entry for the return-linked-list */
+ /*
+ * and now, we know this is a match and we should create an
+ * entry for the return-linked-list
+ */
newco = dup_cookie(co);
if(newco) {
@@ -1340,9 +1402,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
}
if(matches) {
- /* Now we need to make sure that if there is a name appearing more than
- once, the longest specified path version comes first. To make this
- the swiftest way, we just sort them all based on path length. */
+ /*
+ * Now we need to make sure that if there is a name appearing more than
+ * once, the longest specified path version comes first. To make this
+ * the swiftest way, we just sort them all based on path length.
+ */
struct Cookie **array;
size_t i;
@@ -1377,13 +1441,11 @@ fail:
return NULL;
}
-/*****************************************************************************
- *
- * Curl_cookie_clearall()
+/*
+ * Curl_cookie_clearall
*
* Clear all existing cookies and reset the counter.
- *
- ****************************************************************************/
+ */
void Curl_cookie_clearall(struct CookieInfo *cookies)
{
if(cookies) {
@@ -1396,14 +1458,11 @@ void Curl_cookie_clearall(struct CookieInfo *cookies)
}
}
-/*****************************************************************************
- *
- * Curl_cookie_freelist()
+/*
+ * Curl_cookie_freelist
*
* Free a list of cookies previously returned by Curl_cookie_getlist();
- *
- ****************************************************************************/
-
+ */
void Curl_cookie_freelist(struct Cookie *co)
{
struct Cookie *next;
@@ -1414,14 +1473,11 @@ void Curl_cookie_freelist(struct Cookie *co)
}
}
-
-/*****************************************************************************
- *
- * Curl_cookie_clearsess()
+/*
+ * Curl_cookie_clearsess
*
* Free all session cookies in the cookies list.
- *
- ****************************************************************************/
+ */
void Curl_cookie_clearsess(struct CookieInfo *cookies)
{
struct Cookie *first, *curr, *next, *prev = NULL;
@@ -1458,14 +1514,11 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies)
}
}
-
-/*****************************************************************************
- *
+/*
* Curl_cookie_cleanup()
*
* Free a "cookie object" previous created with Curl_cookie_init().
- *
- ****************************************************************************/
+ */
void Curl_cookie_cleanup(struct CookieInfo *c)
{
if(c) {
@@ -1477,12 +1530,13 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
}
}
-/* get_netscape_format()
+/*
+ * get_netscape_format()
*
* Formats a string for Netscape output file, w/o a newline at the end.
- *
- * Function returns a char * to a formatted line. Has to be free()d
-*/
+ * Function returns a char * to a formatted line. The caller is responsible
+ * for freeing the returned pointer.
+ */
static char *get_netscape_format(const struct Cookie *co)
{
return aprintf(
@@ -1495,8 +1549,10 @@ static char *get_netscape_format(const struct Cookie *co)
"%s\t" /* name */
"%s", /* value */
co->httponly?"#HttpOnly_":"",
- /* Make sure all domains are prefixed with a dot if they allow
- tailmatching. This is Mozilla-style. */
+ /*
+ * Make sure all domains are prefixed with a dot if they allow
+ * tailmatching. This is Mozilla-style.
+ */
(co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
co->domain?co->domain:"unknown",
co->tailmatch?"TRUE":"FALSE",
@@ -1515,18 +1571,18 @@ static char *get_netscape_format(const struct Cookie *co)
*
* The function returns non-zero on write failure.
*/
-static int cookie_output(struct Curl_easy *data,
- struct CookieInfo *c, const char *filename)
+static CURLcode cookie_output(struct Curl_easy *data,
+ struct CookieInfo *c, const char *filename)
{
struct Cookie *co;
FILE *out = NULL;
bool use_stdout = FALSE;
char *tempstore = NULL;
- bool error = false;
+ CURLcode error = CURLE_OK;
if(!c)
/* no cookie engine alive */
- return 0;
+ return CURLE_OK;
/* at first, remove expired cookies */
remove_expired(c);
@@ -1544,11 +1600,13 @@ static int cookie_output(struct Curl_easy *data,
tempstore = aprintf("%s.%s.tmp", filename, randsuffix);
if(!tempstore)
- return 1;
+ return CURLE_OUT_OF_MEMORY;
out = fopen(tempstore, FOPEN_WRITETEXT);
- if(!out)
+ if(!out) {
+ error = CURLE_WRITE_ERROR;
goto error;
+ }
}
fputs("# Netscape HTTP Cookie File\n"
@@ -1563,6 +1621,7 @@ static int cookie_output(struct Curl_easy *data,
array = calloc(1, sizeof(struct Cookie *) * c->numcookies);
if(!array) {
+ error = CURLE_OUT_OF_MEMORY;
goto error;
}
@@ -1579,9 +1638,9 @@ static int cookie_output(struct Curl_easy *data,
for(i = 0; i < nvalid; i++) {
char *format_ptr = get_netscape_format(array[i]);
- if(format_ptr == NULL) {
- fprintf(out, "#\n# Fatal libcurl error\n");
+ if(!format_ptr) {
free(array);
+ error = CURLE_OUT_OF_MEMORY;
goto error;
}
fprintf(out, "%s\n", format_ptr);
@@ -1596,18 +1655,24 @@ static int cookie_output(struct Curl_easy *data,
out = NULL;
if(Curl_rename(tempstore, filename)) {
unlink(tempstore);
+ error = CURLE_WRITE_ERROR;
goto error;
}
}
- goto cleanup;
+ /*
+ * If we reach here we have successfully written a cookie file so theree is
+ * no need to inspect the error, any error case should have jumped into the
+ * error block below.
+ */
+ free(tempstore);
+ return CURLE_OK;
+
error:
- error = true;
-cleanup:
if(out && !use_stdout)
fclose(out);
free(tempstore);
- return error ? 1 : 0;
+ return error;
}
static struct curl_slist *cookie_list(struct Curl_easy *data)
@@ -1618,8 +1683,7 @@ static struct curl_slist *cookie_list(struct Curl_easy *data)
char *line;
unsigned int i;
- if((data->cookies == NULL) ||
- (data->cookies->numcookies == 0))
+ if(!data->cookies || (data->cookies->numcookies == 0))
return NULL;
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
@@ -1655,6 +1719,8 @@ struct curl_slist *Curl_cookie_list(struct Curl_easy *data)
void Curl_flush_cookies(struct Curl_easy *data, bool cleanup)
{
+ CURLcode res;
+
if(data->set.str[STRING_COOKIEJAR]) {
if(data->state.cookielist) {
/* If there is a list of cookie files to read, do it first so that
@@ -1666,9 +1732,10 @@ void Curl_flush_cookies(struct Curl_easy *data, bool cleanup)
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
/* if we have a destination file for all the cookies to get dumped to */
- if(cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR]))
- infof(data, "WARNING: failed to save cookies in %s\n",
- data->set.str[STRING_COOKIEJAR]);
+ res = cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR]);
+ if(res)
+ infof(data, "WARNING: failed to save cookies in %s: %s\n",
+ data->set.str[STRING_COOKIEJAR], curl_easy_strerror(res));
}
else {
if(cleanup && data->state.cookielist) {
diff --git a/libs/libcurl/src/curl_addrinfo.c b/libs/libcurl/src/curl_addrinfo.c
index 06537b275f..1d5067bc00 100644
--- a/libs/libcurl/src/curl_addrinfo.c
+++ b/libs/libcurl/src/curl_addrinfo.c
@@ -50,6 +50,12 @@
# define in_addr_t unsigned long
#endif
+#if defined(USE_UNIX_SOCKETS) && defined(WINAPI_FAMILY) && \
+ (WINAPI_FAMILY == WINAPI_FAMILY_APP)
+ /* Required for sockaddr_un type */
+# include <afunix.h>
+#endif
+
#include <stddef.h>
#include "curl_addrinfo.h"
@@ -141,7 +147,7 @@ Curl_getaddrinfo_ex(const char *nodename,
continue;
/* ignore elements without required address info */
- if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0))
+ if(!ai->ai_addr || !(ai->ai_addrlen > 0))
continue;
/* ignore elements with bogus address size */
diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake
index fbe17bc5b0..96a19afc51 100644
--- a/libs/libcurl/src/curl_config.h.cmake
+++ b/libs/libcurl/src/curl_config.h.cmake
@@ -112,21 +112,6 @@
/* Define if you want to enable IPv6 support */
#cmakedefine ENABLE_IPV6 1
-/* Define to the type qualifier of arg 1 for getnameinfo. */
-#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1}
-
-/* Define to the type of arg 1 for getnameinfo. */
-#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1}
-
-/* Define to the type of arg 2 for getnameinfo. */
-#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2}
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46}
-
-/* Define to the type of arg 7 for getnameinfo. */
-#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7}
-
/* Specifies the number of arguments to getservbyport_r */
#cmakedefine GETSERVBYPORT_R_ARGS ${GETSERVBYPORT_R_ARGS}
@@ -208,6 +193,9 @@
/* Define to 1 if you have the `geteuid' function. */
#cmakedefine HAVE_GETEUID 1
+/* Define to 1 if you have the `getppid' function. */
+#cmakedefine HAVE_GETPPID 1
+
/* Define to 1 if you have the gethostbyaddr function. */
#cmakedefine HAVE_GETHOSTBYADDR 1
@@ -244,9 +232,6 @@
/* Define to 1 if you have a working getifaddrs function. */
#cmakedefine HAVE_GETIFADDRS 1
-/* Define to 1 if you have the getnameinfo function. */
-#cmakedefine HAVE_GETNAMEINFO 1
-
/* Define to 1 if you have the `getpass_r' function. */
#cmakedefine HAVE_GETPASS_R 1
@@ -328,6 +313,12 @@
/* Define to 1 if you have a IPv6 capable working inet_pton function. */
#cmakedefine HAVE_INET_PTON 1
+/* Define to 1 if symbol `sa_family_t' exists */
+#cmakedefine HAVE_SA_FAMILY_T 1
+
+/* Define to 1 if symbol `ADDRESS_FAMILY' exists */
+#cmakedefine HAVE_ADDRESS_FAMILY 1
+
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
@@ -500,9 +491,6 @@
/* Define to 1 if you have the <pem.h> header file. */
#cmakedefine HAVE_PEM_H 1
-/* Define to 1 if you have the `perror' function. */
-#cmakedefine HAVE_PERROR 1
-
/* Define to 1 if you have the `pipe' function. */
#cmakedefine HAVE_PIPE 1
@@ -644,12 +632,6 @@
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H 1
-/* Define to 1 if you have the strlcat function. */
-#cmakedefine HAVE_STRLCAT 1
-
-/* Define to 1 if you have the `strlcpy' function. */
-#cmakedefine HAVE_STRLCPY 1
-
/* Define to 1 if you have the strncmpi function. */
#cmakedefine HAVE_STRNCMPI 1
@@ -740,6 +722,9 @@
/* Define to 1 if you have the `utime' function. */
#cmakedefine HAVE_UTIME 1
+/* Define to 1 if you have the `utimes' function. */
+#cmakedefine HAVE_UTIMES 1
+
/* Define to 1 if you have the <utime.h> header file. */
#cmakedefine HAVE_UTIME_H 1
diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in
index ae942fbfb8..d5f8ba9b00 100644
--- a/libs/libcurl/src/curl_config.h.in
+++ b/libs/libcurl/src/curl_config.h.in
@@ -42,6 +42,9 @@
/* to disable Gopher */
#undef CURL_DISABLE_GOPHER
+/* disable alt-svc */
+#undef CURL_DISABLE_HSTS
+
/* to disable HTTP */
#undef CURL_DISABLE_HTTP
@@ -807,9 +810,6 @@
/* Define to 1 if you have the <wolfssh/ssh.h> header file. */
#undef HAVE_WOLFSSH_SSH_H
-/* Define to 1 if you have the `wolfSSLv3_client_method' function. */
-#undef HAVE_WOLFSSLV3_CLIENT_METHOD
-
/* if you have wolfSSL_DES_ecb_encrypt */
#undef HAVE_WOLFSSL_DES_ECB_ENCRYPT
@@ -987,9 +987,6 @@
/* GSASL support enabled */
#undef USE_GSASL
-/* to enable HSTS */
-#undef USE_HSTS
-
/* if hyper is in use */
#undef USE_HYPER
diff --git a/libs/libcurl/src/curl_get_line.c b/libs/libcurl/src/curl_get_line.c
index 438ede7046..8f3b0bd8c1 100644
--- a/libs/libcurl/src/curl_get_line.c
+++ b/libs/libcurl/src/curl_get_line.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -23,7 +23,7 @@
#include "curl_setup.h"
#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
- defined(USE_HSTS)
+ !defined(CURL_DISABLE_HSTS)
#include "curl_get_line.h"
#include "curl_memory.h"
diff --git a/libs/libcurl/src/curl_gssapi.c b/libs/libcurl/src/curl_gssapi.c
index 6445fbad09..acaaa1c683 100644
--- a/libs/libcurl/src/curl_gssapi.c
+++ b/libs/libcurl/src/curl_gssapi.c
@@ -102,7 +102,7 @@ static size_t display_gss_error(OM_uint32 status, int type,
(char *)status_string.value);
}
gss_release_buffer(&min_stat, &status_string);
- } while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
+ } while(!GSS_ERROR(maj_stat) && msg_ctx);
return len;
}
diff --git a/libs/libcurl/src/curl_krb5.h b/libs/libcurl/src/curl_krb5.h
index 3f40f9a6ca..ca06840742 100644
--- a/libs/libcurl/src/curl_krb5.h
+++ b/libs/libcurl/src/curl_krb5.h
@@ -29,7 +29,6 @@ struct Curl_sec_client_mech {
int (*auth)(void *, struct Curl_easy *data, struct connectdata *);
void (*end)(void *);
int (*check_prot)(void *, int);
- int (*overhead)(void *, int, int);
int (*encode)(void *, const void *, int, int, void **);
int (*decode)(void *, void *, int, int, struct connectdata *);
};
diff --git a/libs/libcurl/src/curl_path.c b/libs/libcurl/src/curl_path.c
index 6100d77bd9..65106188c7 100644
--- a/libs/libcurl/src/curl_path.c
+++ b/libs/libcurl/src/curl_path.c
@@ -48,7 +48,7 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data,
/* Check for /~/, indicating relative to the user's home directory */
if(data->conn->handler->protocol & CURLPROTO_SCP) {
real_path = malloc(working_path_len + 1);
- if(real_path == NULL) {
+ if(!real_path) {
free(working_path);
return CURLE_OUT_OF_MEMORY;
}
@@ -62,7 +62,7 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data,
if((working_path_len > 1) && (working_path[1] == '~')) {
size_t homelen = strlen(homedir);
real_path = malloc(homelen + working_path_len + 1);
- if(real_path == NULL) {
+ if(!real_path) {
free(working_path);
return CURLE_OUT_OF_MEMORY;
}
@@ -78,7 +78,7 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data,
}
else {
real_path = malloc(working_path_len + 1);
- if(real_path == NULL) {
+ if(!real_path) {
free(working_path);
return CURLE_OUT_OF_MEMORY;
}
@@ -130,7 +130,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
/* Allocate enough space for home directory and filename + separator */
fullPathLength = strlen(cp) + strlen(homedir) + 2;
*path = malloc(fullPathLength);
- if(*path == NULL)
+ if(!*path)
return CURLE_OUT_OF_MEMORY;
/* Check for quoted filenames */
@@ -169,7 +169,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
else {
/* Read to end of filename - either to whitespace or terminator */
end = strpbrk(cp, WHITESPACE);
- if(end == NULL)
+ if(!end)
end = strchr(cp, '\0');
/* return pointer to second parameter if it exists */
*cpp = end + strspn(end, WHITESPACE);
diff --git a/libs/libcurl/src/curl_rtmp.c b/libs/libcurl/src/curl_rtmp.c
index 1360f335fc..2fa026796e 100644
--- a/libs/libcurl/src/curl_rtmp.c
+++ b/libs/libcurl/src/curl_rtmp.c
@@ -79,6 +79,7 @@ const struct Curl_handler Curl_handler_rtmp = {
rtmp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_RTMP, /* defport */
CURLPROTO_RTMP, /* protocol */
CURLPROTO_RTMP, /* family */
@@ -101,6 +102,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
rtmp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_RTMPT, /* defport */
CURLPROTO_RTMPT, /* protocol */
CURLPROTO_RTMPT, /* family */
@@ -123,6 +125,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
rtmp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_RTMP, /* defport */
CURLPROTO_RTMPE, /* protocol */
CURLPROTO_RTMPE, /* family */
@@ -145,6 +148,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
rtmp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_RTMPT, /* defport */
CURLPROTO_RTMPTE, /* protocol */
CURLPROTO_RTMPTE, /* family */
@@ -167,6 +171,7 @@ const struct Curl_handler Curl_handler_rtmps = {
rtmp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_RTMPS, /* defport */
CURLPROTO_RTMPS, /* protocol */
CURLPROTO_RTMP, /* family */
@@ -189,6 +194,7 @@ const struct Curl_handler Curl_handler_rtmpts = {
rtmp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_RTMPS, /* defport */
CURLPROTO_RTMPTS, /* protocol */
CURLPROTO_RTMPT, /* family */
diff --git a/libs/libcurl/src/curl_sasl.c b/libs/libcurl/src/curl_sasl.c
index 2cba185470..a4d1059cb9 100644
--- a/libs/libcurl/src/curl_sasl.c
+++ b/libs/libcurl/src/curl_sasl.c
@@ -58,7 +58,7 @@
static const struct {
const char *name; /* Name */
size_t len; /* Name length */
- unsigned int bit; /* Flag bit */
+ unsigned short bit; /* Flag bit */
} mechtable[] = {
{ "LOGIN", 5, SASL_MECH_LOGIN },
{ "PLAIN", 5, SASL_MECH_PLAIN },
@@ -128,7 +128,8 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
*
* Returns the SASL mechanism token or 0 if no match.
*/
-unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len)
+unsigned short Curl_sasl_decode_mech(const char *ptr, size_t maxlen,
+ size_t *len)
{
unsigned int i;
char c;
@@ -173,7 +174,7 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
if(!strncmp(value, "*", len))
sasl->prefmech = SASL_AUTH_DEFAULT;
else {
- unsigned int mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
+ unsigned short mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
if(mechbit && mechlen == len)
sasl->prefmech |= mechbit;
else
@@ -242,6 +243,49 @@ static void state(struct SASL *sasl, struct Curl_easy *data,
sasl->state = newstate;
}
+/* Get the SASL server message and convert it to binary. */
+static CURLcode get_server_message(struct SASL *sasl, struct Curl_easy *data,
+ struct bufref *out)
+{
+ unsigned char *msg;
+ size_t msglen;
+ char *serverdata = NULL;
+ CURLcode result = CURLE_OK;
+
+ sasl->params->getmessage(data->state.buffer, &serverdata);
+ if(!serverdata)
+ result = CURLE_BAD_CONTENT_ENCODING;
+ else if(!*serverdata || *serverdata == '=')
+ Curl_bufref_set(out, NULL, 0, NULL);
+ else {
+ result = Curl_base64_decode(serverdata, &msg, &msglen);
+ if(!result)
+ Curl_bufref_set(out, msg, msglen, curl_free);
+ }
+ return result;
+}
+
+/* Encode the outgoing SASL message. */
+static CURLcode build_message(struct Curl_easy *data, struct bufref *msg)
+{
+ CURLcode result = CURLE_OK;
+ char *base64;
+ size_t base64len;
+
+ if(!Curl_bufref_ptr(msg)) /* Empty mesage. */
+ Curl_bufref_set(msg, "", 0, NULL);
+ else if(!Curl_bufref_len(msg)) /* Explicit empty response. */
+ Curl_bufref_set(msg, "=", 1, NULL);
+ else {
+ result = Curl_base64_encode(data, (const char *) Curl_bufref_ptr(msg),
+ Curl_bufref_len(msg), &base64, &base64len);
+ if(!result)
+ Curl_bufref_set(msg, base64, base64len, curl_free);
+ }
+
+ return result;
+}
+
/*
* Curl_sasl_can_authenticate()
*
@@ -272,25 +316,21 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
CURLcode result = CURLE_OK;
unsigned int enabledmechs;
const char *mech = NULL;
- char *resp = NULL;
- size_t len = 0;
+ struct bufref resp;
saslstate state1 = SASL_STOP;
saslstate state2 = SASL_FINAL;
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
- const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
-#else
- const char * const hostname = conn->host.name;
- const long int port = conn->remote_port;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
+ const long int port = SSL_HOST_PORT();
#if defined(USE_KERBEROS5) || defined(USE_NTLM)
const char *service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] :
sasl->params->service;
#endif
const char *oauth_bearer = data->set.str[STRING_BEARER];
+ struct bufref nullmsg;
+ Curl_bufref_init(&nullmsg);
+ Curl_bufref_init(&resp);
sasl->force_ir = force_ir; /* Latch for future use */
sasl->authused = 0; /* No mechanism used yet */
enabledmechs = sasl->authmechs & sasl->prefmech;
@@ -304,8 +344,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
sasl->authused = SASL_MECH_EXTERNAL;
if(force_ir || data->set.sasl_ir)
- result = Curl_auth_create_external_message(data, conn->user, &resp,
- &len);
+ result = Curl_auth_create_external_message(conn->user, &resp);
}
else if(conn->bits.user_passwd) {
#if defined(USE_KERBEROS5)
@@ -321,10 +360,10 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
result = Curl_auth_create_gssapi_user_message(data, conn->user,
conn->passwd,
service,
- data->conn->host.name,
+ conn->host.name,
sasl->mutual_auth,
NULL, &conn->krb5,
- &resp, &len);
+ &resp);
}
else
#endif
@@ -340,8 +379,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
result = Curl_auth_gsasl_start(data, conn->user,
conn->passwd, &conn->gsasl);
if(result == CURLE_OK && (force_ir || data->set.sasl_ir))
- result = Curl_auth_gsasl_token(data, NULL, &conn->gsasl,
- &resp, &len);
+ result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp);
}
else if((enabledmechs & SASL_MECH_SCRAM_SHA_1) &&
Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1,
@@ -354,8 +392,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
result = Curl_auth_gsasl_start(data, conn->user,
conn->passwd, &conn->gsasl);
if(result == CURLE_OK && (force_ir || data->set.sasl_ir))
- result = Curl_auth_gsasl_token(data, NULL, &conn->gsasl,
- &resp, &len);
+ result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp);
}
else
#endif
@@ -385,8 +422,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
conn->user, conn->passwd,
service,
hostname,
- &conn->ntlm, &resp,
- &len);
+ &conn->ntlm, &resp);
}
else
#endif
@@ -397,11 +433,11 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
sasl->authused = SASL_MECH_OAUTHBEARER;
if(force_ir || data->set.sasl_ir)
- result = Curl_auth_create_oauth_bearer_message(data, conn->user,
+ result = Curl_auth_create_oauth_bearer_message(conn->user,
hostname,
port,
oauth_bearer,
- &resp, &len);
+ &resp);
}
else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) {
mech = SASL_MECH_STRING_XOAUTH2;
@@ -409,9 +445,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
sasl->authused = SASL_MECH_XOAUTH2;
if(force_ir || data->set.sasl_ir)
- result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
+ result = Curl_auth_create_xoauth_bearer_message(conn->user,
oauth_bearer,
- &resp, &len);
+ &resp);
}
else if(enabledmechs & SASL_MECH_PLAIN) {
mech = SASL_MECH_STRING_PLAIN;
@@ -419,9 +455,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
sasl->authused = SASL_MECH_PLAIN;
if(force_ir || data->set.sasl_ir)
- result = Curl_auth_create_plain_message(data, conn->sasl_authzid,
+ result = Curl_auth_create_plain_message(conn->sasl_authzid,
conn->user, conn->passwd,
- &resp, &len);
+ &resp);
}
else if(enabledmechs & SASL_MECH_LOGIN) {
mech = SASL_MECH_STRING_LOGIN;
@@ -430,26 +466,29 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
sasl->authused = SASL_MECH_LOGIN;
if(force_ir || data->set.sasl_ir)
- result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
+ result = Curl_auth_create_login_message(conn->user, &resp);
}
}
if(!result && mech) {
- if(resp && sasl->params->maxirlen &&
- strlen(mech) + len > sasl->params->maxirlen) {
- free(resp);
- resp = NULL;
- }
+ if(Curl_bufref_ptr(&resp))
+ result = build_message(data, &resp);
+
+ if(sasl->params->maxirlen &&
+ strlen(mech) + Curl_bufref_len(&resp) > sasl->params->maxirlen)
+ Curl_bufref_free(&resp);
+
+ if(!result)
+ result = sasl->params->sendauth(data, conn, mech,
+ (const char *) Curl_bufref_ptr(&resp));
- result = sasl->params->sendauth(data, conn, mech, resp);
if(!result) {
*progress = SASL_INPROGRESS;
- state(sasl, data, resp ? state2 : state1);
+ state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1);
}
}
- free(resp);
-
+ Curl_bufref_free(&resp);
return result;
}
@@ -464,29 +503,20 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
{
CURLcode result = CURLE_OK;
saslstate newstate = SASL_FINAL;
- char *resp = NULL;
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
- const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
-#else
- const char * const hostname = conn->host.name;
- const long int port = conn->remote_port;
-#endif
-#if !defined(CURL_DISABLE_CRYPTO_AUTH)
- char *chlg = NULL;
- size_t chlglen = 0;
-#endif
+ struct bufref resp;
+ const char * const hostname = SSL_HOST_NAME();
+ const long int port = SSL_HOST_PORT();
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
defined(USE_NTLM)
const char *service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] :
sasl->params->service;
- char *serverdata;
#endif
- size_t len = 0;
const char *oauth_bearer = data->set.str[STRING_BEARER];
+ struct bufref serverdata;
+ Curl_bufref_init(&serverdata);
+ Curl_bufref_init(&resp);
*progress = SASL_INPROGRESS;
if(sasl->state == SASL_FINAL) {
@@ -509,50 +539,45 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
*progress = SASL_DONE;
return result;
case SASL_PLAIN:
- result = Curl_auth_create_plain_message(data, conn->sasl_authzid,
- conn->user, conn->passwd,
- &resp, &len);
+ result = Curl_auth_create_plain_message(conn->sasl_authzid,
+ conn->user, conn->passwd, &resp);
break;
case SASL_LOGIN:
- result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
+ result = Curl_auth_create_login_message(conn->user, &resp);
newstate = SASL_LOGIN_PASSWD;
break;
case SASL_LOGIN_PASSWD:
- result = Curl_auth_create_login_message(data, conn->passwd, &resp, &len);
+ result = Curl_auth_create_login_message(conn->passwd, &resp);
break;
case SASL_EXTERNAL:
- result = Curl_auth_create_external_message(data, conn->user, &resp, &len);
+ result = Curl_auth_create_external_message(conn->user, &resp);
break;
#ifndef CURL_DISABLE_CRYPTO_AUTH
#ifdef USE_GSASL
case SASL_GSASL:
- sasl->params->getmessage(data->state.buffer, &serverdata);
- result = Curl_auth_gsasl_token(data, serverdata, &conn->gsasl,
- &resp, &len);
- if(len > 0)
+ result = get_server_message(sasl, data, &serverdata);
+ if(!result)
+ result = Curl_auth_gsasl_token(data, &serverdata, &conn->gsasl, &resp);
+ if(!result && Curl_bufref_len(&resp) > 0)
newstate = SASL_GSASL;
break;
#endif
case SASL_CRAMMD5:
- sasl->params->getmessage(data->state.buffer, &serverdata);
- result = Curl_auth_decode_cram_md5_message(serverdata, &chlg, &chlglen);
+ result = get_server_message(sasl, data, &serverdata);
if(!result)
- result = Curl_auth_create_cram_md5_message(data, chlg, conn->user,
- conn->passwd, &resp, &len);
- free(chlg);
+ result = Curl_auth_create_cram_md5_message(&serverdata, conn->user,
+ conn->passwd, &resp);
break;
case SASL_DIGESTMD5:
- sasl->params->getmessage(data->state.buffer, &serverdata);
- result = Curl_auth_create_digest_md5_message(data, serverdata,
- conn->user, conn->passwd,
- service,
- &resp, &len);
+ result = get_server_message(sasl, data, &serverdata);
+ if(!result)
+ result = Curl_auth_create_digest_md5_message(data, &serverdata,
+ conn->user, conn->passwd,
+ service, &resp);
newstate = SASL_DIGESTMD5_RESP;
break;
case SASL_DIGESTMD5_RESP:
- resp = strdup("");
- if(!resp)
- result = CURLE_OUT_OF_MEMORY;
+ /* Keep response NULL to output an empty line. */
break;
#endif
@@ -562,18 +587,19 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
result = Curl_auth_create_ntlm_type1_message(data,
conn->user, conn->passwd,
service, hostname,
- &conn->ntlm, &resp, &len);
+ &conn->ntlm, &resp);
newstate = SASL_NTLM_TYPE2MSG;
break;
case SASL_NTLM_TYPE2MSG:
/* Decode the type-2 message */
- sasl->params->getmessage(data->state.buffer, &serverdata);
- result = Curl_auth_decode_ntlm_type2_message(data, serverdata,
- &conn->ntlm);
+ result = get_server_message(sasl, data, &serverdata);
+ if(!result)
+ result = Curl_auth_decode_ntlm_type2_message(data, &serverdata,
+ &conn->ntlm);
if(!result)
result = Curl_auth_create_ntlm_type3_message(data, conn->user,
conn->passwd, &conn->ntlm,
- &resp, &len);
+ &resp);
break;
#endif
@@ -582,55 +608,59 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
result = Curl_auth_create_gssapi_user_message(data, conn->user,
conn->passwd,
service,
- data->conn->host.name,
+ conn->host.name,
sasl->mutual_auth, NULL,
&conn->krb5,
- &resp, &len);
+ &resp);
newstate = SASL_GSSAPI_TOKEN;
break;
case SASL_GSSAPI_TOKEN:
- sasl->params->getmessage(data->state.buffer, &serverdata);
- if(sasl->mutual_auth) {
- /* Decode the user token challenge and create the optional response
- message */
- result = Curl_auth_create_gssapi_user_message(data, NULL, NULL,
- NULL, NULL,
- sasl->mutual_auth,
- serverdata, &conn->krb5,
- &resp, &len);
- newstate = SASL_GSSAPI_NO_DATA;
+ result = get_server_message(sasl, data, &serverdata);
+ if(!result) {
+ if(sasl->mutual_auth) {
+ /* Decode the user token challenge and create the optional response
+ message */
+ result = Curl_auth_create_gssapi_user_message(data, NULL, NULL,
+ NULL, NULL,
+ sasl->mutual_auth,
+ &serverdata,
+ &conn->krb5,
+ &resp);
+ newstate = SASL_GSSAPI_NO_DATA;
+ }
+ else
+ /* Decode the security challenge and create the response message */
+ result = Curl_auth_create_gssapi_security_message(data, &serverdata,
+ &conn->krb5,
+ &resp);
}
- else
- /* Decode the security challenge and create the response message */
- result = Curl_auth_create_gssapi_security_message(data, serverdata,
- &conn->krb5,
- &resp, &len);
break;
case SASL_GSSAPI_NO_DATA:
- sasl->params->getmessage(data->state.buffer, &serverdata);
/* Decode the security challenge and create the response message */
- result = Curl_auth_create_gssapi_security_message(data, serverdata,
- &conn->krb5,
- &resp, &len);
+ result = get_server_message(sasl, data, &serverdata);
+ if(!result)
+ result = Curl_auth_create_gssapi_security_message(data, &serverdata,
+ &conn->krb5,
+ &resp);
break;
#endif
case SASL_OAUTH2:
/* Create the authorisation message */
if(sasl->authused == SASL_MECH_OAUTHBEARER) {
- result = Curl_auth_create_oauth_bearer_message(data, conn->user,
+ result = Curl_auth_create_oauth_bearer_message(conn->user,
hostname,
port,
oauth_bearer,
- &resp, &len);
+ &resp);
/* Failures maybe sent by the server as continuations for OAUTHBEARER */
newstate = SASL_OAUTH2_RESP;
}
else
- result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
+ result = Curl_auth_create_xoauth_bearer_message(conn->user,
oauth_bearer,
- &resp, &len);
+ &resp);
break;
case SASL_OAUTH2_RESP:
@@ -642,11 +672,8 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
return result;
}
else if(code == sasl->params->contcode) {
- /* Acknowledge the continuation by sending a 0x01 response base64
- encoded */
- resp = strdup("AQ==");
- if(!resp)
- result = CURLE_OUT_OF_MEMORY;
+ /* Acknowledge the continuation by sending a 0x01 response. */
+ Curl_bufref_set(&resp, "\x01", 1, NULL);
break;
}
else {
@@ -660,15 +687,15 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
sasl->authmechs ^= sasl->authused;
/* Start an alternative SASL authentication */
- result = Curl_sasl_start(sasl, data, conn, sasl->force_ir, progress);
- newstate = sasl->state; /* Use state from Curl_sasl_start() */
- break;
+ return Curl_sasl_start(sasl, data, conn, sasl->force_ir, progress);
default:
failf(data, "Unsupported SASL authentication mechanism");
result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */
break;
}
+ Curl_bufref_free(&serverdata);
+
switch(result) {
case CURLE_BAD_CONTENT_ENCODING:
/* Cancel dialog */
@@ -676,8 +703,10 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
newstate = SASL_CANCEL;
break;
case CURLE_OK:
- if(resp)
- result = sasl->params->sendcont(data, conn, resp);
+ result = build_message(data, &resp);
+ if(!result)
+ result = sasl->params->sendcont(data, conn,
+ (const char *) Curl_bufref_ptr(&resp));
break;
default:
newstate = SASL_STOP; /* Stop on error */
@@ -685,7 +714,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
break;
}
- free(resp);
+ Curl_bufref_free(&resp);
state(sasl, data, newstate);
diff --git a/libs/libcurl/src/curl_sasl.h b/libs/libcurl/src/curl_sasl.h
index 8648c632b6..e17d323eba 100644
--- a/libs/libcurl/src/curl_sasl.h
+++ b/libs/libcurl/src/curl_sasl.h
@@ -42,7 +42,7 @@ struct connectdata;
/* Authentication mechanism values */
#define SASL_AUTH_NONE 0
-#define SASL_AUTH_ANY ~0U
+#define SASL_AUTH_ANY 0xffff
#define SASL_AUTH_DEFAULT (SASL_AUTH_ANY & ~SASL_MECH_EXTERNAL)
/* Authentication mechanism strings */
@@ -108,9 +108,9 @@ struct SASLproto {
struct SASL {
const struct SASLproto *params; /* Protocol dependent parameters */
saslstate state; /* Current machine state */
- unsigned int authmechs; /* Accepted authentication mechanisms */
- unsigned int prefmech; /* Preferred authentication mechanism */
- unsigned int authused; /* Auth mechanism used for the connection */
+ unsigned short authmechs; /* Accepted authentication mechanisms */
+ unsigned short prefmech; /* Preferred authentication mechanism */
+ unsigned short authused; /* Auth mechanism used for the connection */
bool resetprefs; /* For URL auth option parsing. */
bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */
bool force_ir; /* Protocol always supports initial response */
@@ -126,8 +126,8 @@ struct SASL {
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
/* Convert a mechanism name to a token */
-unsigned int Curl_sasl_decode_mech(const char *ptr,
- size_t maxlen, size_t *len);
+unsigned short Curl_sasl_decode_mech(const char *ptr,
+ size_t maxlen, size_t *len);
/* Parse the URL login options */
CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h
index cf1c26a14e..be4a58d4b6 100644
--- a/libs/libcurl/src/curl_setup.h
+++ b/libs/libcurl/src/curl_setup.h
@@ -247,7 +247,11 @@
* performing this task will result in a synthesized IPv6 address.
*/
#if defined(__APPLE__) && !defined(USE_ARES)
+#include <TargetConditionals.h>
#define USE_RESOLVE_ON_IPS 1
+# if defined(TARGET_OS_OSX) && TARGET_OS_OSX
+# define CURL_OSX_CALL_COPYPROXIES 1
+# endif
#endif
#ifdef USE_LWIPSOCK
@@ -517,7 +521,6 @@
# undef HAVE_GETADDRINFO_THREADSAFE
# undef HAVE_FREEADDRINFO
# undef HAVE_GETADDRINFO
-# undef HAVE_GETNAMEINFO
# undef ENABLE_IPV6
# endif
#endif
@@ -715,13 +718,19 @@ int netware_init(void);
#endif
/*
- * Portable symbolic names for Winsock shutdown() mode flags.
+ * shutdown() flags for systems that don't define them
*/
-#ifdef USE_WINSOCK
-# define SHUT_RD 0x00
-# define SHUT_WR 0x01
-# define SHUT_RDWR 0x02
+#ifndef SHUT_RD
+#define SHUT_RD 0x00
+#endif
+
+#ifndef SHUT_WR
+#define SHUT_WR 0x01
+#endif
+
+#ifndef SHUT_RDWR
+#define SHUT_RDWR 0x02
#endif
/* Define S_ISREG if not defined by system headers, f.e. MSVC */
@@ -772,9 +781,16 @@ endings either CRLF or LF so 't' is appropriate.
# endif
#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */
-/* for systems that don't detect this in configure, use a sensible default */
+/* for systems that don't detect this in configure */
#ifndef CURL_SA_FAMILY_T
-#define CURL_SA_FAMILY_T unsigned short
+# if defined(HAVE_SA_FAMILY_T)
+# define CURL_SA_FAMILY_T sa_family_t
+# elif defined(HAVE_ADDRESS_FAMILY)
+# define CURL_SA_FAMILY_T ADDRESS_FAMILY
+# else
+/* use a sensible default */
+# define CURL_SA_FAMILY_T unsigned short
+# endif
#endif
/* Some convenience macros to get the larger/smaller value out of two given.
@@ -795,6 +811,10 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
#define UNITTEST static
#endif
+#if defined(USE_NGHTTP2) || defined(USE_HYPER)
+#define USE_HTTP2
+#endif
+
#if defined(USE_NGTCP2) || defined(USE_QUICHE)
#define ENABLE_QUIC
#endif
diff --git a/libs/libcurl/src/dict.c b/libs/libcurl/src/dict.c
index 4319dadba5..625b057774 100644
--- a/libs/libcurl/src/dict.c
+++ b/libs/libcurl/src/dict.c
@@ -89,6 +89,7 @@ const struct Curl_handler Curl_handler_dict = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_DICT, /* defport */
CURLPROTO_DICT, /* protocol */
CURLPROTO_DICT, /* family */
@@ -214,14 +215,14 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
}
}
- if((word == NULL) || (*word == (char)0)) {
+ if(!word || (*word == (char)0)) {
infof(data, "lookup word is missing\n");
word = (char *)"default";
}
- if((database == NULL) || (*database == (char)0)) {
+ if(!database || (*database == (char)0)) {
database = (char *)"!";
}
- if((strategy == NULL) || (*strategy == (char)0)) {
+ if(!strategy || (*strategy == (char)0)) {
strategy = (char *)".";
}
@@ -265,11 +266,11 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
}
}
- if((word == NULL) || (*word == (char)0)) {
+ if(!word || (*word == (char)0)) {
infof(data, "lookup word is missing\n");
word = (char *)"default";
}
- if((database == NULL) || (*database == (char)0)) {
+ if(!database || (*database == (char)0)) {
database = (char *)"!";
}
diff --git a/libs/libcurl/src/doh.c b/libs/libcurl/src/doh.c
index 52388cba3e..36f8cd58dc 100644
--- a/libs/libcurl/src/doh.c
+++ b/libs/libcurl/src/doh.c
@@ -313,6 +313,10 @@ static CURLcode dohprobe(struct Curl_easy *data,
ERROR_CHECK_SETOPT(CURLOPT_CAINFO,
data->set.str[STRING_SSL_CAFILE]);
}
+ if(data->set.blobs[BLOB_CAINFO]) {
+ ERROR_CHECK_SETOPT(CURLOPT_CAINFO_BLOB,
+ data->set.blobs[BLOB_CAINFO]);
+ }
if(data->set.str[STRING_SSL_CAPATH]) {
ERROR_CHECK_SETOPT(CURLOPT_CAPATH,
data->set.str[STRING_SSL_CAPATH]);
@@ -351,7 +355,10 @@ static CURLcode dohprobe(struct Curl_easy *data,
(data->set.ssl.revoke_best_effort ?
CURLSSLOPT_REVOKE_BEST_EFFORT : 0) |
(data->set.ssl.native_ca_store ?
- CURLSSLOPT_NATIVE_CA : 0);
+ CURLSSLOPT_NATIVE_CA : 0) |
+ (data->set.ssl.auto_client_cert ?
+ CURLSSLOPT_AUTO_CLIENT_CERT : 0);
+
curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask);
}
@@ -413,17 +420,15 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
if(!dohp->headers)
goto error;
- if(conn->ip_version != CURL_IPRESOLVE_V6) {
- /* create IPv4 DOH request */
- result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V4],
- DNS_TYPE_A, hostname, data->set.str[STRING_DOH],
- data->multi, dohp->headers);
- if(result)
- goto error;
- dohp->pending++;
- }
+ /* create IPv4 DOH request */
+ result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V4],
+ DNS_TYPE_A, hostname, data->set.str[STRING_DOH],
+ data->multi, dohp->headers);
+ if(result)
+ goto error;
+ dohp->pending++;
- if(conn->ip_version != CURL_IPRESOLVE_V4) {
+ if(Curl_ipv6works(data)) {
/* create IPv6 DOH request */
result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6],
DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH],
diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c
index 4ce1bbf63b..530b7c73f2 100644
--- a/libs/libcurl/src/easy.c
+++ b/libs/libcurl/src/easy.c
@@ -789,7 +789,6 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
/* duplicate all blobs */
for(j = (enum dupblob)0; j < BLOB_LAST; j++) {
result = Curl_setblobopt(&dst->set.blobs[j], src->set.blobs[j]);
- /* Curl_setstropt return CURLE_BAD_FUNCTION_ARGUMENT with blob */
if(result)
return result;
}
@@ -895,7 +894,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
(void)Curl_altsvc_load(outcurl->asi, outcurl->set.str[STRING_ALTSVC]);
}
#endif
-#ifdef USE_HSTS
+#ifndef CURL_DISABLE_HSTS
if(data->hsts) {
outcurl->hsts = Curl_hsts_init();
if(!outcurl->hsts)
@@ -1105,7 +1104,7 @@ static CURLcode easy_connection(struct Curl_easy *data,
curl_socket_t *sfd,
struct connectdata **connp)
{
- if(data == NULL)
+ if(!data)
return CURLE_BAD_FUNCTION_ARGUMENT;
/* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
@@ -1171,6 +1170,7 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
CURLcode result;
ssize_t n1;
struct connectdata *c = NULL;
+ SIGPIPE_VARIABLE(pipe_st);
if(Curl_is_in_callback(data))
return CURLE_RECURSIVE_API_CALL;
@@ -1185,7 +1185,9 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
Curl_attach_connnection(data, c);
*n = 0;
+ sigpipe_ignore(data, &pipe_st);
result = Curl_write(data, sfd, buffer, buflen, &n1);
+ sigpipe_restore(&pipe_st);
if(n1 == -1)
return CURLE_SEND_ERROR;
diff --git a/libs/libcurl/src/easyoptions.c b/libs/libcurl/src/easyoptions.c
index db8337b044..4e65e3525b 100644
--- a/libs/libcurl/src/easyoptions.c
+++ b/libs/libcurl/src/easyoptions.c
@@ -38,6 +38,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"AWS_SIGV4", CURLOPT_AWS_SIGV4, CURLOT_STRING, 0},
{"BUFFERSIZE", CURLOPT_BUFFERSIZE, CURLOT_LONG, 0},
{"CAINFO", CURLOPT_CAINFO, CURLOT_STRING, 0},
+ {"CAINFO_BLOB", CURLOPT_CAINFO_BLOB, CURLOT_BLOB, 0},
{"CAPATH", CURLOPT_CAPATH, CURLOT_STRING, 0},
{"CERTINFO", CURLOPT_CERTINFO, CURLOT_LONG, 0},
{"CHUNK_BGN_FUNCTION", CURLOPT_CHUNK_BGN_FUNCTION, CURLOT_FUNCTION, 0},
@@ -205,6 +206,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"PROXYUSERNAME", CURLOPT_PROXYUSERNAME, CURLOT_STRING, 0},
{"PROXYUSERPWD", CURLOPT_PROXYUSERPWD, CURLOT_STRING, 0},
{"PROXY_CAINFO", CURLOPT_PROXY_CAINFO, CURLOT_STRING, 0},
+ {"PROXY_CAINFO_BLOB", CURLOPT_PROXY_CAINFO_BLOB, CURLOT_BLOB, 0},
{"PROXY_CAPATH", CURLOPT_PROXY_CAPATH, CURLOT_STRING, 0},
{"PROXY_CRLFILE", CURLOPT_PROXY_CRLFILE, CURLOT_STRING, 0},
{"PROXY_ISSUERCERT", CURLOPT_PROXY_ISSUERCERT, CURLOT_STRING, 0},
@@ -352,6 +354,6 @@ struct curl_easyoption Curl_easyopts[] = {
*/
int Curl_easyopts_check(void)
{
- return ((CURLOPT_LASTENTRY%10000) != (308 + 1));
+ return ((CURLOPT_LASTENTRY%10000) != (310 + 1));
}
#endif
diff --git a/libs/libcurl/src/file.c b/libs/libcurl/src/file.c
index 1d174e519e..0420db3454 100644
--- a/libs/libcurl/src/file.c
+++ b/libs/libcurl/src/file.c
@@ -111,6 +111,7 @@ const struct Curl_handler Curl_handler_file = {
file_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
0, /* defport */
CURLPROTO_FILE, /* protocol */
CURLPROTO_FILE, /* family */
@@ -410,16 +411,18 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
struct tm buffer;
const struct tm *tm = &buffer;
char header[80];
+ int headerlen;
+ char accept_ranges[24]= { "Accept-ranges: bytes\r\n" };
if(expected_size >= 0) {
- msnprintf(header, sizeof(header),
+ headerlen = msnprintf(header, sizeof(header),
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n",
expected_size);
- result = Curl_client_write(data, CLIENTWRITE_HEADER, header, 0);
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen);
if(result)
return result;
result = Curl_client_write(data, CLIENTWRITE_HEADER,
- (char *)"Accept-ranges: bytes\r\n", 0);
+ accept_ranges, strlen(accept_ranges));
if(result != CURLE_OK)
return result;
}
@@ -430,7 +433,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
return result;
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
- msnprintf(header, sizeof(header),
+ headerlen = msnprintf(header, sizeof(header),
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s",
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
tm->tm_mday,
@@ -440,7 +443,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
tm->tm_min,
tm->tm_sec,
data->set.opt_no_body ? "": "\r\n");
- result = Curl_client_write(data, CLIENTWRITE_HEADER, header, 0);
+ result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen);
if(result)
return result;
/* set the file size to make it available post transfer */
diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c
index 5bf44f1180..444cf35f55 100644
--- a/libs/libcurl/src/ftp.c
+++ b/libs/libcurl/src/ftp.c
@@ -175,6 +175,7 @@ const struct Curl_handler Curl_handler_ftp = {
ftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_FTP, /* defport */
CURLPROTO_FTP, /* protocol */
CURLPROTO_FTP, /* family */
@@ -205,6 +206,7 @@ const struct Curl_handler Curl_handler_ftps = {
ftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_FTPS, /* defport */
CURLPROTO_FTPS, /* protocol */
CURLPROTO_FTP, /* family */
@@ -1090,7 +1092,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
else
res = NULL; /* failure! */
- if(res == NULL) {
+ if(!res) {
failf(data, "failed to resolve the address provided to PORT: %s", host);
free(addr);
return CURLE_FTP_PORT_FAILED;
@@ -2098,6 +2100,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
data->set.get_filetime &&
(data->info.filetime >= 0) ) {
char headerbuf[128];
+ int headerbuflen;
time_t filetime = data->info.filetime;
struct tm buffer;
const struct tm *tm = &buffer;
@@ -2107,7 +2110,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
return result;
/* format: "Tue, 15 Nov 1994 12:45:26" */
- msnprintf(headerbuf, sizeof(headerbuf),
+ headerbuflen = msnprintf(headerbuf, sizeof(headerbuf),
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
tm->tm_mday,
@@ -2116,7 +2119,8 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
- result = Curl_client_write(data, CLIENTWRITE_BOTH, headerbuf, 0);
+ result = Curl_client_write(data, CLIENTWRITE_BOTH, headerbuf,
+ headerbuflen);
if(result)
return result;
} /* end of a ridiculous amount of conditionals */
@@ -2321,9 +2325,9 @@ static CURLcode ftp_state_size_resp(struct Curl_easy *data,
#ifdef CURL_FTP_HTTPSTYLE_HEAD
if(-1 != filesize) {
char clbuf[128];
- msnprintf(clbuf, sizeof(clbuf),
+ int clbuflen = msnprintf(clbuf, sizeof(clbuf),
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
- result = Curl_client_write(data, CLIENTWRITE_BOTH, clbuf, 0);
+ result = Curl_client_write(data, CLIENTWRITE_BOTH, clbuf, clbuflen);
if(result)
return result;
}
@@ -2357,7 +2361,8 @@ static CURLcode ftp_state_rest_resp(struct Curl_easy *data,
#ifdef CURL_FTP_HTTPSTYLE_HEAD
if(ftpcode == 350) {
char buffer[24]= { "Accept-ranges: bytes\r\n" };
- result = Curl_client_write(data, CLIENTWRITE_BOTH, buffer, 0);
+ result = Curl_client_write(data, CLIENTWRITE_BOTH, buffer,
+ strlen(buffer));
if(result)
return result;
}
diff --git a/libs/libcurl/src/ftplistparser.c b/libs/libcurl/src/ftplistparser.c
index 81825e6ff6..716ff38172 100644
--- a/libs/libcurl/src/ftplistparser.c
+++ b/libs/libcurl/src/ftplistparser.c
@@ -424,7 +424,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
endptr++;
while(ISDIGIT(*endptr))
endptr++;
- if(*endptr != 0) {
+ if(*endptr) {
parser->error = CURLE_FTP_BAD_FILE_LIST;
goto fail;
}
diff --git a/libs/libcurl/src/gopher.c b/libs/libcurl/src/gopher.c
index a39cc7e6b4..f61232ff56 100644
--- a/libs/libcurl/src/gopher.c
+++ b/libs/libcurl/src/gopher.c
@@ -74,6 +74,7 @@ const struct Curl_handler Curl_handler_gopher = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_GOPHER, /* defport */
CURLPROTO_GOPHER, /* protocol */
CURLPROTO_GOPHER, /* family */
@@ -97,6 +98,7 @@ const struct Curl_handler Curl_handler_gophers = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_GOPHER, /* defport */
CURLPROTO_GOPHERS, /* protocol */
CURLPROTO_GOPHER, /* family */
diff --git a/libs/libcurl/src/hash.c b/libs/libcurl/src/hash.c
index 5d433ad1fb..12e7aa5f27 100644
--- a/libs/libcurl/src/hash.c
+++ b/libs/libcurl/src/hash.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -245,7 +245,7 @@ Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user,
struct Curl_hash_element *he = le->ptr;
lnext = le->next;
/* ask the callback function if we shall remove this entry or not */
- if(comp == NULL || comp(user, he->ptr)) {
+ if(!comp || comp(user, he->ptr)) {
Curl_llist_remove(list, le, (void *) h);
--h->size; /* one less entry in the hash now */
}
diff --git a/libs/libcurl/src/hostcheck.c b/libs/libcurl/src/hostcheck.c
index 0fef98b2ad..49dbab3472 100644
--- a/libs/libcurl/src/hostcheck.c
+++ b/libs/libcurl/src/hostcheck.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -81,7 +81,7 @@ static int hostmatch(char *hostname, char *pattern)
pattern[len-1] = 0;
pattern_wildcard = strchr(pattern, '*');
- if(pattern_wildcard == NULL)
+ if(!pattern_wildcard)
return strcasecompare(pattern, hostname) ?
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
@@ -97,7 +97,7 @@ static int hostmatch(char *hostname, char *pattern)
match. */
wildcard_enabled = 1;
pattern_label_end = strchr(pattern, '.');
- if(pattern_label_end == NULL || strchr(pattern_label_end + 1, '.') == NULL ||
+ if(!pattern_label_end || strchr(pattern_label_end + 1, '.') == NULL ||
pattern_wildcard > pattern_label_end ||
strncasecompare(pattern, "xn--", 4)) {
wildcard_enabled = 0;
@@ -107,7 +107,7 @@ static int hostmatch(char *hostname, char *pattern)
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
hostname_label_end = strchr(hostname, '.');
- if(hostname_label_end == NULL ||
+ if(!hostname_label_end ||
!strcasecompare(pattern_label_end, hostname_label_end))
return CURL_HOST_NOMATCH;
diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c
index 05c09f6835..e0e3cfc2cb 100644
--- a/libs/libcurl/src/hostip.c
+++ b/libs/libcurl/src/hostip.c
@@ -68,6 +68,10 @@
#include "curl_memory.h"
#include "memdebug.h"
+#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
+#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
+#endif
+
#if defined(CURLRES_SYNCH) && \
defined(HAVE_ALARM) && defined(SIGALRM) && defined(HAVE_SIGSETJMP)
/* alarm-based timeouts can only be used with all the dependencies satisfied */
@@ -466,10 +470,6 @@ Curl_cache_addr(struct Curl_easy *data,
* function is used. You MUST call Curl_resolv_unlock() later (when you're
* done using this struct) to decrease the counter again.
*
- * In debug mode, we specifically test for an interface name "LocalHost"
- * and resolve "localhost" instead as a means to permit test cases
- * to connect to a local test server with any host name.
- *
* Return codes:
*
* CURLRESOLV_ERROR (-1) = error, no pointer
@@ -533,6 +533,19 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
return CURLRESOLV_ERROR;
}
+#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
+ /*
+ * The automagic conversion from IPv4 literals to IPv6 literals only works
+ * if the SCDynamicStoreCopyProxies system function gets called first. As
+ * Curl currently doesn't support system-wide HTTP proxies, we therefore
+ * don't use any value this function might return.
+ *
+ * This function is only available on a macOS and is not needed for
+ * IPv4-only builds, hence the conditions above.
+ */
+ SCDynamicStoreCopyProxies(NULL);
+#endif
+
#ifndef USE_RESOLVE_ON_IPS
/* First check if this is an IPv4 address string */
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
@@ -578,13 +591,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
/* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
non-zero value indicating that we need to wait for the response to
the resolve call */
- addr = Curl_getaddrinfo(data,
-#ifdef DEBUGBUILD
- (data->set.str[STRING_DEVICE]
- && !strcmp(data->set.str[STRING_DEVICE],
- "LocalHost"))?"localhost":
-#endif
- hostname, port, &respwait);
+ addr = Curl_getaddrinfo(data, hostname, port, &respwait);
}
}
if(!addr) {
diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h
index c0fd3c8c46..d178976aa1 100644
--- a/libs/libcurl/src/hostip.h
+++ b/libs/libcurl/src/hostip.h
@@ -136,15 +136,6 @@ void Curl_hostcache_prune(struct Curl_easy *data);
/* Return # of addresses in a Curl_addrinfo struct */
int Curl_num_addresses(const struct Curl_addrinfo *addr);
-#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
-int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
- GETNAMEINFO_TYPE_ARG2 salen,
- char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
- char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
- GETNAMEINFO_TYPE_ARG7 flags,
- int line, const char *source);
-#endif
-
/* IPv4 threadsafe resolve function used for synch and asynch builds */
struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
diff --git a/libs/libcurl/src/hostip6.c b/libs/libcurl/src/hostip6.c
index 53b3c67223..9791d86468 100644
--- a/libs/libcurl/src/hostip6.c
+++ b/libs/libcurl/src/hostip6.c
@@ -140,26 +140,13 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
#ifndef USE_RESOLVE_ON_IPS
char addrbuf[128];
#endif
- int pf;
+ int pf = PF_INET;
*waitp = 0; /* synchronous response only */
- /* Check if a limited name resolve has been requested */
- switch(data->set.ipver) {
- case CURL_IPRESOLVE_V4:
- pf = PF_INET;
- break;
- case CURL_IPRESOLVE_V6:
- pf = PF_INET6;
- break;
- default:
+ if(Curl_ipv6works(data))
+ /* The stack seems to be IPv6-enabled */
pf = PF_UNSPEC;
- break;
- }
-
- if((pf != PF_INET) && !Curl_ipv6works(data))
- /* The stack seems to be a non-IPv6 one */
- pf = PF_INET;
memset(&hints, 0, sizeof(hints));
hints.ai_family = pf;
diff --git a/libs/libcurl/src/hsts.c b/libs/libcurl/src/hsts.c
index fd4926f36b..ef166f196c 100644
--- a/libs/libcurl/src/hsts.c
+++ b/libs/libcurl/src/hsts.c
@@ -25,7 +25,7 @@
*/
#include "curl_setup.h"
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_HSTS)
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HSTS)
#include <curl/curl.h>
#include "urldata.h"
#include "llist.h"
@@ -37,6 +37,7 @@
#include "parsedate.h"
#include "rand.h"
#include "rename.h"
+#include "strtoofft.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -58,7 +59,10 @@ static time_t debugtime(void *unused)
char *timestr = getenv("CURL_TIME");
(void)unused;
if(timestr) {
- unsigned long val = strtol(timestr, NULL, 10) + deltatime;
+ curl_off_t val;
+ (void)curlx_strtoofft(timestr, NULL, 10, &val);
+
+ val += (curl_off_t)deltatime;
return (time_t)val;
}
return time(NULL);
@@ -274,7 +278,7 @@ static CURLcode hsts_push(struct Curl_easy *data,
e.namelen = strlen(sts->host);
e.includeSubDomains = sts->includeSubDomains;
- result = Curl_gmtime(sts->expires, &stamp);
+ result = Curl_gmtime((time_t)sts->expires, &stamp);
if(result)
return result;
@@ -294,7 +298,7 @@ static CURLcode hsts_push(struct Curl_easy *data,
static CURLcode hsts_out(struct stsentry *sts, FILE *fp)
{
struct tm stamp;
- CURLcode result = Curl_gmtime(sts->expires, &stamp);
+ CURLcode result = Curl_gmtime((time_t)sts->expires, &stamp);
if(result)
return result;
@@ -439,7 +443,10 @@ static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h)
expires = Curl_getdate_capped(e.expire);
else
expires = TIME_T_MAX; /* the end of time */
- result = hsts_create(h, e.name, e.includeSubDomains, expires);
+ result = hsts_create(h, e.name,
+ /* bitfield to bool conversion: */
+ e.includeSubDomains ? TRUE : FALSE,
+ expires);
if(result)
return result;
}
@@ -517,4 +524,4 @@ CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h)
return hsts_pull(data, h);
}
-#endif /* CURL_DISABLE_HTTP || USE_HSTS */
+#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */
diff --git a/libs/libcurl/src/hsts.h b/libs/libcurl/src/hsts.h
index ae5db74a24..baa582864a 100644
--- a/libs/libcurl/src/hsts.h
+++ b/libs/libcurl/src/hsts.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2020 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -23,7 +23,7 @@
***************************************************************************/
#include "curl_setup.h"
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_HSTS)
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HSTS)
#include <curl/curl.h>
#include "llist.h"
@@ -35,7 +35,7 @@ struct stsentry {
struct Curl_llist_element node;
const char *host;
bool includeSubDomains;
- time_t expires; /* the timestamp of this entry's expiry */
+ curl_off_t expires; /* the timestamp of this entry's expiry */
};
/* The HSTS cache. Needs to be able to tailmatch host names. */
@@ -61,5 +61,5 @@ CURLcode Curl_hsts_loadcb(struct Curl_easy *data,
#define Curl_hsts_cleanup(x)
#define Curl_hsts_loadcb(x,y)
#define Curl_hsts_save(x,y,z)
-#endif /* CURL_DISABLE_HTTP || USE_HSTS */
+#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */
#endif /* HEADER_CURL_HSTS_H */
diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c
index 02c81c419b..628dd73703 100644
--- a/libs/libcurl/src/http.c
+++ b/libs/libcurl/src/http.c
@@ -133,6 +133,7 @@ const struct Curl_handler Curl_handler_http = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_HTTP, /* defport */
CURLPROTO_HTTP, /* protocol */
CURLPROTO_HTTP, /* family */
@@ -160,6 +161,7 @@ const struct Curl_handler Curl_handler_https = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_HTTPS, /* defport */
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
@@ -740,7 +742,7 @@ output_auth_headers(struct Curl_easy *data,
if(authstatus->picked == CURLAUTH_BEARER) {
/* Bearer */
if((!proxy && data->set.str[STRING_BEARER] &&
- !Curl_checkheaders(data, "Authorization:"))) {
+ !Curl_checkheaders(data, "Authorization"))) {
auth = "Bearer";
result = http_output_bearer(data);
if(result)
@@ -897,6 +899,11 @@ Curl_http_output_auth(struct Curl_easy *data,
* proxy CONNECT loop.
*/
+static int is_valid_auth_separator(char ch)
+{
+ return ch == '\0' || ch == ',' || ISSPACE(ch);
+}
+
CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
const char *auth) /* the first non-space */
{
@@ -940,7 +947,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
while(*auth) {
#ifdef USE_SPNEGO
- if(checkprefix("Negotiate", auth)) {
+ if(checkprefix("Negotiate", auth) && is_valid_auth_separator(auth[9])) {
if((authp->avail & CURLAUTH_NEGOTIATE) ||
Curl_auth_is_spnego_supported()) {
*availp |= CURLAUTH_NEGOTIATE;
@@ -966,7 +973,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
#endif
#ifdef USE_NTLM
/* NTLM support requires the SSL crypto libs */
- if(checkprefix("NTLM", auth)) {
+ if(checkprefix("NTLM", auth) && is_valid_auth_separator(auth[4])) {
if((authp->avail & CURLAUTH_NTLM) ||
(authp->avail & CURLAUTH_NTLM_WB) ||
Curl_auth_is_ntlm_supported()) {
@@ -1004,7 +1011,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
else
#endif
#ifndef CURL_DISABLE_CRYPTO_AUTH
- if(checkprefix("Digest", auth)) {
+ if(checkprefix("Digest", auth) && is_valid_auth_separator(auth[6])) {
if((authp->avail & CURLAUTH_DIGEST) != 0)
infof(data, "Ignoring duplicate digest auth header.\n");
else if(Curl_auth_is_digest_supported()) {
@@ -1026,7 +1033,8 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
}
else
#endif
- if(checkprefix("Basic", auth)) {
+ if(checkprefix("Basic", auth) &&
+ is_valid_auth_separator(auth[5])) {
*availp |= CURLAUTH_BASIC;
authp->avail |= CURLAUTH_BASIC;
if(authp->picked == CURLAUTH_BASIC) {
@@ -1039,7 +1047,8 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
}
}
else
- if(checkprefix("Bearer", auth)) {
+ if(checkprefix("Bearer", auth) &&
+ is_valid_auth_separator(auth[6])) {
*availp |= CURLAUTH_BEARER;
authp->avail |= CURLAUTH_BEARER;
if(authp->picked == CURLAUTH_BEARER) {
@@ -1266,14 +1275,6 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
else
sendsize = size;
- /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
- when we speak HTTPS, as if only a fraction of it is sent now, this data
- needs to fit into the normal read-callback buffer later on and that
- buffer is using this size.
- */
- if(sendsize > CURL_MAX_WRITE_SIZE)
- sendsize = CURL_MAX_WRITE_SIZE;
-
/* OpenSSL is very picky and we must send the SAME buffer pointer to the
library when we attempt to re-send this buffer. Sending the same data
is not enough, we must use the exact same address. For this reason, we
@@ -1286,6 +1287,14 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
Curl_dyn_free(in);
return result;
}
+ /* We never send more than upload_buffer_size bytes in one single chunk
+ when we speak HTTPS, as if only a fraction of it is sent now, this data
+ needs to fit into the normal read-callback buffer later on and that
+ buffer is using this size.
+ */
+ if(sendsize > (size_t)data->set.upload_buffer_size)
+ sendsize = (size_t)data->set.upload_buffer_size;
+
memcpy(data->state.ulbuf, ptr, sendsize);
ptr = data->state.ulbuf;
}
@@ -3113,6 +3122,10 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
/* initialize a dynamic send-buffer */
Curl_dyn_init(&req, DYN_HTTP_REQUEST);
+ /* make sure the header buffer is reset - if there are leftovers from a
+ previous transfer */
+ Curl_dyn_reset(&data->state.headerb);
+
/* add the main request stuff */
/* GET/HEAD/POST/PUT */
result = Curl_dyn_addf(&req, "%s ", request);
@@ -3375,7 +3388,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
if(!k->http_bodyless &&
!data->set.ignorecl && checkprefix("Content-Length:", headp)) {
curl_off_t contentlength;
- CURLofft offt = curlx_strtoofft(headp + 15, NULL, 10, &contentlength);
+ CURLofft offt = curlx_strtoofft(headp + strlen("Content-Length:"),
+ NULL, 10, &contentlength);
if(offt == CURL_OFFT_OK) {
if(data->set.max_filesize &&
@@ -3474,7 +3488,9 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
* of chunks, and a chunk-data set to zero signals the
* end-of-chunks. */
- result = Curl_build_unencoding_stack(data, headp + 18, TRUE);
+ result = Curl_build_unencoding_stack(data,
+ headp + strlen("Transfer-Encoding:"),
+ TRUE);
if(result)
return result;
}
@@ -3487,17 +3503,20 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
* 2616). zlib cannot handle compress. However, errors are
* handled further down when the response body is processed
*/
- result = Curl_build_unencoding_stack(data, headp + 17, FALSE);
+ result = Curl_build_unencoding_stack(data,
+ headp + strlen("Content-Encoding:"),
+ FALSE);
if(result)
return result;
}
else if(checkprefix("Retry-After:", headp)) {
/* Retry-After = HTTP-date / delay-seconds */
curl_off_t retry_after = 0; /* zero for unknown or "now" */
- time_t date = Curl_getdate_capped(&headp[12]);
+ time_t date = Curl_getdate_capped(headp + strlen("Retry-After:"));
if(-1 == date) {
/* not a date, try it as a decimal number */
- (void)curlx_strtoofft(&headp[12], NULL, 10, &retry_after);
+ (void)curlx_strtoofft(headp + strlen("Retry-After:"),
+ NULL, 10, &retry_after);
}
else
/* convert date to number of seconds into the future */
@@ -3516,7 +3535,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
The forth means the requested range was unsatisfied.
*/
- char *ptr = headp + 14;
+ char *ptr = headp + strlen("Content-Range:");
/* Move forward until first digit or asterisk */
while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
@@ -3539,7 +3558,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
CURL_LOCK_ACCESS_SINGLE);
Curl_cookie_add(data,
- data->cookies, TRUE, FALSE, headp + 11,
+ data->cookies, TRUE, FALSE,
+ headp + strlen("Set-Cookie:"),
/* If there is a custom-set Host: name, use it
here, or else use real peer host name. */
data->state.aptr.cookiehost?
@@ -3574,7 +3594,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
return result;
}
#ifdef USE_SPNEGO
- else if(checkprefix("Persistent-Auth", headp)) {
+ else if(checkprefix("Persistent-Auth:", headp)) {
struct negotiatedata *negdata = &conn->negotiate;
struct auth *authp = &data->state.authhost;
if(authp->picked == CURLAUTH_NEGOTIATE) {
@@ -3618,13 +3638,13 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
}
}
-#ifdef USE_HSTS
+#ifndef CURL_DISABLE_HSTS
/* If enabled, the header is incoming and this is over HTTPS */
else if(data->hsts && checkprefix("Strict-Transport-Security:", headp) &&
(conn->handler->flags & PROTOPT_SSL)) {
CURLcode check =
Curl_hsts_parse(data->hsts, data->state.up.hostname,
- &headp[ sizeof("Strict-Transport-Security:") -1 ]);
+ headp + strlen("Strict-Transport-Security:"));
if(check)
infof(data, "Illegal STS header skipped\n");
#ifdef DEBUGBUILD
@@ -3648,7 +3668,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
/* the ALPN of the current request */
enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
result = Curl_altsvc_parse(data, data->asi,
- &headp[ strlen("Alt-Svc:") ],
+ headp + strlen("Alt-Svc:"),
id, conn->host.name,
curlx_uitous(conn->remote_port));
if(result)
diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h
index 36e2152fe3..2a3834ae11 100644
--- a/libs/libcurl/src/http.h
+++ b/libs/libcurl/src/http.h
@@ -184,8 +184,7 @@ struct HTTP {
enum {
HTTPSEND_NADA, /* init */
HTTPSEND_REQUEST, /* sending a request */
- HTTPSEND_BODY, /* sending body */
- HTTPSEND_LAST /* never use this */
+ HTTPSEND_BODY /* sending body */
} sending;
#ifndef CURL_DISABLE_HTTP
@@ -211,6 +210,7 @@ struct HTTP {
char **push_headers; /* allocated array */
size_t push_headers_used; /* number of entries filled in */
size_t push_headers_alloc; /* number of entries allocated */
+ uint32_t error; /* HTTP/2 stream error code */
#endif
#if defined(USE_NGHTTP2) || defined(USE_NGHTTP3)
bool closed; /* TRUE on HTTP2 stream close */
@@ -281,7 +281,6 @@ struct http_conn {
/* list of settings that will be sent */
nghttp2_settings_entry local_settings[3];
size_t local_settings_num;
- uint32_t error_code; /* HTTP/2 error code */
#else
int unused; /* prevent a compiler warning */
#endif
diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c
index ce9a0d393c..f194c18b23 100644
--- a/libs/libcurl/src/http2.c
+++ b/libs/libcurl/src/http2.c
@@ -288,6 +288,7 @@ void Curl_http2_setup_req(struct Curl_easy *data)
http->mem = NULL;
http->len = 0;
http->memlen = 0;
+ http->error = NGHTTP2_NO_ERROR;
}
/* called from http_setup_conn */
@@ -295,7 +296,6 @@ void Curl_http2_setup_conn(struct connectdata *conn)
{
conn->proto.httpc.settings.max_concurrent_streams =
DEFAULT_MAX_CONCURRENT_STREAMS;
- conn->proto.httpc.error_code = NGHTTP2_NO_ERROR;
}
/*
@@ -319,6 +319,7 @@ static const struct Curl_handler Curl_handler_http2 = {
http2_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
http2_conncheck, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_HTTP, /* defport */
CURLPROTO_HTTP, /* protocol */
CURLPROTO_HTTP, /* family */
@@ -341,6 +342,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
http2_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
http2_conncheck, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_HTTP, /* defport */
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
@@ -499,33 +501,43 @@ static int set_transfer_url(struct Curl_easy *data,
const char *v;
CURLU *u = curl_url();
CURLUcode uc;
- char *url;
+ char *url = NULL;
+ int rc = 0;
v = curl_pushheader_byname(hp, ":scheme");
if(v) {
uc = curl_url_set(u, CURLUPART_SCHEME, v, 0);
- if(uc)
- return 1;
+ if(uc) {
+ rc = 1;
+ goto fail;
+ }
}
v = curl_pushheader_byname(hp, ":authority");
if(v) {
uc = curl_url_set(u, CURLUPART_HOST, v, 0);
- if(uc)
- return 2;
+ if(uc) {
+ rc = 2;
+ goto fail;
+ }
}
v = curl_pushheader_byname(hp, ":path");
if(v) {
uc = curl_url_set(u, CURLUPART_PATH, v, 0);
- if(uc)
- return 3;
+ if(uc) {
+ rc = 3;
+ goto fail;
+ }
}
uc = curl_url_get(u, CURLUPART_URL, &url, 0);
if(uc)
- return 4;
+ rc = 4;
+ fail:
curl_url_cleanup(u);
+ if(rc)
+ return rc;
if(data->state.url_alloc)
free(data->state.url);
@@ -571,6 +583,7 @@ static int push_promise(struct Curl_easy *data,
rv = set_transfer_url(newhandle, &heads);
if(rv) {
+ (void)Curl_close(&newhandle);
rv = CURL_PUSH_DENY;
goto fail;
}
@@ -877,7 +890,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
httpc = &conn->proto.httpc;
drain_this(data_s, httpc);
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
- httpc->error_code = error_code;
+ stream->error = error_code;
/* remove the entry from the hash as the stream is now gone */
rv = nghttp2_session_set_stream_user_data(session, stream_id, 0);
@@ -1242,7 +1255,7 @@ static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn)
nghttp2_session_callbacks *callbacks;
conn->proto.httpc.inbuf = malloc(H2_BUFSIZE);
- if(conn->proto.httpc.inbuf == NULL)
+ if(!conn->proto.httpc.inbuf)
return CURLE_OUT_OF_MEMORY;
rc = nghttp2_session_callbacks_new(&callbacks);
@@ -1383,7 +1396,7 @@ static int h2_process_pending_input(struct Curl_easy *data,
}
rv = h2_session_send(data, httpc->h2);
- if(rv != 0) {
+ if(rv) {
*err = CURLE_SEND_ERROR;
return -1;
}
@@ -1397,9 +1410,10 @@ static int h2_process_pending_input(struct Curl_easy *data,
}
if(should_close_session(httpc)) {
+ struct HTTP *stream = data->req.p.http;
H2BUGF(infof(data,
"h2_process_pending_input: nothing to do in this session\n"));
- if(httpc->error_code)
+ if(stream->error)
*err = CURLE_HTTP2;
else {
/* not an error per se, but should still close the connection */
@@ -1422,9 +1436,7 @@ CURLcode Curl_http2_done_sending(struct Curl_easy *data,
if((conn->handler == &Curl_handler_http2_ssl) ||
(conn->handler == &Curl_handler_http2)) {
/* make sure this is only attempted for HTTP/2 transfers */
-
struct HTTP *stream = data->req.p.http;
-
struct http_conn *httpc = &conn->proto.httpc;
nghttp2_session *h2 = httpc->h2;
@@ -1448,7 +1460,7 @@ CURLcode Curl_http2_done_sending(struct Curl_easy *data,
/* and attempt to send the pending frames */
rv = h2_session_send(data, h2);
- if(rv != 0)
+ if(rv)
result = CURLE_SEND_ERROR;
if(nghttp2_session_want_write(h2)) {
@@ -1482,7 +1494,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
/* Reset to FALSE to prevent infinite loop in readwrite_data function. */
stream->closed = FALSE;
- if(httpc->error_code == NGHTTP2_REFUSED_STREAM) {
+ if(stream->error == NGHTTP2_REFUSED_STREAM) {
H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!\n",
stream->stream_id));
connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */
@@ -1490,10 +1502,10 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
*err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */
return -1;
}
- else if(httpc->error_code != NGHTTP2_NO_ERROR) {
+ else if(stream->error != NGHTTP2_NO_ERROR) {
failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
- stream->stream_id, nghttp2_http2_strerror(httpc->error_code),
- httpc->error_code);
+ stream->stream_id, nghttp2_http2_strerror(stream->error),
+ stream->error);
*err = CURLE_HTTP2_STREAM;
return -1;
}
@@ -1609,6 +1621,10 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
return -1;
}
+ if(stream->closed)
+ /* closed overrides paused */
+ return http2_handle_stream_close(conn, data, stream, err);
+
/* Nullify here because we call nghttp2_session_send() and they
might refer to the old buffer. */
stream->upload_mem = NULL;
@@ -1760,7 +1776,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
nread));
}
- if(h2_process_pending_input(data, httpc, err) != 0)
+ if(h2_process_pending_input(data, httpc, err))
return -1;
}
if(stream->memlen) {
@@ -1785,7 +1801,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
return retlen;
}
if(stream->closed)
- return 0;
+ return http2_handle_stream_close(conn, data, stream, err);
*err = CURLE_AGAIN;
H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
stream->stream_id));
@@ -1960,7 +1976,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
more space. */
nheader += 1;
nva = malloc(sizeof(nghttp2_nv) * nheader);
- if(nva == NULL) {
+ if(!nva) {
*err = CURLE_OUT_OF_MEMORY;
return -1;
}
@@ -2083,7 +2099,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
}
/* :authority must come before non-pseudo header fields */
- if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
+ if(authority_idx && authority_idx != AUTHORITY_DST_IDX) {
nghttp2_nv authority = nva[authority_idx];
for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
nva[i] = nva[i - 1];
@@ -2153,7 +2169,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
stream->stream_id = stream_id;
rv = h2_session_send(data, h2);
- if(rv != 0) {
+ if(rv) {
H2BUGF(infof(data,
"http2_send() nghttp2_session_send error (%s)%d\n",
nghttp2_strerror(rv), rv));
@@ -2259,10 +2275,10 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
/* stream 1 is opened implicitly on upgrade */
stream->stream_id = 1;
/* queue SETTINGS frame (again) */
- rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,
- httpc->binlen, NULL);
- if(rv != 0) {
- failf(data, "nghttp2_session_upgrade() failed: %s(%d)",
+ rv = nghttp2_session_upgrade2(httpc->h2, httpc->binsettings, httpc->binlen,
+ data->state.httpreq == HTTPREQ_HEAD, NULL);
+ if(rv) {
+ failf(data, "nghttp2_session_upgrade2() failed: %s(%d)",
nghttp2_strerror(rv), rv);
return CURLE_HTTP2;
}
@@ -2284,7 +2300,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE,
httpc->local_settings,
httpc->local_settings_num);
- if(rv != 0) {
+ if(rv) {
failf(data, "nghttp2_submit_settings() failed: %s(%d)",
nghttp2_strerror(rv), rv);
return CURLE_HTTP2;
@@ -2293,7 +2309,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
rv = nghttp2_session_set_local_window_size(httpc->h2, NGHTTP2_FLAG_NONE, 0,
HTTP2_HUGE_WINDOW_SIZE);
- if(rv != 0) {
+ if(rv) {
failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
nghttp2_strerror(rv), rv);
return CURLE_HTTP2;
@@ -2321,8 +2337,15 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
DEBUGASSERT(httpc->nread_inbuf == 0);
- if(-1 == h2_process_pending_input(data, httpc, &result))
- return CURLE_HTTP2;
+ /* Good enough to call it an end once the remaining payload is copied to the
+ * connection buffer.
+ * Some servers (e.g. nghttpx v1.43.0) may fulfill stream 1 immediately
+ * following the protocol switch other than waiting for the client-side
+ * connection preface. If h2_process_pending_input is invoked here to parse
+ * the remaining payload, stream 1 would be marked as closed too early and
+ * thus ignored in http2_recv (following 252790c53).
+ * The logic in lib/http.c and lib/transfer.c guarantees a following
+ * http2_recv would be invoked very soon. */
return CURLE_OK;
}
@@ -2332,7 +2355,8 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
DEBUGASSERT(data);
DEBUGASSERT(data->conn);
/* if it isn't HTTP/2, we're done */
- if(!data->conn->proto.httpc.h2)
+ if(!(data->conn->handler->protocol & PROTO_FAMILY_HTTP) ||
+ !data->conn->proto.httpc.h2)
return CURLE_OK;
#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
else {
@@ -2456,10 +2480,10 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data)
/* Only call this function for a transfer that already got a HTTP/2
CURLE_HTTP2_STREAM error! */
-bool Curl_h2_http_1_1_error(struct connectdata *conn)
+bool Curl_h2_http_1_1_error(struct Curl_easy *data)
{
- struct http_conn *httpc = &conn->proto.httpc;
- return (httpc->error_code == NGHTTP2_HTTP_1_1_REQUIRED);
+ struct HTTP *stream = data->req.p.http;
+ return (stream->error == NGHTTP2_HTTP_1_1_REQUIRED);
}
#else /* !USE_NGHTTP2 */
diff --git a/libs/libcurl/src/http2.h b/libs/libcurl/src/http2.h
index 114b382718..21e2c086a3 100644
--- a/libs/libcurl/src/http2.h
+++ b/libs/libcurl/src/http2.h
@@ -62,7 +62,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause);
/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */
-bool Curl_h2_http_1_1_error(struct connectdata *conn);
+bool Curl_h2_http_1_1_error(struct Curl_easy *data);
#else /* USE_NGHTTP2 */
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_setup(x,y) CURLE_UNSUPPORTED_PROTOCOL
diff --git a/libs/libcurl/src/http_digest.c b/libs/libcurl/src/http_digest.c
index 132f3930c8..049b232e01 100644
--- a/libs/libcurl/src/http_digest.c
+++ b/libs/libcurl/src/http_digest.c
@@ -56,7 +56,7 @@ CURLcode Curl_input_digest(struct Curl_easy *data,
digest = &data->state.digest;
}
- if(!checkprefix("Digest", header))
+ if(!checkprefix("Digest", header) || !ISSPACE(header[6]))
return CURLE_BAD_CONTENT_ENCODING;
header += strlen("Digest");
diff --git a/libs/libcurl/src/http_negotiate.c b/libs/libcurl/src/http_negotiate.c
index d759748f2e..68cce1bbb2 100644
--- a/libs/libcurl/src/http_negotiate.c
+++ b/libs/libcurl/src/http_negotiate.c
@@ -179,7 +179,7 @@ CURLcode Curl_output_negotiate(struct Curl_easy *data,
free(base64);
- if(userp == NULL) {
+ if(!userp) {
return CURLE_OUT_OF_MEMORY;
}
diff --git a/libs/libcurl/src/http_ntlm.c b/libs/libcurl/src/http_ntlm.c
index 4fa38f0b09..e200fdb1da 100644
--- a/libs/libcurl/src/http_ntlm.c
+++ b/libs/libcurl/src/http_ntlm.c
@@ -39,6 +39,7 @@
#include "http_ntlm.h"
#include "curl_ntlm_core.h"
#include "curl_ntlm_wb.h"
+#include "curl_base64.h"
#include "vauth/vauth.h"
#include "url.h"
@@ -80,7 +81,18 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data,
header++;
if(*header) {
- result = Curl_auth_decode_ntlm_type2_message(data, header, ntlm);
+ unsigned char *hdr;
+ size_t hdrlen;
+
+ result = Curl_base64_decode(header, &hdr, &hdrlen);
+ if(!result) {
+ struct bufref hdrbuf;
+
+ Curl_bufref_init(&hdrbuf);
+ Curl_bufref_set(&hdrbuf, hdr, hdrlen, curl_free);
+ result = Curl_auth_decode_ntlm_type2_message(data, &hdrbuf, ntlm);
+ Curl_bufref_free(&hdrbuf);
+ }
if(result)
return result;
@@ -116,7 +128,8 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
{
char *base64 = NULL;
size_t len = 0;
- CURLcode result;
+ CURLcode result = CURLE_OK;
+ struct bufref ntlmmsg;
/* point to the address of the pointer that holds the string to send to the
server, which is for a plain host or for a HTTP proxy */
@@ -173,10 +186,10 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
passwdp = "";
#ifdef USE_WINDOWS_SSPI
- if(s_hSecDll == NULL) {
+ if(!s_hSecDll) {
/* not thread safe and leaks - use curl_global_init() to avoid */
CURLcode err = Curl_sspi_global_init();
- if(s_hSecDll == NULL)
+ if(!s_hSecDll)
return err;
}
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
@@ -184,50 +197,52 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
#endif
#endif
+ Curl_bufref_init(&ntlmmsg);
switch(*state) {
case NTLMSTATE_TYPE1:
default: /* for the weird cases we (re)start here */
/* Create a type-1 message */
result = Curl_auth_create_ntlm_type1_message(data, userp, passwdp,
service, hostname,
- ntlm, &base64,
- &len);
- if(result)
- return result;
-
- if(base64) {
- free(*allocuserpwd);
- *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
- proxy ? "Proxy-" : "",
- base64);
- free(base64);
- if(!*allocuserpwd)
- return CURLE_OUT_OF_MEMORY;
-
- DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
+ ntlm, &ntlmmsg);
+ if(!result) {
+ DEBUGASSERT(Curl_bufref_len(&ntlmmsg) != 0);
+ result = Curl_base64_encode(data,
+ (const char *) Curl_bufref_ptr(&ntlmmsg),
+ Curl_bufref_len(&ntlmmsg), &base64, &len);
+ if(!result) {
+ free(*allocuserpwd);
+ *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
+ proxy ? "Proxy-" : "",
+ base64);
+ free(base64);
+ if(!*allocuserpwd)
+ result = CURLE_OUT_OF_MEMORY;
+ }
}
break;
case NTLMSTATE_TYPE2:
/* We already received the type-2 message, create a type-3 message */
result = Curl_auth_create_ntlm_type3_message(data, userp, passwdp,
- ntlm, &base64, &len);
- if(result)
- return result;
-
- if(base64) {
- free(*allocuserpwd);
- *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
- proxy ? "Proxy-" : "",
- base64);
- free(base64);
- if(!*allocuserpwd)
- return CURLE_OUT_OF_MEMORY;
-
- DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
-
- *state = NTLMSTATE_TYPE3; /* we send a type-3 */
- authp->done = TRUE;
+ ntlm, &ntlmmsg);
+ if(!result && Curl_bufref_len(&ntlmmsg)) {
+ result = Curl_base64_encode(data,
+ (const char *) Curl_bufref_ptr(&ntlmmsg),
+ Curl_bufref_len(&ntlmmsg), &base64, &len);
+ if(!result) {
+ free(*allocuserpwd);
+ *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
+ proxy ? "Proxy-" : "",
+ base64);
+ free(base64);
+ if(!*allocuserpwd)
+ result = CURLE_OUT_OF_MEMORY;
+ else {
+ *state = NTLMSTATE_TYPE3; /* we send a type-3 */
+ authp->done = TRUE;
+ }
+ }
}
break;
@@ -241,8 +256,9 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
authp->done = TRUE;
break;
}
+ Curl_bufref_free(&ntlmmsg);
- return CURLE_OK;
+ return result;
}
void Curl_http_auth_cleanup_ntlm(struct connectdata *conn)
diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c
index f403ffc0e0..a3a62c1cad 100644
--- a/libs/libcurl/src/http_proxy.c
+++ b/libs/libcurl/src/http_proxy.c
@@ -39,6 +39,8 @@
#include "connect.h"
#include "curlx.h"
#include "vtls/vtls.h"
+#include "transfer.h"
+#include "multiif.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -88,29 +90,12 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex)
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
#ifndef CURL_DISABLE_PROXY
/* for [protocol] tunneled through HTTP proxy */
- struct HTTP http_proxy;
- void *prot_save;
const char *hostname;
int remote_port;
CURLcode result;
- /* BLOCKING */
/* We want "seamless" operations through HTTP proxy tunnel */
- /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
- * member conn->proto.http; we want [protocol] through HTTP and we have
- * to change the member temporarily for connecting to the HTTP
- * proxy. After Curl_proxyCONNECT we have to set back the member to the
- * original pointer
- *
- * This function might be called several times in the multi interface case
- * if the proxy's CONNECT response is not instant.
- */
- prot_save = data->req.p.http;
- memset(&http_proxy, 0, sizeof(http_proxy));
- data->req.p.http = &http_proxy;
- connkeep(conn, "HTTP proxy CONNECT");
-
/* for the secondary socket (FTP), use the "connect to host"
* but ignore the "connect to port" (use the secondary port)
*/
@@ -128,8 +113,8 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex)
remote_port = conn->conn_to_port;
else
remote_port = conn->remote_port;
+
result = Curl_proxyCONNECT(data, sockindex, hostname, remote_port);
- data->req.p.http = prot_save;
if(CURLE_OK != result)
return result;
Curl_safefree(data->state.aptr.proxyuserpwd);
@@ -153,18 +138,53 @@ bool Curl_connect_ongoing(struct connectdata *conn)
(conn->connect_state->tunnel_state != TUNNEL_COMPLETE);
}
+/* when we've sent a CONNECT to a proxy, we should rather either wait for the
+ socket to become readable to be able to get the response headers or if
+ we're still sending the request, wait for write. */
+int Curl_connect_getsock(struct connectdata *conn)
+{
+ struct HTTP *http;
+ DEBUGASSERT(conn);
+ DEBUGASSERT(conn->connect_state);
+ http = &conn->connect_state->http_proxy;
+
+ if(http->sending)
+ return GETSOCK_WRITESOCK(0);
+
+ return GETSOCK_READSOCK(0);
+}
+
static CURLcode connect_init(struct Curl_easy *data, bool reinit)
{
struct http_connect_state *s;
struct connectdata *conn = data->conn;
if(!reinit) {
+ CURLcode result;
DEBUGASSERT(!conn->connect_state);
+ /* we might need the upload buffer for streaming a partial request */
+ result = Curl_get_upload_buffer(data);
+ if(result)
+ return result;
+
s = calloc(1, sizeof(struct http_connect_state));
if(!s)
return CURLE_OUT_OF_MEMORY;
infof(data, "allocate connect buffer!\n");
conn->connect_state = s;
Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS);
+
+ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
+ * member conn->proto.http; we want [protocol] through HTTP and we have
+ * to change the member temporarily for connecting to the HTTP
+ * proxy. After Curl_proxyCONNECT we have to set back the member to the
+ * original pointer
+ *
+ * This function might be called several times in the multi interface case
+ * if the proxy's CONNECT response is not instant.
+ */
+ s->prot_save = data->req.p.http;
+ data->req.p.http = &s->http_proxy;
+ connkeep(conn, "HTTP proxy CONNECT");
}
else {
DEBUGASSERT(conn->connect_state);
@@ -184,6 +204,10 @@ static void connect_done(struct Curl_easy *data)
struct http_connect_state *s = conn->connect_state;
s->tunnel_state = TUNNEL_COMPLETE;
Curl_dyn_free(&s->rcvbuf);
+ Curl_dyn_free(&s->req);
+
+ /* retore the protocol pointer */
+ data->req.p.http = s->prot_save;
infof(data, "CONNECT phase completed!\n");
}
@@ -231,6 +255,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
struct connectdata *conn = data->conn;
curl_socket_t tunnelsocket = conn->sock[sockindex];
struct http_connect_state *s = conn->connect_state;
+ struct HTTP *http = data->req.p.http;
char *linep;
size_t perline;
@@ -246,7 +271,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
timediff_t check;
if(TUNNEL_INIT == s->tunnel_state) {
/* BEGIN CONNECT PHASE */
- struct dynbuf req;
+ struct dynbuf *req = &s->req;
char *hostheader = NULL;
char *host = NULL;
@@ -259,8 +284,8 @@ static CURLcode CONNECT(struct Curl_easy *data,
free(data->req.newurl);
data->req.newurl = NULL;
- /* initialize a dynamic send-buffer */
- Curl_dyn_init(&req, DYN_HTTP_REQUEST);
+ /* initialize send-buffer */
+ Curl_dyn_init(req, DYN_HTTP_REQUEST);
result = CONNECT_host(data, conn,
hostname, remote_port, &hostheader, &host);
@@ -285,7 +310,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
useragent = data->state.aptr.uagent;
result =
- Curl_dyn_addf(&req,
+ Curl_dyn_addf(req,
"CONNECT %s HTTP/%s\r\n"
"%s" /* Host: */
"%s" /* Proxy-Authorization */
@@ -300,16 +325,15 @@ static CURLcode CONNECT(struct Curl_easy *data,
proxyconn);
if(!result)
- result = Curl_add_custom_headers(data, TRUE, &req);
+ result = Curl_add_custom_headers(data, TRUE, req);
if(!result)
/* CRLF terminate the request */
- result = Curl_dyn_add(&req, "\r\n");
+ result = Curl_dyn_add(req, "\r\n");
if(!result) {
/* Send the connect request to the proxy */
- /* BLOCKING */
- result = Curl_buffer_send(&req, data, &data->info.request_size, 0,
+ result = Curl_buffer_send(req, data, &data->info.request_size, 0,
sockindex);
}
if(result)
@@ -317,7 +341,6 @@ static CURLcode CONNECT(struct Curl_easy *data,
}
free(host);
free(hostheader);
- Curl_dyn_free(&req);
if(result)
return result;
@@ -330,12 +353,42 @@ static CURLcode CONNECT(struct Curl_easy *data,
return CURLE_OPERATION_TIMEDOUT;
}
- if(!Curl_conn_data_pending(conn, sockindex))
+ if(!Curl_conn_data_pending(conn, sockindex) && !http->sending)
/* return so we'll be called again polling-style */
return CURLE_OK;
/* at this point, the tunnel_connecting phase is over. */
+ if(http->sending == HTTPSEND_REQUEST) {
+ if(!s->nsend) {
+ size_t fillcount;
+ k->upload_fromhere = data->state.ulbuf;
+ result = Curl_fillreadbuffer(data, data->set.upload_buffer_size,
+ &fillcount);
+ if(result)
+ return result;
+ s->nsend = fillcount;
+ }
+ if(s->nsend) {
+ ssize_t bytes_written;
+ /* write to socket (send away data) */
+ result = Curl_write(data,
+ conn->writesockfd, /* socket to send to */
+ k->upload_fromhere, /* buffer pointer */
+ s->nsend, /* buffer size */
+ &bytes_written); /* actually sent */
+
+ if(!result)
+ /* send to debug callback! */
+ result = Curl_debug(data, CURLINFO_HEADER_OUT,
+ k->upload_fromhere, bytes_written);
+
+ s->nsend -= bytes_written;
+ k->upload_fromhere += bytes_written;
+ return result;
+ }
+ /* if nothing left to send, continue */
+ }
{ /* READING RESPONSE PHASE */
int error = SELECT_OK;
diff --git a/libs/libcurl/src/http_proxy.h b/libs/libcurl/src/http_proxy.h
index a78db0d046..f5a4cb07cf 100644
--- a/libs/libcurl/src/http_proxy.h
+++ b/libs/libcurl/src/http_proxy.h
@@ -38,15 +38,39 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex);
bool Curl_connect_complete(struct connectdata *conn);
bool Curl_connect_ongoing(struct connectdata *conn);
+int Curl_connect_getsock(struct connectdata *conn);
#else
#define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN
#define Curl_proxy_connect(x,y) CURLE_OK
#define Curl_connect_complete(x) CURLE_OK
#define Curl_connect_ongoing(x) FALSE
+#define Curl_connect_getsock(x) 0
#endif
void Curl_connect_free(struct Curl_easy *data);
void Curl_connect_done(struct Curl_easy *data);
+/* struct for HTTP CONNECT state data */
+struct http_connect_state {
+ struct HTTP http_proxy;
+ struct HTTP *prot_save;
+ struct dynbuf rcvbuf;
+ struct dynbuf req;
+ size_t nsend;
+ enum keeponval {
+ KEEPON_DONE,
+ KEEPON_CONNECT,
+ KEEPON_IGNORE
+ } keepon;
+ curl_off_t cl; /* size of content to read and ignore */
+ enum {
+ TUNNEL_INIT, /* init/default/no tunnel state */
+ TUNNEL_CONNECT, /* CONNECT has been sent off */
+ TUNNEL_COMPLETE /* CONNECT response received completely */
+ } tunnel_state;
+ BIT(chunked_encoding);
+ BIT(close_connection);
+};
+
#endif /* HEADER_CURL_HTTP_PROXY_H */
diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c
index e887357e1c..d85bcc391d 100644
--- a/libs/libcurl/src/imap.c
+++ b/libs/libcurl/src/imap.c
@@ -136,6 +136,7 @@ const struct Curl_handler Curl_handler_imap = {
imap_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_IMAP, /* defport */
CURLPROTO_IMAP, /* protocol */
CURLPROTO_IMAP, /* family */
@@ -164,6 +165,7 @@ const struct Curl_handler Curl_handler_imaps = {
imap_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_IMAPS, /* defport */
CURLPROTO_IMAPS, /* protocol */
CURLPROTO_IMAP, /* family */
@@ -919,7 +921,7 @@ static CURLcode imap_state_capability_resp(struct Curl_easy *data,
/* Do we have a SASL based authentication mechanism? */
else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) {
size_t llen;
- unsigned int mechbit;
+ unsigned short mechbit;
line += 5;
wordlen -= 5;
diff --git a/libs/libcurl/src/inet_ntop.c b/libs/libcurl/src/inet_ntop.c
index 9a5af7f421..4c3e9e4dad 100644
--- a/libs/libcurl/src/inet_ntop.c
+++ b/libs/libcurl/src/inet_ntop.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1996-2019 Internet Software Consortium.
+ * Copyright (C) 1996-2021 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -134,7 +134,7 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
/* Are we following an initial run of 0x00s or any real hex?
*/
- if(i != 0)
+ if(i)
*tp++ = ':';
/* Is this address an encapsulated IPv4?
diff --git a/libs/libcurl/src/krb5.c b/libs/libcurl/src/krb5.c
index eb83566d6b..4d1102da36 100644
--- a/libs/libcurl/src/krb5.c
+++ b/libs/libcurl/src/krb5.c
@@ -160,16 +160,6 @@ krb5_decode(void *app_data, void *buf, int len,
}
static int
-krb5_overhead(void *app_data, int level, int len)
-{
- /* no arguments are used */
- (void)app_data;
- (void)level;
- (void)len;
- return 0;
-}
-
-static int
krb5_encode(void *app_data, const void *from, int length, int level, void **to)
{
gss_ctx_id_t *context = app_data;
@@ -305,7 +295,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
break;
}
- if(output_buffer.length != 0) {
+ if(output_buffer.length) {
char *cmd;
result = Curl_base64_encode(data, (char *)output_buffer.value,
@@ -392,7 +382,7 @@ static struct Curl_sec_client_mech Curl_krb5_client_mech = {
krb5_auth,
krb5_end,
krb5_check_prot,
- krb5_overhead,
+
krb5_encode,
krb5_decode
};
@@ -412,7 +402,7 @@ name_to_level(const char *name)
{
int i;
for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
- if(checkprefix(name, level_names[i].name))
+ if(curl_strequal(name, level_names[i].name))
return level_names[i].level;
return PROT_NONE;
}
@@ -657,8 +647,6 @@ static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn,
{
ssize_t tx = 0, len = conn->buffer_size;
- len -= conn->mech->overhead(conn->app_data, conn->data_prot,
- curlx_sztosi(len));
if(len <= 0)
len = length;
while(length) {
@@ -760,7 +748,7 @@ static int sec_set_protection_level(struct Curl_easy *data)
if(level) {
char *pbsz;
- static unsigned int buffer_size = 1 << 20; /* 1048576 */
+ unsigned int buffer_size = 1 << 20; /* 1048576 */
code = ftp_send_command(data, "PBSZ %u", buffer_size);
if(code < 0)
@@ -817,7 +805,7 @@ static CURLcode choose_mech(struct Curl_easy *data, struct connectdata *conn)
const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
tmp_allocation = realloc(conn->app_data, mech->size);
- if(tmp_allocation == NULL) {
+ if(!tmp_allocation) {
failf(data, "Failed realloc of size %zu", mech->size);
mech = NULL;
return CURLE_OUT_OF_MEMORY;
diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c
index 860a4a851a..ed16423026 100644
--- a/libs/libcurl/src/ldap.c
+++ b/libs/libcurl/src/ldap.c
@@ -149,6 +149,7 @@ const struct Curl_handler Curl_handler_ldap = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_LDAP, /* defport */
CURLPROTO_LDAP, /* protocol */
CURLPROTO_LDAP, /* family */
@@ -176,6 +177,7 @@ const struct Curl_handler Curl_handler_ldaps = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_LDAPS, /* defport */
CURLPROTO_LDAPS, /* protocol */
CURLPROTO_LDAP, /* family */
@@ -303,7 +305,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
#else
rc = _ldap_url_parse(data, conn, &ludp);
#endif
- if(rc != 0) {
+ if(rc) {
failf(data, "LDAP local: %s", ldap_err2string(rc));
result = CURLE_LDAP_INVALID_URL;
goto quit;
@@ -387,7 +389,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
goto quit;
}
server = ldapssl_init(host, (int)conn->port, 1);
- if(server == NULL) {
+ if(!server) {
failf(data, "LDAP local: Cannot connect to %s:%ld",
conn->host.dispname, conn->port);
result = CURLE_COULDNT_CONNECT;
@@ -428,7 +430,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
goto quit;
}
server = ldap_init(host, (int)conn->port);
- if(server == NULL) {
+ if(!server) {
failf(data, "LDAP local: Cannot connect to %s:%ld",
conn->host.dispname, conn->port);
result = CURLE_COULDNT_CONNECT;
@@ -464,7 +466,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
}
else {
server = ldap_init(host, (int)conn->port);
- if(server == NULL) {
+ if(!server) {
failf(data, "LDAP local: Cannot connect to %s:%ld",
conn->host.dispname, conn->port);
result = CURLE_COULDNT_CONNECT;
@@ -477,7 +479,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
#else
rc = ldap_simple_bind_s(server, user, passwd);
#endif
- if(!ldap_ssl && rc != 0) {
+ if(!ldap_ssl && rc) {
ldap_proto = LDAP_VERSION2;
ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
#ifdef USE_WIN32_LDAP
@@ -486,7 +488,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
rc = ldap_simple_bind_s(server, user, passwd);
#endif
}
- if(rc != 0) {
+ if(rc) {
#ifdef USE_WIN32_LDAP
failf(data, "LDAP local: bind via ldap_win_bind %s",
ldap_err2string(rc));
@@ -501,7 +503,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg);
- if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
+ if(rc && rc != LDAP_SIZELIMIT_EXCEEDED) {
failf(data, "LDAP remote: %s", ldap_err2string(rc));
result = CURLE_LDAP_SEARCH_FAILED;
goto quit;
@@ -581,7 +583,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
result = CURLE_OUT_OF_MEMORY;
goto quit;
- }
+ }
#else
char *attr = attribute;
#endif
@@ -1061,13 +1063,23 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp)
if(!ludp)
return;
+#if defined(USE_WIN32_LDAP)
+ curlx_unicodefree(ludp->lud_dn);
+ curlx_unicodefree(ludp->lud_filter);
+#else
free(ludp->lud_dn);
free(ludp->lud_filter);
+#endif
if(ludp->lud_attrs) {
size_t i;
- for(i = 0; i < ludp->lud_attrs_dups; i++)
+ for(i = 0; i < ludp->lud_attrs_dups; i++) {
+#if defined(USE_WIN32_LDAP)
+ curlx_unicodefree(ludp->lud_attrs[i]);
+#else
free(ludp->lud_attrs[i]);
+#endif
+ }
free(ludp->lud_attrs);
}
diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist
index f787761ced..b3afa9f8a2 100644
--- a/libs/libcurl/src/libcurl.plist
+++ b/libs/libcurl/src/libcurl.plist
@@ -15,7 +15,7 @@
<string>se.curl.libcurl</string>
<key>CFBundleVersion</key>
- <string>7.76.1</string>
+ <string>7.77.0</string>
<key>CFBundleName</key>
<string>libcurl</string>
@@ -27,9 +27,9 @@
<string>????</string>
<key>CFBundleShortVersionString</key>
- <string>libcurl 7.76.1</string>
+ <string>libcurl 7.77.0</string>
<key>CFBundleGetInfoString</key>
- <string>libcurl.plist 7.76.1</string>
+ <string>libcurl.plist 7.77.0</string>
</dict>
</plist>
diff --git a/libs/libcurl/src/llist.c b/libs/libcurl/src/llist.c
index 17a7be1667..e0ec7393d2 100644
--- a/libs/libcurl/src/llist.c
+++ b/libs/libcurl/src/llist.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -94,13 +94,13 @@ Curl_llist_remove(struct Curl_llist *list, struct Curl_llist_element *e,
void *user)
{
void *ptr;
- if(e == NULL || list->size == 0)
+ if(!e || list->size == 0)
return;
if(e == list->head) {
list->head = e->next;
- if(list->head == NULL)
+ if(!list->head)
list->tail = NULL;
else
e->next->prev = NULL;
diff --git a/libs/libcurl/src/md4.c b/libs/libcurl/src/md4.c
index e731e123d3..c651ddf669 100644
--- a/libs/libcurl/src/md4.c
+++ b/libs/libcurl/src/md4.c
@@ -174,7 +174,7 @@ static void MD4_Init(MD4_CTX *ctx)
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
{
- if(ctx->data == NULL) {
+ if(!ctx->data) {
ctx->data = malloc(size);
if(ctx->data != NULL) {
memcpy(ctx->data, data, size);
diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c
index abadcb02cb..0bf1b46a4c 100644
--- a/libs/libcurl/src/mime.c
+++ b/libs/libcurl/src/mime.c
@@ -152,14 +152,14 @@ curl_off_t VmsRealFileSize(const char *name,
FILE * file;
file = fopen(name, FOPEN_READTEXT); /* VMS */
- if(file == NULL)
+ if(!file)
return 0;
count = 0;
ret_stat = 1;
while(ret_stat > 0) {
ret_stat = fread(buffer, 1, sizeof(buffer), file);
- if(ret_stat != 0)
+ if(ret_stat)
count += ret_stat;
}
fclose(file);
diff --git a/libs/libcurl/src/mprintf.c b/libs/libcurl/src/mprintf.c
index c681248dee..5292026861 100644
--- a/libs/libcurl/src/mprintf.c
+++ b/libs/libcurl/src/mprintf.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1999 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1999 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -815,7 +815,7 @@ static int dprintf_formatf(
size_t len;
str = (char *) p->data.str;
- if(str == NULL) {
+ if(!str) {
/* Write null[] if there's space. */
if(prec == -1 || prec >= (long) sizeof(null) - 1) {
str = null;
diff --git a/libs/libcurl/src/mqtt.c b/libs/libcurl/src/mqtt.c
index 2134409cda..d88fa737df 100644
--- a/libs/libcurl/src/mqtt.c
+++ b/libs/libcurl/src/mqtt.c
@@ -86,6 +86,7 @@ const struct Curl_handler Curl_handler_mqtt = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_MQTT, /* defport */
CURLPROTO_MQTT, /* protocol */
CURLPROTO_MQTT, /* family */
diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c
index be3e41f8bb..1b3e261c68 100644
--- a/libs/libcurl/src/multi.c
+++ b/libs/libcurl/src/multi.c
@@ -381,6 +381,11 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
multi->max_concurrent_streams = 100;
multi->ipv6_works = Curl_ipv6works(NULL);
+#ifdef USE_WINSOCK
+ multi->wsa_event = WSACreateEvent();
+ if(multi->wsa_event == WSA_INVALID_EVENT)
+ goto error;
+#else
#ifdef ENABLE_WAKEUP
if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) {
multi->wakeup_pair[0] = CURL_SOCKET_BAD;
@@ -394,6 +399,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
multi->wakeup_pair[1] = CURL_SOCKET_BAD;
}
#endif
+#endif
return multi;
@@ -872,8 +878,10 @@ bool Curl_multiplex_wanted(const struct Curl_multi *multi)
void Curl_detach_connnection(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
- if(conn)
+ if(conn) {
Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL);
+ Curl_ssl_detach_conn(data, conn);
+ }
data->conn = NULL;
}
@@ -890,6 +898,9 @@ void Curl_attach_connnection(struct Curl_easy *data,
data->conn = conn;
Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data,
&data->conn_queue);
+ if(conn->handler->attach)
+ conn->handler->attach(data, conn);
+ Curl_ssl_associate_conn(data, conn);
}
static int waitconnect_getsock(struct connectdata *conn,
@@ -930,10 +941,8 @@ static int waitproxyconnect_getsock(struct connectdata *conn,
{
sock[0] = conn->sock[FIRSTSOCKET];
- /* when we've sent a CONNECT to a proxy, we should rather wait for the
- socket to become readable to be able to get the response headers */
if(conn->connect_state)
- return GETSOCK_READSOCK(0);
+ return Curl_connect_getsock(conn);
return GETSOCK_WRITESOCK(0);
}
@@ -1083,6 +1092,10 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
struct pollfd *ufds = &a_few_on_stack[0];
bool ufds_malloc = FALSE;
+#ifdef USE_WINSOCK
+ WSANETWORKEVENTS wsa_events;
+ DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
+#endif
if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE;
@@ -1101,11 +1114,11 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
curl_socket_t s = CURL_SOCKET_BAD;
- if(bitmap & GETSOCK_READSOCK(i)) {
+ if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
++nfds;
s = sockbunch[i];
}
- if(bitmap & GETSOCK_WRITESOCK(i)) {
+ if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
++nfds;
s = sockbunch[i];
}
@@ -1128,7 +1141,11 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
nfds += extra_nfds; /* add the externally provided ones */
#ifdef ENABLE_WAKEUP
+#ifdef USE_WINSOCK
+ if(use_wakeup) {
+#else
if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
+#endif
++nfds;
}
#endif
@@ -1156,22 +1173,40 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
curl_socket_t s = CURL_SOCKET_BAD;
-
+#ifdef USE_WINSOCK
+ long mask = 0;
+#endif
if(bitmap & GETSOCK_READSOCK(i)) {
- ufds[nfds].fd = sockbunch[i];
+ s = sockbunch[i];
+#ifdef USE_WINSOCK
+ mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
+#endif
+ ufds[nfds].fd = s;
ufds[nfds].events = POLLIN;
++nfds;
- s = sockbunch[i];
}
if(bitmap & GETSOCK_WRITESOCK(i)) {
- ufds[nfds].fd = sockbunch[i];
+ s = sockbunch[i];
+#ifdef USE_WINSOCK
+ mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
+ send(s, NULL, 0, 0); /* reset FD_WRITE */
+#endif
+ ufds[nfds].fd = s;
ufds[nfds].events = POLLOUT;
++nfds;
- s = sockbunch[i];
}
+ /* s is only set if either being readable or writable is checked */
if(s == CURL_SOCKET_BAD) {
+ /* break on entry not checked for being readable or writable */
break;
}
+#ifdef USE_WINSOCK
+ if(WSAEventSelect(s, multi->wsa_event, mask) != 0) {
+ if(ufds_malloc)
+ free(ufds);
+ return CURLM_INTERNAL_ERROR;
+ }
+#endif
}
data = data->next; /* check next handle */
@@ -1180,6 +1215,22 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
/* Add external file descriptions from poll-like struct curl_waitfd */
for(i = 0; i < extra_nfds; i++) {
+#ifdef USE_WINSOCK
+ long mask = 0;
+ if(extra_fds[i].events & CURL_WAIT_POLLIN)
+ mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
+ if(extra_fds[i].events & CURL_WAIT_POLLPRI)
+ mask |= FD_OOB;
+ if(extra_fds[i].events & CURL_WAIT_POLLOUT) {
+ mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
+ send(extra_fds[i].fd, NULL, 0, 0); /* reset FD_WRITE */
+ }
+ if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) {
+ if(ufds_malloc)
+ free(ufds);
+ return CURLM_INTERNAL_ERROR;
+ }
+#endif
ufds[nfds].fd = extra_fds[i].fd;
ufds[nfds].events = 0;
if(extra_fds[i].events & CURL_WAIT_POLLIN)
@@ -1192,25 +1243,62 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
}
#ifdef ENABLE_WAKEUP
+#ifndef USE_WINSOCK
if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
ufds[nfds].fd = multi->wakeup_pair[0];
ufds[nfds].events = POLLIN;
++nfds;
}
#endif
+#endif
+#if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK)
+ if(nfds || use_wakeup) {
+#else
if(nfds) {
- /* wait... */
- int pollrc = Curl_poll(ufds, nfds, timeout_ms);
+#endif
+ int pollrc;
+#ifdef USE_WINSOCK
+ if(nfds)
+ pollrc = Curl_poll(ufds, nfds, 0); /* just pre-check with WinSock */
+ else
+ pollrc = 0;
+ if(pollrc <= 0) /* now wait... if not ready during the pre-check above */
+ WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
+#else
+ pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */
+#endif
+
if(pollrc > 0) {
retcode = pollrc;
+#ifdef USE_WINSOCK
+ }
+ /* With WinSock, we have to run the following section unconditionally
+ to call WSAEventSelect(fd, event, 0) on all the sockets */
+ {
+#endif
/* copy revents results from the poll to the curl_multi_wait poll
struct, the bit values of the actual underlying poll() implementation
may not be the same as the ones in the public libcurl API! */
for(i = 0; i < extra_nfds; i++) {
- unsigned short mask = 0;
unsigned r = ufds[curlfds + i].revents;
-
+ unsigned short mask = 0;
+#ifdef USE_WINSOCK
+ wsa_events.lNetworkEvents = 0;
+ if(WSAEnumNetworkEvents(extra_fds[i].fd, NULL, &wsa_events) == 0) {
+ if(wsa_events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE))
+ mask |= CURL_WAIT_POLLIN;
+ if(wsa_events.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE))
+ mask |= CURL_WAIT_POLLOUT;
+ if(wsa_events.lNetworkEvents & FD_OOB)
+ mask |= CURL_WAIT_POLLPRI;
+ if(ret && pollrc <= 0 && wsa_events.lNetworkEvents)
+ retcode++;
+ }
+ WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0);
+ if(pollrc <= 0)
+ continue;
+#endif
if(r & POLLIN)
mask |= CURL_WAIT_POLLIN;
if(r & POLLOUT)
@@ -1220,6 +1308,35 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
extra_fds[i].revents = mask;
}
+#ifdef USE_WINSOCK
+ /* Count up all our own sockets that had activity,
+ and remove them from the event. */
+ if(curlfds) {
+ data = multi->easyp;
+ while(data) {
+ bitmap = multi_getsock(data, sockbunch);
+
+ for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
+ if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) {
+ wsa_events.lNetworkEvents = 0;
+ if(WSAEnumNetworkEvents(sockbunch[i], NULL, &wsa_events) == 0) {
+ if(ret && pollrc <= 0 && wsa_events.lNetworkEvents)
+ retcode++;
+ }
+ WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
+ }
+ else {
+ /* break on entry not checked for being readable or writable */
+ break;
+ }
+ }
+
+ data = data->next;
+ }
+ }
+
+ WSAResetEvent(multi->wsa_event);
+#else
#ifdef ENABLE_WAKEUP
if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
if(ufds[curlfds + extra_nfds].revents & POLLIN) {
@@ -1232,10 +1349,8 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
when there is no more data, breaking the loop. */
nread = sread(multi->wakeup_pair[0], buf, sizeof(buf));
if(nread <= 0) {
-#ifndef USE_WINSOCK
if(nread < 0 && EINTR == SOCKERRNO)
continue;
-#endif
break;
}
}
@@ -1244,6 +1359,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
}
}
#endif
+#endif
}
}
@@ -1251,10 +1367,11 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
free(ufds);
if(ret)
*ret = retcode;
- if(!extrawait || nfds)
- /* if any socket was checked */
- ;
- else {
+#if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK)
+ if(extrawait && !nfds && !use_wakeup) {
+#else
+ if(extrawait && !nfds) {
+#endif
long sleep_ms = 0;
/* Avoid busy-looping when there's nothing particular to wait for */
@@ -1303,6 +1420,10 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
return CURLM_BAD_HANDLE;
#ifdef ENABLE_WAKEUP
+#ifdef USE_WINSOCK
+ if(WSASetEvent(multi->wsa_event))
+ return CURLM_OK;
+#else
/* the wakeup_pair variable is only written during init and cleanup,
making it safe to access from another thread after the init part
and before cleanup */
@@ -1336,6 +1457,7 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
}
}
#endif
+#endif
return CURLM_WAKEUP_FAILURE;
}
@@ -2153,12 +2275,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
}
else if((CURLE_HTTP2_STREAM == result) &&
- Curl_h2_http_1_1_error(data->conn)) {
+ Curl_h2_http_1_1_error(data)) {
CURLcode ret = Curl_retry_request(data, &newurl);
if(!ret) {
infof(data, "Downgrades to HTTP/1.1!\n");
- connclose(data->conn, "Disconnect HTTP/2 for HTTP/1");
+ streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1");
data->state.httpwant = CURL_HTTP_VERSION_1_1;
/* clear the error message bit too as we ignore the one we got */
data->state.errorbuf = FALSE;
@@ -2478,10 +2600,14 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
Curl_hash_destroy(&multi->hostcache);
Curl_psl_destroy(&multi->psl);
+#ifdef USE_WINSOCK
+ WSACloseEvent(multi->wsa_event);
+#else
#ifdef ENABLE_WAKEUP
sclose(multi->wakeup_pair[0]);
sclose(multi->wakeup_pair[1]);
#endif
+#endif
free(multi);
return CURLM_OK;
diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h
index edf790132a..96b84749fc 100644
--- a/libs/libcurl/src/multihandle.h
+++ b/libs/libcurl/src/multihandle.h
@@ -140,10 +140,14 @@ struct Curl_multi {
previous callback */
unsigned int max_concurrent_streams;
+#ifdef USE_WINSOCK
+ WSAEVENT wsa_event; /* winsock event used for waits */
+#else
#ifdef ENABLE_WAKEUP
curl_socket_t wakeup_pair[2]; /* socketpair() used for wakeup
0 is used for read, 1 is used for write */
#endif
+#endif
/* multiplexing wanted */
bool multiplexing;
bool recheckstate; /* see Curl_multi_connchanged */
diff --git a/libs/libcurl/src/non-ascii.c b/libs/libcurl/src/non-ascii.c
index 30c240b637..932cf89eef 100644
--- a/libs/libcurl/src/non-ascii.c
+++ b/libs/libcurl/src/non-ascii.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -127,7 +127,7 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data,
&output_ptr, &out_bytes);
if(!data)
iconv_close(tmpcd);
- if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+ if((rc == ICONV_ERROR) || (in_bytes)) {
failf(data,
"The Curl_convert_to_network iconv call failed with errno %i: %s",
errno, strerror(errno));
@@ -193,7 +193,7 @@ CURLcode Curl_convert_from_network(struct Curl_easy *data,
&output_ptr, &out_bytes);
if(!data)
iconv_close(tmpcd);
- if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+ if((rc == ICONV_ERROR) || (in_bytes)) {
failf(data,
"Curl_convert_from_network iconv call failed with errno %i: %s",
errno, strerror(errno));
@@ -260,7 +260,7 @@ CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
&output_ptr, &out_bytes);
if(!data)
iconv_close(tmpcd);
- if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+ if((rc == ICONV_ERROR) || (in_bytes)) {
failf(data,
"The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
errno, strerror(errno));
diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c
index b6980c5900..0b8bc34a03 100644
--- a/libs/libcurl/src/openldap.c
+++ b/libs/libcurl/src/openldap.c
@@ -76,16 +76,16 @@ extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
LDAP **ld);
#endif
-static CURLcode ldap_setup_connection(struct Curl_easy *data,
- struct connectdata *conn);
-static CURLcode ldap_do(struct Curl_easy *data, bool *done);
-static CURLcode ldap_done(struct Curl_easy *data, CURLcode, bool);
-static CURLcode ldap_connect(struct Curl_easy *data, bool *done);
-static CURLcode ldap_connecting(struct Curl_easy *data, bool *done);
-static CURLcode ldap_disconnect(struct Curl_easy *data,
- struct connectdata *conn, bool dead);
+static CURLcode oldap_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn);
+static CURLcode oldap_do(struct Curl_easy *data, bool *done);
+static CURLcode oldap_done(struct Curl_easy *data, CURLcode, bool);
+static CURLcode oldap_connect(struct Curl_easy *data, bool *done);
+static CURLcode oldap_connecting(struct Curl_easy *data, bool *done);
+static CURLcode oldap_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead);
-static Curl_recv ldap_recv;
+static Curl_recv oldap_recv;
/*
* LDAP protocol handler.
@@ -93,20 +93,21 @@ static Curl_recv ldap_recv;
const struct Curl_handler Curl_handler_ldap = {
"LDAP", /* scheme */
- ldap_setup_connection, /* setup_connection */
- ldap_do, /* do_it */
- ldap_done, /* done */
+ oldap_setup_connection, /* setup_connection */
+ oldap_do, /* do_it */
+ oldap_done, /* done */
ZERO_NULL, /* do_more */
- ldap_connect, /* connect_it */
- ldap_connecting, /* connecting */
+ oldap_connect, /* connect_it */
+ oldap_connecting, /* connecting */
ZERO_NULL, /* doing */
ZERO_NULL, /* proto_getsock */
ZERO_NULL, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
ZERO_NULL, /* perform_getsock */
- ldap_disconnect, /* disconnect */
+ oldap_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_LDAP, /* defport */
CURLPROTO_LDAP, /* protocol */
CURLPROTO_LDAP, /* family */
@@ -120,20 +121,21 @@ const struct Curl_handler Curl_handler_ldap = {
const struct Curl_handler Curl_handler_ldaps = {
"LDAPS", /* scheme */
- ldap_setup_connection, /* setup_connection */
- ldap_do, /* do_it */
- ldap_done, /* done */
+ oldap_setup_connection, /* setup_connection */
+ oldap_do, /* do_it */
+ oldap_done, /* done */
ZERO_NULL, /* do_more */
- ldap_connect, /* connect_it */
- ldap_connecting, /* connecting */
+ oldap_connect, /* connect_it */
+ oldap_connecting, /* connecting */
ZERO_NULL, /* doing */
ZERO_NULL, /* proto_getsock */
ZERO_NULL, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
ZERO_NULL, /* perform_getsock */
- ldap_disconnect, /* disconnect */
+ oldap_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_LDAPS, /* defport */
CURLPROTO_LDAPS, /* protocol */
CURLPROTO_LDAP, /* family */
@@ -171,8 +173,8 @@ struct ldapreqinfo {
int nument;
};
-static CURLcode ldap_setup_connection(struct Curl_easy *data,
- struct connectdata *conn)
+static CURLcode oldap_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
{
struct ldapconninfo *li;
LDAPURLDesc *lud;
@@ -207,7 +209,7 @@ static CURLcode ldap_setup_connection(struct Curl_easy *data,
static Sockbuf_IO ldapsb_tls;
#endif
-static CURLcode ldap_connect(struct Curl_easy *data, bool *done)
+static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
{
struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
@@ -255,7 +257,7 @@ static CURLcode ldap_connect(struct Curl_easy *data, bool *done)
return CURLE_OK;
}
-static CURLcode ldap_connecting(struct Curl_easy *data, bool *done)
+static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
{
struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
@@ -354,25 +356,28 @@ static CURLcode ldap_connecting(struct Curl_easy *data, bool *done)
if(info)
ldap_memfree(info);
- conn->recv[FIRSTSOCKET] = ldap_recv;
+ conn->recv[FIRSTSOCKET] = oldap_recv;
*done = TRUE;
return CURLE_OK;
}
-static CURLcode ldap_disconnect(struct Curl_easy *data,
- struct connectdata *conn, bool dead_connection)
+static CURLcode oldap_disconnect(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool dead_connection)
{
struct ldapconninfo *li = conn->proto.ldapc;
(void) dead_connection;
if(li) {
if(li->ld) {
+#ifdef USE_SSL
if(conn->ssl[FIRSTSOCKET].use) {
Sockbuf *sb;
ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data);
}
+#endif
ldap_unbind_ext(li->ld, NULL, NULL);
li->ld = NULL;
}
@@ -382,7 +387,7 @@ static CURLcode ldap_disconnect(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode ldap_do(struct Curl_easy *data, bool *done)
+static CURLcode oldap_do(struct Curl_easy *data, bool *done)
{
struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
@@ -427,8 +432,8 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
return CURLE_OK;
}
-static CURLcode ldap_done(struct Curl_easy *data, CURLcode res,
- bool premature)
+static CURLcode oldap_done(struct Curl_easy *data, CURLcode res,
+ bool premature)
{
struct connectdata *conn = data->conn;
struct ldapreqinfo *lr = data->req.p.ldap;
@@ -450,8 +455,8 @@ static CURLcode ldap_done(struct Curl_easy *data, CURLcode res,
return CURLE_OK;
}
-static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf,
- size_t len, CURLcode *err)
+static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
+ size_t len, CURLcode *err)
{
struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
@@ -547,7 +552,7 @@ static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf,
rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals)) {
int i;
- if(bv.bv_val == NULL)
+ if(!bv.bv_val)
break;
if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
@@ -555,7 +560,7 @@ static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf,
else
binary = 0;
- if(bvals == NULL) {
+ if(!bvals) {
writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
if(writeerr) {
*err = writeerr;
@@ -664,7 +669,7 @@ static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf,
data->req.bytecount += bvals[i].bv_len + 1;
}
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
if(writeerr) {
*err = writeerr;
return -1;
@@ -673,14 +678,14 @@ static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf,
data->req.bytecount++;
}
ber_memfree(bvals);
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
if(writeerr) {
*err = writeerr;
return -1;
}
data->req.bytecount++;
}
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
+ writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
if(writeerr) {
*err = writeerr;
return -1;
diff --git a/libs/libcurl/src/pop3.c b/libs/libcurl/src/pop3.c
index ccfebd02af..9b6ea64804 100644
--- a/libs/libcurl/src/pop3.c
+++ b/libs/libcurl/src/pop3.c
@@ -131,6 +131,7 @@ const struct Curl_handler Curl_handler_pop3 = {
pop3_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_POP3, /* defport */
CURLPROTO_POP3, /* protocol */
CURLPROTO_POP3, /* family */
@@ -159,6 +160,7 @@ const struct Curl_handler Curl_handler_pop3s = {
pop3_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_POP3S, /* defport */
CURLPROTO_POP3S, /* protocol */
CURLPROTO_POP3, /* family */
@@ -709,7 +711,7 @@ static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code,
for(;;) {
size_t llen;
size_t wordlen;
- unsigned int mechbit;
+ unsigned short mechbit;
while(len &&
(*line == ' ' || *line == '\t' ||
@@ -1515,8 +1517,17 @@ CURLcode Curl_pop3_write(struct Curl_easy *data, char *str, size_t nread)
if(prev) {
/* If the partial match was the CRLF and dot then only write the CRLF
as the server would have inserted the dot */
- result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB,
- strip_dot ? prev - 1 : prev);
+ if(strip_dot && prev - 1 > 0) {
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB,
+ prev - 1);
+ }
+ else if(!strip_dot) {
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB,
+ prev);
+ }
+ else {
+ result = CURLE_OK;
+ }
if(result)
return result;
diff --git a/libs/libcurl/src/progress.c b/libs/libcurl/src/progress.c
index cc040a8733..4bcd615eba 100644
--- a/libs/libcurl/src/progress.c
+++ b/libs/libcurl/src/progress.c
@@ -241,6 +241,8 @@ void Curl_pgrsStartNow(struct Curl_easy *data)
data->progress.is_t_startransfer_set = false;
data->progress.ul_limit_start = data->progress.start;
data->progress.dl_limit_start = data->progress.start;
+ data->progress.ul_limit_size = 0;
+ data->progress.dl_limit_size = 0;
data->progress.downloaded = 0;
data->progress.uploaded = 0;
/* clear all bits except HIDE and HEADERS_OUT */
@@ -369,94 +371,82 @@ void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
}
}
+/* returns the average speed in bytes / second */
+static curl_off_t trspeed(curl_off_t size, /* number of bytes */
+ curl_off_t us) /* microseconds */
+{
+ if(us < 1)
+ return size * 1000000;
+ return (curl_off_t)((long double)size/us * 1000000);
+}
+
/* returns TRUE if it's time to show the progress meter */
static bool progress_calc(struct Curl_easy *data, struct curltime now)
{
- curl_off_t timespent;
- curl_off_t timespent_ms; /* milliseconds */
- curl_off_t dl = data->progress.downloaded;
- curl_off_t ul = data->progress.uploaded;
bool timetoshow = FALSE;
+ struct Progress * const p = &data->progress;
- /* The time spent so far (from the start) */
- data->progress.timespent = Curl_timediff_us(now, data->progress.start);
- timespent = (curl_off_t)data->progress.timespent/1000000; /* seconds */
- timespent_ms = (curl_off_t)data->progress.timespent/1000; /* ms */
-
- /* The average download speed this far */
- if(dl < CURL_OFF_T_MAX/1000)
- data->progress.dlspeed = (dl * 1000 / (timespent_ms>0?timespent_ms:1));
- else
- data->progress.dlspeed = (dl / (timespent>0?timespent:1));
-
- /* The average upload speed this far */
- if(ul < CURL_OFF_T_MAX/1000)
- data->progress.ulspeed = (ul * 1000 / (timespent_ms>0?timespent_ms:1));
- else
- data->progress.ulspeed = (ul / (timespent>0?timespent:1));
+ /* The time spent so far (from the start) in microseconds */
+ p->timespent = Curl_timediff_us(now, p->start);
+ p->dlspeed = trspeed(p->downloaded, p->timespent);
+ p->ulspeed = trspeed(p->uploaded, p->timespent);
/* Calculations done at most once a second, unless end is reached */
- if(data->progress.lastshow != now.tv_sec) {
+ if(p->lastshow != now.tv_sec) {
int countindex; /* amount of seconds stored in the speeder array */
- int nowindex = data->progress.speeder_c% CURR_TIME;
- data->progress.lastshow = now.tv_sec;
+ int nowindex = p->speeder_c% CURR_TIME;
+ p->lastshow = now.tv_sec;
timetoshow = TRUE;
/* Let's do the "current speed" thing, with the dl + ul speeds
combined. Store the speed at entry 'nowindex'. */
- data->progress.speeder[ nowindex ] =
- data->progress.downloaded + data->progress.uploaded;
+ p->speeder[ nowindex ] = p->downloaded + p->uploaded;
/* remember the exact time for this moment */
- data->progress.speeder_time [ nowindex ] = now;
+ p->speeder_time [ nowindex ] = now;
/* advance our speeder_c counter, which is increased every time we get
here and we expect it to never wrap as 2^32 is a lot of seconds! */
- data->progress.speeder_c++;
+ p->speeder_c++;
/* figure out how many index entries of data we have stored in our speeder
array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of
transfer. Imagine, after one second we have filled in two entries,
after two seconds we've filled in three entries etc. */
- countindex = ((data->progress.speeder_c >= CURR_TIME)?
- CURR_TIME:data->progress.speeder_c) - 1;
+ countindex = ((p->speeder_c >= CURR_TIME)? CURR_TIME:p->speeder_c) - 1;
/* first of all, we don't do this if there's no counted seconds yet */
if(countindex) {
int checkindex;
timediff_t span_ms;
+ curl_off_t amount;
/* Get the index position to compare with the 'nowindex' position.
Get the oldest entry possible. While we have less than CURR_TIME
entries, the first entry will remain the oldest. */
- checkindex = (data->progress.speeder_c >= CURR_TIME)?
- data->progress.speeder_c%CURR_TIME:0;
+ checkindex = (p->speeder_c >= CURR_TIME)? p->speeder_c%CURR_TIME:0;
/* Figure out the exact time for the time span */
- span_ms = Curl_timediff(now, data->progress.speeder_time[checkindex]);
+ span_ms = Curl_timediff(now, p->speeder_time[checkindex]);
if(0 == span_ms)
span_ms = 1; /* at least one millisecond MUST have passed */
/* Calculate the average speed the last 'span_ms' milliseconds */
- {
- curl_off_t amount = data->progress.speeder[nowindex]-
- data->progress.speeder[checkindex];
-
- if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */)
- /* the 'amount' value is bigger than would fit in 32 bits if
- multiplied with 1000, so we use the double math for this */
- data->progress.current_speed = (curl_off_t)
- ((double)amount/((double)span_ms/1000.0));
- else
- /* the 'amount' value is small enough to fit within 32 bits even
- when multiplied with 1000 */
- data->progress.current_speed = amount*CURL_OFF_T_C(1000)/span_ms;
- }
+ amount = p->speeder[nowindex]- p->speeder[checkindex];
+
+ if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */)
+ /* the 'amount' value is bigger than would fit in 32 bits if
+ multiplied with 1000, so we use the double math for this */
+ p->current_speed = (curl_off_t)
+ ((double)amount/((double)span_ms/1000.0));
+ else
+ /* the 'amount' value is small enough to fit within 32 bits even
+ when multiplied with 1000 */
+ p->current_speed = amount*CURL_OFF_T_C(1000)/span_ms;
}
else
/* the first second we use the average */
- data->progress.current_speed =
- data->progress.ulspeed + data->progress.dlspeed;
+ p->current_speed = p->ulspeed + p->dlspeed;
} /* Calculations end */
return timetoshow;
diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c
index 3029ff5264..007d5c50b6 100644
--- a/libs/libcurl/src/rtsp.c
+++ b/libs/libcurl/src/rtsp.c
@@ -109,6 +109,7 @@ const struct Curl_handler Curl_handler_rtsp = {
rtsp_disconnect, /* disconnect */
rtsp_rtp_readwrite, /* readwrite */
rtsp_conncheck, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_RTSP, /* defport */
CURLPROTO_RTSP, /* protocol */
CURLPROTO_RTSP, /* family */
@@ -680,7 +681,7 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
}
}
- if(rtp_dataleft != 0 && rtp[0] == '$') {
+ if(rtp_dataleft && rtp[0] == '$') {
DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft,
*readmore ? "(READMORE)" : ""));
@@ -824,7 +825,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header)
/* Copy the id substring into a new buffer */
data->set.str[STRING_RTSP_SESSION_ID] = malloc(idlen + 1);
- if(data->set.str[STRING_RTSP_SESSION_ID] == NULL)
+ if(!data->set.str[STRING_RTSP_SESSION_ID])
return CURLE_OUT_OF_MEMORY;
memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, idlen);
(data->set.str[STRING_RTSP_SESSION_ID])[idlen] = '\0';
diff --git a/libs/libcurl/src/select.c b/libs/libcurl/src/select.c
index d7346b195f..52dca5a2c0 100644
--- a/libs/libcurl/src/select.c
+++ b/libs/libcurl/src/select.c
@@ -442,7 +442,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
if(ufds[i].events & POLLPRI)
ufds[i].revents |= POLLPRI;
}
- if(ufds[i].revents != 0)
+ if(ufds[i].revents)
r++;
}
diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c
index b57b7878c2..e41bb805f5 100644
--- a/libs/libcurl/src/sendf.c
+++ b/libs/libcurl/src/sendf.c
@@ -65,7 +65,7 @@ static size_t convert_lineends(struct Curl_easy *data,
char *inPtr, *outPtr;
/* sanity check */
- if((startPtr == NULL) || (size < 1)) {
+ if(!startPtr || (size < 1)) {
return size;
}
@@ -309,6 +309,18 @@ CURLcode Curl_write(struct Curl_easy *data,
conn = data->conn;
num = (sockfd == conn->sock[SECONDARYSOCKET]);
+#ifdef CURLDEBUG
+ {
+ /* Allow debug builds to override this logic to force short sends
+ */
+ char *p = getenv("CURL_SMALLSENDS");
+ if(p) {
+ size_t altsize = (size_t)strtoul(p, NULL, 10);
+ if(altsize)
+ len = CURLMIN(len, altsize);
+ }
+ }
+#endif
bytes_written = conn->send[num](data, num, mem, len, &result);
*written = bytes_written;
@@ -604,7 +616,7 @@ static CURLcode chop_write(struct Curl_easy *data,
/* Curl_client_write() sends data to the write callback(s)
The bit pattern defines to what "streams" to write to. Body and/or header.
- The defines are in sendf.h of course.
+ The defines are in sendf.h of course. "len" is not allowed to be 0.
If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
local character encoding. This is a problem and should be changed in
@@ -616,9 +628,8 @@ CURLcode Curl_client_write(struct Curl_easy *data,
size_t len)
{
struct connectdata *conn = data->conn;
- if(0 == len)
- len = strlen(ptr);
+ DEBUGASSERT(len);
DEBUGASSERT(type <= 3);
/* FTP data may need conversion. */
diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c
index 022dd38003..fb8b86d474 100644
--- a/libs/libcurl/src/setopt.c
+++ b/libs/libcurl/src/setopt.c
@@ -426,6 +426,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
version_max = C_SSLVERSION_MAX_VALUE(arg);
if(version < CURL_SSLVERSION_DEFAULT ||
+ version == CURL_SSLVERSION_SSLv2 ||
+ version == CURL_SSLVERSION_SSLv3 ||
version >= CURL_SSLVERSION_LAST ||
version_max < CURL_SSLVERSION_MAX_NONE ||
version_max >= CURL_SSLVERSION_MAX_LAST)
@@ -752,6 +754,20 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
}
data->state.cookielist = cl; /* store the list for later use */
}
+ else {
+ /* clear the list of cookie files */
+ curl_slist_free_all(data->state.cookielist);
+ data->state.cookielist = NULL;
+
+ if(!data->share || !data->share->cookies) {
+ /* throw away all existing cookies if this isn't a shared cookie
+ container */
+ Curl_cookie_clearall(data->cookies);
+ Curl_cookie_cleanup(data->cookies);
+ }
+ /* disable the cookie engine */
+ data->cookies = NULL;
+ }
break;
case CURLOPT_COOKIEJAR:
@@ -797,7 +813,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_COOKIELIST:
argptr = va_arg(param, char *);
- if(argptr == NULL)
+ if(!argptr)
break;
if(strcasecompare(argptr, "ALL")) {
@@ -2025,6 +2041,20 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE],
va_arg(param, char *));
break;
+ case CURLOPT_CAINFO_BLOB:
+ /*
+ * Blob that holds CA info for SSL connection.
+ * Specify entire PEM of the CA certificate
+ */
+#ifdef USE_SSL
+ if(Curl_ssl->supports & SSLSUPP_CAINFO_BLOB)
+ result = Curl_setblobopt(&data->set.blobs[BLOB_CAINFO],
+ va_arg(param, struct curl_blob *));
+ else
+#endif
+ return CURLE_NOT_BUILT_IN;
+
+ break;
#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_CAINFO:
/*
@@ -2034,6 +2064,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY],
va_arg(param, char *));
break;
+ case CURLOPT_PROXY_CAINFO_BLOB:
+ /*
+ * Blob that holds CA info for SSL connection proxy.
+ * Specify entire PEM of the CA certificate
+ */
+#ifdef USE_SSL
+ if(Curl_ssl->supports & SSLSUPP_CAINFO_BLOB)
+ result = Curl_setblobopt(&data->set.blobs[BLOB_CAINFO_PROXY],
+ va_arg(param, struct curl_blob *));
+ else
+#endif
+ return CURLE_NOT_BUILT_IN;
+ break;
#endif
case CURLOPT_CAPATH:
/*
@@ -2155,7 +2198,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
else if(arg < UPLOADBUFFER_MIN)
arg = UPLOADBUFFER_MIN;
- data->set.upload_buffer_size = arg;
+ data->set.upload_buffer_size = (unsigned int)arg;
Curl_safefree(data->state.ulbuf); /* force a realloc next opportunity */
break;
@@ -2268,12 +2311,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_SSL_OPTIONS:
arg = va_arg(param, long);
- data->set.ssl.enable_beast =
- (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
+ data->set.ssl.enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
data->set.ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
data->set.ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
+ data->set.ssl.auto_client_cert = !!(arg & CURLSSLOPT_AUTO_CLIENT_CERT);
/* If a setting is added here it should also be added in dohprobe()
which sets its own CURLOPT_SSL_OPTIONS based on these settings. */
break;
@@ -2281,13 +2324,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSL_OPTIONS:
arg = va_arg(param, long);
- data->set.proxy_ssl.enable_beast =
- (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
+ data->set.proxy_ssl.enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
- data->set.proxy_ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
data->set.proxy_ssl.revoke_best_effort =
!!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
+ data->set.proxy_ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
+ data->set.proxy_ssl.auto_client_cert =
+ !!(arg & CURLSSLOPT_AUTO_CLIENT_CERT);
break;
#endif
@@ -2895,7 +2939,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.trailer_data = va_arg(param, void *);
#endif
break;
-#ifdef USE_HSTS
+#ifndef CURL_DISABLE_HSTS
case CURLOPT_HSTSREADFUNCTION:
data->set.hsts_read = va_arg(param, curl_hstsread_callback);
break;
diff --git a/libs/libcurl/src/setup-vms.h b/libs/libcurl/src/setup-vms.h
index ba75dc295b..a6710d9076 100644
--- a/libs/libcurl/src/setup-vms.h
+++ b/libs/libcurl/src/setup-vms.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -87,7 +87,7 @@ static char *vms_translate_path(const char *path)
/* See if the result is in VMS format, if not, we are done */
/* Assume that this is a PATH, not just some data */
test_str = strpbrk(path, ":[<^");
- if(test_str == NULL) {
+ if(!test_str) {
return (char *)path;
}
@@ -119,7 +119,7 @@ static char *vms_getenv(const char *envvar)
/* first use the DECC getenv() function */
result = decc$getenv(envvar);
- if(result == NULL) {
+ if(!result) {
return result;
}
@@ -154,7 +154,7 @@ static struct passwd *vms_getpwuid(uid_t uid)
#endif
my_passwd = decc_getpwuid(uid);
- if(my_passwd == NULL) {
+ if(!my_passwd) {
return my_passwd;
}
diff --git a/libs/libcurl/src/share.c b/libs/libcurl/src/share.c
index 4f1804dbd2..9c43c8f705 100644
--- a/libs/libcurl/src/share.c
+++ b/libs/libcurl/src/share.c
@@ -235,7 +235,7 @@ Curl_share_lock(struct Curl_easy *data, curl_lock_data type,
{
struct Curl_share *share = data->share;
- if(share == NULL)
+ if(!share)
return CURLSHE_INVALID;
if(share->specifier & (1<<type)) {
@@ -252,7 +252,7 @@ Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
{
struct Curl_share *share = data->share;
- if(share == NULL)
+ if(!share)
return CURLSHE_INVALID;
if(share->specifier & (1<<type)) {
diff --git a/libs/libcurl/src/sigpipe.h b/libs/libcurl/src/sigpipe.h
index 430cfc6489..d6ec5fca3c 100644
--- a/libs/libcurl/src/sigpipe.h
+++ b/libs/libcurl/src/sigpipe.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -24,7 +24,7 @@
#include "curl_setup.h"
#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && \
- (defined(USE_OPENSSL) || defined(USE_MBEDTLS))
+ (defined(USE_OPENSSL) || defined(USE_MBEDTLS) || defined(USE_WOLFSSL))
#include <signal.h>
struct sigpipe_ignore {
diff --git a/libs/libcurl/src/smb.c b/libs/libcurl/src/smb.c
index 183bc12a51..39facb267d 100644
--- a/libs/libcurl/src/smb.c
+++ b/libs/libcurl/src/smb.c
@@ -88,6 +88,7 @@ const struct Curl_handler Curl_handler_smb = {
smb_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_SMB, /* defport */
CURLPROTO_SMB, /* protocol */
CURLPROTO_SMB, /* family */
@@ -114,6 +115,7 @@ const struct Curl_handler Curl_handler_smbs = {
smb_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_SMBS, /* defport */
CURLPROTO_SMBS, /* protocol */
CURLPROTO_SMB, /* family */
@@ -627,9 +629,8 @@ static CURLcode smb_send_and_recv(struct Curl_easy *data, void **msg)
/* Check if there is data in the transfer buffer */
if(!smbc->send_size && smbc->upload_size) {
- size_t nread = smbc->upload_size > data->set.upload_buffer_size ?
- data->set.upload_buffer_size :
- smbc->upload_size;
+ size_t nread = smbc->upload_size > (size_t)data->set.upload_buffer_size ?
+ (size_t)data->set.upload_buffer_size : smbc->upload_size;
data->req.upload_fromhere = data->state.ulbuf;
result = Curl_fillreadbuffer(data, nread, &nread);
if(result && result != CURLE_AGAIN)
diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c
index be4cd675ca..feffc05bc9 100644
--- a/libs/libcurl/src/smtp.c
+++ b/libs/libcurl/src/smtp.c
@@ -136,6 +136,7 @@ const struct Curl_handler Curl_handler_smtp = {
smtp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_SMTP, /* defport */
CURLPROTO_SMTP, /* protocol */
CURLPROTO_SMTP, /* family */
@@ -164,6 +165,7 @@ const struct Curl_handler Curl_handler_smtps = {
smtp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_SMTPS, /* defport */
CURLPROTO_SMTPS, /* protocol */
CURLPROTO_SMTP, /* family */
@@ -894,7 +896,7 @@ static CURLcode smtp_state_ehlo_resp(struct Curl_easy *data,
for(;;) {
size_t llen;
size_t wordlen;
- unsigned int mechbit;
+ unsigned short mechbit;
while(len &&
(*line == ' ' || *line == '\t' ||
@@ -1821,7 +1823,7 @@ CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread)
return CURLE_OUT_OF_MEMORY;
}
}
- DEBUGASSERT(data->set.upload_buffer_size >= (size_t)nread);
+ DEBUGASSERT((size_t)data->set.upload_buffer_size >= (size_t)nread);
/* Have we already sent part of the EOB? */
eob_sent = smtp->eob;
diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c
index d1c2a2ed14..5cde4a46a1 100644
--- a/libs/libcurl/src/socks.c
+++ b/libs/libcurl/src/socks.c
@@ -426,7 +426,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
*/
/* wrong version ? */
- if(socksreq[0] != 0) {
+ if(socksreq[0]) {
failf(data,
"SOCKS4 reply has wrong version, version should be 0.");
return CURLPX_BAD_VERSION;
@@ -742,7 +742,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
return CURLPX_OK;
}
/* ignore the first (VER) byte */
- else if(socksreq[1] != 0) { /* status */
+ else if(socksreq[1]) { /* status */
failf(data, "User was rejected by the SOCKS5 server (%d %d).",
socksreq[0], socksreq[1]);
return CURLPX_USER_REJECTED;
@@ -927,7 +927,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
"SOCKS5 reply has wrong version, version should be 5.");
return CURLPX_BAD_VERSION;
}
- else if(socksreq[1] != 0) { /* Anything besides 0 is an error */
+ else if(socksreq[1]) { /* Anything besides 0 is an error */
CURLproxycode rc = CURLPX_REPLY_UNASSIGNED;
int code = socksreq[1];
failf(data, "Can't complete SOCKS5 connection to %s. (%d)",
diff --git a/libs/libcurl/src/socks_gssapi.c b/libs/libcurl/src/socks_gssapi.c
index 3ab786d0bd..10b942a984 100644
--- a/libs/libcurl/src/socks_gssapi.c
+++ b/libs/libcurl/src/socks_gssapi.c
@@ -195,7 +195,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
return CURLE_COULDNT_CONNECT;
}
- if(gss_send_token.length != 0) {
+ if(gss_send_token.length) {
socksreq[0] = 1; /* GSS-API subnegotiation version */
socksreq[1] = 1; /* authentication message type */
us_length = htons((short)gss_send_token.length);
diff --git a/libs/libcurl/src/socks_sspi.c b/libs/libcurl/src/socks_sspi.c
index b343538f0c..813c6be574 100644
--- a/libs/libcurl/src/socks_sspi.c
+++ b/libs/libcurl/src/socks_sspi.c
@@ -198,7 +198,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
return CURLE_COULDNT_CONNECT;
}
- if(sspi_send_token.cbBuffer != 0) {
+ if(sspi_send_token.cbBuffer) {
socksreq[0] = 1; /* GSS-API subnegotiation version */
socksreq[1] = 1; /* authentication message type */
us_length = htons((short)sspi_send_token.cbBuffer);
diff --git a/libs/libcurl/src/splay.c b/libs/libcurl/src/splay.c
index 98baf5d871..a94e2c85e9 100644
--- a/libs/libcurl/src/splay.c
+++ b/libs/libcurl/src/splay.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1997 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1997 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -42,7 +42,7 @@ struct Curl_tree *Curl_splay(struct curltime i,
{
struct Curl_tree N, *l, *r, *y;
- if(t == NULL)
+ if(!t)
return t;
N.smaller = N.larger = NULL;
l = r = &N;
@@ -50,14 +50,14 @@ struct Curl_tree *Curl_splay(struct curltime i,
for(;;) {
long comp = compare(i, t->key);
if(comp < 0) {
- if(t->smaller == NULL)
+ if(!t->smaller)
break;
if(compare(i, t->smaller->key) < 0) {
y = t->smaller; /* rotate smaller */
t->smaller = y->larger;
y->larger = t;
t = y;
- if(t->smaller == NULL)
+ if(!t->smaller)
break;
}
r->smaller = t; /* link smaller */
@@ -65,14 +65,14 @@ struct Curl_tree *Curl_splay(struct curltime i,
t = t->smaller;
}
else if(comp > 0) {
- if(t->larger == NULL)
+ if(!t->larger)
break;
if(compare(i, t->larger->key) > 0) {
y = t->larger; /* rotate larger */
t->larger = y->smaller;
y->smaller = t;
t = y;
- if(t->larger == NULL)
+ if(!t->larger)
break;
}
l->larger = t; /* link larger */
@@ -104,7 +104,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i,
(time_t)-1, (unsigned int)-1
}; /* will *NEVER* appear */
- if(node == NULL)
+ if(!node)
return t;
if(t != NULL) {
@@ -125,7 +125,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i,
}
}
- if(t == NULL) {
+ if(!t) {
node->smaller = node->larger = NULL;
}
else if(compare(i, t->key) < 0) {
@@ -262,7 +262,7 @@ int Curl_splayremove(struct Curl_tree *t,
}
else {
/* Remove the root node */
- if(t->smaller == NULL)
+ if(!t->smaller)
x = t->larger;
else {
x = Curl_splay(removenode->key, t->smaller);
diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c
index 3862aabd6f..5298a0d76c 100644
--- a/libs/libcurl/src/strerror.c
+++ b/libs/libcurl/src/strerror.c
@@ -320,9 +320,12 @@ curl_easy_strerror(CURLcode error)
case CURLE_QUIC_CONNECT_ERROR:
return "QUIC connection error";
- case CURLE_PROXY:
+ case CURLE_PROXY:
return "proxy handshake error";
+ case CURLE_SSL_CLIENTCERT:
+ return "SSL Client Certificate required";
+
/* error codes not used by current libcurl */
case CURLE_OBSOLETE20:
case CURLE_OBSOLETE24:
diff --git a/libs/libcurl/src/system_win32.c b/libs/libcurl/src/system_win32.c
index 2132f43ef7..2939fd0d74 100644
--- a/libs/libcurl/src/system_win32.c
+++ b/libs/libcurl/src/system_win32.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2016 - 2020, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2016 - 2021, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -58,7 +58,7 @@ CURLcode Curl_win32_init(long flags)
wVersionRequested = MAKEWORD(2, 2);
res = WSAStartup(wVersionRequested, &wsaData);
- if(res != 0)
+ if(res)
/* Tell the user that we couldn't find a usable */
/* winsock.dll. */
return CURLE_FAILED_INIT;
diff --git a/libs/libcurl/src/telnet.c b/libs/libcurl/src/telnet.c
index f96a4cb4c5..fdd137fb0c 100644
--- a/libs/libcurl/src/telnet.c
+++ b/libs/libcurl/src/telnet.c
@@ -185,6 +185,7 @@ const struct Curl_handler Curl_handler_telnet = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_TELNET, /* defport */
CURLPROTO_TELNET, /* protocol */
CURLPROTO_TELNET, /* family */
@@ -921,7 +922,7 @@ static void suboption(struct Curl_easy *data)
size_t tmplen = (strlen(v->data) + 1);
/* Add the variable only if it fits */
if(len + tmplen < (int)sizeof(temp)-6) {
- if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
+ if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) {
msnprintf((char *)&temp[len], sizeof(temp) - len,
"%c%s%c%s", CURL_NEW_ENV_VAR, varname,
CURL_NEW_ENV_VALUE, varval);
diff --git a/libs/libcurl/src/tftp.c b/libs/libcurl/src/tftp.c
index 76d3ff4515..11150af361 100644
--- a/libs/libcurl/src/tftp.c
+++ b/libs/libcurl/src/tftp.c
@@ -182,6 +182,7 @@ const struct Curl_handler Curl_handler_tftp = {
tftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_TFTP, /* defport */
CURLPROTO_TFTP, /* protocol */
CURLPROTO_TFTP, /* family */
@@ -319,7 +320,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
const char *option, *value;
tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value);
- if(tmp == NULL) {
+ if(!tmp) {
failf(data, "Malformed ACK packet, rejecting");
return CURLE_TFTP_ILLEGAL;
}
@@ -776,7 +777,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
return result;
state->sbytes += (int)cb;
state->data->req.upload_fromhere += cb;
- } while(state->sbytes < state->blksize && cb != 0);
+ } while(state->sbytes < state->blksize && cb);
sbytes = sendto(state->sockfd, (void *) state->spacket.data,
4 + state->sbytes, SEND_4TH_ARG,
@@ -1256,7 +1257,7 @@ static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done)
failf(data, "%s", Curl_strerror(error, buffer, sizeof(buffer)));
state->event = TFTP_EVENT_ERROR;
}
- else if(rc != 0) {
+ else if(rc) {
result = tftp_receive_packet(data);
if(result)
return result;
diff --git a/libs/libcurl/src/timeval.c b/libs/libcurl/src/timeval.c
index 8523dad400..ca98fe50e5 100644
--- a/libs/libcurl/src/timeval.c
+++ b/libs/libcurl/src/timeval.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -78,14 +78,16 @@ struct curltime Curl_now(void)
** code compiles but fails during run-time if clock_gettime() is
** called on unsupported OS version.
*/
-#if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1)
+#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
+ (HAVE_BUILTIN_AVAILABLE == 1)
bool have_clock_gettime = FALSE;
if(__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *))
have_clock_gettime = TRUE;
#endif
if(
-#if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1)
+#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \
+ (HAVE_BUILTIN_AVAILABLE == 1)
have_clock_gettime &&
#endif
(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow))) {
diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c
index 56ad5e612e..bca4e548fa 100644
--- a/libs/libcurl/src/transfer.c
+++ b/libs/libcurl/src/transfer.c
@@ -99,6 +99,8 @@ char *Curl_checkheaders(const struct Curl_easy *data,
{
struct curl_slist *head;
size_t thislen = strlen(thisheader);
+ DEBUGASSERT(thislen);
+ DEBUGASSERT(thisheader[thislen-1] != ':');
for(head = data->set.headers; head; head = head->next) {
if(strncasecompare(head->data, thisheader, thislen) &&
@@ -495,11 +497,13 @@ static int data_pending(const struct Curl_easy *data)
return Curl_quic_data_pending(data);
#endif
+ if(conn->handler->protocol&PROTO_FAMILY_FTP)
+ return Curl_ssl_data_pending(conn, SECONDARYSOCKET);
+
/* in the case of libssh2, we can never be really sure that we have emptied
its internal buffers so we MUST always try until we get EAGAIN back */
return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
#if defined(USE_NGHTTP2)
- Curl_ssl_data_pending(conn, FIRSTSOCKET) ||
/* For HTTP/2, we may read up everything including response body
with header fields in Curl_http_readwrite_headers. If no
content-length is provided, curl waits for the connection
@@ -507,10 +511,9 @@ static int data_pending(const struct Curl_easy *data)
TRUE. The thing is if we read everything, then http2_recv won't
be called and we cannot signal the HTTP/2 stream has closed. As
a workaround, we return nonzero here to call http2_recv. */
- ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20);
-#else
- Curl_ssl_data_pending(conn, FIRSTSOCKET);
+ ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20) ||
#endif
+ Curl_ssl_data_pending(conn, FIRSTSOCKET);
}
/*
@@ -830,7 +833,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
Make sure that ALL_CONTENT_ENCODINGS contains all the
encodings handled here. */
if(data->set.http_ce_skip || !k->writer_stack) {
- if(!k->ignorebody) {
+ if(!k->ignorebody && nread) {
#ifndef CURL_DISABLE_POP3
if(conn->handler->protocol & PROTO_FAMILY_POP3)
result = Curl_pop3_write(data, k->str, nread);
@@ -840,7 +843,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
nread);
}
}
- else if(!k->ignorebody)
+ else if(!k->ignorebody && nread)
result = Curl_unencode_write(data, k->writer_stack, k->str, nread);
}
k->badheader = HEADER_NORMAL; /* taken care of now */
diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c
index 19fcfb842c..1ee38af0d5 100644
--- a/libs/libcurl/src/url.c
+++ b/libs/libcurl/src/url.c
@@ -292,6 +292,7 @@ static const struct Curl_handler Curl_handler_dummy = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
0, /* defport */
0, /* protocol */
0, /* family */
@@ -923,14 +924,14 @@ socks_proxy_info_matches(const struct proxy_info *data,
/* the user information is case-sensitive
or at least it is not defined as case-insensitive
see https://tools.ietf.org/html/rfc3986#section-3.2.1 */
- if((data->user == NULL) != (needle->user == NULL))
+ if(!data->user != !needle->user)
return FALSE;
/* curl_strequal does a case insentive comparison, so do not use it here! */
if(data->user &&
needle->user &&
strcmp(data->user, needle->user) != 0)
return FALSE;
- if((data->passwd == NULL) != (needle->passwd == NULL))
+ if(!data->passwd != !needle->passwd)
return FALSE;
/* curl_strequal does a case insentive comparison, so do not use it here! */
if(data->passwd &&
@@ -1171,6 +1172,12 @@ ConnectionExists(struct Curl_easy *data,
continue;
}
+ if(data->set.ipver != CURL_IPRESOLVE_WHATEVER
+ && data->set.ipver != check->ip_version) {
+ /* skip because the connection is not via the requested IP version */
+ continue;
+ }
+
if(bundle->multiuse == BUNDLE_MULTIPLEX)
multiplexed = CONN_INUSE(check);
@@ -1315,6 +1322,13 @@ ConnectionExists(struct Curl_easy *data,
}
}
+ /* If multiplexing isn't enabled on the h2 connection and h1 is
+ explicitly requested, handle it: */
+ if((needle->handler->protocol & PROTO_FAMILY_HTTP) &&
+ (check->httpversion >= 20) &&
+ (data->state.httpwant < CURL_HTTP_VERSION_2_0))
+ continue;
+
if((needle->handler->flags&PROTOPT_SSL)
#ifndef CURL_DISABLE_PROXY
|| !needle->bits.httpproxy || needle->bits.tunnel_proxy
@@ -1944,7 +1958,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
-#ifdef USE_HSTS
+#ifndef CURL_DISABLE_HSTS
if(data->hsts && strcasecompare("http", data->state.up.scheme)) {
if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) {
char *url;
@@ -3556,7 +3570,7 @@ static CURLcode create_conn(struct Curl_easy *data,
#ifdef USE_UNIX_SOCKETS
if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
- if(conn->unix_domain_socket == NULL) {
+ if(!conn->unix_domain_socket) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
@@ -3731,6 +3745,7 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT];
+ data->set.ssl.primary.ca_info_blob = data->set.blobs[BLOB_CAINFO];
data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES];
#ifndef CURL_DISABLE_PROXY
@@ -3746,6 +3761,8 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.proxy_ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY];
data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
+ data->set.proxy_ssl.primary.ca_info_blob =
+ data->set.blobs[BLOB_CAINFO_PROXY];
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c
index e3a788221b..6483208ec7 100644
--- a/libs/libcurl/src/urlapi.c
+++ b/libs/libcurl/src/urlapi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -667,6 +667,94 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
#define HOSTNAME_END(x) (((x) == '/') || ((x) == '?') || ((x) == '#'))
+/*
+ * Handle partial IPv4 numerical addresses and different bases, like
+ * '16843009', '0x7f', '0x7f.1' '0177.1.1.1' etc.
+ *
+ * If the given input string is syntactically wrong or any part for example is
+ * too big, this function returns FALSE and doesn't create any output.
+ *
+ * Output the "normalized" version of that input string in plain quad decimal
+ * integers and return TRUE.
+ */
+static bool ipv4_normalize(const char *hostname, char *outp, size_t olen)
+{
+ bool done = FALSE;
+ int n = 0;
+ const char *c = hostname;
+ unsigned long parts[4] = {0, 0, 0, 0};
+
+ while(!done) {
+ char *endp;
+ unsigned long l;
+ if((*c < '0') || (*c > '9'))
+ /* most importantly this doesn't allow a leading plus or minus */
+ return FALSE;
+ l = strtoul(c, &endp, 0);
+
+ /* overflow or nothing parsed at all */
+ if(((l == ULONG_MAX) && (errno == ERANGE)) || (endp == c))
+ return FALSE;
+
+#if SIZEOF_LONG > 4
+ /* a value larger than 32 bits */
+ if(l > UINT_MAX)
+ return FALSE;
+#endif
+
+ parts[n] = l;
+ c = endp;
+
+ switch (*c) {
+ case '.' :
+ if(n == 3)
+ return FALSE;
+ n++;
+ c++;
+ break;
+
+ case '\0':
+ done = TRUE;
+ break;
+
+ default:
+ return FALSE;
+ }
+ }
+
+ /* this is deemed a valid IPv4 numerical address */
+
+ switch(n) {
+ case 0: /* a -- 32 bits */
+ msnprintf(outp, olen, "%u.%u.%u.%u",
+ parts[0] >> 24, (parts[0] >> 16) & 0xff,
+ (parts[0] >> 8) & 0xff, parts[0] & 0xff);
+ break;
+ case 1: /* a.b -- 8.24 bits */
+ if((parts[0] > 0xff) || (parts[1] > 0xffffff))
+ return FALSE;
+ msnprintf(outp, olen, "%u.%u.%u.%u",
+ parts[0], (parts[1] >> 16) & 0xff,
+ (parts[1] >> 8) & 0xff, parts[1] & 0xff);
+ break;
+ case 2: /* a.b.c -- 8.8.16 bits */
+ if((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xffff))
+ return FALSE;
+ msnprintf(outp, olen, "%u.%u.%u.%u",
+ parts[0], parts[1], (parts[2] >> 8) & 0xff,
+ parts[2] & 0xff);
+ break;
+ case 3: /* a.b.c.d -- 8.8.8.8 bits */
+ if((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff) ||
+ (parts[3] > 0xff))
+ return FALSE;
+ msnprintf(outp, olen, "%u.%u.%u.%u",
+ parts[0], parts[1], parts[2], parts[3]);
+ break;
+ }
+ return TRUE;
+}
+
static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
{
char *path;
@@ -899,6 +987,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
}
if(hostname) {
+ char normalized_ipv4[sizeof("255.255.255.255") + 1];
/*
* Parse the login details and strip them out of the host name.
*/
@@ -922,7 +1011,10 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
return result;
}
- u->host = strdup(hostname);
+ if(ipv4_normalize(hostname, normalized_ipv4, sizeof(normalized_ipv4)))
+ u->host = strdup(normalized_ipv4);
+ else
+ u->host = strdup(hostname);
if(!u->host)
return CURLUE_OUT_OF_MEMORY;
diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h
index fec875652c..fb905c36c5 100644
--- a/libs/libcurl/src/urldata.h
+++ b/libs/libcurl/src/urldata.h
@@ -253,6 +253,7 @@ struct ssl_primary_config {
char *cipher_list13; /* list of TLS 1.3 cipher suites to use */
char *pinned_key;
struct curl_blob *cert_blob;
+ struct curl_blob *ca_info_blob;
char *curves; /* list of curves to use */
BIT(verifypeer); /* set TRUE if this is desired */
BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */
@@ -286,6 +287,8 @@ struct ssl_config_data {
BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation
list errors */
BIT(native_ca_store); /* use the native ca store of operating system */
+ BIT(auto_client_cert); /* automatically locate and use a client
+ certificate for authentication (Schannel) */
};
struct ssl_general_config {
@@ -791,12 +794,16 @@ struct Curl_handler {
struct connectdata *conn,
unsigned int checks_to_perform);
+ /* attach() attaches this transfer to this connection */
+ void (*attach)(struct Curl_easy *data, struct connectdata *conn);
+
int defport; /* Default port. */
unsigned int protocol; /* See CURLPROTO_* - this needs to be the single
specific protocol bit */
unsigned int family; /* single bit for protocol family; basically the
non-TLS name of the protocol this is */
unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */
+
};
#define PROTOPT_NONE 0 /* nothing extra */
@@ -855,25 +862,8 @@ struct proxy_info {
char *passwd; /* proxy password string, allocated */
};
-/* struct for HTTP CONNECT state data */
-struct http_connect_state {
- struct dynbuf rcvbuf;
- enum keeponval {
- KEEPON_DONE,
- KEEPON_CONNECT,
- KEEPON_IGNORE
- } keepon;
- curl_off_t cl; /* size of content to read and ignore */
- enum {
- TUNNEL_INIT, /* init/default/no tunnel state */
- TUNNEL_CONNECT, /* CONNECT has been sent off */
- TUNNEL_COMPLETE /* CONNECT response received completely */
- } tunnel_state;
- BIT(chunked_encoding);
- BIT(close_connection);
-};
-
struct ldapconninfo;
+struct http_connect_state;
/* for the (SOCKS) connect state machine */
enum connect_t {
@@ -1602,6 +1592,8 @@ enum dupblob {
BLOB_KEY_PROXY,
BLOB_SSL_ISSUERCERT,
BLOB_SSL_ISSUERCERT_PROXY,
+ BLOB_CAINFO,
+ BLOB_CAINFO_PROXY,
BLOB_LAST
};
@@ -1664,7 +1656,7 @@ struct UserDefined {
curl_conv_callback convtonetwork;
/* function to convert from UTF-8 encoding: */
curl_conv_callback convfromutf8;
-#ifdef USE_HSTS
+#ifndef CURL_DISABLE_HSTS
curl_hstsread_callback hsts_read;
void *hsts_read_userp;
curl_hstswrite_callback hsts_write;
@@ -1717,8 +1709,8 @@ struct UserDefined {
struct ssl_general_config general_ssl; /* general user defined SSL stuff */
long dns_cache_timeout; /* DNS cache timeout */
long buffer_size; /* size of receive buffer to use */
- size_t upload_buffer_size; /* size of upload buffer to use,
- keep it >= CURL_MAX_WRITE_SIZE */
+ unsigned int 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 */
unsigned char ipver; /* the CURL_IPRESOLVE_* defines in the public header
@@ -1926,7 +1918,7 @@ struct Curl_easy {
NOTE that the 'cookie' field in the
UserDefined struct defines if the "engine"
is to be used or not. */
-#ifdef USE_HSTS
+#ifndef CURL_DISABLE_HSTS
struct hsts *hsts;
#endif
#ifndef CURL_DISABLE_ALTSVC
diff --git a/libs/libcurl/src/vauth/cleartext.c b/libs/libcurl/src/vauth/cleartext.c
index 620dba03ef..d17e16f108 100644
--- a/libs/libcurl/src/vauth/cleartext.c
+++ b/libs/libcurl/src/vauth/cleartext.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -32,7 +32,6 @@
#include "urldata.h"
#include "vauth/vauth.h"
-#include "curl_base64.h"
#include "curl_md5.h"
#include "warnless.h"
#include "strtok.h"
@@ -51,31 +50,24 @@
*
* Parameters:
*
- * data [in] - The session handle.
* authzid [in] - The authorization identity.
* authcid [in] - The authentication identity.
* passwd [in] - The password.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
- const char *authzid,
+CURLcode Curl_auth_create_plain_message(const char *authzid,
const char *authcid,
const char *passwd,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
- CURLcode result;
char *plainauth;
+ size_t plainlen;
size_t zlen;
size_t clen;
size_t plen;
- size_t plainlen;
- *outlen = 0;
- *outptr = NULL;
zlen = (authzid == NULL ? 0 : strlen(authzid));
clen = strlen(authcid);
plen = strlen(passwd);
@@ -86,23 +78,20 @@ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
plainlen = zlen + clen + plen + 2;
- plainauth = malloc(plainlen);
+ plainauth = malloc(plainlen + 1);
if(!plainauth)
return CURLE_OUT_OF_MEMORY;
/* Calculate the reply */
- if(zlen != 0)
+ if(zlen)
memcpy(plainauth, authzid, zlen);
plainauth[zlen] = '\0';
memcpy(plainauth + zlen + 1, authcid, clen);
plainauth[zlen + clen + 1] = '\0';
memcpy(plainauth + zlen + clen + 2, passwd, plen);
-
- /* Base64 encode the reply */
- result = Curl_base64_encode(data, plainauth, plainlen, outptr, outlen);
- free(plainauth);
-
- return result;
+ plainauth[plainlen] = '\0';
+ Curl_bufref_set(out, plainauth, plainlen, curl_free);
+ return CURLE_OK;
}
/*
@@ -113,34 +102,15 @@ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
*
* Parameters:
*
- * data [in] - The session handle.
* valuep [in] - The user name or user's password.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_auth_create_login_message(struct Curl_easy *data,
- const char *valuep, char **outptr,
- size_t *outlen)
+CURLcode Curl_auth_create_login_message(const char *valuep, struct bufref *out)
{
- size_t vlen = strlen(valuep);
-
- if(!vlen) {
- /* Calculate an empty reply */
- *outptr = strdup("=");
- if(*outptr) {
- *outlen = (size_t) 1;
- return CURLE_OK;
- }
-
- *outlen = 0;
- return CURLE_OUT_OF_MEMORY;
- }
-
- /* Base64 encode the value */
- return Curl_base64_encode(data, valuep, vlen, outptr, outlen);
+ Curl_bufref_set(out, valuep, strlen(valuep), NULL);
+ return CURLE_OK;
}
/*
@@ -151,20 +121,16 @@ CURLcode Curl_auth_create_login_message(struct Curl_easy *data,
*
* Parameters:
*
- * data [in] - The session handle.
* user [in] - The user name.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_auth_create_external_message(struct Curl_easy *data,
- const char *user, char **outptr,
- size_t *outlen)
+CURLcode Curl_auth_create_external_message(const char *user,
+ struct bufref *out)
{
/* This is the same formatting as the login message */
- return Curl_auth_create_login_message(data, user, outptr, outlen);
+ return Curl_auth_create_login_message(user, out);
}
#endif /* if no users */
diff --git a/libs/libcurl/src/vauth/cram.c b/libs/libcurl/src/vauth/cram.c
index 1a376259a8..9ddb0ac379 100644
--- a/libs/libcurl/src/vauth/cram.c
+++ b/libs/libcurl/src/vauth/cram.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -30,7 +30,6 @@
#include "urldata.h"
#include "vauth/vauth.h"
-#include "curl_base64.h"
#include "curl_hmac.h"
#include "curl_md5.h"
#include "warnless.h"
@@ -40,69 +39,31 @@
#include "curl_memory.h"
#include "memdebug.h"
-/*
- * Curl_auth_decode_cram_md5_message()
- *
- * This is used to decode an already encoded CRAM-MD5 challenge message.
- *
- * Parameters:
- *
- * chlg64 [in] - The base64 encoded challenge message.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
- *
- * Returns CURLE_OK on success.
- */
-CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr,
- size_t *outlen)
-{
- CURLcode result = CURLE_OK;
- size_t chlg64len = strlen(chlg64);
-
- *outptr = NULL;
- *outlen = 0;
-
- /* Decode the challenge if necessary */
- if(chlg64len && *chlg64 != '=')
- result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen);
-
- return result;
-}
/*
* Curl_auth_create_cram_md5_message()
*
- * This is used to generate an already encoded CRAM-MD5 response message ready
- * for sending to the recipient.
+ * This is used to generate a CRAM-MD5 response message ready for sending to
+ * the recipient.
*
* Parameters:
*
- * data [in] - The session handle.
* chlg [in] - The challenge.
* userp [in] - The user name.
* passwdp [in] - The user's password.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data,
- const char *chlg,
+CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
const char *userp,
const char *passwdp,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
- CURLcode result = CURLE_OK;
- size_t chlglen = 0;
struct HMAC_context *ctxt;
unsigned char digest[MD5_DIGEST_LEN];
char *response;
- if(chlg)
- chlglen = strlen(chlg);
-
/* Compute the digest using the password as the key */
ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
(const unsigned char *) passwdp,
@@ -111,9 +72,9 @@ CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
/* Update the digest with the given challenge */
- if(chlglen > 0)
- Curl_HMAC_update(ctxt, (const unsigned char *) chlg,
- curlx_uztoui(chlglen));
+ if(Curl_bufref_len(chlg))
+ Curl_HMAC_update(ctxt, Curl_bufref_ptr(chlg),
+ curlx_uztoui(Curl_bufref_len(chlg)));
/* Finalise the digest */
Curl_HMAC_final(ctxt, digest);
@@ -127,12 +88,8 @@ CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data,
if(!response)
return CURLE_OUT_OF_MEMORY;
- /* Base64 encode the response */
- result = Curl_base64_encode(data, response, 0, outptr, outlen);
-
- free(response);
-
- return result;
+ Curl_bufref_set(out, response, strlen(response), curl_free);
+ return CURLE_OK;
}
#endif /* !CURL_DISABLE_CRYPTO_AUTH */
diff --git a/libs/libcurl/src/vauth/digest.c b/libs/libcurl/src/vauth/digest.c
index 559852fcba..a04ffab6fb 100644
--- a/libs/libcurl/src/vauth/digest.c
+++ b/libs/libcurl/src/vauth/digest.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -254,7 +254,7 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value)
*
* Parameters:
*
- * chlg64 [in] - The base64 encoded challenge message.
+ * chlgref [in] - The challenge message.
* nonce [in/out] - The buffer where the nonce will be stored.
* nlen [in] - The length of the nonce buffer.
* realm [in/out] - The buffer where the realm will be stored.
@@ -266,55 +266,35 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value)
*
* Returns CURLE_OK on success.
*/
-static CURLcode auth_decode_digest_md5_message(const char *chlg64,
+static CURLcode auth_decode_digest_md5_message(const struct bufref *chlgref,
char *nonce, size_t nlen,
char *realm, size_t rlen,
char *alg, size_t alen,
char *qop, size_t qlen)
{
- CURLcode result = CURLE_OK;
- unsigned char *chlg = NULL;
- size_t chlglen = 0;
- size_t chlg64len = strlen(chlg64);
-
- /* Decode the base-64 encoded challenge message */
- if(chlg64len && *chlg64 != '=') {
- result = Curl_base64_decode(chlg64, &chlg, &chlglen);
- if(result)
- return result;
- }
+ const char *chlg = (const char *) Curl_bufref_ptr(chlgref);
/* Ensure we have a valid challenge message */
- if(!chlg)
+ if(!Curl_bufref_len(chlgref))
return CURLE_BAD_CONTENT_ENCODING;
/* Retrieve nonce string from the challenge */
- if(!auth_digest_get_key_value((char *) chlg, "nonce=\"", nonce, nlen,
- '\"')) {
- free(chlg);
+ if(!auth_digest_get_key_value(chlg, "nonce=\"", nonce, nlen, '\"'))
return CURLE_BAD_CONTENT_ENCODING;
- }
/* Retrieve realm string from the challenge */
- if(!auth_digest_get_key_value((char *) chlg, "realm=\"", realm, rlen,
- '\"')) {
+ if(!auth_digest_get_key_value(chlg, "realm=\"", realm, rlen, '\"')) {
/* Challenge does not have a realm, set empty string [RFC2831] page 6 */
strcpy(realm, "");
}
/* Retrieve algorithm string from the challenge */
- if(!auth_digest_get_key_value((char *) chlg, "algorithm=", alg, alen, ',')) {
- free(chlg);
+ if(!auth_digest_get_key_value(chlg, "algorithm=", alg, alen, ','))
return CURLE_BAD_CONTENT_ENCODING;
- }
/* Retrieve qop-options string from the challenge */
- if(!auth_digest_get_key_value((char *) chlg, "qop=\"", qop, qlen, '\"')) {
- free(chlg);
+ if(!auth_digest_get_key_value(chlg, "qop=\"", qop, qlen, '\"'))
return CURLE_BAD_CONTENT_ENCODING;
- }
-
- free(chlg);
return CURLE_OK;
}
@@ -342,22 +322,20 @@ bool Curl_auth_is_digest_supported(void)
* Parameters:
*
* data [in] - The session handle.
- * chlg64 [in] - The base64 encoded challenge message.
+ * chlg [in] - The challenge message.
* userp [in] - The user name.
* passwdp [in] - The user's password.
* service [in] - The service type such as http, smtp, pop or imap.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
- const char *chlg64,
+ const struct bufref *chlg,
const char *userp,
const char *passwdp,
const char *service,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
size_t i;
struct MD5_context *ctxt;
@@ -378,9 +356,10 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
char *spn = NULL;
/* Decode the challenge message */
- CURLcode result = auth_decode_digest_md5_message(chlg64, nonce,
- sizeof(nonce), realm,
- sizeof(realm), algorithm,
+ CURLcode result = auth_decode_digest_md5_message(chlg,
+ nonce, sizeof(nonce),
+ realm, sizeof(realm),
+ algorithm,
sizeof(algorithm),
qop_options,
sizeof(qop_options));
@@ -500,11 +479,8 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
if(!response)
return CURLE_OUT_OF_MEMORY;
- /* Base64 encode the response */
- result = Curl_base64_encode(data, response, 0, outptr, outlen);
-
- free(response);
-
+ /* Return the response. */
+ Curl_bufref_set(out, response, strlen(response), curl_free);
return result;
}
diff --git a/libs/libcurl/src/vauth/digest_sspi.c b/libs/libcurl/src/vauth/digest_sspi.c
index dad947a37e..2602ffd363 100644
--- a/libs/libcurl/src/vauth/digest_sspi.c
+++ b/libs/libcurl/src/vauth/digest_sspi.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2014 - 2016, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -32,7 +32,6 @@
#include "vauth/vauth.h"
#include "vauth/digest.h"
#include "urldata.h"
-#include "curl_base64.h"
#include "warnless.h"
#include "curl_multibyte.h"
#include "sendf.h"
@@ -79,28 +78,24 @@ bool Curl_auth_is_digest_supported(void)
* Parameters:
*
* data [in] - The session handle.
- * chlg64 [in] - The base64 encoded challenge message.
+ * chlg [in] - The challenge message.
* userp [in] - The user name in the format User or Domain\User.
* passwdp [in] - The user's password.
* service [in] - The service type such as http, smtp, pop or imap.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
- const char *chlg64,
+ const struct bufref *chlg,
const char *userp,
const char *passwdp,
const char *service,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
CURLcode result = CURLE_OK;
TCHAR *spn = NULL;
- size_t chlglen = 0;
size_t token_max = 0;
- unsigned char *input_token = NULL;
unsigned char *output_token = NULL;
CredHandle credentials;
CtxtHandle context;
@@ -115,17 +110,9 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
unsigned long attrs;
TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
- /* Decode the base-64 encoded challenge message */
- if(strlen(chlg64) && *chlg64 != '=') {
- result = Curl_base64_decode(chlg64, &input_token, &chlglen);
- if(result)
- return result;
- }
-
/* Ensure we have a valid challenge message */
- if(!input_token) {
+ if(!Curl_bufref_len(chlg)) {
infof(data, "DIGEST-MD5 handshake failure (empty challenge message)\n");
-
return CURLE_BAD_CONTENT_ENCODING;
}
@@ -133,8 +120,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
&SecurityPackage);
if(status != SEC_E_OK) {
- free(input_token);
-
failf(data, "SSPI: couldn't get auth info");
return CURLE_AUTH_ERROR;
}
@@ -146,18 +131,13 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
/* Allocate our response buffer */
output_token = malloc(token_max);
- if(!output_token) {
- free(input_token);
-
+ if(!output_token)
return CURLE_OUT_OF_MEMORY;
- }
/* Generate our SPN */
spn = Curl_auth_build_spn(service, data->conn->host.name, NULL);
if(!spn) {
free(output_token);
- free(input_token);
-
return CURLE_OUT_OF_MEMORY;
}
@@ -167,8 +147,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
if(result) {
free(spn);
free(output_token);
- free(input_token);
-
return result;
}
@@ -190,8 +168,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
Curl_sspi_free_identity(p_identity);
free(spn);
free(output_token);
- free(input_token);
-
return CURLE_LOGIN_DENIED;
}
@@ -200,8 +176,8 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
chlg_desc.cBuffers = 1;
chlg_desc.pBuffers = &chlg_buf;
chlg_buf.BufferType = SECBUFFER_TOKEN;
- chlg_buf.pvBuffer = input_token;
- chlg_buf.cbBuffer = curlx_uztoul(chlglen);
+ chlg_buf.pvBuffer = (void *) Curl_bufref_ptr(chlg);
+ chlg_buf.cbBuffer = curlx_uztoul(Curl_bufref_len(chlg));
/* Setup the response "output" security buffer */
resp_desc.ulVersion = SECBUFFER_VERSION;
@@ -227,7 +203,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
Curl_sspi_free_identity(p_identity);
free(spn);
free(output_token);
- free(input_token);
if(status == SEC_E_INSUFFICIENT_MEMORY)
return CURLE_OUT_OF_MEMORY;
@@ -238,9 +213,8 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
return CURLE_AUTH_ERROR;
}
- /* Base64 encode the response */
- result = Curl_base64_encode(data, (char *) output_token, resp_buf.cbBuffer,
- outptr, outlen);
+ /* Return the response. */
+ Curl_bufref_set(out, output_token, resp_buf.cbBuffer, curl_free);
/* Free our handles */
s_pSecFn->DeleteSecurityContext(&context);
@@ -252,12 +226,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
/* Free the SPN */
free(spn);
- /* Free the response buffer */
- free(output_token);
-
- /* Free the decoded challenge message */
- free(input_token);
-
return result;
}
diff --git a/libs/libcurl/src/vauth/gsasl.c b/libs/libcurl/src/vauth/gsasl.c
index 02a06357f0..40fef53c93 100644
--- a/libs/libcurl/src/vauth/gsasl.c
+++ b/libs/libcurl/src/vauth/gsasl.c
@@ -28,7 +28,6 @@
#include <curl/curl.h>
-#include "curl_base64.h"
#include "vauth/vauth.h"
#include "urldata.h"
#include "sendf.h"
@@ -94,42 +93,24 @@ CURLcode Curl_auth_gsasl_start(struct Curl_easy *data,
}
CURLcode Curl_auth_gsasl_token(struct Curl_easy *data,
- const char *chlg64,
+ const struct bufref *chlg,
struct gsasldata *gsasl,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
- unsigned char *chlg = NULL;
- size_t chlglen = 0;
- CURLcode result = CURLE_OK;
int res;
char *response;
-
- if(chlg64) {
- result = Curl_base64_decode(chlg64, &chlg, &chlglen);
- if(result)
- return result;
- }
+ size_t outlen;
res = gsasl_step(gsasl->client,
- (const char *)chlg, chlglen, &response, outlen);
+ (const char *) Curl_bufref_ptr(chlg), Curl_bufref_len(chlg),
+ &response, &outlen);
if(res != GSASL_OK && res != GSASL_NEEDS_MORE) {
- if(chlg64)
- free(chlg);
failf(data, "GSASL step: %s\n", gsasl_strerror(res));
return CURLE_BAD_CONTENT_ENCODING;
}
- if(*outlen > 0) {
- result = Curl_base64_encode(data, response, 0, outptr, outlen);
- gsasl_free(response);
- }
- else {
- *outptr = strdup("");
- if(!*outptr)
- result = CURLE_OUT_OF_MEMORY;
- }
-
- return result;
+ Curl_bufref_set(out, response, outlen, gsasl_free);
+ return CURLE_OK;
}
void Curl_auth_gsasl_cleanup(struct gsasldata *gsasl)
diff --git a/libs/libcurl/src/vauth/krb5_gssapi.c b/libs/libcurl/src/vauth/krb5_gssapi.c
index 0412815e93..b43982b9bd 100644
--- a/libs/libcurl/src/vauth/krb5_gssapi.c
+++ b/libs/libcurl/src/vauth/krb5_gssapi.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -32,7 +32,6 @@
#include "vauth/vauth.h"
#include "curl_sasl.h"
#include "urldata.h"
-#include "curl_base64.h"
#include "curl_gssapi.h"
#include "sendf.h"
#include "curl_printf.h"
@@ -70,12 +69,9 @@ bool Curl_auth_is_gssapi_supported(void)
* host [in[ - The host name.
* mutual_auth [in] - Flag specifying whether or not mutual authentication
* is enabled.
- * chlg64 [in] - Pointer to the optional base64 encoded challenge
- * message.
+ * chlg [in] - Optional challenge message.
* krb5 [in/out] - The Kerberos 5 data struct being used and modified.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
@@ -85,13 +81,11 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
const char *service,
const char *host,
const bool mutual_auth,
- const char *chlg64,
+ const struct bufref *chlg,
struct kerberos5data *krb5,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
CURLcode result = CURLE_OK;
- size_t chlglen = 0;
- unsigned char *chlg = NULL;
OM_uint32 major_status;
OM_uint32 minor_status;
OM_uint32 unused_status;
@@ -127,24 +121,13 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
free(spn);
}
- if(chlg64 && *chlg64) {
- /* Decode the base-64 encoded challenge message */
- if(*chlg64 != '=') {
- result = Curl_base64_decode(chlg64, &chlg, &chlglen);
- if(result)
- return result;
- }
-
- /* Ensure we have a valid challenge message */
- if(!chlg) {
+ if(chlg) {
+ if(!Curl_bufref_len(chlg)) {
infof(data, "GSSAPI handshake failure (empty challenge message)\n");
-
return CURLE_BAD_CONTENT_ENCODING;
}
-
- /* Setup the challenge "input" security buffer */
- input_token.value = chlg;
- input_token.length = chlglen;
+ input_token.value = (void *) Curl_bufref_ptr(chlg);
+ input_token.length = Curl_bufref_len(chlg);
}
major_status = Curl_gss_init_sec_context(data,
@@ -158,9 +141,6 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
mutual_auth,
NULL);
- /* Free the decoded challenge as it is not required anymore */
- free(input_token.value);
-
if(GSS_ERROR(major_status)) {
if(output_token.value)
gss_release_buffer(&unused_status, &output_token);
@@ -172,17 +152,11 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
}
if(output_token.value && output_token.length) {
- /* Base64 encode the response */
- result = Curl_base64_encode(data, (char *) output_token.value,
- output_token.length, outptr, outlen);
-
+ result = Curl_bufref_memdup(out, output_token.value, output_token.length);
gss_release_buffer(&unused_status, &output_token);
}
- else if(mutual_auth) {
- *outptr = strdup("");
- if(!*outptr)
- result = CURLE_OUT_OF_MEMORY;
- }
+ else
+ Curl_bufref_set(out, mutual_auth? "": NULL, 0, NULL);
return result;
}
@@ -196,24 +170,19 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
* Parameters:
*
* data [in] - The session handle.
- * chlg64 [in] - Pointer to the optional base64 encoded challenge message.
+ * chlg [in] - Optional challenge message.
* krb5 [in/out] - The Kerberos 5 data struct being used and modified.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
- const char *chlg64,
+ const struct bufref *chlg,
struct kerberos5data *krb5,
- char **outptr,
- size_t *outlen)
+ struct bufref *out)
{
CURLcode result = CURLE_OK;
- size_t chlglen = 0;
size_t messagelen = 0;
- unsigned char *chlg = NULL;
unsigned char *message = NULL;
OM_uint32 major_status;
OM_uint32 minor_status;
@@ -228,17 +197,9 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
gss_name_t username = GSS_C_NO_NAME;
gss_buffer_desc username_token;
- /* Decode the base-64 encoded input message */
- if(strlen(chlg64) && *chlg64 != '=') {
- result = Curl_base64_decode(chlg64, &chlg, &chlglen);
- if(result)
- return result;
- }
-
/* Ensure we have a valid challenge message */
- if(!chlg) {
+ if(!Curl_bufref_len(chlg)) {
infof(data, "GSSAPI handshake failure (empty security message)\n");
-
return CURLE_BAD_CONTENT_ENCODING;
}
@@ -249,9 +210,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
if(GSS_ERROR(major_status)) {
Curl_gss_log_error(data, "gss_inquire_context() failed: ",
major_status, minor_status);
-
- free(chlg);
-
return CURLE_AUTH_ERROR;
}
@@ -261,15 +219,12 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
if(GSS_ERROR(major_status)) {
Curl_gss_log_error(data, "gss_display_name() failed: ",
major_status, minor_status);
-
- free(chlg);
-
return CURLE_AUTH_ERROR;
}
/* Setup the challenge "input" security buffer */
- input_token.value = chlg;
- input_token.length = chlglen;
+ input_token.value = (void *) Curl_bufref_ptr(chlg);
+ input_token.length = Curl_bufref_len(chlg);
/* Decrypt the inbound challenge and obtain the qop */
major_status = gss_unwrap(&minor_status, krb5->context, &input_token,
@@ -277,27 +232,20 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
if(GSS_ERROR(major_status)) {
Curl_gss_log_error(data, "gss_unwrap() failed: ",
major_status, minor_status);
-
gss_release_buffer(&unused_status, &username_token);
- free(chlg);
-
return CURLE_BAD_CONTENT_ENCODING;
}
/* Not 4 octets long so fail as per RFC4752 Section 3.1 */
if(output_token.length != 4) {
infof(data, "GSSAPI handshake failure (invalid security data)\n");
-
gss_release_buffer(&unused_status, &username_token);
- free(chlg);
-
return CURLE_BAD_CONTENT_ENCODING;
}
/* Copy the data out and free the challenge as it is not required anymore */
memcpy(&indata, output_token.value, 4);
gss_release_buffer(&unused_status, &output_token);
- free(chlg);
/* Extract the security layer */
sec_layer = indata & 0x000000FF;
@@ -305,7 +253,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
infof(data, "GSSAPI handshake failure (invalid security layer)\n");
gss_release_buffer(&unused_status, &username_token);
-
return CURLE_BAD_CONTENT_ENCODING;
}
@@ -323,7 +270,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
message = malloc(messagelen);
if(!message) {
gss_release_buffer(&unused_status, &username_token);
-
return CURLE_OUT_OF_MEMORY;
}
@@ -352,16 +298,12 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
if(GSS_ERROR(major_status)) {
Curl_gss_log_error(data, "gss_wrap() failed: ",
major_status, minor_status);
-
free(message);
-
return CURLE_AUTH_ERROR;
}
- /* Base64 encode the response */
- result = Curl_base64_encode(data, (char *) output_token.value,
- output_token.length, outptr, outlen);
-
+ /* Return the response. */
+ result = Curl_bufref_memdup(out, output_token.value, output_token.length);
/* Free the output buffer */
gss_release_buffer(&unused_status, &output_token);
diff --git a/libs/libcurl/src/vauth/krb5_sspi.c b/libs/libcurl/src/vauth/krb5_sspi.c
index b2d1635343..e110644225 100644
--- a/libs/libcurl/src/vauth/krb5_sspi.c
+++ b/libs/libcurl/src/vauth/krb5_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2020, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2021, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -30,7 +30,6 @@
#include "vauth/vauth.h"
#include "urldata.h"
-#include "curl_base64.h"
#include "warnless.h"
#include "curl_multibyte.h"
#include "sendf.h"
@@ -81,11 +80,9 @@ bool Curl_auth_is_gssapi_supported(void)
* host [in] - The host name.
* mutual_auth [in] - Flag specifying whether or not mutual authentication
* is enabled.
- * chlg64 [in] - The optional base64 encoded challenge message.
+ * chlg [in] - Optional challenge message.
* krb5 [in/out] - The Kerberos 5 data struct being used and modified.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
@@ -95,13 +92,11 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
const char *service,
const char *host,
const bool mutual_auth,
- const char *chlg64,
+ const struct bufref *chlg,
struct kerberos5data *krb5,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
CURLcode result = CURLE_OK;
- size_t chlglen = 0;
- unsigned char *chlg = NULL;
CtxtHandle context;
PSecPkgInfo SecurityPackage;
SecBuffer chlg_buf;
@@ -176,18 +171,9 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
- if(chlg64 && *chlg64) {
- /* Decode the base-64 encoded challenge message */
- if(*chlg64 != '=') {
- result = Curl_base64_decode(chlg64, &chlg, &chlglen);
- if(result)
- return result;
- }
-
- /* Ensure we have a valid challenge message */
- if(!chlg) {
+ if(chlg) {
+ if(!Curl_bufref_len(chlg)) {
infof(data, "GSSAPI handshake failure (empty challenge message)\n");
-
return CURLE_BAD_CONTENT_ENCODING;
}
@@ -196,8 +182,8 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
chlg_desc.cBuffers = 1;
chlg_desc.pBuffers = &chlg_buf;
chlg_buf.BufferType = SECBUFFER_TOKEN;
- chlg_buf.pvBuffer = chlg;
- chlg_buf.cbBuffer = curlx_uztoul(chlglen);
+ chlg_buf.pvBuffer = (void *) Curl_bufref_ptr(chlg);
+ chlg_buf.cbBuffer = curlx_uztoul(Curl_bufref_len(chlg));
}
/* Setup the response "output" security buffer */
@@ -220,16 +206,11 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
&resp_desc, &attrs,
&expiry);
- /* Free the decoded challenge as it is not required anymore */
- free(chlg);
-
- if(status == SEC_E_INSUFFICIENT_MEMORY) {
+ if(status == SEC_E_INSUFFICIENT_MEMORY)
return CURLE_OUT_OF_MEMORY;
- }
- if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+ if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED)
return CURLE_AUTH_ERROR;
- }
if(memcmp(&context, krb5->context, sizeof(context))) {
s_pSecFn->DeleteSecurityContext(krb5->context);
@@ -238,15 +219,12 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
}
if(resp_buf.cbBuffer) {
- /* Base64 encode the response */
- result = Curl_base64_encode(data, (char *) resp_buf.pvBuffer,
- resp_buf.cbBuffer, outptr, outlen);
- }
- else if(mutual_auth) {
- *outptr = strdup("");
- if(!*outptr)
- result = CURLE_OUT_OF_MEMORY;
+ result = Curl_bufref_memdup(out, resp_buf.pvBuffer, resp_buf.cbBuffer);
}
+ else if(mutual_auth)
+ Curl_bufref_set(out, "", 0, NULL);
+ else
+ Curl_bufref_set(out, NULL, 0, NULL);
return result;
}
@@ -260,26 +238,20 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
* Parameters:
*
* data [in] - The session handle.
- * chlg64 [in] - The optional base64 encoded challenge message.
+ * chlg [in] - The optional challenge message.
* krb5 [in/out] - The Kerberos 5 data struct being used and modified.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
- const char *chlg64,
+ const struct bufref *chlg,
struct kerberos5data *krb5,
- char **outptr,
- size_t *outlen)
+ struct bufref *out)
{
- CURLcode result = CURLE_OK;
size_t offset = 0;
- size_t chlglen = 0;
size_t messagelen = 0;
size_t appdatalen = 0;
- unsigned char *chlg = NULL;
unsigned char *trailer = NULL;
unsigned char *message = NULL;
unsigned char *padding = NULL;
@@ -298,17 +270,9 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
SECURITY_STATUS status;
char *user_name;
- /* Decode the base-64 encoded input message */
- if(strlen(chlg64) && *chlg64 != '=') {
- result = Curl_base64_decode(chlg64, &chlg, &chlglen);
- if(result)
- return result;
- }
-
/* Ensure we have a valid challenge message */
- if(!chlg) {
+ if(!Curl_bufref_len(chlg)) {
infof(data, "GSSAPI handshake failure (empty security message)\n");
-
return CURLE_BAD_CONTENT_ENCODING;
}
@@ -316,35 +280,31 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
status = s_pSecFn->QueryContextAttributes(krb5->context,
SECPKG_ATTR_SIZES,
&sizes);
- if(status != SEC_E_OK) {
- free(chlg);
- if(status == SEC_E_INSUFFICIENT_MEMORY)
- return CURLE_OUT_OF_MEMORY;
+ if(status == SEC_E_INSUFFICIENT_MEMORY)
+ return CURLE_OUT_OF_MEMORY;
+ if(status != SEC_E_OK)
return CURLE_AUTH_ERROR;
- }
/* Get the fully qualified username back from the context */
status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials,
SECPKG_CRED_ATTR_NAMES,
&names);
- if(status != SEC_E_OK) {
- free(chlg);
- if(status == SEC_E_INSUFFICIENT_MEMORY)
- return CURLE_OUT_OF_MEMORY;
+ if(status == SEC_E_INSUFFICIENT_MEMORY)
+ return CURLE_OUT_OF_MEMORY;
+ if(status != SEC_E_OK)
return CURLE_AUTH_ERROR;
- }
/* Setup the "input" security buffer */
input_desc.ulVersion = SECBUFFER_VERSION;
input_desc.cBuffers = 2;
input_desc.pBuffers = input_buf;
input_buf[0].BufferType = SECBUFFER_STREAM;
- input_buf[0].pvBuffer = chlg;
- input_buf[0].cbBuffer = curlx_uztoul(chlglen);
+ input_buf[0].pvBuffer = (void *) Curl_bufref_ptr(chlg);
+ input_buf[0].cbBuffer = curlx_uztoul(Curl_bufref_len(chlg));
input_buf[1].BufferType = SECBUFFER_DATA;
input_buf[1].pvBuffer = NULL;
input_buf[1].cbBuffer = 0;
@@ -353,31 +313,23 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop);
if(status != SEC_E_OK) {
infof(data, "GSSAPI handshake failure (empty security message)\n");
-
- free(chlg);
-
return CURLE_BAD_CONTENT_ENCODING;
}
/* Not 4 octets long so fail as per RFC4752 Section 3.1 */
if(input_buf[1].cbBuffer != 4) {
infof(data, "GSSAPI handshake failure (invalid security data)\n");
-
- free(chlg);
-
return CURLE_BAD_CONTENT_ENCODING;
}
/* Copy the data out and free the challenge as it is not required anymore */
memcpy(&indata, input_buf[1].pvBuffer, 4);
s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer);
- free(chlg);
/* Extract the security layer */
sec_layer = indata & 0x000000FF;
if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) {
infof(data, "GSSAPI handshake failure (invalid security layer)\n");
-
return CURLE_BAD_CONTENT_ENCODING;
}
@@ -479,17 +431,14 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
offset += wrap_buf[1].cbBuffer;
memcpy(appdata + offset, wrap_buf[2].pvBuffer, wrap_buf[2].cbBuffer);
- /* Base64 encode the response */
- result = Curl_base64_encode(data, (char *) appdata, appdatalen, outptr,
- outlen);
-
/* Free all of our local buffers */
- free(appdata);
free(padding);
free(message);
free(trailer);
- return result;
+ /* Return the response. */
+ Curl_bufref_set(out, appdata, appdatalen, curl_free);
+ return CURLE_OK;
}
/*
diff --git a/libs/libcurl/src/vauth/ntlm.c b/libs/libcurl/src/vauth/ntlm.c
index 4adf49704f..47e53572cb 100644
--- a/libs/libcurl/src/vauth/ntlm.c
+++ b/libs/libcurl/src/vauth/ntlm.c
@@ -36,7 +36,6 @@
#include "urldata.h"
#include "non-ascii.h"
#include "sendf.h"
-#include "curl_base64.h"
#include "curl_ntlm_core.h"
#include "curl_gethostname.h"
#include "curl_multibyte.h"
@@ -157,31 +156,31 @@ static void ntlm_print_hex(FILE *handle, const char *buf, size_t len)
* Parameters:
*
* data [in] - The session handle.
- * buffer [in] - The decoded type-2 message.
- * size [in] - The input buffer size, at least 32 bytes.
+ * type2ref [in] - The type-2 message.
* ntlm [in/out] - The NTLM data struct being used and modified.
*
* Returns CURLE_OK on success.
*/
static CURLcode ntlm_decode_type2_target(struct Curl_easy *data,
- unsigned char *buffer,
- size_t size,
+ const struct bufref *type2ref,
struct ntlmdata *ntlm)
{
unsigned short target_info_len = 0;
unsigned int target_info_offset = 0;
+ const unsigned char *type2 = Curl_bufref_ptr(type2ref);
+ size_t type2len = Curl_bufref_len(type2ref);
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
(void) data;
#endif
- if(size >= 48) {
- target_info_len = Curl_read16_le(&buffer[40]);
- target_info_offset = Curl_read32_le(&buffer[44]);
+ if(type2len >= 48) {
+ target_info_len = Curl_read16_le(&type2[40]);
+ target_info_offset = Curl_read32_le(&type2[44]);
if(target_info_len > 0) {
- if((target_info_offset >= size) ||
- ((target_info_offset + target_info_len) > size) ||
- (target_info_offset < 48)) {
+ if((target_info_offset > type2len) ||
+ (target_info_offset + target_info_len) > type2len ||
+ target_info_offset < 48) {
infof(data, "NTLM handshake failure (bad type-2 message). "
"Target Info Offset Len is set incorrect by the peer\n");
return CURLE_BAD_CONTENT_ENCODING;
@@ -192,7 +191,7 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data,
if(!ntlm->target_info)
return CURLE_OUT_OF_MEMORY;
- memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len);
+ memcpy(ntlm->target_info, &type2[target_info_offset], target_info_len);
}
}
@@ -234,21 +233,20 @@ bool Curl_auth_is_ntlm_supported(void)
/*
* Curl_auth_decode_ntlm_type2_message()
*
- * This is used to decode an already encoded NTLM type-2 message. The message
- * is first decoded from a base64 string into a raw NTLM message and checked
- * for validity before the appropriate data for creating a type-3 message is
- * written to the given NTLM data structure.
+ * This is used to decode an NTLM type-2 message. The raw NTLM message is
+ * checked * for validity before the appropriate data for creating a type-3
+ * message is * written to the given NTLM data structure.
*
* Parameters:
*
* data [in] - The session handle.
- * type2msg [in] - The base64 encoded type-2 message.
+ * type2ref [in] - The type-2 message.
* ntlm [in/out] - The NTLM data struct being used and modified.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
- const char *type2msg,
+ const struct bufref *type2ref,
struct ntlmdata *ntlm)
{
static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
@@ -270,8 +268,8 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
*/
CURLcode result = CURLE_OK;
- unsigned char *type2 = NULL;
- size_t type2_len = 0;
+ const unsigned char *type2 = Curl_bufref_ptr(type2ref);
+ size_t type2len = Curl_bufref_len(type2ref);
#if defined(NTLM_NEEDS_NSS_INIT)
/* Make sure the crypto backend is initialized */
@@ -282,26 +280,12 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
(void)data;
#endif
- /* Decode the base-64 encoded type-2 message */
- if(strlen(type2msg) && *type2msg != '=') {
- result = Curl_base64_decode(type2msg, &type2, &type2_len);
- if(result)
- return result;
- }
-
- /* Ensure we have a valid type-2 message */
- if(!type2) {
- infof(data, "NTLM handshake failure (empty type-2 message)\n");
- return CURLE_BAD_CONTENT_ENCODING;
- }
-
ntlm->flags = 0;
- if((type2_len < 32) ||
+ if((type2len < 32) ||
(memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
(memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) {
/* This was not a good enough type-2 message */
- free(type2);
infof(data, "NTLM handshake failure (bad type-2 message)\n");
return CURLE_BAD_CONTENT_ENCODING;
}
@@ -310,9 +294,8 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
memcpy(ntlm->nonce, &type2[24], 8);
if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
- result = ntlm_decode_type2_target(data, type2, type2_len, ntlm);
+ result = ntlm_decode_type2_target(data, type2ref, ntlm);
if(result) {
- free(type2);
infof(data, "NTLM handshake failure (bad type-2 message)\n");
return result;
}
@@ -327,8 +310,6 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
fprintf(stderr, "**** Header %s\n ", header);
});
- free(type2);
-
return result;
}
@@ -346,8 +327,8 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
/*
* Curl_auth_create_ntlm_type1_message()
*
- * This is used to generate an already encoded NTLM type-1 message ready for
- * sending to the recipient using the appropriate compile time crypto API.
+ * This is used to generate an NTLM type-1 message ready for sending to the
+ * recipient using the appropriate compile time crypto API.
*
* Parameters:
*
@@ -357,9 +338,7 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
* service [in] - The service type such as http, smtp, pop or imap.
* host [in] - The host name.
* ntlm [in/out] - The NTLM data struct being used and modified.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
@@ -369,7 +348,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
const char *service,
const char *hostname,
struct ntlmdata *ntlm,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
/* NTLM type-1 message structure:
@@ -387,7 +366,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
size_t size;
- unsigned char ntlmbuf[NTLM_BUFSIZE];
+ char *ntlmbuf;
const char *host = ""; /* empty */
const char *domain = ""; /* empty */
size_t hostlen = 0;
@@ -395,6 +374,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
size_t hostoff = 0;
size_t domoff = hostoff + hostlen; /* This is 0: remember that host and
domain are empty */
+ (void)data;
(void)userp;
(void)passwdp;
(void)service,
@@ -409,38 +389,40 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
#else
#define NTLM2FLAG 0
#endif
- msnprintf((char *)ntlmbuf, NTLM_BUFSIZE,
- NTLMSSP_SIGNATURE "%c"
- "\x01%c%c%c" /* 32-bit type = 1 */
- "%c%c%c%c" /* 32-bit NTLM flag field */
- "%c%c" /* domain length */
- "%c%c" /* domain allocated space */
- "%c%c" /* domain name offset */
- "%c%c" /* 2 zeroes */
- "%c%c" /* host length */
- "%c%c" /* host allocated space */
- "%c%c" /* host name offset */
- "%c%c" /* 2 zeroes */
- "%s" /* host name */
- "%s", /* domain string */
- 0, /* trailing zero */
- 0, 0, 0, /* part of type-1 long */
-
- LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
- NTLMFLAG_REQUEST_TARGET |
- NTLMFLAG_NEGOTIATE_NTLM_KEY |
- NTLM2FLAG |
- NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
- SHORTPAIR(domlen),
- SHORTPAIR(domlen),
- SHORTPAIR(domoff),
- 0, 0,
- SHORTPAIR(hostlen),
- SHORTPAIR(hostlen),
- SHORTPAIR(hostoff),
- 0, 0,
- host, /* this is empty */
- domain /* this is empty */);
+ ntlmbuf = aprintf(NTLMSSP_SIGNATURE "%c"
+ "\x01%c%c%c" /* 32-bit type = 1 */
+ "%c%c%c%c" /* 32-bit NTLM flag field */
+ "%c%c" /* domain length */
+ "%c%c" /* domain allocated space */
+ "%c%c" /* domain name offset */
+ "%c%c" /* 2 zeroes */
+ "%c%c" /* host length */
+ "%c%c" /* host allocated space */
+ "%c%c" /* host name offset */
+ "%c%c" /* 2 zeroes */
+ "%s" /* host name */
+ "%s", /* domain string */
+ 0, /* trailing zero */
+ 0, 0, 0, /* part of type-1 long */
+
+ LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
+ NTLMFLAG_REQUEST_TARGET |
+ NTLMFLAG_NEGOTIATE_NTLM_KEY |
+ NTLM2FLAG |
+ NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
+ SHORTPAIR(domlen),
+ SHORTPAIR(domlen),
+ SHORTPAIR(domoff),
+ 0, 0,
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostoff),
+ 0, 0,
+ host, /* this is empty */
+ domain /* this is empty */);
+
+ if(!ntlmbuf)
+ return CURLE_OUT_OF_MEMORY;
/* Initial packet length */
size = 32 + hostlen + domlen;
@@ -467,8 +449,8 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
fprintf(stderr, "\n****\n");
});
- /* Return with binary blob encoded into base64 */
- return Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen);
+ Curl_bufref_set(out, ntlmbuf, size, curl_free);
+ return CURLE_OK;
}
/*
@@ -483,9 +465,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
* userp [in] - The user name in the format User or Domain\User.
* passwdp [in] - The user's password.
* ntlm [in/out] - The NTLM data struct being used and modified.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
@@ -493,7 +473,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
const char *userp,
const char *passwdp,
struct ntlmdata *ntlm,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
/* NTLM type-3 message structure:
@@ -847,8 +827,8 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
if(result)
return CURLE_CONV_FAILED;
- /* Return with binary blob encoded into base64 */
- result = Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen);
+ /* Return the binary blob. */
+ result = Curl_bufref_memdup(out, ntlmbuf, size);
Curl_auth_cleanup_ntlm(ntlm);
diff --git a/libs/libcurl/src/vauth/ntlm_sspi.c b/libs/libcurl/src/vauth/ntlm_sspi.c
index 07dc97398e..1b1a176301 100644
--- a/libs/libcurl/src/vauth/ntlm_sspi.c
+++ b/libs/libcurl/src/vauth/ntlm_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -28,7 +28,6 @@
#include "vauth/vauth.h"
#include "urldata.h"
-#include "curl_base64.h"
#include "curl_ntlm_core.h"
#include "warnless.h"
#include "curl_multibyte.h"
@@ -78,9 +77,7 @@ bool Curl_auth_is_ntlm_supported(void)
* service [in] - The service type such as http, smtp, pop or imap.
* host [in] - The host name.
* ntlm [in/out] - The NTLM data struct being used and modified.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
@@ -90,7 +87,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
const char *service,
const char *host,
struct ntlmdata *ntlm,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
PSecPkgInfo SecurityPackage;
SecBuffer type_1_buf;
@@ -181,9 +178,9 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED)
return CURLE_AUTH_ERROR;
- /* Base64 encode the response */
- return Curl_base64_encode(data, (char *) ntlm->output_token,
- type_1_buf.cbBuffer, outptr, outlen);
+ /* Return the response. */
+ Curl_bufref_set(out, ntlm->output_token, type_1_buf.cbBuffer, NULL);
+ return CURLE_OK;
}
/*
@@ -194,42 +191,34 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
* Parameters:
*
* data [in] - The session handle.
- * type2msg [in] - The base64 encoded type-2 message.
+ * type2 [in] - The type-2 message.
* ntlm [in/out] - The NTLM data struct being used and modified.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
- const char *type2msg,
+ const struct bufref *type2,
struct ntlmdata *ntlm)
{
- CURLcode result = CURLE_OK;
- unsigned char *type2 = NULL;
- size_t type2_len = 0;
-
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
(void) data;
#endif
- /* Decode the base-64 encoded type-2 message */
- if(strlen(type2msg) && *type2msg != '=') {
- result = Curl_base64_decode(type2msg, &type2, &type2_len);
- if(result)
- return result;
- }
-
/* Ensure we have a valid type-2 message */
- if(!type2) {
+ if(!Curl_bufref_len(type2)) {
infof(data, "NTLM handshake failure (empty type-2 message)\n");
-
return CURLE_BAD_CONTENT_ENCODING;
}
- /* Simply store the challenge for use later */
- ntlm->input_token = type2;
- ntlm->input_token_len = type2_len;
+ /* Store the challenge for later use */
+ ntlm->input_token = malloc(Curl_bufref_len(type2) + 1);
+ if(!ntlm->input_token)
+ return CURLE_OUT_OF_MEMORY;
+ memcpy(ntlm->input_token, Curl_bufref_ptr(type2), Curl_bufref_len(type2));
+ ntlm->input_token[Curl_bufref_len(type2)] = '\0';
+ ntlm->input_token_len = Curl_bufref_len(type2);
- return result;
+ return CURLE_OK;
}
/*
@@ -245,9 +234,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
* userp [in] - The user name in the format User or Domain\User.
* passwdp [in] - The user's password.
* ntlm [in/out] - The NTLM data struct being used and modified.
- * outptr [in/out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen [out] - The length of the output message.
+ * out [out] - The result storage.
*
* Returns CURLE_OK on success.
*/
@@ -255,7 +242,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
const char *userp,
const char *passwdp,
struct ntlmdata *ntlm,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
CURLcode result = CURLE_OK;
SecBuffer type_2_bufs[2];
@@ -331,12 +318,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
return CURLE_AUTH_ERROR;
}
- /* Base64 encode the response */
- result = Curl_base64_encode(data, (char *) ntlm->output_token,
- type_3_buf.cbBuffer, outptr, outlen);
-
+ /* Return the response. */
+ result = Curl_bufref_memdup(out, ntlm->output_token, type_3_buf.cbBuffer);
Curl_auth_cleanup_ntlm(ntlm);
-
return result;
}
diff --git a/libs/libcurl/src/vauth/oauth2.c b/libs/libcurl/src/vauth/oauth2.c
index ca5842a7c0..a5f16a0bf4 100644
--- a/libs/libcurl/src/vauth/oauth2.c
+++ b/libs/libcurl/src/vauth/oauth2.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -31,7 +31,6 @@
#include "urldata.h"
#include "vauth/vauth.h"
-#include "curl_base64.h"
#include "warnless.h"
#include "curl_printf.h"
@@ -42,31 +41,26 @@
/*
* Curl_auth_create_oauth_bearer_message()
*
- * This is used to generate an already encoded OAuth 2.0 message ready for
- * sending to the recipient.
+ * This is used to generate an OAuth 2.0 message ready for sending to the
+ * recipient.
*
* Parameters:
*
- * data[in] - The session handle.
* user[in] - The user name.
* host[in] - The host name.
* port[in] - The port(when not Port 80).
* bearer[in] - The bearer token.
- * outptr[in / out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen[out] - The length of the output message.
+ * out[out] - The result storage.
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
- const char *user,
+CURLcode Curl_auth_create_oauth_bearer_message(const char *user,
const char *host,
const long port,
const char *bearer,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
- CURLcode result = CURLE_OK;
- char *oauth = NULL;
+ char *oauth;
/* Generate the message */
if(port == 0 || port == 80)
@@ -78,49 +72,34 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
if(!oauth)
return CURLE_OUT_OF_MEMORY;
- /* Base64 encode the reply */
- result = Curl_base64_encode(data, oauth, strlen(oauth), outptr, outlen);
-
- free(oauth);
-
- return result;
+ Curl_bufref_set(out, oauth, strlen(oauth), curl_free);
+ return CURLE_OK;
}
/*
* Curl_auth_create_xoauth_bearer_message()
*
- * This is used to generate an already encoded XOAuth 2.0 message ready for
- * sending to the recipient.
+ * This is used to generate a XOAuth 2.0 message ready for * sending to the
+ * recipient.
*
* Parameters:
*
- * data[in] - The session handle.
* user[in] - The user name.
* bearer[in] - The bearer token.
- * outptr[in / out] - The address where a pointer to newly allocated memory
- * holding the result will be stored upon completion.
- * outlen[out] - The length of the output message.
+ * out[out] - The result storage.
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data,
- const char *user,
+CURLcode Curl_auth_create_xoauth_bearer_message(const char *user,
const char *bearer,
- char **outptr, size_t *outlen)
+ struct bufref *out)
{
- CURLcode result = CURLE_OK;
-
/* Generate the message */
char *xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
if(!xoauth)
return CURLE_OUT_OF_MEMORY;
- /* Base64 encode the reply */
- result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen);
-
- free(xoauth);
-
- return result;
+ Curl_bufref_set(out, xoauth, strlen(xoauth), curl_free);
+ return CURLE_OK;
}
#endif /* disabled, no users */
-
diff --git a/libs/libcurl/src/vauth/vauth.c b/libs/libcurl/src/vauth/vauth.c
index 129b8f8b57..3624fb0c4a 100644
--- a/libs/libcurl/src/vauth/vauth.c
+++ b/libs/libcurl/src/vauth/vauth.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2020, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2021, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -72,6 +72,7 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
{
char *utf8_spn = NULL;
TCHAR *tchar_spn = NULL;
+ TCHAR *dupe_tchar_spn = NULL;
(void) realm;
@@ -84,23 +85,19 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
/* Generate our UTF8 based SPN */
utf8_spn = aprintf("%s/%s", service, host);
- if(!utf8_spn) {
+ if(!utf8_spn)
return NULL;
- }
- /* Allocate our TCHAR based SPN */
+ /* Allocate and return a TCHAR based SPN. Since curlx_convert_UTF8_to_tchar
+ must be freed by curlx_unicodefree we'll dupe the result so that the
+ pointer this function returns can be normally free'd. */
tchar_spn = curlx_convert_UTF8_to_tchar(utf8_spn);
- if(!tchar_spn) {
- free(utf8_spn);
-
+ free(utf8_spn);
+ if(!tchar_spn)
return NULL;
- }
-
- /* Release the UTF8 variant when operating with Unicode */
- curlx_unicodefree(utf8_spn);
-
- /* Return our newly allocated SPN */
- return tchar_spn;
+ dupe_tchar_spn = _tcsdup(tchar_spn);
+ curlx_unicodefree(tchar_spn);
+ return dupe_tchar_spn;
}
#endif /* USE_WINDOWS_SSPI */
diff --git a/libs/libcurl/src/vauth/vauth.h b/libs/libcurl/src/vauth/vauth.h
index 03a5f8adb5..ec5b0007f5 100644
--- a/libs/libcurl/src/vauth/vauth.h
+++ b/libs/libcurl/src/vauth/vauth.h
@@ -24,6 +24,8 @@
#include <curl/curl.h>
+#include "bufref.h"
+
struct Curl_easy;
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
@@ -62,45 +64,37 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
/* This is used to test if the user contains a Windows domain name */
bool Curl_auth_user_contains_domain(const char *user);
-/* This is used to generate a base64 encoded PLAIN cleartext message */
-CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
- const char *authzid,
+/* This is used to generate a PLAIN cleartext message */
+CURLcode Curl_auth_create_plain_message(const char *authzid,
const char *authcid,
const char *passwd,
- char **outptr, size_t *outlen);
+ struct bufref *out);
-/* This is used to generate a base64 encoded LOGIN cleartext message */
-CURLcode Curl_auth_create_login_message(struct Curl_easy *data,
- const char *valuep, char **outptr,
- size_t *outlen);
+/* This is used to generate a LOGIN cleartext message */
+CURLcode Curl_auth_create_login_message(const char *value,
+ struct bufref *out);
-/* This is used to generate a base64 encoded EXTERNAL cleartext message */
-CURLcode Curl_auth_create_external_message(struct Curl_easy *data,
- const char *user, char **outptr,
- size_t *outlen);
+/* This is used to generate an EXTERNAL cleartext message */
+CURLcode Curl_auth_create_external_message(const char *user,
+ struct bufref *out);
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
-/* This is used to decode a CRAM-MD5 challenge message */
-CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr,
- size_t *outlen);
-
/* This is used to generate a CRAM-MD5 response message */
-CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data,
- const char *chlg,
+CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
const char *userp,
const char *passwdp,
- char **outptr, size_t *outlen);
+ struct bufref *out);
/* This is used to evaluate if DIGEST is supported */
bool Curl_auth_is_digest_supported(void);
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
- const char *chlg64,
+ const struct bufref *chlg,
const char *userp,
const char *passwdp,
const char *service,
- char **outptr, size_t *outlen);
+ struct bufref *out);
/* This is used to decode a HTTP DIGEST challenge message */
CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
@@ -132,9 +126,9 @@ CURLcode Curl_auth_gsasl_start(struct Curl_easy *data,
/* This is used to process and generate a new SASL token */
CURLcode Curl_auth_gsasl_token(struct Curl_easy *data,
- const char *chlg64,
+ const struct bufref *chlg,
struct gsasldata *gsasl,
- char **outptr, size_t *outlen);
+ struct bufref *out);
/* This is used to clean up the gsasl specific data */
void Curl_auth_gsasl_cleanup(struct gsasldata *digest);
@@ -151,12 +145,11 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
const char *service,
const char *host,
struct ntlmdata *ntlm,
- char **outptr,
- size_t *outlen);
+ struct bufref *out);
/* This is used to decode a base64 encoded NTLM type-2 message */
CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
- const char *type2msg,
+ const struct bufref *type2,
struct ntlmdata *ntlm);
/* This is used to generate a base64 encoded NTLM type-3 message */
@@ -164,25 +157,23 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
const char *userp,
const char *passwdp,
struct ntlmdata *ntlm,
- char **outptr, size_t *outlen);
+ struct bufref *out);
/* This is used to clean up the NTLM specific data */
void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm);
#endif /* USE_NTLM */
/* This is used to generate a base64 encoded OAuth 2.0 message */
-CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
- const char *user,
+CURLcode Curl_auth_create_oauth_bearer_message(const char *user,
const char *host,
const long port,
const char *bearer,
- char **outptr, size_t *outlen);
+ struct bufref *out);
/* This is used to generate a base64 encoded XOAuth 2.0 message */
-CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data,
- const char *user,
+CURLcode Curl_auth_create_xoauth_bearer_message(const char *user,
const char *bearer,
- char **outptr, size_t *outlen);
+ struct bufref *out);
#if defined(USE_KERBEROS5)
/* This is used to evaluate if GSSAPI (Kerberos V5) is supported */
@@ -196,17 +187,16 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
const char *service,
const char *host,
const bool mutual,
- const char *chlg64,
+ const struct bufref *chlg,
struct kerberos5data *krb5,
- char **outptr, size_t *outlen);
+ struct bufref *out);
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security
token message */
CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
- const char *input,
+ const struct bufref *chlg,
struct kerberos5data *krb5,
- char **outptr,
- size_t *outlen);
+ struct bufref *out);
/* This is used to clean up the GSSAPI specific data */
void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5);
diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c
index b33f2fe83b..b67b9a4660 100644
--- a/libs/libcurl/src/version.c
+++ b/libs/libcurl/src/version.c
@@ -66,6 +66,14 @@
#include <zstd.h>
#endif
+#ifdef USE_GSASL
+#include <gsasl.h>
+#endif
+
+#ifdef USE_OPENLDAP
+#include <ldap.h>
+#endif
+
#ifdef HAVE_BROTLI
static size_t brotli_version(char *buf, size_t bufsz)
{
@@ -100,7 +108,7 @@ static size_t zstd_version(char *buf, size_t bufsz)
* zeros in the data.
*/
-#define VERSION_PARTS 16 /* number of substrings we can concatenate */
+#define VERSION_PARTS 17 /* number of substrings we can concatenate */
char *curl_version(void)
{
@@ -150,6 +158,9 @@ char *curl_version(void)
#ifdef USE_GSASL
char gsasl_buf[30];
#endif
+#ifdef USE_OPENLDAP
+ char ldap_buf[30];
+#endif
int i = 0;
int j;
@@ -243,6 +254,24 @@ char *curl_version(void)
gsasl_check_version(NULL));
src[i++] = gsasl_buf;
#endif
+#ifdef USE_OPENLDAP
+ {
+ LDAPAPIInfo api;
+ api.ldapai_info_version = LDAP_API_INFO_VERSION;
+
+ if(ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) == LDAP_OPT_SUCCESS) {
+ unsigned int patch = api.ldapai_vendor_version % 100;
+ unsigned int major = api.ldapai_vendor_version / 10000;
+ unsigned int minor =
+ ((api.ldapai_vendor_version - major * 10000) - patch) / 100;
+ msnprintf(ldap_buf, sizeof(ldap_buf), "%s/%u.%u.%u",
+ api.ldapai_vendor_name, major, minor, patch);
+ src[i++] = ldap_buf;
+ ldap_memfree(api.ldapai_vendor_name);
+ ber_memvfree((void **)api.ldapai_extensions);
+ }
+ }
+#endif
DEBUGASSERT(i <= VERSION_PARTS);
@@ -436,7 +465,7 @@ static curl_version_info_data version_info = {
#ifndef CURL_DISABLE_ALTSVC
| CURL_VERSION_ALTSVC
#endif
-#if defined(USE_HSTS)
+#ifndef CURL_DISABLE_HSTS
| CURL_VERSION_HSTS
#endif
#if defined(USE_GSASL)
@@ -469,7 +498,8 @@ static curl_version_info_data version_info = {
#endif
0, /* zstd_ver_num */
NULL, /* zstd version */
- NULL /* Hyper version */
+ NULL, /* Hyper version */
+ NULL /* gsasl version */
};
curl_version_info_data *curl_version_info(CURLversion stamp)
@@ -573,6 +603,12 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
}
#endif
+#ifdef USE_GSASL
+ {
+ version_info.gsasl_version = gsasl_check_version(NULL);
+ }
+#endif
+
(void)stamp; /* avoid compiler warnings, we don't use this */
return &version_info;
}
diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c
index 3d64519987..7f076759b8 100644
--- a/libs/libcurl/src/vquic/ngtcp2.c
+++ b/libs/libcurl/src/vquic/ngtcp2.c
@@ -226,7 +226,7 @@ static int write_client_handshake(struct quicsocket *qs,
int rv;
crypto_data = &qs->crypto_data[level];
- if(crypto_data->buf == NULL) {
+ if(!crypto_data->buf) {
crypto_data->buf = malloc(4096);
if(!crypto_data->buf)
return 0;
@@ -603,7 +603,7 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
static int
cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id,
- uint64_t offset, size_t datalen, void *user_data,
+ uint64_t offset, uint64_t datalen, void *user_data,
void *stream_user_data)
{
struct quicsocket *qs = (struct quicsocket *)user_data;
@@ -615,7 +615,7 @@ cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id,
(void)stream_user_data;
rv = nghttp3_conn_add_ack_offset(qs->h3conn, stream_id, datalen);
- if(rv != 0) {
+ if(rv) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
@@ -634,7 +634,7 @@ static int cb_stream_close(ngtcp2_conn *tconn, int64_t stream_id,
rv = nghttp3_conn_close_stream(qs->h3conn, stream_id,
app_error_code);
- if(rv != 0) {
+ if(rv) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
@@ -653,7 +653,7 @@ static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id,
(void)stream_user_data;
rv = nghttp3_conn_reset_stream(qs->h3conn, stream_id);
- if(rv != 0) {
+ if(rv) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
@@ -682,7 +682,7 @@ static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id,
(void)stream_user_data;
rv = nghttp3_conn_unblock_stream(qs->h3conn, stream_id);
- if(rv != 0) {
+ if(rv) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
@@ -934,6 +934,7 @@ static const struct Curl_handler Curl_handler_http3 = {
ng_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ng_conncheck, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_HTTP, /* defport */
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
@@ -1309,7 +1310,7 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
if(stream->h3out->used == 0) {
int rv = nghttp3_conn_resume_stream(conn, stream_id);
- if(rv != 0) {
+ if(rv) {
return NGTCP2_ERR_CALLBACK_FAILURE;
}
}
@@ -1545,7 +1546,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem,
}
/* :authority must come before non-pseudo header fields */
- if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
+ if(authority_idx && authority_idx != AUTHORITY_DST_IDX) {
nghttp3_nv authority = nva[authority_idx];
for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
nva[i] = nva[i - 1];
@@ -1741,7 +1742,7 @@ static CURLcode ng_process_ingress(struct Curl_easy *data,
remote_addrlen);
rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts);
- if(rv != 0) {
+ if(rv) {
/* TODO Send CONNECTION_CLOSE if possible */
return CURLE_RECV_ERROR;
}
@@ -1785,7 +1786,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
}
rv = ngtcp2_conn_handle_expiry(qs->qconn, ts);
- if(rv != 0) {
+ if(rv) {
failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
ngtcp2_strerror(rv));
return CURLE_SEND_ERROR;
@@ -1821,7 +1822,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
outlen == NGTCP2_ERR_STREAM_SHUT_WR) {
assert(ndatalen == -1);
rv = nghttp3_conn_block_stream(qs->h3conn, stream_id);
- if(rv != 0) {
+ if(rv) {
failf(data, "nghttp3_conn_block_stream returned error: %s\n",
nghttp3_strerror(rv));
return CURLE_SEND_ERROR;
@@ -1831,7 +1832,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
else if(outlen == NGTCP2_ERR_WRITE_MORE) {
assert(ndatalen >= 0);
rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen);
- if(rv != 0) {
+ if(rv) {
failf(data, "nghttp3_conn_add_write_offset returned error: %s\n",
nghttp3_strerror(rv));
return CURLE_SEND_ERROR;
@@ -1847,7 +1848,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
}
else if(ndatalen >= 0) {
rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen);
- if(rv != 0) {
+ if(rv) {
failf(data, "nghttp3_conn_add_write_offset returned error: %s\n",
nghttp3_strerror(rv));
return CURLE_SEND_ERROR;
diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c
index a3870749b5..b62d88437a 100644
--- a/libs/libcurl/src/vquic/quiche.c
+++ b/libs/libcurl/src/vquic/quiche.c
@@ -157,6 +157,7 @@ static const struct Curl_handler Curl_handler_http3 = {
quiche_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
quiche_conncheck, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_HTTP, /* defport */
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
@@ -225,7 +226,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
quiche_config_log_keys(qs->cfg);
qs->conn = quiche_connect(conn->host.name, (const uint8_t *) qs->scid,
- sizeof(qs->scid), qs->cfg);
+ sizeof(qs->scid), addr, addrlen, qs->cfg);
if(!qs->conn) {
failf(data, "can't create quiche connection");
return CURLE_OUT_OF_MEMORY;
@@ -359,6 +360,9 @@ static CURLcode process_ingress(struct Curl_easy *data, int sockfd,
ssize_t recvd;
uint8_t *buf = (uint8_t *)data->state.buffer;
size_t bufsize = data->set.buffer_size;
+ struct sockaddr_storage from;
+ socklen_t from_len;
+ quiche_recv_info recv_info;
DEBUGASSERT(qs->conn);
@@ -366,17 +370,24 @@ static CURLcode process_ingress(struct Curl_easy *data, int sockfd,
quiche_conn_on_timeout(qs->conn);
do {
- recvd = recv(sockfd, buf, bufsize, 0);
+ from_len = sizeof(from);
+
+ recvd = recvfrom(sockfd, buf, bufsize, 0,
+ (struct sockaddr *)&from, &from_len);
+
if((recvd < 0) && ((SOCKERRNO == EAGAIN) || (SOCKERRNO == EWOULDBLOCK)))
break;
if(recvd < 0) {
- failf(data, "quiche: recv() unexpectedly returned %zd "
+ failf(data, "quiche: recvfrom() unexpectedly returned %zd "
"(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd);
return CURLE_RECV_ERROR;
}
- recvd = quiche_conn_recv(qs->conn, buf, recvd);
+ recv_info.from = (struct sockaddr *) &from;
+ recv_info.from_len = from_len;
+
+ recvd = quiche_conn_recv(qs->conn, buf, recvd, &recv_info);
if(recvd == QUICHE_ERR_DONE)
break;
@@ -399,9 +410,10 @@ static CURLcode flush_egress(struct Curl_easy *data, int sockfd,
ssize_t sent;
uint8_t out[1200];
int64_t timeout_ns;
+ quiche_send_info send_info;
do {
- sent = quiche_conn_send(qs->conn, out, sizeof(out));
+ sent = quiche_conn_send(qs->conn, out, sizeof(out), &send_info);
if(sent == QUICHE_ERR_DONE)
break;
@@ -410,9 +422,10 @@ static CURLcode flush_egress(struct Curl_easy *data, int sockfd,
return CURLE_SEND_ERROR;
}
- sent = send(sockfd, out, sent, 0);
+ sent = sendto(sockfd, out, sent, 0,
+ (struct sockaddr *)&send_info.to, send_info.to_len);
if(sent < 0) {
- failf(data, "send() returned %zd", sent);
+ failf(data, "sendto() returned %zd", sent);
return CURLE_SEND_ERROR;
}
} while(1);
@@ -750,7 +763,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem,
}
/* :authority must come before non-pseudo header fields */
- if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
+ if(authority_idx && authority_idx != AUTHORITY_DST_IDX) {
quiche_h3_header authority = nva[authority_idx];
for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
nva[i] = nva[i - 1];
diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c
index 4644f4cb96..d146d15fdf 100644
--- a/libs/libcurl/src/vssh/libssh.c
+++ b/libs/libcurl/src/vssh/libssh.c
@@ -159,6 +159,7 @@ const struct Curl_handler Curl_handler_scp = {
scp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_SSH, /* defport */
CURLPROTO_SCP, /* protocol */
CURLPROTO_SCP, /* family */
@@ -185,6 +186,7 @@ const struct Curl_handler Curl_handler_sftp = {
sftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_SSH, /* defport */
CURLPROTO_SFTP, /* protocol */
CURLPROTO_SFTP, /* family */
@@ -549,49 +551,48 @@ cleanup:
return rc;
}
-#define MOVE_TO_ERROR_STATE(_r) { \
- state(data, SSH_SESSION_DISCONNECT); \
- sshc->actualcode = _r; \
- rc = SSH_ERROR; \
- break; \
-}
+#define MOVE_TO_ERROR_STATE(_r) do { \
+ state(data, SSH_SESSION_DISCONNECT); \
+ sshc->actualcode = _r; \
+ rc = SSH_ERROR; \
+ } while(0)
-#define MOVE_TO_SFTP_CLOSE_STATE() { \
- state(data, SSH_SFTP_CLOSE); \
- sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \
- rc = SSH_ERROR; \
- break; \
-}
+#define MOVE_TO_SFTP_CLOSE_STATE() do { \
+ state(data, SSH_SFTP_CLOSE); \
+ sshc->actualcode = \
+ sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \
+ rc = SSH_ERROR; \
+ } while(0)
-#define MOVE_TO_LAST_AUTH \
- if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \
- rc = SSH_OK; \
- state(data, SSH_AUTH_PASS_INIT); \
- break; \
- } \
- else { \
- MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \
- }
+#define MOVE_TO_LAST_AUTH do { \
+ if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \
+ rc = SSH_OK; \
+ state(data, SSH_AUTH_PASS_INIT); \
+ } \
+ else { \
+ MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \
+ } \
+ } while(0)
-#define MOVE_TO_TERTIARY_AUTH \
- if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \
- rc = SSH_OK; \
- state(data, SSH_AUTH_KEY_INIT); \
- break; \
- } \
- else { \
- MOVE_TO_LAST_AUTH; \
- }
+#define MOVE_TO_TERTIARY_AUTH do { \
+ if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \
+ rc = SSH_OK; \
+ state(data, SSH_AUTH_KEY_INIT); \
+ } \
+ else { \
+ MOVE_TO_LAST_AUTH; \
+ } \
+ } while(0)
-#define MOVE_TO_SECONDARY_AUTH \
- if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \
- rc = SSH_OK; \
- state(data, SSH_AUTH_GSSAPI); \
- break; \
- } \
- else { \
- MOVE_TO_TERTIARY_AUTH; \
- }
+#define MOVE_TO_SECONDARY_AUTH do { \
+ if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \
+ rc = SSH_OK; \
+ state(data, SSH_AUTH_GSSAPI); \
+ } \
+ else { \
+ MOVE_TO_TERTIARY_AUTH; \
+ } \
+ } while(0)
static
int myssh_auth_interactive(struct connectdata *conn)
@@ -629,7 +630,7 @@ restart:
rc = SSH_OK;
else if(rc == SSH_AUTH_INFO) {
nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session);
- if(nprompts != 0)
+ if(nprompts)
return SSH_ERROR;
sshc->kbd_state = 2;
@@ -704,6 +705,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc != SSH_OK) {
failf(data, "Failure establishing ssh session");
MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT);
+ break;
}
state(data, SSH_HOSTKEY);
@@ -714,6 +716,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
rc = myssh_is_known(data);
if(rc != SSH_OK) {
MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION);
+ break;
}
state(data, SSH_AUTHLIST);
@@ -735,6 +738,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
else if(rc == SSH_AUTH_ERROR) {
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+ break;
}
sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
@@ -753,6 +757,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
else { /* unsupported authentication method */
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+ break;
}
break;
@@ -760,6 +765,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_AUTH_PKEY_INIT:
if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) {
MOVE_TO_SECONDARY_AUTH;
+ break;
}
/* Two choices, (1) private key was given on CMD,
@@ -775,6 +781,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc != SSH_OK) {
MOVE_TO_SECONDARY_AUTH;
+ break;
}
}
@@ -833,6 +840,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_AUTH_GSSAPI:
if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) {
MOVE_TO_TERTIARY_AUTH;
+ break;
}
rc = ssh_userauth_gssapi(sshc->ssh_session);
@@ -879,6 +887,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) {
/* Host key authentication is intentionally not implemented */
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+ break;
}
state(data, SSH_AUTH_PASS);
/* FALLTHROUGH */
@@ -951,8 +960,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
* Get the "home" directory
*/
sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, ".");
- if(sshc->homedir == NULL) {
+ if(!sshc->homedir) {
MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
+ break;
}
data->state.most_recent_ftp_entrypath = sshc->homedir;
@@ -1025,7 +1035,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_SFTP_QUOTE_SETSTAT:
rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2,
sshc->quote_attrs);
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
failf(data, "Attempt to set SFTP stats failed: %s",
@@ -1044,7 +1054,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_SFTP_QUOTE_SYMLINK:
rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2,
sshc->quote_path1);
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
failf(data, "symlink command failed: %s",
@@ -1060,7 +1070,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_SFTP_QUOTE_MKDIR:
rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1,
(mode_t)data->set.new_directory_perms);
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
Curl_safefree(sshc->quote_path1);
failf(data, "mkdir command failed: %s",
ssh_get_error(sshc->ssh_session));
@@ -1075,7 +1085,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_SFTP_QUOTE_RENAME:
rc = sftp_rename(sshc->sftp_session, sshc->quote_path1,
sshc->quote_path2);
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
failf(data, "rename command failed: %s",
@@ -1090,7 +1100,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_SFTP_QUOTE_RMDIR:
rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
Curl_safefree(sshc->quote_path1);
failf(data, "rmdir command failed: %s",
ssh_get_error(sshc->ssh_session));
@@ -1104,7 +1114,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_SFTP_QUOTE_UNLINK:
rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1);
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
Curl_safefree(sshc->quote_path1);
failf(data, "rm command failed: %s",
ssh_get_error(sshc->ssh_session));
@@ -1179,7 +1189,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
sftp_attributes attrs;
attrs = sftp_stat(sshc->sftp_session, protop->path);
- if(attrs != 0) {
+ if(attrs) {
data->info.filetime = attrs->mtime;
sftp_attributes_free(attrs);
}
@@ -1203,16 +1213,17 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
{
int flags;
- if(data->state.resume_from != 0) {
+ if(data->state.resume_from) {
sftp_attributes attrs;
if(data->state.resume_from < 0) {
attrs = sftp_stat(sshc->sftp_session, protop->path);
- if(attrs != 0) {
+ if(attrs) {
curl_off_t size = attrs->size;
if(size < 0) {
failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME);
+ break;
}
data->state.resume_from = attrs->size;
@@ -1254,6 +1265,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
else {
MOVE_TO_SFTP_CLOSE_STATE();
+ break;
}
}
@@ -1292,8 +1304,11 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
CURL_READFUNC_ABORT return code still aborts */
failf(data, "Failed to read data");
MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST);
+ break;
}
} while(passed < data->state.resume_from);
+ if(rc)
+ break;
}
/* now, decrease the size of the read */
@@ -1304,8 +1319,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
- if(rc != 0) {
+ if(rc) {
MOVE_TO_SFTP_CLOSE_STATE();
+ break;
}
}
if(data->state.infilesize > 0) {
@@ -1375,6 +1391,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
(err != SSH_FX_FAILURE) &&
(err != SSH_FX_PERMISSION_DENIED)) {
MOVE_TO_SFTP_CLOSE_STATE();
+ break;
}
rc = 0; /* clear rc and continue */
}
@@ -1398,6 +1415,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
failf(data, "Could not open directory for reading: %s",
ssh_get_error(sshc->ssh_session));
MOVE_TO_SFTP_CLOSE_STATE();
+ break;
}
state(data, SSH_SFTP_READDIR);
break;
@@ -1417,7 +1435,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
char *tmpLine;
tmpLine = aprintf("%s\n", sshc->readdir_filename);
- if(tmpLine == NULL) {
+ if(!tmpLine) {
state(data, SSH_SFTP_CLOSE);
sshc->actualcode = CURLE_OUT_OF_MEMORY;
break;
@@ -1456,7 +1474,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
sshc->readdir_linkPath = aprintf("%s%s", protop->path,
sshc->readdir_filename);
- if(sshc->readdir_linkPath == NULL) {
+ if(!sshc->readdir_linkPath) {
state(data, SSH_SFTP_CLOSE);
sshc->actualcode = CURLE_OUT_OF_MEMORY;
break;
@@ -1491,12 +1509,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
failf(data, "Could not read symlink for reading: %s",
ssh_get_error(sshc->ssh_session));
MOVE_TO_SFTP_CLOSE_STATE();
+ break;
}
- if(sshc->readdir_link_attrs->name == NULL) {
+ if(!sshc->readdir_link_attrs->name) {
sshc->readdir_tmp = sftp_readlink(sshc->sftp_session,
sshc->readdir_linkPath);
- if(sshc->readdir_filename == NULL)
+ if(!sshc->readdir_filename)
sshc->readdir_len = 0;
else
sshc->readdir_len = strlen(sshc->readdir_tmp);
@@ -1586,6 +1605,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
ssh_get_error(sshc->ssh_session));
MOVE_TO_SFTP_CLOSE_STATE();
+ break;
}
state(data, SSH_SFTP_DOWNLOAD_STAT);
@@ -1661,8 +1681,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
rc = sftp_seek64(sshc->sftp_file, from);
- if(rc != 0) {
+ if(rc) {
MOVE_TO_SFTP_CLOSE_STATE();
+ break;
}
}
data->req.size = size;
@@ -1699,8 +1720,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
size - data->state.resume_from);
rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
- if(rc != 0) {
+ if(rc) {
MOVE_TO_SFTP_CLOSE_STATE();
+ break;
}
}
}
@@ -1795,6 +1817,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
failf(data, "SCP requires a known file size for upload");
sshc->actualcode = CURLE_UPLOAD_FAILED;
MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+ break;
}
sshc->scp_session =
@@ -1822,6 +1845,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
err_msg = ssh_get_error(sshc->ssh_session);
failf(data, "%s", err_msg);
MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+ break;
}
rc = ssh_scp_push_file(sshc->scp_session, protop->path,
@@ -1831,6 +1855,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
err_msg = ssh_get_error(sshc->ssh_session);
failf(data, "%s", err_msg);
MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+ break;
}
/* upload data */
@@ -1859,6 +1884,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
err_msg = ssh_get_error(sshc->ssh_session);
failf(data, "%s", err_msg);
MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
+ break;
}
state(data, SSH_SCP_DOWNLOAD);
/* FALLTHROUGH */
@@ -2163,7 +2189,7 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done)
ssh = &conn->proto.sshc;
ssh->ssh_session = ssh_new();
- if(ssh->ssh_session == NULL) {
+ if(!ssh->ssh_session) {
failf(data, "Failure initialising ssh session");
return CURLE_FAILED_INIT;
}
@@ -2661,7 +2687,7 @@ static void sftp_quote(struct Curl_easy *data)
* command with a space so we can check for it unconditionally
*/
cp = strchr(cmd, ' ');
- if(cp == NULL) {
+ if(!cp) {
failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
state(data, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
@@ -2810,7 +2836,7 @@ static void sftp_quote_stat(struct Curl_easy *data)
if(sshc->quote_attrs)
sftp_attributes_free(sshc->quote_attrs);
sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2);
- if(sshc->quote_attrs == NULL) {
+ if(!sshc->quote_attrs) {
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
failf(data, "Attempt to get SFTP stats failed: %d",
diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c
index 9d188d0582..8a6345b948 100644
--- a/libs/libcurl/src/vssh/libssh2.c
+++ b/libs/libcurl/src/vssh/libssh2.c
@@ -121,6 +121,7 @@ static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t *sock);
static CURLcode ssh_setup_connection(struct Curl_easy *data,
struct connectdata *conn);
+static void ssh_attach(struct Curl_easy *data, struct connectdata *conn);
/*
* SCP protocol handler.
@@ -142,6 +143,7 @@ const struct Curl_handler Curl_handler_scp = {
scp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ssh_attach,
PORT_SSH, /* defport */
CURLPROTO_SCP, /* protocol */
CURLPROTO_SCP, /* family */
@@ -170,6 +172,7 @@ const struct Curl_handler Curl_handler_sftp = {
sftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ssh_attach,
PORT_SSH, /* defport */
CURLPROTO_SFTP, /* protocol */
CURLPROTO_SFTP, /* family */
@@ -956,7 +959,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
out_of_memory = TRUE;
}
- if(out_of_memory || sshc->rsa == NULL) {
+ if(out_of_memory || !sshc->rsa) {
Curl_safefree(sshc->rsa);
Curl_safefree(sshc->rsa_pub);
state(data, SSH_SESSION_FREE);
@@ -1359,7 +1362,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
* command with a space so we can check for it unconditionally
*/
cp = strchr(cmd, ' ');
- if(cp == NULL) {
+ if(!cp) {
failf(data, "Syntax error command '%s'. Missing parameter!",
cmd);
state(data, SSH_SFTP_CLOSE);
@@ -1534,7 +1537,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
+ if(rc && !sshc->acceptfail) { /* get those attributes */
sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
@@ -1633,7 +1636,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
@@ -1656,7 +1659,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
@@ -1677,7 +1680,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
failf(data, "mkdir command failed: %s",
@@ -1702,7 +1705,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
@@ -1722,7 +1725,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
failf(data, "rmdir command failed: %s",
@@ -1741,7 +1744,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
failf(data, "rm command failed: %s", sftp_libssh2_strerror(sftperr));
@@ -1764,7 +1767,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- if(rc != 0 && !sshc->acceptfail) {
+ if(rc && !sshc->acceptfail) {
sftperr = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1);
failf(data, "statvfs command failed: %s",
@@ -1857,7 +1860,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
* same name as the last directory in the path.
*/
- if(data->state.resume_from != 0) {
+ if(data->state.resume_from) {
LIBSSH2_SFTP_ATTRIBUTES attrs;
if(data->state.resume_from < 0) {
rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
@@ -2931,7 +2934,7 @@ static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done)
static CURLcode ssh_block_statemach(struct Curl_easy *data,
struct connectdata *conn,
- bool duringconnect)
+ bool disconnect)
{
struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result = CURLE_OK;
@@ -2945,17 +2948,19 @@ static CURLcode ssh_block_statemach(struct Curl_easy *data,
if(result)
break;
- if(Curl_pgrsUpdate(data))
- return CURLE_ABORTED_BY_CALLBACK;
+ if(!disconnect) {
+ if(Curl_pgrsUpdate(data))
+ return CURLE_ABORTED_BY_CALLBACK;
- result = Curl_speedcheck(data, now);
- if(result)
- break;
+ result = Curl_speedcheck(data, now);
+ if(result)
+ break;
- left = Curl_timeleft(data, NULL, duringconnect);
- if(left < 0) {
- failf(data, "Operation timed out");
- return CURLE_OPERATION_TIMEDOUT;
+ left = Curl_timeleft(data, NULL, FALSE);
+ if(left < 0) {
+ failf(data, "Operation timed out");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
}
if(block) {
@@ -3054,17 +3059,15 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
#ifdef CURL_LIBSSH2_DEBUG
curl_socket_t sock;
#endif
- struct SSHPROTO *sshp = data->req.p.ssh;
struct ssh_conn *sshc;
CURLcode result;
struct connectdata *conn = data->conn;
/* initialize per-handle data if not already */
- if(!sshp) {
+ if(!data->req.p.ssh) {
result = ssh_setup_connection(data, conn);
if(result)
return result;
- sshp = data->req.p.ssh;
}
/* We default to persistent connections. We set this already in this connect
@@ -3086,7 +3089,7 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
my_libssh2_free,
my_libssh2_realloc, data);
- if(sshc->ssh_session == NULL) {
+ if(!sshc->ssh_session) {
failf(data, "Failure initialising ssh session");
return CURLE_FAILED_INIT;
}
@@ -3280,10 +3283,8 @@ static CURLcode scp_disconnect(struct Curl_easy *data,
if(sshc->ssh_session) {
/* only if there's a session still around to use! */
-
state(data, SSH_SESSION_DISCONNECT);
-
- result = ssh_block_statemach(data, conn, FALSE);
+ result = ssh_block_statemach(data, conn, TRUE);
}
return result;
@@ -3297,10 +3298,9 @@ static CURLcode ssh_done(struct Curl_easy *data, CURLcode status)
struct SSHPROTO *sshp = data->req.p.ssh;
struct connectdata *conn = data->conn;
- if(!status) {
+ if(!status)
/* run the state-machine */
result = ssh_block_statemach(data, conn, FALSE);
- }
else
result = status;
@@ -3440,7 +3440,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data,
if(sshc->ssh_session) {
/* only if there's a session still around to use! */
state(data, SSH_SFTP_SHUTDOWN);
- result = ssh_block_statemach(data, conn, FALSE);
+ result = ssh_block_statemach(data, conn, TRUE);
}
DEBUGF(infof(data, "SSH DISCONNECT is done\n"));
@@ -3607,4 +3607,21 @@ size_t Curl_ssh_version(char *buffer, size_t buflen)
return msnprintf(buffer, buflen, "libssh2/%s", LIBSSH2_VERSION);
}
+/* The SSH session is associated with the *CONNECTION* but the callback user
+ * pointer is an easy handle pointer. This function allows us to reassign the
+ * user pointer to the *CURRENT* (new) easy handle.
+ */
+static void ssh_attach(struct Curl_easy *data, struct connectdata *conn)
+{
+ DEBUGASSERT(data);
+ DEBUGASSERT(conn);
+ if(conn->handler->protocol & PROTO_FAMILY_SSH) {
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ if(sshc->ssh_session) {
+ /* only re-attach if the session already exists */
+ void **abstract = libssh2_session_abstract(sshc->ssh_session);
+ *abstract = data;
+ }
+ }
+}
#endif /* USE_LIBSSH2 */
diff --git a/libs/libcurl/src/vssh/ssh.h b/libs/libcurl/src/vssh/ssh.h
index 52e1ee6c20..505b0787c5 100644
--- a/libs/libcurl/src/vssh/ssh.h
+++ b/libs/libcurl/src/vssh/ssh.h
@@ -263,9 +263,12 @@ extern const struct Curl_handler Curl_handler_sftp;
CURLcode Curl_ssh_init(void);
void Curl_ssh_cleanup(void);
size_t Curl_ssh_version(char *buffer, size_t buflen);
+void Curl_ssh_attach(struct Curl_easy *data,
+ struct connectdata *conn);
#else
/* for non-SSH builds */
#define Curl_ssh_cleanup()
+#define Curl_ssh_attach(x,y)
#endif
#endif /* HEADER_CURL_SSH_H */
diff --git a/libs/libcurl/src/vssh/wolfssh.c b/libs/libcurl/src/vssh/wolfssh.c
index de0b1c7776..9f3266a24d 100644
--- a/libs/libcurl/src/vssh/wolfssh.c
+++ b/libs/libcurl/src/vssh/wolfssh.c
@@ -91,6 +91,7 @@ const struct Curl_handler Curl_handler_scp = {
wscp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_SSH, /* defport */
CURLPROTO_SCP, /* protocol */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
@@ -119,6 +120,7 @@ const struct Curl_handler Curl_handler_sftp = {
wsftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_SSH, /* defport */
CURLPROTO_SFTP, /* protocol */
CURLPROTO_SFTP, /* family */
@@ -388,7 +390,7 @@ static CURLcode wssh_connect(struct Curl_easy *data, bool *done)
}
sshc->ssh_session = wolfSSH_new(sshc->ctx);
- if(sshc->ssh_session == NULL) {
+ if(!sshc->ssh_session) {
failf(data, "No wolfSSH session");
goto error;
}
@@ -861,7 +863,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block)
char *line = aprintf("%s\n",
data->set.list_only ?
name->fName : name->lName);
- if(line == NULL) {
+ if(!line) {
state(data, SSH_SFTP_CLOSE);
sshc->actualcode = CURLE_OUT_OF_MEMORY;
break;
diff --git a/libs/libcurl/src/vtls/bearssl.c b/libs/libcurl/src/vtls/bearssl.c
index a63056d4ef..7f729713d8 100644
--- a/libs/libcurl/src/vtls/bearssl.c
+++ b/libs/libcurl/src/vtls/bearssl.c
@@ -300,12 +300,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
-#ifndef CURL_DISABLE_PROXY
- const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
-#else
- const char *hostname = conn->host.name;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
const bool verifyhost = SSL_CONN_CONFIG(verifyhost);
CURLcode ret;
@@ -390,14 +385,14 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
* protocols array in `struct ssl_backend_data`.
*/
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
#endif
) {
- backend->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
- infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ backend->protocols[cur++] = ALPN_H2;
+ infof(data, "ALPN, offering %s\n", ALPN_H2);
}
#endif
@@ -545,8 +540,8 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data,
if(protocol) {
infof(data, "ALPN, server accepted to use %s\n", protocol);
-#ifdef USE_NGHTTP2
- if(!strcmp(protocol, NGHTTP2_PROTO_VERSION_ID))
+#ifdef USE_HTTP2
+ if(!strcmp(protocol, ALPN_H2))
conn->negnpn = CURL_HTTP_VERSION_2;
else
#endif
diff --git a/libs/libcurl/src/vtls/gskit.c b/libs/libcurl/src/vtls/gskit.c
index b0c73437bb..ca953769d1 100644
--- a/libs/libcurl/src/vtls/gskit.c
+++ b/libs/libcurl/src/vtls/gskit.c
@@ -101,8 +101,10 @@
struct ssl_backend_data {
gsk_handle handle;
int iocport;
+#ifndef CURL_DISABLE_PROXY
int localfd;
int remotefd;
+#endif
};
#define BACKEND connssl->backend
@@ -302,8 +304,9 @@ static CURLcode set_callback(struct Curl_easy *data,
static CURLcode set_ciphers(struct Curl_easy *data,
- gsk_handle h, unsigned int *protoflags)
+ gsk_handle h, unsigned int *protoflags)
{
+ struct connectdata *conn = data->conn;
const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
const char *clp;
const struct gskit_cipher *ctp;
@@ -515,6 +518,7 @@ static void close_async_handshake(struct ssl_connect_data *connssl)
static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
int directions)
{
+#ifndef CURL_DISABLE_PROXY
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex];
fd_set fds_read;
@@ -583,6 +587,9 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
}
return ret; /* OK */
+#else
+ return 0;
+#endif
}
@@ -596,6 +603,7 @@ static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data,
while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0)
;
BACKEND->handle = (gsk_handle) NULL;
+#ifndef CURL_DISABLE_PROXY
if(BACKEND->localfd >= 0) {
close(BACKEND->localfd);
BACKEND->localfd = -1;
@@ -604,6 +612,7 @@ static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data,
close(BACKEND->remotefd);
BACKEND->remotefd = -1;
}
+#endif
}
if(BACKEND->iocport >= 0)
close_async_handshake(connssl);
@@ -665,6 +674,7 @@ static ssize_t gskit_recv(struct Curl_easy *data, int num, char *buf,
static CURLcode
set_ssl_version_min_max(unsigned int *protoflags, struct Curl_easy *data)
{
+ struct connectdata *conn = data->conn;
long ssl_version = SSL_CONN_CONFIG(version);
long ssl_version_max = SSL_CONN_CONFIG(version_max);
long i = ssl_version;
@@ -705,20 +715,23 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert);
const long int ssl_version = SSL_CONN_CONFIG(version);
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
- conn->host.name;
+ const char * const hostname = SSL_HOST_NAME();
const char *sni;
unsigned int protoflags = 0;
Qso_OverlappedIO_t commarea;
+#ifndef CURL_DISABLE_PROXY
int sockpair[2];
static const int sobufsize = CURL_MAX_WRITE_SIZE;
+#endif
/* Create SSL environment, start (preferably asynchronous) handshake. */
BACKEND->handle = (gsk_handle) NULL;
BACKEND->iocport = -1;
+#ifndef CURL_DISABLE_PROXY
BACKEND->localfd = -1;
BACKEND->remotefd = -1;
+#endif
/* GSKit supports two ways of specifying an SSL context: either by
* application identifier (that should have been defined at the system
@@ -757,6 +770,7 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
if(result)
return result;
+#ifndef CURL_DISABLE_PROXY
/* Establish a pipelining socket pair for SSL over SSL. */
if(conn->proxy_ssl[sockindex].use) {
if(Curl_socketpair(0, 0, 0, sockpair))
@@ -774,6 +788,7 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
curlx_nonblock(BACKEND->localfd, TRUE);
curlx_nonblock(BACKEND->remotefd, TRUE);
}
+#endif
/* Determine which SSL/TLS version should be enabled. */
sni = hostname;
@@ -826,8 +841,13 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
if(!result)
result = set_numeric(data, BACKEND->handle, GSK_OS400_READ_TIMEOUT, 1);
if(!result)
+#ifndef CURL_DISABLE_PROXY
result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0?
BACKEND->localfd: conn->sock[sockindex]);
+#else
+ result = set_numeric(data, BACKEND->handle, GSK_FD,
+ conn->sock[sockindex]);
+#endif
if(!result)
result = set_ciphers(data, BACKEND->handle, &protoflags);
if(!protoflags) {
@@ -896,10 +916,12 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
else if(errno != ENOBUFS)
result = gskit_status(data, GSK_ERROR_IO,
"QsoCreateIOCompletionPort()", 0);
+#ifndef CURL_DISABLE_PROXY
else if(conn->proxy_ssl[sockindex].use) {
/* Cannot pipeline while handshaking synchronously. */
result = CURLE_SSL_CONNECT_ERROR;
}
+#endif
else {
/* No more completion port available. Use synchronous IO. */
result = gskit_status(data, gsk_secure_soc_init(BACKEND->handle),
@@ -1035,8 +1057,7 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data,
}
/* Check pinned public key. */
- ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+ ptr = SSL_PINNED_PUB_KEY();
if(!result && ptr) {
curl_X509certificate x509;
curl_asn1Element *p;
@@ -1158,7 +1179,9 @@ static void gskit_close(struct Curl_easy *data, struct connectdata *conn,
int sockindex)
{
close_one(&conn->ssl[sockindex], data, conn, sockindex);
+#ifndef CURL_DISABLE_PROXY
close_one(&conn->proxy_ssl[sockindex], data, conn, sockindex);
+#endif
}
@@ -1281,7 +1304,9 @@ const struct Curl_ssl Curl_ssl_gskit = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
- NULL /* sha256sum */
+ NULL, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
#endif /* USE_GSKIT */
diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c
index e3fad7fe02..ecde5c44de 100644
--- a/libs/libcurl/src/vtls/gtls.c
+++ b/libs/libcurl/src/vtls/gtls.c
@@ -263,7 +263,7 @@ static CURLcode handshake(struct Curl_easy *data,
strerr = gnutls_alert_get_name(alert);
}
- if(strerr == NULL)
+ if(!strerr)
strerr = gnutls_strerror(rc);
infof(data, "gnutls_handshake() warning: %s\n", strerr);
@@ -277,7 +277,7 @@ static CURLcode handshake(struct Curl_easy *data,
strerr = gnutls_alert_get_name(alert);
}
- if(strerr == NULL)
+ if(!strerr)
strerr = gnutls_strerror(rc);
failf(data, "gnutls_handshake() failed: %s", strerr);
@@ -308,15 +308,29 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type)
#define GNUTLS_SRP "+SRP"
static CURLcode
-set_ssl_version_min_max(const char **prioritylist, struct Curl_easy *data)
+set_ssl_version_min_max(struct Curl_easy *data,
+ const char **prioritylist,
+ const char *tls13support)
{
struct connectdata *conn = data->conn;
long ssl_version = SSL_CONN_CONFIG(version);
long ssl_version_max = SSL_CONN_CONFIG(version_max);
- if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
+ if((ssl_version == CURL_SSLVERSION_DEFAULT) ||
+ (ssl_version == CURL_SSLVERSION_TLSv1))
+ ssl_version = CURL_SSLVERSION_TLSv1_0;
+ if(ssl_version_max == CURL_SSLVERSION_MAX_NONE)
ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT;
+ if(!tls13support) {
+ /* If the running GnuTLS doesn't support TLS 1.3, we must not specify a
+ prioritylist involving that since it will make GnuTLS return an en
+ error back at us */
+ if((ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) ||
+ (ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT)) {
+ ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+ }
}
+
switch(ssl_version | ssl_version_max) {
case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
@@ -395,6 +409,7 @@ gtls_connect_step1(struct Curl_easy *data,
const char *err = NULL;
const char * const hostname = SSL_HOST_NAME();
long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult);
+ const char *tls13support;
if(connssl->state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
@@ -542,36 +557,34 @@ gtls_connect_step1(struct Curl_easy *data,
if(rc != GNUTLS_E_SUCCESS)
return CURLE_SSL_CONNECT_ERROR;
+ /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */
+ tls13support = gnutls_check_version("3.6.5");
+
/* Ensure +SRP comes at the *end* of all relevant strings so that it can be
* removed if a run-time error indicates that SRP is not supported by this
* GnuTLS version */
switch(SSL_CONN_CONFIG(version)) {
- case CURL_SSLVERSION_SSLv3:
- prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
- break;
+ case CURL_SSLVERSION_TLSv1_3:
+ if(!tls13support) {
+ failf(data, "This GnuTLS installation does not support TLS 1.3");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ /* FALLTHROUGH */
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
- prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0"
-#ifdef HAS_TLS13
- ":+VERS-TLS1.3"
-#endif
- ;
- break;
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
- case CURL_SSLVERSION_TLSv1_2:
- case CURL_SSLVERSION_TLSv1_3:
- {
- CURLcode result = set_ssl_version_min_max(&prioritylist, data);
- if(result != CURLE_OK)
- return result;
- break;
- }
+ case CURL_SSLVERSION_TLSv1_2: {
+ CURLcode result = set_ssl_version_min_max(data, &prioritylist,
+ tls13support);
+ if(result)
+ return result;
+ break;
+ }
case CURL_SSLVERSION_SSLv2:
- failf(data, "GnuTLS does not support SSLv2");
- return CURLE_SSL_CONNECT_ERROR;
+ case CURL_SSLVERSION_SSLv3:
default:
- failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+ failf(data, "GnuTLS does not support SSLv2 or SSLv3");
return CURLE_SSL_CONNECT_ERROR;
}
@@ -586,7 +599,6 @@ gtls_connect_step1(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
strcpy(prioritysrp, prioritylist);
strcpy(prioritysrp + len, ":" GNUTLS_SRP);
-
rc = gnutls_priority_set_direct(session, prioritysrp, &err);
free(prioritysrp);
@@ -611,16 +623,16 @@ gtls_connect_step1(struct Curl_easy *data,
int cur = 0;
gnutls_datum_t protocols[2];
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
#endif
) {
- protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID;
- protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN;
+ protocols[cur].data = (unsigned char *)ALPN_H2;
+ protocols[cur].size = ALPN_H2_LENGTH;
cur++;
- infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ infof(data, "ALPN, offering %.*s\n", ALPN_H2_LENGTH, ALPN_H2);
}
#endif
@@ -1178,8 +1190,7 @@ gtls_connect_step3(struct Curl_easy *data,
infof(data, "\t server certificate activation date OK\n");
}
- ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+ ptr = SSL_PINNED_PUB_KEY();
if(ptr) {
result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
if(result != CURLE_OK) {
@@ -1243,10 +1254,10 @@ gtls_connect_step3(struct Curl_easy *data,
infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
proto.data);
-#ifdef USE_NGHTTP2
- if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN &&
- !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
- NGHTTP2_PROTO_VERSION_ID_LEN)) {
+#ifdef USE_HTTP2
+ if(proto.size == ALPN_H2_LENGTH &&
+ !memcmp(ALPN_H2, proto.data,
+ ALPN_H2_LENGTH)) {
conn->negnpn = CURL_HTTP_VERSION_2;
}
else
@@ -1645,7 +1656,9 @@ const struct Curl_ssl Curl_ssl_gnutls = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
- gtls_sha256sum /* sha256sum */
+ gtls_sha256sum, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
#endif /* USE_GNUTLS */
diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c
index 4b36f2d20c..3a0be0f04b 100644
--- a/libs/libcurl/src/vtls/mbedtls.c
+++ b/libs/libcurl/src/vtls/mbedtls.c
@@ -251,22 +251,16 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
- const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
-#else
- const char * const hostname = conn->host.name;
- const long int port = conn->remote_port;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
+ const long int port = SSL_HOST_PORT();
int ret = -1;
char errorbuf[128];
errorbuf[0] = 0;
- /* mbedTLS only supports SSLv3 and TLSv1 */
- if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
- failf(data, "mbedTLS does not support SSLv2");
- return CURLE_SSL_CONNECT_ERROR;
+ if((SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) ||
+ (SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)) {
+ failf(data, "Not supported SSL version");
+ return CURLE_NOT_BUILT_IN;
}
#ifdef THREADING_SUPPORT
@@ -414,13 +408,6 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
MBEDTLS_SSL_MINOR_VERSION_1);
infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n");
break;
- case CURL_SSLVERSION_SSLv3:
- mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
- MBEDTLS_SSL_MINOR_VERSION_0);
- mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
- MBEDTLS_SSL_MINOR_VERSION_0);
- infof(data, "mbedTLS: Set SSL version to SSLv3\n");
- break;
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
@@ -549,14 +536,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
const mbedtls_x509_crt *peercert;
-#ifndef CURL_DISABLE_PROXY
- const char * const pinnedpubkey = SSL_IS_PROXY() ?
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY];
-#else
- const char * const pinnedpubkey =
- data->set.str[STRING_SSL_PINNEDPUBLICKEY];
-#endif
+ const char * const pinnedpubkey = SSL_PINNED_PUB_KEY();
conn->recv[sockindex] = mbed_recv;
conn->send[sockindex] = mbed_send;
@@ -1113,7 +1093,9 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
- mbedtls_sha256sum /* sha256sum */
+ mbedtls_sha256sum, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
#endif /* USE_MBEDTLS */
diff --git a/libs/libcurl/src/vtls/mesalink.c b/libs/libcurl/src/vtls/mesalink.c
index 5d6a1495d7..bf8600d323 100644
--- a/libs/libcurl/src/vtls/mesalink.c
+++ b/libs/libcurl/src/vtls/mesalink.c
@@ -98,8 +98,7 @@ mesalink_connect_step1(struct Curl_easy *data,
#ifdef ENABLE_IPV6
struct in6_addr addr6;
#endif
- const char *const hostname =
- SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name;
+ const char * const hostname = SSL_HOST_NAME();
size_t hostname_len = strlen(hostname);
SSL_METHOD *req_method = NULL;
@@ -667,7 +666,9 @@ const struct Curl_ssl Curl_ssl_mesalink = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
- NULL /* sha256sum */
+ NULL, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
#endif
diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c
index a9f6959e3b..1582b1e580 100644
--- a/libs/libcurl/src/vtls/nss.c
+++ b/libs/libcurl/src/vtls/nss.c
@@ -139,9 +139,15 @@ static const struct cipher_s cipherlist[] = {
{"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
{"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
{"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA},
+ {"dhe_rsa_3des_sha", SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA},
+ {"dhe_dss_3des_sha", SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA},
+ {"dhe_rsa_des_sha", SSL_DHE_RSA_WITH_DES_CBC_SHA},
+ {"dhe_dss_des_sha", SSL_DHE_DSS_WITH_DES_CBC_SHA},
/* TLS 1.0: Exportable 56-bit Cipher Suites. */
{"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
{"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
+ /* Ephemeral DH with RC4 bulk encryption */
+ {"dhe_dss_rc4_128_sha", TLS_DHE_DSS_WITH_RC4_128_SHA},
/* AES ciphers. */
{"dhe_dss_aes_128_cbc_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA},
{"dhe_dss_aes_256_cbc_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA},
@@ -219,6 +225,25 @@ static const struct cipher_s cipherlist[] = {
{"aes_256_gcm_sha_384", TLS_AES_256_GCM_SHA384},
{"chacha20_poly1305_sha_256", TLS_CHACHA20_POLY1305_SHA256},
#endif
+#ifdef TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ /* AES CBC cipher suites in RFC 5246. Introduced in NSS release 3.20 */
+ {"dhe_dss_aes_128_sha_256", TLS_DHE_DSS_WITH_AES_128_CBC_SHA256},
+ {"dhe_dss_aes_256_sha_256", TLS_DHE_DSS_WITH_AES_256_CBC_SHA256},
+#endif
+#ifdef TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ /* Camellia cipher suites in RFC 4132/5932.
+ Introduced in NSS release 3.12 */
+ {"dhe_rsa_camellia_128_sha", TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA},
+ {"dhe_dss_camellia_128_sha", TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA},
+ {"dhe_rsa_camellia_256_sha", TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA},
+ {"dhe_dss_camellia_256_sha", TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA},
+ {"rsa_camellia_128_sha", TLS_RSA_WITH_CAMELLIA_128_CBC_SHA},
+ {"rsa_camellia_256_sha", TLS_RSA_WITH_CAMELLIA_256_CBC_SHA},
+#endif
+#ifdef TLS_RSA_WITH_SEED_CBC_SHA
+ /* SEED cipher suite in RFC 4162. Introduced in NSS release 3.12.3 */
+ {"rsa_seed_sha", TLS_RSA_WITH_SEED_CBC_SHA},
+#endif
};
#if defined(WIN32)
@@ -312,7 +337,7 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
while((*cipher) && (ISSPACE(*cipher)))
++cipher;
- cipher_list = strchr(cipher, ',');
+ cipher_list = strpbrk(cipher, ":, ");
if(cipher_list) {
*cipher_list++ = '\0';
}
@@ -380,7 +405,7 @@ static int is_file(const char *filename)
{
struct_stat st;
- if(filename == NULL)
+ if(!filename)
return 0;
if(stat(filename, &st) == 0)
@@ -845,8 +870,8 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
}
#ifdef USE_NGHTTP2
- if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN &&
- !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) {
+ if(buflen == ALPN_H2_LENGTH &&
+ !memcmp(ALPN_H2, buf, ALPN_H2_LENGTH)) {
conn->negnpn = CURL_HTTP_VERSION_2;
}
else
@@ -1423,7 +1448,7 @@ static CURLcode nss_setup(struct Curl_easy *data)
static int nss_init(void)
{
/* curl_global_init() is not thread-safe so this test is ok */
- if(nss_initlock == NULL) {
+ if(!nss_initlock) {
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
nss_initlock = PR_NewLock();
nss_crllock = PR_NewLock();
@@ -1699,8 +1724,7 @@ static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version)
return CURLE_OK;
case CURL_SSLVERSION_SSLv3:
- *nssver = SSL_LIBRARY_VERSION_3_0;
- return CURLE_OK;
+ return CURLE_NOT_BUILT_IN;
case CURL_SSLVERSION_TLSv1_0:
*nssver = SSL_LIBRARY_VERSION_TLS_1_0;
@@ -1806,7 +1830,7 @@ static CURLcode nss_set_blocking(struct ssl_connect_data *connssl,
struct Curl_easy *data,
bool blocking)
{
- static PRSocketOptionData sock_opt;
+ PRSocketOptionData sock_opt;
struct ssl_backend_data *backend = connssl->backend;
sock_opt.option = PR_SockOpt_Nonblocking;
sock_opt.value.non_blocking = !blocking;
@@ -2079,16 +2103,15 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
int cur = 0;
unsigned char protocols[128];
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
#endif
) {
- protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
- memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
- NGHTTP2_PROTO_VERSION_ID_LEN);
- cur += NGHTTP2_PROTO_VERSION_ID_LEN;
+ protocols[cur++] = ALPN_H2_LENGTH;
+ memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH);
+ cur += ALPN_H2_LENGTH;
}
#endif
protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
@@ -2442,7 +2465,9 @@ const struct Curl_ssl Curl_ssl_nss = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
nss_false_start, /* false_start */
- nss_sha256sum /* sha256sum */
+ nss_sha256sum, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
#endif /* USE_NSS */
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index 6583300b3c..ebd7abc3b4 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.c
@@ -122,12 +122,6 @@
#define HAVE_ERR_REMOVE_THREAD_STATE 1
#endif
-#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \
- OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */
-#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */
-#define OPENSSL_NO_SSL2
-#endif
-
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \
!(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER < 0x20700000L)
@@ -246,6 +240,10 @@ struct ssl_backend_data {
#endif
};
+static void ossl_associate_connection(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex);
+
/*
* Number of bytes to read from the random number seed file. This must be
* a finite value (because some entropy "files" like /dev/urandom have
@@ -625,7 +623,7 @@ SSL_CTX_use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob,
goto end;
}
- if(x == NULL) {
+ if(!x) {
ret = 0;
goto end;
}
@@ -656,7 +654,7 @@ SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob,
ret = 0;
goto end;
}
- if(pkey == NULL) {
+ if(!pkey) {
ret = 0;
goto end;
}
@@ -669,7 +667,7 @@ SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob,
static int
SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob,
- const char *key_passwd)
+ const char *key_passwd)
{
/* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */
#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* OpenSSL 1.0.2 or later */ \
@@ -687,7 +685,7 @@ SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob,
x = PEM_read_bio_X509_AUX(in, NULL,
passwd_callback, (void *)key_passwd);
- if(x == NULL) {
+ if(!x) {
ret = 0;
goto end;
}
@@ -731,7 +729,7 @@ SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob,
return ret;
#else
(void)ctx; /* unused */
- (void)in; /* unused */
+ (void)blob; /* unused */
(void)key_passwd; /* unused */
return 0;
#endif
@@ -875,7 +873,7 @@ int cert_stuff(struct Curl_easy *data,
STACK_OF(X509) *ca = NULL;
if(cert_blob) {
cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len));
- if(cert_bio == NULL) {
+ if(!cert_bio) {
failf(data,
"BIO_new_mem_buf NULL, " OSSL_PACKAGE
" error %s",
@@ -886,7 +884,7 @@ int cert_stuff(struct Curl_easy *data,
}
else {
cert_bio = BIO_new(BIO_s_file());
- if(cert_bio == NULL) {
+ if(!cert_bio) {
failf(data,
"BIO_new return NULL, " OSSL_PACKAGE
" error %s",
@@ -2262,12 +2260,10 @@ select_next_proto_cb(SSL *ssl,
struct connectdata *conn = data->conn;
(void)ssl;
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
- !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID,
- NGHTTP2_PROTO_VERSION_ID_LEN)) {
- infof(data, "NPN, negotiated HTTP2 (%s)\n",
- NGHTTP2_PROTO_VERSION_ID);
+ !select_next_protocol(out, outlen, in, inlen, ALPN_H2, ALPN_H2_LENGTH)) {
+ infof(data, "NPN, negotiated HTTP2 (%s)\n", ALPN_H2);
conn->negnpn = CURL_HTTP_VERSION_2;
return SSL_TLSEXT_ERR_OK;
}
@@ -2518,6 +2514,67 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
return res;
}
+static CURLcode load_cacert_from_memory(SSL_CTX *ctx,
+ const struct curl_blob *ca_info_blob)
+{
+ /* these need freed at the end */
+ BIO *cbio = NULL;
+ STACK_OF(X509_INFO) *inf = NULL;
+
+ /* everything else is just a reference */
+ int i, count = 0;
+ X509_STORE *cts = NULL;
+ X509_INFO *itmp = NULL;
+
+ if(ca_info_blob->len > (size_t)INT_MAX)
+ return CURLE_SSL_CACERT_BADFILE;
+
+ cts = SSL_CTX_get_cert_store(ctx);
+ if(!cts)
+ return CURLE_OUT_OF_MEMORY;
+
+ cbio = BIO_new_mem_buf(ca_info_blob->data, (int)ca_info_blob->len);
+ if(!cbio)
+ return CURLE_OUT_OF_MEMORY;
+
+ inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL);
+ if(!inf) {
+ BIO_free(cbio);
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ /* add each entry from PEM file to x509_store */
+ for(i = 0; i < (int)sk_X509_INFO_num(inf); ++i) {
+ itmp = sk_X509_INFO_value(inf, i);
+ if(itmp->x509) {
+ if(X509_STORE_add_cert(cts, itmp->x509)) {
+ ++count;
+ }
+ else {
+ /* set count to 0 to return an error */
+ count = 0;
+ break;
+ }
+ }
+ if(itmp->crl) {
+ if(X509_STORE_add_crl(cts, itmp->crl)) {
+ ++count;
+ }
+ else {
+ /* set count to 0 to return an error */
+ count = 0;
+ break;
+ }
+ }
+ }
+
+ sk_X509_INFO_pop_free(inf, X509_INFO_free);
+ BIO_free(cbio);
+
+ /* if we didn't end up importing anything, treat that as an error */
+ return (count > 0 ? CURLE_OK : CURLE_SSL_CACERT_BADFILE);
+}
+
static CURLcode ossl_connect_step1(struct Curl_easy *data,
struct connectdata *conn, int sockindex)
{
@@ -2528,6 +2585,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
curl_socket_t sockfd = conn->sock[sockindex];
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
ctx_option_t ctx_options = 0;
+ void *ssl_sessionid = NULL;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
bool sni;
@@ -2545,8 +2603,11 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#endif
char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
+ const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
- const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+ const char * const ssl_cafile =
+ /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
+ (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
@@ -2581,31 +2642,11 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
use_sni(TRUE);
break;
case CURL_SSLVERSION_SSLv2:
-#ifdef OPENSSL_NO_SSL2
- failf(data, OSSL_PACKAGE " was built without SSLv2 support");
+ failf(data, "No SSLv2 support");
return CURLE_NOT_BUILT_IN;
-#else
-#ifdef USE_OPENSSL_SRP
- if(ssl_authtype == CURL_TLSAUTH_SRP)
- return CURLE_SSL_CONNECT_ERROR;
-#endif
- req_method = SSLv2_client_method();
- use_sni(FALSE);
- break;
-#endif
case CURL_SSLVERSION_SSLv3:
-#ifdef OPENSSL_NO_SSL3_METHOD
- failf(data, OSSL_PACKAGE " was built without SSLv3 support");
+ failf(data, "No SSLv3 support");
return CURLE_NOT_BUILT_IN;
-#else
-#ifdef USE_OPENSSL_SRP
- if(ssl_authtype == CURL_TLSAUTH_SRP)
- return CURLE_SSL_CONNECT_ERROR;
-#endif
- req_method = SSLv3_client_method();
- use_sni(FALSE);
- break;
-#endif
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
return CURLE_SSL_CONNECT_ERROR;
@@ -2693,41 +2734,9 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#endif
switch(ssl_version) {
- /* "--sslv2" option means SSLv2 only, disable all others */
case CURL_SSLVERSION_SSLv2:
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
- SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION);
- SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION);
-#else
- ctx_options |= SSL_OP_NO_SSLv3;
- ctx_options |= SSL_OP_NO_TLSv1;
-# if OPENSSL_VERSION_NUMBER >= 0x1000100FL
- ctx_options |= SSL_OP_NO_TLSv1_1;
- ctx_options |= SSL_OP_NO_TLSv1_2;
-# ifdef TLS1_3_VERSION
- ctx_options |= SSL_OP_NO_TLSv1_3;
-# endif
-# endif
-#endif
- break;
-
- /* "--sslv3" option means SSLv3 only, disable all others */
case CURL_SSLVERSION_SSLv3:
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
- SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION);
- SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION);
-#else
- ctx_options |= SSL_OP_NO_SSLv2;
- ctx_options |= SSL_OP_NO_TLSv1;
-# if OPENSSL_VERSION_NUMBER >= 0x1000100FL
- ctx_options |= SSL_OP_NO_TLSv1_1;
- ctx_options |= SSL_OP_NO_TLSv1_2;
-# ifdef TLS1_3_VERSION
- ctx_options |= SSL_OP_NO_TLSv1_3;
-# endif
-# endif
-#endif
- break;
+ return CURLE_NOT_BUILT_IN;
/* "--tlsv<x.y>" options mean TLS >= version <x.y> */
case CURL_SSLVERSION_DEFAULT:
@@ -2768,18 +2777,17 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
int cur = 0;
unsigned char protocols[128];
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
#endif
) {
- protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
+ protocols[cur++] = ALPN_H2_LENGTH;
- memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
- NGHTTP2_PROTO_VERSION_ID_LEN);
- cur += NGHTTP2_PROTO_VERSION_ID_LEN;
- infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH);
+ cur += ALPN_H2_LENGTH;
+ infof(data, "ALPN, offering %s\n", ALPN_H2);
}
#endif
@@ -2885,8 +2893,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
if((SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost)) &&
(SSL_SET_OPTION(native_ca_store))) {
X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx);
- HCERTSTORE hStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL,
- TEXT("ROOT"));
+ HCERTSTORE hStore = CertOpenSystemStore(0, TEXT("ROOT"));
if(hStore) {
PCCERT_CONTEXT pContext = NULL;
@@ -3023,6 +3030,19 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
}
#endif
+ if(ca_info_blob) {
+ result = load_cacert_from_memory(backend->ctx, ca_info_blob);
+ if(result) {
+ if(result == CURLE_OUT_OF_MEMORY ||
+ (verifypeer && !imported_native_ca)) {
+ failf(data, "error importing CA certificate blob");
+ return result;
+ }
+ /* Only warning if no certificate verification is required. */
+ infof(data, "error importing CA certificate blob, continuing anyway\n");
+ }
+ }
+
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
/* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */
{
@@ -3079,7 +3099,8 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#endif
#ifdef CURL_CA_FALLBACK
- if(verifypeer && !ssl_cafile && !ssl_capath && !imported_native_ca) {
+ if(verifypeer &&
+ !ca_info_blob && !ssl_cafile && !ssl_capath && !imported_native_ca) {
/* verifying the peer without any CA certificates won't
work so use openssl's built in default as fallback */
SSL_CTX_set_default_verify_paths(backend->ctx);
@@ -3209,46 +3230,23 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
}
#endif
- /* Check if there's a cached ID we can/should use here! */
- if(SSL_SET_OPTION(primary.sessionid)) {
- void *ssl_sessionid = NULL;
- int data_idx = ossl_get_ssl_data_index();
- int connectdata_idx = ossl_get_ssl_conn_index();
- int sockindex_idx = ossl_get_ssl_sockindex_index();
- int proxy_idx = ossl_get_proxy_index();
+ ossl_associate_connection(data, conn, sockindex);
- if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 &&
- proxy_idx >= 0) {
- /* Store the data needed for the "new session" callback.
- * The sockindex is stored as a pointer to an array element. */
- SSL_set_ex_data(backend->handle, data_idx, data);
- SSL_set_ex_data(backend->handle, connectdata_idx, conn);
- SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex);
-#ifndef CURL_DISABLE_PROXY
- SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1:
- NULL);
-#else
- SSL_set_ex_data(backend->handle, proxy_idx, NULL);
-#endif
-
- }
-
- Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE,
- &ssl_sessionid, NULL, sockindex)) {
- /* we got a session id, use it! */
- if(!SSL_set_session(backend->handle, ssl_sessionid)) {
- Curl_ssl_sessionid_unlock(data);
- failf(data, "SSL: SSL_set_session failed: %s",
- ossl_strerror(ERR_get_error(), error_buffer,
- sizeof(error_buffer)));
- return CURLE_SSL_CONNECT_ERROR;
- }
- /* Informational message */
- infof(data, "SSL re-using session ID\n");
+ Curl_ssl_sessionid_lock(data);
+ if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE,
+ &ssl_sessionid, NULL, sockindex)) {
+ /* we got a session id, use it! */
+ if(!SSL_set_session(backend->handle, ssl_sessionid)) {
+ Curl_ssl_sessionid_unlock(data);
+ failf(data, "SSL: SSL_set_session failed: %s",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)));
+ return CURLE_SSL_CONNECT_ERROR;
}
- Curl_ssl_sessionid_unlock(data);
+ /* Informational message */
+ infof(data, "SSL re-using session ID\n");
}
+ Curl_ssl_sessionid_unlock(data);
#ifndef CURL_DISABLE_PROXY
if(conn->proxy_ssl[sockindex].use) {
@@ -3353,6 +3351,19 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
error_buffer */
strcpy(error_buffer, "SSL certificate verification failed");
}
+#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \
+ !defined(LIBRESSL_VERSION_NUMBER) && \
+ !defined(OPENSSL_IS_BORINGSSL))
+ /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on
+ OpenSSL version above v1.1.1, not Libre SSL nor BoringSSL */
+ else if((lib == ERR_LIB_SSL) &&
+ (reason == SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)) {
+ /* If client certificate is required, communicate the
+ error to client */
+ result = CURLE_SSL_CLIENTCERT;
+ ossl_strerror(errdetail, error_buffer, sizeof(error_buffer));
+ }
+#endif
else {
result = CURLE_SSL_CONNECT_ERROR;
ossl_strerror(errdetail, error_buffer, sizeof(error_buffer));
@@ -3366,11 +3377,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
*/
if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
const char * const hostname = SSL_HOST_NAME();
-#ifndef CURL_DISABLE_PROXY
- const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
-#else
- const long int port = conn->remote_port;
-#endif
+ const long int port = SSL_HOST_PORT();
char extramsg[80]="";
int sockerr = SOCKERRNO;
if(sockerr && detail == SSL_ERROR_SYSCALL)
@@ -3404,12 +3411,12 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
const unsigned char *neg_protocol;
unsigned int len;
SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len);
- if(len != 0) {
+ if(len) {
infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol);
-#ifdef USE_NGHTTP2
- if(len == NGHTTP2_PROTO_VERSION_ID_LEN &&
- !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) {
+#ifdef USE_HTTP2
+ if(len == ALPN_H2_LENGTH &&
+ !memcmp(ALPN_H2, neg_protocol, len)) {
conn->negnpn = CURL_HTTP_VERSION_2;
}
else
@@ -3896,7 +3903,7 @@ static CURLcode servercert(struct Curl_easy *data,
(int)SSL_SET_OPTION(issuercert_blob)->len);
else {
fp = BIO_new(BIO_s_file());
- if(fp == NULL) {
+ if(!fp) {
failf(data,
"BIO_new return NULL, " OSSL_PACKAGE
" error %s",
@@ -3983,8 +3990,7 @@ static CURLcode servercert(struct Curl_easy *data,
/* when not strict, we don't bother about the verify cert problems */
result = CURLE_OK;
- ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+ ptr = SSL_PINNED_PUB_KEY();
if(!result && ptr) {
result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
if(result)
@@ -4474,10 +4480,95 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl,
(void *)backend->ctx : (void *)backend->handle;
}
+static void ossl_associate_connection(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
+
+ /* If we don't have SSL context, do nothing. */
+ if(!backend->handle)
+ return;
+
+ if(SSL_SET_OPTION(primary.sessionid)) {
+ int data_idx = ossl_get_ssl_data_index();
+ int connectdata_idx = ossl_get_ssl_conn_index();
+ int sockindex_idx = ossl_get_ssl_sockindex_index();
+ int proxy_idx = ossl_get_proxy_index();
+
+ if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 &&
+ proxy_idx >= 0) {
+ /* Store the data needed for the "new session" callback.
+ * The sockindex is stored as a pointer to an array element. */
+ SSL_set_ex_data(backend->handle, data_idx, data);
+ SSL_set_ex_data(backend->handle, connectdata_idx, conn);
+ SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex);
+#ifndef CURL_DISABLE_PROXY
+ SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1:
+ NULL);
+#else
+ SSL_set_ex_data(backend->handle, proxy_idx, NULL);
+#endif
+ }
+ }
+}
+
+/*
+ * Starting with TLS 1.3, the ossl_new_session_cb callback gets called after
+ * the handshake. If the transfer that sets up the callback gets killed before
+ * this callback arrives, we must make sure to properly clear the data to
+ * avoid UAF problems. A future optimization could be to instead store another
+ * transfer that might still be using the same connection.
+ */
+
+static void ossl_disassociate_connection(struct Curl_easy *data,
+ int sockindex)
+{
+ struct connectdata *conn = data->conn;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
+
+ /* If we don't have SSL context, do nothing. */
+ if(!backend->handle)
+ return;
+
+ if(SSL_SET_OPTION(primary.sessionid)) {
+ bool isproxy = FALSE;
+ bool incache;
+ void *old_ssl_sessionid = NULL;
+ int data_idx = ossl_get_ssl_data_index();
+ int connectdata_idx = ossl_get_ssl_conn_index();
+ int sockindex_idx = ossl_get_ssl_sockindex_index();
+ int proxy_idx = ossl_get_proxy_index();
+
+ if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 &&
+ proxy_idx >= 0) {
+ /* Invalidate the session cache entry, if any */
+ isproxy = SSL_get_ex_data(backend->handle, proxy_idx) ? TRUE : FALSE;
+
+ /* Disable references to data in "new session" callback to avoid
+ * accessing a stale pointer. */
+ SSL_set_ex_data(backend->handle, data_idx, NULL);
+ SSL_set_ex_data(backend->handle, connectdata_idx, NULL);
+ SSL_set_ex_data(backend->handle, sockindex_idx, NULL);
+ SSL_set_ex_data(backend->handle, proxy_idx, NULL);
+ }
+
+ Curl_ssl_sessionid_lock(data);
+ incache = !(Curl_ssl_getsessionid(data, conn, isproxy,
+ &old_ssl_sessionid, NULL, sockindex));
+ if(incache)
+ Curl_ssl_delsessionid(data, old_ssl_sessionid);
+ Curl_ssl_sessionid_unlock(data);
+ }
+}
+
const struct Curl_ssl Curl_ssl_openssl = {
{ CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */
SSLSUPP_CA_PATH |
+ SSLSUPP_CAINFO_BLOB |
SSLSUPP_CERTINFO |
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_SSL_CTX |
@@ -4508,10 +4599,12 @@ const struct Curl_ssl Curl_ssl_openssl = {
ossl_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256)
- ossl_sha256sum /* sha256sum */
+ ossl_sha256sum, /* sha256sum */
#else
- NULL /* sha256sum */
+ NULL, /* sha256sum */
#endif
+ ossl_associate_connection, /* associate_connection */
+ ossl_disassociate_connection /* disassociate_connection */
};
#endif /* USE_OPENSSL */
diff --git a/libs/libcurl/src/vtls/rustls.c b/libs/libcurl/src/vtls/rustls.c
index e4f589de57..d5247f936a 100644
--- a/libs/libcurl/src/vtls/rustls.c
+++ b/libs/libcurl/src/vtls/rustls.c
@@ -37,16 +37,11 @@
#include "multiif.h"
-/* Per https://www.bearssl.org/api1.html, max TLS record size plus max
- per-record overhead. */
-#define TLSBUF_SIZE (16384 + 325)
-
struct ssl_backend_data
{
const struct rustls_client_config *config;
- struct rustls_client_session *session;
+ struct rustls_connection *conn;
bool data_pending;
- uint8_t *tlsbuf;
};
/* For a given rustls_result error code, return the best-matching CURLcode. */
@@ -82,6 +77,28 @@ cr_connect(struct Curl_easy *data UNUSED_PARAM,
return CURLE_SSL_CONNECT_ERROR;
}
+static int
+read_cb(void *userdata, uint8_t *buf, uintptr_t len, uintptr_t *out_n)
+{
+ ssize_t n = sread(*(int *)userdata, buf, len);
+ if(n < 0) {
+ return SOCKERRNO;
+ }
+ *out_n = n;
+ return 0;
+}
+
+static int
+write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n)
+{
+ ssize_t n = swrite(*(int *)userdata, buf, len);
+ if(n < 0) {
+ return SOCKERRNO;
+ }
+ *out_n = n;
+ return 0;
+}
+
/*
* On each run:
* - Read a chunk of bytes from the socket into rustls' TLS input buffer.
@@ -101,65 +118,44 @@ cr_recv(struct Curl_easy *data, int sockindex,
struct connectdata *conn = data->conn;
struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
struct ssl_backend_data *const backend = connssl->backend;
- struct rustls_client_session *const session = backend->session;
- curl_socket_t sockfd = conn->sock[sockindex];
+ struct rustls_connection *const rconn = backend->conn;
size_t n = 0;
- ssize_t tls_bytes_read = 0;
- size_t tls_bytes_processed = 0;
+ size_t tls_bytes_read = 0;
size_t plain_bytes_copied = 0;
rustls_result rresult = 0;
char errorbuf[255];
+ rustls_io_result io_error;
- tls_bytes_read = sread(sockfd, backend->tlsbuf, TLSBUF_SIZE);
- if(tls_bytes_read == 0) {
- failf(data, "connection closed without TLS close_notify alert");
+ io_error = rustls_connection_read_tls(rconn, read_cb,
+ &conn->sock[sockindex], &tls_bytes_read);
+ if(io_error == EAGAIN || io_error == EWOULDBLOCK) {
+ infof(data, "sread: EAGAIN or EWOULDBLOCK\n");
+ }
+ else if(io_error) {
+ failf(data, "reading from socket: %s", strerror(io_error));
*err = CURLE_READ_ERROR;
return -1;
}
- else if(tls_bytes_read < 0) {
- if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
- infof(data, "sread: EAGAIN or EWOULDBLOCK\n");
- *err = CURLE_AGAIN;
- return -1;
- }
- failf(data, "reading from socket: %s", strerror(SOCKERRNO));
+ else if(tls_bytes_read == 0) {
+ failf(data, "connection closed without TLS close_notify alert");
*err = CURLE_READ_ERROR;
return -1;
}
- /*
- * Now pull those bytes from the buffer into ClientSession.
- */
- DEBUGASSERT(tls_bytes_read > 0);
- while(tls_bytes_processed < (size_t)tls_bytes_read) {
- rresult = rustls_client_session_read_tls(session,
- backend->tlsbuf + tls_bytes_processed,
- tls_bytes_read - tls_bytes_processed,
- &n);
- if(rresult != RUSTLS_RESULT_OK) {
- failf(data, "error in rustls_client_session_read_tls");
- *err = CURLE_READ_ERROR;
- return -1;
- }
- else if(n == 0) {
- infof(data, "EOF from rustls_client_session_read_tls\n");
- break;
- }
+ infof(data, "cr_recv read %ld bytes from the network\n", tls_bytes_read);
- rresult = rustls_client_session_process_new_packets(session);
- if(rresult != RUSTLS_RESULT_OK) {
- rustls_error(rresult, errorbuf, sizeof(errorbuf), &n);
- failf(data, "%.*s", n, errorbuf);
- *err = map_error(rresult);
- return -1;
- }
-
- tls_bytes_processed += n;
- backend->data_pending = TRUE;
+ rresult = rustls_connection_process_new_packets(rconn);
+ if(rresult != RUSTLS_RESULT_OK) {
+ rustls_error(rresult, errorbuf, sizeof(errorbuf), &n);
+ failf(data, "%.*s", n, errorbuf);
+ *err = map_error(rresult);
+ return -1;
}
+ backend->data_pending = TRUE;
+
while(plain_bytes_copied < plainlen) {
- rresult = rustls_client_session_read(session,
+ rresult = rustls_connection_read(rconn,
(uint8_t *)plainbuf + plain_bytes_copied,
plainlen - plain_bytes_copied,
&n);
@@ -168,20 +164,21 @@ cr_recv(struct Curl_easy *data, int sockindex,
return 0;
}
else if(rresult != RUSTLS_RESULT_OK) {
- failf(data, "error in rustls_client_session_read");
+ failf(data, "error in rustls_connection_read");
*err = CURLE_READ_ERROR;
return -1;
}
else if(n == 0) {
- /* rustls returns 0 from client_session_read to mean "all currently
+ /* rustls returns 0 from connection_read to mean "all currently
available data has been read." If we bring in more ciphertext with
read_tls, more plaintext will become available. So don't tell curl
this is an EOF. Instead, say "come back later." */
- infof(data, "EOF from rustls_client_session_read\n");
+ infof(data, "cr_recv got 0 bytes of plaintext\n");
backend->data_pending = FALSE;
break;
}
else {
+ infof(data, "cr_recv copied out %ld bytes of plaintext\n", n);
plain_bytes_copied += n;
}
}
@@ -214,68 +211,50 @@ cr_send(struct Curl_easy *data, int sockindex,
struct connectdata *conn = data->conn;
struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
struct ssl_backend_data *const backend = connssl->backend;
- struct rustls_client_session *const session = backend->session;
- curl_socket_t sockfd = conn->sock[sockindex];
- ssize_t n = 0;
+ struct rustls_connection *const rconn = backend->conn;
size_t plainwritten = 0;
- size_t tlslen = 0;
size_t tlswritten = 0;
+ size_t tlswritten_total = 0;
rustls_result rresult;
+ rustls_io_result io_error;
+
+ infof(data, "cr_send %ld bytes of plaintext\n", plainlen);
if(plainlen > 0) {
- rresult = rustls_client_session_write(session,
- plainbuf, plainlen, &plainwritten);
+ rresult = rustls_connection_write(rconn, plainbuf, plainlen,
+ &plainwritten);
if(rresult != RUSTLS_RESULT_OK) {
- failf(data, "error in rustls_client_session_write");
+ failf(data, "error in rustls_connection_write");
*err = CURLE_WRITE_ERROR;
return -1;
}
else if(plainwritten == 0) {
- failf(data, "EOF in rustls_client_session_write");
+ failf(data, "EOF in rustls_connection_write");
*err = CURLE_WRITE_ERROR;
return -1;
}
}
- while(rustls_client_session_wants_write(session)) {
- rresult = rustls_client_session_write_tls(
- session, backend->tlsbuf, TLSBUF_SIZE, &tlslen);
- if(rresult != RUSTLS_RESULT_OK) {
- failf(data, "error in rustls_client_session_write_tls");
- *err = CURLE_WRITE_ERROR;
+ while(rustls_connection_wants_write(rconn)) {
+ io_error = rustls_connection_write_tls(rconn, write_cb,
+ &conn->sock[sockindex], &tlswritten);
+ if(io_error == EAGAIN || io_error == EWOULDBLOCK) {
+ infof(data, "swrite: EAGAIN after %ld bytes\n", tlswritten_total);
+ *err = CURLE_AGAIN;
return -1;
}
- else if(tlslen == 0) {
- failf(data, "EOF in rustls_client_session_write_tls");
+ else if(io_error) {
+ failf(data, "writing to socket: %s", strerror(io_error));
*err = CURLE_WRITE_ERROR;
return -1;
}
-
- tlswritten = 0;
-
- while(tlswritten < tlslen) {
- n = swrite(sockfd, backend->tlsbuf + tlswritten, tlslen - tlswritten);
- if(n < 0) {
- if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
- /* Since recv is called from poll, there should be room to
- write at least some bytes before hitting EAGAIN. */
- infof(data, "swrite: EAGAIN after %ld bytes\n", tlswritten);
- DEBUGASSERT(tlswritten > 0);
- break;
- }
- failf(data, "error in swrite");
- *err = CURLE_WRITE_ERROR;
- return -1;
- }
- if(n == 0) {
- failf(data, "EOF in swrite");
- *err = CURLE_WRITE_ERROR;
- return -1;
- }
- tlswritten += n;
+ if(tlswritten == 0) {
+ failf(data, "EOF in swrite");
+ *err = CURLE_WRITE_ERROR;
+ return -1;
}
-
- DEBUGASSERT(tlswritten <= tlslen);
+ infof(data, "cr_send wrote %ld bytes to network\n", tlswritten);
+ tlswritten_total += tlswritten;
}
return plainwritten;
@@ -310,7 +289,7 @@ static CURLcode
cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
struct ssl_backend_data *const backend)
{
- struct rustls_client_session *session = backend->session;
+ struct rustls_connection *rconn = backend->conn;
struct rustls_client_config_builder *config_builder = NULL;
const char *const ssl_cafile = SSL_CONN_CONFIG(CAfile);
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
@@ -318,19 +297,26 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
char errorbuf[256];
size_t errorlen;
int result;
-
- backend->tlsbuf = calloc(TLSBUF_SIZE, 1);
- if(backend->tlsbuf == NULL) {
- return CURLE_OUT_OF_MEMORY;
- }
+ rustls_slice_bytes alpn[2] = {
+ { (const uint8_t *)ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH },
+ { (const uint8_t *)ALPN_H2, ALPN_H2_LENGTH },
+ };
config_builder = rustls_client_config_builder_new();
+#ifdef USE_HTTP2
+ infof(data, "offering ALPN for HTTP/1.1 and HTTP/2\n");
+ rustls_client_config_builder_set_protocols(config_builder, alpn, 2);
+#else
+ infof(data, "offering ALPN for HTTP/1.1 only\n");
+ rustls_client_config_builder_set_protocols(config_builder, alpn, 1);
+#endif
if(!verifypeer) {
rustls_client_config_builder_dangerous_set_certificate_verifier(
- config_builder, cr_verify_none, NULL);
+ config_builder, cr_verify_none);
/* rustls doesn't support IP addresses (as of 0.19.0), and will reject
- * sessions created with an IP address, even when certificate verification
- * is turned off. Set a placeholder hostname and disable SNI. */
+ * connections created with an IP address, even when certificate
+ * verification is turned off. Set a placeholder hostname and disable
+ * SNI. */
if(cr_hostname_is_ip(hostname)) {
rustls_client_config_builder_set_enable_sni(config_builder, false);
hostname = "example.invalid";
@@ -357,18 +343,51 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
}
backend->config = rustls_client_config_builder_build(config_builder);
- DEBUGASSERT(session == NULL);
- result = rustls_client_session_new(
- backend->config, hostname, &session);
+ DEBUGASSERT(rconn == NULL);
+ result = rustls_client_connection_new(backend->config, hostname, &rconn);
if(result != RUSTLS_RESULT_OK) {
rustls_error(result, errorbuf, sizeof(errorbuf), &errorlen);
- failf(data, "failed to create client session: %.*s", errorlen, errorbuf);
+ failf(data, "rustls_client_connection_new: %.*s", errorlen, errorbuf);
return CURLE_COULDNT_CONNECT;
}
- backend->session = session;
+ rustls_connection_set_userdata(rconn, backend);
+ backend->conn = rconn;
return CURLE_OK;
}
+static void
+cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn,
+ const struct rustls_connection *rconn)
+{
+ const uint8_t *protocol = NULL;
+ size_t len = 0;
+
+ rustls_connection_get_alpn_protocol(rconn, &protocol, &len);
+ if(NULL == protocol) {
+ infof(data, "ALPN, server did not agree to a protocol\n");
+ return;
+ }
+
+#ifdef USE_HTTP2
+ if(len == ALPN_H2_LENGTH && 0 == memcmp(ALPN_H2, protocol, len)) {
+ infof(data, "ALPN, negotiated h2\n");
+ conn->negnpn = CURL_HTTP_VERSION_2;
+ }
+ else
+#endif
+ if(len == ALPN_HTTP_1_1_LENGTH &&
+ 0 == memcmp(ALPN_HTTP_1_1, protocol, len)) {
+ infof(data, "ALPN, negotiated http/1.1\n");
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+ }
+ else {
+ infof(data, "ALPN, negotiated an unrecognized protocol\n");
+ }
+
+ Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
+}
+
static CURLcode
cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
int sockindex, bool *done)
@@ -376,7 +395,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
curl_socket_t sockfd = conn->sock[sockindex];
struct ssl_backend_data *const backend = connssl->backend;
- struct rustls_client_session *session = NULL;
+ struct rustls_connection *rconn = NULL;
CURLcode tmperr = CURLE_OK;
int result;
int what;
@@ -393,7 +412,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
connssl->state = ssl_connection_negotiating;
}
- session = backend->session;
+ rconn = backend->conn;
/* Read/write data until the handshake is done or the socket would block. */
for(;;) {
@@ -404,18 +423,21 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
* then becomes true when we first write data, then becomes false again
* once the handshake is done.
*/
- if(!rustls_client_session_is_handshaking(session)) {
+ if(!rustls_connection_is_handshaking(rconn)) {
infof(data, "Done handshaking\n");
/* Done with the handshake. Set up callbacks to send/receive data. */
connssl->state = ssl_connection_complete;
+
+ cr_set_negotiated_alpn(data, conn, rconn);
+
conn->recv[sockindex] = cr_recv;
conn->send[sockindex] = cr_send;
*done = TRUE;
return CURLE_OK;
}
- wants_read = rustls_client_session_wants_read(session);
- wants_write = rustls_client_session_wants_write(session);
+ wants_read = rustls_connection_wants_read(rconn);
+ wants_write = rustls_connection_wants_write(rconn);
DEBUGASSERT(wants_read || wants_write);
writefd = wants_write?sockfd:CURL_SOCKET_BAD;
readfd = wants_read?sockfd:CURL_SOCKET_BAD;
@@ -439,7 +461,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
/* socket is readable or writable */
if(wants_write) {
- infof(data, "ClientSession wants us to write_tls.\n");
+ infof(data, "rustls_connection wants us to write_tls.\n");
cr_send(data, sockindex, NULL, 0, &tmperr);
if(tmperr == CURLE_AGAIN) {
infof(data, "writing would block\n");
@@ -451,7 +473,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
}
if(wants_read) {
- infof(data, "ClientSession wants us to read_tls.\n");
+ infof(data, "rustls_connection wants us to read_tls.\n");
cr_recv(data, sockindex, NULL, 0, &tmperr);
if(tmperr == CURLE_AGAIN) {
@@ -482,13 +504,13 @@ cr_getsock(struct connectdata *conn, curl_socket_t *socks)
struct ssl_connect_data *const connssl = &conn->ssl[FIRSTSOCKET];
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
struct ssl_backend_data *const backend = connssl->backend;
- struct rustls_client_session *session = backend->session;
+ struct rustls_connection *rconn = backend->conn;
- if(rustls_client_session_wants_write(session)) {
+ if(rustls_connection_wants_write(rconn)) {
socks[0] = sockfd;
return GETSOCK_WRITESOCK(0);
}
- if(rustls_client_session_wants_read(session)) {
+ if(rustls_connection_wants_read(rconn)) {
socks[0] = sockfd;
return GETSOCK_READSOCK(0);
}
@@ -501,7 +523,7 @@ cr_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
struct ssl_backend_data *backend = connssl->backend;
- return &backend->session;
+ return &backend->conn;
}
static void
@@ -513,21 +535,20 @@ cr_close(struct Curl_easy *data, struct connectdata *conn,
CURLcode tmperr = CURLE_OK;
ssize_t n = 0;
- if(backend->session) {
- rustls_client_session_send_close_notify(backend->session);
+ if(backend->conn) {
+ rustls_connection_send_close_notify(backend->conn);
n = cr_send(data, sockindex, NULL, 0, &tmperr);
if(n < 0) {
failf(data, "error sending close notify: %d", tmperr);
}
- rustls_client_session_free(backend->session);
- backend->session = NULL;
+ rustls_connection_free(backend->conn);
+ backend->conn = NULL;
}
if(backend->config) {
rustls_client_config_free(backend->config);
backend->config = NULL;
}
- free(backend->tlsbuf);
}
const struct Curl_ssl Curl_ssl_rustls = {
@@ -554,7 +575,9 @@ const struct Curl_ssl Curl_ssl_rustls = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
- NULL /* sha256sum */
+ NULL, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
#endif /* USE_RUSTLS */
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c
index 961a71f6d5..2bcf11db25 100644
--- a/libs/libcurl/src/vtls/schannel.c
+++ b/libs/libcurl/src/vtls/schannel.c
@@ -117,6 +117,10 @@
#define SP_PROT_TLS1_2_CLIENT 0x00000800
#endif
+#ifndef SCH_USE_STRONG_CRYPTO
+#define SCH_USE_STRONG_CRYPTO 0x00400000
+#endif
+
#ifndef SECBUFFER_ALERT
#define SECBUFFER_ALERT 17
#endif
@@ -324,17 +328,22 @@ get_alg_id_by_name(char *name)
}
static CURLcode
-set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers)
+set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers,
+ ALG_ID *algIds)
{
char *startCur = ciphers;
int algCount = 0;
- static ALG_ID algIds[45]; /*There are 45 listed in the MS headers*/
- while(startCur && (0 != *startCur) && (algCount < 45)) {
+ while(startCur && (0 != *startCur) && (algCount < NUMOF_CIPHERS)) {
long alg = strtol(startCur, 0, 0);
if(!alg)
alg = get_alg_id_by_name(startCur);
if(alg)
algIds[algCount++] = alg;
+ else if(!strncmp(startCur, "USE_STRONG_CRYPTO",
+ sizeof("USE_STRONG_CRYPTO") - 1) ||
+ !strncmp(startCur, "SCH_USE_STRONG_CRYPTO",
+ sizeof("SCH_USE_STRONG_CRYPTO") - 1))
+ schannel_cred->dwFlags |= SCH_USE_STRONG_CRYPTO;
else
return CURLE_SSL_CIPHER;
startCur = strchr(startCur, ':');
@@ -358,7 +367,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
size_t store_name_len;
sep = _tcschr(path, TEXT('\\'));
- if(sep == NULL)
+ if(!sep)
return CURLE_SSL_CERTPROBLEM;
store_name_len = sep - path;
@@ -388,7 +397,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
store_path_start = sep + 1;
sep = _tcschr(store_path_start, TEXT('\\'));
- if(sep == NULL)
+ if(!sep)
return CURLE_SSL_CERTPROBLEM;
*thumbprint = sep + 1;
@@ -398,7 +407,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
*sep = TEXT('\0');
*store_path = _tcsdup(store_path_start);
*sep = TEXT('\\');
- if(*store_path == NULL)
+ if(!*store_path)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
@@ -428,12 +437,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif
TCHAR *host_name;
CURLcode result;
-#ifndef CURL_DISABLE_PROXY
- char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
-#else
- char * const hostname = conn->host.name;
-#endif
+ char * const hostname = SSL_HOST_NAME();
DEBUGF(infof(data,
"schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
@@ -469,7 +473,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif
#else
#ifdef HAS_MANUAL_VERIFY_API
- if(SSL_CONN_CONFIG(CAfile)) {
+ if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) {
if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
BACKEND->use_manual_cred_validation = true;
@@ -483,7 +487,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
else
BACKEND->use_manual_cred_validation = false;
#else
- if(SSL_CONN_CONFIG(CAfile)) {
+ if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) {
failf(data, "schannel: CA cert support not built in");
return CURLE_NOT_BUILT_IN;
}
@@ -558,6 +562,14 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
"names in server certificates.\n"));
}
+ if(!SSL_SET_OPTION(auto_client_cert)) {
+ schannel_cred.dwFlags &= ~SCH_CRED_USE_DEFAULT_CREDS;
+ schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
+ infof(data, "schannel: disabled automatic use of client certificate\n");
+ }
+ else
+ infof(data, "schannel: enabled automatic use of client certificate\n");
+
switch(conn->ssl_config.version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
@@ -572,18 +584,17 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
break;
}
case CURL_SSLVERSION_SSLv3:
- schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
- break;
case CURL_SSLVERSION_SSLv2:
- schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT;
- break;
+ failf(data, "SSL versions not supported");
+ return CURLE_NOT_BUILT_IN;
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
return CURLE_SSL_CONNECT_ERROR;
}
if(SSL_CONN_CONFIG(cipher_list)) {
- result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list));
+ result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list),
+ BACKEND->algIds);
if(CURLE_OK != result) {
failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
return result;
@@ -700,7 +711,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
if(!blob)
free(certdata);
- if(cert_store == NULL) {
+ if(!cert_store) {
DWORD errorcode = GetLastError();
if(errorcode == ERROR_INVALID_PASSWORD)
failf(data, "schannel: Failed to import cert file %s, "
@@ -717,7 +728,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
CERT_FIND_ANY, NULL, NULL);
- if(client_certs[0] == NULL) {
+ if(!client_certs[0]) {
failf(data, "schannel: Failed to get certificate from file %s"
", last error is 0x%x",
cert_showfilename_error, GetLastError());
@@ -861,11 +872,11 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
list_start_index = cur;
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
- memcpy(&alpn_buffer[cur], NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN);
- cur += NGHTTP2_PROTO_ALPN_LEN;
- infof(data, "schannel: ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ memcpy(&alpn_buffer[cur], ALPN_H2, ALPN_H2_LENGTH);
+ cur += ALPN_H2_LENGTH;
+ infof(data, "schannel: ALPN, offering %s\n", ALPN_H2);
}
#endif
@@ -893,11 +904,15 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
- /* setup request flags */
+ /* security request flags */
BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_STREAM;
+ if(!SSL_SET_OPTION(auto_client_cert)) {
+ BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+ }
+
/* allocate memory for the security context handle */
BACKEND->ctxt = (struct Curl_schannel_ctxt *)
calloc(1, sizeof(struct Curl_schannel_ctxt));
@@ -997,12 +1012,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
bool doread;
-#ifndef CURL_DISABLE_PROXY
- char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
-#else
- char * const hostname = conn->host.name;
-#endif
+ char * const hostname = SSL_HOST_NAME();
const char *pubkey_ptr;
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
@@ -1015,23 +1025,23 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
return CURLE_SSL_CONNECT_ERROR;
/* buffer to store previously received and decrypted data */
- if(BACKEND->decdata_buffer == NULL) {
+ if(!BACKEND->decdata_buffer) {
BACKEND->decdata_offset = 0;
BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
BACKEND->decdata_buffer = malloc(BACKEND->decdata_length);
- if(BACKEND->decdata_buffer == NULL) {
+ if(!BACKEND->decdata_buffer) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
}
/* buffer to store previously received and encrypted data */
- if(BACKEND->encdata_buffer == NULL) {
+ if(!BACKEND->encdata_buffer) {
BACKEND->encdata_is_incomplete = false;
BACKEND->encdata_offset = 0;
BACKEND->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
BACKEND->encdata_buffer = malloc(BACKEND->encdata_length);
- if(BACKEND->encdata_buffer == NULL) {
+ if(!BACKEND->encdata_buffer) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
@@ -1046,7 +1056,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
reallocated_buffer = realloc(BACKEND->encdata_buffer,
reallocated_length);
- if(reallocated_buffer == NULL) {
+ if(!reallocated_buffer) {
failf(data, "schannel: unable to re-allocate memory");
return CURLE_OUT_OF_MEMORY;
}
@@ -1101,7 +1111,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&outbuf_desc, outbuf, 3);
- if(inbuf[0].pvBuffer == NULL) {
+ if(!inbuf[0].pvBuffer) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
@@ -1251,9 +1261,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n"));
}
- pubkey_ptr = SSL_IS_PROXY() ?
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+ pubkey_ptr = SSL_PINNED_PUB_KEY();
if(pubkey_ptr) {
result = pkp_pin_peer_pubkey(data, conn, sockindex, pubkey_ptr);
if(result) {
@@ -1340,8 +1348,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
CERT_CONTEXT *ccert_context = NULL;
bool isproxy = SSL_IS_PROXY();
#ifdef DEBUGBUILD
- const char * const hostname = isproxy ? conn->http_proxy.host.name :
- conn->host.name;
+ const char * const hostname = SSL_HOST_NAME();
#endif
#ifdef HAS_ALPN
SecPkgContext_ApplicationProtocol alpn_result;
@@ -1389,10 +1396,9 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
infof(data, "schannel: ALPN, server accepted to use %.*s\n",
alpn_result.ProtocolIdSize, alpn_result.ProtocolId);
-#ifdef USE_NGHTTP2
- if(alpn_result.ProtocolIdSize == NGHTTP2_PROTO_VERSION_ID_LEN &&
- !memcmp(NGHTTP2_PROTO_VERSION_ID, alpn_result.ProtocolId,
- NGHTTP2_PROTO_VERSION_ID_LEN)) {
+#ifdef USE_HTTP2
+ if(alpn_result.ProtocolIdSize == ALPN_H2_LENGTH &&
+ !memcmp(ALPN_H2, alpn_result.ProtocolId, ALPN_H2_LENGTH)) {
conn->negnpn = CURL_HTTP_VERSION_2;
}
else
@@ -1453,7 +1459,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&ccert_context);
- if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) {
+ if((sspi_status != SEC_E_OK) || !ccert_context) {
failf(data, "schannel: failed to retrieve remote cert context");
return CURLE_PEER_FAILED_VERIFICATION;
}
@@ -1805,7 +1811,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
}
reallocated_buffer = realloc(BACKEND->encdata_buffer,
reallocated_length);
- if(reallocated_buffer == NULL) {
+ if(!reallocated_buffer) {
*err = CURLE_OUT_OF_MEMORY;
failf(data, "schannel: unable to re-allocate memory");
goto cleanup;
@@ -1894,7 +1900,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
}
reallocated_buffer = realloc(BACKEND->decdata_buffer,
reallocated_length);
- if(reallocated_buffer == NULL) {
+ if(!reallocated_buffer) {
*err = CURLE_OUT_OF_MEMORY;
failf(data, "schannel: unable to re-allocate memory");
goto cleanup;
@@ -2128,12 +2134,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
* Shutting Down an Schannel Connection
*/
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-#ifndef CURL_DISABLE_PROXY
- char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
-#else
- char * const hostname = conn->host.name;
-#endif
+ char * const hostname = SSL_HOST_NAME();
DEBUGASSERT(data);
@@ -2296,7 +2297,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&pCertContextServer);
- if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) {
+ if((sspi_status != SEC_E_OK) || !pCertContextServer) {
char buffer[STRERROR_LEN];
failf(data, "schannel: Failed to read remote certificate context: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
@@ -2406,6 +2407,9 @@ const struct Curl_ssl Curl_ssl_schannel = {
{ CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */
SSLSUPP_CERTINFO |
+#ifdef HAS_MANUAL_VERIFY_API
+ SSLSUPP_CAINFO_BLOB |
+#endif
SSLSUPP_PINNEDPUBKEY,
sizeof(struct ssl_backend_data),
@@ -2429,7 +2433,9 @@ const struct Curl_ssl Curl_ssl_schannel = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
- schannel_sha256sum /* sha256sum */
+ schannel_sha256sum, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
#endif /* USE_SCHANNEL */
diff --git a/libs/libcurl/src/vtls/schannel.h b/libs/libcurl/src/vtls/schannel.h
index 2952caa1a5..77853aa30f 100644
--- a/libs/libcurl/src/vtls/schannel.h
+++ b/libs/libcurl/src/vtls/schannel.h
@@ -71,6 +71,8 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
#endif
#endif
+#define NUMOF_CIPHERS 45 /* There are 45 listed in the MS headers */
+
struct Curl_schannel_cred {
CredHandle cred_handle;
TimeStamp time_stamp;
@@ -102,6 +104,7 @@ struct ssl_backend_data {
#ifdef HAS_MANUAL_VERIFY_API
bool use_manual_cred_validation; /* true if manual cred validation is used */
#endif
+ ALG_ID algIds[NUMOF_CIPHERS];
};
#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */
diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c
index e0fdbd5b63..25d47b8087 100644
--- a/libs/libcurl/src/vtls/schannel_verify.c
+++ b/libs/libcurl/src/vtls/schannel_verify.c
@@ -77,21 +77,156 @@ static int is_cr_or_lf(char c)
return c == '\r' || c == '\n';
}
-static CURLcode add_certs_to_store(HCERTSTORE trust_store,
- const char *ca_file,
- struct Curl_easy *data)
+/* Search the substring needle,needlelen into string haystack,haystacklen
+ * Strings don't need to be terminated by a '\0'.
+ * Similar of OSX/Linux memmem (not available on Visual Studio).
+ * Return position of beginning of first occurence or NULL if not found
+ */
+static const char *c_memmem(const void *haystack, size_t haystacklen,
+ const void *needle, size_t needlelen)
+{
+ const char *p;
+ char first;
+ const char *str_limit = (const char *)haystack + haystacklen;
+ if(!needlelen || needlelen > haystacklen)
+ return NULL;
+ first = *(const char *)needle;
+ for(p = (const char *)haystack; p <= (str_limit - needlelen); p++)
+ if(((*p) == first) && (memcmp(p, needle, needlelen) == 0))
+ return p;
+
+ return NULL;
+}
+
+static CURLcode add_certs_data_to_store(HCERTSTORE trust_store,
+ const char *ca_buffer,
+ size_t ca_buffer_size,
+ const char *ca_file_text,
+ struct Curl_easy *data)
+{
+ const size_t begin_cert_len = strlen(BEGIN_CERT);
+ const size_t end_cert_len = strlen(END_CERT);
+ CURLcode result = CURLE_OK;
+ int num_certs = 0;
+ bool more_certs = 1;
+ const char *current_ca_file_ptr = ca_buffer;
+ const char *ca_buffer_limit = ca_buffer + ca_buffer_size;
+
+ while(more_certs && (current_ca_file_ptr<ca_buffer_limit)) {
+ const char *begin_cert_ptr = c_memmem(current_ca_file_ptr,
+ ca_buffer_limit-current_ca_file_ptr,
+ BEGIN_CERT,
+ begin_cert_len);
+ if(!begin_cert_ptr || !is_cr_or_lf(begin_cert_ptr[begin_cert_len])) {
+ more_certs = 0;
+ }
+ else {
+ const char *end_cert_ptr = c_memmem(begin_cert_ptr,
+ ca_buffer_limit-begin_cert_ptr,
+ END_CERT,
+ end_cert_len);
+ if(!end_cert_ptr) {
+ failf(data,
+ "schannel: CA file '%s' is not correctly formatted",
+ ca_file_text);
+ result = CURLE_SSL_CACERT_BADFILE;
+ more_certs = 0;
+ }
+ else {
+ CERT_BLOB cert_blob;
+ CERT_CONTEXT *cert_context = NULL;
+ BOOL add_cert_result = FALSE;
+ DWORD actual_content_type = 0;
+ DWORD cert_size = (DWORD)
+ ((end_cert_ptr + end_cert_len) - begin_cert_ptr);
+
+ cert_blob.pbData = (BYTE *)begin_cert_ptr;
+ cert_blob.cbData = cert_size;
+ if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB,
+ &cert_blob,
+ CERT_QUERY_CONTENT_FLAG_CERT,
+ CERT_QUERY_FORMAT_FLAG_ALL,
+ 0,
+ NULL,
+ &actual_content_type,
+ NULL,
+ NULL,
+ NULL,
+ (const void **)&cert_context)) {
+ char buffer[STRERROR_LEN];
+ failf(data,
+ "schannel: failed to extract certificate from CA file "
+ "'%s': %s",
+ ca_file_text,
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
+ result = CURLE_SSL_CACERT_BADFILE;
+ more_certs = 0;
+ }
+ else {
+ current_ca_file_ptr = begin_cert_ptr + cert_size;
+
+ /* Sanity check that the cert_context object is the right type */
+ if(CERT_QUERY_CONTENT_CERT != actual_content_type) {
+ failf(data,
+ "schannel: unexpected content type '%d' when extracting "
+ "certificate from CA file '%s'",
+ actual_content_type, ca_file_text);
+ result = CURLE_SSL_CACERT_BADFILE;
+ more_certs = 0;
+ }
+ else {
+ add_cert_result =
+ CertAddCertificateContextToStore(trust_store,
+ cert_context,
+ CERT_STORE_ADD_ALWAYS,
+ 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_text,
+ Curl_winapi_strerror(GetLastError(), buffer,
+ sizeof(buffer)));
+ result = CURLE_SSL_CACERT_BADFILE;
+ more_certs = 0;
+ }
+ else {
+ num_certs++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(result == CURLE_OK) {
+ if(!num_certs) {
+ infof(data,
+ "schannel: did not add any certificates from CA file '%s'\n",
+ ca_file_text);
+ }
+ else {
+ infof(data,
+ "schannel: added %d certificate(s) from CA file '%s'\n",
+ num_certs, ca_file_text);
+ }
+ }
+ return result;
+}
+
+static CURLcode add_certs_file_to_store(HCERTSTORE trust_store,
+ const char *ca_file,
+ struct Curl_easy *data)
{
CURLcode result;
HANDLE ca_file_handle = INVALID_HANDLE_VALUE;
LARGE_INTEGER file_size;
char *ca_file_buffer = NULL;
- char *current_ca_file_ptr = NULL;
TCHAR *ca_file_tstr = NULL;
size_t ca_file_bufsize = 0;
DWORD total_bytes_read = 0;
- bool more_certs = 0;
- int num_certs = 0;
- size_t END_CERT_LEN;
ca_file_tstr = curlx_convert_UTF8_to_tchar((char *)ca_file);
if(!ca_file_tstr) {
@@ -181,106 +316,10 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
if(result != CURLE_OK) {
goto cleanup;
}
-
- END_CERT_LEN = strlen(END_CERT);
-
- more_certs = 1;
- current_ca_file_ptr = ca_file_buffer;
- while(more_certs && *current_ca_file_ptr != '\0') {
- char *begin_cert_ptr = strstr(current_ca_file_ptr, BEGIN_CERT);
- if(!begin_cert_ptr || !is_cr_or_lf(begin_cert_ptr[strlen(BEGIN_CERT)])) {
- more_certs = 0;
- }
- else {
- char *end_cert_ptr = strstr(begin_cert_ptr, END_CERT);
- if(!end_cert_ptr) {
- failf(data,
- "schannel: CA file '%s' is not correctly formatted",
- ca_file);
- result = CURLE_SSL_CACERT_BADFILE;
- more_certs = 0;
- }
- else {
- CERT_BLOB cert_blob;
- CERT_CONTEXT *cert_context = NULL;
- BOOL add_cert_result = FALSE;
- DWORD actual_content_type = 0;
- DWORD cert_size = (DWORD)
- ((end_cert_ptr + END_CERT_LEN) - begin_cert_ptr);
-
- cert_blob.pbData = (BYTE *)begin_cert_ptr;
- cert_blob.cbData = cert_size;
- if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB,
- &cert_blob,
- CERT_QUERY_CONTENT_FLAG_CERT,
- CERT_QUERY_FORMAT_FLAG_ALL,
- 0,
- NULL,
- &actual_content_type,
- NULL,
- 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_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
- result = CURLE_SSL_CACERT_BADFILE;
- more_certs = 0;
- }
- else {
- current_ca_file_ptr = begin_cert_ptr + cert_size;
-
- /* Sanity check that the cert_context object is the right type */
- if(CERT_QUERY_CONTENT_CERT != actual_content_type) {
- failf(data,
- "schannel: unexpected content type '%d' when extracting "
- "certificate from CA file '%s'",
- actual_content_type, ca_file);
- result = CURLE_SSL_CACERT_BADFILE;
- more_certs = 0;
- }
- else {
- add_cert_result =
- CertAddCertificateContextToStore(trust_store,
- cert_context,
- CERT_STORE_ADD_ALWAYS,
- 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_winapi_strerror(GetLastError(), buffer,
- sizeof(buffer)));
- result = CURLE_SSL_CACERT_BADFILE;
- more_certs = 0;
- }
- else {
- num_certs++;
- }
- }
- }
- }
- }
- }
-
- if(result == CURLE_OK) {
- if(!num_certs) {
- infof(data,
- "schannel: did not add any certificates from CA file '%s'\n",
- ca_file);
- }
- else {
- infof(data,
- "schannel: added %d certificate(s) from CA file '%s'\n",
- num_certs, ca_file);
- }
- }
+ result = add_certs_data_to_store(trust_store,
+ ca_file_buffer, ca_file_bufsize,
+ ca_file,
+ data);
cleanup:
if(ca_file_handle != INVALID_HANDLE_VALUE) {
@@ -389,7 +428,7 @@ static DWORD cert_get_name_string(struct Curl_easy *data,
if(entry->dwAltNameChoice != CERT_ALT_NAME_DNS_NAME) {
continue;
}
- if(entry->pwszDNSName == NULL) {
+ if(!entry->pwszDNSName) {
infof(data, "schannel: Empty DNS name.");
continue;
}
@@ -536,27 +575,22 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
const CERT_CHAIN_CONTEXT *pChainContext = NULL;
HCERTCHAINENGINE cert_chain_engine = NULL;
HCERTSTORE trust_store = NULL;
-#ifndef CURL_DISABLE_PROXY
- const char * const conn_hostname = SSL_IS_PROXY() ?
- conn->http_proxy.host.name :
- conn->host.name;
-#else
- const char * const conn_hostname = conn->host.name;
-#endif
+ const char * const conn_hostname = SSL_HOST_NAME();
sspi_status =
s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&pCertContextServer);
- if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) {
+ if((sspi_status != SEC_E_OK) || !pCertContextServer) {
char buffer[STRERROR_LEN];
failf(data, "schannel: Failed to read remote certificate context: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
result = CURLE_PEER_FAILED_VERIFICATION;
}
- if(result == CURLE_OK && SSL_CONN_CONFIG(CAfile) &&
+ if(result == CURLE_OK &&
+ (SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
BACKEND->use_manual_cred_validation) {
/*
* Create a chain engine that uses the certificates in the CA file as
@@ -582,8 +616,19 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
result = CURLE_SSL_CACERT_BADFILE;
}
else {
- result = add_certs_to_store(trust_store, SSL_CONN_CONFIG(CAfile),
- data);
+ const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
+ if(ca_info_blob) {
+ result = add_certs_data_to_store(trust_store,
+ (const char *)ca_info_blob->data,
+ ca_info_blob->len,
+ "(memory blob)",
+ data);
+ }
+ else {
+ result = add_certs_file_to_store(trust_store,
+ SSL_CONN_CONFIG(CAfile),
+ data);
+ }
}
}
diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c
index 9d637da2ec..edd375ea7d 100644
--- a/libs/libcurl/src/vtls/sectransp.c
+++ b/libs/libcurl/src/vtls/sectransp.c
@@ -67,6 +67,7 @@
#define CURL_BUILD_IOS_7 0
#define CURL_BUILD_IOS_9 0
#define CURL_BUILD_IOS_11 0
+#define CURL_BUILD_IOS_13 0
#define CURL_BUILD_MAC 1
/* This is the maximum API level we are allowed to use when building: */
#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
@@ -76,6 +77,7 @@
#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
#define CURL_BUILD_MAC_10_11 MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
#define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
+#define CURL_BUILD_MAC_10_15 MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
/* These macros mean "the following code is present to allow runtime backward
compatibility with at least this cat or earlier":
(You set this at build-time using the compiler command line option
@@ -91,6 +93,7 @@
#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
#define CURL_BUILD_IOS_9 __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000
#define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+#define CURL_BUILD_IOS_13 __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
#define CURL_BUILD_MAC 0
#define CURL_BUILD_MAC_10_5 0
#define CURL_BUILD_MAC_10_6 0
@@ -99,6 +102,7 @@
#define CURL_BUILD_MAC_10_9 0
#define CURL_BUILD_MAC_10_11 0
#define CURL_BUILD_MAC_10_13 0
+#define CURL_BUILD_MAC_10_15 0
#define CURL_SUPPORT_MAC_10_5 0
#define CURL_SUPPORT_MAC_10_6 0
#define CURL_SUPPORT_MAC_10_7 0
@@ -138,6 +142,636 @@ struct ssl_backend_data {
size_t ssl_write_buffered_length;
};
+struct st_cipher {
+ const char *name; /* Cipher suite IANA name. It starts with "TLS_" prefix */
+ const char *alias_name; /* Alias name is the same as OpenSSL cipher name */
+ SSLCipherSuite num; /* Cipher suite code/number defined in IANA registry */
+ bool weak; /* Flag to mark cipher as weak based on previous implementation
+ of Secure Transport back-end by CURL */
+};
+
+/* Macro to initialize st_cipher data structure: stringify id to name, cipher
+ number/id, 'weak' suite flag
+ */
+#define CIPHER_DEF(num, alias, weak) \
+ { #num, alias, num, weak }
+
+/*
+ Macro to initialize st_cipher data structure with name, code (IANA cipher
+ number/id value), and 'weak' suite flag. The first 28 cipher suite numbers
+ have the same IANA code for both SSL and TLS standards: numbers 0x0000 to
+ 0x001B. They have different names though. The first 4 letters of the cipher
+ suite name are the protocol name: "SSL_" or "TLS_", rest of the IANA name is
+ the same for both SSL and TLS cipher suite name.
+ The second part of the problem is that macOS/iOS SDKs don't define all TLS
+ codes but only 12 of them. The SDK defines all SSL codes though, i.e. SSL_NUM
+ constant is always defined for those 28 ciphers while TLS_NUM is defined only
+ for 12 of the first 28 ciphers. Those 12 TLS cipher codes match to
+ corresponding SSL enum value and represent the same cipher suite. Therefore
+ we'll use the SSL enum value for those cipher suites because it is defined
+ for all 28 of them.
+ We make internal data consistent and based on TLS names, i.e. all st_cipher
+ item names start with the "TLS_" prefix.
+ Summarizing all the above, those 28 first ciphers are presented in our table
+ with both TLS and SSL names. Their cipher numbers are assigned based on the
+ SDK enum value for the SSL cipher, which matches to IANA TLS number.
+ */
+#define CIPHER_DEF_SSLTLS(num_wo_prefix, alias, weak) \
+ { "TLS_" #num_wo_prefix, alias, SSL_##num_wo_prefix, weak }
+
+/*
+ Cipher suites were marked as weak based on the following:
+ RC4 encryption - rfc7465, the document contains a list of deprecated ciphers.
+ Marked in the code below as weak.
+ RC2 encryption - many mentions, was found vulnerable to a relatively easy
+ attack https://link.springer.com/chapter/10.1007%2F3-540-69710-1_14
+ Marked in the code below as weak.
+ DES and IDEA encryption - rfc5469, has a list of deprecated ciphers.
+ Marked in the code below as weak.
+ Anonymous Diffie-Hellman authentication and anonymous elliptic curve
+ Diffie-Hellman - vulnerable to a man-in-the-middle attack. Deprecated by
+ RFC 4346 aka TLS 1.1 (section A.5, page 60)
+ Null bulk encryption suites - not encrypted communication
+ Export ciphers, i.e. ciphers with restrictions to be used outside the US for
+ software exported to some countries, they were excluded from TLS 1.1
+ version. More precisely, they were noted as ciphers which MUST NOT be
+ negotiated in RFC 4346 aka TLS 1.1 (section A.5, pages 60 and 61).
+ All of those filters were considered weak because they contain a weak
+ algorithm like DES, RC2 or RC4, and already considered weak by other
+ criteria.
+ 3DES - NIST deprecated it and is going to retire it by 2023
+ https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA
+ OpenSSL https://www.openssl.org/blog/blog/2016/08/24/sweet32/ also
+ deprecated those ciphers. Some other libraries also consider it
+ vulnerable or at least not strong enough.
+
+ CBC ciphers are vulnerable with SSL3.0 and TLS1.0:
+ https://www.cisco.com/c/en/us/support/docs/security/email-security-appliance
+ /118518-technote-esa-00.html
+ We don't take care of this issue because it is resolved by later TLS
+ versions and for us, it requires more complicated checks, we need to
+ check a protocol version also. Vulnerability doesn't look very critical
+ and we do not filter out those cipher suites.
+ */
+
+#define CIPHER_WEAK_NOT_ENCRYPTED TRUE
+#define CIPHER_WEAK_RC_ENCRYPTION TRUE
+#define CIPHER_WEAK_DES_ENCRYPTION TRUE
+#define CIPHER_WEAK_IDEA_ENCRYPTION TRUE
+#define CIPHER_WEAK_ANON_AUTH TRUE
+#define CIPHER_WEAK_3DES_ENCRYPTION TRUE
+#define CIPHER_STRONG_ENOUGH FALSE
+
+/* Please do not change the order of the first ciphers available for SSL.
+ Do not insert and do not delete any of them. Code below
+ depends on their order and continuity.
+ If you add a new cipher, please maintain order by number, i.e.
+ insert in between existing items to appropriate place based on
+ cipher suite IANA number
+*/
+const static struct st_cipher ciphertable[] = {
+ /* SSL version 3.0 and initial TLS 1.0 cipher suites.
+ Defined since SDK 10.2.8 */
+ CIPHER_DEF_SSLTLS(NULL_WITH_NULL_NULL, /* 0x0000 */
+ NULL,
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF_SSLTLS(RSA_WITH_NULL_MD5, /* 0x0001 */
+ "NULL-MD5",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF_SSLTLS(RSA_WITH_NULL_SHA, /* 0x0002 */
+ "NULL-SHA",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_RC4_40_MD5, /* 0x0003 */
+ "EXP-RC4-MD5",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(RSA_WITH_RC4_128_MD5, /* 0x0004 */
+ "RC4-MD5",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(RSA_WITH_RC4_128_SHA, /* 0x0005 */
+ "RC4-SHA",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* 0x0006 */
+ "EXP-RC2-CBC-MD5",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(RSA_WITH_IDEA_CBC_SHA, /* 0x0007 */
+ "IDEA-CBC-SHA",
+ CIPHER_WEAK_IDEA_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x0008 */
+ "EXP-DES-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(RSA_WITH_DES_CBC_SHA, /* 0x0009 */
+ "DES-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(RSA_WITH_3DES_EDE_CBC_SHA, /* 0x000A */
+ "DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DH_DSS_EXPORT_WITH_DES40_CBC_SHA, /* 0x000B */
+ "EXP-DH-DSS-DES-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DH_DSS_WITH_DES_CBC_SHA, /* 0x000C */
+ "DH-DSS-DES-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DH_DSS_WITH_3DES_EDE_CBC_SHA, /* 0x000D */
+ "DH-DSS-DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DH_RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x000E */
+ "EXP-DH-RSA-DES-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DH_RSA_WITH_DES_CBC_SHA, /* 0x000F */
+ "DH-RSA-DES-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x0010 */
+ "DH-RSA-DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, /* 0x0011 */
+ "EXP-EDH-DSS-DES-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DHE_DSS_WITH_DES_CBC_SHA, /* 0x0012 */
+ "EDH-DSS-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* 0x0013 */
+ "DHE-DSS-DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x0014 */
+ "EXP-EDH-RSA-DES-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DHE_RSA_WITH_DES_CBC_SHA, /* 0x0015 */
+ "EDH-RSA-DES-CBC-SHA",
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x0016 */
+ "DHE-RSA-DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF_SSLTLS(DH_anon_EXPORT_WITH_RC4_40_MD5, /* 0x0017 */
+ "EXP-ADH-RC4-MD5",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF_SSLTLS(DH_anon_WITH_RC4_128_MD5, /* 0x0018 */
+ "ADH-RC4-MD5",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF_SSLTLS(DH_anon_EXPORT_WITH_DES40_CBC_SHA, /* 0x0019 */
+ "EXP-ADH-DES-CBC-SHA",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF_SSLTLS(DH_anon_WITH_DES_CBC_SHA, /* 0x001A */
+ "ADH-DES-CBC-SHA",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF_SSLTLS(DH_anon_WITH_3DES_EDE_CBC_SHA, /* 0x001B */
+ "ADH-DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF(SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* 0x001C */
+ NULL,
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* 0x001D */
+ NULL,
+ CIPHER_STRONG_ENOUGH),
+
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+ /* RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption */
+ CIPHER_DEF(TLS_PSK_WITH_NULL_SHA, /* 0x002C */
+ "PSK-NULL-SHA",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA, /* 0x002D */
+ "DHE-PSK-NULL-SHA",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA, /* 0x002E */
+ "RSA-PSK-NULL-SHA",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+
+ /* TLS addenda using AES, per RFC 3268. Defined since SDK 10.4u */
+ CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA, /* 0x002F */
+ "AES128-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_CBC_SHA, /* 0x0030 */
+ "DH-DSS-AES128-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_CBC_SHA, /* 0x0031 */
+ "DH-RSA-AES128-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* 0x0032 */
+ "DHE-DSS-AES128-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* 0x0033 */
+ "DHE-RSA-AES128-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_anon_WITH_AES_128_CBC_SHA, /* 0x0034 */
+ "ADH-AES128-SHA",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA, /* 0x0035 */
+ "AES256-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_CBC_SHA, /* 0x0036 */
+ "DH-DSS-AES256-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_CBC_SHA, /* 0x0037 */
+ "DH-RSA-AES256-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* 0x0038 */
+ "DHE-DSS-AES256-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* 0x0039 */
+ "DHE-RSA-AES256-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_anon_WITH_AES_256_CBC_SHA, /* 0x003A */
+ "ADH-AES256-SHA",
+ CIPHER_WEAK_ANON_AUTH),
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+ /* TLS 1.2 addenda, RFC 5246 */
+ /* Server provided RSA certificate for key exchange. */
+ CIPHER_DEF(TLS_RSA_WITH_NULL_SHA256, /* 0x003B */
+ "NULL-SHA256",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA256, /* 0x003C */
+ "AES128-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA256, /* 0x003D */
+ "AES256-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ /* Server-authenticated (and optionally client-authenticated)
+ Diffie-Hellman. */
+ CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, /* 0x003E */
+ "DH-DSS-AES128-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, /* 0x003F */
+ "DH-RSA-AES128-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, /* 0x0040 */
+ "DHE-DSS-AES128-SHA256",
+ CIPHER_STRONG_ENOUGH),
+
+ /* TLS 1.2 addenda, RFC 5246 */
+ CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, /* 0x0067 */
+ "DHE-RSA-AES128-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, /* 0x0068 */
+ "DH-DSS-AES256-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, /* 0x0069 */
+ "DH-RSA-AES256-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, /* 0x006A */
+ "DHE-DSS-AES256-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, /* 0x006B */
+ "DHE-RSA-AES256-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_anon_WITH_AES_128_CBC_SHA256, /* 0x006C */
+ "ADH-AES128-SHA256",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF(TLS_DH_anon_WITH_AES_256_CBC_SHA256, /* 0x006D */
+ "ADH-AES256-SHA256",
+ CIPHER_WEAK_ANON_AUTH),
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+ /* Addendum from RFC 4279, TLS PSK */
+ CIPHER_DEF(TLS_PSK_WITH_RC4_128_SHA, /* 0x008A */
+ "PSK-RC4-SHA",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF(TLS_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x008B */
+ "PSK-3DES-EDE-CBC-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF(TLS_PSK_WITH_AES_128_CBC_SHA, /* 0x008C */
+ "PSK-AES128-CBC-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_PSK_WITH_AES_256_CBC_SHA, /* 0x008D */
+ "PSK-AES256-CBC-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_RC4_128_SHA, /* 0x008E */
+ "DHE-PSK-RC4-SHA",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x008F */
+ "DHE-PSK-3DES-EDE-CBC-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_CBC_SHA, /* 0x0090 */
+ "DHE-PSK-AES128-CBC-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_CBC_SHA, /* 0x0091 */
+ "DHE-PSK-AES256-CBC-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_RC4_128_SHA, /* 0x0092 */
+ "RSA-PSK-RC4-SHA",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x0093 */
+ "RSA-PSK-3DES-EDE-CBC-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_CBC_SHA, /* 0x0094 */
+ "RSA-PSK-AES128-CBC-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_CBC_SHA, /* 0x0095 */
+ "RSA-PSK-AES256-CBC-SHA",
+ CIPHER_STRONG_ENOUGH),
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+ /* Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites
+ for TLS. */
+ CIPHER_DEF(TLS_RSA_WITH_AES_128_GCM_SHA256, /* 0x009C */
+ "AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_RSA_WITH_AES_256_GCM_SHA384, /* 0x009D */
+ "AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, /* 0x009E */
+ "DHE-RSA-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, /* 0x009F */
+ "DHE-RSA-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, /* 0x00A0 */
+ "DH-RSA-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, /* 0x00A1 */
+ "DH-RSA-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, /* 0x00A2 */
+ "DHE-DSS-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, /* 0x00A3 */
+ "DHE-DSS-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, /* 0x00A4 */
+ "DH-DSS-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, /* 0x00A5 */
+ "DH-DSS-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DH_anon_WITH_AES_128_GCM_SHA256, /* 0x00A6 */
+ "ADH-AES128-GCM-SHA256",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF(TLS_DH_anon_WITH_AES_256_GCM_SHA384, /* 0x00A7 */
+ "ADH-AES256-GCM-SHA384",
+ CIPHER_WEAK_ANON_AUTH),
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+ /* RFC 5487 - PSK with SHA-256/384 and AES GCM */
+ CIPHER_DEF(TLS_PSK_WITH_AES_128_GCM_SHA256, /* 0x00A8 */
+ "PSK-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_PSK_WITH_AES_256_GCM_SHA384, /* 0x00A9 */
+ "PSK-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, /* 0x00AA */
+ "DHE-PSK-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, /* 0x00AB */
+ "DHE-PSK-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, /* 0x00AC */
+ "RSA-PSK-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, /* 0x00AD */
+ "RSA-PSK-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_PSK_WITH_AES_128_CBC_SHA256, /* 0x00AE */
+ "PSK-AES128-CBC-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_PSK_WITH_AES_256_CBC_SHA384, /* 0x00AF */
+ "PSK-AES256-CBC-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_PSK_WITH_NULL_SHA256, /* 0x00B0 */
+ "PSK-NULL-SHA256",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_PSK_WITH_NULL_SHA384, /* 0x00B1 */
+ "PSK-NULL-SHA384",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, /* 0x00B2 */
+ "DHE-PSK-AES128-CBC-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, /* 0x00B3 */
+ "DHE-PSK-AES256-CBC-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA256, /* 0x00B4 */
+ "DHE-PSK-NULL-SHA256",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA384, /* 0x00B5 */
+ "DHE-PSK-NULL-SHA384",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, /* 0x00B6 */
+ "RSA-PSK-AES128-CBC-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, /* 0x00B7 */
+ "RSA-PSK-AES256-CBC-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA256, /* 0x00B8 */
+ "RSA-PSK-NULL-SHA256",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA384, /* 0x00B9 */
+ "RSA-PSK-NULL-SHA384",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+
+ /* RFC 5746 - Secure Renegotiation. This is not a real suite,
+ it is a response to initiate negotiation again */
+ CIPHER_DEF(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, /* 0x00FF */
+ NULL,
+ CIPHER_STRONG_ENOUGH),
+
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ /* TLS 1.3 standard cipher suites for ChaCha20+Poly1305.
+ Note: TLS 1.3 ciphersuites do not specify the key exchange
+ algorithm -- they only specify the symmetric ciphers.
+ Cipher alias name matches to OpenSSL cipher name, and for
+ TLS 1.3 ciphers */
+ CIPHER_DEF(TLS_AES_128_GCM_SHA256, /* 0x1301 */
+ NULL, /* The OpenSSL cipher name matches to the IANA name */
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_AES_256_GCM_SHA384, /* 0x1302 */
+ NULL, /* The OpenSSL cipher name matches to the IANA name */
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_CHACHA20_POLY1305_SHA256, /* 0x1303 */
+ NULL, /* The OpenSSL cipher name matches to the IANA name */
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_AES_128_CCM_SHA256, /* 0x1304 */
+ NULL, /* The OpenSSL cipher name matches to the IANA name */
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_AES_128_CCM_8_SHA256, /* 0x1305 */
+ NULL, /* The OpenSSL cipher name matches to the IANA name */
+ CIPHER_STRONG_ENOUGH),
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+
+#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
+ /* ECDSA addenda, RFC 4492 */
+ CIPHER_DEF(TLS_ECDH_ECDSA_WITH_NULL_SHA, /* 0xC001 */
+ "ECDH-ECDSA-NULL-SHA",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, /* 0xC002 */
+ "ECDH-ECDSA-RC4-SHA",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC003 */
+ "ECDH-ECDSA-DES-CBC3-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC004 */
+ "ECDH-ECDSA-AES128-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC005 */
+ "ECDH-ECDSA-AES256-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_NULL_SHA, /* 0xC006 */
+ "ECDHE-ECDSA-NULL-SHA",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, /* 0xC007 */
+ "ECDHE-ECDSA-RC4-SHA",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC008 */
+ "ECDHE-ECDSA-DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC009 */
+ "ECDHE-ECDSA-AES128-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC00A */
+ "ECDHE-ECDSA-AES256-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_RSA_WITH_NULL_SHA, /* 0xC00B */
+ "ECDH-RSA-NULL-SHA",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_ECDH_RSA_WITH_RC4_128_SHA, /* 0xC00C */
+ "ECDH-RSA-RC4-SHA",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC00D */
+ "ECDH-RSA-DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* 0xC00E */
+ "ECDH-RSA-AES128-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* 0xC00F */
+ "ECDH-RSA-AES256-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_NULL_SHA, /* 0xC010 */
+ "ECDHE-RSA-NULL-SHA",
+ CIPHER_WEAK_NOT_ENCRYPTED),
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_RC4_128_SHA, /* 0xC011 */
+ "ECDHE-RSA-RC4-SHA",
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC012 */
+ "ECDHE-RSA-DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* 0xC013 */
+ "ECDHE-RSA-AES128-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, /* 0xC014 */
+ "ECDHE-RSA-AES256-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_anon_WITH_NULL_SHA, /* 0xC015 */
+ "AECDH-NULL-SHA",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF(TLS_ECDH_anon_WITH_RC4_128_SHA, /* 0xC016 */
+ "AECDH-RC4-SHA",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, /* 0xC017 */
+ "AECDH-DES-CBC3-SHA",
+ CIPHER_WEAK_3DES_ENCRYPTION),
+ CIPHER_DEF(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, /* 0xC018 */
+ "AECDH-AES128-SHA",
+ CIPHER_WEAK_ANON_AUTH),
+ CIPHER_DEF(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, /* 0xC019 */
+ "AECDH-AES256-SHA",
+ CIPHER_WEAK_ANON_AUTH),
+#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+ /* Addenda from rfc 5289 Elliptic Curve Cipher Suites with
+ HMAC SHA-256/384. */
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC023 */
+ "ECDHE-ECDSA-AES128-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC024 */
+ "ECDHE-ECDSA-AES256-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC025 */
+ "ECDH-ECDSA-AES128-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC026 */
+ "ECDH-ECDSA-AES256-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, /* 0xC027 */
+ "ECDHE-RSA-AES128-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, /* 0xC028 */
+ "ECDHE-RSA-AES256-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, /* 0xC029 */
+ "ECDH-RSA-AES128-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, /* 0xC02A */
+ "ECDH-RSA-AES256-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ /* Addenda from rfc 5289 Elliptic Curve Cipher Suites with
+ SHA-256/384 and AES Galois Counter Mode (GCM) */
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02B */
+ "ECDHE-ECDSA-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02C */
+ "ECDHE-ECDSA-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02D */
+ "ECDH-ECDSA-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02E */
+ "ECDH-ECDSA-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, /* 0xC02F */
+ "ECDHE-RSA-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, /* 0xC030 */
+ "ECDHE-RSA-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, /* 0xC031 */
+ "ECDH-RSA-AES128-GCM-SHA256",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, /* 0xC032 */
+ "ECDH-RSA-AES256-GCM-SHA384",
+ CIPHER_STRONG_ENOUGH),
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+
+#if CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13
+ /* ECDHE_PSK Cipher Suites for Transport Layer Security (TLS), RFC 5489 */
+ CIPHER_DEF(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, /* 0xC035 */
+ "ECDHE-PSK-AES128-CBC-SHA",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, /* 0xC036 */
+ "ECDHE-PSK-AES256-CBC-SHA",
+ CIPHER_STRONG_ENOUGH),
+#endif /* CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 */
+
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ /* Addenda from rfc 7905 ChaCha20-Poly1305 Cipher Suites for
+ Transport Layer Security (TLS). */
+ CIPHER_DEF(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA8 */
+ "ECDHE-RSA-CHACHA20-POLY1305",
+ CIPHER_STRONG_ENOUGH),
+ CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA9 */
+ "ECDHE-ECDSA-CHACHA20-POLY1305",
+ CIPHER_STRONG_ENOUGH),
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+
+#if CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13
+ /* ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS),
+ RFC 7905 */
+ CIPHER_DEF(TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCAB */
+ "PSK-CHACHA20-POLY1305",
+ CIPHER_STRONG_ENOUGH),
+#endif /* CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 */
+
+ /* Tags for SSL 2 cipher kinds which are not specified for SSL 3.
+ Defined since SDK 10.2.8 */
+ CIPHER_DEF(SSL_RSA_WITH_RC2_CBC_MD5, /* 0xFF80 */
+ NULL,
+ CIPHER_WEAK_RC_ENCRYPTION),
+ CIPHER_DEF(SSL_RSA_WITH_IDEA_CBC_MD5, /* 0xFF81 */
+ NULL,
+ CIPHER_WEAK_IDEA_ENCRYPTION),
+ CIPHER_DEF(SSL_RSA_WITH_DES_CBC_MD5, /* 0xFF82 */
+ NULL,
+ CIPHER_WEAK_DES_ENCRYPTION),
+ CIPHER_DEF(SSL_RSA_WITH_3DES_EDE_CBC_MD5, /* 0xFF83 */
+ NULL,
+ CIPHER_WEAK_3DES_ENCRYPTION),
+};
+
+#define NUM_OF_CIPHERS sizeof(ciphertable)/sizeof(ciphertable[0])
+
+
/* pinned public key support tests */
/* version 1 supports macOS 10.12+ and iOS 10+ */
@@ -295,586 +929,23 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
}
#ifndef CURL_DISABLE_VERBOSE_STRINGS
-CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher)
-{
- switch(cipher) {
- /* SSL version 3.0 */
- case SSL_RSA_WITH_NULL_MD5:
- return "SSL_RSA_WITH_NULL_MD5";
- break;
- case SSL_RSA_WITH_NULL_SHA:
- return "SSL_RSA_WITH_NULL_SHA";
- break;
- case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
- return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
- break;
- case SSL_RSA_WITH_RC4_128_MD5:
- return "SSL_RSA_WITH_RC4_128_MD5";
- break;
- case SSL_RSA_WITH_RC4_128_SHA:
- return "SSL_RSA_WITH_RC4_128_SHA";
- break;
- case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
- return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
- break;
- case SSL_RSA_WITH_IDEA_CBC_SHA:
- return "SSL_RSA_WITH_IDEA_CBC_SHA";
- break;
- case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
- return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
- break;
- case SSL_RSA_WITH_DES_CBC_SHA:
- return "SSL_RSA_WITH_DES_CBC_SHA";
- break;
- case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
- return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
- return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
- break;
- case SSL_DH_DSS_WITH_DES_CBC_SHA:
- return "SSL_DH_DSS_WITH_DES_CBC_SHA";
- break;
- case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
- return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
- break;
- case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
- return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
- break;
- case SSL_DH_RSA_WITH_DES_CBC_SHA:
- return "SSL_DH_RSA_WITH_DES_CBC_SHA";
- break;
- case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
- return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
- return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
- break;
- case SSL_DHE_DSS_WITH_DES_CBC_SHA:
- return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
- break;
- case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
- return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
- break;
- case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
- return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
- break;
- case SSL_DHE_RSA_WITH_DES_CBC_SHA:
- return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
- break;
- case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
- return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
- break;
- case SSL_DH_anon_WITH_RC4_128_MD5:
- return "SSL_DH_anon_WITH_RC4_128_MD5";
- break;
- case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
- return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
- break;
- case SSL_DH_anon_WITH_DES_CBC_SHA:
- return "SSL_DH_anon_WITH_DES_CBC_SHA";
- break;
- case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
- return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
- break;
- case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
- return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
- break;
- case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
- return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
- break;
- /* TLS 1.0 with AES (RFC 3268)
- (Apparently these are used in SSLv3 implementations as well.) */
- case TLS_RSA_WITH_AES_128_CBC_SHA:
- return "TLS_RSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
- return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
- return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
- return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DH_anon_WITH_AES_128_CBC_SHA:
- return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
- break;
- case TLS_RSA_WITH_AES_256_CBC_SHA:
- return "TLS_RSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
- return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
- return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
- return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DH_anon_WITH_AES_256_CBC_SHA:
- return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
- break;
- /* SSL version 2.0 */
- case SSL_RSA_WITH_RC2_CBC_MD5:
- return "SSL_RSA_WITH_RC2_CBC_MD5";
- break;
- case SSL_RSA_WITH_IDEA_CBC_MD5:
- return "SSL_RSA_WITH_IDEA_CBC_MD5";
- break;
- case SSL_RSA_WITH_DES_CBC_MD5:
- return "SSL_RSA_WITH_DES_CBC_MD5";
- break;
- case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
- return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
- break;
- }
- return "SSL_NULL_WITH_NULL_NULL";
-}
-
CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
{
- switch(cipher) {
- /* TLS 1.0 with AES (RFC 3268) */
- case TLS_RSA_WITH_AES_128_CBC_SHA:
- return "TLS_RSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
- return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
- return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
- return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
- return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DH_anon_WITH_AES_128_CBC_SHA:
- return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
- break;
- case TLS_RSA_WITH_AES_256_CBC_SHA:
- return "TLS_RSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
- return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
- return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
- return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
- return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DH_anon_WITH_AES_256_CBC_SHA:
- return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
- break;
-#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
- /* TLS 1.0 with ECDSA (RFC 4492) */
- case TLS_ECDH_ECDSA_WITH_NULL_SHA:
- return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
- break;
- case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
- return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
- break;
- case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
- return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
- return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
- return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
- return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
- break;
- case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
- return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
- break;
- case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
- return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
- return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_ECDH_RSA_WITH_NULL_SHA:
- return "TLS_ECDH_RSA_WITH_NULL_SHA";
- break;
- case TLS_ECDH_RSA_WITH_RC4_128_SHA:
- return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
- break;
- case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
- return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
- return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
- return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_ECDHE_RSA_WITH_NULL_SHA:
- return "TLS_ECDHE_RSA_WITH_NULL_SHA";
- break;
- case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
- return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
- break;
- case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
- break;
- case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
- break;
- case TLS_ECDH_anon_WITH_NULL_SHA:
- return "TLS_ECDH_anon_WITH_NULL_SHA";
- break;
- case TLS_ECDH_anon_WITH_RC4_128_SHA:
- return "TLS_ECDH_anon_WITH_RC4_128_SHA";
- break;
- case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
- return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
- return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
- break;
- case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
- return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
- break;
-#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
-#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
- /* TLS 1.2 (RFC 5246) */
- case TLS_RSA_WITH_NULL_MD5:
- return "TLS_RSA_WITH_NULL_MD5";
- break;
- case TLS_RSA_WITH_NULL_SHA:
- return "TLS_RSA_WITH_NULL_SHA";
- break;
- case TLS_RSA_WITH_RC4_128_MD5:
- return "TLS_RSA_WITH_RC4_128_MD5";
- break;
- case TLS_RSA_WITH_RC4_128_SHA:
- return "TLS_RSA_WITH_RC4_128_SHA";
- break;
- case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
- return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_RSA_WITH_NULL_SHA256:
- return "TLS_RSA_WITH_NULL_SHA256";
- break;
- case TLS_RSA_WITH_AES_128_CBC_SHA256:
- return "TLS_RSA_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_RSA_WITH_AES_256_CBC_SHA256:
- return "TLS_RSA_WITH_AES_256_CBC_SHA256";
- break;
- case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
- return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
- return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
- return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
- return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
- return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
- return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
- return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
- return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
- break;
- case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
- return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
- break;
- case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
- return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
- break;
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
- break;
- case TLS_DH_anon_WITH_RC4_128_MD5:
- return "TLS_DH_anon_WITH_RC4_128_MD5";
- break;
- case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
- return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
- return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
- return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
- break;
- /* TLS 1.2 with AES GCM (RFC 5288) */
- case TLS_RSA_WITH_AES_128_GCM_SHA256:
- return "TLS_RSA_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_RSA_WITH_AES_256_GCM_SHA384:
- return "TLS_RSA_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
- return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
- return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
- return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
- return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
- return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
- return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
- return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
- return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
- return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
- break;
- /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
- case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
- return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
- return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
- break;
- case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
- return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
- return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
- break;
- case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
- return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
- return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
- break;
- case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
- return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
- return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
- break;
- case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
- return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
- return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
- return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
- return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
- return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
- return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
- return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
- break;
-#else
- case SSL_RSA_WITH_NULL_MD5:
- return "TLS_RSA_WITH_NULL_MD5";
- break;
- case SSL_RSA_WITH_NULL_SHA:
- return "TLS_RSA_WITH_NULL_SHA";
- break;
- case SSL_RSA_WITH_RC4_128_MD5:
- return "TLS_RSA_WITH_RC4_128_MD5";
- break;
- case SSL_RSA_WITH_RC4_128_SHA:
- return "TLS_RSA_WITH_RC4_128_SHA";
- break;
- case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
- return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
- break;
- case SSL_DH_anon_WITH_RC4_128_MD5:
- return "TLS_DH_anon_WITH_RC4_128_MD5";
- break;
- case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
- return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
- break;
-#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
-#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
- /* TLS PSK (RFC 4279): */
- case TLS_PSK_WITH_RC4_128_SHA:
- return "TLS_PSK_WITH_RC4_128_SHA";
- break;
- case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
- return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_PSK_WITH_AES_128_CBC_SHA:
- return "TLS_PSK_WITH_AES_128_CBC_SHA";
- break;
- case TLS_PSK_WITH_AES_256_CBC_SHA:
- return "TLS_PSK_WITH_AES_256_CBC_SHA";
- break;
- case TLS_DHE_PSK_WITH_RC4_128_SHA:
- return "TLS_DHE_PSK_WITH_RC4_128_SHA";
- break;
- case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
- return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
- return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
- break;
- case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
- return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
- break;
- case TLS_RSA_PSK_WITH_RC4_128_SHA:
- return "TLS_RSA_PSK_WITH_RC4_128_SHA";
- break;
- case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
- return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
- break;
- case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
- return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
- break;
- case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
- return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
- break;
- /* More TLS PSK (RFC 4785): */
- case TLS_PSK_WITH_NULL_SHA:
- return "TLS_PSK_WITH_NULL_SHA";
- break;
- case TLS_DHE_PSK_WITH_NULL_SHA:
- return "TLS_DHE_PSK_WITH_NULL_SHA";
- break;
- case TLS_RSA_PSK_WITH_NULL_SHA:
- return "TLS_RSA_PSK_WITH_NULL_SHA";
- break;
- /* Even more TLS PSK (RFC 5487): */
- case TLS_PSK_WITH_AES_128_GCM_SHA256:
- return "TLS_PSK_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_PSK_WITH_AES_256_GCM_SHA384:
- return "TLS_PSK_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
- return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
- return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
- return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
- break;
- case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
- return "TLS_PSK_WITH_AES_256_GCM_SHA384";
- break;
- case TLS_PSK_WITH_AES_128_CBC_SHA256:
- return "TLS_PSK_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_PSK_WITH_AES_256_CBC_SHA384:
- return "TLS_PSK_WITH_AES_256_CBC_SHA384";
- break;
- case TLS_PSK_WITH_NULL_SHA256:
- return "TLS_PSK_WITH_NULL_SHA256";
- break;
- case TLS_PSK_WITH_NULL_SHA384:
- return "TLS_PSK_WITH_NULL_SHA384";
- break;
- case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
- return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
- return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
- break;
- case TLS_DHE_PSK_WITH_NULL_SHA256:
- return "TLS_DHE_PSK_WITH_NULL_SHA256";
- break;
- case TLS_DHE_PSK_WITH_NULL_SHA384:
- return "TLS_RSA_PSK_WITH_NULL_SHA384";
- break;
- case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
- return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
- break;
- case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
- return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
- break;
- case TLS_RSA_PSK_WITH_NULL_SHA256:
- return "TLS_RSA_PSK_WITH_NULL_SHA256";
- break;
- case TLS_RSA_PSK_WITH_NULL_SHA384:
- return "TLS_RSA_PSK_WITH_NULL_SHA384";
- break;
-#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
-#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
- /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */
- case TLS_AES_128_GCM_SHA256:
- return "TLS_AES_128_GCM_SHA256";
- break;
- case TLS_AES_256_GCM_SHA384:
- return "TLS_AES_256_GCM_SHA384";
- break;
- case TLS_CHACHA20_POLY1305_SHA256:
- return "TLS_CHACHA20_POLY1305_SHA256";
- break;
- case TLS_AES_128_CCM_SHA256:
- return "TLS_AES_128_CCM_SHA256";
- break;
- case TLS_AES_128_CCM_8_SHA256:
- return "TLS_AES_128_CCM_8_SHA256";
- break;
- case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
- return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
- break;
- case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
- return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
- break;
-#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+ /* The first ciphers in the ciphertable are continuos. Here we do small
+ optimization and instead of loop directly get SSL name by cipher number.
+ */
+ if(cipher <= SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA) {
+ return ciphertable[cipher].name;
+ }
+ /* Iterate through the rest of the ciphers */
+ for(size_t i = SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA + 1;
+ i < NUM_OF_CIPHERS;
+ ++i) {
+ if(ciphertable[i].num == cipher) {
+ return ciphertable[i].name;
+ }
}
- return "TLS_NULL_WITH_NULL_NULL";
+ return ciphertable[SSL_NULL_WITH_NULL_NULL].name;
}
#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
@@ -1087,12 +1158,14 @@ static OSStatus CopyIdentityWithLabel(char *label,
(SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
err = SecIdentityCopyCertificate(identity, &cert);
if(err == noErr) {
+ OSStatus copy_status = noErr;
#if CURL_BUILD_IOS
common_name = SecCertificateCopySubjectSummary(cert);
#elif CURL_BUILD_MAC_10_7
- SecCertificateCopyCommonName(cert, &common_name);
+ copy_status = SecCertificateCopyCommonName(cert, &common_name);
#endif
- if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
+ if(copy_status == noErr &&
+ CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
CFRelease(cert);
CFRelease(common_name);
CFRetain(identity);
@@ -1253,7 +1326,7 @@ CF_INLINE bool is_file(const char *filename)
{
struct_stat st;
- if(filename == NULL)
+ if(!filename)
return false;
if(stat(filename, &st) == 0)
@@ -1386,6 +1459,200 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
return CURLE_SSL_CONNECT_ERROR;
}
+static bool is_cipher_suite_strong(SSLCipherSuite suite_num)
+{
+ for(size_t i = 0; i < NUM_OF_CIPHERS; ++i) {
+ if(ciphertable[i].num == suite_num) {
+ return !ciphertable[i].weak;
+ }
+ }
+ /* If the cipher is not in our list, assume it is a new one
+ and therefore strong. Previous implementation was the same,
+ if cipher suite is not in the list, it was considered strong enough */
+ return true;
+}
+
+static bool is_separator(char c)
+{
+ /* Return whether character is a cipher list separator. */
+ switch(c) {
+ case ' ':
+ case '\t':
+ case ':':
+ case ',':
+ case ';':
+ return true;
+ }
+ return false;
+}
+
+static CURLcode sectransp_set_default_ciphers(struct Curl_easy *data,
+ SSLContextRef ssl_ctx)
+{
+ size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
+ SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
+ OSStatus err = noErr;
+
+#if CURL_BUILD_MAC
+ int darwinver_maj = 0, darwinver_min = 0;
+
+ GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
+#endif /* CURL_BUILD_MAC */
+
+ /* Disable cipher suites that ST supports but are not safe. These ciphers
+ are unlikely to be used in any case since ST gives other ciphers a much
+ higher priority, but it's probably better that we not connect at all than
+ to give the user a false sense of security if the server only supports
+ insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
+ err = SSLGetNumberSupportedCiphers(ssl_ctx, &all_ciphers_count);
+ if(err != noErr) {
+ failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d",
+ err);
+ return CURLE_SSL_CIPHER;
+ }
+ all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+ if(!all_ciphers) {
+ failf(data, "SSL: Failed to allocate memory for all ciphers");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+ if(!allowed_ciphers) {
+ Curl_safefree(all_ciphers);
+ failf(data, "SSL: Failed to allocate memory for allowed ciphers");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ err = SSLGetSupportedCiphers(ssl_ctx, all_ciphers,
+ &all_ciphers_count);
+ if(err != noErr) {
+ Curl_safefree(all_ciphers);
+ Curl_safefree(allowed_ciphers);
+ return CURLE_SSL_CIPHER;
+ }
+ for(i = 0UL ; i < all_ciphers_count ; i++) {
+#if CURL_BUILD_MAC
+ /* There's a known bug in early versions of Mountain Lion where ST's ECC
+ ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
+ Work around the problem here by disabling those ciphers if we are
+ running in an affected version of OS X. */
+ if(darwinver_maj == 12 && darwinver_min <= 3 &&
+ all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
+ continue;
+ }
+#endif /* CURL_BUILD_MAC */
+ if(is_cipher_suite_strong(all_ciphers[i])) {
+ allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
+ }
+ }
+ err = SSLSetEnabledCiphers(ssl_ctx, allowed_ciphers,
+ allowed_ciphers_count);
+ Curl_safefree(all_ciphers);
+ Curl_safefree(allowed_ciphers);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
+ return CURLE_SSL_CIPHER;
+ }
+ return CURLE_OK;
+}
+
+static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data,
+ SSLContextRef ssl_ctx,
+ const char *ciphers)
+{
+ size_t ciphers_count = 0;
+ const char *cipher_start = ciphers;
+ OSStatus err = noErr;
+ SSLCipherSuite selected_ciphers[NUM_OF_CIPHERS];
+
+ if(!ciphers)
+ return CURLE_OK;
+
+ while(is_separator(*ciphers)) /* Skip initial separators. */
+ ciphers++;
+ if(!*ciphers)
+ return CURLE_OK;
+
+ cipher_start = ciphers;
+ while(*cipher_start && ciphers_count < NUM_OF_CIPHERS) {
+ bool cipher_found = FALSE;
+ size_t cipher_len = 0;
+ const char *cipher_end = NULL;
+ bool tls_name = FALSE;
+
+ /* Skip separators */
+ while(is_separator(*cipher_start))
+ cipher_start++;
+ if(*cipher_start == '\0') {
+ break;
+ }
+ /* Find last position of a cipher in the ciphers string */
+ cipher_end = cipher_start;
+ while (*cipher_end != '\0' && !is_separator(*cipher_end)) {
+ ++cipher_end;
+ }
+
+ /* IANA cipher names start with the TLS_ or SSL_ prefix.
+ If the 4th symbol of the cipher is '_' we look for a cipher in the
+ table by its (TLS) name.
+ Otherwise, we try to match cipher by an alias. */
+ if(cipher_start[3] == '_') {
+ tls_name = TRUE;
+ }
+ /* Iterate through the cipher table and look for the cipher, starting
+ the cipher number 0x01 because the 0x00 is not the real cipher */
+ cipher_len = cipher_end - cipher_start;
+ for(size_t i = 1; i < NUM_OF_CIPHERS; ++i) {
+ const char *table_cipher_name = NULL;
+ if(tls_name) {
+ table_cipher_name = ciphertable[i].name;
+ }
+ else if(ciphertable[i].alias_name != NULL) {
+ table_cipher_name = ciphertable[i].alias_name;
+ }
+ else {
+ continue;
+ }
+ /* Compare a part of the string between separators with a cipher name
+ in the table and make sure we matched the whole cipher name */
+ if(strncmp(cipher_start, table_cipher_name, cipher_len) == 0
+ && table_cipher_name[cipher_len] == '\0') {
+ selected_ciphers[ciphers_count] = ciphertable[i].num;
+ ++ciphers_count;
+ cipher_found = TRUE;
+ break;
+ }
+ }
+ if(!cipher_found) {
+ /* It would be more human-readable if we print the wrong cipher name
+ but we don't want to allocate any additional memory and copy the name
+ into it, then add it into logs.
+ Also, we do not modify an original cipher list string. We just point
+ to positions where cipher starts and ends in the cipher list string.
+ The message is a bit cryptic and longer than necessary but can be
+ understood by humans. */
+ failf(data, "SSL: cipher string \"%s\" contains unsupported cipher name"
+ " starting position %d and ending position %d",
+ ciphers,
+ cipher_start - ciphers,
+ cipher_end - ciphers);
+ return CURLE_SSL_CIPHER;
+ }
+ if(*cipher_end) {
+ cipher_start = cipher_end + 1;
+ }
+ else {
+ break;
+ }
+ }
+ /* All cipher suites in the list are found. Report to logs as-is */
+ infof(data, "SSL: Setting cipher suites list \"%s\"\n", ciphers);
+
+ err = SSLSetEnabledCiphers(ssl_ctx, selected_ciphers, ciphers_count);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
+ return CURLE_SSL_CIPHER;
+ }
+ return CURLE_OK;
+}
static CURLcode sectransp_connect_step1(struct Curl_easy *data,
struct connectdata *conn,
@@ -1394,28 +1661,22 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
curl_socket_t sockfd = conn->sock[sockindex];
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
- const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
- const struct curl_blob *ssl_cablob = NULL;
+ const struct curl_blob *ssl_cablob = SSL_CONN_CONFIG(ca_info_blob);
+ const char * const ssl_cafile =
+ /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
+ (ssl_cablob ? NULL : SSL_CONN_CONFIG(CAfile));
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
-#ifndef CURL_DISABLE_PROXY
bool isproxy = SSL_IS_PROXY();
- const char * const hostname = isproxy ? conn->http_proxy.host.name :
- conn->host.name;
- const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
-#else
- const isproxy = FALSE;
- const char * const hostname = conn->host.name;
- const long int port = conn->remote_port;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
+ const long int port = SSL_HOST_PORT();
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
struct in_addr addr;
#endif /* ENABLE_IPV6 */
- size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
- SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
+ char *ciphers;
OSStatus err = noErr;
#if CURL_BUILD_MAC
int darwinver_maj = 0, darwinver_min = 0;
@@ -1486,21 +1747,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
break;
}
case CURL_SSLVERSION_SSLv3:
- err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol3);
- if(err != noErr) {
- failf(data, "Your version of the OS does not support SSLv3");
- return CURLE_SSL_CONNECT_ERROR;
- }
- (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol3);
- break;
case CURL_SSLVERSION_SSLv2:
- err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol2);
- if(err != noErr) {
- failf(data, "Your version of the OS does not support SSLv2");
- return CURLE_SSL_CONNECT_ERROR;
- }
- (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol2);
- break;
+ failf(data, "SSL versions not supported");
+ return CURLE_NOT_BUILT_IN;
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
return CURLE_SSL_CONNECT_ERROR;
@@ -1535,23 +1784,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
break;
}
case CURL_SSLVERSION_SSLv3:
- err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
- kSSLProtocol3,
- true);
- if(err != noErr) {
- failf(data, "Your version of the OS does not support SSLv3");
- return CURLE_SSL_CONNECT_ERROR;
- }
- break;
case CURL_SSLVERSION_SSLv2:
- err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
- kSSLProtocol2,
- true);
- if(err != noErr) {
- failf(data, "Your version of the OS does not support SSLv2");
- return CURLE_SSL_CONNECT_ERROR;
- }
- break;
+ failf(data, "SSL versions not supported");
+ return CURLE_NOT_BUILT_IN;
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
return CURLE_SSL_CONNECT_ERROR;
@@ -1583,23 +1818,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
failf(data, "Your version of the OS does not support TLSv1.3");
return CURLE_SSL_CONNECT_ERROR;
case CURL_SSLVERSION_SSLv2:
- err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
- kSSLProtocol2,
- true);
- if(err != noErr) {
- failf(data, "Your version of the OS does not support SSLv2");
- return CURLE_SSL_CONNECT_ERROR;
- }
- break;
case CURL_SSLVERSION_SSLv3:
- err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
- kSSLProtocol3,
- true);
- if(err != noErr) {
- failf(data, "Your version of the OS does not support SSLv3");
- return CURLE_SSL_CONNECT_ERROR;
- }
- break;
+ failf(data, "SSL versions not supported");
+ return CURLE_NOT_BUILT_IN;
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
return CURLE_SSL_CONNECT_ERROR;
@@ -1612,14 +1833,14 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0,
&kCFTypeArrayCallBacks);
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
&& (!isproxy || !conn->bits.tunnel_proxy)
#endif
) {
- CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID));
- infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2));
+ infof(data, "ALPN, offering %s\n", ALPN_H2);
}
#endif
@@ -1790,7 +2011,8 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile);
if(!(is_cert_file || is_cert_data)) {
- failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
+ failf(data, "SSL: can't load CA certificate file %s",
+ ssl_cafile ? ssl_cafile : "(blob memory)");
return CURLE_SSL_CACERT_BADFILE;
}
}
@@ -1820,121 +2042,16 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
infof(data, "WARNING: disabling hostname validation also disables SNI.\n");
}
- /* Disable cipher suites that ST supports but are not safe. These ciphers
- are unlikely to be used in any case since ST gives other ciphers a much
- higher priority, but it's probably better that we not connect at all than
- to give the user a false sense of security if the server only supports
- insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
- err = SSLGetNumberSupportedCiphers(backend->ssl_ctx, &all_ciphers_count);
- if(err != noErr) {
- failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d",
- err);
- return CURLE_SSL_CIPHER;
- }
- all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
- if(!all_ciphers) {
- failf(data, "SSL: Failed to allocate memory for all ciphers");
- return CURLE_OUT_OF_MEMORY;
- }
- allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
- if(!allowed_ciphers) {
- Curl_safefree(all_ciphers);
- failf(data, "SSL: Failed to allocate memory for allowed ciphers");
- return CURLE_OUT_OF_MEMORY;
- }
- err = SSLGetSupportedCiphers(backend->ssl_ctx, all_ciphers,
- &all_ciphers_count);
- if(err != noErr) {
- Curl_safefree(all_ciphers);
- Curl_safefree(allowed_ciphers);
- return CURLE_SSL_CIPHER;
+ ciphers = SSL_CONN_CONFIG(cipher_list);
+ if(ciphers) {
+ err = sectransp_set_selected_ciphers(data, backend->ssl_ctx, ciphers);
}
- for(i = 0UL ; i < all_ciphers_count ; i++) {
-#if CURL_BUILD_MAC
- /* There's a known bug in early versions of Mountain Lion where ST's ECC
- ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
- Work around the problem here by disabling those ciphers if we are
- running in an affected version of OS X. */
- if(darwinver_maj == 12 && darwinver_min <= 3 &&
- all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
- continue;
- }
-#endif /* CURL_BUILD_MAC */
- switch(all_ciphers[i]) {
- /* Disable NULL ciphersuites: */
- case SSL_NULL_WITH_NULL_NULL:
- case SSL_RSA_WITH_NULL_MD5:
- case SSL_RSA_WITH_NULL_SHA:
- case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
- case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
- case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
- case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
- case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
- case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
- case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
- case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
- case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
- case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
- case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
- case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
- case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
- case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
- case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
- /* Disable anonymous ciphersuites: */
- case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
- case SSL_DH_anon_WITH_RC4_128_MD5:
- case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
- case SSL_DH_anon_WITH_DES_CBC_SHA:
- case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
- case TLS_DH_anon_WITH_AES_128_CBC_SHA:
- case TLS_DH_anon_WITH_AES_256_CBC_SHA:
- case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
- case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
- case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
- case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
- case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
- case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
- case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
- case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
- case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
- /* Disable weak key ciphersuites: */
- case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
- case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
- case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
- case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
- case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
- case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
- case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
- case SSL_RSA_WITH_DES_CBC_SHA:
- case SSL_DH_DSS_WITH_DES_CBC_SHA:
- case SSL_DH_RSA_WITH_DES_CBC_SHA:
- case SSL_DHE_DSS_WITH_DES_CBC_SHA:
- case SSL_DHE_RSA_WITH_DES_CBC_SHA:
- /* Disable IDEA: */
- case SSL_RSA_WITH_IDEA_CBC_SHA:
- case SSL_RSA_WITH_IDEA_CBC_MD5:
- /* Disable RC4: */
- case SSL_RSA_WITH_RC4_128_MD5:
- case SSL_RSA_WITH_RC4_128_SHA:
- case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
- case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/
- case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
- case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
- case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */
- case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */
- case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */
- break;
- default: /* enable everything else */
- allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
- break;
- }
+ else {
+ err = sectransp_set_default_ciphers(data, backend->ssl_ctx);
}
- err = SSLSetEnabledCiphers(backend->ssl_ctx, allowed_ciphers,
- allowed_ciphers_count);
- Curl_safefree(all_ciphers);
- Curl_safefree(allowed_ciphers);
if(err != noErr) {
- failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
+ failf(data, "SSL: Unable to set ciphers for SSL/TLS handshake. "
+ "Error code: %d", err);
return CURLE_SSL_CIPHER;
}
@@ -1972,7 +2089,8 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
else {
CURLcode result;
ssl_sessionid =
- aprintf("%s:%d:%d:%s:%ld", ssl_cafile,
+ aprintf("%s:%d:%d:%s:%ld",
+ ssl_cafile ? ssl_cafile : "(blob memory)",
verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
ssl_sessionid_len = strlen(ssl_sessionid);
@@ -2023,21 +2141,21 @@ static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
/* Jump through the separators at the beginning of the certificate. */
sep_start = strstr(in, "-----");
- if(sep_start == NULL)
+ if(!sep_start)
return 0;
cert_start = strstr(sep_start + 1, "-----");
- if(cert_start == NULL)
+ if(!cert_start)
return -1;
cert_start += 5;
/* Find separator after the end of the certificate. */
cert_end = strstr(cert_start, "-----");
- if(cert_end == NULL)
+ if(!cert_end)
return -1;
sep_end = strstr(cert_end + 1, "-----");
- if(sep_end == NULL)
+ if(!sep_end)
return -1;
sep_end += 5;
@@ -2112,7 +2230,7 @@ static int read_cert(const char *file, unsigned char **out, size_t *outlen)
}
static int append_cert_to_array(struct Curl_easy *data,
- unsigned char *buf, size_t buflen,
+ const unsigned char *buf, size_t buflen,
CFMutableArrayRef array)
{
CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
@@ -2150,18 +2268,14 @@ static int append_cert_to_array(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
- SSLContextRef ctx)
+static CURLcode verify_cert_buf(struct Curl_easy *data,
+ const unsigned char *certbuf, size_t buflen,
+ SSLContextRef ctx)
{
int n = 0, rc;
long res;
- unsigned char *certbuf, *der;
- size_t buflen, derlen, offset = 0;
-
- if(read_cert(cafile, &certbuf, &buflen) < 0) {
- failf(data, "SSL: failed to read or invalid CA certificate");
- return CURLE_SSL_CACERT_BADFILE;
- }
+ unsigned char *der;
+ size_t derlen, offset = 0;
/*
* Certbuf now contains the contents of the certificate file, which can be
@@ -2174,8 +2288,7 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
*/
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeArrayCallBacks);
- if(array == NULL) {
- free(certbuf);
+ if(!array) {
failf(data, "SSL: out of memory creating CA certificate array");
return CURLE_OUT_OF_MEMORY;
}
@@ -2189,7 +2302,6 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
*/
res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
if(res < 0) {
- free(certbuf);
CFRelease(array);
failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle",
n, offset);
@@ -2200,7 +2312,6 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
if(res == 0 && offset == 0) {
/* This is not a PEM file, probably a certificate in DER format. */
rc = append_cert_to_array(data, certbuf, buflen, array);
- free(certbuf);
if(rc != CURLE_OK) {
CFRelease(array);
return rc;
@@ -2209,14 +2320,12 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
}
else if(res == 0) {
/* No more certificates in the bundle. */
- free(certbuf);
break;
}
rc = append_cert_to_array(data, der, derlen, array);
free(der);
if(rc != CURLE_OK) {
- free(certbuf);
CFRelease(array);
return rc;
}
@@ -2224,7 +2333,7 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
SecTrustRef trust;
OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
- if(trust == NULL) {
+ if(!trust) {
failf(data, "SSL: error getting certificate chain");
CFRelease(array);
return CURLE_PEER_FAILED_VERIFICATION;
@@ -2273,6 +2382,38 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
}
}
+static CURLcode verify_cert(struct Curl_easy *data, const char *cafile,
+ const struct curl_blob *ca_info_blob,
+ SSLContextRef ctx)
+{
+ int result;
+ unsigned char *certbuf;
+ size_t buflen;
+
+ if(ca_info_blob) {
+ certbuf = (unsigned char *)malloc(ca_info_blob->len + 1);
+ if(!certbuf) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+ buflen = ca_info_blob->len;
+ memcpy(certbuf, ca_info_blob->data, ca_info_blob->len);
+ certbuf[ca_info_blob->len]='\0';
+ }
+ else if(cafile) {
+ if(read_cert(cafile, &certbuf, &buflen) < 0) {
+ failf(data, "SSL: failed to read or invalid CA certificate");
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ }
+ else
+ return CURLE_SSL_CACERT_BADFILE;
+
+ result = verify_cert_buf(data, certbuf, buflen, ctx);
+ free(certbuf);
+ return result;
+}
+
+
#ifdef SECTRANSP_PINNEDPUBKEY
static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
SSLContextRef ctx,
@@ -2297,19 +2438,19 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
do {
SecTrustRef trust;
OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
- if(ret != noErr || trust == NULL)
+ if(ret != noErr || !trust)
break;
SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
CFRelease(trust);
- if(keyRef == NULL)
+ if(!keyRef)
break;
#ifdef SECTRANSP_PINNEDPUBKEY_V1
publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL);
CFRelease(keyRef);
- if(publicKeyBits == NULL)
+ if(!publicKeyBits)
break;
#elif SECTRANSP_PINNEDPUBKEY_V2
@@ -2317,7 +2458,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL,
&publicKeyBits);
CFRelease(keyRef);
- if(success != errSecSuccess || publicKeyBits == NULL)
+ if(success != errSecSuccess || !publicKeyBits)
break;
#endif /* SECTRANSP_PINNEDPUBKEY_V2 */
@@ -2389,12 +2530,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
OSStatus err;
SSLCipherSuite cipher;
SSLProtocol protocol = 0;
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
-#else
- const char * const hostname = conn->host.name;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
@@ -2413,8 +2549,10 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* The below is errSSLServerAuthCompleted; it's not defined in
Leopard's headers */
case -9841:
- if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
- CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data,
+ if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
+ SSL_CONN_CONFIG(verifypeer)) {
+ CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
+ SSL_CONN_CONFIG(ca_info_blob),
backend->ssl_ctx);
if(result)
return result;
@@ -2601,8 +2739,9 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
#if CURL_BUILD_MAC_10_6
/* Only returned when kSSLSessionOptionBreakOnCertRequested is set */
case errSSLClientCertRequested:
- failf(data, "The server has requested a client certificate");
- break;
+ failf(data, "Server requested a client certificate during the "
+ "handshake");
+ return CURLE_SSL_CLIENTCERT;
#endif
#if CURL_BUILD_MAC_10_9
/* Alias for errSSLLast, end of error range */
@@ -2640,11 +2779,11 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
switch(protocol) {
case kSSLProtocol2:
infof(data, "SSL 2.0 connection using %s\n",
- SSLCipherNameForNumber(cipher));
+ TLSCipherNameForNumber(cipher));
break;
case kSSLProtocol3:
infof(data, "SSL 3.0 connection using %s\n",
- SSLCipherNameForNumber(cipher));
+ TLSCipherNameForNumber(cipher));
break;
case kTLSProtocol1:
infof(data, "TLS 1.0 connection using %s\n",
@@ -2681,10 +2820,9 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1)
chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0);
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
if(chosenProtocol &&
- !CFStringCompare(chosenProtocol, CFSTR(NGHTTP2_PROTO_VERSION_ID),
- 0)) {
+ !CFStringCompare(chosenProtocol, CFSTR(ALPN_H2), 0)) {
conn->negnpn = CURL_HTTP_VERSION_2;
}
else
@@ -3258,8 +3396,10 @@ static ssize_t sectransp_recv(struct Curl_easy *data,
/* The below is errSSLPeerAuthCompleted; it's not defined in
Leopard's headers */
case -9841:
- if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
- CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data,
+ if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
+ SSL_CONN_CONFIG(verifypeer)) {
+ CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
+ SSL_CONN_CONFIG(ca_info_blob),
backend->ssl_ctx);
if(result)
return result;
@@ -3286,6 +3426,7 @@ static void *sectransp_get_internals(struct ssl_connect_data *connssl,
const struct Curl_ssl Curl_ssl_sectransp = {
{ CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */
+ SSLSUPP_CAINFO_BLOB |
#ifdef SECTRANSP_PINNEDPUBKEY
SSLSUPP_PINNEDPUBKEY,
#else
@@ -3313,7 +3454,9 @@ const struct Curl_ssl Curl_ssl_sectransp = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
sectransp_false_start, /* false_start */
- sectransp_sha256sum /* sha256sum */
+ sectransp_sha256sum, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
#ifdef __clang__
diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c
index 2e07df0a04..65f4f773dd 100644
--- a/libs/libcurl/src/vtls/vtls.c
+++ b/libs/libcurl/src/vtls/vtls.c
@@ -135,6 +135,7 @@ Curl_ssl_config_matches(struct ssl_primary_config *data,
(data->verifyhost == needle->verifyhost) &&
(data->verifystatus == needle->verifystatus) &&
blobcmp(data->cert_blob, needle->cert_blob) &&
+ blobcmp(data->ca_info_blob, needle->ca_info_blob) &&
Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
Curl_safe_strcasecompare(data->CAfile, needle->CAfile) &&
Curl_safe_strcasecompare(data->clientcert, needle->clientcert) &&
@@ -161,6 +162,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
dest->sessionid = source->sessionid;
CLONE_BLOB(cert_blob);
+ CLONE_BLOB(ca_info_blob);
CLONE_STRING(CApath);
CLONE_STRING(CAfile);
CLONE_STRING(clientcert);
@@ -185,6 +187,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
Curl_safefree(sslc->cipher_list13);
Curl_safefree(sslc->pinned_key);
Curl_safefree(sslc->cert_blob);
+ Curl_safefree(sslc->ca_info_blob);
Curl_safefree(sslc->curves);
}
@@ -315,6 +318,8 @@ Curl_ssl_connect(struct Curl_easy *data, struct connectdata *conn,
if(!result)
Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */
+ else
+ conn->ssl[sockindex].use = FALSE;
return result;
}
@@ -338,7 +343,9 @@ Curl_ssl_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
/* mark this is being ssl requested from here on. */
conn->ssl[sockindex].use = TRUE;
result = Curl_ssl->connect_nonblocking(data, conn, sockindex, done);
- if(!result && *done)
+ if(result)
+ conn->ssl[sockindex].use = FALSE;
+ else if(*done)
Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */
return result;
}
@@ -579,6 +586,25 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
return CURLE_OK;
}
+void Curl_ssl_associate_conn(struct Curl_easy *data,
+ struct connectdata *conn)
+{
+ if(Curl_ssl->associate_connection) {
+ Curl_ssl->associate_connection(data, conn, FIRSTSOCKET);
+ if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted)
+ Curl_ssl->associate_connection(data, conn, SECONDARYSOCKET);
+ }
+}
+
+void Curl_ssl_detach_conn(struct Curl_easy *data,
+ struct connectdata *conn)
+{
+ if(Curl_ssl->disassociate_connection) {
+ Curl_ssl->disassociate_connection(data, FIRSTSOCKET);
+ if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted)
+ Curl_ssl->disassociate_connection(data, SECONDARYSOCKET);
+ }
+}
void Curl_ssl_close_all(struct Curl_easy *data)
{
@@ -1207,7 +1233,9 @@ static const struct Curl_ssl Curl_ssl_multi = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
- NULL /* sha256sum */
+ NULL, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
const struct Curl_ssl *Curl_ssl =
diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h
index 2b43e7744b..7f93e7aedb 100644
--- a/libs/libcurl/src/vtls/vtls.h
+++ b/libs/libcurl/src/vtls/vtls.h
@@ -32,6 +32,7 @@ struct ssl_connect_data;
#define SSLSUPP_SSL_CTX (1<<3) /* supports CURLOPT_SSL_CTX */
#define SSLSUPP_HTTPS_PROXY (1<<4) /* supports access via HTTPS proxies */
#define SSLSUPP_TLS13_CIPHERSUITES (1<<5) /* supports TLS 1.3 ciphersuites */
+#define SSLSUPP_CAINFO_BLOB (1<<6)
struct Curl_ssl {
/*
@@ -83,6 +84,11 @@ struct Curl_ssl {
bool (*false_start)(void);
CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen,
unsigned char *sha256sum, size_t sha256sumlen);
+
+ void (*associate_connection)(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex);
+ void (*disassociate_connection)(struct Curl_easy *data, int sockindex);
};
#ifdef USE_SSL
@@ -126,9 +132,11 @@ bool Curl_ssl_tls13_ciphersuites(void);
#define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */
#endif
-/* see https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */
+/* see https://www.iana.org/assignments/tls-extensiontype-values/ */
#define ALPN_HTTP_1_1_LENGTH 8
#define ALPN_HTTP_1_1 "http/1.1"
+#define ALPN_H2_LENGTH 2
+#define ALPN_H2 "h2"
/* set of helper macros for the backends to access the correct fields. For the
proxy or for the remote host - to properly support HTTPS proxy */
@@ -148,6 +156,8 @@ bool Curl_ssl_tls13_ciphersuites(void);
(SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name)
#define SSL_HOST_DISPNAME() \
(SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname)
+#define SSL_HOST_PORT() \
+ (SSL_IS_PROXY() ? conn->port : conn->remote_port)
#define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \
? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \
: data->set.str[STRING_SSL_PINNEDPUBLICKEY])
@@ -158,6 +168,7 @@ bool Curl_ssl_tls13_ciphersuites(void);
#define SSL_CONN_CONFIG(var) conn->ssl_config.var
#define SSL_HOST_NAME() conn->host.name
#define SSL_HOST_DISPNAME() conn->host.dispname
+#define SSL_HOST_PORT() conn->remote_port
#define SSL_PINNED_PUB_KEY() \
data->set.str[STRING_SSL_PINNEDPUBLICKEY]
#endif
@@ -277,6 +288,11 @@ bool Curl_ssl_cert_status_request(void);
bool Curl_ssl_false_start(void);
+void Curl_ssl_associate_conn(struct Curl_easy *data,
+ struct connectdata *conn);
+void Curl_ssl_detach_conn(struct Curl_easy *data,
+ struct connectdata *conn);
+
#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
#else /* if not USE_SSL */
@@ -303,6 +319,8 @@ bool Curl_ssl_false_start(void);
#define Curl_ssl_cert_status_request() FALSE
#define Curl_ssl_false_start() FALSE
#define Curl_ssl_tls13_ciphersuites() FALSE
+#define Curl_ssl_associate_conn(a,b) Curl_nop_stmt
+#define Curl_ssl_detach_conn(a,b) Curl_nop_stmt
#endif
#endif /* HEADER_CURL_VTLS_H */
diff --git a/libs/libcurl/src/vtls/wolfssl.c b/libs/libcurl/src/vtls/wolfssl.c
index c6f428034f..60e27e3662 100644
--- a/libs/libcurl/src/vtls/wolfssl.c
+++ b/libs/libcurl/src/vtls/wolfssl.c
@@ -47,16 +47,6 @@
#endif
#endif
-/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in
- options.h, but is only seen in >= 3.6.6 since that's when they started
- disabling SSLv3 by default. */
-#ifndef WOLFSSL_ALLOW_SSLV3
-#if (LIBWOLFSSL_VERSION_HEX < 0x03006006) || \
- defined(HAVE_WOLFSSLV3_CLIENT_METHOD)
-#define WOLFSSL_ALLOW_SSLV3
-#endif
-#endif
-
#include <limits.h>
#include "urldata.h"
@@ -285,18 +275,6 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
failf(data, "wolfSSL: TLS 1.3 is not yet supported");
return CURLE_SSL_CONNECT_ERROR;
#endif
- case CURL_SSLVERSION_SSLv3:
-#ifdef WOLFSSL_ALLOW_SSLV3
- req_method = SSLv3_client_method();
- use_sni(FALSE);
-#else
- failf(data, "wolfSSL does not support SSLv3");
- return CURLE_NOT_BUILT_IN;
-#endif
- break;
- case CURL_SSLVERSION_SSLv2:
- failf(data, "wolfSSL does not support SSLv2");
- return CURLE_SSL_CONNECT_ERROR;
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
return CURLE_SSL_CONNECT_ERROR;
@@ -418,12 +396,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#ifdef ENABLE_IPV6
struct in6_addr addr6;
#endif
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
-#else
- const char * const hostname = conn->host.name;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
size_t hostname_len = strlen(hostname);
if((hostname_len < USHRT_MAX) &&
(0 == Curl_inet_pton(AF_INET, hostname, &addr4)) &&
@@ -474,10 +447,10 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
/* wolfSSL's ALPN protocol name list format is a comma separated string of
protocols in descending order of preference, eg: "h2,http/1.1" */
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
- strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ",");
- infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ strcpy(protocols + strlen(protocols), ALPN_H2 ",");
+ infof(data, "ALPN, offering %s\n", ALPN_H2);
}
#endif
@@ -552,20 +525,9 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
int ret = -1;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
- const char * const dispname = SSL_IS_PROXY() ?
- conn->http_proxy.host.dispname : conn->host.dispname;
- const char * const pinnedpubkey = SSL_IS_PROXY() ?
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY];
-#else
- const char * const hostname = conn->host.name;
- const char * const dispname = conn->host.dispname;
- const char * const pinnedpubkey =
- data->set.str[STRING_SSL_PINNEDPUBLICKEY];
-#endif
+ const char * const hostname = SSL_HOST_NAME();
+ const char * const dispname = SSL_HOST_DISPNAME();
+ const char * const pinnedpubkey = SSL_PINNED_PUB_KEY();
conn->recv[sockindex] = wolfssl_recv;
conn->send[sockindex] = wolfssl_send;
@@ -725,11 +687,10 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
if(protocol_len == ALPN_HTTP_1_1_LENGTH &&
!memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
conn->negnpn = CURL_HTTP_VERSION_1_1;
-#ifdef USE_NGHTTP2
+#ifdef USE_HTTP2
else if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
- protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN &&
- !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID,
- NGHTTP2_PROTO_VERSION_ID_LEN))
+ protocol_len == ALPN_H2_LENGTH &&
+ !memcmp(protocol, ALPN_H2, ALPN_H2_LENGTH))
conn->negnpn = CURL_HTTP_VERSION_2;
#endif
else
@@ -820,7 +781,7 @@ static ssize_t wolfssl_send(struct Curl_easy *data,
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
int rc = SSL_write(backend->handle, mem, memlen);
- if(rc < 0) {
+ if(rc <= 0) {
int err = SSL_get_error(backend->handle, rc);
switch(err) {
@@ -1164,7 +1125,9 @@ const struct Curl_ssl Curl_ssl_wolfssl = {
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
- wolfssl_sha256sum /* sha256sum */
+ wolfssl_sha256sum, /* sha256sum */
+ NULL, /* associate_connection */
+ NULL /* disassociate_connection */
};
#endif
diff --git a/libs/libcurl/src/x509asn1.c b/libs/libcurl/src/x509asn1.c
index f29aa05b87..281c97248b 100644
--- a/libs/libcurl/src/x509asn1.c
+++ b/libs/libcurl/src/x509asn1.c
@@ -1145,10 +1145,8 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
int matched = -1;
size_t addrlen = (size_t) -1;
ssize_t len;
- const char *const hostname = SSL_IS_PROXY()?
- conn->http_proxy.host.name : conn->host.name;
- const char *const dispname = SSL_IS_PROXY()?
- conn->http_proxy.host.dispname : conn->host.dispname;
+ const char * const hostname = SSL_HOST_NAME();
+ const char * const dispname = SSL_HOST_DISPNAME();
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else