summaryrefslogtreecommitdiff
path: root/Utilities/cmcurl
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2022-10-31 16:11:41 -0400
committerBrad King <brad.king@kitware.com>2022-10-31 16:11:41 -0400
commit9ffe6b0969fc270cc2a1aac2b2c1bf986af291d5 (patch)
tree75711965f7fd24679383853a840f42efff676e31 /Utilities/cmcurl
parentfa9bbb8627e8af5153367721eb037b6e094670d1 (diff)
parentec122fff08ab9a8e56fb90126ecedb99c759011b (diff)
downloadcmake-9ffe6b0969fc270cc2a1aac2b2c1bf986af291d5.tar.gz
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2022-10-26 (cd95ee9f)
Diffstat (limited to 'Utilities/cmcurl')
-rw-r--r--Utilities/cmcurl/CMake/CMakeConfigurableFile.in4
-rw-r--r--Utilities/cmcurl/CMake/CurlSymbolHiding.cmake4
-rw-r--r--Utilities/cmcurl/CMake/CurlTests.c60
-rw-r--r--Utilities/cmcurl/CMake/FindBearSSL.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindBrotli.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindCARES.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindGSS.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindLibPSL.cmake45
-rw-r--r--Utilities/cmcurl/CMake/FindLibSSH2.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindMSH3.cmake2
-rw-r--r--Utilities/cmcurl/CMake/FindMbedTLS.cmake2
-rw-r--r--Utilities/cmcurl/CMake/FindNGHTTP2.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindNGHTTP3.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindNGTCP2.cmake6
-rw-r--r--Utilities/cmcurl/CMake/FindNSS.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindQUICHE.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindWolfSSL.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindZstd.cmake4
-rw-r--r--Utilities/cmcurl/CMake/Macros.cmake4
-rw-r--r--Utilities/cmcurl/CMake/OtherTests.cmake171
-rw-r--r--Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake41
-rw-r--r--Utilities/cmcurl/CMake/Utilities.cmake4
-rw-r--r--Utilities/cmcurl/CMake/cmake_uninstall.cmake.in4
-rw-r--r--Utilities/cmcurl/CMake/curl-config.cmake.in4
-rw-r--r--Utilities/cmcurl/CMakeLists.txt299
-rw-r--r--Utilities/cmcurl/include/curl/curl.h77
-rw-r--r--Utilities/cmcurl/include/curl/curlver.h10
-rw-r--r--Utilities/cmcurl/include/curl/easy.h4
-rw-r--r--Utilities/cmcurl/include/curl/header.h10
-rw-r--r--Utilities/cmcurl/include/curl/mprintf.h4
-rw-r--r--Utilities/cmcurl/include/curl/multi.h7
-rw-r--r--Utilities/cmcurl/include/curl/options.h4
-rw-r--r--Utilities/cmcurl/include/curl/stdcheaders.h4
-rw-r--r--Utilities/cmcurl/include/curl/system.h2
-rw-r--r--Utilities/cmcurl/include/curl/typecheck-gcc.h17
-rw-r--r--Utilities/cmcurl/include/curl/urlapi.h4
-rw-r--r--Utilities/cmcurl/include/curl/websockets.h83
-rw-r--r--Utilities/cmcurl/lib/CMakeLists.txt30
-rw-r--r--Utilities/cmcurl/lib/Makefile.inc17
-rw-r--r--Utilities/cmcurl/lib/altsvc.c62
-rw-r--r--Utilities/cmcurl/lib/altsvc.h4
-rw-r--r--Utilities/cmcurl/lib/amigaos.c212
-rw-r--r--Utilities/cmcurl/lib/amigaos.h18
-rw-r--r--Utilities/cmcurl/lib/arpa_telnet.h4
-rw-r--r--Utilities/cmcurl/lib/asyn-ares.c49
-rw-r--r--Utilities/cmcurl/lib/asyn-thread.c21
-rw-r--r--Utilities/cmcurl/lib/asyn.h6
-rw-r--r--Utilities/cmcurl/lib/base64.c80
-rw-r--r--Utilities/cmcurl/lib/bufref.c4
-rw-r--r--Utilities/cmcurl/lib/bufref.h4
-rw-r--r--Utilities/cmcurl/lib/c-hyper.c69
-rw-r--r--Utilities/cmcurl/lib/c-hyper.h5
-rw-r--r--Utilities/cmcurl/lib/conncache.c4
-rw-r--r--Utilities/cmcurl/lib/conncache.h3
-rw-r--r--Utilities/cmcurl/lib/connect.c85
-rw-r--r--Utilities/cmcurl/lib/connect.h4
-rw-r--r--Utilities/cmcurl/lib/content_encoding.c83
-rw-r--r--Utilities/cmcurl/lib/content_encoding.h7
-rw-r--r--Utilities/cmcurl/lib/cookie.c204
-rw-r--r--Utilities/cmcurl/lib/cookie.h25
-rw-r--r--Utilities/cmcurl/lib/curl_addrinfo.c6
-rw-r--r--Utilities/cmcurl/lib/curl_addrinfo.h4
-rw-r--r--Utilities/cmcurl/lib/curl_base64.h2
-rw-r--r--Utilities/cmcurl/lib/curl_config.h.cmake260
-rw-r--r--Utilities/cmcurl/lib/curl_ctype.c130
-rw-r--r--Utilities/cmcurl/lib/curl_ctype.h42
-rw-r--r--Utilities/cmcurl/lib/curl_des.c4
-rw-r--r--Utilities/cmcurl/lib/curl_des.h2
-rw-r--r--Utilities/cmcurl/lib/curl_endian.c4
-rw-r--r--Utilities/cmcurl/lib/curl_endian.h4
-rw-r--r--Utilities/cmcurl/lib/curl_fnmatch.c4
-rw-r--r--Utilities/cmcurl/lib/curl_fnmatch.h4
-rw-r--r--Utilities/cmcurl/lib/curl_get_line.c10
-rw-r--r--Utilities/cmcurl/lib/curl_get_line.h4
-rw-r--r--Utilities/cmcurl/lib/curl_gethostname.c4
-rw-r--r--Utilities/cmcurl/lib/curl_gethostname.h4
-rw-r--r--Utilities/cmcurl/lib/curl_gssapi.c14
-rw-r--r--Utilities/cmcurl/lib/curl_gssapi.h4
-rw-r--r--Utilities/cmcurl/lib/curl_hmac.h6
-rw-r--r--Utilities/cmcurl/lib/curl_krb5.h4
-rw-r--r--Utilities/cmcurl/lib/curl_ldap.h4
-rw-r--r--Utilities/cmcurl/lib/curl_md4.h4
-rw-r--r--Utilities/cmcurl/lib/curl_md5.h4
-rw-r--r--Utilities/cmcurl/lib/curl_memory.h4
-rw-r--r--Utilities/cmcurl/lib/curl_memrchr.c4
-rw-r--r--Utilities/cmcurl/lib/curl_memrchr.h4
-rw-r--r--Utilities/cmcurl/lib/curl_multibyte.c2
-rw-r--r--Utilities/cmcurl/lib/curl_multibyte.h4
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_core.c17
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_core.h6
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_wb.c6
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_wb.h4
-rw-r--r--Utilities/cmcurl/lib/curl_path.c5
-rw-r--r--Utilities/cmcurl/lib/curl_path.h4
-rw-r--r--Utilities/cmcurl/lib/curl_printf.h4
-rw-r--r--Utilities/cmcurl/lib/curl_range.c6
-rw-r--r--Utilities/cmcurl/lib/curl_range.h4
-rw-r--r--Utilities/cmcurl/lib/curl_rtmp.c6
-rw-r--r--Utilities/cmcurl/lib/curl_rtmp.h4
-rw-r--r--Utilities/cmcurl/lib/curl_sasl.c2
-rw-r--r--Utilities/cmcurl/lib/curl_sasl.h2
-rw-r--r--Utilities/cmcurl/lib/curl_setup.h58
-rw-r--r--Utilities/cmcurl/lib/curl_setup_once.h79
-rw-r--r--Utilities/cmcurl/lib/curl_sha256.h3
-rw-r--r--Utilities/cmcurl/lib/curl_sspi.c4
-rw-r--r--Utilities/cmcurl/lib/curl_sspi.h4
-rw-r--r--Utilities/cmcurl/lib/curl_threads.c4
-rw-r--r--Utilities/cmcurl/lib/curl_threads.h4
-rw-r--r--Utilities/cmcurl/lib/curlx.h4
-rw-r--r--Utilities/cmcurl/lib/dict.c2
-rw-r--r--Utilities/cmcurl/lib/dict.h4
-rw-r--r--Utilities/cmcurl/lib/doh.c21
-rw-r--r--Utilities/cmcurl/lib/doh.h51
-rw-r--r--Utilities/cmcurl/lib/dotdot.c182
-rw-r--r--Utilities/cmcurl/lib/dynbuf.c21
-rw-r--r--Utilities/cmcurl/lib/dynbuf.h10
-rw-r--r--Utilities/cmcurl/lib/easy.c136
-rw-r--r--Utilities/cmcurl/lib/easy_lock.h105
-rw-r--r--Utilities/cmcurl/lib/easygetopt.c4
-rw-r--r--Utilities/cmcurl/lib/easyif.h7
-rw-r--r--Utilities/cmcurl/lib/easyoptions.c20
-rw-r--r--Utilities/cmcurl/lib/easyoptions.h4
-rw-r--r--Utilities/cmcurl/lib/escape.c8
-rw-r--r--Utilities/cmcurl/lib/escape.h2
-rw-r--r--Utilities/cmcurl/lib/file.c31
-rw-r--r--Utilities/cmcurl/lib/file.h4
-rw-r--r--Utilities/cmcurl/lib/fileinfo.c4
-rw-r--r--Utilities/cmcurl/lib/fileinfo.h4
-rw-r--r--Utilities/cmcurl/lib/fopen.c113
-rw-r--r--Utilities/cmcurl/lib/fopen.h (renamed from Utilities/cmcurl/lib/vssh/wolfssh.h)13
-rw-r--r--Utilities/cmcurl/lib/formdata.c8
-rw-r--r--Utilities/cmcurl/lib/formdata.h4
-rw-r--r--Utilities/cmcurl/lib/ftp.c42
-rw-r--r--Utilities/cmcurl/lib/ftp.h7
-rw-r--r--Utilities/cmcurl/lib/ftplistparser.c8
-rw-r--r--Utilities/cmcurl/lib/ftplistparser.h4
-rw-r--r--Utilities/cmcurl/lib/functypes.h115
-rw-r--r--Utilities/cmcurl/lib/getenv.c4
-rw-r--r--Utilities/cmcurl/lib/getinfo.c22
-rw-r--r--Utilities/cmcurl/lib/getinfo.h4
-rw-r--r--Utilities/cmcurl/lib/gopher.c2
-rw-r--r--Utilities/cmcurl/lib/gopher.h4
-rw-r--r--Utilities/cmcurl/lib/h2h3.c7
-rw-r--r--Utilities/cmcurl/lib/h2h3.h2
-rw-r--r--Utilities/cmcurl/lib/hash.c4
-rw-r--r--Utilities/cmcurl/lib/hash.h4
-rw-r--r--Utilities/cmcurl/lib/headers.c72
-rw-r--r--Utilities/cmcurl/lib/headers.h4
-rw-r--r--Utilities/cmcurl/lib/hmac.c2
-rw-r--r--Utilities/cmcurl/lib/hostasyn.c4
-rw-r--r--Utilities/cmcurl/lib/hostip.c75
-rw-r--r--Utilities/cmcurl/lib/hostip.h6
-rw-r--r--Utilities/cmcurl/lib/hostip4.c10
-rw-r--r--Utilities/cmcurl/lib/hostip6.c10
-rw-r--r--Utilities/cmcurl/lib/hostsyn.c4
-rw-r--r--Utilities/cmcurl/lib/hsts.c33
-rw-r--r--Utilities/cmcurl/lib/hsts.h4
-rw-r--r--Utilities/cmcurl/lib/http.c201
-rw-r--r--Utilities/cmcurl/lib/http.h27
-rw-r--r--Utilities/cmcurl/lib/http2.c67
-rw-r--r--Utilities/cmcurl/lib/http2.h4
-rw-r--r--Utilities/cmcurl/lib/http_aws_sigv4.c542
-rw-r--r--Utilities/cmcurl/lib/http_aws_sigv4.h4
-rw-r--r--Utilities/cmcurl/lib/http_chunks.c7
-rw-r--r--Utilities/cmcurl/lib/http_chunks.h4
-rw-r--r--Utilities/cmcurl/lib/http_digest.c8
-rw-r--r--Utilities/cmcurl/lib/http_digest.h4
-rw-r--r--Utilities/cmcurl/lib/http_negotiate.c4
-rw-r--r--Utilities/cmcurl/lib/http_negotiate.h4
-rw-r--r--Utilities/cmcurl/lib/http_ntlm.c4
-rw-r--r--Utilities/cmcurl/lib/http_ntlm.h4
-rw-r--r--Utilities/cmcurl/lib/http_proxy.c12
-rw-r--r--Utilities/cmcurl/lib/http_proxy.h2
-rw-r--r--Utilities/cmcurl/lib/idn_win32.c10
-rw-r--r--Utilities/cmcurl/lib/if2ip.c2
-rw-r--r--Utilities/cmcurl/lib/if2ip.h2
-rw-r--r--Utilities/cmcurl/lib/imap.c20
-rw-r--r--Utilities/cmcurl/lib/imap.h4
-rw-r--r--Utilities/cmcurl/lib/inet_ntop.c4
-rw-r--r--Utilities/cmcurl/lib/inet_ntop.h4
-rw-r--r--Utilities/cmcurl/lib/inet_pton.c4
-rw-r--r--Utilities/cmcurl/lib/inet_pton.h4
-rw-r--r--Utilities/cmcurl/lib/krb5.c20
-rw-r--r--Utilities/cmcurl/lib/ldap.c28
-rw-r--r--Utilities/cmcurl/lib/libcurl.rc4
-rw-r--r--Utilities/cmcurl/lib/llist.c4
-rw-r--r--Utilities/cmcurl/lib/llist.h4
-rw-r--r--Utilities/cmcurl/lib/md4.c15
-rw-r--r--Utilities/cmcurl/lib/md5.c4
-rw-r--r--Utilities/cmcurl/lib/memdebug.c25
-rw-r--r--Utilities/cmcurl/lib/memdebug.h49
-rw-r--r--Utilities/cmcurl/lib/mime.c11
-rw-r--r--Utilities/cmcurl/lib/mime.h7
-rw-r--r--Utilities/cmcurl/lib/mprintf.c35
-rw-r--r--Utilities/cmcurl/lib/mqtt.c28
-rw-r--r--Utilities/cmcurl/lib/mqtt.h4
-rw-r--r--Utilities/cmcurl/lib/multi.c90
-rw-r--r--Utilities/cmcurl/lib/multihandle.h14
-rw-r--r--Utilities/cmcurl/lib/multiif.h7
-rw-r--r--Utilities/cmcurl/lib/netrc.c124
-rw-r--r--Utilities/cmcurl/lib/netrc.h12
-rw-r--r--Utilities/cmcurl/lib/nonblock.c2
-rw-r--r--Utilities/cmcurl/lib/nonblock.h4
-rw-r--r--Utilities/cmcurl/lib/noproxy.c222
-rw-r--r--Utilities/cmcurl/lib/noproxy.h (renamed from Utilities/cmcurl/lib/dotdot.h)29
-rw-r--r--Utilities/cmcurl/lib/openldap.c6
-rw-r--r--Utilities/cmcurl/lib/parsedate.c4
-rw-r--r--Utilities/cmcurl/lib/parsedate.h4
-rw-r--r--Utilities/cmcurl/lib/pingpong.c7
-rw-r--r--Utilities/cmcurl/lib/pingpong.h4
-rw-r--r--Utilities/cmcurl/lib/pop3.c2
-rw-r--r--Utilities/cmcurl/lib/pop3.h4
-rw-r--r--Utilities/cmcurl/lib/progress.c4
-rw-r--r--Utilities/cmcurl/lib/progress.h4
-rw-r--r--Utilities/cmcurl/lib/psl.c4
-rw-r--r--Utilities/cmcurl/lib/psl.h4
-rw-r--r--Utilities/cmcurl/lib/quic.h3
-rw-r--r--Utilities/cmcurl/lib/rand.c77
-rw-r--r--Utilities/cmcurl/lib/rand.h12
-rw-r--r--Utilities/cmcurl/lib/rename.c4
-rw-r--r--Utilities/cmcurl/lib/rename.h4
-rw-r--r--Utilities/cmcurl/lib/rtsp.c4
-rw-r--r--Utilities/cmcurl/lib/rtsp.h4
-rw-r--r--Utilities/cmcurl/lib/select.c14
-rw-r--r--Utilities/cmcurl/lib/select.h5
-rw-r--r--Utilities/cmcurl/lib/sendf.c75
-rw-r--r--Utilities/cmcurl/lib/sendf.h6
-rw-r--r--Utilities/cmcurl/lib/setopt.c245
-rw-r--r--Utilities/cmcurl/lib/setopt.h4
-rw-r--r--Utilities/cmcurl/lib/setup-os400.h4
-rw-r--r--Utilities/cmcurl/lib/setup-vms.h4
-rw-r--r--Utilities/cmcurl/lib/setup-win32.h19
-rw-r--r--Utilities/cmcurl/lib/sha256.c2
-rw-r--r--Utilities/cmcurl/lib/share.c6
-rw-r--r--Utilities/cmcurl/lib/share.h4
-rw-r--r--Utilities/cmcurl/lib/sigpipe.h4
-rw-r--r--Utilities/cmcurl/lib/slist.c4
-rw-r--r--Utilities/cmcurl/lib/slist.h4
-rw-r--r--Utilities/cmcurl/lib/smb.c4
-rw-r--r--Utilities/cmcurl/lib/smb.h6
-rw-r--r--Utilities/cmcurl/lib/smtp.c10
-rw-r--r--Utilities/cmcurl/lib/smtp.h8
-rw-r--r--Utilities/cmcurl/lib/sockaddr.h4
-rw-r--r--Utilities/cmcurl/lib/socketpair.c4
-rw-r--r--Utilities/cmcurl/lib/socketpair.h6
-rw-r--r--Utilities/cmcurl/lib/socks.c2
-rw-r--r--Utilities/cmcurl/lib/socks.h2
-rw-r--r--Utilities/cmcurl/lib/socks_gssapi.c8
-rw-r--r--Utilities/cmcurl/lib/socks_sspi.c6
-rw-r--r--Utilities/cmcurl/lib/speedcheck.c4
-rw-r--r--Utilities/cmcurl/lib/speedcheck.h4
-rw-r--r--Utilities/cmcurl/lib/splay.c8
-rw-r--r--Utilities/cmcurl/lib/splay.h4
-rw-r--r--Utilities/cmcurl/lib/strcase.c86
-rw-r--r--Utilities/cmcurl/lib/strcase.h4
-rw-r--r--Utilities/cmcurl/lib/strdup.c4
-rw-r--r--Utilities/cmcurl/lib/strdup.h4
-rw-r--r--Utilities/cmcurl/lib/strerror.c16
-rw-r--r--Utilities/cmcurl/lib/strerror.h4
-rw-r--r--Utilities/cmcurl/lib/strtok.c4
-rw-r--r--Utilities/cmcurl/lib/strtok.h4
-rw-r--r--Utilities/cmcurl/lib/strtoofft.c10
-rw-r--r--Utilities/cmcurl/lib/strtoofft.h4
-rw-r--r--Utilities/cmcurl/lib/system_win32.c4
-rw-r--r--Utilities/cmcurl/lib/system_win32.h4
-rw-r--r--Utilities/cmcurl/lib/telnet.c2
-rw-r--r--Utilities/cmcurl/lib/telnet.h4
-rw-r--r--Utilities/cmcurl/lib/tftp.c2
-rw-r--r--Utilities/cmcurl/lib/tftp.h4
-rw-r--r--Utilities/cmcurl/lib/timediff.c4
-rw-r--r--Utilities/cmcurl/lib/timediff.h2
-rw-r--r--Utilities/cmcurl/lib/timeval.c4
-rw-r--r--Utilities/cmcurl/lib/timeval.h2
-rw-r--r--Utilities/cmcurl/lib/transfer.c112
-rw-r--r--Utilities/cmcurl/lib/transfer.h2
-rw-r--r--Utilities/cmcurl/lib/url.c740
-rw-r--r--Utilities/cmcurl/lib/url.h5
-rw-r--r--Utilities/cmcurl/lib/urlapi-int.h10
-rw-r--r--Utilities/cmcurl/lib/urlapi.c904
-rw-r--r--Utilities/cmcurl/lib/urldata.h298
-rw-r--r--Utilities/cmcurl/lib/vauth/cleartext.c4
-rw-r--r--Utilities/cmcurl/lib/vauth/cram.c4
-rw-r--r--Utilities/cmcurl/lib/vauth/digest.c185
-rw-r--r--Utilities/cmcurl/lib/vauth/digest.h13
-rw-r--r--Utilities/cmcurl/lib/vauth/digest_sspi.c16
-rw-r--r--Utilities/cmcurl/lib/vauth/gsasl.c7
-rw-r--r--Utilities/cmcurl/lib/vauth/krb5_gssapi.c4
-rw-r--r--Utilities/cmcurl/lib/vauth/krb5_sspi.c4
-rw-r--r--Utilities/cmcurl/lib/vauth/ntlm.c17
-rw-r--r--Utilities/cmcurl/lib/vauth/ntlm.h7
-rw-r--r--Utilities/cmcurl/lib/vauth/ntlm_sspi.c4
-rw-r--r--Utilities/cmcurl/lib/vauth/oauth2.c4
-rw-r--r--Utilities/cmcurl/lib/vauth/spnego_gssapi.c2
-rw-r--r--Utilities/cmcurl/lib/vauth/spnego_sspi.c2
-rw-r--r--Utilities/cmcurl/lib/vauth/vauth.c21
-rw-r--r--Utilities/cmcurl/lib/vauth/vauth.h10
-rw-r--r--Utilities/cmcurl/lib/version.c19
-rw-r--r--Utilities/cmcurl/lib/version_win32.c2
-rw-r--r--Utilities/cmcurl/lib/version_win32.h4
-rw-r--r--Utilities/cmcurl/lib/vquic/msh3.c58
-rw-r--r--Utilities/cmcurl/lib/vquic/msh3.h2
-rw-r--r--Utilities/cmcurl/lib/vquic/ngtcp2.c855
-rw-r--r--Utilities/cmcurl/lib/vquic/ngtcp2.h36
-rw-r--r--Utilities/cmcurl/lib/vquic/quiche.c68
-rw-r--r--Utilities/cmcurl/lib/vquic/quiche.h4
-rw-r--r--Utilities/cmcurl/lib/vquic/vquic.c2
-rw-r--r--Utilities/cmcurl/lib/vquic/vquic.h2
-rw-r--r--Utilities/cmcurl/lib/vssh/libssh.c60
-rw-r--r--Utilities/cmcurl/lib/vssh/libssh2.c127
-rw-r--r--Utilities/cmcurl/lib/vssh/ssh.h12
-rw-r--r--Utilities/cmcurl/lib/vssh/wolfssh.c2
-rw-r--r--Utilities/cmcurl/lib/vtls/bearssl.c34
-rw-r--r--Utilities/cmcurl/lib/vtls/bearssl.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/gskit.c2
-rw-r--r--Utilities/cmcurl/lib/vtls/gskit.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/gtls.c11
-rw-r--r--Utilities/cmcurl/lib/vtls/gtls.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/hostcheck.c2
-rw-r--r--Utilities/cmcurl/lib/vtls/hostcheck.h2
-rw-r--r--Utilities/cmcurl/lib/vtls/keylog.c5
-rw-r--r--Utilities/cmcurl/lib/vtls/keylog.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/mbedtls.c8
-rw-r--r--Utilities/cmcurl/lib/vtls/mbedtls.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/mbedtls_threadlock.c4
-rw-r--r--Utilities/cmcurl/lib/vtls/mbedtls_threadlock.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/nss.c32
-rw-r--r--Utilities/cmcurl/lib/vtls/nssg.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.c820
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.h5
-rw-r--r--Utilities/cmcurl/lib/vtls/rustls.c8
-rw-r--r--Utilities/cmcurl/lib/vtls/rustls.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel.c515
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel.h94
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel_verify.c2
-rw-r--r--Utilities/cmcurl/lib/vtls/sectransp.c10
-rw-r--r--Utilities/cmcurl/lib/vtls/sectransp.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls.c28
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls.h7
-rw-r--r--Utilities/cmcurl/lib/vtls/wolfssl.c26
-rw-r--r--Utilities/cmcurl/lib/vtls/wolfssl.h4
-rw-r--r--Utilities/cmcurl/lib/vtls/x509asn1.c7
-rw-r--r--Utilities/cmcurl/lib/vtls/x509asn1.h2
-rw-r--r--Utilities/cmcurl/lib/warnless.c4
-rw-r--r--Utilities/cmcurl/lib/warnless.h2
-rw-r--r--Utilities/cmcurl/lib/wildcard.c4
-rw-r--r--Utilities/cmcurl/lib/wildcard.h5
-rw-r--r--Utilities/cmcurl/lib/ws.c757
-rw-r--r--Utilities/cmcurl/lib/ws.h69
348 files changed, 8246 insertions, 4295 deletions
diff --git a/Utilities/cmcurl/CMake/CMakeConfigurableFile.in b/Utilities/cmcurl/CMake/CMakeConfigurableFile.in
index 8ccd016a67..b93e7539a1 100644
--- a/Utilities/cmcurl/CMake/CMakeConfigurableFile.in
+++ b/Utilities/cmcurl/CMake/CMakeConfigurableFile.in
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,5 +18,7 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
@CMAKE_CONFIGURABLE_FILE_CONTENT@
diff --git a/Utilities/cmcurl/CMake/CurlSymbolHiding.cmake b/Utilities/cmcurl/CMake/CurlSymbolHiding.cmake
index e99ea6f648..75215a122f 100644
--- a/Utilities/cmcurl/CMake/CurlSymbolHiding.cmake
+++ b/Utilities/cmcurl/CMake/CurlSymbolHiding.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
include(CheckCSourceCompiles)
diff --git a/Utilities/cmcurl/CMake/CurlTests.c b/Utilities/cmcurl/CMake/CurlTests.c
index 42addd7185..6a9fdea098 100644
--- a/Utilities/cmcurl/CMake/CurlTests.c
+++ b/Utilities/cmcurl/CMake/CurlTests.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifdef TIME_WITH_SYS_TIME
/* Time with sys/time test */
@@ -182,28 +184,6 @@ if (sizeof (bool *) )
#include <float.h>
int main() { return 0; }
#endif
-#ifdef HAVE_GETADDRINFO
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-int main(void) {
- struct addrinfo hints, *ai;
- int error;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-#ifndef getaddrinfo
- (void)getaddrinfo;
-#endif
- error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
- if (error) {
- return 1;
- }
- return 0;
-}
-#endif
#ifdef HAVE_FILE_OFFSET_BITS
#ifdef _FILE_OFFSET_BITS
#undef _FILE_OFFSET_BITS
@@ -514,3 +494,39 @@ main() {
return 0;
}
#endif
+#ifdef HAVE_ATOMIC
+/* includes start */
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_STDATOMIC_H
+# include <stdatomic.h>
+#endif
+/* includes end */
+
+int
+main() {
+ _Atomic int i = 1;
+ i = 0; // Force an atomic-write operation.
+ return i;
+}
+#endif
+#ifdef HAVE_WIN32_WINNT
+/* includes start */
+#ifdef WIN32
+# include "../lib/setup-win32.h"
+#endif
+/* includes end */
+
+#define enquote(x) #x
+#define expand(x) enquote(x)
+#pragma message("_WIN32_WINNT=" expand(_WIN32_WINNT))
+
+int
+main() {
+ return 0;
+}
+#endif
diff --git a/Utilities/cmcurl/CMake/FindBearSSL.cmake b/Utilities/cmcurl/CMake/FindBearSSL.cmake
index 9455f4ba30..88d5e87ade 100644
--- a/Utilities/cmcurl/CMake/FindBearSSL.cmake
+++ b/Utilities/cmcurl/CMake/FindBearSSL.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
find_path(BEARSSL_INCLUDE_DIRS bearssl.h)
diff --git a/Utilities/cmcurl/CMake/FindBrotli.cmake b/Utilities/cmcurl/CMake/FindBrotli.cmake
index 0ed08550d2..833e1811ae 100644
--- a/Utilities/cmcurl/CMake/FindBrotli.cmake
+++ b/Utilities/cmcurl/CMake/FindBrotli.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
include(FindPackageHandleStandardArgs)
diff --git a/Utilities/cmcurl/CMake/FindCARES.cmake b/Utilities/cmcurl/CMake/FindCARES.cmake
index 71806823d2..99cf31d913 100644
--- a/Utilities/cmcurl/CMake/FindCARES.cmake
+++ b/Utilities/cmcurl/CMake/FindCARES.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
# - Find c-ares
# Find the c-ares includes and library
diff --git a/Utilities/cmcurl/CMake/FindGSS.cmake b/Utilities/cmcurl/CMake/FindGSS.cmake
index 4e4747d6cc..ec2bd57bae 100644
--- a/Utilities/cmcurl/CMake/FindGSS.cmake
+++ b/Utilities/cmcurl/CMake/FindGSS.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
# - Try to find the GSS Kerberos library
# Once done this will define
diff --git a/Utilities/cmcurl/CMake/FindLibPSL.cmake b/Utilities/cmcurl/CMake/FindLibPSL.cmake
new file mode 100644
index 0000000000..66abdd79a3
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindLibPSL.cmake
@@ -0,0 +1,45 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+# - Try to find the libpsl library
+# Once done this will define
+#
+# LIBPSL_FOUND - system has the libpsl library
+# LIBPSL_INCLUDE_DIR - the libpsl include directory
+# LIBPSL_LIBRARY - the libpsl library name
+
+find_path(LIBPSL_INCLUDE_DIR libpsl.h)
+
+find_library(LIBPSL_LIBRARY NAMES psl libpsl)
+
+if(LIBPSL_INCLUDE_DIR)
+ file(STRINGS "${LIBPSL_INCLUDE_DIR}/libpsl.h" libpsl_version_str REGEX "^#define[\t ]+PSL_VERSION[\t ]+\"(.*)\"")
+ string(REGEX REPLACE "^.*\"([^\"]+)\"" "\\1" LIBPSL_VERSION "${libpsl_version_str}")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibPSL
+ REQUIRED_VARS LIBPSL_LIBRARY LIBPSL_INCLUDE_DIR
+ VERSION_VAR LIBPSL_VERSION)
+
+mark_as_advanced(LIBPSL_INCLUDE_DIR LIBPSL_LIBRARY)
diff --git a/Utilities/cmcurl/CMake/FindLibSSH2.cmake b/Utilities/cmcurl/CMake/FindLibSSH2.cmake
index ce46a408bf..0ec7f7e3b9 100644
--- a/Utilities/cmcurl/CMake/FindLibSSH2.cmake
+++ b/Utilities/cmcurl/CMake/FindLibSSH2.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
# - Try to find the libssh2 library
# Once done this will define
diff --git a/Utilities/cmcurl/CMake/FindMSH3.cmake b/Utilities/cmcurl/CMake/FindMSH3.cmake
index 1b8b9d83a2..96477e2828 100644
--- a/Utilities/cmcurl/CMake/FindMSH3.cmake
+++ b/Utilities/cmcurl/CMake/FindMSH3.cmake
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
#[=======================================================================[.rst:
diff --git a/Utilities/cmcurl/CMake/FindMbedTLS.cmake b/Utilities/cmcurl/CMake/FindMbedTLS.cmake
index 7bdb1976d0..fcd6717f6f 100644
--- a/Utilities/cmcurl/CMake/FindMbedTLS.cmake
+++ b/Utilities/cmcurl/CMake/FindMbedTLS.cmake
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
diff --git a/Utilities/cmcurl/CMake/FindNGHTTP2.cmake b/Utilities/cmcurl/CMake/FindNGHTTP2.cmake
index 8614492b10..6d70c4a049 100644
--- a/Utilities/cmcurl/CMake/FindNGHTTP2.cmake
+++ b/Utilities/cmcurl/CMake/FindNGHTTP2.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
include(FindPackageHandleStandardArgs)
diff --git a/Utilities/cmcurl/CMake/FindNGHTTP3.cmake b/Utilities/cmcurl/CMake/FindNGHTTP3.cmake
index 643b600972..8d8ebc1b1e 100644
--- a/Utilities/cmcurl/CMake/FindNGHTTP3.cmake
+++ b/Utilities/cmcurl/CMake/FindNGHTTP3.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
#[=======================================================================[.rst:
diff --git a/Utilities/cmcurl/CMake/FindNGTCP2.cmake b/Utilities/cmcurl/CMake/FindNGTCP2.cmake
index 5757009a56..61e54c2d67 100644
--- a/Utilities/cmcurl/CMake/FindNGTCP2.cmake
+++ b/Utilities/cmcurl/CMake/FindNGTCP2.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
#[=======================================================================[.rst:
@@ -69,7 +71,7 @@ endif()
if(NGTCP2_FIND_COMPONENTS)
set(NGTCP2_CRYPTO_BACKEND "")
foreach(component IN LISTS NGTCP2_FIND_COMPONENTS)
- if(component MATCHES "^(OpenSSL|GnuTLS)")
+ if(component MATCHES "^(BoringSSL|OpenSSL|GnuTLS)")
if(NGTCP2_CRYPTO_BACKEND)
message(FATAL_ERROR "NGTCP2: Only one crypto library can be selected")
endif()
diff --git a/Utilities/cmcurl/CMake/FindNSS.cmake b/Utilities/cmcurl/CMake/FindNSS.cmake
index 899c6b0756..6742dda83f 100644
--- a/Utilities/cmcurl/CMake/FindNSS.cmake
+++ b/Utilities/cmcurl/CMake/FindNSS.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
if(UNIX)
find_package(PkgConfig QUIET)
diff --git a/Utilities/cmcurl/CMake/FindQUICHE.cmake b/Utilities/cmcurl/CMake/FindQUICHE.cmake
index 0247364d41..fc47027d74 100644
--- a/Utilities/cmcurl/CMake/FindQUICHE.cmake
+++ b/Utilities/cmcurl/CMake/FindQUICHE.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
#[=======================================================================[.rst:
diff --git a/Utilities/cmcurl/CMake/FindWolfSSL.cmake b/Utilities/cmcurl/CMake/FindWolfSSL.cmake
index 42256b3cd1..986f01e00e 100644
--- a/Utilities/cmcurl/CMake/FindWolfSSL.cmake
+++ b/Utilities/cmcurl/CMake/FindWolfSSL.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
find_path(WolfSSL_INCLUDE_DIR NAMES wolfssl/ssl.h)
find_library(WolfSSL_LIBRARY NAMES wolfssl)
diff --git a/Utilities/cmcurl/CMake/FindZstd.cmake b/Utilities/cmcurl/CMake/FindZstd.cmake
index eaba39746f..2d6540443c 100644
--- a/Utilities/cmcurl/CMake/FindZstd.cmake
+++ b/Utilities/cmcurl/CMake/FindZstd.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
#[=======================================================================[.rst:
diff --git a/Utilities/cmcurl/CMake/Macros.cmake b/Utilities/cmcurl/CMake/Macros.cmake
index d57dd6ad57..4d7380eb5f 100644
--- a/Utilities/cmcurl/CMake/Macros.cmake
+++ b/Utilities/cmcurl/CMake/Macros.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
#File defines convenience macros for available feature testing
diff --git a/Utilities/cmcurl/CMake/OtherTests.cmake b/Utilities/cmcurl/CMake/OtherTests.cmake
index 0421c1c34c..b3031f749d 100644
--- a/Utilities/cmcurl/CMake/OtherTests.cmake
+++ b/Utilities/cmcurl/CMake/OtherTests.cmake
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
include(CheckCSourceCompiles)
# The begin of the sources (macros and includes)
@@ -46,175 +48,6 @@ endif()
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
-if(1) # CMake hard-codes these
- set(RECV_TYPE_ARG1 "curl_socket_t")
- set(RECV_TYPE_ARG2 "char *")
- set(RECV_TYPE_ARG3 "size_t")
- set(RECV_TYPE_ARG4 "int")
- set(RECV_TYPE_RETV "ssize_t")
-else()
-function(curl_cv_func_recv_run_test recv_retv recv_arg1 recv_arg2 recv_arg3 recv_arg4)
- unset(curl_cv_func_recv_test CACHE)
- check_c_source_compiles("
- ${_source_epilogue}
- #ifdef WINSOCK_API_LINKAGE
- WINSOCK_API_LINKAGE
- #endif
- extern ${recv_retv} ${signature_call_conv}
- recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
- int main(void) {
- ${recv_arg1} s=0;
- ${recv_arg2} buf=0;
- ${recv_arg3} len=0;
- ${recv_arg4} flags=0;
- ${recv_retv} res = recv(s, buf, len, flags);
- (void) res;
- return 0;
- }"
- curl_cv_func_recv_test)
- message(STATUS
- "Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
- if(curl_cv_func_recv_test)
- set(curl_cv_func_recv_args
- "${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}" PARENT_SCOPE)
- set(RECV_TYPE_ARG1 "${recv_arg1}" PARENT_SCOPE)
- set(RECV_TYPE_ARG2 "${recv_arg2}" PARENT_SCOPE)
- set(RECV_TYPE_ARG3 "${recv_arg3}" PARENT_SCOPE)
- set(RECV_TYPE_ARG4 "${recv_arg4}" PARENT_SCOPE)
- set(RECV_TYPE_RETV "${recv_retv}" PARENT_SCOPE)
- set(HAVE_RECV 1 PARENT_SCOPE)
- set(curl_cv_func_recv_done 1 PARENT_SCOPE)
- endif()
-endfunction()
-
-check_c_source_compiles("${_source_epilogue}
-int main(void) {
- recv(0, 0, 0, 0);
- return 0;
-}" curl_cv_recv)
-if(curl_cv_recv)
- if(NOT DEFINED curl_cv_func_recv_args OR curl_cv_func_recv_args STREQUAL "unknown")
- if(APPLE)
- curl_cv_func_recv_run_test("ssize_t" "int" "void *" "size_t" "int")
- endif()
- foreach(recv_retv "int" "ssize_t" )
- foreach(recv_arg1 "SOCKET" "int" )
- foreach(recv_arg2 "char *" "void *" )
- foreach(recv_arg3 "int" "size_t" "socklen_t" "unsigned int")
- foreach(recv_arg4 "int" "unsigned int")
- if(NOT curl_cv_func_recv_done)
- curl_cv_func_recv_run_test(${recv_retv} ${recv_arg1} ${recv_arg2} ${recv_arg3} ${recv_arg4})
- endif()
- endforeach()
- endforeach()
- endforeach()
- endforeach()
- endforeach()
- else()
- string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
- string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
- string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}")
- string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}")
- string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
- endif()
-
- if(curl_cv_func_recv_args STREQUAL "unknown")
- message(FATAL_ERROR "Cannot find proper types to use for recv args")
- endif()
-else()
- message(FATAL_ERROR "Unable to link function recv")
-endif()
-set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
-endif()
-set(HAVE_RECV 1)
-
-if(1) # CMake hard-codes these
- set(SEND_QUAL_ARG2 " ")
- set(SEND_TYPE_ARG1 "curl_socket_t")
- set(SEND_TYPE_ARG2 "char *")
- set(SEND_TYPE_ARG3 "size_t")
- set(SEND_TYPE_ARG4 "int")
- set(SEND_TYPE_RETV "ssize_t")
-else()
-function(curl_cv_func_send_run_test send_retv send_arg1 send_arg2 send_arg3 send_arg4)
- unset(curl_cv_func_send_test CACHE)
- check_c_source_compiles("
- ${_source_epilogue}
- #ifdef WINSOCK_API_LINKAGE
- WINSOCK_API_LINKAGE
- #endif
- extern ${send_retv} ${signature_call_conv}
- send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
- int main(void) {
- ${send_arg1} s=0;
- ${send_arg2} buf=0;
- ${send_arg3} len=0;
- ${send_arg4} flags=0;
- ${send_retv} res = send(s, buf, len, flags);
- (void) res;
- return 0;
- }"
- curl_cv_func_send_test)
- message(STATUS
- "Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
- if(curl_cv_func_send_test)
- string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
- string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
- set(curl_cv_func_send_args
- "${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}" PARENT_SCOPE)
- set(SEND_TYPE_ARG1 "${send_arg1}" PARENT_SCOPE)
- set(SEND_TYPE_ARG2 "${send_arg2}" PARENT_SCOPE)
- set(SEND_TYPE_ARG3 "${send_arg3}" PARENT_SCOPE)
- set(SEND_TYPE_ARG4 "${send_arg4}" PARENT_SCOPE)
- set(SEND_TYPE_RETV "${send_retv}" PARENT_SCOPE)
- set(HAVE_SEND 1 PARENT_SCOPE)
- set(curl_cv_func_send_done 1 PARENT_SCOPE)
- endif()
-endfunction()
-
-check_c_source_compiles("${_source_epilogue}
-int main(void) {
- send(0, 0, 0, 0);
- return 0;
-}" curl_cv_send)
-if(curl_cv_send)
- if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
- if(APPLE)
- curl_cv_func_send_run_test("ssize_t" "int" "const void *" "size_t" "int")
- endif()
- foreach(send_retv "int" "ssize_t" )
- foreach(send_arg1 "SOCKET" "int" "ssize_t" )
- foreach(send_arg2 "const char *" "const void *" "void *" "char *")
- foreach(send_arg3 "int" "size_t" "socklen_t" "unsigned int")
- foreach(send_arg4 "int" "unsigned int")
- if(NOT curl_cv_func_send_done)
- curl_cv_func_send_run_test("${send_retv}" "${send_arg1}" "${send_arg2}" "${send_arg3}" "${send_arg4}")
- endif()
- endforeach()
- endforeach()
- endforeach()
- endforeach()
- endforeach()
- else()
- string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
- string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
- string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}")
- string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}")
- string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}")
- string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}")
- endif()
-
- if("${curl_cv_func_send_args}" STREQUAL "unknown")
- message(FATAL_ERROR "Cannot find proper types to use for send args")
- endif()
- set(SEND_QUAL_ARG2 "const")
-else()
- message(FATAL_ERROR "Unable to link function send")
-endif()
-set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
-endif()
-set(HAVE_SEND 1)
-
check_c_source_compiles("${_source_epilogue}
int main(void) {
int flag = MSG_NOSIGNAL;
diff --git a/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake b/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
index dd653daea8..9a513bb6cb 100644
--- a/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
+++ b/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,36 +18,26 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
if(NOT UNIX)
if(WIN32)
- set(HAVE_LIBDL 0)
- set(HAVE_LIBUCB 0)
set(HAVE_LIBSOCKET 0)
- set(NOT_NEED_LIBNSL 0)
- set(HAVE_LIBNSL 0)
set(HAVE_GETHOSTNAME 1)
set(HAVE_LIBZ 0)
- set(HAVE_DLOPEN 0)
-
- set(HAVE_ALLOCA_H 0)
set(HAVE_ARPA_INET_H 0)
- set(HAVE_DLFCN_H 0)
set(HAVE_FCNTL_H 1)
set(HAVE_INTTYPES_H 0)
set(HAVE_IO_H 1)
- set(HAVE_MALLOC_H 1)
- set(HAVE_MEMORY_H 1)
set(HAVE_NETDB_H 0)
- set(HAVE_NETINET_IF_ETHER_H 0)
set(HAVE_NETINET_IN_H 0)
set(HAVE_NET_IF_H 0)
set(HAVE_PROCESS_H 1)
set(HAVE_PWD_H 0)
set(HAVE_SETJMP_H 1)
set(HAVE_SIGNAL_H 1)
- set(HAVE_SOCKIO_H 0)
set(HAVE_STDINT_H 0)
set(HAVE_STDLIB_H 1)
set(HAVE_STRINGS_H 0)
@@ -64,40 +54,26 @@ if(NOT UNIX)
set(HAVE_TERMIOS_H 0)
set(HAVE_TERMIO_H 0)
set(HAVE_TIME_H 1)
- set(HAVE_UNISTD_H 0)
set(HAVE_UTIME_H 0)
- set(HAVE_X509_H 0)
- set(HAVE_ZLIB_H 0)
set(HAVE_SOCKET 1)
- set(HAVE_POLL 0)
set(HAVE_SELECT 1)
set(HAVE_STRDUP 1)
- set(HAVE_STRSTR 1)
- set(HAVE_STRTOK_R 0)
- set(HAVE_STRFTIME 1)
- set(HAVE_UNAME 0)
- set(HAVE_STRCASECMP 0)
set(HAVE_STRICMP 1)
set(HAVE_STRCMPI 1)
set(HAVE_GETTIMEOFDAY 0)
- set(HAVE_INET_ADDR 1)
set(HAVE_CLOSESOCKET 1)
- set(HAVE_SETVBUF 0)
set(HAVE_SIGSETJMP 0)
+ set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1)
set(HAVE_GETPASS_R 0)
- set(HAVE_STRLCAT 0)
set(HAVE_GETPWUID 0)
set(HAVE_GETEUID 0)
set(HAVE_UTIME 1)
set(HAVE_RAND_EGD 0)
- set(HAVE_RAND_SCREEN 0)
- set(HAVE_RAND_STATUS 0)
set(HAVE_GMTIME_R 0)
- set(HAVE_LOCALTIME_R 0)
+ set(HAVE_GETADDRINFO_THREADSAFE 1)
set(HAVE_GETHOSTBYNAME_R 0)
- set(HAVE_SIGNAL_FUNC 1)
- set(HAVE_SIGNAL_MACRO 0)
+ set(HAVE_SIGNAL 1)
set(HAVE_GETHOSTBYNAME_R_3 0)
set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
@@ -109,11 +85,6 @@ if(NOT UNIX)
set(TIME_WITH_SYS_TIME 0)
set(HAVE_O_NONBLOCK 0)
set(HAVE_IN_ADDR_T 0)
- if(ENABLE_IPV6)
- set(HAVE_GETADDRINFO 1)
- else()
- set(HAVE_GETADDRINFO 0)
- endif()
set(STDC_HEADERS 1)
set(HAVE_SIGACTION 0)
diff --git a/Utilities/cmcurl/CMake/Utilities.cmake b/Utilities/cmcurl/CMake/Utilities.cmake
index 8f9b861bae..78bfd6ffe6 100644
--- a/Utilities/cmcurl/CMake/Utilities.cmake
+++ b/Utilities/cmcurl/CMake/Utilities.cmake
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
# File containing various utilities
diff --git a/Utilities/cmcurl/CMake/cmake_uninstall.cmake.in b/Utilities/cmcurl/CMake/cmake_uninstall.cmake.in
index d9d9c4e3af..2549d41f42 100644
--- a/Utilities/cmcurl/CMake/cmake_uninstall.cmake.in
+++ b/Utilities/cmcurl/CMake/cmake_uninstall.cmake.in
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
diff --git a/Utilities/cmcurl/CMake/curl-config.cmake.in b/Utilities/cmcurl/CMake/curl-config.cmake.in
index 957148ecc6..496a92d0e5 100644
--- a/Utilities/cmcurl/CMake/curl-config.cmake.in
+++ b/Utilities/cmcurl/CMake/curl-config.cmake.in
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
@PACKAGE_INIT@
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index 9b468c3625..7e9aef0715 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -153,6 +153,8 @@ endif()
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
# curl/libcurl CMake script
# by Tetetest and Sukender (Benoit Neil)
@@ -172,6 +174,27 @@ endif()
# To check:
# (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not.
# (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options.
+
+# Note: By default this CMake build script detects the version of some
+# dependencies using `check_symbol_exists`. Those checks do not work
+# in the case that both CURL and its dependency are included as
+# sub-projects in a larger build using `FetchContent`. To support
+# that case, additional variables may be defined by the parent
+# project, ideally in the "extra" find package redirect file:
+# https://cmake.org/cmake/help/latest/module/FetchContent.html#integrating-with-find-package
+#
+# The following variables are available:
+# HAVE_RAND_EGD: `RAND_egd` present in OpenSSL
+# HAVE_BORINGSSL: OpenSSL is BoringSSL
+# HAVE_PK11_CREATEMANAGEDGENERICOBJECTL: `PK11_CreateManagedGenericObject` present in NSS
+# HAVE_SSL_CTX_SET_QUIC_METHOD: `SSL_CTX_set_quic_method` present in OpenSSL
+# HAVE_QUICHE_CONN_SET_QLOG_FD: `quiche_conn_set_qlog_fd` present in QUICHE
+# HAVE_ZSTD_CREATEDSTREAM: `ZSTD_createDStream` present in Zstd
+#
+# For each of the above variables, if the variable is DEFINED (either
+# to ON or OFF), the symbol detection will be skipped. If the
+# variable is NOT DEFINED, the symbol detection will be performed.
+
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
include(Utilities)
include(Macros)
@@ -200,7 +223,11 @@ endif()
# SET(PACKAGE_STRING "curl-")
# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.se/mail/")
set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
-set(OS "\"${CMAKE_SYSTEM_NAME}\"")
+if(CMAKE_C_COMPILER_TARGET)
+ set(OS "\"${CMAKE_C_COMPILER_TARGET}\"")
+else()
+ set(OS "\"${CMAKE_SYSTEM_NAME}\"")
+endif()
include_directories(${CURL_SOURCE_DIR}/include)
@@ -211,21 +238,13 @@ option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
if(WIN32)
option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
- option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON)
option(ENABLE_UNICODE "Set to ON to use the Unicode version of the Windows API functions" OFF)
if(0) # This code not needed for building within CMake.
set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string")
if(CURL_TARGET_WINDOWS_VERSION)
add_definitions(-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}")
- elseif(ENABLE_INET_PTON)
- # _WIN32_WINNT_VISTA (0x0600)
- add_definitions(-D_WIN32_WINNT=0x0600)
- set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WIN32_WINNT=0x0600")
- else()
- # _WIN32_WINNT_WINXP (0x0501)
- add_definitions(-D_WIN32_WINNT=0x0501)
- set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WIN32_WINNT=0x0501")
+ set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}")
endif()
endif()
if(ENABLE_UNICODE)
@@ -475,19 +494,7 @@ if(ENABLE_THREADED_RESOLVER)
endif()
# Check for all needed libraries
-if(0) # This code not needed for building within CMake.
-check_library_exists_concat("${CMAKE_DL_LIBS}" dlopen HAVE_LIBDL)
-else()
- # Use the cmake-defined dl libs as dl is should not be used
- # on HPUX, but rather dld this avoids a warning
- list(APPEND CURL_LIBS ${CMAKE_DL_LIBS})
-endif()
check_library_exists_concat("socket" connect HAVE_LIBSOCKET)
-check_library_exists("c" gethostbyname "" NOT_NEED_LIBNSL)
-
-if(NOT NOT_NEED_LIBNSL)
- check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL)
-endif()
check_function_exists(gethostname HAVE_GETHOSTNAME)
@@ -598,16 +605,12 @@ if(CURL_USE_OPENSSL)
include_directories(${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
- check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
- check_include_file("openssl/err.h" HAVE_OPENSSL_ERR_H)
- check_include_file("openssl/pem.h" HAVE_OPENSSL_PEM_H)
- check_include_file("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
- check_include_file("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
- check_include_file("openssl/x509.h" HAVE_OPENSSL_X509_H)
- check_include_file("openssl/rand.h" HAVE_OPENSSL_RAND_H)
- check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS)
- check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
- check_symbol_exists(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD)
+ if(NOT DEFINED HAVE_RAND_EGD)
+ check_symbol_exists(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD)
+ endif()
+ if(NOT DEFINED HAVE_BORINGSSL)
+ check_symbol_exists(OPENSSL_IS_BORINGSSL "openssl/base.h" HAVE_BORINGSSL)
+ endif()
# Optionally build with a specific CA cert bundle.
if(CURL_CA_BUNDLE)
@@ -651,11 +654,13 @@ if(CURL_USE_NSS)
list(APPEND CURL_LIBS ${NSS_LIBRARIES})
set(SSL_ENABLED ON)
set(USE_NSS ON)
- cmake_push_check_state()
- set(CMAKE_REQUIRED_INCLUDES ${NSS_INCLUDE_DIRS})
- set(CMAKE_REQUIRED_LIBRARIES ${NSS_LIBRARIES})
- check_symbol_exists(PK11_CreateManagedGenericObject "pk11pub.h" HAVE_PK11_CREATEMANAGEDGENERICOBJECT)
- cmake_pop_check_state()
+ if(NOT DEFINED HAVE_PK11_CREATEMANAGEDGENERICOBJECT)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_INCLUDES ${NSS_INCLUDE_DIRS})
+ set(CMAKE_REQUIRED_LIBRARIES ${NSS_LIBRARIES})
+ check_symbol_exists(PK11_CreateManagedGenericObject "pk11pub.h" HAVE_PK11_CREATEMANAGEDGENERICOBJECT)
+ cmake_pop_check_state()
+ endif()
endif()
option(USE_NGHTTP2 "Use Nghttp2 library" OFF)
@@ -667,20 +672,26 @@ endif()
function(CheckQuicSupportInOpenSSL)
# Be sure that the OpenSSL library actually supports QUIC.
- cmake_push_check_state()
- set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}")
- set(CMAKE_REQUIRED_LIBRARIES "${OPENSSL_LIBRARIES}")
- check_symbol_exists(SSL_CTX_set_quic_method "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD)
+ if(NOT DEFINED HAVE_SSL_CTX_SET_QUIC_METHOD)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}")
+ set(CMAKE_REQUIRED_LIBRARIES "${OPENSSL_LIBRARIES}")
+ check_symbol_exists(SSL_CTX_set_quic_method "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD)
+ cmake_pop_check_state()
+ endif()
if(NOT HAVE_SSL_CTX_SET_QUIC_METHOD)
- message(FATAL_ERROR "QUIC support is missing in OpenSSL/boringssl. Try setting -DOPENSSL_ROOT_DIR")
+ message(FATAL_ERROR "QUIC support is missing in OpenSSL/BoringSSL. Try setting -DOPENSSL_ROOT_DIR")
endif()
- cmake_pop_check_state()
endfunction()
option(USE_NGTCP2 "Use ngtcp2 and nghttp3 libraries for HTTP/3 support" OFF)
if(USE_NGTCP2)
if(USE_OPENSSL)
- find_package(NGTCP2 REQUIRED OpenSSL)
+ if(HAVE_BORINGSSL)
+ find_package(NGTCP2 REQUIRED BoringSSL)
+ else()
+ find_package(NGTCP2 REQUIRED OpenSSL)
+ endif()
CheckQuicSupportInOpenSSL()
elseif(USE_GNUTLS)
# TODO add GnuTLS support as vtls library.
@@ -708,11 +719,13 @@ if(USE_QUICHE)
set(USE_QUICHE ON)
include_directories(${QUICHE_INCLUDE_DIRS})
list(APPEND CURL_LIBS ${QUICHE_LIBRARIES})
- cmake_push_check_state()
- set(CMAKE_REQUIRED_INCLUDES "${QUICHE_INCLUDE_DIRS}")
- set(CMAKE_REQUIRED_LIBRARIES "${QUICHE_LIBRARIES}")
- check_symbol_exists(quiche_conn_set_qlog_fd "quiche.h" HAVE_QUICHE_CONN_SET_QLOG_FD)
- cmake_pop_check_state()
+ if(NOT DEFINED HAVE_QUICHE_CONN_SET_QLOG_FD)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_INCLUDES "${QUICHE_INCLUDE_DIRS}")
+ set(CMAKE_REQUIRED_LIBRARIES "${QUICHE_LIBRARIES}")
+ check_symbol_exists(quiche_conn_set_qlog_fd "quiche.h" HAVE_QUICHE_CONN_SET_QLOG_FD)
+ cmake_pop_check_state()
+ endif()
endif()
option(USE_MSH3 "Use msquic library for HTTP/3 support" OFF)
@@ -748,7 +761,6 @@ if(NOT CURL_DISABLE_LDAP)
# Now that we know, we're not using windows LDAP...
if(USE_WIN32_LDAP)
check_include_file_concat("winldap.h" HAVE_WINLDAP_H)
- check_include_file_concat("winber.h" HAVE_WINBER_H)
else()
# Check for LDAP
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
@@ -831,34 +843,29 @@ endif()
if(NOT CURL_DISABLE_LDAPS)
check_include_file_concat("ldap_ssl.h" HAVE_LDAP_SSL_H)
- check_include_file_concat("ldapssl.h" HAVE_LDAPSSL_H)
endif()
-# Check for idn
+# Check for idn2
option(USE_LIBIDN2 "Use libidn2 for IDN support" ON)
-set(HAVE_LIBIDN2 OFF)
if(USE_LIBIDN2)
check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
+else()
+ set(HAVE_LIBIDN2 OFF)
endif()
if(WIN32)
option(USE_WIN32_IDN "Use WinIDN for IDN support" OFF)
if(USE_WIN32_IDN)
- list(APPEND CURL_LIBS "Normaliz")
+ list(APPEND CURL_LIBS "normaliz")
set(WANT_IDN_PROTOTYPES ON)
endif()
endif()
-# Check for symbol dlopen (same as HAVE_LIBDL)
-check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
-
set(HAVE_LIBZ OFF)
-set(HAVE_ZLIB_H OFF)
set(USE_ZLIB OFF)
#optional_dependency(ZLIB)
find_package(ZLIB)
if(ZLIB_FOUND)
- set(HAVE_ZLIB_H ON)
set(HAVE_LIBZ ON)
set(USE_ZLIB ON)
@@ -890,11 +897,13 @@ option(CURL_ZSTD "Set to ON to enable building curl with zstd support." OFF)
set(HAVE_ZSTD OFF)
if(CURL_ZSTD)
find_package(Zstd REQUIRED)
- cmake_push_check_state()
- set(CMAKE_REQUIRED_INCLUDES ${Zstd_INCLUDE_DIRS})
- set(CMAKE_REQUIRED_LIBRARIES ${Zstd_LIBRARIES})
- check_symbol_exists(ZSTD_createDStream "zstd.h" HAVE_ZSTD_CREATEDSTREAM)
- cmake_pop_check_state()
+ if (NOT DEFINED HAVE_ZSTD_CREATEDSTREAM)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_INCLUDES ${Zstd_INCLUDE_DIRS})
+ set(CMAKE_REQUIRED_LIBRARIES ${Zstd_LIBRARIES})
+ check_symbol_exists(ZSTD_createDStream "zstd.h" HAVE_ZSTD_CREATEDSTREAM)
+ cmake_pop_check_state()
+ endif()
if(Zstd_FOUND AND HAVE_ZSTD_CREATEDSTREAM)
set(HAVE_ZSTD ON)
list(APPEND CURL_LIBS ${Zstd_LIBRARIES})
@@ -902,42 +911,46 @@ if(CURL_ZSTD)
endif()
endif()
+#libpsl
+option(CURL_USE_LIBPSL "Use libPSL" ON)
+mark_as_advanced(CURL_USE_LIBPSL)
+set(USE_LIBPSL OFF)
+
+if(CURL_USE_LIBPSL)
+ find_package(LibPSL)
+ if(LIBPSL_FOUND)
+ list(APPEND CURL_LIBS ${LIBPSL_LIBRARY})
+ list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBPSL_INCLUDE_DIR}")
+ include_directories("${LIBPSL_INCLUDE_DIR}")
+ set(USE_LIBPSL ON)
+ endif()
+endif()
+
#libSSH2
option(CURL_USE_LIBSSH2 "Use libSSH2" ON)
mark_as_advanced(CURL_USE_LIBSSH2)
set(USE_LIBSSH2 OFF)
-set(HAVE_LIBSSH2 OFF)
-set(HAVE_LIBSSH2_H OFF)
if(CURL_USE_LIBSSH2)
find_package(LibSSH2)
if(LIBSSH2_FOUND)
list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY})
- set(CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBRARY})
list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}")
include_directories("${LIBSSH2_INCLUDE_DIR}")
- set(HAVE_LIBSSH2 ON)
set(USE_LIBSSH2 ON)
-
- # find_package has already found the headers
- set(HAVE_LIBSSH2_H ON)
- set(CURL_INCLUDES ${CURL_INCLUDES} "${LIBSSH2_INCLUDE_DIR}/libssh2.h")
- set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DHAVE_LIBSSH2_H")
- unset(CMAKE_REQUIRED_LIBRARIES)
endif()
endif()
# libssh
option(CURL_USE_LIBSSH "Use libSSH" OFF)
mark_as_advanced(CURL_USE_LIBSSH)
-if(NOT HAVE_LIBSSH2 AND CURL_USE_LIBSSH)
+if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH)
find_package(libssh CONFIG)
if(libssh_FOUND)
message(STATUS "Found libssh ${libssh_VERSION}")
# Use imported target for include and library paths.
list(APPEND CURL_LIBS ssh)
set(USE_LIBSSH ON)
- set(HAVE_LIBSSH_LIBSSH_H 1)
endif()
endif()
@@ -979,14 +992,15 @@ if(CURL_USE_GSSAPI)
set(_LINKER_FLAGS_STR "${_LINKER_FLAGS_STR} -L\"${_dir}\"")
endforeach()
- set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}")
- set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
- check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+ if(NOT DEFINED HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+ set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}")
+ set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
+ check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+ unset(CMAKE_REQUIRED_LIBRARIES)
+ endif()
if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
set(HAVE_OLD_GSSMIT ON)
endif()
- unset(CMAKE_REQUIRED_LIBRARIES)
-
endif()
include_directories(${GSS_INCLUDE_DIR})
@@ -1105,7 +1119,6 @@ else()
set(HAVE_WINSOCK2_H 0)
endif()
-check_include_file_concat("stdio.h" HAVE_STDIO_H)
check_include_file_concat("inttypes.h" HAVE_INTTYPES_H)
check_include_file_concat("sys/filio.h" HAVE_SYS_FILIO_H)
check_include_file_concat("sys/ioctl.h" HAVE_SYS_IOCTL_H)
@@ -1118,11 +1131,9 @@ check_include_file_concat("sys/sockio.h" HAVE_SYS_SOCKIO_H)
check_include_file_concat("sys/stat.h" HAVE_SYS_STAT_H)
check_include_file_concat("sys/time.h" HAVE_SYS_TIME_H)
check_include_file_concat("sys/types.h" HAVE_SYS_TYPES_H)
-check_include_file_concat("sys/uio.h" HAVE_SYS_UIO_H)
check_include_file_concat("sys/un.h" HAVE_SYS_UN_H)
check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H)
check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H)
-check_include_file_concat("alloca.h" HAVE_ALLOCA_H)
check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file_concat("arpa/tftp.h" HAVE_ARPA_TFTP_H)
check_include_file_concat("assert.h" HAVE_ASSERT_H)
@@ -1131,7 +1142,6 @@ check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
check_include_file_concat("idn2.h" HAVE_IDN2_H)
check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
check_include_file_concat("io.h" HAVE_IO_H)
-check_include_file_concat("krb.h" HAVE_KRB_H)
check_include_file_concat("libgen.h" HAVE_LIBGEN_H)
check_include_file_concat("locale.h" HAVE_LOCALE_H)
check_include_file_concat("net/if.h" HAVE_NET_IF_H)
@@ -1140,15 +1150,14 @@ check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H)
check_include_file("linux/tcp.h" HAVE_LINUX_TCP_H)
-check_include_file_concat("pem.h" HAVE_PEM_H)
check_include_file_concat("poll.h" HAVE_POLL_H)
check_include_file_concat("pwd.h" HAVE_PWD_H)
check_include_file_concat("setjmp.h" HAVE_SETJMP_H)
check_include_file_concat("signal.h" HAVE_SIGNAL_H)
check_include_file_concat("ssl.h" HAVE_SSL_H)
+check_include_file_concat("stdatomic.h" HAVE_STDATOMIC_H)
check_include_file_concat("stdbool.h" HAVE_STDBOOL_H)
check_include_file_concat("stdint.h" HAVE_STDINT_H)
-check_include_file_concat("stdio.h" HAVE_STDIO_H)
check_include_file_concat("stdlib.h" HAVE_STDLIB_H)
check_include_file_concat("string.h" HAVE_STRING_H)
check_include_file_concat("strings.h" HAVE_STRINGS_H)
@@ -1158,24 +1167,20 @@ check_include_file_concat("termios.h" HAVE_TERMIOS_H)
check_include_file_concat("time.h" HAVE_TIME_H)
check_include_file_concat("unistd.h" HAVE_UNISTD_H)
check_include_file_concat("utime.h" HAVE_UTIME_H)
-check_include_file_concat("x509.h" HAVE_X509_H)
check_include_file_concat("process.h" HAVE_PROCESS_H)
check_include_file_concat("stddef.h" HAVE_STDDEF_H)
-check_include_file_concat("dlfcn.h" HAVE_DLFCN_H)
-check_include_file_concat("malloc.h" HAVE_MALLOC_H)
-check_include_file_concat("memory.h" HAVE_MEMORY_H)
-check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
check_include_file_concat("stdint.h" HAVE_STDINT_H)
-check_include_file_concat("sockio.h" HAVE_SOCKIO_H)
check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H)
check_type_size(size_t SIZEOF_SIZE_T)
check_type_size(ssize_t SIZEOF_SSIZE_T)
check_type_size("time_t" SIZEOF_TIME_T)
-find_file(RANDOM_FILE urandom /dev)
-mark_as_advanced(RANDOM_FILE)
+if(NOT CMAKE_CROSSCOMPILING)
+ find_file(RANDOM_FILE urandom /dev)
+ mark_as_advanced(RANDOM_FILE)
+endif()
# Check for some functions that are used
if(HAVE_LIBWS2_32)
@@ -1186,57 +1191,46 @@ elseif(HAVE_LIBNETWORK)
set(CMAKE_REQUIRED_LIBRARIES network)
endif()
+check_symbol_exists(fchmod "${CURL_INCLUDES}" HAVE_FCHMOD)
check_symbol_exists(basename "${CURL_INCLUDES}" HAVE_BASENAME)
check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET)
+check_symbol_exists(socketpair "${CURL_INCLUDES}" HAVE_SOCKETPAIR)
+check_symbol_exists(recv "${CURL_INCLUDES}" HAVE_RECV)
+check_symbol_exists(send "${CURL_INCLUDES}" HAVE_SEND)
check_symbol_exists(select "${CURL_INCLUDES}" HAVE_SELECT)
-check_symbol_exists(poll "${CURL_INCLUDES}" HAVE_POLL)
check_symbol_exists(strdup "${CURL_INCLUDES}" HAVE_STRDUP)
-check_symbol_exists(strstr "${CURL_INCLUDES}" HAVE_STRSTR)
check_symbol_exists(strtok_r "${CURL_INCLUDES}" HAVE_STRTOK_R)
-check_symbol_exists(strftime "${CURL_INCLUDES}" HAVE_STRFTIME)
-check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME)
check_symbol_exists(strcasecmp "${CURL_INCLUDES}" HAVE_STRCASECMP)
check_symbol_exists(stricmp "${CURL_INCLUDES}" HAVE_STRICMP)
check_symbol_exists(strcmpi "${CURL_INCLUDES}" HAVE_STRCMPI)
-check_symbol_exists(strncmpi "${CURL_INCLUDES}" HAVE_STRNCMPI)
check_symbol_exists(alarm "${CURL_INCLUDES}" HAVE_ALARM)
-if(NOT HAVE_STRNCMPI)
- set(HAVE_STRCMPI)
-endif()
check_symbol_exists(getppid "${CURL_INCLUDES}" HAVE_GETPPID)
check_symbol_exists(utimes "${CURL_INCLUDES}" HAVE_UTIMES)
check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
-check_symbol_exists(inet_addr "${CURL_INCLUDES}" HAVE_INET_ADDR)
check_symbol_exists(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
check_symbol_exists(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP)
check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R)
check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID)
check_symbol_exists(getpwuid_r "${CURL_INCLUDES}" HAVE_GETPWUID_R)
check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID)
-check_symbol_exists(usleep "${CURL_INCLUDES}" HAVE_USLEEP)
check_symbol_exists(utime "${CURL_INCLUDES}" HAVE_UTIME)
check_symbol_exists(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R)
-check_symbol_exists(localtime_r "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
-check_symbol_exists(gethostbyname "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME)
check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
-check_symbol_exists(signal "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC)
-check_symbol_exists(SIGALRM "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
-if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
- set(HAVE_SIGNAL 1)
-endif()
-check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME)
+check_symbol_exists(signal "${CURL_INCLUDES}" HAVE_SIGNAL)
check_symbol_exists(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL)
check_symbol_exists(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64)
check_symbol_exists(strerror_r "${CURL_INCLUDES}" HAVE_STRERROR_R)
check_symbol_exists(siginterrupt "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
check_symbol_exists(getaddrinfo "${CURL_INCLUDES}" HAVE_GETADDRINFO)
+if(NOT HAVE_GETADDRINFO)
+ set(HAVE_GETADDRINFO_THREADSAFE OFF)
+endif()
check_symbol_exists(freeaddrinfo "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE)
check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE)
-check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
check_symbol_exists(getpeername "${CURL_INCLUDES}" HAVE_GETPEERNAME)
check_symbol_exists(getsockname "${CURL_INCLUDES}" HAVE_GETSOCKNAME)
check_symbol_exists(if_nametoindex "${CURL_INCLUDES}" HAVE_IF_NAMETOINDEX)
@@ -1244,10 +1238,16 @@ check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT)
check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE)
check_symbol_exists(setmode "${CURL_INCLUDES}" HAVE_SETMODE)
check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT)
-check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL)
-check_symbol_exists(ioctl "${CURL_INCLUDES}" HAVE_IOCTL)
-check_symbol_exists(setsockopt "${CURL_INCLUDES}" HAVE_SETSOCKOPT)
+
+if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1900))
+ # earlier MSVC compilers had faulty snprintf implementations
+ check_symbol_exists(snprintf "${CURL_INCLUDES}" HAVE_SNPRINTF)
+endif()
check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME)
+check_symbol_exists(inet_ntop "${CURL_INCLUDES}" HAVE_INET_NTOP)
+if(MSVC AND (MSVC_VERSION LESS_EQUAL 1600))
+ set(HAVE_INET_NTOP OFF)
+endif()
check_symbol_exists(inet_pton "${CURL_INCLUDES}" HAVE_INET_PTON)
check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR)
@@ -1297,7 +1297,6 @@ foreach(CURL_TEST
HAVE_IOCTL_FIONBIO
HAVE_IOCTL_SIOCGIFADDR
HAVE_SETSOCKOPT_SO_NONBLOCK
- HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
TIME_WITH_SYS_TIME
HAVE_O_NONBLOCK
HAVE_GETHOSTBYNAME_R_3
@@ -1309,10 +1308,10 @@ foreach(CURL_TEST
HAVE_IN_ADDR_T
HAVE_BOOL_T
STDC_HEADERS
- HAVE_GETADDRINFO
HAVE_FILE_OFFSET_BITS
HAVE_VARIADIC_MACROS_C99
HAVE_VARIADIC_MACROS_GCC
+ HAVE_ATOMIC
)
curl_internal_test(${CURL_TEST})
endforeach()
@@ -1329,8 +1328,30 @@ set(CMAKE_EXTRA_INCLUDE_FILES "curl/system.h")
check_type_size("curl_off_t" SIZEOF_CURL_OFF_T)
set(CMAKE_EXTRA_INCLUDE_FILES "")
+if(WIN32)
+ # detect actual value of _WIN32_WINNT and store as HAVE_WIN32_WINNT
+ curl_internal_test(HAVE_WIN32_WINNT)
+ if(HAVE_WIN32_WINNT)
+ string(REGEX MATCH ".*_WIN32_WINNT=0x[0-9a-fA-F]+" OUTPUT "${OUTPUT}")
+ string(REGEX REPLACE ".*_WIN32_WINNT=" "" HAVE_WIN32_WINNT "${OUTPUT}")
+ message(STATUS "Found _WIN32_WINNT=${HAVE_WIN32_WINNT}")
+ endif()
+ # avoid storing HAVE_WIN32_WINNT in CMake cache
+ unset(HAVE_WIN32_WINNT CACHE)
+endif()
+
set(CMAKE_REQUIRED_FLAGS)
+option(ENABLE_WEBSOCKETS "Set to ON to enable EXPERIMENTAL websockets" OFF)
+
+if(ENABLE_WEBSOCKETS)
+ if(${SIZEOF_CURL_OFF_T} GREATER "4")
+ set(USE_WEBSOCKETS ON)
+ else()
+ message(WARNING "curl_off_t is too small to enable WebSockets")
+ endif()
+endif()
+
foreach(CURL_TEST
HAVE_GLIBC_STRERROR_R
HAVE_POSIX_STRERROR_R
@@ -1374,18 +1395,6 @@ if(NOT HAVE_IN_ADDR_T)
set(in_addr_t "unsigned long")
endif()
-# Fix libz / zlib.h
-
-if(NOT CURL_SPECIAL_LIBZ)
- if(NOT HAVE_LIBZ)
- set(HAVE_ZLIB_H 0)
- endif()
-
- if(NOT HAVE_ZLIB_H)
- set(HAVE_LIBZ 0)
- endif()
-endif()
-
# Check for nonblocking
set(HAVE_DISABLED_NONBLOCKING 1)
if(HAVE_FIONBIO OR
@@ -1445,6 +1454,25 @@ if(WIN32)
if(USE_WIN32_CRYPTO OR USE_SCHANNEL)
list(APPEND CURL_LIBS "advapi32" "crypt32")
endif()
+
+ # Matching logic used for Curl_win32_random()
+ if(MINGW)
+ check_c_source_compiles("
+ #include <_mingw.h>
+ #if defined(__MINGW64_VERSION_MAJOR)
+ #error
+ #endif
+ int main(void) {
+ return 0;
+ }"
+ HAVE_MINGW_ORIGINAL)
+ endif()
+
+ if(NOT HAVE_MINGW_ORIGINAL)
+ list(APPEND CURL_LIBS "bcrypt")
+ else()
+ set(HAVE_FTRUNCATE OFF)
+ endif()
endif()
if(MSVC)
@@ -1602,6 +1630,9 @@ _add_if("HTTP3" USE_NGTCP2 OR USE_QUICHE)
_add_if("MultiSSL" CURL_WITH_MULTI_SSL)
_add_if("HTTPS-proxy" SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS OR USE_NSS))
_add_if("unicode" ENABLE_UNICODE)
+_add_if("threadsafe" HAVE_ATOMIC OR (WIN32 AND
+ HAVE_WIN32_WINNT GREATER_EQUAL 0x600))
+_add_if("PSL" USE_LIBPSL)
string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
@@ -1638,6 +1669,8 @@ _add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH)
_add_if("RTSP" NOT CURL_DISABLE_RTSP)
_add_if("RTMP" USE_LIBRTMP)
_add_if("MQTT" NOT CURL_DISABLE_MQTT)
+_add_if("WS" USE_WEBSOCKETS)
+_add_if("WSS" USE_WEBSOCKETS)
if(_items)
list(SORT _items)
endif()
@@ -1771,13 +1804,13 @@ if(MSVC_VERSION EQUAL 1600)
endif()
endif()
-if(NOT TARGET uninstall)
+if(NOT TARGET curl_uninstall)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake
IMMEDIATE @ONLY)
- add_custom_target(uninstall
+ add_custom_target(curl_uninstall
COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake)
endif()
diff --git a/Utilities/cmcurl/include/curl/curl.h b/Utilities/cmcurl/include/curl/curl.h
index 8cdfdb69e9..7a12581450 100644
--- a/Utilities/cmcurl/include/curl/curl.h
+++ b/Utilities/cmcurl/include/curl/curl.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -73,7 +75,8 @@
defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \
- (defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000))
+ (defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) || \
+ defined(__sun__)
#include <sys/select.h>
#endif
@@ -575,7 +578,7 @@ typedef enum {
CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */
CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
- CURLE_CONV_FAILED, /* 75 - conversion failed */
+ CURLE_OBSOLETE75, /* 75 - NOT IN USE since 7.82.0 */
CURLE_OBSOLETE76, /* 76 - NOT IN USE since 7.82.0 */
CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
or wrong format */
@@ -613,6 +616,7 @@ typedef enum {
CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */
CURLE_PROXY, /* 97 - proxy handshake error */
CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */
+ CURLE_UNRECOVERABLE_POLL, /* 99 - poll/select returned fatal error */
CURL_LAST /* never use! */
} CURLcode;
@@ -677,6 +681,7 @@ typedef enum {
#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
#define CURLE_LDAP_INVALID_URL CURLE_OBSOLETE62
#define CURLE_CONV_REQD CURLE_OBSOLETE76
+#define CURLE_CONV_FAILED CURLE_OBSOLETE75
/* This was the error code 50 in 7.7.3 and a few earlier versions, this
is no longer used by libcurl but is instead #defined here only to not
@@ -835,8 +840,8 @@ enum curl_khstat {
CURLKHSTAT_FINE_ADD_TO_FILE,
CURLKHSTAT_FINE,
CURLKHSTAT_REJECT, /* reject the connection, return an error */
- CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so
- this causes a CURLE_DEFER error but otherwise the
+ CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now.
+ Causes a CURLE_PEER_FAILED_VERIFICATION error but the
connection will be left intact etc */
CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key*/
CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */
@@ -855,7 +860,18 @@ typedef int
const struct curl_khkey *knownkey, /* known */
const struct curl_khkey *foundkey, /* found */
enum curl_khmatch, /* libcurl's view on the keys */
- void *clientp); /* custom pointer passed from app */
+ void *clientp); /* custom pointer passed with */
+ /* CURLOPT_SSH_KEYDATA */
+
+typedef int
+ (*curl_sshhostkeycallback) (void *clientp,/* custom pointer passed*/
+ /* with CURLOPT_SSH_HOSTKEYDATA */
+ int keytype, /* CURLKHTYPE */
+ const char *key, /*hostkey to check*/
+ size_t keylen); /*length of the key*/
+ /*return CURLE_OK to accept*/
+ /*or something else to refuse*/
+
/* parameter for the CURLOPT_USE_SSL option */
typedef enum {
@@ -995,7 +1011,8 @@ typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy,
#define CURLHSTS_ENABLE (long)(1<<0)
#define CURLHSTS_READONLYFILE (long)(1<<1)
-/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+/* The CURLPROTO_ defines below are for the **deprecated** CURLOPT_*PROTOCOLS
+ options. Do not use. */
#define CURLPROTO_HTTP (1<<0)
#define CURLPROTO_HTTPS (1<<1)
#define CURLPROTO_FTP (1<<2)
@@ -1461,12 +1478,11 @@ typedef enum {
Note that setting multiple bits may cause extra network round-trips. */
CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_VALUES, 111),
- /* FTP option that changes the timeout, in seconds, associated with
- getting a response. This is different from transfer timeout time and
- essentially places a demand on the FTP server to acknowledge commands
- in a timely manner. */
- CURLOPT(CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112),
-#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
+ /* Option that changes the timeout, in seconds, associated with getting a
+ response. This is different from transfer timeout time and essentially
+ places a demand on the server to acknowledge commands in a timely
+ manner. For FTP, SMTP, IMAP and POP3. */
+ CURLOPT(CURLOPT_SERVER_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112),
/* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
tell libcurl to use those IP versions only. This only has effect on
@@ -2122,6 +2138,25 @@ typedef enum {
/* Set MIME option flags. */
CURLOPT(CURLOPT_MIME_OPTIONS, CURLOPTTYPE_LONG, 315),
+ /* set the SSH host key callback, must point to a curl_sshkeycallback
+ function */
+ CURLOPT(CURLOPT_SSH_HOSTKEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 316),
+
+ /* set the SSH host key callback custom pointer */
+ CURLOPT(CURLOPT_SSH_HOSTKEYDATA, CURLOPTTYPE_CBPOINT, 317),
+
+ /* specify which protocols that are allowed to be used for the transfer,
+ which thus helps the app which takes URLs from users or other external
+ inputs and want to restrict what protocol(s) to deal with. Defaults to
+ all built-in protocols. */
+ CURLOPT(CURLOPT_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 318),
+
+ /* specify which protocols that libcurl is allowed to follow directs to */
+ CURLOPT(CURLOPT_REDIR_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 319),
+
+ /* websockets options */
+ CURLOPT(CURLOPT_WS_OPTIONS, CURLOPTTYPE_LONG, 320),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -2147,6 +2182,9 @@ typedef enum {
#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+/* */
+#define CURLOPT_FTP_RESPONSE_TIMEOUT CURLOPT_SERVER_RESPONSE_TIMEOUT
+
#else
/* This is set if CURL_NO_OLDIES is defined at compile-time */
#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
@@ -2161,7 +2199,7 @@ typedef enum {
#define CURL_IPRESOLVE_V4 1 /* uses only IPv4 addresses/connections */
#define CURL_IPRESOLVE_V6 2 /* uses only IPv6 addresses/connections */
- /* three convenient "aliases" that follow the name scheme better */
+ /* Convenient "aliases" */
#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
/* These enums are for use with the CURLOPT_HTTP_VERSION option. */
@@ -2589,8 +2627,10 @@ CURL_EXTERN void curl_free(void *p);
*
* curl_global_init() should be invoked exactly once for each application that
* uses libcurl and before any call of other libcurl functions.
- *
- * This function is not thread-safe!
+
+ * This function is thread-safe if CURL_VERSION_THREADSAFE is set in the
+ * curl_version_info_data.features flag (fetch by curl_version_info()).
+
*/
CURL_EXTERN CURLcode curl_global_init(long flags);
@@ -2799,8 +2839,9 @@ typedef enum {
CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58,
CURLINFO_PROXY_ERROR = CURLINFO_LONG + 59,
CURLINFO_REFERER = CURLINFO_STRING + 60,
-
- CURLINFO_LASTONE = 60
+ CURLINFO_CAINFO = CURLINFO_STRING + 61,
+ CURLINFO_CAPATH = CURLINFO_STRING + 62,
+ CURLINFO_LASTONE = 62
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
@@ -3006,6 +3047,7 @@ typedef struct curl_version_info_data curl_version_info_data;
#define CURL_VERSION_UNICODE (1<<27) /* Unicode support on Windows */
#define CURL_VERSION_HSTS (1<<28) /* HSTS is supported */
#define CURL_VERSION_GSASL (1<<29) /* libgsasl is supported */
+#define CURL_VERSION_THREADSAFE (1<<30) /* libcurl API is thread-safe */
/*
* NAME curl_version_info()
@@ -3070,6 +3112,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
#include "urlapi.h"
#include "options.h"
#include "header.h"
+#include "websockets.h"
/* the typechecker doesn't work in C++ (yet) */
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
diff --git a/Utilities/cmcurl/include/curl/curlver.h b/Utilities/cmcurl/include/curl/curlver.h
index 718d58c085..9eb50679c5 100644
--- a/Utilities/cmcurl/include/curl/curlver.h
+++ b/Utilities/cmcurl/include/curl/curlver.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* This header file contains nothing but libcurl version info, generated by
@@ -30,13 +32,13 @@
/* This is the version number of the libcurl package from which this header
file origins: */
-#define LIBCURL_VERSION "7.83.1"
+#define LIBCURL_VERSION "7.86.0"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 83
-#define LIBCURL_VERSION_PATCH 1
+#define LIBCURL_VERSION_MINOR 86
+#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 +59,7 @@
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
-#define LIBCURL_VERSION_NUM 0x075301
+#define LIBCURL_VERSION_NUM 0x075600
/*
* This is the date and time when the full source package was created. The
diff --git a/Utilities/cmcurl/include/curl/easy.h b/Utilities/cmcurl/include/curl/easy.h
index 2dbfb26b5b..9c7e63adad 100644
--- a/Utilities/cmcurl/include/curl/easy.h
+++ b/Utilities/cmcurl/include/curl/easy.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifdef __cplusplus
extern "C" {
diff --git a/Utilities/cmcurl/include/curl/header.h b/Utilities/cmcurl/include/curl/header.h
index 7715b61e22..1598c6f113 100644
--- a/Utilities/cmcurl/include/curl/header.h
+++ b/Utilities/cmcurl/include/curl/header.h
@@ -20,8 +20,14 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct curl_header {
char *name; /* this might not use the same case */
char *value;
@@ -61,4 +67,8 @@ CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *easy,
int request,
struct curl_header *prev);
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
#endif /* CURLINC_HEADER_H */
diff --git a/Utilities/cmcurl/include/curl/mprintf.h b/Utilities/cmcurl/include/curl/mprintf.h
index 3549552dba..cb948dcd97 100644
--- a/Utilities/cmcurl/include/curl/mprintf.h
+++ b/Utilities/cmcurl/include/curl/mprintf.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <stdarg.h>
diff --git a/Utilities/cmcurl/include/curl/multi.h b/Utilities/cmcurl/include/curl/multi.h
index 91cd95d323..2f3ec37a76 100644
--- a/Utilities/cmcurl/include/curl/multi.h
+++ b/Utilities/cmcurl/include/curl/multi.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
This is an "external" header file. Don't give away any internals here!
@@ -75,6 +77,7 @@ typedef enum {
CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */
CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */
CURLM_ABORTED_BY_CALLBACK,
+ CURLM_UNRECOVERABLE_POLL,
CURLM_LAST
} CURLMcode;
@@ -121,7 +124,7 @@ struct curl_waitfd {
/*
* Name: curl_multi_init()
*
- * Desc: inititalize multi-style curl usage
+ * Desc: initialize multi-style curl usage
*
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
*/
diff --git a/Utilities/cmcurl/include/curl/options.h b/Utilities/cmcurl/include/curl/options.h
index 91360b3581..a792687cf4 100644
--- a/Utilities/cmcurl/include/curl/options.h
+++ b/Utilities/cmcurl/include/curl/options.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifdef __cplusplus
@@ -31,7 +33,7 @@ typedef enum {
CURLOT_VALUES, /* (a defined set or bitmask) */
CURLOT_OFF_T, /* curl_off_t (a range of values) */
CURLOT_OBJECT, /* pointer (void *) */
- CURLOT_STRING, /* (char * to zero terminated buffer) */
+ CURLOT_STRING, /* (char * to null-terminated buffer) */
CURLOT_SLIST, /* (struct curl_slist *) */
CURLOT_CBPTR, /* (void * passed as-is to a callback) */
CURLOT_BLOB, /* blob (struct curl_blob *) */
diff --git a/Utilities/cmcurl/include/curl/stdcheaders.h b/Utilities/cmcurl/include/curl/stdcheaders.h
index 60596c7568..82e1b5fef6 100644
--- a/Utilities/cmcurl/include/curl/stdcheaders.h
+++ b/Utilities/cmcurl/include/curl/stdcheaders.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <sys/types.h>
diff --git a/Utilities/cmcurl/include/curl/system.h b/Utilities/cmcurl/include/curl/system.h
index 000fea6c75..8d56b8a4a1 100644
--- a/Utilities/cmcurl/include/curl/system.h
+++ b/Utilities/cmcurl/include/curl/system.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
diff --git a/Utilities/cmcurl/include/curl/typecheck-gcc.h b/Utilities/cmcurl/include/curl/typecheck-gcc.h
index 9e14d8a372..2dabcb4166 100644
--- a/Utilities/cmcurl/include/curl/typecheck-gcc.h
+++ b/Utilities/cmcurl/include/curl/typecheck-gcc.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* wraps curl_easy_setopt() with typechecking */
@@ -270,9 +272,9 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_DNS_SERVERS || \
(option) == CURLOPT_DOH_URL || \
(option) == CURLOPT_EGDSOCKET || \
- (option) == CURLOPT_FTPPORT || \
(option) == CURLOPT_FTP_ACCOUNT || \
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
+ (option) == CURLOPT_FTPPORT || \
(option) == CURLOPT_HSTS || \
(option) == CURLOPT_INTERFACE || \
(option) == CURLOPT_ISSUERCERT || \
@@ -286,10 +288,8 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_PASSWORD || \
(option) == CURLOPT_PINNEDPUBLICKEY || \
(option) == CURLOPT_PRE_PROXY || \
+ (option) == CURLOPT_PROTOCOLS_STR || \
(option) == CURLOPT_PROXY || \
- (option) == CURLOPT_PROXYPASSWORD || \
- (option) == CURLOPT_PROXYUSERNAME || \
- (option) == CURLOPT_PROXYUSERPWD || \
(option) == CURLOPT_PROXY_CAINFO || \
(option) == CURLOPT_PROXY_CAPATH || \
(option) == CURLOPT_PROXY_CRLFILE || \
@@ -297,17 +297,21 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_PROXY_KEYPASSWD || \
(option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \
(option) == CURLOPT_PROXY_SERVICE_NAME || \
+ (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \
(option) == CURLOPT_PROXY_SSLCERT || \
(option) == CURLOPT_PROXY_SSLCERTTYPE || \
(option) == CURLOPT_PROXY_SSLKEY || \
(option) == CURLOPT_PROXY_SSLKEYTYPE || \
- (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \
(option) == CURLOPT_PROXY_TLS13_CIPHERS || \
(option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \
(option) == CURLOPT_PROXY_TLSAUTH_TYPE || \
(option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \
+ (option) == CURLOPT_PROXYPASSWORD || \
+ (option) == CURLOPT_PROXYUSERNAME || \
+ (option) == CURLOPT_PROXYUSERPWD || \
(option) == CURLOPT_RANDOM_FILE || \
(option) == CURLOPT_RANGE || \
+ (option) == CURLOPT_REDIR_PROTOCOLS_STR || \
(option) == CURLOPT_REFERER || \
(option) == CURLOPT_REQUEST_TARGET || \
(option) == CURLOPT_RTSP_SESSION_ID || \
@@ -374,6 +378,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_WRITEDATA || \
(option) == CURLOPT_RESOLVER_START_DATA || \
(option) == CURLOPT_TRAILERDATA || \
+ (option) == CURLOPT_SSH_HOSTKEYDATA || \
0)
/* evaluates to true if option takes a POST data argument (void* or char*) */
diff --git a/Utilities/cmcurl/include/curl/urlapi.h b/Utilities/cmcurl/include/curl/urlapi.h
index a475f91b60..e15c213ccd 100644
--- a/Utilities/cmcurl/include/curl/urlapi.h
+++ b/Utilities/cmcurl/include/curl/urlapi.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl.h"
diff --git a/Utilities/cmcurl/include/curl/websockets.h b/Utilities/cmcurl/include/curl/websockets.h
new file mode 100644
index 0000000000..4d57f91e56
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/websockets.h
@@ -0,0 +1,83 @@
+#ifndef CURLINC_WEBSOCKETS_H
+#define CURLINC_WEBSOCKETS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct curl_ws_frame {
+ int age; /* zero */
+ int flags; /* See the CURLWS_* defines */
+ curl_off_t offset; /* the offset of this data into the frame */
+ curl_off_t bytesleft; /* number of pending bytes left of the payload */
+};
+
+/* flag bits */
+#define CURLWS_TEXT (1<<0)
+#define CURLWS_BINARY (1<<1)
+#define CURLWS_CONT (1<<2)
+#define CURLWS_CLOSE (1<<3)
+#define CURLWS_PING (1<<4)
+#define CURLWS_OFFSET (1<<5)
+
+/*
+ * NAME curl_ws_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the websocket connection. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
+ size_t *recv,
+ struct curl_ws_frame **metap);
+
+/* sendflags for curl_ws_send() */
+#define CURLWS_PONG (1<<6)
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the websocket connection. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer,
+ size_t buflen, size_t *sent,
+ curl_off_t framesize,
+ unsigned int sendflags);
+
+/* bits for the CURLOPT_WS_OPTIONS bitmask: */
+#define CURLWS_RAW_MODE (1<<0)
+
+CURL_EXTERN struct curl_ws_frame *curl_ws_meta(CURL *curl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CURLINC_WEBSOCKETS_H */
diff --git a/Utilities/cmcurl/lib/CMakeLists.txt b/Utilities/cmcurl/lib/CMakeLists.txt
index 6cf45adc34..313847397f 100644
--- a/Utilities/cmcurl/lib/CMakeLists.txt
+++ b/Utilities/cmcurl/lib/CMakeLists.txt
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -18,9 +18,12 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
set(LIB_NAME cmcurl)
set(LIBCURL_OUTPUT_NAME cmcurl)
+add_definitions(-DBUILDING_LIBCURL)
if(BUILD_SHARED_LIBS)
set(CURL_STATICLIB NO)
@@ -143,7 +146,6 @@ endif()
if(WIN32)
if(BUILD_SHARED_LIBS)
- set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "_USRDLL")
if(MSVC)
# Add "_imp" as a suffix before the extension to avoid conflicting with
# the statically linked "libcurl.lib"
@@ -156,16 +158,18 @@ target_include_directories(${LIB_NAME} INTERFACE
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
-install(TARGETS ${LIB_NAME}
- EXPORT ${TARGETS_EXPORT_NAME}
- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-)
-
-export(TARGETS ${LIB_NAME}
- APPEND FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
- NAMESPACE ${PROJECT_NAME}::
-)
+if(CURL_ENABLE_EXPORT_TARGET)
+ install(TARGETS ${LIB_NAME}
+ EXPORT ${TARGETS_EXPORT_NAME}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ )
+
+ export(TARGETS ${LIB_NAME}
+ FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
+ NAMESPACE ${PROJECT_NAME}::
+ )
+endif()
endif()
diff --git a/Utilities/cmcurl/lib/Makefile.inc b/Utilities/cmcurl/lib/Makefile.inc
index 1ab0078966..b2d2e9e52f 100644
--- a/Utilities/cmcurl/lib/Makefile.inc
+++ b/Utilities/cmcurl/lib/Makefile.inc
@@ -18,6 +18,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# SPDX-License-Identifier: curl
+#
###########################################################################
LIB_VAUTH_CFILES = \
@@ -108,7 +110,6 @@ LIB_CFILES = \
content_encoding.c \
cookie.c \
curl_addrinfo.c \
- curl_ctype.c \
curl_des.c \
curl_endian.c \
curl_fnmatch.c \
@@ -127,7 +128,6 @@ LIB_CFILES = \
curl_threads.c \
dict.c \
doh.c \
- dotdot.c \
dynbuf.c \
easy.c \
easygetopt.c \
@@ -135,6 +135,7 @@ LIB_CFILES = \
escape.c \
file.c \
fileinfo.c \
+ fopen.c \
formdata.c \
ftp.c \
ftplistparser.c \
@@ -176,6 +177,7 @@ LIB_CFILES = \
multi.c \
netrc.c \
nonblock.c \
+ noproxy.c \
openldap.c \
parsedate.c \
pingpong.c \
@@ -215,7 +217,8 @@ LIB_CFILES = \
version.c \
version_win32.c \
warnless.c \
- wildcard.c
+ wildcard.c \
+ ws.c
LIB_HFILES = \
altsvc.h \
@@ -260,14 +263,16 @@ LIB_HFILES = \
curlx.h \
dict.h \
doh.h \
- dotdot.h \
dynbuf.h \
+ easy_lock.h \
easyif.h \
easyoptions.h \
escape.h \
file.h \
fileinfo.h \
+ fopen.h \
formdata.h \
+ functypes.h \
ftp.h \
ftplistparser.h \
getinfo.h \
@@ -297,6 +302,7 @@ LIB_HFILES = \
multiif.h \
netrc.h \
nonblock.h \
+ noproxy.h \
parsedate.h \
pingpong.h \
pop3.h \
@@ -336,7 +342,8 @@ LIB_HFILES = \
urldata.h \
version_win32.h \
warnless.h \
- wildcard.h
+ wildcard.h \
+ ws.h
LIB_RCFILES = libcurl.rc
diff --git a/Utilities/cmcurl/lib/altsvc.c b/Utilities/cmcurl/lib/altsvc.c
index dd2d0ebed6..7bca840151 100644
--- a/Utilities/cmcurl/lib/altsvc.c
+++ b/Utilities/cmcurl/lib/altsvc.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
* The Alt-Svc: header is defined in RFC 7838:
@@ -34,7 +36,7 @@
#include "parsedate.h"
#include "sendf.h"
#include "warnless.h"
-#include "rand.h"
+#include "fopen.h"
#include "rename.h"
/* The last 3 #include files should be in this order */
@@ -50,15 +52,7 @@
#define MAX_ALTSVC_ALPNLENSTR "10"
#define MAX_ALTSVC_ALPNLEN 10
-#if defined(USE_QUICHE) && !defined(UNITTESTS)
-#define H3VERSION "h3-29"
-#elif defined(USE_NGTCP2) && !defined(UNITTESTS)
-#define H3VERSION "h3-29"
-#elif defined(USE_MSH3) && !defined(UNITTESTS)
-#define H3VERSION "h3-29"
-#else
#define H3VERSION "h3"
-#endif
static enum alpnid alpn2alpnid(char *name)
{
@@ -184,10 +178,9 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
/*
* Load alt-svc entries from the given file. The text based line-oriented file
- * format is documented here:
- * https://github.com/curl/curl/wiki/QUIC-implementation
+ * format is documented here: https://curl.se/docs/alt-svc.html
*
- * This function only returns error on major problems that prevents alt-svc
+ * This function only returns error on major problems that prevent alt-svc
* handling to work completely. It will ignore individual syntactical errors
* etc.
*/
@@ -336,8 +329,7 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
struct Curl_llist_element *n;
CURLcode result = CURLE_OK;
FILE *out;
- char *tempstore;
- unsigned char randsuffix[9];
+ char *tempstore = NULL;
if(!altsvc)
/* no cache activated */
@@ -351,17 +343,8 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
/* marked as read-only, no file or zero length file name */
return CURLE_OK;
- if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
- return CURLE_FAILED_INIT;
-
- tempstore = aprintf("%s.%s.tmp", file, randsuffix);
- if(!tempstore)
- return CURLE_OUT_OF_MEMORY;
-
- out = fopen(tempstore, FOPEN_WRITETEXT);
- if(!out)
- result = CURLE_WRITE_ERROR;
- else {
+ result = Curl_fopen(data, file, &out, &tempstore);
+ if(!result) {
fputs("# Your alt-svc cache. https://curl.se/docs/alt-svc.html\n"
"# This file was generated by libcurl! Edit at your own risk.\n",
out);
@@ -373,10 +356,10 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
break;
}
fclose(out);
- if(!result && Curl_rename(tempstore, file))
+ if(!result && tempstore && Curl_rename(tempstore, file))
result = CURLE_WRITE_ERROR;
- if(result)
+ if(result && tempstore)
unlink(tempstore);
}
free(tempstore);
@@ -479,6 +462,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
struct altsvc *as;
unsigned short dstport = srcport; /* the same by default */
CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
+ size_t entries = 0;
#ifdef CURL_DISABLE_VERBOSE_STRINGS
(void)data;
#endif
@@ -489,11 +473,10 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
DEBUGASSERT(asi);
- /* Flush all cached alternatives for this source origin, if any */
- altsvc_flush(asi, srcalpnid, srchost, srcport);
-
/* "clear" is a magic keyword */
if(strcasecompare(alpnbuf, "clear")) {
+ /* Flush cached alternatives for this source origin */
+ altsvc_flush(asi, srcalpnid, srchost, srcport);
return CURLE_OK;
}
@@ -511,6 +494,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
bool quoted = FALSE;
time_t maxage = 24 * 3600; /* default is 24 hours */
bool persist = FALSE;
+ bool valid = TRUE;
p++;
if(*p != ':') {
/* host name starts here */
@@ -520,7 +504,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
len = p - hostp;
if(!len || (len >= MAX_ALTSVC_HOSTLEN)) {
infof(data, "Excessive alt-svc host name, ignoring.");
- dstalpnid = ALPN_none;
+ valid = FALSE;
}
else {
memcpy(namebuf, hostp, len);
@@ -537,10 +521,11 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
unsigned long port = strtoul(++p, &end_ptr, 10);
if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
infof(data, "Unknown alt-svc port number, ignoring.");
- dstalpnid = ALPN_none;
+ valid = FALSE;
}
+ else
+ dstport = curlx_ultous(port);
p = end_ptr;
- dstport = curlx_ultous(port);
}
if(*p++ != '\"')
break;
@@ -592,7 +577,12 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
persist = TRUE;
}
}
- if(dstalpnid) {
+ if(dstalpnid && valid) {
+ if(!entries++)
+ /* Flush cached alternatives for this source origin, if any - when
+ this is the first entry of the line. */
+ altsvc_flush(asi, srcalpnid, srchost, srcport);
+
as = altsvc_createid(srchost, dsthost,
srcalpnid, dstalpnid,
srcport, dstport);
@@ -606,10 +596,6 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
Curl_alpnid2str(dstalpnid));
}
}
- else {
- infof(data, "Unknown alt-svc protocol \"%s\", skipping.",
- alpnbuf);
- }
}
else
break;
diff --git a/Utilities/cmcurl/lib/altsvc.h b/Utilities/cmcurl/lib/altsvc.h
index 2ab89e7059..2751d272a1 100644
--- a/Utilities/cmcurl/lib/altsvc.h
+++ b/Utilities/cmcurl/lib/altsvc.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/amigaos.c b/Utilities/cmcurl/lib/amigaos.c
index 78bb22c7e2..e8c2fc02e0 100644
--- a/Utilities/cmcurl/lib/amigaos.c
+++ b/Utilities/cmcurl/lib/amigaos.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,13 +18,23 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#ifdef __AMIGA__
-# include "amigaos.h"
-# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL)
+
+#include <curl/curl.h>
+
+#include "hostip.h"
+#include "amigaos.h"
+
+#ifdef HAVE_PROTO_BSDSOCKET_H
+# if defined(__amigaos4__)
+# include <bsdsocket/socketbasetags.h>
+# elif !defined(USE_AMISSL)
# include <amitcp/socketbasetags.h>
# endif
# ifdef __libnix__
@@ -36,8 +46,154 @@
#include "curl_memory.h"
#include "memdebug.h"
-#ifdef __AMIGA__
-#if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL)
+#ifdef HAVE_PROTO_BSDSOCKET_H
+
+#ifdef __amigaos4__
+/*
+ * AmigaOS 4.x specific code
+ */
+
+/*
+ * hostip4.c - Curl_ipv4_resolve_r() replacement code
+ *
+ * Logic that needs to be considered are the following build cases:
+ * - newlib networking
+ * - clib2 networking
+ * - direct bsdsocket.library networking (usually AmiSSL builds)
+ * Each with the threaded resolver enabled or not.
+ *
+ * With the threaded resolver enabled, try to use gethostbyname_r() where
+ * available, otherwise (re)open bsdsocket.library and fallback to
+ * gethostbyname().
+ */
+
+#include <proto/bsdsocket.h>
+
+static struct SocketIFace *__CurlISocket = NULL;
+static uint32 SocketFeatures = 0;
+
+#define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01
+#define HAVE_BSDSOCKET_GETADDRINFO 0x02
+
+CURLcode Curl_amiga_init(void)
+{
+ struct SocketIFace *ISocket;
+ struct Library *base = OpenLibrary("bsdsocket.library", 4);
+
+ if(base) {
+ ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
+ if(ISocket) {
+ ULONG enabled = 0;
+
+ SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE,
+ SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled,
+ TAG_DONE);
+
+ if(enabled) {
+ SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R;
+ }
+
+ __CurlISocket = ISocket;
+
+ atexit(Curl_amiga_cleanup);
+
+ return CURLE_OK;
+ }
+ CloseLibrary(base);
+ }
+
+ return CURLE_FAILED_INIT;
+}
+
+void Curl_amiga_cleanup(void)
+{
+ if(__CurlISocket) {
+ struct Library *base = __CurlISocket->Data.LibBase;
+ DropInterface((struct Interface *)__CurlISocket);
+ CloseLibrary(base);
+ __CurlISocket = NULL;
+ }
+}
+
+#ifdef CURLRES_AMIGA
+/*
+ * Because we need to handle the different cases in hostip4.c at run-time,
+ * not at compile-time, based on what was detected in Curl_amiga_init(),
+ * we replace it completely with our own as to not complicate the baseline
+ * code. Assumes malloc/calloc/free are thread safe because Curl_he2ai()
+ * allocates memory also.
+ */
+
+struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
+ int port)
+{
+ struct Curl_addrinfo *ai = NULL;
+ struct hostent *h;
+ struct SocketIFace *ISocket = __CurlISocket;
+
+ if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) {
+ LONG h_errnop = 0;
+ struct hostent *buf;
+
+ buf = calloc(1, CURL_HOSTENT_SIZE);
+ if(buf) {
+ h = gethostbyname_r((STRPTR)hostname, buf,
+ (char *)buf + sizeof(struct hostent),
+ CURL_HOSTENT_SIZE - sizeof(struct hostent),
+ &h_errnop);
+ if(h) {
+ ai = Curl_he2ai(h, port);
+ }
+ free(buf);
+ }
+ }
+ else {
+ #ifdef CURLRES_THREADED
+ /* gethostbyname() is not thread safe, so we need to reopen bsdsocket
+ * on the thread's context
+ */
+ struct Library *base = OpenLibrary("bsdsocket.library", 4);
+ if(base) {
+ ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
+ if(ISocket) {
+ h = gethostbyname((STRPTR)hostname);
+ if(h) {
+ ai = Curl_he2ai(h, port);
+ }
+ DropInterface((struct Interface *)ISocket);
+ }
+ CloseLibrary(base);
+ }
+ #else
+ /* not using threaded resolver - safe to use this as-is */
+ h = gethostbyname(hostname);
+ if(h) {
+ ai = Curl_he2ai(h, port);
+ }
+ #endif
+ }
+
+ return ai;
+}
+#endif /* CURLRES_AMIGA */
+
+#ifdef USE_AMISSL
+int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *errorfds, struct timeval *timeout)
+{
+ int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0);
+ /* Ensure Ctrl-C signal is actioned */
+ if((r == -1) && (SOCKERRNO == EINTR))
+ raise(SIGINT);
+ return r;
+}
+#endif /* USE_AMISSL */
+
+#elif !defined(USE_AMISSL) /* __amigaos4__ */
+/*
+ * Amiga OS3 specific code
+ */
+
struct Library *SocketBase = NULL;
extern int errno, h_errno;
@@ -47,7 +203,7 @@ void __request(const char *msg);
# define __request(msg) Printf(msg "\n\a")
#endif
-void Curl_amiga_cleanup()
+void Curl_amiga_cleanup(void)
{
if(SocketBase) {
CloseLibrary(SocketBase);
@@ -55,68 +211,36 @@ void Curl_amiga_cleanup()
}
}
-bool Curl_amiga_init()
+CURLcode Curl_amiga_init(void)
{
if(!SocketBase)
SocketBase = OpenLibrary("bsdsocket.library", 4);
if(!SocketBase) {
__request("No TCP/IP Stack running!");
- return FALSE;
+ return CURLE_FAILED_INIT;
}
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
TAG_DONE)) {
__request("SocketBaseTags ERROR");
- return FALSE;
+ return CURLE_FAILED_INIT;
}
#ifndef __libnix__
atexit(Curl_amiga_cleanup);
#endif
- return TRUE;
+ return CURLE_OK;
}
#ifdef __libnix__
ADD2EXIT(Curl_amiga_cleanup, -50);
#endif
-#endif /* HAVE_PROTO_BSDSOCKET_H */
+#endif /* !USE_AMISSL */
-#ifdef USE_AMISSL
-void Curl_amiga_X509_free(X509 *a)
-{
- X509_free(a);
-}
-
-/* AmiSSL replaces many functions with macros. Curl requires pointer
- * to some of these functions. Thus, we have to encapsulate these macros.
- */
-
-#include "warnless.h"
-
-int (SHA256_Init)(SHA256_CTX *c)
-{
- return SHA256_Init(c);
-};
-
-int (SHA256_Update)(SHA256_CTX *c, const void *data, size_t len)
-{
- return SHA256_Update(c, data, curlx_uztoui(len));
-};
-
-int (SHA256_Final)(unsigned char *md, SHA256_CTX *c)
-{
- return SHA256_Final(md, c);
-};
-
-void (X509_INFO_free)(X509_INFO *a)
-{
- X509_INFO_free(a);
-};
+#endif /* HAVE_PROTO_BSDSOCKET_H */
-#endif /* USE_AMISSL */
#endif /* __AMIGA__ */
-
diff --git a/Utilities/cmcurl/lib/amigaos.h b/Utilities/cmcurl/lib/amigaos.h
index 02e5bb546a..9abfb59eac 100644
--- a/Utilities/cmcurl/lib/amigaos.h
+++ b/Utilities/cmcurl/lib/amigaos.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,25 +20,23 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
-#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL)
+#if defined(__AMIGA__) && defined(HAVE_PROTO_BSDSOCKET_H) && \
+ (!defined(USE_AMISSL) || defined(__amigaos4__))
-bool Curl_amiga_init();
-void Curl_amiga_cleanup();
+CURLcode Curl_amiga_init(void);
+void Curl_amiga_cleanup(void);
#else
-#define Curl_amiga_init() 1
+#define Curl_amiga_init() CURLE_OK
#define Curl_amiga_cleanup() Curl_nop_stmt
#endif
-#ifdef USE_AMISSL
-#include <openssl/x509v3.h>
-void Curl_amiga_X509_free(X509 *a);
-#endif /* USE_AMISSL */
-
#endif /* HEADER_CURL_AMIGAOS_H */
diff --git a/Utilities/cmcurl/lib/arpa_telnet.h b/Utilities/cmcurl/lib/arpa_telnet.h
index cbe31de5a3..523f7f51e7 100644
--- a/Utilities/cmcurl/lib/arpa_telnet.h
+++ b/Utilities/cmcurl/lib/arpa_telnet.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_TELNET
/*
diff --git a/Utilities/cmcurl/lib/asyn-ares.c b/Utilities/cmcurl/lib/asyn-ares.c
index c885adef54..33edba1395 100644
--- a/Utilities/cmcurl/lib/asyn-ares.c
+++ b/Utilities/cmcurl/lib/asyn-ares.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -113,6 +115,7 @@ struct thread_data {
#ifndef HAVE_CARES_GETADDRINFO
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
#endif
+ char hostname[1];
};
/* How long we are willing to wait for additional parallel responses after
@@ -250,8 +253,6 @@ void Curl_resolver_kill(struct Curl_easy *data)
*/
static void destroy_async_data(struct Curl_async *async)
{
- free(async->hostname);
-
if(async->tdata) {
struct thread_data *res = async->tdata;
if(res) {
@@ -263,8 +264,6 @@ static void destroy_async_data(struct Curl_async *async)
}
async->tdata = NULL;
}
-
- async->hostname = NULL;
}
/*
@@ -306,7 +305,7 @@ int Curl_resolver_getsock(struct Curl_easy *data,
* 2) wait for the timeout period to check for action on ares' sockets.
* 3) tell ares to act on all the sockets marked as "with action"
*
- * return number of sockets it worked on
+ * return number of sockets it worked on, or -1 on error
*/
static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
@@ -338,8 +337,11 @@ static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
break;
}
- if(num)
+ if(num) {
nfds = Curl_poll(pfd, num, timeout_ms);
+ if(nfds < 0)
+ return -1;
+ }
else
nfds = 0;
@@ -376,7 +378,8 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
DEBUGASSERT(dns);
*dns = NULL;
- waitperform(data, 0);
+ if(waitperform(data, 0) < 0)
+ return CURLE_UNRECOVERABLE_POLL;
#ifndef HAVE_CARES_GETADDRINFO
/* Now that we've checked for any last minute results above, see if there are
@@ -475,7 +478,8 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
else
timeout_ms = 1000;
- waitperform(data, timeout_ms);
+ if(waitperform(data, timeout_ms) < 0)
+ return CURLE_UNRECOVERABLE_POLL;
result = Curl_resolver_is_resolved(data, entry);
if(result || data->state.async.done)
@@ -742,7 +746,7 @@ static void addrinfo_cb(void *arg, int status, int timeouts,
* Curl_resolver_getaddrinfo() - when using ares
*
* Returns name information about the given hostname and port number. If
- * successful, the 'hostent' is returned and the forth argument will point to
+ * successful, the 'hostent' is returned and the fourth argument will point to
* memory we need to free after use. That memory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else.
*/
@@ -751,25 +755,18 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
int port,
int *waitp)
{
- char *bufp;
-
+ struct thread_data *res = NULL;
+ size_t namelen = strlen(hostname);
*waitp = 0; /* default to synchronous response */
- bufp = strdup(hostname);
- if(bufp) {
- struct thread_data *res = NULL;
- free(data->state.async.hostname);
- data->state.async.hostname = bufp;
+ res = calloc(sizeof(struct thread_data) + namelen, 1);
+ if(res) {
+ strcpy(res->hostname, hostname);
+ data->state.async.hostname = res->hostname;
data->state.async.port = port;
data->state.async.done = FALSE; /* not done */
data->state.async.status = 0; /* clear */
data->state.async.dns = NULL; /* clear */
- res = calloc(sizeof(struct thread_data), 1);
- if(!res) {
- free(data->state.async.hostname);
- data->state.async.hostname = NULL;
- return NULL;
- }
data->state.async.tdata = res;
/* initial status - failed */
@@ -782,13 +779,17 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
int pf = PF_INET;
memset(&hints, 0, sizeof(hints));
#ifdef CURLRES_IPV6
- if(Curl_ipv6works(data))
+ if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
/* The stack seems to be IPv6-enabled */
pf = PF_UNSPEC;
#endif /* CURLRES_IPV6 */
hints.ai_family = pf;
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
SOCK_STREAM : SOCK_DGRAM;
+ /* Since the service is a numerical one, set the hint flags
+ * accordingly to save a call to getservbyname in inside C-Ares
+ */
+ hints.ai_flags = ARES_AI_NUMERICSERV;
msnprintf(service, sizeof(service), "%d", port);
res->num_pending = 1;
ares_getaddrinfo((ares_channel)data->state.async.resolver, hostname,
@@ -797,7 +798,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
#else
#ifdef HAVE_CARES_IPV6
- if(Curl_ipv6works(data)) {
+ if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) {
/* The stack seems to be IPv6-enabled */
res->num_pending = 2;
diff --git a/Utilities/cmcurl/lib/asyn-thread.c b/Utilities/cmcurl/lib/asyn-thread.c
index 149172ad3d..8b375eb5ee 100644
--- a/Utilities/cmcurl/lib/asyn-thread.c
+++ b/Utilities/cmcurl/lib/asyn-thread.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -262,23 +264,28 @@ int init_thread_sync_data(struct thread_data *td,
return 1;
err_exit:
- /* Memory allocation failed */
+#ifndef CURL_DISABLE_SOCKETPAIR
+ if(tsd->sock_pair[0] != CURL_SOCKET_BAD) {
+ sclose(tsd->sock_pair[0]);
+ tsd->sock_pair[0] = CURL_SOCKET_BAD;
+ }
+#endif
destroy_thread_sync_data(tsd);
return 0;
}
-static int getaddrinfo_complete(struct Curl_easy *data)
+static CURLcode getaddrinfo_complete(struct Curl_easy *data)
{
struct thread_sync_data *tsd = conn_thread_sync_data(data);
- int rc;
+ CURLcode result;
- rc = Curl_addrinfo_callback(data, tsd->sock_error, tsd->res);
+ result = Curl_addrinfo_callback(data, tsd->sock_error, tsd->res);
/* The tsd->res structure has been copied to async.dns and perhaps the DNS
cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
*/
tsd->res = NULL;
- return rc;
+ return result;
}
@@ -700,7 +707,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
*waitp = 0; /* default to synchronous response */
#ifdef CURLRES_IPV6
- if(Curl_ipv6works(data))
+ if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
/* The stack seems to be IPv6-enabled */
pf = PF_UNSPEC;
#endif /* CURLRES_IPV6 */
diff --git a/Utilities/cmcurl/lib/asyn.h b/Utilities/cmcurl/lib/asyn.h
index 3130395826..1aab21aaa7 100644
--- a/Utilities/cmcurl/lib/asyn.h
+++ b/Utilities/cmcurl/lib/asyn.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -146,7 +148,7 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
* Curl_resolver_getaddrinfo() - when using this resolver
*
* Returns name information about the given hostname and port number. If
- * successful, the 'hostent' is returned and the forth argument will point to
+ * successful, the 'hostent' is returned and the fourth argument will point to
* memory we need to free after use. That memory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else.
*
diff --git a/Utilities/cmcurl/lib/base64.c b/Utilities/cmcurl/lib/base64.c
index 960a1ca3ad..52654c2bc3 100644
--- a/Utilities/cmcurl/lib/base64.c
+++ b/Utilities/cmcurl/lib/base64.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* Base64 encoding/decoding */
@@ -41,10 +43,11 @@
#include "memdebug.h"
/* ---- Base64 Encoding/Decoding Table --- */
+/* Padding character string starts at offset 64. */
static const char base64[]=
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648
+/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648
section 5 */
static const char base64url[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
@@ -52,25 +55,18 @@ static const char base64url[]=
static size_t decodeQuantum(unsigned char *dest, const char *src)
{
size_t padding = 0;
- const char *s, *p;
+ const char *s;
unsigned long i, x = 0;
for(i = 0, s = src; i < 4; i++, s++) {
if(*s == '=') {
- x = (x << 6);
+ x <<= 6;
padding++;
}
else {
- unsigned long v = 0;
- p = base64;
-
- while(*p && (*p != *s)) {
- v++;
- p++;
- }
-
- if(*p == *s)
- x = (x << 6) + v;
+ const char *p = strchr(base64, *s);
+ if(p)
+ x = (x << 6) + curlx_uztoul(p - base64);
else
return 0;
}
@@ -107,11 +103,11 @@ CURLcode Curl_base64_decode(const char *src,
unsigned char **outptr, size_t *outlen)
{
size_t srclen = 0;
- size_t length = 0;
size_t padding = 0;
size_t i;
size_t numQuantums;
size_t rawlen = 0;
+ const char *padptr;
unsigned char *pos;
unsigned char *newstr;
@@ -124,19 +120,17 @@ CURLcode Curl_base64_decode(const char *src,
return CURLE_BAD_CONTENT_ENCODING;
/* Find the position of any = padding characters */
- while((src[length] != '=') && src[length])
- length++;
-
- /* A maximum of two = padding characters is allowed */
- if(src[length] == '=') {
+ padptr = strchr(src, '=');
+ if(padptr) {
padding++;
- if(src[length + 1] == '=')
+ /* A maximum of two = padding characters is allowed */
+ if(padptr[1] == '=')
padding++;
- }
- /* Check the = padding characters weren't part way through the input */
- if(length + padding != srclen)
- return CURLE_BAD_CONTENT_ENCODING;
+ /* Check the = padding characters weren't part way through the input */
+ if(padptr + padding != src + srclen)
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
/* Calculate the number of quantums */
numQuantums = srclen / 4;
@@ -144,7 +138,7 @@ CURLcode Curl_base64_decode(const char *src,
/* Calculate the size of the decoded string */
rawlen = (numQuantums * 3) - padding;
- /* Allocate our buffer including room for a zero terminator */
+ /* Allocate our buffer including room for a null-terminator */
newstr = malloc(rawlen + 1);
if(!newstr)
return CURLE_OUT_OF_MEMORY;
@@ -185,6 +179,7 @@ static CURLcode base64_encode(const char *table64,
char *output;
char *base64data;
const char *indata = inputbuff;
+ const char *padstr = &table64[64]; /* Point to padding string. */
*outptr = NULL;
*outlen = 0;
@@ -222,27 +217,30 @@ static CURLcode base64_encode(const char *table64,
switch(inputparts) {
case 1: /* only one byte read */
- msnprintf(output, 5, "%c%c==",
- table64[obuf[0]],
- table64[obuf[1]]);
+ i = msnprintf(output, 5, "%c%c%s%s",
+ table64[obuf[0]],
+ table64[obuf[1]],
+ padstr,
+ padstr);
break;
case 2: /* two bytes read */
- msnprintf(output, 5, "%c%c%c=",
- table64[obuf[0]],
- table64[obuf[1]],
- table64[obuf[2]]);
+ i = msnprintf(output, 5, "%c%c%c%s",
+ table64[obuf[0]],
+ table64[obuf[1]],
+ table64[obuf[2]],
+ padstr);
break;
default:
- msnprintf(output, 5, "%c%c%c%c",
- table64[obuf[0]],
- table64[obuf[1]],
- table64[obuf[2]],
- table64[obuf[3]]);
+ i = msnprintf(output, 5, "%c%c%c%c",
+ table64[obuf[0]],
+ table64[obuf[1]],
+ table64[obuf[2]],
+ table64[obuf[3]]);
break;
}
- output += 4;
+ output += i;
}
/* Zero terminate */
@@ -270,8 +268,6 @@ static CURLcode base64_encode(const char *table64,
* Returns CURLE_OK on success, otherwise specific error code. Function
* output shall not be considered valid unless CURLE_OK is returned.
*
- * When encoded data length is 0, returns NULL in *outptr.
- *
* @unittest: 1302
*/
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
@@ -293,8 +289,6 @@ CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
* Returns CURLE_OK on success, otherwise specific error code. Function
* output shall not be considered valid unless CURLE_OK is returned.
*
- * When encoded data length is 0, returns NULL in *outptr.
- *
* @unittest: 1302
*/
CURLcode Curl_base64url_encode(const char *inputbuff, size_t insize,
diff --git a/Utilities/cmcurl/lib/bufref.c b/Utilities/cmcurl/lib/bufref.c
index b84511e185..91b037431d 100644
--- a/Utilities/cmcurl/lib/bufref.c
+++ b/Utilities/cmcurl/lib/bufref.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2021 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/bufref.h b/Utilities/cmcurl/lib/bufref.h
index 25f65d894d..96b818b537 100644
--- a/Utilities/cmcurl/lib/bufref.h
+++ b/Utilities/cmcurl/lib/bufref.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2021 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
diff --git a/Utilities/cmcurl/lib/c-hyper.c b/Utilities/cmcurl/lib/c-hyper.c
index 69082982cf..86abcdb0fa 100644
--- a/Utilities/cmcurl/lib/c-hyper.c
+++ b/Utilities/cmcurl/lib/c-hyper.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -52,6 +54,7 @@
#include "multiif.h"
#include "progress.h"
#include "content_encoding.h"
+#include "ws.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -288,7 +291,7 @@ static CURLcode status_line(struct Curl_easy *data,
len);
if(!data->state.hconnect || !data->set.suppress_connect_headers) {
- writetype = CLIENTWRITE_HEADER;
+ writetype = CLIENTWRITE_HEADER|CLIENTWRITE_STATUS;
if(data->set.include_header)
writetype |= CLIENTWRITE_BODY;
result = Curl_client_write(data, writetype,
@@ -469,6 +472,24 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
if(result)
break;
+ k->deductheadercount =
+ (100 <= http_status && 199 >= http_status)?k->headerbytecount:0;
+#ifdef USE_WEBSOCKETS
+ if(k->upgr101 == UPGR101_WS) {
+ if(http_status == 101) {
+ /* verify the response */
+ result = Curl_ws_accept(data);
+ if(result)
+ return result;
+ }
+ else {
+ failf(data, "Expected 101, got %u", k->httpcode);
+ result = CURLE_HTTP_RETURNED_ERROR;
+ break;
+ }
+ }
+#endif
+
/* Curl_http_auth_act() checks what authentication methods that are
* available and decides which one (if any) to use. It will set 'newurl'
* if an auth method was picked. */
@@ -690,9 +711,18 @@ static int uploadstreamed(void *userdata, hyper_context *ctx,
data->state.hresult = result;
return HYPER_POLL_ERROR;
}
- if(!fillcount)
- /* done! */
- *chunk = NULL;
+ if(!fillcount) {
+ if((data->req.keepon & KEEP_SEND_PAUSE) != KEEP_SEND_PAUSE)
+ /* done! */
+ *chunk = NULL;
+ else {
+ /* paused, save a waker */
+ if(data->hyp.send_body_waker)
+ hyper_waker_free(data->hyp.send_body_waker);
+ data->hyp.send_body_waker = hyper_context_waker(ctx);
+ return HYPER_POLL_PENDING;
+ }
+ }
else {
hyper_buf *copy = hyper_buf_copy((uint8_t *)data->state.ulbuf, fillcount);
if(copy)
@@ -907,12 +937,13 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
result = CURLE_OUT_OF_MEMORY;
goto error;
}
- if(conn->negnpn == CURL_HTTP_VERSION_2) {
+ if(conn->alpn == CURL_HTTP_VERSION_2) {
hyper_clientconn_options_http2(options, 1);
h2 = TRUE;
}
hyper_clientconn_options_set_preserve_header_case(options, 1);
hyper_clientconn_options_set_preserve_header_order(options, 1);
+ hyper_clientconn_options_http1_allow_multiline_headers(options, 1);
hyper_clientconn_options_exec(options, h->exec);
@@ -1002,10 +1033,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
/* For HTTP/2, we show the Host: header as if we sent it, to make it look
like for HTTP/1 but it isn't actually sent since :authority is then
used. */
- result = Curl_debug(data, CURLINFO_HEADER_OUT, data->state.aptr.host,
- strlen(data->state.aptr.host));
- if(result)
- goto error;
+ Curl_debug(data, CURLINFO_HEADER_OUT, data->state.aptr.host,
+ strlen(data->state.aptr.host));
}
if(data->state.aptr.proxyuserpwd) {
@@ -1047,6 +1076,21 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
goto error;
}
+#ifndef CURL_DISABLE_ALTSVC
+ if(conn->bits.altused && !Curl_checkheaders(data, STRCONST("Alt-Used"))) {
+ char *altused = aprintf("Alt-Used: %s:%d\r\n",
+ conn->conn_to_host.name, conn->conn_to_port);
+ if(!altused) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ result = Curl_hyper_header(data, headers, altused);
+ if(result)
+ goto error;
+ free(altused);
+ }
+#endif
+
#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy &&
!Curl_checkheaders(data, STRCONST("Proxy-Connection")) &&
@@ -1098,6 +1142,9 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
if(result)
goto error;
+ if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS))
+ result = Curl_ws_request(data, headers);
+
result = Curl_add_timecondition(data, headers);
if(result)
goto error;
@@ -1110,9 +1157,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
if(result)
goto error;
- result = Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"\r\n", 2);
- if(result)
- goto error;
+ Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"\r\n", 2);
data->req.upload_chunky = FALSE;
sendtask = hyper_clientconn_send(client, req);
diff --git a/Utilities/cmcurl/lib/c-hyper.h b/Utilities/cmcurl/lib/c-hyper.h
index d63defeffe..70507ad2a4 100644
--- a/Utilities/cmcurl/lib/c-hyper.h
+++ b/Utilities/cmcurl/lib/c-hyper.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -34,6 +36,7 @@ struct hyptransfer {
const hyper_executor *exec;
hyper_task *endtask;
hyper_waker *exp100_waker;
+ hyper_waker *send_body_waker;
};
size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
diff --git a/Utilities/cmcurl/lib/conncache.c b/Utilities/cmcurl/lib/conncache.c
index aa29620fa3..a557ac6dc9 100644
--- a/Utilities/cmcurl/lib/conncache.c
+++ b/Utilities/cmcurl/lib/conncache.c
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -496,7 +498,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
conn = curr->ptr;
if(!CONN_INUSE(conn) && !conn->bits.close &&
- !conn->bits.connect_only) {
+ !conn->connect_only) {
/* Set higher score for the age passed since the connection was used */
score = Curl_timediff(now, conn->lastused);
diff --git a/Utilities/cmcurl/lib/conncache.h b/Utilities/cmcurl/lib/conncache.h
index ef11dcfd29..94664bc357 100644
--- a/Utilities/cmcurl/lib/conncache.h
+++ b/Utilities/cmcurl/lib/conncache.h
@@ -21,6 +21,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -29,6 +31,7 @@
* be shared.
*/
+#include <curl/curl.h>
#include "timeval.h"
struct connectdata;
diff --git a/Utilities/cmcurl/lib/connect.c b/Utilities/cmcurl/lib/connect.c
index 9bcf525ebb..ac007c61b0 100644
--- a/Utilities/cmcurl/lib/connect.c
+++ b/Utilities/cmcurl/lib/connect.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -470,8 +472,10 @@ static CURLcode bindlocal(struct Curl_easy *data,
}
if(--portnum > 0) {
- infof(data, "Bind to local port %hu failed, trying next", port);
port++; /* try next port */
+ if(port == 0)
+ break;
+ infof(data, "Bind to local port %hu failed, trying next", port - 1);
/* We re-use/clobber the port variable here below */
if(sock->sa_family == AF_INET)
si4->sin_port = ntohs(port);
@@ -621,7 +625,8 @@ void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn,
else
data->info.conn_local_ip[0] = 0;
data->info.conn_scheme = conn->handler->scheme;
- data->info.conn_protocol = conn->handler->protocol;
+ /* conn_protocol can only provide "old" protocols */
+ data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK;
data->info.conn_primary_port = conn->port;
data->info.conn_remote_port = conn->remote_port;
data->info.conn_local_port = local_port;
@@ -757,11 +762,10 @@ void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn,
char local_ip[MAX_IPADR_LEN] = "";
int local_port = -1;
- if(conn->transport == TRNSPRT_TCP) {
- if(!conn->bits.reuse && !conn->bits.tcp_fastopen)
- Curl_conninfo_remote(data, conn, sockfd);
- Curl_conninfo_local(data, sockfd, local_ip, &local_port);
- } /* end of TCP-only section */
+ if(!conn->bits.reuse &&
+ (conn->transport != TRNSPRT_TCP || !conn->bits.tcp_fastopen))
+ Curl_conninfo_remote(data, conn, sockfd);
+ Curl_conninfo_local(data, sockfd, local_ip, &local_port);
/* persist connection info in session handle */
Curl_persistconninfo(data, conn, local_ip, local_port);
@@ -899,6 +903,8 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
conn->tempsock[i] = CURL_SOCKET_BAD;
post_SOCKS(data, conn, sockindex, connected);
connkeep(conn, "HTTP/3 default");
+ if(conn->tempsock[other] != CURL_SOCKET_BAD)
+ Curl_quic_disconnect(data, conn, other);
return CURLE_OK;
}
/* When a QUIC connect attempt fails, the better error explanation is in
@@ -1033,7 +1039,6 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
(conn->tempsock[1] == CURL_SOCKET_BAD)) {
/* no more addresses to try */
const char *hostname;
- char buffer[STRERROR_LEN];
CURLcode failreason = result;
/* if the first address family runs out of addresses to try before the
@@ -1060,11 +1065,7 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
"%" CURL_FORMAT_TIMEDIFF_T " ms: %s",
hostname, conn->port,
Curl_timediff(now, data->progress.t_startsingle),
-#ifdef ENABLE_QUIC
- (conn->transport == TRNSPRT_QUIC) ?
- curl_easy_strerror(result) :
-#endif
- Curl_strerror(error, buffer, sizeof(buffer)));
+ curl_easy_strerror(result));
Curl_quic_disconnect(data, conn, 0);
Curl_quic_disconnect(data, conn, 1);
@@ -1196,6 +1197,7 @@ static CURLcode singleipconnect(struct Curl_easy *data,
#ifdef TCP_FASTOPEN_CONNECT
int optval = 1;
#endif
+ const char *ipmsg;
char buffer[STRERROR_LEN];
curl_socket_t *sockp = &conn->tempsock[tempindex];
*sockp = CURL_SOCKET_BAD;
@@ -1213,7 +1215,13 @@ static CURLcode singleipconnect(struct Curl_easy *data,
Curl_closesocket(data, conn, sockfd);
return CURLE_OK;
}
- infof(data, " Trying %s:%d...", ipaddress, port);
+#ifdef ENABLE_IPV6
+ if(addr.family == AF_INET6)
+ ipmsg = " Trying [%s]:%d...";
+ else
+#endif
+ ipmsg = " Trying %s:%d...";
+ infof(data, ipmsg, ipaddress, port);
#ifdef ENABLE_IPV6
is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
@@ -1600,9 +1608,20 @@ CURLcode Curl_socket(struct Curl_easy *data,
*/
addr->family = ai->ai_family;
- addr->socktype = (conn->transport == TRNSPRT_TCP) ? SOCK_STREAM : SOCK_DGRAM;
- addr->protocol = conn->transport != TRNSPRT_TCP ? IPPROTO_UDP :
- ai->ai_protocol;
+ switch(conn->transport) {
+ case TRNSPRT_TCP:
+ addr->socktype = SOCK_STREAM;
+ addr->protocol = IPPROTO_TCP;
+ break;
+ case TRNSPRT_UNIX:
+ addr->socktype = SOCK_STREAM;
+ addr->protocol = IPPROTO_IP;
+ break;
+ default: /* UDP and QUIC */
+ addr->socktype = SOCK_DGRAM;
+ addr->protocol = IPPROTO_UDP;
+ break;
+ }
addr->addrlen = ai->ai_addrlen;
if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
@@ -1636,6 +1655,24 @@ CURLcode Curl_socket(struct Curl_easy *data,
if(conn->transport == TRNSPRT_QUIC) {
/* QUIC sockets need to be nonblocking */
(void)curlx_nonblock(*sockfd, TRUE);
+ switch(addr->family) {
+#if defined(__linux__) && defined(IP_MTU_DISCOVER)
+ case AF_INET: {
+ int val = IP_PMTUDISC_DO;
+ (void)setsockopt(*sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &val,
+ sizeof(val));
+ break;
+ }
+#endif
+#if defined(__linux__) && defined(IPV6_MTU_DISCOVER)
+ case AF_INET6: {
+ int val = IPV6_PMTUDISC_DO;
+ (void)setsockopt(*sockfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val,
+ sizeof(val));
+ break;
+ }
+#endif
+ }
}
#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
@@ -1645,20 +1682,6 @@ CURLcode Curl_socket(struct Curl_easy *data,
}
#endif
-#if defined(__linux__) && defined(IP_RECVERR)
- if(addr->socktype == SOCK_DGRAM) {
- int one = 1;
- switch(addr->family) {
- case AF_INET:
- (void)setsockopt(*sockfd, SOL_IP, IP_RECVERR, &one, sizeof(one));
- break;
- case AF_INET6:
- (void)setsockopt(*sockfd, SOL_IPV6, IPV6_RECVERR, &one, sizeof(one));
- break;
- }
- }
-#endif
-
return CURLE_OK;
}
diff --git a/Utilities/cmcurl/lib/connect.h b/Utilities/cmcurl/lib/connect.h
index 1a055f58de..582ff0813d 100644
--- a/Utilities/cmcurl/lib/connect.h
+++ b/Utilities/cmcurl/lib/connect.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/content_encoding.c b/Utilities/cmcurl/lib/content_encoding.c
index 4c723c3af3..9e345b197e 100644
--- a/Utilities/cmcurl/lib/content_encoding.c
+++ b/Utilities/cmcurl/lib/content_encoding.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -26,7 +28,7 @@
#include <curl/curl.h>
#include <stddef.h>
-#ifdef HAVE_ZLIB_H
+#ifdef HAVE_LIBZ
#include <cm3p/zlib.h>
#endif
@@ -80,8 +82,9 @@ typedef enum {
ZLIB_INIT_GZIP /* initialized in transparent gzip mode */
} zlibInitState;
-/* Writer parameters. */
-struct zlib_params {
+/* Deflate and gzip writer. */
+struct zlib_writer {
+ struct contenc_writer super;
zlibInitState zlib_init; /* zlib init state */
uInt trailerlen; /* Remaining trailer byte count. */
z_stream z; /* State structure for zlib. */
@@ -133,7 +136,7 @@ exit_zlib(struct Curl_easy *data,
}
static CURLcode process_trailer(struct Curl_easy *data,
- struct zlib_params *zp)
+ struct zlib_writer *zp)
{
z_stream *z = &zp->z;
CURLcode result = CURLE_OK;
@@ -160,7 +163,7 @@ static CURLcode inflate_stream(struct Curl_easy *data,
struct contenc_writer *writer,
zlibInitState started)
{
- struct zlib_params *zp = (struct zlib_params *) &writer->params;
+ struct zlib_writer *zp = (struct zlib_writer *) writer;
z_stream *z = &zp->z; /* zlib state structure */
uInt nread = z->avail_in;
Bytef *orig_in = z->next_in;
@@ -263,7 +266,7 @@ static CURLcode inflate_stream(struct Curl_easy *data,
static CURLcode deflate_init_writer(struct Curl_easy *data,
struct contenc_writer *writer)
{
- struct zlib_params *zp = (struct zlib_params *) &writer->params;
+ struct zlib_writer *zp = (struct zlib_writer *) writer;
z_stream *z = &zp->z; /* zlib state structure */
if(!writer->downstream)
@@ -283,7 +286,7 @@ static CURLcode deflate_unencode_write(struct Curl_easy *data,
struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
- struct zlib_params *zp = (struct zlib_params *) &writer->params;
+ struct zlib_writer *zp = (struct zlib_writer *) writer;
z_stream *z = &zp->z; /* zlib state structure */
/* Set the compressed input when this function is called */
@@ -300,7 +303,7 @@ static CURLcode deflate_unencode_write(struct Curl_easy *data,
static void deflate_close_writer(struct Curl_easy *data,
struct contenc_writer *writer)
{
- struct zlib_params *zp = (struct zlib_params *) &writer->params;
+ struct zlib_writer *zp = (struct zlib_writer *) writer;
z_stream *z = &zp->z; /* zlib state structure */
exit_zlib(data, z, &zp->zlib_init, CURLE_OK);
@@ -312,7 +315,7 @@ static const struct content_encoding deflate_encoding = {
deflate_init_writer,
deflate_unencode_write,
deflate_close_writer,
- sizeof(struct zlib_params)
+ sizeof(struct zlib_writer)
};
@@ -320,7 +323,7 @@ static const struct content_encoding deflate_encoding = {
static CURLcode gzip_init_writer(struct Curl_easy *data,
struct contenc_writer *writer)
{
- struct zlib_params *zp = (struct zlib_params *) &writer->params;
+ struct zlib_writer *zp = (struct zlib_writer *) writer;
z_stream *z = &zp->z; /* zlib state structure */
if(!writer->downstream)
@@ -437,7 +440,7 @@ static CURLcode gzip_unencode_write(struct Curl_easy *data,
struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
- struct zlib_params *zp = (struct zlib_params *) &writer->params;
+ struct zlib_writer *zp = (struct zlib_writer *) writer;
z_stream *z = &zp->z; /* zlib state structure */
if(zp->zlib_init == ZLIB_INIT_GZIP) {
@@ -564,7 +567,7 @@ static CURLcode gzip_unencode_write(struct Curl_easy *data,
static void gzip_close_writer(struct Curl_easy *data,
struct contenc_writer *writer)
{
- struct zlib_params *zp = (struct zlib_params *) &writer->params;
+ struct zlib_writer *zp = (struct zlib_writer *) writer;
z_stream *z = &zp->z; /* zlib state structure */
exit_zlib(data, z, &zp->zlib_init, CURLE_OK);
@@ -576,15 +579,16 @@ static const struct content_encoding gzip_encoding = {
gzip_init_writer,
gzip_unencode_write,
gzip_close_writer,
- sizeof(struct zlib_params)
+ sizeof(struct zlib_writer)
};
#endif /* HAVE_LIBZ */
#ifdef HAVE_BROTLI
-/* Writer parameters. */
-struct brotli_params {
+/* Brotli writer. */
+struct brotli_writer {
+ struct contenc_writer super;
BrotliDecoderState *br; /* State structure for brotli. */
};
@@ -629,7 +633,7 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
static CURLcode brotli_init_writer(struct Curl_easy *data,
struct contenc_writer *writer)
{
- struct brotli_params *bp = (struct brotli_params *) &writer->params;
+ struct brotli_writer *bp = (struct brotli_writer *) writer;
(void) data;
if(!writer->downstream)
@@ -643,7 +647,7 @@ static CURLcode brotli_unencode_write(struct Curl_easy *data,
struct contenc_writer *writer,
const char *buf, size_t nbytes)
{
- struct brotli_params *bp = (struct brotli_params *) &writer->params;
+ struct brotli_writer *bp = (struct brotli_writer *) writer;
const uint8_t *src = (const uint8_t *) buf;
char *decomp;
uint8_t *dst;
@@ -690,7 +694,8 @@ static CURLcode brotli_unencode_write(struct Curl_easy *data,
static void brotli_close_writer(struct Curl_easy *data,
struct contenc_writer *writer)
{
- struct brotli_params *bp = (struct brotli_params *) &writer->params;
+ struct brotli_writer *bp = (struct brotli_writer *) writer;
+
(void) data;
if(bp->br) {
@@ -705,14 +710,15 @@ static const struct content_encoding brotli_encoding = {
brotli_init_writer,
brotli_unencode_write,
brotli_close_writer,
- sizeof(struct brotli_params)
+ sizeof(struct brotli_writer)
};
#endif
#ifdef HAVE_ZSTD
-/* Writer parameters. */
-struct zstd_params {
+/* Zstd writer. */
+struct zstd_writer {
+ struct contenc_writer super;
ZSTD_DStream *zds; /* State structure for zstd. */
void *decomp;
};
@@ -720,7 +726,8 @@ struct zstd_params {
static CURLcode zstd_init_writer(struct Curl_easy *data,
struct contenc_writer *writer)
{
- struct zstd_params *zp = (struct zstd_params *)&writer->params;
+ struct zstd_writer *zp = (struct zstd_writer *) writer;
+
(void)data;
if(!writer->downstream)
@@ -736,7 +743,7 @@ static CURLcode zstd_unencode_write(struct Curl_easy *data,
const char *buf, size_t nbytes)
{
CURLcode result = CURLE_OK;
- struct zstd_params *zp = (struct zstd_params *)&writer->params;
+ struct zstd_writer *zp = (struct zstd_writer *) writer;
ZSTD_inBuffer in;
ZSTD_outBuffer out;
size_t errorCode;
@@ -775,7 +782,8 @@ static CURLcode zstd_unencode_write(struct Curl_easy *data,
static void zstd_close_writer(struct Curl_easy *data,
struct contenc_writer *writer)
{
- struct zstd_params *zp = (struct zstd_params *)&writer->params;
+ struct zstd_writer *zp = (struct zstd_writer *) writer;
+
(void)data;
if(zp->decomp) {
@@ -794,7 +802,7 @@ static const struct content_encoding zstd_encoding = {
zstd_init_writer,
zstd_unencode_write,
zstd_close_writer,
- sizeof(struct zstd_params)
+ sizeof(struct zstd_writer)
};
#endif
@@ -827,7 +835,7 @@ static const struct content_encoding identity_encoding = {
identity_init_writer,
identity_unencode_write,
identity_close_writer,
- 0
+ sizeof(struct contenc_writer)
};
@@ -919,7 +927,7 @@ static const struct content_encoding client_encoding = {
client_init_writer,
client_unencode_write,
client_close_writer,
- 0
+ sizeof(struct contenc_writer)
};
@@ -962,7 +970,7 @@ static const struct content_encoding error_encoding = {
error_init_writer,
error_unencode_write,
error_close_writer,
- 0
+ sizeof(struct contenc_writer)
};
/* Create an unencoding writer stage using the given handler. */
@@ -971,8 +979,10 @@ new_unencoding_writer(struct Curl_easy *data,
const struct content_encoding *handler,
struct contenc_writer *downstream)
{
- size_t sz = offsetof(struct contenc_writer, params) + handler->paramsize;
- struct contenc_writer *writer = (struct contenc_writer *)calloc(1, sz);
+ struct contenc_writer *writer;
+
+ DEBUGASSERT(handler->writersize >= sizeof(struct contenc_writer));
+ writer = (struct contenc_writer *) calloc(1, handler->writersize);
if(writer) {
writer->handler = handler;
@@ -1026,19 +1036,23 @@ static const struct content_encoding *find_encoding(const char *name,
return NULL;
}
+/* allow no more than 5 "chained" compression steps */
+#define MAX_ENCODE_STACK 5
+
/* Set-up the unencoding stack from the Content-Encoding header value.
* See RFC 7231 section 3.1.2.2. */
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
const char *enclist, int maybechunked)
{
struct SingleRequest *k = &data->req;
+ int counter = 0;
do {
const char *name;
size_t namelen;
/* Parse a single encoding name. */
- while(ISSPACE(*enclist) || *enclist == ',')
+ while(ISBLANK(*enclist) || *enclist == ',')
enclist++;
name = enclist;
@@ -1066,6 +1080,11 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
if(!encoding)
encoding = &error_encoding; /* Defer error at stack use. */
+ if(++counter >= MAX_ENCODE_STACK) {
+ failf(data, "Reject response due to %u content encodings",
+ counter);
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
/* Stack the unencoding stage. */
writer = new_unencoding_writer(data, encoding, k->writer_stack);
if(!writer)
diff --git a/Utilities/cmcurl/lib/content_encoding.h b/Utilities/cmcurl/lib/content_encoding.h
index acfd0c27b0..3c278cf727 100644
--- a/Utilities/cmcurl/lib/content_encoding.h
+++ b/Utilities/cmcurl/lib/content_encoding.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,13 +20,14 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
struct contenc_writer {
const struct content_encoding *handler; /* Encoding handler. */
struct contenc_writer *downstream; /* Downstream writer. */
- void *params; /* Encoding-specific storage (variable length). */
};
/* Content encoding writer. */
@@ -40,7 +41,7 @@ struct content_encoding {
const char *buf, size_t nbytes);
void (*close_writer)(struct Curl_easy *data,
struct contenc_writer *writer);
- size_t paramsize;
+ size_t writersize;
};
diff --git a/Utilities/cmcurl/lib/cookie.c b/Utilities/cmcurl/lib/cookie.c
index 0c2d49b478..8eaedeeb7f 100644
--- a/Utilities/cmcurl/lib/cookie.c
+++ b/Utilities/cmcurl/lib/cookie.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/***
@@ -33,8 +35,9 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
called before any cookies are set.
struct Cookie *Curl_cookie_add(struct Curl_easy *data,
- struct CookieInfo *c, bool httpheader, char *lineptr,
- const char *domain, const char *path);
+ struct CookieInfo *c, bool httpheader, bool noexpire,
+ char *lineptr, const char *domain, const char *path,
+ bool secure);
The 'lineptr' parameter is a full "Set-cookie:" line as
received from a server.
@@ -96,8 +99,8 @@ Example set of cookies:
#include "curl_get_line.h"
#include "curl_memrchr.h"
#include "parsedate.h"
-#include "rand.h"
#include "rename.h"
+#include "fopen.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -439,6 +442,29 @@ static bool bad_domain(const char *domain)
}
/*
+ RFC 6265 section 4.1.1 says a server should accept this range:
+
+ cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
+
+ But Firefox and Chrome as of June 2022 accept space, comma and double-quotes
+ fine. The prime reason for filtering out control bytes is that some HTTP
+ servers return 400 for requests that contain such.
+*/
+static int invalid_octets(const char *p)
+{
+ /* Reject all bytes \x01 - \x1f (*except* \x09, TAB) + \x7f */
+ static const char badoctets[] = {
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x0a"
+ "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+ "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f"
+ };
+ size_t len;
+ /* scan for all the octets that are *not* in cookie-octet */
+ len = strcspn(p, badoctets);
+ return (p[len] != '\0');
+}
+
+/*
* Curl_cookie_add
*
* Add a single cookie line to the cookie keeping object. Be aware that
@@ -468,6 +494,8 @@ Curl_cookie_add(struct Curl_easy *data,
struct Cookie *clist;
struct Cookie *co;
struct Cookie *lastc = NULL;
+ struct Cookie *replace_co = NULL;
+ struct Cookie *replace_clist = NULL;
time_t now = time(NULL);
bool replace_old = FALSE;
bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
@@ -477,6 +505,10 @@ Curl_cookie_add(struct Curl_easy *data,
(void)data;
#endif
+ DEBUGASSERT(MAX_SET_COOKIE_AMOUNT <= 255); /* counter is an unsigned char */
+ if(data->req.setcookies >= MAX_SET_COOKIE_AMOUNT)
+ return NULL;
+
/* First, alloc and init a new struct for it */
co = calloc(1, sizeof(struct Cookie));
if(!co)
@@ -505,7 +537,7 @@ Curl_cookie_add(struct Curl_easy *data,
do {
/* we have a <what>=<this> pair or a stand-alone word here */
name[0] = what[0] = 0; /* init the buffers */
- if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n=] =%"
+ if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\t\r\n=] =%"
MAX_NAME_TXT "[^;\r\n]",
name, what)) {
/*
@@ -559,6 +591,13 @@ Curl_cookie_add(struct Curl_easy *data,
while(*whatptr && ISBLANK(*whatptr))
whatptr++;
+ /* Reject cookies with a TAB inside the content */
+ if(strchr(whatptr, '\t')) {
+ freecookie(co);
+ infof(data, "cookie contains TAB, dropping");
+ return NULL;
+ }
+
/*
* Check if we have a reserved prefix set before anything else, as we
* otherwise have to test for the prefix in both the cookie name and
@@ -586,6 +625,11 @@ Curl_cookie_add(struct Curl_easy *data,
badcookie = TRUE;
break;
}
+ if(invalid_octets(whatptr) || invalid_octets(name)) {
+ infof(data, "invalid octets in name/value, cookie dropped");
+ badcookie = TRUE;
+ break;
+ }
}
else if(!len) {
/*
@@ -628,7 +672,7 @@ Curl_cookie_add(struct Curl_easy *data,
break;
}
}
- else if(strcasecompare("domain", name)) {
+ else if(strcasecompare("domain", name) && whatptr[0]) {
bool is_ip;
/*
@@ -816,7 +860,7 @@ Curl_cookie_add(struct Curl_easy *data,
freecookie(co);
return NULL;
}
-
+ data->req.setcookies++;
}
else {
/*
@@ -1020,12 +1064,53 @@ Curl_cookie_add(struct Curl_easy *data,
}
#endif
+ /* A non-secure cookie may not overlay an existing secure cookie. */
myhash = cookiehash(co->domain);
clist = c->cookies[myhash];
- replace_old = FALSE;
while(clist) {
if(strcasecompare(clist->name, co->name)) {
/* the names are identical */
+ bool matching_domains = FALSE;
+
+ if(clist->domain && co->domain) {
+ if(strcasecompare(clist->domain, co->domain))
+ /* The domains are identical */
+ matching_domains = TRUE;
+ }
+ else if(!clist->domain && !co->domain)
+ matching_domains = TRUE;
+
+ if(matching_domains && /* the domains were identical */
+ clist->spath && co->spath && /* both have paths */
+ clist->secure && !co->secure && !secure) {
+ size_t cllen;
+ const char *sep;
+
+ /*
+ * A non-secure cookie may not overlay an existing secure cookie.
+ * For an existing cookie "a" with path "/login", refuse a new
+ * cookie "a" with for example path "/login/en", while the path
+ * "/loginhelper" is ok.
+ */
+
+ sep = strchr(clist->spath + 1, '/');
+
+ if(sep)
+ cllen = sep - clist->spath;
+ else
+ cllen = strlen(clist->spath);
+
+ if(strncasecompare(clist->spath, co->spath, cllen)) {
+ infof(data, "cookie '%s' for domain '%s' dropped, would "
+ "overlay an existing cookie", co->name, co->domain);
+ freecookie(co);
+ return NULL;
+ }
+ }
+ }
+
+ if(!replace_co && strcasecompare(clist->name, co->name)) {
+ /* the names are identical */
if(clist->domain && co->domain) {
if(strcasecompare(clist->domain, co->domain) &&
@@ -1040,30 +1125,7 @@ Curl_cookie_add(struct Curl_easy *data,
/* the domains were identical */
if(clist->spath && co->spath) {
- if(clist->secure && !co->secure && !secure) {
- size_t cllen;
- const char *sep;
-
- /*
- * A non-secure cookie may not overlay an existing secure cookie.
- * For an existing cookie "a" with path "/login", refuse a new
- * cookie "a" with for example path "/login/en", while the path
- * "/loginhelper" is ok.
- */
-
- sep = strchr(clist->spath + 1, '/');
-
- if(sep)
- cllen = sep - clist->spath;
- else
- cllen = strlen(clist->spath);
-
- if(strncasecompare(clist->spath, co->spath, cllen)) {
- freecookie(co);
- return NULL;
- }
- }
- else if(strcasecompare(clist->spath, co->spath))
+ if(strcasecompare(clist->spath, co->spath))
replace_old = TRUE;
else
replace_old = FALSE;
@@ -1085,42 +1147,37 @@ Curl_cookie_add(struct Curl_easy *data,
freecookie(co);
return NULL;
}
-
if(replace_old) {
- co->next = clist->next; /* get the next-pointer first */
-
- /* when replacing, creationtime is kept from old */
- co->creationtime = clist->creationtime;
-
- /* then free all the old pointers */
- free(clist->name);
- free(clist->value);
- free(clist->domain);
- free(clist->path);
- free(clist->spath);
- free(clist->expirestr);
- free(clist->version);
- free(clist->maxage);
-
- *clist = *co; /* then store all the new 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
- */
- do {
- lastc = clist;
- clist = clist->next;
- } while(clist);
- break;
+ replace_co = co;
+ replace_clist = clist;
}
}
lastc = clist;
clist = clist->next;
}
+ if(replace_co) {
+ co = replace_co;
+ clist = replace_clist;
+ co->next = clist->next; /* get the next-pointer first */
+
+ /* when replacing, creationtime is kept from old */
+ co->creationtime = clist->creationtime;
+
+ /* then free all the old pointers */
+ free(clist->name);
+ free(clist->value);
+ free(clist->domain);
+ free(clist->path);
+ free(clist->spath);
+ free(clist->expirestr);
+ free(clist->version);
+ free(clist->maxage);
+
+ *clist = *co; /* then store all the new data */
+
+ free(co); /* free the newly allocated memory */
+ co = clist;
+ }
if(c->running)
/* Only show this when NOT reading the cookies from a file */
@@ -1357,7 +1414,8 @@ static struct Cookie *dup_cookie(struct Cookie *src)
*
* It shall only return cookies that haven't expired.
*/
-struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
+struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
+ struct CookieInfo *c,
const char *host, const char *path,
bool secure)
{
@@ -1412,6 +1470,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
mainco = newco;
matches++;
+ if(matches >= MAX_COOKIE_SEND_AMOUNT) {
+ infof(data, "Included max number of cookies (%zu) in request!",
+ matches);
+ break;
+ }
}
else
goto fail;
@@ -1613,20 +1676,9 @@ static CURLcode cookie_output(struct Curl_easy *data,
use_stdout = TRUE;
}
else {
- unsigned char randsuffix[9];
-
- if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
- return 2;
-
- tempstore = aprintf("%s.%s.tmp", filename, randsuffix);
- if(!tempstore)
- return CURLE_OUT_OF_MEMORY;
-
- out = fopen(tempstore, FOPEN_WRITETEXT);
- if(!out) {
- error = CURLE_WRITE_ERROR;
+ error = Curl_fopen(data, filename, &out, &tempstore);
+ if(error)
goto error;
- }
}
fputs("# Netscape HTTP Cookie File\n"
@@ -1673,7 +1725,7 @@ static CURLcode cookie_output(struct Curl_easy *data,
if(!use_stdout) {
fclose(out);
out = NULL;
- if(Curl_rename(tempstore, filename)) {
+ if(tempstore && Curl_rename(tempstore, filename)) {
unlink(tempstore);
error = CURLE_WRITE_ERROR;
goto error;
diff --git a/Utilities/cmcurl/lib/cookie.h b/Utilities/cmcurl/lib/cookie.h
index 0ffe08e63a..abc0a2e8a0 100644
--- a/Utilities/cmcurl/lib/cookie.h
+++ b/Utilities/cmcurl/lib/cookie.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -81,10 +83,26 @@ struct CookieInfo {
*/
#define MAX_COOKIE_LINE 5000
-/* This is the maximum length of a cookie name or content we deal with: */
+/* Maximum length of an incoming cookie name or content we deal with. Longer
+ cookies are ignored. */
#define MAX_NAME 4096
#define MAX_NAME_TXT "4095"
+/* Maximum size for an outgoing cookie line libcurl will use in an http
+ request. This is the default maximum length used in some versions of Apache
+ httpd. */
+#define MAX_COOKIE_HEADER_LEN 8190
+
+/* Maximum number of cookies libcurl will send in a single request, even if
+ there might be more cookies that match. One reason to cap the number is to
+ keep the maximum HTTP request within the maximum allowed size. */
+#define MAX_COOKIE_SEND_AMOUNT 150
+
+/* Maximum number of Set-Cookie: lines accepted in a single response. If more
+ such header lines are received, they are ignored. This value must be less
+ than 256 since an unsigned char is used to count. */
+#define MAX_SET_COOKIE_AMOUNT 50
+
struct Curl_easy;
/*
* Add a cookie to the internal list of cookies. The domain and path arguments
@@ -97,7 +115,8 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data,
const char *domain, const char *path,
bool secure);
-struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, const char *host,
+struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
+ struct CookieInfo *c, const char *host,
const char *path, bool secure);
void Curl_cookie_freelist(struct Cookie *cookies);
void Curl_cookie_clearall(struct CookieInfo *cookies);
diff --git a/Utilities/cmcurl/lib/curl_addrinfo.c b/Utilities/cmcurl/lib/curl_addrinfo.c
index 842fd7fe24..72e778b34e 100644
--- a/Utilities/cmcurl/lib/curl_addrinfo.c
+++ b/Utilities/cmcurl/lib/curl_addrinfo.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -277,7 +279,7 @@ Curl_he2ai(const struct hostent *he, int port)
for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) {
size_t ss_size;
- size_t namelen = strlen(he->h_name) + 1; /* include zero termination */
+ size_t namelen = strlen(he->h_name) + 1; /* include null-terminatior */
#ifdef ENABLE_IPV6
if(he->h_addrtype == AF_INET6)
ss_size = sizeof(struct sockaddr_in6);
diff --git a/Utilities/cmcurl/lib/curl_addrinfo.h b/Utilities/cmcurl/lib/curl_addrinfo.h
index 73a8c1b334..b778121a7c 100644
--- a/Utilities/cmcurl/lib/curl_addrinfo.h
+++ b/Utilities/cmcurl/lib/curl_addrinfo.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_base64.h b/Utilities/cmcurl/lib/curl_base64.h
index 4cb9d73537..85368a163c 100644
--- a/Utilities/cmcurl/lib/curl_base64.h
+++ b/Utilities/cmcurl/lib/curl_base64.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
diff --git a/Utilities/cmcurl/lib/curl_config.h.cmake b/Utilities/cmcurl/lib/curl_config.h.cmake
index 4a6f90e3a7..b8a58c831b 100644
--- a/Utilities/cmcurl/lib/curl_config.h.cmake
+++ b/Utilities/cmcurl/lib/curl_config.h.cmake
@@ -18,15 +18,14 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* lib/curl_config.h.in. Generated somehow by cmake. */
#include <cm3p/kwiml/abi.h>
-/* when building libcurl itself */
-#cmakedefine BUILDING_LIBCURL 1
-
-/* to disable alt-svc */
+/* disables alt-svc */
#cmakedefine CURL_DISABLE_ALTSVC 1
/* disables cookies support */
@@ -138,9 +137,6 @@
/* Define to 1 if you have the alarm function. */
#cmakedefine HAVE_ALARM 1
-/* Define to 1 if you have the <alloca.h> header file. */
-#cmakedefine HAVE_ALLOCA_H 1
-
/* Define to 1 if you have the <arpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H 1
@@ -150,6 +146,12 @@
/* Define to 1 if you have the <assert.h> header file. */
#cmakedefine HAVE_ASSERT_H 1
+/* Define to 1 if you have _Atomic support. */
+#cmakedefine HAVE_ATOMIC 1
+
+/* Define to 1 if you have the `fchmod' function. */
+#cmakedefine HAVE_FCHMOD 1
+
/* Define to 1 if you have the `basename' function. */
#cmakedefine HAVE_BASENAME 1
@@ -165,12 +167,6 @@
/* Define to 1 if you have the `closesocket' function. */
#cmakedefine HAVE_CLOSESOCKET 1
-/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
-#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#cmakedefine HAVE_DLFCN_H 1
-
/* Define to 1 if you have the <errno.h> header file. */
#cmakedefine HAVE_ERRNO_H 1
@@ -192,15 +188,15 @@
/* Define to 1 if you have a working getaddrinfo function. */
#cmakedefine HAVE_GETADDRINFO 1
+/* Define to 1 if the getaddrinfo function is threadsafe. */
+#cmakedefine HAVE_GETADDRINFO_THREADSAFE 1
+
/* Define to 1 if you have the `geteuid' function. */
#cmakedefine HAVE_GETEUID 1
/* Define to 1 if you have the `getppid' function. */
#cmakedefine HAVE_GETPPID 1
-/* Define to 1 if you have the gethostbyname function. */
-#cmakedefine HAVE_GETHOSTBYNAME 1
-
/* Define to 1 if you have the gethostbyname_r function. */
#cmakedefine HAVE_GETHOSTBYNAME_R 1
@@ -225,9 +221,6 @@
/* Define to 1 if you have the `getppid' function. */
#cmakedefine HAVE_GETPPID 1
-/* Define to 1 if you have the `getprotobyname' function. */
-#cmakedefine HAVE_GETPROTOBYNAME 1
-
/* Define to 1 if you have the `getpeername' function. */
#cmakedefine HAVE_GETPEERNAME 1
@@ -279,18 +272,9 @@
/* Define to 1 if you have the `idna_strerror' function. */
#cmakedefine HAVE_IDNA_STRERROR 1
-/* Define to 1 if you have the `idn_free' function. */
-#cmakedefine HAVE_IDN_FREE 1
-
-/* Define to 1 if you have the <idn-free.h> header file. */
-#cmakedefine HAVE_IDN_FREE_H 1
-
/* Define to 1 if you have the <ifaddrs.h> header file. */
#cmakedefine HAVE_IFADDRS_H 1
-/* Define to 1 if you have the `inet_addr' function. */
-#cmakedefine HAVE_INET_ADDR 1
-
/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
#cmakedefine HAVE_INET_NTOP 1
@@ -306,9 +290,6 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
-/* Define to 1 if you have the ioctl function. */
-#cmakedefine HAVE_IOCTL 1
-
/* Define to 1 if you have the ioctlsocket function. */
#cmakedefine HAVE_IOCTLSOCKET 1
@@ -331,21 +312,9 @@
/* Define to 1 if you have the <io.h> header file. */
#cmakedefine HAVE_IO_H 1
-/* if you have the Kerberos4 libraries (including -ldes) */
-#cmakedefine HAVE_KRB4 1
-
-/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
-#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM 1
-
-/* Define to 1 if you have the <krb.h> header file. */
-#cmakedefine HAVE_KRB_H 1
-
/* Define to 1 if you have the lber.h header file. */
#cmakedefine HAVE_LBER_H 1
-/* Define to 1 if you have the ldapssl.h header file. */
-#cmakedefine HAVE_LDAPSSL_H 1
-
/* Define to 1 if you have the ldap.h header file. */
#cmakedefine HAVE_LDAP_H 1
@@ -367,24 +336,12 @@
/* Define to 1 if you have the idn2.h header file. */
#cmakedefine HAVE_IDN2_H 1
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-#cmakedefine HAVE_LIBRESOLV 1
-
-/* Define to 1 if you have the `resolve' library (-lresolve). */
-#cmakedefine HAVE_LIBRESOLVE 1
-
/* Define to 1 if you have the `socket' library (-lsocket). */
#cmakedefine HAVE_LIBSOCKET 1
/* Define to 1 if you have the `ssh2' library (-lssh2). */
#cmakedefine HAVE_LIBSSH2 1
-/* Define to 1 if you have the <libssh2.h> header file. */
-#cmakedefine HAVE_LIBSSH2_H 1
-
-/* Define to 1 if you have the <libssh/libssh.h> header file. */
-#cmakedefine HAVE_LIBSSH_LIBSSH_H 1
-
/* if zlib is available */
#cmakedefine HAVE_LIBZ 1
@@ -397,20 +354,11 @@
/* Define to 1 if you have the <locale.h> header file. */
#cmakedefine HAVE_LOCALE_H 1
-/* Define to 1 if you have a working localtime_r function. */
-#cmakedefine HAVE_LOCALTIME_R 1
-
/* Define to 1 if the compiler supports the 'long long' data type. */
#if KWIML_ABI_SIZEOF_LONG_LONG
# define HAVE_LONGLONG 1
#endif
-/* Define to 1 if you have the malloc.h header file. */
-#cmakedefine HAVE_MALLOC_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#cmakedefine HAVE_MEMORY_H 1
-
/* Define to 1 if you have the MSG_NOSIGNAL flag. */
#cmakedefine HAVE_MSG_NOSIGNAL 1
@@ -429,42 +377,12 @@
/* Define to 1 if you have the <net/if.h> header file. */
#cmakedefine HAVE_NET_IF_H 1
-/* Define to 1 if NI_WITHSCOPEID exists and works. */
-#cmakedefine HAVE_NI_WITHSCOPEID 1
-
/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */
#cmakedefine HAVE_OLD_GSSMIT 1
-/* Define to 1 if you have the <openssl/crypto.h> header file. */
-#cmakedefine HAVE_OPENSSL_CRYPTO_H 1
-
-/* Define to 1 if you have the <openssl/err.h> header file. */
-#cmakedefine HAVE_OPENSSL_ERR_H 1
-
-/* Define to 1 if you have the <openssl/pem.h> header file. */
-#cmakedefine HAVE_OPENSSL_PEM_H 1
-
-/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
-#cmakedefine HAVE_OPENSSL_PKCS12_H 1
-
-/* Define to 1 if you have the <openssl/rsa.h> header file. */
-#cmakedefine HAVE_OPENSSL_RSA_H 1
-
-/* Define to 1 if you have the <openssl/ssl.h> header file. */
-#cmakedefine HAVE_OPENSSL_SSL_H 1
-
-/* Define to 1 if you have the <openssl/x509.h> header file. */
-#cmakedefine HAVE_OPENSSL_X509_H 1
-
-/* Define to 1 if you have the <pem.h> header file. */
-#cmakedefine HAVE_PEM_H 1
-
/* Define to 1 if you have the `pipe' function. */
#cmakedefine HAVE_PIPE 1
-/* Define to 1 if you have a working poll function. */
-#cmakedefine HAVE_POLL 1
-
/* If you have a fine poll */
#cmakedefine HAVE_POLL_FINE 1
@@ -483,18 +401,9 @@
/* Define to 1 if you have the `RAND_egd' function. */
#cmakedefine HAVE_RAND_EGD 1
-/* Define to 1 if you have the `RAND_screen' function. */
-#cmakedefine HAVE_RAND_SCREEN 1
-
-/* Define to 1 if you have the `RAND_status' function. */
-#cmakedefine HAVE_RAND_STATUS 1
-
/* Define to 1 if you have the recv function. */
#cmakedefine HAVE_RECV 1
-/* Define to 1 if you have the recvfrom function. */
-#cmakedefine HAVE_RECVFROM 1
-
/* Define to 1 if you have the select function. */
#cmakedefine HAVE_SELECT 1
@@ -522,9 +431,6 @@
/* Define to 1 if you have the `setrlimit' function. */
#cmakedefine HAVE_SETRLIMIT 1
-/* Define to 1 if you have the setsockopt function. */
-#cmakedefine HAVE_SETSOCKOPT 1
-
/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1
@@ -549,27 +455,27 @@
/* Define to 1 if you have the `socket' function. */
#cmakedefine HAVE_SOCKET 1
+/* Define to 1 if you have the socketpair function. */
+#cmakedefine HAVE_SOCKETPAIR 1
+
/* Define to 1 if you have the <ssl.h> header file. */
#cmakedefine HAVE_SSL_H 1
+/* Define to 1 if you have the <stdatomic.h> header file. */
+#cmakedefine HAVE_STDATOMIC_H 1
+
/* Define to 1 if you have the <stdbool.h> header file. */
#cmakedefine HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H 1
-/* Define to 1 if you have the <stdio.h> header file. */
-#cmakedefine HAVE_STDIO_H 1
-
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H 1
/* Define to 1 if you have the strcasecmp function. */
#cmakedefine HAVE_STRCASECMP 1
-/* Define to 1 if you have the strcasestr function. */
-#cmakedefine HAVE_STRCASESTR 1
-
/* Define to 1 if you have the strcmpi function. */
#cmakedefine HAVE_STRCMPI 1
@@ -588,18 +494,9 @@
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H 1
-/* Define to 1 if you have the strncmpi function. */
-#cmakedefine HAVE_STRNCMPI 1
-
-/* Define to 1 if you have the strnicmp function. */
-#cmakedefine HAVE_STRNICMP 1
-
/* Define to 1 if you have the <stropts.h> header file. */
#cmakedefine HAVE_STROPTS_H 1
-/* Define to 1 if you have the strstr function. */
-#cmakedefine HAVE_STRSTR 1
-
/* Define to 1 if you have the strtok_r function. */
#cmakedefine HAVE_STRTOK_R 1
@@ -645,9 +542,6 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H 1
-/* Define to 1 if you have the <sys/uio.h> header file. */
-#cmakedefine HAVE_SYS_UIO_H 1
-
/* Define to 1 if you have the <sys/un.h> header file. */
#cmakedefine HAVE_SYS_UN_H 1
@@ -663,15 +557,6 @@
/* Define to 1 if you have the <time.h> header file. */
#cmakedefine HAVE_TIME_H 1
-/* Define to 1 if you have the <tld.h> header file. */
-#cmakedefine HAVE_TLD_H 1
-
-/* Define to 1 if you have the `tld_strerror' function. */
-#cmakedefine HAVE_TLD_STRERROR 1
-
-/* Define to 1 if you have the `uname' function. */
-#cmakedefine HAVE_UNAME 1
-
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
@@ -690,9 +575,6 @@
/* Define to 1 if compiler supports old gcc variadic macro style. */
#cmakedefine HAVE_VARIADIC_MACROS_GCC 1
-/* Define to 1 if you have the winber.h header file. */
-#cmakedefine HAVE_WINBER_H 1
-
/* Define to 1 if you have the windows.h header file. */
#cmakedefine HAVE_WINDOWS_H 1
@@ -705,28 +587,12 @@
/* Define this symbol if your OS supports changing the contents of argv */
#cmakedefine HAVE_WRITABLE_ARGV 1
-/* Define to 1 if you have the writev function. */
-#cmakedefine HAVE_WRITEV 1
-
/* Define to 1 if you have the ws2tcpip.h header file. */
#cmakedefine HAVE_WS2TCPIP_H 1
-/* Define to 1 if you have the <x509.h> header file. */
-#cmakedefine HAVE_X509_H 1
-
/* Define if you have the <process.h> header file. */
#cmakedefine HAVE_PROCESS_H 1
-/* if you have the zlib.h header file */
-#cmakedefine HAVE_ZLIB_H 1
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#cmakedefine LT_OBJDIR ${LT_OBJDIR}
-
-/* If you lack a fine basename() prototype */
-#cmakedefine NEED_BASENAME_PROTO 1
-
/* Define to 1 if you need the lber.h header file even with ldap.h */
#cmakedefine NEED_LBER_H 1
@@ -760,84 +626,6 @@
/* a suitable file to read random data from */
#cmakedefine RANDOM_FILE "${RANDOM_FILE}"
-/* Define to the type of arg 1 for recvfrom. */
-#cmakedefine RECVFROM_TYPE_ARG1 ${RECVFROM_TYPE_ARG1}
-
-/* Define to the type pointed by arg 2 for recvfrom. */
-#cmakedefine RECVFROM_TYPE_ARG2 ${RECVFROM_TYPE_ARG2}
-
-/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
-#cmakedefine RECVFROM_TYPE_ARG2_IS_VOID 1
-
-/* Define to the type of arg 3 for recvfrom. */
-#cmakedefine RECVFROM_TYPE_ARG3 ${RECVFROM_TYPE_ARG3}
-
-/* Define to the type of arg 4 for recvfrom. */
-#cmakedefine RECVFROM_TYPE_ARG4 ${RECVFROM_TYPE_ARG4}
-
-/* Define to the type pointed by arg 5 for recvfrom. */
-#cmakedefine RECVFROM_TYPE_ARG5 ${RECVFROM_TYPE_ARG5}
-
-/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
-#cmakedefine RECVFROM_TYPE_ARG5_IS_VOID 1
-
-/* Define to the type pointed by arg 6 for recvfrom. */
-#cmakedefine RECVFROM_TYPE_ARG6 ${RECVFROM_TYPE_ARG6}
-
-/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
-#cmakedefine RECVFROM_TYPE_ARG6_IS_VOID 1
-
-/* Define to the function return type for recvfrom. */
-#cmakedefine RECVFROM_TYPE_RETV ${RECVFROM_TYPE_RETV}
-
-/* Define to the type of arg 1 for recv. */
-#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}
-
-/* Define to the type of arg 2 for recv. */
-#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}
-
-/* Define to the type of arg 3 for recv. */
-#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}
-
-/* Define to the type of arg 4 for recv. */
-#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}
-
-/* Define to the function return type for recv. */
-#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV}
-
-/* Define to the type qualifier of arg 5 for select. */
-#cmakedefine SELECT_QUAL_ARG5 ${SELECT_QUAL_ARG5}
-
-/* Define to the type of arg 1 for select. */
-#cmakedefine SELECT_TYPE_ARG1 ${SELECT_TYPE_ARG1}
-
-/* Define to the type of args 2, 3 and 4 for select. */
-#cmakedefine SELECT_TYPE_ARG234 ${SELECT_TYPE_ARG234}
-
-/* Define to the type of arg 5 for select. */
-#cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5}
-
-/* Define to the function return type for select. */
-#cmakedefine SELECT_TYPE_RETV ${SELECT_TYPE_RETV}
-
-/* Define to the type qualifier of arg 2 for send. */
-#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}
-
-/* Define to the type of arg 1 for send. */
-#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}
-
-/* Define to the type of arg 2 for send. */
-#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}
-
-/* Define to the type of arg 3 for send. */
-#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}
-
-/* Define to the type of arg 4 for send. */
-#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}
-
-/* Define to the function return type for send. */
-#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV}
-
/*
Note: SIZEOF_* variables are fetched with CMake through check_type_size().
As per CMake documentation on CheckTypeSize, C preprocessor code is
@@ -882,9 +670,6 @@ ${SIZEOF_TIME_T_CODE}
/* Define to 1 if you have the ANSI C header files. */
#cmakedefine STDC_HEADERS 1
-/* Define to the type of arg 3 for strerror_r. */
-#cmakedefine STRERROR_R_TYPE_ARG3 ${STRERROR_R_TYPE_ARG3}
-
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#cmakedefine TIME_WITH_SYS_TIME 1
@@ -918,6 +703,9 @@ ${SIZEOF_TIME_T_CODE}
/* if libSSH2 is in use */
#cmakedefine USE_LIBSSH2 1
+/* if libPSL is in use */
+#cmakedefine USE_LIBPSL 1
+
/* If you want to build curl with the built-in manual */
#cmakedefine USE_MANUAL 1
@@ -967,9 +755,6 @@ ${SIZEOF_TIME_T_CODE}
/* enable multiple SSL backends */
#cmakedefine CURL_WITH_MULTI_SSL 1
-/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
-#cmakedefine USE_YASSLEMUL 1
-
/* Version number of package */
#cmakedefine VERSION ${VERSION}
@@ -1023,3 +808,6 @@ ${SIZEOF_TIME_T_CODE}
/* to make the compiler know the prototypes of Windows IDN APIs */
#cmakedefine WANT_IDN_PROTOTYPES 1
+
+/* Define to 1 to enable websocket support. */
+#cmakedefine USE_WEBSOCKETS 1
diff --git a/Utilities/cmcurl/lib/curl_ctype.c b/Utilities/cmcurl/lib/curl_ctype.c
deleted file mode 100644
index 233a69e76f..0000000000
--- a/Utilities/cmcurl/lib/curl_ctype.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#undef _U
-#define _U (1<<0) /* upper case */
-#undef _L
-#define _L (1<<1) /* lower case */
-#undef _N
-#define _N (1<<2) /* decimal numerical digit */
-#undef _S
-#define _S (1<<3) /* space */
-#undef _P
-#define _P (1<<4) /* punctuation */
-#undef _C
-#define _C (1<<5) /* control */
-#undef _X
-#define _X (1<<6) /* hexadecimal letter */
-#undef _B
-#define _B (1<<7) /* blank */
-
-static const unsigned char ascii[128] = {
- _C, _C, _C, _C, _C, _C, _C, _C,
- _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C,
- _C, _C, _C, _C, _C, _C, _C, _C,
- _C, _C, _C, _C, _C, _C, _C, _C,
- _S|_B, _P, _P, _P, _P, _P, _P, _P,
- _P, _P, _P, _P, _P, _P, _P, _P,
- _N, _N, _N, _N, _N, _N, _N, _N,
- _N, _N, _P, _P, _P, _P, _P, _P,
- _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
- _U, _U, _U, _U, _U, _U, _U, _U,
- _U, _U, _U, _U, _U, _U, _U, _U,
- _U, _U, _U, _P, _P, _P, _P, _P,
- _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
- _L, _L, _L, _L, _L, _L, _L, _L,
- _L, _L, _L, _L, _L, _L, _L, _L,
- _L, _L, _L, _P, _P, _P, _P, _C
-};
-
-int Curl_isspace(int c)
-{
- if((c < 0) || (c >= 0x80))
- return FALSE;
- return (ascii[c] & _S);
-}
-
-int Curl_isdigit(int c)
-{
- if((c < 0) || (c >= 0x80))
- return FALSE;
- return (ascii[c] & _N);
-}
-
-int Curl_isalnum(int c)
-{
- if((c < 0) || (c >= 0x80))
- return FALSE;
- return (ascii[c] & (_N|_U|_L));
-}
-
-int Curl_isxdigit(int c)
-{
- if((c < 0) || (c >= 0x80))
- return FALSE;
- return (ascii[c] & (_N|_X));
-}
-
-int Curl_isgraph(int c)
-{
- if((c < 0) || (c >= 0x80) || (c == ' '))
- return FALSE;
- return (ascii[c] & (_N|_X|_U|_L|_P|_S));
-}
-
-int Curl_isprint(int c)
-{
- if((c < 0) || (c >= 0x80))
- return FALSE;
- return (ascii[c] & (_N|_X|_U|_L|_P|_S));
-}
-
-int Curl_isalpha(int c)
-{
- if((c < 0) || (c >= 0x80))
- return FALSE;
- return (ascii[c] & (_U|_L));
-}
-
-int Curl_isupper(int c)
-{
- if((c < 0) || (c >= 0x80))
- return FALSE;
- return (ascii[c] & (_U));
-}
-
-int Curl_islower(int c)
-{
- if((c < 0) || (c >= 0x80))
- return FALSE;
- return (ascii[c] & (_L));
-}
-
-int Curl_iscntrl(int c)
-{
- if((c < 0) || (c >= 0x80))
- return FALSE;
- return (ascii[c] & (_C));
-}
-
diff --git a/Utilities/cmcurl/lib/curl_ctype.h b/Utilities/cmcurl/lib/curl_ctype.h
index 2fa749dca9..dc6b8cab86 100644
--- a/Utilities/cmcurl/lib/curl_ctype.h
+++ b/Utilities/cmcurl/lib/curl_ctype.h
@@ -20,34 +20,28 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
-#include "curl_setup.h"
+#define ISLOWHEXALHA(x) (((x) >= 'a') && ((x) <= 'f'))
+#define ISUPHEXALHA(x) (((x) >= 'A') && ((x) <= 'F'))
-int Curl_isspace(int c);
-int Curl_isdigit(int c);
-int Curl_isalnum(int c);
-int Curl_isxdigit(int c);
-int Curl_isgraph(int c);
-int Curl_isprint(int c);
-int Curl_isalpha(int c);
-int Curl_isupper(int c);
-int Curl_islower(int c);
-int Curl_iscntrl(int c);
+#define ISLOWCNTRL(x) ((x) >= 0 && ((x) <= 0x1f))
+#define IS7F(x) ((x) == 0x7f)
-#define ISSPACE(x) (Curl_isspace((int) ((unsigned char)x)))
-#define ISDIGIT(x) (Curl_isdigit((int) ((unsigned char)x)))
-#define ISALNUM(x) (Curl_isalnum((int) ((unsigned char)x)))
-#define ISXDIGIT(x) (Curl_isxdigit((int) ((unsigned char)x)))
-#define ISGRAPH(x) (Curl_isgraph((int) ((unsigned char)x)))
-#define ISALPHA(x) (Curl_isalpha((int) ((unsigned char)x)))
-#define ISPRINT(x) (Curl_isprint((int) ((unsigned char)x)))
-#define ISUPPER(x) (Curl_isupper((int) ((unsigned char)x)))
-#define ISLOWER(x) (Curl_islower((int) ((unsigned char)x)))
-#define ISCNTRL(x) (Curl_iscntrl((int) ((unsigned char)x)))
-#define ISASCII(x) (((x) >= 0) && ((x) <= 0x80))
+#define ISLOWPRINT(x) (((x) >= 9) && ((x) <= 0x0d))
-#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \
- (((unsigned char)x) == '\t'))
+#define ISPRINT(x) (ISLOWPRINT(x) || (((x) >= ' ') && ((x) <= 0x7e)))
+#define ISGRAPH(x) (ISLOWPRINT(x) || (((x) > ' ') && ((x) <= 0x7e)))
+#define ISCNTRL(x) (ISLOWCNTRL(x) || IS7F(x))
+#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x))
+#define ISXDIGIT(x) (ISDIGIT(x) || ISLOWHEXALHA(x) || ISUPHEXALHA(x))
+#define ISALNUM(x) (ISDIGIT(x) || ISLOWER(x) || ISUPPER(x))
+#define ISUPPER(x) (((x) >= 'A') && ((x) <= 'Z'))
+#define ISLOWER(x) (((x) >= 'a') && ((x) <= 'z'))
+#define ISDIGIT(x) (((x) >= '0') && ((x) <= '9'))
+#define ISBLANK(x) (((x) == ' ') || ((x) == '\t'))
+#define ISSPACE(x) (ISBLANK(x) || (((x) >= 0xa) && ((x) <= 0x0d)))
#endif /* HEADER_CURL_CTYPE_H */
diff --git a/Utilities/cmcurl/lib/curl_des.c b/Utilities/cmcurl/lib/curl_des.c
index 5f28ef4f33..a2bf648c29 100644
--- a/Utilities/cmcurl/lib/curl_des.c
+++ b/Utilities/cmcurl/lib/curl_des.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -39,7 +41,7 @@
*
* The function is a port of the Java based oddParity() function over at:
*
- * https://davenport.sourceforge.io/ntlm.html
+ * https://davenport.sourceforge.net/ntlm.html
*
* Parameters:
*
diff --git a/Utilities/cmcurl/lib/curl_des.h b/Utilities/cmcurl/lib/curl_des.h
index 3d0fd92600..c1c167471a 100644
--- a/Utilities/cmcurl/lib/curl_des.h
+++ b/Utilities/cmcurl/lib/curl_des.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_endian.c b/Utilities/cmcurl/lib/curl_endian.c
index ecde74bfb1..3cc7734f31 100644
--- a/Utilities/cmcurl/lib/curl_endian.c
+++ b/Utilities/cmcurl/lib/curl_endian.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_endian.h b/Utilities/cmcurl/lib/curl_endian.h
index 4e12d7da4d..758d55f2c5 100644
--- a/Utilities/cmcurl/lib/curl_endian.h
+++ b/Utilities/cmcurl/lib/curl_endian.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* Converts a 16-bit integer from little endian */
diff --git a/Utilities/cmcurl/lib/curl_fnmatch.c b/Utilities/cmcurl/lib/curl_fnmatch.c
index 4bfa58598e..0dd1eb5ef5 100644
--- a/Utilities/cmcurl/lib/curl_fnmatch.c
+++ b/Utilities/cmcurl/lib/curl_fnmatch.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_fnmatch.h b/Utilities/cmcurl/lib/curl_fnmatch.h
index 1c80ea7793..8324be533d 100644
--- a/Utilities/cmcurl/lib/curl_fnmatch.h
+++ b/Utilities/cmcurl/lib/curl_fnmatch.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#define CURL_FNMATCH_MATCH 0
diff --git a/Utilities/cmcurl/lib/curl_get_line.c b/Utilities/cmcurl/lib/curl_get_line.c
index 8f3b0bd8c1..22e3705f4c 100644
--- a/Utilities/cmcurl/lib/curl_get_line.c
+++ b/Utilities/cmcurl/lib/curl_get_line.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,12 +18,14 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
- !defined(CURL_DISABLE_HSTS)
+ !defined(CURL_DISABLE_HSTS) || !defined(CURL_DISABLE_NETRC)
#include "curl_get_line.h"
#include "curl_memory.h"
@@ -31,8 +33,8 @@
#include "memdebug.h"
/*
- * get_line() makes sure to only return complete whole lines that fit in 'len'
- * bytes and end with a newline.
+ * Curl_get_line() makes sure to only return complete whole lines that fit in
+ * 'len' bytes and end with a newline.
*/
char *Curl_get_line(char *buf, int len, FILE *input)
{
diff --git a/Utilities/cmcurl/lib/curl_get_line.h b/Utilities/cmcurl/lib/curl_get_line.h
index 597aa09a9c..b2a534d001 100644
--- a/Utilities/cmcurl/lib/curl_get_line.h
+++ b/Utilities/cmcurl/lib/curl_get_line.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* get_line() makes sure to only return complete whole lines that fit in 'len'
diff --git a/Utilities/cmcurl/lib/curl_gethostname.c b/Utilities/cmcurl/lib/curl_gethostname.c
index 2d5ff61cf6..4747e938db 100644
--- a/Utilities/cmcurl/lib/curl_gethostname.c
+++ b/Utilities/cmcurl/lib/curl_gethostname.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_gethostname.h b/Utilities/cmcurl/lib/curl_gethostname.h
index 2161c40ac3..b7360969ac 100644
--- a/Utilities/cmcurl/lib/curl_gethostname.h
+++ b/Utilities/cmcurl/lib/curl_gethostname.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* Hostname buffer size */
diff --git a/Utilities/cmcurl/lib/curl_gssapi.c b/Utilities/cmcurl/lib/curl_gssapi.c
index 1543a0ff46..01ab48ec3e 100644
--- a/Utilities/cmcurl/lib/curl_gssapi.c
+++ b/Utilities/cmcurl/lib/curl_gssapi.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -89,7 +91,7 @@ static size_t display_gss_error(OM_uint32 status, int type,
OM_uint32 maj_stat;
OM_uint32 min_stat;
OM_uint32 msg_ctx = 0;
- gss_buffer_desc status_string;
+ gss_buffer_desc status_string = GSS_C_EMPTY_BUFFER;
do {
maj_stat = gss_display_status(&min_stat,
@@ -98,10 +100,12 @@ static size_t display_gss_error(OM_uint32 status, int type,
GSS_C_NO_OID,
&msg_ctx,
&status_string);
- if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) {
- len += msnprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
- "%.*s. ", (int)status_string.length,
- (char *)status_string.value);
+ if(maj_stat == GSS_S_COMPLETE && status_string.length > 0) {
+ if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) {
+ len += msnprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
+ "%.*s. ", (int)status_string.length,
+ (char *)status_string.value);
+ }
}
gss_release_buffer(&min_stat, &status_string);
} while(!GSS_ERROR(maj_stat) && msg_ctx);
diff --git a/Utilities/cmcurl/lib/curl_gssapi.h b/Utilities/cmcurl/lib/curl_gssapi.h
index 466d09ed0a..b4ed482aa2 100644
--- a/Utilities/cmcurl/lib/curl_gssapi.h
+++ b/Utilities/cmcurl/lib/curl_gssapi.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_hmac.h b/Utilities/cmcurl/lib/curl_hmac.h
index 5755655d02..36c0bd62e5 100644
--- a/Utilities/cmcurl/lib/curl_hmac.h
+++ b/Utilities/cmcurl/lib/curl_hmac.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,10 +20,14 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_CRYPTO_AUTH
+#include <curl/curl.h>
+
#define HMAC_MD5_LENGTH 16
typedef CURLcode (* HMAC_hinit_func)(void *context);
diff --git a/Utilities/cmcurl/lib/curl_krb5.h b/Utilities/cmcurl/lib/curl_krb5.h
index ca06840742..ccd6f10e3d 100644
--- a/Utilities/cmcurl/lib/curl_krb5.h
+++ b/Utilities/cmcurl/lib/curl_krb5.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
struct Curl_sec_client_mech {
diff --git a/Utilities/cmcurl/lib/curl_ldap.h b/Utilities/cmcurl/lib/curl_ldap.h
index 124e18b133..ba3ede4260 100644
--- a/Utilities/cmcurl/lib/curl_ldap.h
+++ b/Utilities/cmcurl/lib/curl_ldap.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_LDAP
extern const struct Curl_handler Curl_handler_ldap;
diff --git a/Utilities/cmcurl/lib/curl_md4.h b/Utilities/cmcurl/lib/curl_md4.h
index f9dafcb53c..8049355cff 100644
--- a/Utilities/cmcurl/lib/curl_md4.h
+++ b/Utilities/cmcurl/lib/curl_md4.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_md5.h b/Utilities/cmcurl/lib/curl_md5.h
index b7d7c1f5d2..789329654b 100644
--- a/Utilities/cmcurl/lib/curl_md5.h
+++ b/Utilities/cmcurl/lib/curl_md5.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_CRYPTO_AUTH
diff --git a/Utilities/cmcurl/lib/curl_memory.h b/Utilities/cmcurl/lib/curl_memory.h
index 5806290637..092fc9f758 100644
--- a/Utilities/cmcurl/lib/curl_memory.h
+++ b/Utilities/cmcurl/lib/curl_memory.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
diff --git a/Utilities/cmcurl/lib/curl_memrchr.c b/Utilities/cmcurl/lib/curl_memrchr.c
index 0bd845f690..c329a6176a 100644
--- a/Utilities/cmcurl/lib/curl_memrchr.c
+++ b/Utilities/cmcurl/lib/curl_memrchr.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_memrchr.h b/Utilities/cmcurl/lib/curl_memrchr.h
index c8394bb433..e7654e1d9a 100644
--- a/Utilities/cmcurl/lib/curl_memrchr.h
+++ b/Utilities/cmcurl/lib/curl_memrchr.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_multibyte.c b/Utilities/cmcurl/lib/curl_multibyte.c
index 32c03a5b71..309dccbfef 100644
--- a/Utilities/cmcurl/lib/curl_multibyte.c
+++ b/Utilities/cmcurl/lib/curl_multibyte.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
diff --git a/Utilities/cmcurl/lib/curl_multibyte.h b/Utilities/cmcurl/lib/curl_multibyte.h
index 491155e6a7..929714873a 100644
--- a/Utilities/cmcurl/lib/curl_multibyte.h
+++ b/Utilities/cmcurl/lib/curl_multibyte.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_ntlm_core.c b/Utilities/cmcurl/lib/curl_ntlm_core.c
index f3b8b130f1..38e193c186 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_core.c
+++ b/Utilities/cmcurl/lib/curl_ntlm_core.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -27,7 +29,7 @@
/*
* NTLM details:
*
- * https://davenport.sourceforge.io/ntlm.html
+ * https://davenport.sourceforge.net/ntlm.html
* https://www.innovation.ch/java/ntlm.html
*/
@@ -58,14 +60,19 @@
#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL)
-#ifdef USE_WOLFSSL
-#include <wolfssl/options.h>
-#endif
-
+#if defined(USE_OPENSSL)
# include <openssl/des.h>
# include <openssl/md5.h>
# include <openssl/ssl.h>
# include <openssl/rand.h>
+#else
+# include <wolfssl/options.h>
+# include <wolfssl/openssl/des.h>
+# include <wolfssl/openssl/md5.h>
+# include <wolfssl/openssl/ssl.h>
+# include <wolfssl/openssl/rand.h>
+#endif
+
# if (defined(OPENSSL_VERSION_NUMBER) && \
(OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
# define DES_key_schedule des_key_schedule
diff --git a/Utilities/cmcurl/lib/curl_ntlm_core.h b/Utilities/cmcurl/lib/curl_ntlm_core.h
index 5e52bb26de..60444c9dc6 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_core.h
+++ b/Utilities/cmcurl/lib/curl_ntlm_core.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -35,10 +37,10 @@
#define NTLM_NEEDS_NSS_INIT
#endif
-#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
#ifdef USE_WOLFSSL
# include <wolfssl/options.h>
-#endif
+# include <wolfssl/openssl/ssl.h>
+#elif defined(USE_OPENSSL)
# include <openssl/ssl.h>
#endif
diff --git a/Utilities/cmcurl/lib/curl_ntlm_wb.c b/Utilities/cmcurl/lib/curl_ntlm_wb.c
index 5a3bc3c893..33dcf0ce25 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_wb.c
+++ b/Utilities/cmcurl/lib/curl_ntlm_wb.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -28,7 +30,7 @@
/*
* NTLM details:
*
- * https://davenport.sourceforge.io/ntlm.html
+ * https://davenport.sourceforge.net/ntlm.html
* https://www.innovation.ch/java/ntlm.html
*/
diff --git a/Utilities/cmcurl/lib/curl_ntlm_wb.h b/Utilities/cmcurl/lib/curl_ntlm_wb.h
index 961b568733..1f04db8c3d 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_wb.h
+++ b/Utilities/cmcurl/lib/curl_ntlm_wb.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_path.c b/Utilities/cmcurl/lib/curl_path.c
index a1669d12f7..b55e83047d 100644
--- a/Utilities/cmcurl/lib/curl_path.c
+++ b/Utilities/cmcurl/lib/curl_path.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl AND ISC
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -120,7 +122,8 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
bool relativePath = false;
static const char WHITESPACE[] = " \t\r\n";
- if(!*cp) {
+ DEBUGASSERT(homedir);
+ if(!*cp || !homedir) {
*cpp = NULL;
*path = NULL;
return CURLE_QUOTE_ERROR;
diff --git a/Utilities/cmcurl/lib/curl_path.h b/Utilities/cmcurl/lib/curl_path.h
index a376bd1d2a..98e56eaad3 100644
--- a/Utilities/cmcurl/lib/curl_path.h
+++ b/Utilities/cmcurl/lib/curl_path.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_printf.h b/Utilities/cmcurl/lib/curl_printf.h
index 9fa625f108..3823828cd9 100644
--- a/Utilities/cmcurl/lib/curl_printf.h
+++ b/Utilities/cmcurl/lib/curl_printf.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
diff --git a/Utilities/cmcurl/lib/curl_range.c b/Utilities/cmcurl/lib/curl_range.c
index 24bdb3052e..dd92d05b39 100644
--- a/Utilities/cmcurl/lib/curl_range.c
+++ b/Utilities/cmcurl/lib/curl_range.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -45,7 +47,7 @@ CURLcode Curl_range(struct Curl_easy *data)
from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
if(from_t == CURL_OFFT_FLOW)
return CURLE_RANGE_ERROR;
- while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+ while(*ptr && (ISBLANK(*ptr) || (*ptr == '-')))
ptr++;
to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
if(to_t == CURL_OFFT_FLOW)
diff --git a/Utilities/cmcurl/lib/curl_range.h b/Utilities/cmcurl/lib/curl_range.h
index 0a07baf146..33570abc25 100644
--- a/Utilities/cmcurl/lib/curl_range.h
+++ b/Utilities/cmcurl/lib/curl_range.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_rtmp.c b/Utilities/cmcurl/lib/curl_rtmp.c
index 2fa026796e..b0c371041e 100644
--- a/Utilities/cmcurl/lib/curl_rtmp.c
+++ b/Utilities/cmcurl/lib/curl_rtmp.c
@@ -5,8 +5,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
+ * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012, Howard Chu, <hyc@highlandsun.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_rtmp.h b/Utilities/cmcurl/lib/curl_rtmp.h
index f45fa71d12..f856085dc3 100644
--- a/Utilities/cmcurl/lib/curl_rtmp.h
+++ b/Utilities/cmcurl/lib/curl_rtmp.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2020, Howard Chu, <hyc@highlandsun.com>
+ * Copyright (C) 2010 - 2022, Howard Chu, <hyc@highlandsun.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifdef USE_LIBRTMP
extern const struct Curl_handler Curl_handler_rtmp;
diff --git a/Utilities/cmcurl/lib/curl_sasl.c b/Utilities/cmcurl/lib/curl_sasl.c
index 48d6625ba4..9684ee476e 100644
--- a/Utilities/cmcurl/lib/curl_sasl.c
+++ b/Utilities/cmcurl/lib/curl_sasl.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC2195 CRAM-MD5 authentication
* RFC2617 Basic and Digest Access Authentication
* RFC2831 DIGEST-MD5 authentication
diff --git a/Utilities/cmcurl/lib/curl_sasl.h b/Utilities/cmcurl/lib/curl_sasl.h
index d377ae7bc8..c709d56a67 100644
--- a/Utilities/cmcurl/lib/curl_sasl.h
+++ b/Utilities/cmcurl/lib/curl_sasl.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <curl/curl.h>
diff --git a/Utilities/cmcurl/lib/curl_setup.h b/Utilities/cmcurl/lib/curl_setup.h
index 3dd5950189..c3ad25f999 100644
--- a/Utilities/cmcurl/lib/curl_setup.h
+++ b/Utilities/cmcurl/lib/curl_setup.h
@@ -20,12 +20,19 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#if defined(BUILDING_LIBCURL) && !defined(CURL_NO_OLDIES)
#define CURL_NO_OLDIES
#endif
+/* define mingw version macros, eg __MINGW{32,64}_{MINOR,MAJOR}_VERSION */
+#ifdef __MINGW32__
+#include <_mingw.h>
+#endif
+
/*
* Disable Visual Studio warnings:
* 4127 "conditional expression is constant"
@@ -155,8 +162,6 @@
/* please, do it beyond the point further indicated in this file. */
/* ================================================================ */
-#include <curl/curl.h>
-
/*
* Disable other protocols when http is the only one desired.
*/
@@ -216,7 +221,7 @@
/* ================================================================ */
/* No system header file shall be included in this file before this */
-/* point. The only allowed ones are those included from curl/system.h */
+/* point. */
/* ================================================================ */
/*
@@ -243,6 +248,8 @@
# include "setup-win32.h"
#endif
+#include <curl/system.h>
+
/*
* Use getaddrinfo to resolve the IPv4 address literal. If the current network
* interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
@@ -271,14 +278,41 @@
#endif
#ifdef __AMIGA__
+# ifdef __amigaos4__
+# define __USE_INLINE__
+ /* use our own resolver which uses runtime feature detection */
+# define CURLRES_AMIGA
+ /* getaddrinfo() currently crashes bsdsocket.library, so disable */
+# undef HAVE_GETADDRINFO
+# if !(defined(__NEWLIB__) || \
+ (defined(__CLIB2__) && defined(__THREAD_SAFE)))
+ /* disable threaded resolver with clib2 - requires newlib or clib-ts */
+# undef USE_THREADS_POSIX
+# endif
+# endif
# include <exec/types.h>
# include <exec/execbase.h>
# include <proto/exec.h>
# include <proto/dos.h>
# include <unistd.h>
-# ifdef HAVE_PROTO_BSDSOCKET_H
-# include <proto/bsdsocket.h> /* ensure bsdsocket.library use */
-# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
+# if defined(HAVE_PROTO_BSDSOCKET_H) && \
+ (!defined(__amigaos4__) || defined(USE_AMISSL))
+ /* use bsdsocket.library directly, instead of libc networking functions */
+# include <proto/bsdsocket.h>
+# ifdef __amigaos4__
+ int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *errorfds, struct timeval *timeout);
+# define select(a,b,c,d,e) Curl_amiga_select(a,b,c,d,e)
+# else
+# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
+# endif
+ /* must not use libc's fcntl() on bsdsocket.library sockfds! */
+# undef HAVE_FCNTL
+# undef HAVE_FCNTL_O_NONBLOCK
+# else
+ /* use libc networking and hence close() and fnctl() */
+# undef HAVE_CLOSESOCKET_CAMEL
+# undef HAVE_IOCTLSOCKET_CAMEL
# endif
/*
* In clib2 arpa/inet.h warns that some prototypes may clash
@@ -292,8 +326,10 @@
#include <assert.h>
#endif
-#ifdef __TANDEM /* for nsr-tandem-nsk systems */
-#include <floss.h>
+#ifdef __TANDEM /* for ns*-tandem-nsk systems */
+# if ! defined __LP64
+# include <floss.h> /* FLOSS is only used for 32-bit builds. */
+# endif
#endif
#ifndef STDC_HEADERS /* no standard C headers! */
@@ -571,7 +607,6 @@
/* now undef the stock libc functions just to avoid them being used */
# undef HAVE_GETADDRINFO
# undef HAVE_FREEADDRINFO
-# undef HAVE_GETHOSTBYNAME
#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
# define CURLRES_ASYNCH
# define CURLRES_THREADED
@@ -722,12 +757,12 @@
#define SHUT_RDWR 0x02
#endif
-/* Define S_ISREG if not defined by system headers, f.e. MSVC */
+/* Define S_ISREG if not defined by system headers, e.g. MSVC */
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
-/* Define S_ISDIR if not defined by system headers, f.e. MSVC */
+/* Define S_ISDIR if not defined by system headers, e.g. MSVC */
#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
@@ -811,6 +846,7 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
#if defined(USE_NGTCP2) || defined(USE_QUICHE) || defined(USE_MSH3)
#define ENABLE_QUIC
+#define USE_HTTP3
#endif
#if defined(USE_UNIX_SOCKETS) && defined(WIN32)
diff --git a/Utilities/cmcurl/lib/curl_setup_once.h b/Utilities/cmcurl/lib/curl_setup_once.h
index 38018d23c7..f09b00f9f2 100644
--- a/Utilities/cmcurl/lib/curl_setup_once.h
+++ b/Utilities/cmcurl/lib/curl_setup_once.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
@@ -31,7 +33,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
-#include <ctype.h>
#include <time.h>
#ifdef HAVE_ERRNO_H
@@ -86,6 +87,8 @@
#include <sys/socket.h>
#endif
+#include "functypes.h"
+
#ifdef __hpux
# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
# ifdef OLD_APP32_64BIT_OFF_T
@@ -148,20 +151,10 @@ struct timeval {
* SEND_TYPE_RETV must also be defined.
*/
-#if !defined(RECV_TYPE_ARG1) || \
- !defined(RECV_TYPE_ARG2) || \
- !defined(RECV_TYPE_ARG3) || \
- !defined(RECV_TYPE_ARG4) || \
- !defined(RECV_TYPE_RETV)
- /* */
- Error Missing_definition_of_return_and_arguments_types_of_recv
- /* */
-#else
#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
(RECV_TYPE_ARG2)(y), \
(RECV_TYPE_ARG3)(z), \
(RECV_TYPE_ARG4)(0))
-#endif
#else /* HAVE_RECV */
#ifndef sread
/* */
@@ -178,21 +171,10 @@ struct timeval {
(SEND_TYPE_ARG3)(z))
#elif defined(HAVE_SEND)
-#if !defined(SEND_TYPE_ARG1) || \
- !defined(SEND_QUAL_ARG2) || \
- !defined(SEND_TYPE_ARG2) || \
- !defined(SEND_TYPE_ARG3) || \
- !defined(SEND_TYPE_ARG4) || \
- !defined(SEND_TYPE_RETV)
- /* */
- Error Missing_definition_of_return_and_arguments_types_of_send
- /* */
-#else
#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
(SEND_QUAL_ARG2 SEND_TYPE_ARG2)(y), \
(SEND_TYPE_ARG3)(z), \
(SEND_TYPE_ARG4)(SEND_4TH_ARG))
-#endif
#else /* HAVE_SEND */
#ifndef swrite
/* */
@@ -202,46 +184,6 @@ struct timeval {
#endif /* HAVE_SEND */
-#if 0
-#if defined(HAVE_RECVFROM)
-/*
- * Currently recvfrom is only used on udp sockets.
- */
-#if !defined(RECVFROM_TYPE_ARG1) || \
- !defined(RECVFROM_TYPE_ARG2) || \
- !defined(RECVFROM_TYPE_ARG3) || \
- !defined(RECVFROM_TYPE_ARG4) || \
- !defined(RECVFROM_TYPE_ARG5) || \
- !defined(RECVFROM_TYPE_ARG6) || \
- !defined(RECVFROM_TYPE_RETV)
- /* */
- Error Missing_definition_of_return_and_arguments_types_of_recvfrom
- /* */
-#else
-#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \
- (RECVFROM_TYPE_ARG2 *)(b), \
- (RECVFROM_TYPE_ARG3) (bl), \
- (RECVFROM_TYPE_ARG4) (0), \
- (RECVFROM_TYPE_ARG5 *)(f), \
- (RECVFROM_TYPE_ARG6 *)(fl))
-#endif
-#else /* HAVE_RECVFROM */
-#ifndef sreadfrom
- /* */
- Error Missing_definition_of_macro_sreadfrom
- /* */
-#endif
-#endif /* HAVE_RECVFROM */
-
-
-#ifdef RECVFROM_TYPE_ARG6_IS_VOID
-# define RECVFROM_ARG6_T int
-#else
-# define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6
-#endif
-#endif /* if 0 */
-
-
/*
* Function-like macro definition used to close a socket.
*/
@@ -267,9 +209,6 @@ struct timeval {
# define sfcntl fcntl
#endif
-#define TOLOWER(x) (tolower((int) ((unsigned char)x)))
-
-
/*
* 'bool' stuff compatible with HP-UX headers.
*/
@@ -306,6 +245,14 @@ struct timeval {
# define HAVE_BOOL_T
#endif
+/* the type we use for storing a single boolean bit */
+#ifdef _MSC_VER
+typedef bool bit;
+#define BIT(x) bool x
+#else
+typedef unsigned int bit;
+#define BIT(x) bit x:1
+#endif
/*
* Redefine TRUE and FALSE too, to catch current use. With this
diff --git a/Utilities/cmcurl/lib/curl_sha256.h b/Utilities/cmcurl/lib/curl_sha256.h
index 2b7890a039..754c761fb3 100644
--- a/Utilities/cmcurl/lib/curl_sha256.h
+++ b/Utilities/cmcurl/lib/curl_sha256.h
@@ -21,9 +21,12 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_CRYPTO_AUTH
+#include <curl/curl.h>
#include "curl_hmac.h"
extern const struct HMAC_params Curl_HMAC_SHA256[1];
diff --git a/Utilities/cmcurl/lib/curl_sspi.c b/Utilities/cmcurl/lib/curl_sspi.c
index 339bf549fb..33108c48e9 100644
--- a/Utilities/cmcurl/lib/curl_sspi.c
+++ b/Utilities/cmcurl/lib/curl_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_sspi.h b/Utilities/cmcurl/lib/curl_sspi.h
index 881384d4e4..ad111309c5 100644
--- a/Utilities/cmcurl/lib/curl_sspi.h
+++ b/Utilities/cmcurl/lib/curl_sspi.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_threads.c b/Utilities/cmcurl/lib/curl_threads.c
index 414614401d..eb8e136087 100644
--- a/Utilities/cmcurl/lib/curl_threads.c
+++ b/Utilities/cmcurl/lib/curl_threads.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curl_threads.h b/Utilities/cmcurl/lib/curl_threads.h
index e10b7a1b0e..63392f671f 100644
--- a/Utilities/cmcurl/lib/curl_threads.h
+++ b/Utilities/cmcurl/lib/curl_threads.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/curlx.h b/Utilities/cmcurl/lib/curlx.h
index 9f21f60d5f..1796afa00a 100644
--- a/Utilities/cmcurl/lib/curlx.h
+++ b/Utilities/cmcurl/lib/curlx.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
diff --git a/Utilities/cmcurl/lib/dict.c b/Utilities/cmcurl/lib/dict.c
index e23e661912..6f7678f5ca 100644
--- a/Utilities/cmcurl/lib/dict.c
+++ b/Utilities/cmcurl/lib/dict.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/dict.h b/Utilities/cmcurl/lib/dict.h
index 6a6c772d13..b283a0dfc1 100644
--- a/Utilities/cmcurl/lib/dict.h
+++ b/Utilities/cmcurl/lib/dict.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_DICT
diff --git a/Utilities/cmcurl/lib/doh.c b/Utilities/cmcurl/lib/doh.c
index 4aef8b266a..3b1d5d60ef 100644
--- a/Utilities/cmcurl/lib/doh.c
+++ b/Utilities/cmcurl/lib/doh.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -69,12 +71,6 @@ static const char *doh_strerror(DOHcode code)
}
#endif
-#ifdef DEBUGBUILD
-#define UNITTEST
-#else
-#define UNITTEST static
-#endif
-
/* @unittest 1655
*/
UNITTEST DOHcode doh_encode(const char *host,
@@ -247,6 +243,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
the gcc typecheck helpers */
struct dynbuf *resp = &p->serverdoh;
ERROR_CHECK_SETOPT(CURLOPT_URL, url);
+ ERROR_CHECK_SETOPT(CURLOPT_DEFAULT_PROTOCOL, "https");
ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb);
ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, resp);
ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDS, p->dohbuffer);
@@ -306,14 +303,6 @@ static CURLcode dohprobe(struct Curl_easy *data,
}
if(data->set.ssl.certinfo)
ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L);
- if(data->set.str[STRING_SSL_RANDOM_FILE]) {
- ERROR_CHECK_SETOPT(CURLOPT_RANDOM_FILE,
- data->set.str[STRING_SSL_RANDOM_FILE]);
- }
- if(data->set.str[STRING_SSL_EGDSOCKET]) {
- ERROR_CHECK_SETOPT(CURLOPT_EGDSOCKET,
- data->set.str[STRING_SSL_EGDSOCKET]);
- }
if(data->set.ssl.fsslctx)
ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
if(data->set.ssl.fsslctxp)
@@ -407,7 +396,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
goto error;
dohp->pending++;
- if(Curl_ipv6works(data)) {
+ if((conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) {
/* create IPv6 DoH request */
result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6],
DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH],
@@ -803,7 +792,7 @@ doh2ai(const struct dohentry *de, const char *hostname, int port)
#endif
CURLcode result = CURLE_OK;
int i;
- size_t hostlen = strlen(hostname) + 1; /* include zero terminator */
+ size_t hostlen = strlen(hostname) + 1; /* include null-terminator */
if(!de)
/* no input == no output! */
diff --git a/Utilities/cmcurl/lib/doh.h b/Utilities/cmcurl/lib/doh.h
index 70e96e012f..678e807fe4 100644
--- a/Utilities/cmcurl/lib/doh.h
+++ b/Utilities/cmcurl/lib/doh.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "urldata.h"
@@ -27,21 +29,6 @@
#ifndef CURL_DISABLE_DOH
-/*
- * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name
- * and returns a 'Curl_addrinfo *' with the address information.
- */
-
-struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
- const char *hostname,
- int port,
- int *waitp);
-
-CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
- struct Curl_dns_entry **dns);
-
-int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks);
-
typedef enum {
DOH_OK,
DOH_DNS_BAD_LABEL, /* 1 */
@@ -67,6 +54,38 @@ typedef enum {
DNS_TYPE_DNAME = 39 /* RFC6672 */
} DNStype;
+/* one of these for each DoH request */
+struct dnsprobe {
+ CURL *easy;
+ DNStype dnstype;
+ unsigned char dohbuffer[512];
+ size_t dohlen;
+ struct dynbuf serverdoh;
+};
+
+struct dohdata {
+ struct curl_slist *headers;
+ struct dnsprobe probe[DOH_PROBE_SLOTS];
+ unsigned int pending; /* still outstanding requests */
+ int port;
+ const char *host;
+};
+
+/*
+ * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name
+ * and returns a 'Curl_addrinfo *' with the address information.
+ */
+
+struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
+ const char *hostname,
+ int port,
+ int *waitp);
+
+CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
+ struct Curl_dns_entry **dns);
+
+int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks);
+
#define DOH_MAX_ADDR 24
#define DOH_MAX_CNAME 4
diff --git a/Utilities/cmcurl/lib/dotdot.c b/Utilities/cmcurl/lib/dotdot.c
deleted file mode 100644
index 73ef2fa729..0000000000
--- a/Utilities/cmcurl/lib/dotdot.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#include <curl/curl.h>
-
-#include "dotdot.h"
-#include "curl_memory.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/*
- * "Remove Dot Segments"
- * https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4
- */
-
-/*
- * Curl_dedotdotify()
- * @unittest: 1395
- *
- * This function gets a null-terminated path with dot and dotdot sequences
- * passed in and strips them off according to the rules in RFC 3986 section
- * 5.2.4.
- *
- * The function handles a query part ('?' + stuff) appended but it expects
- * that fragments ('#' + stuff) have already been cut off.
- *
- * RETURNS
- *
- * an allocated dedotdotified output string
- */
-char *Curl_dedotdotify(const char *input)
-{
- size_t inlen = strlen(input);
- char *clone;
- size_t clen = inlen; /* the length of the cloned input */
- char *out = malloc(inlen + 1);
- char *outptr;
- char *orgclone;
- char *queryp;
- if(!out)
- return NULL; /* out of memory */
-
- *out = 0; /* null-terminates, for inputs like "./" */
-
- /* get a cloned copy of the input */
- clone = strdup(input);
- if(!clone) {
- free(out);
- return NULL;
- }
- orgclone = clone;
- outptr = out;
-
- if(!*clone) {
- /* zero length string, return that */
- free(out);
- return clone;
- }
-
- /*
- * To handle query-parts properly, we must find it and remove it during the
- * dotdot-operation and then append it again at the end to the output
- * string.
- */
- queryp = strchr(clone, '?');
- if(queryp)
- *queryp = 0;
-
- do {
-
- /* A. If the input buffer begins with a prefix of "../" or "./", then
- remove that prefix from the input buffer; otherwise, */
-
- if(!strncmp("./", clone, 2)) {
- clone += 2;
- clen -= 2;
- }
- else if(!strncmp("../", clone, 3)) {
- clone += 3;
- clen -= 3;
- }
-
- /* B. if the input buffer begins with a prefix of "/./" or "/.", where
- "." is a complete path segment, then replace that prefix with "/" in
- the input buffer; otherwise, */
- else if(!strncmp("/./", clone, 3)) {
- clone += 2;
- clen -= 2;
- }
- else if(!strcmp("/.", clone)) {
- clone[1]='/';
- clone++;
- clen -= 1;
- }
-
- /* C. if the input buffer begins with a prefix of "/../" or "/..", where
- ".." is a complete path segment, then replace that prefix with "/" in
- the input buffer and remove the last segment and its preceding "/" (if
- any) from the output buffer; otherwise, */
-
- else if(!strncmp("/../", clone, 4)) {
- clone += 3;
- clen -= 3;
- /* remove the last segment from the output buffer */
- while(outptr > out) {
- outptr--;
- if(*outptr == '/')
- break;
- }
- *outptr = 0; /* null-terminate where it stops */
- }
- else if(!strcmp("/..", clone)) {
- clone[2]='/';
- clone += 2;
- clen -= 2;
- /* remove the last segment from the output buffer */
- while(outptr > out) {
- outptr--;
- if(*outptr == '/')
- break;
- }
- *outptr = 0; /* null-terminate where it stops */
- }
-
- /* D. if the input buffer consists only of "." or "..", then remove
- that from the input buffer; otherwise, */
-
- else if(!strcmp(".", clone) || !strcmp("..", clone)) {
- *clone = 0;
- *out = 0;
- }
-
- else {
- /* E. move the first path segment in the input buffer to the end of
- the output buffer, including the initial "/" character (if any) and
- any subsequent characters up to, but not including, the next "/"
- character or the end of the input buffer. */
-
- do {
- *outptr++ = *clone++;
- clen--;
- } while(*clone && (*clone != '/'));
- *outptr = 0;
- }
-
- } while(*clone);
-
- if(queryp) {
- size_t qlen;
- /* There was a query part, append that to the output. The 'clone' string
- may now have been altered so we copy from the original input string
- from the correct index. */
- size_t oindex = queryp - orgclone;
- qlen = strlen(&input[oindex]);
- memcpy(outptr, &input[oindex], qlen + 1); /* include the end zero byte */
- }
-
- free(orgclone);
- return out;
-}
diff --git a/Utilities/cmcurl/lib/dynbuf.c b/Utilities/cmcurl/lib/dynbuf.c
index ada7e0ccf5..0b1cf9afd8 100644
--- a/Utilities/cmcurl/lib/dynbuf.c
+++ b/Utilities/cmcurl/lib/dynbuf.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2020 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -126,7 +128,6 @@ void Curl_dyn_reset(struct dynbuf *s)
s->leng = 0;
}
-#ifdef USE_NGTCP2
/*
* Specify the size of the tail to keep (number of bytes from the end of the
* buffer). The rest will be dropped.
@@ -151,7 +152,6 @@ CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail)
return CURLE_OK;
}
-#endif
/*
* Appends a buffer with length.
@@ -253,3 +253,18 @@ size_t Curl_dyn_len(const struct dynbuf *s)
DEBUGASSERT(!s->leng || s->bufr);
return s->leng;
}
+
+/*
+ * Set a new (smaller) length.
+ */
+CURLcode Curl_dyn_setlen(struct dynbuf *s, size_t set)
+{
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ if(set > s->leng)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ s->leng = set;
+ s->bufr[s->leng] = 0;
+ return CURLE_OK;
+}
diff --git a/Utilities/cmcurl/lib/dynbuf.h b/Utilities/cmcurl/lib/dynbuf.h
index 252411f842..04a728c779 100644
--- a/Utilities/cmcurl/lib/dynbuf.h
+++ b/Utilities/cmcurl/lib/dynbuf.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2020, 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2020 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,8 +20,12 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
+#include <curl/curl.h>
+
#ifndef BUILDING_LIBCURL
/* this renames the functions so that the tool code can use the same code
without getting symbol collisions */
@@ -36,12 +40,13 @@
#define Curl_dyn_len(a) curlx_dyn_len(a)
#define Curl_dyn_reset(a) curlx_dyn_reset(a)
#define Curl_dyn_tail(a,b) curlx_dyn_tail(a,b)
+#define Curl_dyn_setlen(a,b) curlx_dyn_setlen(a,b)
#define curlx_dynbuf dynbuf /* for the struct name */
#endif
struct dynbuf {
char *bufr; /* point to a null-terminated allocated buffer */
- size_t leng; /* number of bytes *EXCLUDING* the zero terminator */
+ size_t leng; /* number of bytes *EXCLUDING* the null-terminator */
size_t allc; /* size of the current allocation */
size_t toobig; /* size limit for the buffer */
#ifdef DEBUGBUILD
@@ -61,6 +66,7 @@ CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap)
WARN_UNUSED_RESULT;
void Curl_dyn_reset(struct dynbuf *s);
CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail);
+CURLcode Curl_dyn_setlen(struct dynbuf *s, size_t set);
char *Curl_dyn_ptr(const struct dynbuf *s);
unsigned char *Curl_dyn_uptr(const struct dynbuf *s);
size_t Curl_dyn_len(const struct dynbuf *s);
diff --git a/Utilities/cmcurl/lib/easy.c b/Utilities/cmcurl/lib/easy.c
index bd9d695bb5..b8ac1ef8a8 100644
--- a/Utilities/cmcurl/lib/easy.c
+++ b/Utilities/cmcurl/lib/easy.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -80,6 +82,8 @@
#include "altsvc.h"
#include "hsts.h"
+#include "easy_lock.h"
+
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -89,6 +93,19 @@
static unsigned int initialized;
static long init_flags;
+#ifdef GLOBAL_INIT_IS_THREADSAFE
+
+static curl_simple_lock s_lock = CURL_SIMPLE_LOCK_INIT;
+#define global_init_lock() curl_simple_lock_lock(&s_lock)
+#define global_init_unlock() curl_simple_lock_unlock(&s_lock)
+
+#else
+
+#define global_init_lock()
+#define global_init_unlock()
+
+#endif
+
/*
* strdup (and other memory functions) is redefined in complicated
* ways, but at this point it must be defined as the system-supplied strdup
@@ -161,7 +178,7 @@ static CURLcode global_init(long flags, bool memoryfuncs)
#endif
#ifdef __AMIGA__
- if(!Curl_amiga_init()) {
+ if(Curl_amiga_init()) {
DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
goto fail;
}
@@ -207,7 +224,14 @@ static CURLcode global_init(long flags, bool memoryfuncs)
*/
CURLcode curl_global_init(long flags)
{
- return global_init(flags, TRUE);
+ CURLcode result;
+ global_init_lock();
+
+ result = global_init(flags, TRUE);
+
+ global_init_unlock();
+
+ return result;
}
/*
@@ -218,15 +242,20 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
curl_free_callback f, curl_realloc_callback r,
curl_strdup_callback s, curl_calloc_callback c)
{
+ CURLcode result;
+
/* Invalid input, return immediately */
if(!m || !f || !r || !s || !c)
return CURLE_FAILED_INIT;
+ global_init_lock();
+
if(initialized) {
/* Already initialized, don't do it again, but bump the variable anyway to
work like curl_global_init() and require the same amount of cleanup
calls. */
initialized++;
+ global_init_unlock();
return CURLE_OK;
}
@@ -239,7 +268,11 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
Curl_ccalloc = c;
/* Call the actual init function, but without setting */
- return global_init(flags, FALSE);
+ result = global_init(flags, FALSE);
+
+ global_init_unlock();
+
+ return result;
}
/**
@@ -248,11 +281,17 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
*/
void curl_global_cleanup(void)
{
- if(!initialized)
+ global_init_lock();
+
+ if(!initialized) {
+ global_init_unlock();
return;
+ }
- if(--initialized)
+ if(--initialized) {
+ global_init_unlock();
return;
+ }
Curl_ssl_cleanup();
Curl_resolver_global_cleanup();
@@ -273,6 +312,25 @@ void curl_global_cleanup(void)
#endif
init_flags = 0;
+
+ global_init_unlock();
+}
+
+/*
+ * curl_global_sslset() globally initializes the SSL backend to use.
+ */
+CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+ const curl_ssl_backend ***avail)
+{
+ CURLsslset rc;
+
+ global_init_lock();
+
+ rc = Curl_init_sslset_nolock(id, name, avail);
+
+ global_init_unlock();
+
+ return rc;
}
/*
@@ -285,14 +343,18 @@ struct Curl_easy *curl_easy_init(void)
struct Curl_easy *data;
/* Make sure we inited the global SSL stuff */
+ global_init_lock();
+
if(!initialized) {
- result = curl_global_init(CURL_GLOBAL_DEFAULT);
+ result = global_init(CURL_GLOBAL_DEFAULT, TRUE);
if(result) {
/* something in the global init failed, return nothing */
DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
+ global_init_unlock();
return NULL;
}
}
+ global_init_unlock();
/* We use curl_open() with undefined URL so far */
result = Curl_open(&data);
@@ -507,19 +569,23 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
/* wait for activity or timeout */
pollrc = Curl_poll(fds, numfds, ev->ms);
+ if(pollrc < 0)
+ return CURLE_UNRECOVERABLE_POLL;
after = Curl_now();
ev->msbump = FALSE; /* reset here */
- if(0 == pollrc) {
+ if(!pollrc) {
/* timeout! */
ev->ms = 0;
/* fprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */
mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
&ev->running_handles);
}
- else if(pollrc > 0) {
+ else {
+ /* here pollrc is > 0 */
+
/* loop over the monitored sockets to see which ones had activity */
for(i = 0; i< numfds; i++) {
if(fds[i].revents) {
@@ -545,8 +611,6 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
}
}
}
- else
- return CURLE_RECV_ERROR;
if(mcode)
return CURLE_URL_MALFORMAT;
@@ -662,7 +726,7 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
else {
/* this multi handle will only ever have a single easy handled attached
to it, so make it use minimal hashes */
- multi = Curl_multi_handle(1, 3);
+ multi = Curl_multi_handle(1, 3, 7);
if(!multi)
return CURLE_OUT_OF_MEMORY;
data->multi_easy = multi;
@@ -838,6 +902,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
outcurl->progress.flags = data->progress.flags;
outcurl->progress.callback = data->progress.callback;
+#ifndef CURL_DISABLE_COOKIES
if(data->cookies) {
/* If cookies are enabled in the parent handle, we enable them
in the clone as well! */
@@ -856,6 +921,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
if(!outcurl->state.cookielist)
goto fail;
}
+#endif
if(data->state.url) {
outcurl->state.url = strdup(data->state.url);
@@ -878,7 +944,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
goto fail;
}
-#ifdef USE_ALTSVC
+#ifndef CURL_DISABLE_ALTSVC
if(data->asi) {
outcurl->asi = Curl_altsvc_init();
if(!outcurl->asi)
@@ -937,8 +1003,10 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
fail:
if(outcurl) {
+#ifndef CURL_DISABLE_COOKIES
curl_slist_free_all(outcurl->state.cookielist);
outcurl->state.cookielist = NULL;
+#endif
Curl_safefree(outcurl->state.buffer);
Curl_dyn_free(&outcurl->state.headerb);
Curl_safefree(outcurl->state.url);
@@ -1065,6 +1133,16 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
}
}
+#ifdef USE_HYPER
+ if(!(newstate & KEEP_SEND_PAUSE)) {
+ /* need to wake the send body waker */
+ if(data->hyp.send_body_waker) {
+ hyper_waker_wake(data->hyp.send_body_waker);
+ data->hyp.send_body_waker = NULL;
+ }
+ }
+#endif
+
/* if there's no error and we're not pausing both directions, we want
to have this handle checked soon */
if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
@@ -1093,8 +1171,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
}
-static CURLcode easy_connection(struct Curl_easy *data,
- curl_socket_t *sfd,
+static CURLcode easy_connection(struct Curl_easy *data, curl_socket_t *sfd,
struct connectdata **connp)
{
if(!data)
@@ -1153,11 +1230,12 @@ CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen,
}
/*
- * Sends data over the connected socket. Use after successful
- * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ * Sends data over the connected socket.
+ *
+ * This is the private internal version of curl_easy_send()
*/
-CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
- size_t buflen, size_t *n)
+CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer,
+ size_t buflen, ssize_t *n)
{
curl_socket_t sfd;
CURLcode result;
@@ -1165,9 +1243,6 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
struct connectdata *c = NULL;
SIGPIPE_VARIABLE(pipe_st);
- if(Curl_is_in_callback(data))
- return CURLE_RECURSIVE_API_CALL;
-
result = easy_connection(data, &sfd, &c);
if(result)
return result;
@@ -1189,8 +1264,25 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
if(!result && !n1)
return CURLE_AGAIN;
- *n = (size_t)n1;
+ *n = n1;
+
+ return result;
+}
+
+/*
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
+ size_t buflen, size_t *n)
+{
+ ssize_t written = 0;
+ CURLcode result;
+ if(Curl_is_in_callback(data))
+ return CURLE_RECURSIVE_API_CALL;
+ result = Curl_senddata(data, buffer, buflen, &written);
+ *n = (size_t)written;
return result;
}
diff --git a/Utilities/cmcurl/lib/easy_lock.h b/Utilities/cmcurl/lib/easy_lock.h
new file mode 100644
index 0000000000..d96e56b8d8
--- /dev/null
+++ b/Utilities/cmcurl/lib/easy_lock.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#define GLOBAL_INIT_IS_THREADSAFE
+
+#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600
+
+#ifdef __MINGW32__
+#ifndef __MINGW64_VERSION_MAJOR
+#if (__MINGW32_MAJOR_VERSION < 5) || \
+ (__MINGW32_MAJOR_VERSION == 5 && __MINGW32_MINOR_VERSION == 0)
+/* mingw >= 5.0.1 defines SRWLOCK, and slightly different from MS define */
+typedef PVOID SRWLOCK, *PSRWLOCK;
+#endif
+#endif
+#ifndef SRWLOCK_INIT
+#define SRWLOCK_INIT NULL
+#endif
+#endif /* __MINGW32__ */
+
+#define curl_simple_lock SRWLOCK
+#define CURL_SIMPLE_LOCK_INIT SRWLOCK_INIT
+
+#define curl_simple_lock_lock(m) AcquireSRWLockExclusive(m)
+#define curl_simple_lock_unlock(m) ReleaseSRWLockExclusive(m)
+
+#elif defined(HAVE_ATOMIC) && defined(HAVE_STDATOMIC_H)
+#include <stdatomic.h>
+#if defined(HAVE_SCHED_YIELD)
+#include <sched.h>
+#endif
+
+#define curl_simple_lock atomic_int
+#define CURL_SIMPLE_LOCK_INIT 0
+
+/* a clang-thing */
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#ifndef __INTEL_COMPILER
+/* The Intel compiler tries to look like GCC *and* clang *and* lies in its
+ __has_builtin() function, so override it. */
+
+/* if GCC on i386/x86_64 or if the built-in is present */
+#if ( (defined(__GNUC__) && !defined(__clang__)) && \
+ (defined(__i386__) || defined(__x86_64__))) || \
+ __has_builtin(__builtin_ia32_pause)
+#define HAVE_BUILTIN_IA32_PAUSE
+#endif
+
+#endif
+
+static inline void curl_simple_lock_lock(curl_simple_lock *lock)
+{
+ for(;;) {
+ if(!atomic_exchange_explicit(lock, true, memory_order_acquire))
+ break;
+ /* Reduce cache coherency traffic */
+ while(atomic_load_explicit(lock, memory_order_relaxed)) {
+ /* Reduce load (not mandatory) */
+#ifdef HAVE_BUILTIN_IA32_PAUSE
+ __builtin_ia32_pause();
+#elif defined(__aarch64__)
+ __asm__ volatile("yield" ::: "memory");
+#elif defined(HAVE_SCHED_YIELD)
+ sched_yield();
+#endif
+ }
+ }
+}
+
+static inline void curl_simple_lock_unlock(curl_simple_lock *lock)
+{
+ atomic_store_explicit(lock, false, memory_order_release);
+}
+
+#else
+
+#undef GLOBAL_INIT_IS_THREADSAFE
+
+#endif
diff --git a/Utilities/cmcurl/lib/easygetopt.c b/Utilities/cmcurl/lib/easygetopt.c
index 7b2213fb24..a639bb3758 100644
--- a/Utilities/cmcurl/lib/easygetopt.c
+++ b/Utilities/cmcurl/lib/easygetopt.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* ___|___/|_| ______|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel.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
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/easyif.h b/Utilities/cmcurl/lib/easyif.h
index 3364418285..205382cd07 100644
--- a/Utilities/cmcurl/lib/easyif.h
+++ b/Utilities/cmcurl/lib/easyif.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,11 +20,16 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
* Prototypes for library-wide functions provided by easy.c
*/
+CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer,
+ size_t buflen, ssize_t *n);
+
#ifdef CURLDEBUG
CURL_EXTERN CURLcode curl_easy_perform_ev(struct Curl_easy *easy);
#endif
diff --git a/Utilities/cmcurl/lib/easyoptions.c b/Utilities/cmcurl/lib/easyoptions.c
index 04871ad1e3..e59b63af7a 100644
--- a/Utilities/cmcurl/lib/easyoptions.c
+++ b/Utilities/cmcurl/lib/easyoptions.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* ___|___/|_| ______|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel.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
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* This source code is generated by optiontable.pl - DO NOT EDIT BY HAND */
@@ -105,7 +107,8 @@ struct curl_easyoption Curl_easyopts[] = {
{"FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS,
CURLOT_LONG, 0},
{"FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD, CURLOT_VALUES, 0},
- {"FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOT_LONG, 0},
+ {"FTP_RESPONSE_TIMEOUT", CURLOPT_SERVER_RESPONSE_TIMEOUT,
+ CURLOT_LONG, CURLOT_FLAG_ALIAS},
{"FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP, CURLOT_LONG, 0},
{"FTP_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, CURLOT_FLAG_ALIAS},
{"FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC, CURLOT_LONG, 0},
@@ -201,6 +204,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"PROGRESSDATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
{"PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION, CURLOT_FUNCTION, 0},
{"PROTOCOLS", CURLOPT_PROTOCOLS, CURLOT_LONG, 0},
+ {"PROTOCOLS_STR", CURLOPT_PROTOCOLS_STR, CURLOT_STRING, 0},
{"PROXY", CURLOPT_PROXY, CURLOT_STRING, 0},
{"PROXYAUTH", CURLOPT_PROXYAUTH, CURLOT_VALUES, 0},
{"PROXYHEADER", CURLOPT_PROXYHEADER, CURLOT_SLIST, 0},
@@ -243,6 +247,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"READDATA", CURLOPT_READDATA, CURLOT_CBPTR, 0},
{"READFUNCTION", CURLOPT_READFUNCTION, CURLOT_FUNCTION, 0},
{"REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS, CURLOT_LONG, 0},
+ {"REDIR_PROTOCOLS_STR", CURLOPT_REDIR_PROTOCOLS_STR, CURLOT_STRING, 0},
{"REFERER", CURLOPT_REFERER, CURLOT_STRING, 0},
{"REQUEST_TARGET", CURLOPT_REQUEST_TARGET, CURLOT_STRING, 0},
{"RESOLVE", CURLOPT_RESOLVE, CURLOT_SLIST, 0},
@@ -262,8 +267,8 @@ struct curl_easyoption Curl_easyopts[] = {
{"SASL_IR", CURLOPT_SASL_IR, CURLOT_LONG, 0},
{"SEEKDATA", CURLOPT_SEEKDATA, CURLOT_CBPTR, 0},
{"SEEKFUNCTION", CURLOPT_SEEKFUNCTION, CURLOT_FUNCTION, 0},
- {"SERVER_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT,
- CURLOT_LONG, CURLOT_FLAG_ALIAS},
+ {"SERVER_RESPONSE_TIMEOUT", CURLOPT_SERVER_RESPONSE_TIMEOUT,
+ CURLOT_LONG, 0},
{"SERVICE_NAME", CURLOPT_SERVICE_NAME, CURLOT_STRING, 0},
{"SHARE", CURLOPT_SHARE, CURLOT_OBJECT, 0},
{"SOCKOPTDATA", CURLOPT_SOCKOPTDATA, CURLOT_CBPTR, 0},
@@ -273,6 +278,8 @@ struct curl_easyoption Curl_easyopts[] = {
{"SOCKS5_GSSAPI_SERVICE", CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOT_STRING, 0},
{"SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES, CURLOT_VALUES, 0},
{"SSH_COMPRESSION", CURLOPT_SSH_COMPRESSION, CURLOT_LONG, 0},
+ {"SSH_HOSTKEYDATA", CURLOPT_SSH_HOSTKEYDATA, CURLOT_CBPTR, 0},
+ {"SSH_HOSTKEYFUNCTION", CURLOPT_SSH_HOSTKEYFUNCTION, CURLOT_FUNCTION, 0},
{"SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
CURLOT_STRING, 0},
{"SSH_HOST_PUBLIC_KEY_SHA256", CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256,
@@ -347,10 +354,11 @@ struct curl_easyoption Curl_easyopts[] = {
{"WRITEDATA", CURLOPT_WRITEDATA, CURLOT_CBPTR, 0},
{"WRITEFUNCTION", CURLOPT_WRITEFUNCTION, CURLOT_FUNCTION, 0},
{"WRITEHEADER", CURLOPT_HEADERDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
+ {"WS_OPTIONS", CURLOPT_WS_OPTIONS, CURLOT_LONG, 0},
{"XFERINFODATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, 0},
{"XFERINFOFUNCTION", CURLOPT_XFERINFOFUNCTION, CURLOT_FUNCTION, 0},
{"XOAUTH2_BEARER", CURLOPT_XOAUTH2_BEARER, CURLOT_STRING, 0},
- {NULL, CURLOPT_LASTENTRY, 0, 0} /* end of table */
+ {NULL, CURLOPT_LASTENTRY, CURLOT_LONG, 0} /* end of table */
};
#ifdef DEBUGBUILD
@@ -360,6 +368,6 @@ struct curl_easyoption Curl_easyopts[] = {
*/
int Curl_easyopts_check(void)
{
- return ((CURLOPT_LASTENTRY%10000) != (315 + 1));
+ return ((CURLOPT_LASTENTRY%10000) != (320 + 1));
}
#endif
diff --git a/Utilities/cmcurl/lib/easyoptions.h b/Utilities/cmcurl/lib/easyoptions.h
index 91e11908bd..33f816d6b6 100644
--- a/Utilities/cmcurl/lib/easyoptions.h
+++ b/Utilities/cmcurl/lib/easyoptions.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* should probably go into the public header */
diff --git a/Utilities/cmcurl/lib/escape.c b/Utilities/cmcurl/lib/escape.c
index ff5887508e..da7e5524f7 100644
--- a/Utilities/cmcurl/lib/escape.c
+++ b/Utilities/cmcurl/lib/escape.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* Escape and unescape URL encoding in strings. The functions return a new
@@ -75,6 +77,9 @@ char *curl_unescape(const char *string, int length)
return curl_easy_unescape(NULL, string, length, NULL);
}
+/* Escapes for URL the given unescaped string of given length.
+ * 'data' is ignored since 7.82.0.
+ */
char *curl_easy_escape(struct Curl_easy *data, const char *string,
int inlength)
{
@@ -116,8 +121,6 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
* Returns a pointer to a malloced string in *ostring with length given in
* *olen. If length == 0, the length is assumed to be strlen(string).
*
- * 'data' can be set to NULL
- *
* ctrl options:
* - REJECT_NADA: accept everything
* - REJECT_CTRL: rejects control characters (byte codes lower than 32) in
@@ -191,6 +194,7 @@ CURLcode Curl_urldecode(const char *string, size_t length,
* pointer to a malloced string with length given in *olen.
* If length == 0, the length is assumed to be strlen(string).
* If olen == NULL, no output length is stored.
+ * 'data' is ignored since 7.82.0.
*/
char *curl_easy_unescape(struct Curl_easy *data, const char *string,
int length, int *olen)
diff --git a/Utilities/cmcurl/lib/escape.h b/Utilities/cmcurl/lib/escape.h
index 02668835cc..61d4611bf7 100644
--- a/Utilities/cmcurl/lib/escape.h
+++ b/Utilities/cmcurl/lib/escape.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* Escape and unescape URL encoding in strings. The functions return a new
* allocated string or NULL if an error occurred. */
diff --git a/Utilities/cmcurl/lib/file.c b/Utilities/cmcurl/lib/file.c
index 3da79a2c1b..d82d57b463 100644
--- a/Utilities/cmcurl/lib/file.c
+++ b/Utilities/cmcurl/lib/file.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -69,6 +71,8 @@
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
#define DOS_FILESYSTEM 1
+#elif defined(__amigaos4__)
+#define AMIGA_FILESYSTEM 1
#endif
#ifdef OPEN_NEEDS_ARG3
@@ -194,8 +198,33 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
return CURLE_URL_MALFORMAT;
}
+ #ifdef AMIGA_FILESYSTEM
+ /*
+ * A leading slash in an AmigaDOS path denotes the parent
+ * directory, and hence we block this as it is relative.
+ * Absolute paths start with 'volumename:', so we check for
+ * this first. Failing that, we treat the path as a real unix
+ * path, but only if the application was compiled with -lunix.
+ */
+ fd = -1;
+ file->path = real_path;
+
+ if(real_path[0] == '/') {
+ extern int __unix_path_semantics;
+ if(strchr(real_path + 1, ':')) {
+ /* Amiga absolute path */
+ fd = open_readonly(real_path + 1, O_RDONLY);
+ file->path++;
+ }
+ else if(__unix_path_semantics) {
+ /* -lunix fallback */
+ fd = open_readonly(real_path, O_RDONLY);
+ }
+ }
+ #else
fd = open_readonly(real_path, O_RDONLY);
file->path = real_path;
+ #endif
#endif
file->freepath = real_path; /* free this when done */
@@ -234,7 +263,7 @@ static CURLcode file_disconnect(struct Curl_easy *data,
{
(void)dead_connection; /* not used */
(void)conn;
- return file_done(data, 0, 0);
+ return file_done(data, CURLE_OK, FALSE);
}
#ifdef DOS_FILESYSTEM
diff --git a/Utilities/cmcurl/lib/file.h b/Utilities/cmcurl/lib/file.h
index 338f92e46a..826d45380d 100644
--- a/Utilities/cmcurl/lib/file.h
+++ b/Utilities/cmcurl/lib/file.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
diff --git a/Utilities/cmcurl/lib/fileinfo.c b/Utilities/cmcurl/lib/fileinfo.c
index b7e9f0f5e8..7bbf24bdeb 100644
--- a/Utilities/cmcurl/lib/fileinfo.c
+++ b/Utilities/cmcurl/lib/fileinfo.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/fileinfo.h b/Utilities/cmcurl/lib/fileinfo.h
index 5ae23ad4a3..5bad718cc8 100644
--- a/Utilities/cmcurl/lib/fileinfo.h
+++ b/Utilities/cmcurl/lib/fileinfo.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <curl/curl.h>
diff --git a/Utilities/cmcurl/lib/fopen.c b/Utilities/cmcurl/lib/fopen.c
new file mode 100644
index 0000000000..ad3691ba9d
--- /dev/null
+++ b/Utilities/cmcurl/lib/fopen.c
@@ -0,0 +1,113 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
+ !defined(CURL_DISABLE_HSTS)
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "urldata.h"
+#include "rand.h"
+#include "fopen.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_fopen() opens a file for writing with a temp name, to be renamed
+ * to the final name when completed. If there is an existing file using this
+ * name at the time of the open, this function will clone the mode from that
+ * file. if 'tempname' is non-NULL, it needs a rename after the file is
+ * written.
+ */
+CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
+ FILE **fh, char **tempname)
+{
+ CURLcode result = CURLE_WRITE_ERROR;
+ unsigned char randsuffix[9];
+ char *tempstore = NULL;
+ struct_stat sb;
+ int fd = -1;
+ *tempname = NULL;
+
+ if(stat(filename, &sb) == -1 || !S_ISREG(sb.st_mode)) {
+ /* a non-regular file, fallback to direct fopen() */
+ *fh = fopen(filename, FOPEN_WRITETEXT);
+ if(*fh)
+ return CURLE_OK;
+ goto fail;
+ }
+
+ result = Curl_rand_hex(data, randsuffix, sizeof(randsuffix));
+ if(result)
+ goto fail;
+
+ tempstore = aprintf("%s.%s.tmp", filename, randsuffix);
+ if(!tempstore) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto fail;
+ }
+
+ result = CURLE_WRITE_ERROR;
+ fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ if(fd == -1)
+ goto fail;
+
+#ifdef HAVE_FCHMOD
+ {
+ struct_stat nsb;
+ if((fstat(fd, &nsb) != -1) &&
+ (nsb.st_uid == sb.st_uid) && (nsb.st_gid == sb.st_gid)) {
+ /* if the user and group are the same, clone the original mode */
+ if(fchmod(fd, sb.st_mode) == -1)
+ goto fail;
+ }
+ }
+#endif
+
+ *fh = fdopen(fd, FOPEN_WRITETEXT);
+ if(!*fh)
+ goto fail;
+
+ *tempname = tempstore;
+ return CURLE_OK;
+
+fail:
+ if(fd != -1) {
+ close(fd);
+ unlink(tempstore);
+ }
+
+ free(tempstore);
+
+ *tempname = NULL;
+ return result;
+}
+
+#endif /* ! disabled */
diff --git a/Utilities/cmcurl/lib/vssh/wolfssh.h b/Utilities/cmcurl/lib/fopen.h
index 7b6ac489a4..289e55f2af 100644
--- a/Utilities/cmcurl/lib/vssh/wolfssh.h
+++ b/Utilities/cmcurl/lib/fopen.h
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_WOLFSSH_H
-#define HEADER_CURL_WOLFSSH_H
+#ifndef HEADER_CURL_FOPEN_H
+#define HEADER_CURL_FOPEN_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,8 +20,11 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
-extern const struct Curl_handler Curl_handler_sftp;
+CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
+ FILE **fh, char **tempname);
-#endif /* HEADER_CURL_WOLFSSH_H */
+#endif
diff --git a/Utilities/cmcurl/lib/formdata.c b/Utilities/cmcurl/lib/formdata.c
index 5fefd7a6ef..46542b4329 100644
--- a/Utilities/cmcurl/lib/formdata.c
+++ b/Utilities/cmcurl/lib/formdata.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -249,8 +251,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
}
}
else {
- /* This is not array-state, get next option */
- option = va_arg(params, CURLformoption);
+ /* This is not array-state, get next option. This gets an 'int' with
+ va_arg() because CURLformoption might be a smaller type than int and
+ might cause compiler warnings and wrong behavior. */
+ option = (CURLformoption)va_arg(params, int);
if(CURLFORM_END == option)
break;
}
diff --git a/Utilities/cmcurl/lib/formdata.h b/Utilities/cmcurl/lib/formdata.h
index 09c6e9c28a..c6c6397cd2 100644
--- a/Utilities/cmcurl/lib/formdata.h
+++ b/Utilities/cmcurl/lib/formdata.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/ftp.c b/Utilities/cmcurl/lib/ftp.c
index 45d9cedc3b..d02ab99e96 100644
--- a/Utilities/cmcurl/lib/ftp.c
+++ b/Utilities/cmcurl/lib/ftp.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -514,10 +516,9 @@ static CURLcode AllowServerConnect(struct Curl_easy *data, bool *connected)
}
else {
/* Add timeout to multi handle and break out of the loop */
- if(*connected == FALSE) {
- Curl_expire(data, data->set.accepttimeout > 0 ?
- data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, 0);
- }
+ Curl_expire(data, data->set.accepttimeout ?
+ data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT,
+ EXPIRE_FTP_ACCEPT);
}
return result;
@@ -783,8 +784,9 @@ static CURLcode ftp_state_user(struct Curl_easy *data,
&conn->proto.ftpc.pp, "USER %s",
conn->user?conn->user:"");
if(!result) {
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ ftpc->ftp_trying_alternative = FALSE;
state(data, FTP_USER);
- data->state.ftp_trying_alternative = FALSE;
}
return result;
}
@@ -2127,9 +2129,11 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
default:
infof(data, "unsupported MDTM reply format");
break;
- case 550: /* "No such file or directory" */
- failf(data, "Given file does not exist");
- result = CURLE_REMOTE_FILE_NOT_FOUND;
+ case 550: /* 550 is used for several different problems, e.g.
+ "No such file or directory" or "Permission denied".
+ It does not mean that the file does not exist at all. */
+ infof(data, "MDTM failed: file does not exist or permission problem,"
+ " continuing");
break;
}
@@ -2622,13 +2626,13 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
(the server denies to log the specified user) */
if(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] &&
- !data->state.ftp_trying_alternative) {
+ !ftpc->ftp_trying_alternative) {
/* Ok, USER failed. Let's try the supplied command. */
result =
Curl_pp_sendf(data, &ftpc->pp, "%s",
data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
if(!result) {
- data->state.ftp_trying_alternative = TRUE;
+ ftpc->ftp_trying_alternative = TRUE;
state(data, FTP_USER);
}
}
@@ -2701,10 +2705,11 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
set a valid level */
Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]);
- if(Curl_sec_login(data, conn))
- infof(data, "Logging in with password in cleartext");
- else
- infof(data, "Authentication successful");
+ if(Curl_sec_login(data, conn)) {
+ failf(data, "secure login failed");
+ return CURLE_WEIRD_SERVER_REPLY;
+ }
+ infof(data, "Authentication successful");
}
#endif
@@ -3561,8 +3566,10 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
bool connected = FALSE;
bool complete = FALSE;
- /* the ftp struct is inited in ftp_connect() */
- struct FTP *ftp = data->req.p.ftp;
+ /* the ftp struct is inited in ftp_connect(). If we are connecting to an HTTP
+ * proxy then the state will not be valid until after that connection is
+ * complete */
+ struct FTP *ftp = NULL;
/* if the second connection isn't done yet, wait for it */
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
@@ -3603,6 +3610,9 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
return result;
#endif
+ /* Curl_proxy_connect might have moved the protocol state */
+ ftp = data->req.p.ftp;
+
if(ftpc->state) {
/* already in a state so skip the initial commands.
They are only done to kickstart the do_more state */
diff --git a/Utilities/cmcurl/lib/ftp.h b/Utilities/cmcurl/lib/ftp.h
index 1cfdac0851..7f6f4328d1 100644
--- a/Utilities/cmcurl/lib/ftp.h
+++ b/Utilities/cmcurl/lib/ftp.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,8 +20,12 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
+#include "curl_setup.h"
+
#include "pingpong.h"
#ifndef CURL_DISABLE_FTP
@@ -149,6 +153,7 @@ struct ftp_conn {
curl_off_t known_filesize; /* file size is different from -1, if wildcard
LIST parsing was done and wc_statemach set
it */
+ BIT(ftp_trying_alternative);
};
#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */
diff --git a/Utilities/cmcurl/lib/ftplistparser.c b/Utilities/cmcurl/lib/ftplistparser.c
index 716ff38172..40f5f3f189 100644
--- a/Utilities/cmcurl/lib/ftplistparser.c
+++ b/Utilities/cmcurl/lib/ftplistparser.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/**
@@ -420,7 +422,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
char *endptr = finfo->b_data + 6;
/* here we can deal with directory size, pass the leading
whitespace and then the digits */
- while(ISSPACE(*endptr))
+ while(ISBLANK(*endptr))
endptr++;
while(ISDIGIT(*endptr))
endptr++;
@@ -892,7 +894,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
parser->item_length++;
switch(parser->state.NT.sub.time) {
case PL_WINNT_TIME_PRESPACE:
- if(!ISSPACE(c)) {
+ if(!ISBLANK(c)) {
parser->state.NT.sub.time = PL_WINNT_TIME_TIME;
}
break;
diff --git a/Utilities/cmcurl/lib/ftplistparser.h b/Utilities/cmcurl/lib/ftplistparser.h
index e4cd8201d9..0a80543417 100644
--- a/Utilities/cmcurl/lib/ftplistparser.h
+++ b/Utilities/cmcurl/lib/ftplistparser.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/functypes.h b/Utilities/cmcurl/lib/functypes.h
new file mode 100644
index 0000000000..8891b1d5d6
--- /dev/null
+++ b/Utilities/cmcurl/lib/functypes.h
@@ -0,0 +1,115 @@
+#ifndef HEADER_CURL_FUNCTYPES_H
+#define HEADER_CURL_FUNCTYPES_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/* defaults:
+
+ ssize_t recv(int, void *, size_t, int);
+ ssize_t send(int, const void *, size_t, int);
+
+ If other argument or return types are needed:
+
+ 1. For systems that run configure or cmake, the alternatives are provided
+ here.
+ 2. For systems with config-*.h files, define them there.
+*/
+
+#ifdef WIN32
+/* int recv(SOCKET, char *, int, int) */
+#define RECV_TYPE_ARG1 SOCKET
+#define RECV_TYPE_ARG2 char *
+#define RECV_TYPE_ARG3 int
+#define RECV_TYPE_RETV int
+
+/* int send(SOCKET, const char *, int, int); */
+#define SEND_TYPE_ARG1 SOCKET
+#define SEND_TYPE_ARG2 char *
+#define SEND_TYPE_ARG3 int
+#define SEND_TYPE_RETV int
+
+#elif defined(__AMIGA__) /* Any AmigaOS flavour */
+
+/* long recv(long, char *, long, long); */
+#define RECV_TYPE_ARG1 long
+#define RECV_TYPE_ARG2 char *
+#define RECV_TYPE_ARG3 long
+#define RECV_TYPE_ARG4 long
+#define RECV_TYPE_RETV long
+
+/* int send(int, const char *, int, int); */
+#define SEND_TYPE_ARG1 int
+#define SEND_TYPE_ARG2 char *
+#define SEND_TYPE_ARG3 int
+#define SEND_TYPE_RETV int
+#endif
+
+
+#ifndef RECV_TYPE_ARG1
+#define RECV_TYPE_ARG1 int
+#endif
+
+#ifndef RECV_TYPE_ARG2
+#define RECV_TYPE_ARG2 void *
+#endif
+
+#ifndef RECV_TYPE_ARG3
+#define RECV_TYPE_ARG3 size_t
+#endif
+
+#ifndef RECV_TYPE_ARG4
+#define RECV_TYPE_ARG4 int
+#endif
+
+#ifndef RECV_TYPE_RETV
+#define RECV_TYPE_RETV ssize_t
+#endif
+
+#ifndef SEND_QUAL_ARG2
+#define SEND_QUAL_ARG2 const
+#endif
+
+#ifndef SEND_TYPE_ARG1
+#define SEND_TYPE_ARG1 int
+#endif
+
+#ifndef SEND_TYPE_ARG2
+#define SEND_TYPE_ARG2 void *
+#endif
+
+#ifndef SEND_TYPE_ARG3
+#define SEND_TYPE_ARG3 size_t
+#endif
+
+#ifndef SEND_TYPE_ARG4
+#define SEND_TYPE_ARG4 int
+#endif
+
+#ifndef SEND_TYPE_RETV
+#define SEND_TYPE_RETV ssize_t
+#endif
+
+#endif /* HEADER_CURL_FUNCTYPES_H */
diff --git a/Utilities/cmcurl/lib/getenv.c b/Utilities/cmcurl/lib/getenv.c
index 92c53505c6..5f00fd13a4 100644
--- a/Utilities/cmcurl/lib/getenv.c
+++ b/Utilities/cmcurl/lib/getenv.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/getinfo.c b/Utilities/cmcurl/lib/getinfo.c
index 9091e6139d..c3556b3102 100644
--- a/Utilities/cmcurl/lib/getinfo.c
+++ b/Utilities/cmcurl/lib/getinfo.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -164,6 +166,20 @@ static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
case CURLINFO_SCHEME:
*param_charp = data->info.conn_scheme;
break;
+ case CURLINFO_CAPATH:
+#ifdef CURL_CA_PATH
+ *param_charp = CURL_CA_PATH;
+#else
+ *param_charp = NULL;
+#endif
+ break;
+ case CURLINFO_CAINFO:
+#ifdef CURL_CA_BUNDLE
+ *param_charp = CURL_CA_BUNDLE;
+#else
+ *param_charp = NULL;
+#endif
+ break;
default:
return CURLE_UNKNOWN_OPTION;
@@ -285,6 +301,7 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
/* return if the condition prevented the document to get transferred */
*param_longp = data->info.timecond ? 1L : 0L;
break;
+#ifndef CURL_DISABLE_RTSP
case CURLINFO_RTSP_CLIENT_CSEQ:
*param_longp = data->state.rtsp_next_client_CSeq;
break;
@@ -294,6 +311,7 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
case CURLINFO_RTSP_CSEQ_RECV:
*param_longp = data->state.rtsp_CSeq_recv;
break;
+#endif
case CURLINFO_HTTP_VERSION:
switch(data->info.httpversion) {
case 10:
@@ -560,7 +578,7 @@ CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...)
CURLcode result = CURLE_UNKNOWN_OPTION;
if(!data)
- return result;
+ return CURLE_BAD_FUNCTION_ARGUMENT;
va_start(arg, info);
diff --git a/Utilities/cmcurl/lib/getinfo.h b/Utilities/cmcurl/lib/getinfo.h
index f35d1b4b34..1b5e8c20f8 100644
--- a/Utilities/cmcurl/lib/getinfo.h
+++ b/Utilities/cmcurl/lib/getinfo.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...);
CURLcode Curl_initinfo(struct Curl_easy *data);
diff --git a/Utilities/cmcurl/lib/gopher.c b/Utilities/cmcurl/lib/gopher.c
index 0a3ba8fb56..01f4bdef0c 100644
--- a/Utilities/cmcurl/lib/gopher.c
+++ b/Utilities/cmcurl/lib/gopher.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/gopher.h b/Utilities/cmcurl/lib/gopher.h
index 6b8bd554a6..4ea269d2b4 100644
--- a/Utilities/cmcurl/lib/gopher.h
+++ b/Utilities/cmcurl/lib/gopher.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_GOPHER
diff --git a/Utilities/cmcurl/lib/h2h3.c b/Utilities/cmcurl/lib/h2h3.c
index c0ed58d37a..50254ad0fa 100644
--- a/Utilities/cmcurl/lib/h2h3.c
+++ b/Utilities/cmcurl/lib/h2h3.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -189,7 +191,7 @@ CURLcode Curl_pseudo_headers(struct Curl_easy *data,
vptr = Curl_checkheaders(data, STRCONST(H2H3_PSEUDO_SCHEME));
if(vptr) {
vptr += sizeof(H2H3_PSEUDO_SCHEME);
- while(*vptr && ISSPACE(*vptr))
+ while(*vptr && ISBLANK(*vptr))
vptr++;
nva[2].value = vptr;
infof(data, "set pseudo header %s to %s", H2H3_PSEUDO_SCHEME, vptr);
@@ -256,9 +258,6 @@ CURLcode Curl_pseudo_headers(struct Curl_easy *data,
nva[i].valuelen = (end - hdbuf);
}
- nva[i].value = hdbuf;
- nva[i].valuelen = (end - hdbuf);
-
++i;
}
diff --git a/Utilities/cmcurl/lib/h2h3.h b/Utilities/cmcurl/lib/h2h3.h
index 22256841c6..84caec5d5e 100644
--- a/Utilities/cmcurl/lib/h2h3.h
+++ b/Utilities/cmcurl/lib/h2h3.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/hash.c b/Utilities/cmcurl/lib/hash.c
index 8848906947..b6a2a33c72 100644
--- a/Utilities/cmcurl/lib/hash.c
+++ b/Utilities/cmcurl/lib/hash.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/hash.h b/Utilities/cmcurl/lib/hash.h
index e166916a90..5b59bf1118 100644
--- a/Utilities/cmcurl/lib/hash.h
+++ b/Utilities/cmcurl/lib/hash.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/headers.c b/Utilities/cmcurl/lib/headers.c
index 226c696be6..978c918f4f 100644
--- a/Utilities/cmcurl/lib/headers.c
+++ b/Utilities/cmcurl/lib/headers.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -32,7 +34,7 @@
#include "curl_memory.h"
#include "memdebug.h"
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_HEADERS_API)
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HEADERS_API)
/* Generate the curl_header struct for the user. This function MUST assign all
struct fields in the output struct. */
@@ -72,8 +74,8 @@ CURLHcode curl_easy_header(CURL *easy,
struct Curl_header_store *hs = NULL;
struct Curl_header_store *pick = NULL;
if(!name || !hout || !data ||
- (type > (CURLH_HEADER|CURLH_TRAILER|CURLH_CONNECT|CURLH_1XX)) ||
- !type || (request < -1))
+ (type > (CURLH_HEADER|CURLH_TRAILER|CURLH_CONNECT|CURLH_1XX|
+ CURLH_PSEUDO)) || !type || (request < -1))
return CURLHE_BAD_ARGUMENT;
if(!Curl_llist_count(&data->state.httphdrs))
return CURLHE_NOHEADERS; /* no headers available */
@@ -205,7 +207,7 @@ static CURLcode namevalue(char *header, size_t hlen, unsigned int type,
return CURLE_BAD_FUNCTION_ARGUMENT;
/* skip all leading space letters */
- while(*header && ISSPACE(*header))
+ while(*header && ISBLANK(*header))
header++;
*value = header;
@@ -216,6 +218,57 @@ static CURLcode namevalue(char *header, size_t hlen, unsigned int type,
return CURLE_OK;
}
+static CURLcode unfold_value(struct Curl_easy *data, const char *value,
+ size_t vlen) /* length of the incoming header */
+{
+ struct Curl_header_store *hs;
+ struct Curl_header_store *newhs;
+ size_t olen; /* length of the old value */
+ size_t oalloc; /* length of the old name + value + separator */
+ size_t offset;
+ DEBUGASSERT(data->state.prevhead);
+ hs = data->state.prevhead;
+ olen = strlen(hs->value);
+ offset = hs->value - hs->buffer;
+ oalloc = olen + offset + 1;
+
+ /* skip all trailing space letters */
+ while(vlen && ISSPACE(value[vlen - 1]))
+ vlen--;
+
+ /* save only one leading space */
+ while((vlen > 1) && ISBLANK(value[0]) && ISBLANK(value[1])) {
+ vlen--;
+ value++;
+ }
+
+ /* since this header block might move in the realloc below, it needs to
+ first be unlinked from the list and then re-added again after the
+ realloc */
+ Curl_llist_remove(&data->state.httphdrs, &hs->node, NULL);
+
+ /* new size = struct + new value length + old name+value length */
+ newhs = Curl_saferealloc(hs, sizeof(*hs) + vlen + oalloc + 1);
+ if(!newhs)
+ return CURLE_OUT_OF_MEMORY;
+ /* ->name' and ->value point into ->buffer (to keep the header allocation
+ in a single memory block), which now potentially have moved. Adjust
+ them. */
+ newhs->name = newhs->buffer;
+ newhs->value = &newhs->buffer[offset];
+
+ /* put the data at the end of the previous data, not the newline */
+ memcpy(&newhs->value[olen], value, vlen);
+ newhs->value[olen + vlen] = 0; /* null-terminate at newline */
+
+ /* insert this node into the list of headers */
+ Curl_llist_insert_next(&data->state.httphdrs, data->state.httphdrs.tail,
+ newhs, &newhs->node);
+ data->state.prevhead = newhs;
+ return CURLE_OK;
+}
+
+
/*
* Curl_headers_push() gets passed a full HTTP header to store. It gets called
* immediately before the header callback. The header is CRLF terminated.
@@ -242,6 +295,15 @@ CURLcode Curl_headers_push(struct Curl_easy *data, const char *header,
}
hlen = end - header + 1;
+ if((header[0] == ' ') || (header[0] == '\t')) {
+ if(data->state.prevhead)
+ /* line folding, append value to the previous header's value */
+ return unfold_value(data, header, hlen);
+ else
+ /* can't unfold without a previous header */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
hs = calloc(1, sizeof(*hs) + hlen);
if(!hs)
return CURLE_OUT_OF_MEMORY;
@@ -260,7 +322,7 @@ CURLcode Curl_headers_push(struct Curl_easy *data, const char *header,
/* insert this node into the list of headers */
Curl_llist_insert_next(&data->state.httphdrs, data->state.httphdrs.tail,
hs, &hs->node);
-
+ data->state.prevhead = hs;
return CURLE_OK;
fail:
free(hs);
diff --git a/Utilities/cmcurl/lib/headers.h b/Utilities/cmcurl/lib/headers.h
index 48c013b04d..96332dbd0b 100644
--- a/Utilities/cmcurl/lib/headers.h
+++ b/Utilities/cmcurl/lib/headers.h
@@ -20,10 +20,12 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_HEADERS_API)
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HEADERS_API)
struct Curl_header_store {
struct Curl_llist_element node;
diff --git a/Utilities/cmcurl/lib/hmac.c b/Utilities/cmcurl/lib/hmac.c
index 85b175d45f..dfb0db5757 100644
--- a/Utilities/cmcurl/lib/hmac.c
+++ b/Utilities/cmcurl/lib/hmac.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC2104 Keyed-Hashing for Message Authentication
*
***************************************************************************/
diff --git a/Utilities/cmcurl/lib/hostasyn.c b/Utilities/cmcurl/lib/hostasyn.c
index f7d99ce9a6..0bfbe2ef86 100644
--- a/Utilities/cmcurl/lib/hostasyn.c
+++ b/Utilities/cmcurl/lib/hostasyn.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/hostip.c b/Utilities/cmcurl/lib/hostip.c
index 7000b85501..941ecacf4a 100644
--- a/Utilities/cmcurl/lib/hostip.c
+++ b/Utilities/cmcurl/lib/hostip.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -179,7 +181,7 @@ create_hostcache_id(const char *name, int port, char *ptr, size_t buflen)
len = buflen - 7;
/* store and lower case the name */
while(len--)
- *ptr++ = (char)TOLOWER(*name++);
+ *ptr++ = Curl_raw_tolower(*name++);
msnprintf(ptr, 7, ":%u", port);
}
@@ -295,6 +297,31 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data,
}
}
+ /* See if the returned entry matches the required resolve mode */
+ if(dns && data->conn->ip_version != CURL_IPRESOLVE_WHATEVER) {
+ int pf = PF_INET;
+ bool found = false;
+ struct Curl_addrinfo *addr = dns->addr;
+
+#ifdef PF_INET6
+ if(data->conn->ip_version == CURL_IPRESOLVE_V6)
+ pf = PF_INET6;
+#endif
+
+ while(addr) {
+ if(addr->ai_family == pf) {
+ found = true;
+ break;
+ }
+ addr = addr->ai_next;
+ }
+
+ if(!found) {
+ infof(data, "Hostname in DNS cache doesn't have needed family, zapped");
+ dns = NULL; /* the memory deallocation is being handled by the hash */
+ Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
+ }
+ }
return dns;
}
@@ -461,12 +488,12 @@ Curl_cache_addr(struct Curl_easy *data,
}
#ifdef ENABLE_IPV6
-/* return a static IPv6 resolve for 'localhost' */
-static struct Curl_addrinfo *get_localhost6(int port)
+/* return a static IPv6 ::1 for the name */
+static struct Curl_addrinfo *get_localhost6(int port, const char *name)
{
struct Curl_addrinfo *ca;
const size_t ss_size = sizeof(struct sockaddr_in6);
- const size_t hostlen = strlen("localhost");
+ const size_t hostlen = strlen(name);
struct sockaddr_in6 sa6;
unsigned char ipv6[16];
unsigned short port16 = (unsigned short)(port & 0xffff);
@@ -491,19 +518,19 @@ static struct Curl_addrinfo *get_localhost6(int port)
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
memcpy(ca->ai_addr, &sa6, ss_size);
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
- strcpy(ca->ai_canonname, "localhost");
+ strcpy(ca->ai_canonname, name);
return ca;
}
#else
-#define get_localhost6(x) NULL
+#define get_localhost6(x,y) NULL
#endif
-/* return a static IPv4 resolve for 'localhost' */
-static struct Curl_addrinfo *get_localhost(int port)
+/* return a static IPv4 127.0.0.1 for the given name */
+static struct Curl_addrinfo *get_localhost(int port, const char *name)
{
struct Curl_addrinfo *ca;
const size_t ss_size = sizeof(struct sockaddr_in);
- const size_t hostlen = strlen("localhost");
+ const size_t hostlen = strlen(name);
struct sockaddr_in sa;
unsigned int ipv4;
unsigned short port16 = (unsigned short)(port & 0xffff);
@@ -527,8 +554,8 @@ static struct Curl_addrinfo *get_localhost(int port)
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
memcpy(ca->ai_addr, &sa, ss_size);
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
- strcpy(ca->ai_canonname, "localhost");
- ca->ai_next = get_localhost6(port);
+ strcpy(ca->ai_canonname, name);
+ ca->ai_next = get_localhost6(port, name);
return ca;
}
@@ -544,7 +571,11 @@ bool Curl_ipv6works(struct Curl_easy *data)
have the info kept for fast re-use */
DEBUGASSERT(data);
DEBUGASSERT(data->multi);
- return data->multi->ipv6_works;
+ if(data->multi->ipv6_up == IPV6_UNKNOWN) {
+ bool works = Curl_ipv6works(NULL);
+ data->multi->ipv6_up = works ? IPV6_WORKS : IPV6_DEAD;
+ }
+ return data->multi->ipv6_up == IPV6_WORKS;
}
else {
int ipv6_works = -1;
@@ -581,6 +612,17 @@ bool Curl_host_is_ipnum(const char *hostname)
return FALSE;
}
+
+/* return TRUE if 'part' is a case insensitive tail of 'full' */
+static bool tailmatch(const char *full, const char *part)
+{
+ size_t plen = strlen(part);
+ size_t flen = strlen(full);
+ if(plen > flen)
+ return FALSE;
+ return strncasecompare(part, &full[flen - plen], plen);
+}
+
/*
* Curl_resolv() is the main name resolve function within libcurl. It resolves
* a name and returns a pointer to the entry in the 'entry' argument (if one
@@ -716,8 +758,9 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
if(conn->ip_version == CURL_IPRESOLVE_V6 && !Curl_ipv6works(data))
return CURLRESOLV_ERROR;
- if(strcasecompare(hostname, "localhost"))
- addr = get_localhost(port);
+ if(strcasecompare(hostname, "localhost") ||
+ tailmatch(hostname, ".localhost"))
+ addr = get_localhost(port, hostname);
#ifndef CURL_DISABLE_DOH
else if(allowDOH && data->set.doh && !ipnum)
addr = Curl_doh(data, hostname, port, &respwait);
@@ -991,9 +1034,9 @@ static void freednsentry(void *freethis)
/*
* Curl_init_dnscache() inits a new DNS cache.
*/
-void Curl_init_dnscache(struct Curl_hash *hash)
+void Curl_init_dnscache(struct Curl_hash *hash, int size)
{
- Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
+ Curl_hash_init(hash, size, Curl_hash_str, Curl_str_key_compare,
freednsentry);
}
diff --git a/Utilities/cmcurl/lib/hostip.h b/Utilities/cmcurl/lib/hostip.h
index 1db5981842..9d3170737c 100644
--- a/Utilities/cmcurl/lib/hostip.h
+++ b/Utilities/cmcurl/lib/hostip.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -130,7 +132,7 @@ void Curl_resolv_unlock(struct Curl_easy *data,
struct Curl_dns_entry *dns);
/* init a new dns cache */
-void Curl_init_dnscache(struct Curl_hash *hash);
+void Curl_init_dnscache(struct Curl_hash *hash, int hashsize);
/* prune old entries from the DNS cache */
void Curl_hostcache_prune(struct Curl_easy *data);
diff --git a/Utilities/cmcurl/lib/hostip4.c b/Utilities/cmcurl/lib/hostip4.c
index 1fd791015c..1dd54e879d 100644
--- a/Utilities/cmcurl/lib/hostip4.c
+++ b/Utilities/cmcurl/lib/hostip4.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -110,7 +112,8 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
#endif /* CURLRES_SYNCH */
#endif /* CURLRES_IPV4 */
-#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES)
+#if defined(CURLRES_IPV4) && \
+ !defined(CURLRES_ARES) && !defined(CURLRES_AMIGA)
/*
* Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function.
@@ -295,4 +298,5 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
return ai;
}
-#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */
+#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) &&
+ !defined(CURLRES_AMIGA) */
diff --git a/Utilities/cmcurl/lib/hostip6.c b/Utilities/cmcurl/lib/hostip6.c
index c2d5f08e32..c62c254c72 100644
--- a/Utilities/cmcurl/lib/hostip6.c
+++ b/Utilities/cmcurl/lib/hostip6.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -94,8 +96,8 @@ static void dump_addrinfo(struct connectdata *conn,
* non-ares version).
*
* Returns name information about the given hostname and port number. If
- * successful, the 'addrinfo' is returned and the forth argument will point to
- * memory we need to free after use. That memory *MUST* be freed with
+ * successful, the 'addrinfo' is returned and the fourth argument will point
+ * to memory we need to free after use. That memory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else.
*/
struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
@@ -115,7 +117,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
*waitp = 0; /* synchronous response only */
- if(Curl_ipv6works(data))
+ if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
/* The stack seems to be IPv6-enabled */
pf = PF_UNSPEC;
diff --git a/Utilities/cmcurl/lib/hostsyn.c b/Utilities/cmcurl/lib/hostsyn.c
index c00c2744c4..ee54363bf9 100644
--- a/Utilities/cmcurl/lib/hostsyn.c
+++ b/Utilities/cmcurl/lib/hostsyn.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/hsts.c b/Utilities/cmcurl/lib/hsts.c
index b9fa6f7af5..e3b686ebfa 100644
--- a/Utilities/cmcurl/lib/hsts.c
+++ b/Utilities/cmcurl/lib/hsts.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
* The Strict-Transport-Security header is defined in RFC 6797:
@@ -35,7 +37,7 @@
#include "sendf.h"
#include "strtoofft.h"
#include "parsedate.h"
-#include "rand.h"
+#include "fopen.h"
#include "rename.h"
#include "strtoofft.h"
@@ -154,7 +156,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
return CURLE_OK;
do {
- while(*p && ISSPACE(*p))
+ while(*p && ISBLANK(*p))
p++;
if(Curl_strncasecompare("max-age=", p, 8)) {
bool quoted = FALSE;
@@ -165,7 +167,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
return CURLE_BAD_FUNCTION_ARGUMENT;
p += 8;
- while(*p && ISSPACE(*p))
+ while(*p && ISBLANK(*p))
p++;
if(*p == '\"') {
p++;
@@ -198,7 +200,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
p++;
}
- while(*p && ISSPACE(*p))
+ while(*p && ISBLANK(*p))
p++;
if(*p == ';')
p++;
@@ -354,8 +356,7 @@ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
struct Curl_llist_element *n;
CURLcode result = CURLE_OK;
FILE *out;
- char *tempstore;
- unsigned char randsuffix[9];
+ char *tempstore = NULL;
if(!h)
/* no cache activated */
@@ -369,17 +370,8 @@ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
/* marked as read-only, no file or zero length file name */
goto skipsave;
- if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
- return CURLE_FAILED_INIT;
-
- tempstore = aprintf("%s.%s.tmp", file, randsuffix);
- if(!tempstore)
- return CURLE_OUT_OF_MEMORY;
-
- out = fopen(tempstore, FOPEN_WRITETEXT);
- if(!out)
- result = CURLE_WRITE_ERROR;
- else {
+ result = Curl_fopen(data, file, &out, &tempstore);
+ if(!result) {
fputs("# Your HSTS cache. https://curl.se/docs/hsts.html\n"
"# This file was generated by libcurl! Edit at your own risk.\n",
out);
@@ -391,10 +383,10 @@ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
break;
}
fclose(out);
- if(!result && Curl_rename(tempstore, file))
+ if(!result && tempstore && Curl_rename(tempstore, file))
result = CURLE_WRITE_ERROR;
- if(result)
+ if(result && tempstore)
unlink(tempstore);
}
free(tempstore);
@@ -494,8 +486,7 @@ static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h)
/*
* Load the HSTS cache from the given file. The text based line-oriented file
- * format is documented here:
- * https://github.com/curl/curl/wiki/HSTS
+ * format is documented here: https://curl.se/docs/hsts.html
*
* This function only returns error on major problems that prevent hsts
* handling to work completely. It will ignore individual syntactical errors
diff --git a/Utilities/cmcurl/lib/hsts.h b/Utilities/cmcurl/lib/hsts.h
index 653c05348d..0e36a7756b 100644
--- a/Utilities/cmcurl/lib/hsts.h
+++ b/Utilities/cmcurl/lib/hsts.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2020 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2020 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/http.c b/Utilities/cmcurl/lib/http.c
index b215307dca..f57859e8b0 100644
--- a/Utilities/cmcurl/lib/http.c
+++ b/Utilities/cmcurl/lib/http.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -82,6 +84,7 @@
#include "strdup.h"
#include "altsvc.h"
#include "hsts.h"
+#include "ws.h"
#include "c-hyper.h"
/* The last 3 #include files should be in this order */
@@ -112,6 +115,10 @@ static int https_getsock(struct Curl_easy *data,
#endif
static CURLcode http_setup_conn(struct Curl_easy *data,
struct connectdata *conn);
+#ifdef USE_WEBSOCKETS
+static CURLcode ws_setup_conn(struct Curl_easy *data,
+ struct connectdata *conn);
+#endif
/*
* HTTP handler interface.
@@ -140,6 +147,32 @@ const struct Curl_handler Curl_handler_http = {
PROTOPT_USERPWDCTRL
};
+#ifdef USE_WEBSOCKETS
+const struct Curl_handler Curl_handler_ws = {
+ "WS", /* scheme */
+ ws_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ Curl_http_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ http_getsock_do, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ PORT_HTTP, /* defport */
+ CURLPROTO_WS, /* protocol */
+ CURLPROTO_HTTP, /* family */
+ PROTOPT_CREDSPERREQUEST | /* flags */
+ PROTOPT_USERPWDCTRL
+};
+#endif
+
#ifdef USE_SSL
/*
* HTTPS handler interface.
@@ -164,11 +197,38 @@ const struct Curl_handler Curl_handler_https = {
PORT_HTTPS, /* defport */
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
- PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | /* flags */
+ PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */
+ PROTOPT_USERPWDCTRL
+};
+
+#ifdef USE_WEBSOCKETS
+const struct Curl_handler Curl_handler_wss = {
+ "WSS", /* scheme */
+ ws_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ Curl_http_connect, /* connect_it */
+ https_connecting, /* connecting */
+ ZERO_NULL, /* doing */
+ https_getsock, /* proto_getsock */
+ http_getsock_do, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ PORT_HTTPS, /* defport */
+ CURLPROTO_WSS, /* protocol */
+ CURLPROTO_HTTP, /* family */
+ PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL
};
#endif
+#endif
+
static CURLcode http_setup_conn(struct Curl_easy *data,
struct connectdata *conn)
{
@@ -203,6 +263,16 @@ static CURLcode http_setup_conn(struct Curl_easy *data,
return CURLE_OK;
}
+#ifdef USE_WEBSOCKETS
+static CURLcode ws_setup_conn(struct Curl_easy *data,
+ struct connectdata *conn)
+{
+ /* websockets is 1.1 only (for now) */
+ data->state.httpwant = CURL_HTTP_VERSION_1_1;
+ return http_setup_conn(data, conn);
+}
+#endif
+
#ifndef CURL_DISABLE_PROXY
/*
* checkProxyHeaders() checks the linked list of custom proxy headers
@@ -651,21 +721,6 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data)
return result;
}
-/*
- * Curl_allow_auth_to_host() tells if authentication, cookies or other
- * "sensitive data" can (still) be sent to this host.
- */
-bool Curl_allow_auth_to_host(struct Curl_easy *data)
-{
- struct connectdata *conn = data->conn;
- return (!data->state.this_is_a_follow ||
- data->set.allow_auth_to_other_hosts ||
- (data->state.first_host &&
- strcasecompare(data->state.first_host, conn->host.name) &&
- (data->state.first_remote_port == conn->remote_port) &&
- (data->state.first_remote_protocol == conn->handler->protocol)));
-}
-
#ifndef CURL_DISABLE_HTTP_AUTH
/*
* Output the correct authentication header depending on the auth type
@@ -864,7 +919,7 @@ Curl_http_output_auth(struct Curl_easy *data,
/* To prevent the user+password to get sent to other than the original host
due to a location-follow */
- if(Curl_allow_auth_to_host(data)
+ if(Curl_auth_allowed_to_host(data)
#ifndef CURL_DISABLE_NETRC
|| conn->bits.netrc
#endif
@@ -1516,7 +1571,7 @@ CURLcode Curl_http_connect(struct Curl_easy *data, bool *done)
}
#endif
- if(conn->given->protocol & CURLPROTO_HTTPS) {
+ if(conn->given->flags & PROTOPT_SSL) {
/* perform SSL initialization */
result = https_connecting(data, done);
if(result)
@@ -1641,6 +1696,7 @@ CURLcode Curl_http_done(struct Curl_easy *data,
Curl_mime_cleanpart(&http->form);
Curl_dyn_reset(&data->state.headerb);
Curl_hyper_done(data);
+ Curl_ws_done(data);
if(status)
return status;
@@ -1917,7 +1973,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
checkprefix("Cookie:", compare)) &&
/* be careful of sending this potentially sensitive header to
other hosts */
- !Curl_allow_auth_to_host(data))
+ !Curl_auth_allowed_to_host(data))
;
else {
#ifdef USE_HYPER
@@ -2030,7 +2086,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
const char **method, Curl_HttpReq *reqp)
{
- Curl_HttpReq httpreq = data->state.httpreq;
+ Curl_HttpReq httpreq = (Curl_HttpReq)data->state.httpreq;
const char *request;
if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
data->set.upload)
@@ -2149,9 +2205,9 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
[brackets] if the host name is a plain IPv6-address. RFC2732-style. */
const char *host = conn->host.name;
- if(((conn->given->protocol&CURLPROTO_HTTPS) &&
+ if(((conn->given->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS)) &&
(conn->remote_port == PORT_HTTPS)) ||
- ((conn->given->protocol&CURLPROTO_HTTP) &&
+ ((conn->given->protocol&(CURLPROTO_HTTP|CURLPROTO_WS)) &&
(conn->remote_port == PORT_HTTP)) )
/* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
the port number in the host string */
@@ -2700,6 +2756,13 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
FIRSTSOCKET);
if(result)
failf(data, "Failed sending HTTP request");
+#ifdef USE_WEBSOCKETS
+ else if((conn->handler->protocol & (CURLPROTO_WS|CURLPROTO_WSS)) &&
+ !(data->set.connect_only))
+ /* Set up the transfer for two-way since without CONNECT_ONLY set, this
+ request probably wants to send data too post upgrade */
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, FIRSTSOCKET);
+#endif
else
/* HTTP GET/HEAD download: */
Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
@@ -2709,12 +2772,14 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
}
#if !defined(CURL_DISABLE_COOKIES)
+
CURLcode Curl_http_cookies(struct Curl_easy *data,
struct connectdata *conn,
struct dynbuf *r)
{
CURLcode result = CURLE_OK;
char *addcookies = NULL;
+ bool linecap = FALSE;
if(data->set.str[STRING_COOKIE] &&
!Curl_checkheaders(data, STRCONST("Cookie")))
addcookies = data->set.str[STRING_COOKIE];
@@ -2727,12 +2792,12 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
const char *host = data->state.aptr.cookiehost ?
data->state.aptr.cookiehost : conn->host.name;
const bool secure_context =
- conn->handler->protocol&CURLPROTO_HTTPS ||
+ conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
strcasecompare("localhost", host) ||
!strcmp(host, "127.0.0.1") ||
!strcmp(host, "[::1]") ? TRUE : FALSE;
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
- co = Curl_cookie_getlist(data->cookies, host, data->state.up.path,
+ co = Curl_cookie_getlist(data, data->cookies, host, data->state.up.path,
secure_context);
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
}
@@ -2746,6 +2811,13 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
if(result)
break;
}
+ if((Curl_dyn_len(r) + strlen(co->name) + strlen(co->value) + 1) >=
+ MAX_COOKIE_HEADER_LEN) {
+ infof(data, "Restricted outgoing cookies due to header size, "
+ "'%s' not sent", co->name);
+ linecap = TRUE;
+ break;
+ }
result = Curl_dyn_addf(r, "%s%s=%s", count?"; ":"",
co->name, co->value);
if(result)
@@ -2756,7 +2828,7 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
}
Curl_cookie_freelist(store);
}
- if(addcookies && !result) {
+ if(addcookies && !result && !linecap) {
if(!count)
result = Curl_dyn_addn(r, STRCONST("Cookie: "));
if(!result) {
@@ -3033,7 +3105,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
if(conn->transport != TRNSPRT_QUIC) {
if(conn->httpversion < 20) { /* unless the connection is re-used and
already http2 */
- switch(conn->negnpn) {
+ switch(conn->alpn) {
case CURL_HTTP_VERSION_2:
conn->httpversion = 20; /* we know we're on HTTP/2 now */
@@ -3245,6 +3317,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
}
result = Curl_http_cookies(data, conn, &req);
+ if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS))
+ result = Curl_ws_request(data, &req);
if(!result)
result = Curl_add_timecondition(data, &req);
if(!result)
@@ -3509,15 +3583,15 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
else if(checkprefix("Retry-After:", headp)) {
/* Retry-After = HTTP-date / delay-seconds */
curl_off_t retry_after = 0; /* zero for unknown or "now" */
- time_t date = Curl_getdate_capped(headp + strlen("Retry-After:"));
- if(-1 == date) {
- /* not a date, try it as a decimal number */
- (void)curlx_strtoofft(headp + strlen("Retry-After:"),
- NULL, 10, &retry_after);
+ /* Try it as a decimal number, if it works it is not a date */
+ (void)curlx_strtoofft(headp + strlen("Retry-After:"),
+ NULL, 10, &retry_after);
+ if(!retry_after) {
+ time_t date = Curl_getdate_capped(headp + strlen("Retry-After:"));
+ if(-1 != date)
+ /* convert date to number of seconds into the future */
+ retry_after = date - time(NULL);
}
- else
- /* convert date to number of seconds into the future */
- retry_after = date - time(NULL);
data->info.retry_after = retry_after; /* store it */
}
else if(!k->http_bodyless && checkprefix("Content-Range:", headp)) {
@@ -3529,7 +3603,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
The second format was added since Sun's webserver
JavaWebServer/1.1.1 obviously sends the header this way!
The third added since some servers use that!
- The forth means the requested range was unsatisfied.
+ The fourth means the requested range was unsatisfied.
*/
char *ptr = headp + strlen("Content-Range:");
@@ -3557,7 +3631,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
const char *host = data->state.aptr.cookiehost?
data->state.aptr.cookiehost:conn->host.name;
const bool secure_context =
- conn->handler->protocol&CURLPROTO_HTTPS ||
+ conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
strcasecompare("localhost", host) ||
!strcmp(host, "127.0.0.1") ||
!strcmp(host, "[::1]") ? TRUE : FALSE;
@@ -3641,7 +3715,14 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
#ifndef CURL_DISABLE_HSTS
/* If enabled, the header is incoming and this is over HTTPS */
else if(data->hsts && checkprefix("Strict-Transport-Security:", headp) &&
- (conn->handler->flags & PROTOPT_SSL)) {
+ ((conn->handler->flags & PROTOPT_SSL) ||
+#ifdef CURLDEBUG
+ /* allow debug builds to circumvent the HTTPS restriction */
+ getenv("CURL_HSTS_HTTP")
+#else
+ 0
+#endif
+ )) {
CURLcode check =
Curl_hsts_parse(data->hsts, data->state.up.hostname,
headp + strlen("Strict-Transport-Security:"));
@@ -3723,7 +3804,7 @@ CURLcode Curl_http_statusline(struct Curl_easy *data,
connclose(conn, "HTTP/1.0 close after body");
}
else if(conn->httpversion == 20 ||
- (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
+ (k->upgr101 == UPGR101_H2 && k->httpcode == 101)) {
DEBUGF(infof(data, "HTTP/2 found, allow multiplexing"));
/* HTTP/2 cannot avoid multiplexing since it is a core functionality
of the protocol */
@@ -3799,11 +3880,16 @@ static CURLcode verify_header(struct Curl_easy *data)
if(k->headerline < 2)
/* the first "header" is the status-line and it has no colon */
return CURLE_OK;
- ptr = memchr(header, ':', hlen);
- if(!ptr) {
- /* this is bad, bail out */
- failf(data, "Header without colon");
- return CURLE_WEIRD_SERVER_REPLY;
+ if(((header[0] == ' ') || (header[0] == '\t')) && k->headerline > 2)
+ /* line folding, can't happen on line 2 */
+ ;
+ else {
+ ptr = memchr(header, ':', hlen);
+ if(!ptr) {
+ /* this is bad, bail out */
+ failf(data, "Header without colon");
+ return CURLE_WEIRD_SERVER_REPLY;
+ }
}
return CURLE_OK;
}
@@ -3944,9 +4030,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
break;
case 101:
/* Switching Protocols */
- if(k->upgr101 == UPGR101_REQUESTED) {
+ if(k->upgr101 == UPGR101_H2) {
/* Switching to HTTP/2 */
- infof(data, "Received 101");
+ infof(data, "Received 101, Switching to HTTP/2");
k->upgr101 = UPGR101_RECEIVED;
/* we'll get more headers (HTTP/2 response) */
@@ -3960,8 +4046,21 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
return result;
*nread = 0;
}
+#ifdef USE_WEBSOCKETS
+ else if(k->upgr101 == UPGR101_WS) {
+ /* verify the response */
+ result = Curl_ws_accept(data);
+ if(result)
+ return result;
+ k->header = FALSE; /* no more header to parse! */
+ if(data->set.connect_only) {
+ k->keepon &= ~KEEP_RECV; /* read no more content */
+ *nread = 0;
+ }
+ }
+#endif
else {
- /* Switching to another protocol (e.g. WebSocket) */
+ /* Not switching to another protocol */
k->header = FALSE; /* no more header to parse! */
}
break;
@@ -4054,6 +4153,16 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
return CURLE_HTTP_RETURNED_ERROR;
}
+#ifdef USE_WEBSOCKETS
+ /* All non-101 HTTP status codes are bad when wanting to upgrade to
+ websockets */
+ if(data->req.upgr101 == UPGR101_WS) {
+ failf(data, "Refused WebSockets upgrade: %d", k->httpcode);
+ return CURLE_HTTP_RETURNED_ERROR;
+ }
+#endif
+
+
data->req.deductheadercount =
(100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
diff --git a/Utilities/cmcurl/lib/http.h b/Utilities/cmcurl/lib/http.h
index c4ab3c22de..f7cbb34244 100644
--- a/Utilities/cmcurl/lib/http.h
+++ b/Utilities/cmcurl/lib/http.h
@@ -20,8 +20,11 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
+#include "ws.h"
typedef enum {
HTTPREQ_GET,
@@ -48,6 +51,15 @@ extern const struct Curl_handler Curl_handler_http;
extern const struct Curl_handler Curl_handler_https;
#endif
+#ifdef USE_WEBSOCKETS
+extern const struct Curl_handler Curl_handler_ws;
+
+#ifdef USE_SSL
+extern const struct Curl_handler Curl_handler_wss;
+#endif
+#endif /* websockets */
+
+
/* Header specific functions */
bool Curl_compareheader(const char *headerline, /* line to check */
const char *header, /* header keyword _with_ colon */
@@ -216,6 +228,10 @@ struct HTTP {
HTTPSEND_BODY /* sending body */
} sending;
+#ifdef USE_WEBSOCKETS
+ struct websocket ws;
+#endif
+
#ifndef CURL_DISABLE_HTTP
struct dynbuf send_buffer; /* used if the request couldn't be sent in one
chunk, points to an allocated send_buffer
@@ -225,13 +241,11 @@ struct HTTP {
/*********** for HTTP/2 we store stream-local data here *************/
int32_t stream_id; /* stream we are interested in */
- bool bodystarted;
/* We store non-final and final response headers here, per-stream */
struct dynbuf header_recvbuf;
size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
upper layer */
struct dynbuf trailer_recvbuf;
- int status_code; /* HTTP status code */
const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
size_t pauselen; /* the number of bytes left in data */
bool close_handled; /* TRUE if stream closure is handled by libcurl */
@@ -242,6 +256,8 @@ struct HTTP {
uint32_t error; /* HTTP/2 stream error code */
#endif
#if defined(USE_NGHTTP2) || defined(USE_NGHTTP3)
+ bool bodystarted;
+ int status_code; /* HTTP status code */
bool closed; /* TRUE on HTTP2 stream close */
char *mem; /* points to a buffer in memory to store received data */
size_t len; /* size of the buffer 'mem' points to */
@@ -258,6 +274,7 @@ struct HTTP {
#ifndef USE_MSH3
/*********** for HTTP/3 we store stream-local data here *************/
int64_t stream3_id; /* stream we are interested in */
+ uint64_t error3; /* HTTP/3 stream error code */
bool firstheader; /* FALSE until headers arrive */
bool firstbody; /* FALSE until body arrives */
bool h3req; /* FALSE until request is issued */
@@ -364,10 +381,4 @@ Curl_http_output_auth(struct Curl_easy *data,
bool proxytunnel); /* TRUE if this is the request setting
up the proxy tunnel */
-/*
- * Curl_allow_auth_to_host() tells if authentication, cookies or other
- * "sensitive data" can (still) be sent to this host.
- */
-bool Curl_allow_auth_to_host(struct Curl_easy *data);
-
#endif /* HEADER_CURL_HTTP_H */
diff --git a/Utilities/cmcurl/lib/http2.c b/Utilities/cmcurl/lib/http2.c
index 0120b86311..b7409b027d 100644
--- a/Utilities/cmcurl/lib/http2.c
+++ b/Utilities/cmcurl/lib/http2.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -643,7 +645,7 @@ static int push_promise(struct Curl_easy *data,
frame->promised_stream_id,
newhandle);
if(rv) {
- infof(data, "failed to set user_data for stream %d",
+ infof(data, "failed to set user_data for stream %u",
frame->promised_stream_id);
DEBUGASSERT(0);
rv = CURL_PUSH_DENY;
@@ -713,19 +715,19 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
if(!data_s) {
H2BUGF(infof(data,
- "No Curl_easy associated with stream: %x",
+ "No Curl_easy associated with stream: %u",
stream_id));
return 0;
}
stream = data_s->req.p.http;
if(!stream) {
- H2BUGF(infof(data_s, "No proto pointer for stream: %x",
+ H2BUGF(infof(data_s, "No proto pointer for stream: %u",
stream_id));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x",
+ H2BUGF(infof(data_s, "on_frame_recv() header %x stream %u",
frame->hd.type, stream_id));
switch(frame->hd.type) {
@@ -913,7 +915,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
/* remove the entry from the hash as the stream is now gone */
rv = nghttp2_session_set_stream_user_data(session, stream_id, 0);
if(rv) {
- infof(data_s, "http/2: failed to clear user_data for stream %d",
+ infof(data_s, "http/2: failed to clear user_data for stream %u",
stream_id);
DEBUGASSERT(0);
}
@@ -1050,6 +1052,12 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
else if(stream->push_headers_used ==
stream->push_headers_alloc) {
char **headp;
+ if(stream->push_headers_alloc > 1000) {
+ /* this is beyond crazy many headers, bail out */
+ failf(data_s, "Too many PUSH_PROMISE headers");
+ Curl_safefree(stream->push_headers);
+ return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+ }
stream->push_headers_alloc *= 2;
headp = Curl_saferealloc(stream->push_headers,
stream->push_headers_alloc * sizeof(char *));
@@ -1240,13 +1248,13 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
/* do this before the reset handling, as that might clear ->stream_id */
if(http->stream_id == httpc->pause_stream_id) {
- H2BUGF(infof(data, "DONE the pause stream (%x)", http->stream_id));
+ H2BUGF(infof(data, "DONE the pause stream (%u)", http->stream_id));
httpc->pause_stream_id = 0;
}
if(premature || (!http->closed && http->stream_id)) {
/* RST_STREAM */
set_transfer(httpc, data); /* set the transfer */
- H2BUGF(infof(data, "RST stream %x", http->stream_id));
+ H2BUGF(infof(data, "RST stream %u", http->stream_id));
if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE,
http->stream_id, NGHTTP2_STREAM_CLOSED))
(void)nghttp2_session_send(httpc->h2);
@@ -1260,7 +1268,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
int rv = nghttp2_session_set_stream_user_data(httpc->h2,
http->stream_id, 0);
if(rv) {
- infof(data, "http/2: failed to clear user_data for stream %d",
+ infof(data, "http/2: failed to clear user_data for stream %u",
http->stream_id);
DEBUGASSERT(0);
}
@@ -1269,6 +1277,27 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
}
}
+static int client_new(struct connectdata *conn,
+ nghttp2_session_callbacks *callbacks)
+{
+#if NGHTTP2_VERSION_NUM < 0x013200
+ /* before 1.50.0 */
+ return nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn);
+#else
+ nghttp2_option *o;
+ int rc = nghttp2_option_new(&o);
+ if(rc)
+ return rc;
+ /* turn off RFC 9113 leading and trailing white spaces validation against
+ HTTP field value. */
+ nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
+ rc = nghttp2_session_client_new2(&conn->proto.httpc.h2, callbacks, conn,
+ o);
+ nghttp2_option_del(o);
+ return rc;
+#endif
+}
+
/*
* Initialize nghttp2 for a Curl connection
*/
@@ -1309,7 +1338,7 @@ static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn)
nghttp2_session_callbacks_set_error_callback(callbacks, error_callback);
/* The nghttp2 session is not yet setup, do it */
- rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn);
+ rc = client_new(conn, callbacks);
nghttp2_session_callbacks_del(callbacks);
@@ -1363,7 +1392,7 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
free(base64);
- k->upgr101 = UPGR101_REQUESTED;
+ k->upgr101 = UPGR101_H2;
return result;
}
@@ -1519,7 +1548,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
/* Reset to FALSE to prevent infinite loop in readwrite_data function. */
stream->closed = FALSE;
if(stream->error == NGHTTP2_REFUSED_STREAM) {
- H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection",
+ H2BUGF(infof(data, "REFUSED_STREAM (%u), try again on a new connection",
stream->stream_id));
connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */
data->state.refused_stream = TRUE;
@@ -1527,7 +1556,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
return -1;
}
else if(stream->error != NGHTTP2_NO_ERROR) {
- failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
+ failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %u)",
stream->stream_id, nghttp2_http2_strerror(stream->error),
stream->error);
*err = CURLE_HTTP2_STREAM;
@@ -1535,7 +1564,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
}
if(!stream->bodystarted) {
- failf(data, "HTTP/2 stream %d was closed cleanly, but before getting "
+ failf(data, "HTTP/2 stream %u was closed cleanly, but before getting "
" all response header fields, treated as error",
stream->stream_id);
*err = CURLE_HTTP2_STREAM;
@@ -1740,7 +1769,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
if(stream->closed)
/* closed overrides paused */
return 0;
- H2BUGF(infof(data, "stream %x is paused, pause id: %x",
+ H2BUGF(infof(data, "stream %u is paused, pause id: %u",
stream->stream_id, httpc->pause_stream_id));
*err = CURLE_AGAIN;
return -1;
@@ -1771,7 +1800,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
/* This will happen when the server or proxy server is SIGKILLed
during data transfer. We should emit an error since our data
received may be incomplete. */
- failf(data, "HTTP/2 stream %d was not closed cleanly before"
+ failf(data, "HTTP/2 stream %u was not closed cleanly before"
" end of the underlying stream",
stream->stream_id);
*err = CURLE_HTTP2_STREAM;
@@ -1855,7 +1884,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
if(stream->stream_id != -1) {
if(stream->close_handled) {
- infof(data, "stream %d closed", stream->stream_id);
+ infof(data, "stream %u closed", stream->stream_id);
*err = CURLE_HTTP2_STREAM;
return -1;
}
@@ -1968,13 +1997,13 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
if(stream_id < 0) {
H2BUGF(infof(data,
- "http2_send() nghttp2_submit_request error (%s)%d",
+ "http2_send() nghttp2_submit_request error (%s)%u",
nghttp2_strerror(stream_id), stream_id));
*err = CURLE_SEND_ERROR;
return -1;
}
- infof(data, "Using Stream ID: %x (easy handle %p)",
+ infof(data, "Using Stream ID: %u (easy handle %p)",
stream_id, (void *)data);
stream->stream_id = stream_id;
@@ -2094,7 +2123,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data,
stream->stream_id,
data);
if(rv) {
- infof(data, "http/2: failed to set user_data for stream %d",
+ infof(data, "http/2: failed to set user_data for stream %u",
stream->stream_id);
DEBUGASSERT(0);
}
diff --git a/Utilities/cmcurl/lib/http2.h b/Utilities/cmcurl/lib/http2.h
index d6986d97fa..f0390596ce 100644
--- a/Utilities/cmcurl/lib/http2.h
+++ b/Utilities/cmcurl/lib/http2.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/http_aws_sigv4.c b/Utilities/cmcurl/lib/http_aws_sigv4.c
index 210c3dbe56..440eb385f8 100644
--- a/Utilities/cmcurl/lib/http_aws_sigv4.c
+++ b/Utilities/cmcurl/lib/http_aws_sigv4.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -27,8 +29,6 @@
#include "urldata.h"
#include "strcase.h"
#include "strdup.h"
-#include "vauth/vauth.h"
-#include "vauth/digest.h"
#include "http_aws_sigv4.h"
#include "curl_sha256.h"
#include "transfer.h"
@@ -44,6 +44,8 @@
#include "curl_memory.h"
#include "memdebug.h"
+#include "slist.h"
+
#define HMAC_SHA256(k, kl, d, dl, o) \
do { \
ret = Curl_hmacit(Curl_HMAC_SHA256, \
@@ -51,19 +53,219 @@
(unsigned int)kl, \
(unsigned char *)d, \
(unsigned int)dl, o); \
- if(ret != CURLE_OK) { \
+ if(ret) { \
goto fail; \
} \
} while(0)
+#define TIMESTAMP_SIZE 17
+
static void sha256_to_hex(char *dst, unsigned char *sha, size_t dst_l)
{
int i;
DEBUGASSERT(dst_l >= 65);
for(i = 0; i < 32; ++i) {
- curl_msnprintf(dst + (i * 2), dst_l - (i * 2), "%02x", sha[i]);
+ msnprintf(dst + (i * 2), dst_l - (i * 2), "%02x", sha[i]);
+ }
+}
+
+static char *find_date_hdr(struct Curl_easy *data, const char *sig_hdr)
+{
+ char *tmp = Curl_checkheaders(data, sig_hdr, strlen(sig_hdr));
+
+ if(tmp)
+ return tmp;
+ return Curl_checkheaders(data, STRCONST("Date"));
+}
+
+/* remove whitespace, and lowercase all headers */
+static void trim_headers(struct curl_slist *head)
+{
+ struct curl_slist *l;
+ for(l = head; l; l = l->next) {
+ char *value; /* to read from */
+ char *store;
+ size_t colon = strcspn(l->data, ":");
+ Curl_strntolower(l->data, l->data, colon);
+
+ value = &l->data[colon];
+ if(!*value)
+ continue;
+ ++value;
+ store = value;
+
+ /* skip leading whitespace */
+ while(*value && ISBLANK(*value))
+ value++;
+
+ while(*value) {
+ int space = 0;
+ while(*value && ISBLANK(*value)) {
+ value++;
+ space++;
+ }
+ if(space) {
+ /* replace any number of consecutive whitespace with a single space,
+ unless at the end of the string, then nothing */
+ if(*value)
+ *store++ = ' ';
+ }
+ else
+ *store++ = *value++;
+ }
+ *store = 0; /* null terminate */
+ }
+}
+
+/* maximum lenth for the aws sivg4 parts */
+#define MAX_SIGV4_LEN 64
+#define MAX_SIGV4_LEN_TXT "64"
+
+#define DATE_HDR_KEY_LEN (MAX_SIGV4_LEN + sizeof("X--Date"))
+
+#define MAX_HOST_LEN 255
+/* FQDN + host: */
+#define FULL_HOST_LEN (MAX_HOST_LEN + sizeof("host:"))
+
+/* string been x-PROVIDER-date:TIMESTAMP, I need +1 for ':' */
+#define DATE_FULL_HDR_LEN (DATE_HDR_KEY_LEN + TIMESTAMP_SIZE + 1)
+
+/* timestamp should point to a buffer of at last TIMESTAMP_SIZE bytes */
+static CURLcode make_headers(struct Curl_easy *data,
+ const char *hostname,
+ char *timestamp,
+ char *provider1,
+ char **date_header,
+ struct dynbuf *canonical_headers,
+ struct dynbuf *signed_headers)
+{
+ char date_hdr_key[DATE_HDR_KEY_LEN];
+ char date_full_hdr[DATE_FULL_HDR_LEN];
+ struct curl_slist *head = NULL;
+ struct curl_slist *tmp_head = NULL;
+ CURLcode ret = CURLE_OUT_OF_MEMORY;
+ struct curl_slist *l;
+ int again = 1;
+
+ /* provider1 mid */
+ Curl_strntolower(provider1, provider1, strlen(provider1));
+ provider1[0] = Curl_raw_toupper(provider1[0]);
+
+ msnprintf(date_hdr_key, DATE_HDR_KEY_LEN, "X-%s-Date", provider1);
+
+ /* provider1 lowercase */
+ Curl_strntolower(provider1, provider1, 1); /* first byte only */
+ msnprintf(date_full_hdr, DATE_FULL_HDR_LEN,
+ "x-%s-date:%s", provider1, timestamp);
+
+ if(Curl_checkheaders(data, STRCONST("Host"))) {
+ head = NULL;
+ }
+ else {
+ char full_host[FULL_HOST_LEN + 1];
+
+ if(data->state.aptr.host) {
+ size_t pos;
+
+ if(strlen(data->state.aptr.host) > FULL_HOST_LEN) {
+ ret = CURLE_URL_MALFORMAT;
+ goto fail;
+ }
+ strcpy(full_host, data->state.aptr.host);
+ /* remove /r/n as the separator for canonical request must be '\n' */
+ pos = strcspn(full_host, "\n\r");
+ full_host[pos] = 0;
+ }
+ else {
+ if(strlen(hostname) > MAX_HOST_LEN) {
+ ret = CURLE_URL_MALFORMAT;
+ goto fail;
+ }
+ msnprintf(full_host, FULL_HOST_LEN, "host:%s", hostname);
+ }
+
+ head = curl_slist_append(NULL, full_host);
+ if(!head)
+ goto fail;
+ }
+
+
+ for(l = data->set.headers; l; l = l->next) {
+ tmp_head = curl_slist_append(head, l->data);
+ if(!tmp_head)
+ goto fail;
+ head = tmp_head;
+ }
+
+ trim_headers(head);
+
+ *date_header = find_date_hdr(data, date_hdr_key);
+ if(!*date_header) {
+ tmp_head = curl_slist_append(head, date_full_hdr);
+ if(!tmp_head)
+ goto fail;
+ head = tmp_head;
+ *date_header = curl_maprintf("%s: %s", date_hdr_key, timestamp);
+ }
+ else {
+ char *value;
+
+ *date_header = strdup(*date_header);
+ if(!*date_header)
+ goto fail;
+
+ value = strchr(*date_header, ':');
+ if(!value)
+ goto fail;
+ ++value;
+ while(ISBLANK(*value))
+ ++value;
+ strncpy(timestamp, value, TIMESTAMP_SIZE - 1);
+ timestamp[TIMESTAMP_SIZE - 1] = 0;
+ }
+
+ /* alpha-sort in a case sensitive manner */
+ do {
+ again = 0;
+ for(l = head; l; l = l->next) {
+ struct curl_slist *next = l->next;
+
+ if(next && strcmp(l->data, next->data) > 0) {
+ char *tmp = l->data;
+
+ l->data = next->data;
+ next->data = tmp;
+ again = 1;
+ }
+ }
+ } while(again);
+
+ for(l = head; l; l = l->next) {
+ char *tmp;
+
+ if(Curl_dyn_add(canonical_headers, l->data))
+ goto fail;
+ if(Curl_dyn_add(canonical_headers, "\n"))
+ goto fail;
+
+ tmp = strchr(l->data, ':');
+ if(tmp)
+ *tmp = 0;
+
+ if(l != head) {
+ if(Curl_dyn_add(signed_headers, ";"))
+ goto fail;
+ }
+ if(Curl_dyn_add(signed_headers, l->data))
+ goto fail;
}
+
+ ret = CURLE_OK;
+fail:
+ curl_slist_free_all(head);
+
+ return ret;
}
CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
@@ -71,29 +273,21 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
CURLcode ret = CURLE_OUT_OF_MEMORY;
struct connectdata *conn = data->conn;
size_t len;
- const char *tmp0;
- const char *tmp1;
- char *provider0_low = NULL;
- char *provider0_up = NULL;
- char *provider1_low = NULL;
- char *provider1_mid = NULL;
- char *region = NULL;
- char *service = NULL;
+ const char *arg;
+ char provider0[MAX_SIGV4_LEN + 1]="";
+ char provider1[MAX_SIGV4_LEN + 1]="";
+ char region[MAX_SIGV4_LEN + 1]="";
+ char service[MAX_SIGV4_LEN + 1]="";
const char *hostname = conn->host.name;
-#ifdef DEBUGBUILD
- char *force_timestamp;
-#endif
time_t clock;
struct tm tm;
- char timestamp[17];
+ char timestamp[TIMESTAMP_SIZE];
char date[9];
- const char *content_type = Curl_checkheaders(data, STRCONST("Content-Type"));
- char *canonical_headers = NULL;
- char *signed_headers = NULL;
- Curl_HttpReq httpreq;
- const char *method;
- size_t post_data_len;
- const char *post_data = data->set.postfields ? data->set.postfields : "";
+ struct dynbuf canonical_headers;
+ struct dynbuf signed_headers;
+ char *date_header = NULL;
+ const char *post_data = data->set.postfields;
+ size_t post_data_len = 0;
unsigned char sha_hash[32];
char sha_hex[65];
char *canonical_request = NULL;
@@ -101,10 +295,9 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
char *credential_scope = NULL;
char *str_to_sign = NULL;
const char *user = data->state.aptr.user ? data->state.aptr.user : "";
- const char *passwd = data->state.aptr.passwd ? data->state.aptr.passwd : "";
char *secret = NULL;
- unsigned char tmp_sign0[32] = {0};
- unsigned char tmp_sign1[32] = {0};
+ unsigned char sign0[32] = {0};
+ unsigned char sign1[32] = {0};
char *auth_headers = NULL;
DEBUGASSERT(!proxy);
@@ -115,6 +308,10 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
return CURLE_OK;
}
+ /* we init thoses buffers here, so goto fail will free initialized dynbuf */
+ Curl_dyn_init(&canonical_headers, CURL_MAX_HTTP_HEADER);
+ Curl_dyn_init(&signed_headers, CURL_MAX_HTTP_HEADER);
+
/*
* Parameters parsing
* Google and Outscale use the same OSC or GOOG,
@@ -122,223 +319,154 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
* AWS is the default because most of non-amazon providers
* are still using aws:amz as a prefix.
*/
- tmp0 = data->set.str[STRING_AWS_SIGV4] ?
+ arg = data->set.str[STRING_AWS_SIGV4] ?
data->set.str[STRING_AWS_SIGV4] : "aws:amz";
- tmp1 = strchr(tmp0, ':');
- len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0);
- if(len < 1) {
- infof(data, "first provider can't be empty");
+
+ /* provider1[:provider2[:region[:service]]]
+
+ No string can be longer than N bytes of non-whitespace
+ */
+ (void)sscanf(arg, "%" MAX_SIGV4_LEN_TXT "[^:]"
+ ":%" MAX_SIGV4_LEN_TXT "[^:]"
+ ":%" MAX_SIGV4_LEN_TXT "[^:]"
+ ":%" MAX_SIGV4_LEN_TXT "s",
+ provider0, provider1, region, service);
+ if(!provider0[0]) {
+ failf(data, "first provider can't be empty");
ret = CURLE_BAD_FUNCTION_ARGUMENT;
goto fail;
}
- provider0_low = malloc(len + 1);
- provider0_up = malloc(len + 1);
- if(!provider0_low || !provider0_up) {
- goto fail;
- }
- Curl_strntolower(provider0_low, tmp0, len);
- provider0_low[len] = '\0';
- Curl_strntoupper(provider0_up, tmp0, len);
- provider0_up[len] = '\0';
-
- if(tmp1) {
- tmp0 = tmp1 + 1;
- tmp1 = strchr(tmp0, ':');
- len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0);
- if(len < 1) {
- infof(data, "second provider can't be empty");
- ret = CURLE_BAD_FUNCTION_ARGUMENT;
- goto fail;
- }
- provider1_low = malloc(len + 1);
- provider1_mid = malloc(len + 1);
- if(!provider1_low || !provider1_mid) {
- goto fail;
- }
- Curl_strntolower(provider1_low, tmp0, len);
- provider1_low[len] = '\0';
- Curl_strntolower(provider1_mid, tmp0, len);
- provider1_mid[0] = Curl_raw_toupper(provider1_mid[0]);
- provider1_mid[len] = '\0';
-
- if(tmp1) {
- tmp0 = tmp1 + 1;
- tmp1 = strchr(tmp0, ':');
- len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0);
- if(len < 1) {
- infof(data, "region can't be empty");
- ret = CURLE_BAD_FUNCTION_ARGUMENT;
- goto fail;
- }
- region = Curl_memdup(tmp0, len + 1);
- if(!region) {
- goto fail;
- }
- region[len] = '\0';
+ else if(!provider1[0])
+ strcpy(provider1, provider0);
- if(tmp1) {
- tmp0 = tmp1 + 1;
- service = strdup(tmp0);
- if(!service) {
- goto fail;
- }
- if(strlen(service) < 1) {
- infof(data, "service can't be empty");
- ret = CURLE_BAD_FUNCTION_ARGUMENT;
- goto fail;
- }
- }
- }
- }
- else {
- provider1_low = Curl_memdup(provider0_low, len + 1);
- provider1_mid = Curl_memdup(provider0_low, len + 1);
- if(!provider1_low || !provider1_mid) {
- goto fail;
- }
- provider1_mid[0] = Curl_raw_toupper(provider1_mid[0]);
- }
-
- if(!service) {
- tmp0 = hostname;
- tmp1 = strchr(tmp0, '.');
- len = tmp1 - tmp0;
- if(!tmp1 || len < 1) {
- infof(data, "service missing in parameters or hostname");
+ if(!service[0]) {
+ char *hostdot = strchr(hostname, '.');
+ if(!hostdot) {
+ failf(data, "service missing in parameters and hostname");
ret = CURLE_URL_MALFORMAT;
goto fail;
}
- service = Curl_memdup(tmp0, len + 1);
- if(!service) {
+ len = hostdot - hostname;
+ if(len > MAX_SIGV4_LEN) {
+ failf(data, "service too long in hostname");
+ ret = CURLE_URL_MALFORMAT;
goto fail;
}
+ strncpy(service, hostname, len);
service[len] = '\0';
- if(!region) {
- tmp0 = tmp1 + 1;
- tmp1 = strchr(tmp0, '.');
- len = tmp1 - tmp0;
- if(!tmp1 || len < 1) {
- infof(data, "region missing in parameters or hostname");
+ if(!region[0]) {
+ const char *reg = hostdot + 1;
+ const char *hostreg = strchr(reg, '.');
+ if(!hostreg) {
+ failf(data, "region missing in parameters and hostname");
ret = CURLE_URL_MALFORMAT;
goto fail;
}
- region = Curl_memdup(tmp0, len + 1);
- if(!region) {
+ len = hostreg - reg;
+ if(len > MAX_SIGV4_LEN) {
+ failf(data, "region too long in hostname");
+ ret = CURLE_URL_MALFORMAT;
goto fail;
}
+ strncpy(region, reg, len);
region[len] = '\0';
}
}
#ifdef DEBUGBUILD
- force_timestamp = getenv("CURL_FORCETIME");
- if(force_timestamp)
- clock = 0;
- else
- time(&clock);
+ {
+ char *force_timestamp = getenv("CURL_FORCETIME");
+ if(force_timestamp)
+ clock = 0;
+ else
+ time(&clock);
+ }
#else
time(&clock);
#endif
ret = Curl_gmtime(clock, &tm);
- if(ret != CURLE_OK) {
+ if(ret) {
goto fail;
}
if(!strftime(timestamp, sizeof(timestamp), "%Y%m%dT%H%M%SZ", &tm)) {
+ ret = CURLE_OUT_OF_MEMORY;
goto fail;
}
+
+ ret = make_headers(data, hostname, timestamp, provider1,
+ &date_header, &canonical_headers, &signed_headers);
+ if(ret)
+ goto fail;
+ ret = CURLE_OUT_OF_MEMORY;
+
memcpy(date, timestamp, sizeof(date));
date[sizeof(date) - 1] = 0;
- if(content_type) {
- content_type = strchr(content_type, ':');
- if(!content_type) {
- ret = CURLE_FAILED_INIT;
- goto fail;
- }
- content_type++;
- /* Skip whitespace now */
- while(*content_type == ' ' || *content_type == '\t')
- ++content_type;
-
- canonical_headers = curl_maprintf("content-type:%s\n"
- "host:%s\n"
- "x-%s-date:%s\n",
- content_type,
- hostname,
- provider1_low, timestamp);
- signed_headers = curl_maprintf("content-type;host;x-%s-date",
- provider1_low);
- }
- else {
- canonical_headers = curl_maprintf("host:%s\n"
- "x-%s-date:%s\n",
- hostname,
- provider1_low, timestamp);
- signed_headers = curl_maprintf("host;x-%s-date", provider1_low);
- }
-
- if(!canonical_headers || !signed_headers) {
- goto fail;
+ if(post_data) {
+ if(data->set.postfieldsize < 0)
+ post_data_len = strlen(post_data);
+ else
+ post_data_len = (size_t)data->set.postfieldsize;
}
-
- if(data->set.postfieldsize < 0)
- post_data_len = strlen(post_data);
- else
- post_data_len = (size_t)data->set.postfieldsize;
if(Curl_sha256it(sha_hash, (const unsigned char *) post_data,
- post_data_len)) {
+ post_data_len))
goto fail;
- }
sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
- Curl_http_method(data, conn, &method, &httpreq);
-
- canonical_request =
- curl_maprintf("%s\n" /* HTTPRequestMethod */
- "%s\n" /* CanonicalURI */
- "%s\n" /* CanonicalQueryString */
- "%s\n" /* CanonicalHeaders */
- "%s\n" /* SignedHeaders */
- "%s", /* HashedRequestPayload in hex */
- method,
- data->state.up.path,
- data->state.up.query ? data->state.up.query : "",
- canonical_headers,
- signed_headers,
- sha_hex);
- if(!canonical_request) {
- goto fail;
+ {
+ Curl_HttpReq httpreq;
+ const char *method;
+
+ Curl_http_method(data, conn, &method, &httpreq);
+
+ canonical_request =
+ curl_maprintf("%s\n" /* HTTPRequestMethod */
+ "%s\n" /* CanonicalURI */
+ "%s\n" /* CanonicalQueryString */
+ "%s\n" /* CanonicalHeaders */
+ "%s\n" /* SignedHeaders */
+ "%s", /* HashedRequestPayload in hex */
+ method,
+ data->state.up.path,
+ data->state.up.query ? data->state.up.query : "",
+ Curl_dyn_ptr(&canonical_headers),
+ Curl_dyn_ptr(&signed_headers),
+ sha_hex);
+ if(!canonical_request)
+ goto fail;
}
- request_type = curl_maprintf("%s4_request", provider0_low);
- if(!request_type) {
+ /* provider 0 lowercase */
+ Curl_strntolower(provider0, provider0, strlen(provider0));
+ request_type = curl_maprintf("%s4_request", provider0);
+ if(!request_type)
goto fail;
- }
credential_scope = curl_maprintf("%s/%s/%s/%s",
date, region, service, request_type);
- if(!credential_scope) {
+ if(!credential_scope)
goto fail;
- }
if(Curl_sha256it(sha_hash, (unsigned char *) canonical_request,
- strlen(canonical_request))) {
+ strlen(canonical_request)))
goto fail;
- }
sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
+ /* provider 0 uppercase */
+ Curl_strntoupper(provider0, provider0, strlen(provider0));
+
/*
- * Google allow to use rsa key instead of HMAC, so this code might change
- * In the future, but for now we support only HMAC version
+ * Google allows using RSA key instead of HMAC, so this code might change
+ * in the future. For now we ony support HMAC.
*/
str_to_sign = curl_maprintf("%s4-HMAC-SHA256\n" /* Algorithm */
"%s\n" /* RequestDateTime */
"%s\n" /* CredentialScope */
"%s", /* HashedCanonicalRequest in hex */
- provider0_up,
+ provider0,
timestamp,
credential_scope,
sha_hex);
@@ -346,36 +474,33 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
goto fail;
}
- secret = curl_maprintf("%s4%s", provider0_up, passwd);
- if(!secret) {
+ /* provider 0 uppercase */
+ secret = curl_maprintf("%s4%s", provider0,
+ data->state.aptr.passwd ?
+ data->state.aptr.passwd : "");
+ if(!secret)
goto fail;
- }
- HMAC_SHA256(secret, strlen(secret),
- date, strlen(date), tmp_sign0);
- HMAC_SHA256(tmp_sign0, sizeof(tmp_sign0),
- region, strlen(region), tmp_sign1);
- HMAC_SHA256(tmp_sign1, sizeof(tmp_sign1),
- service, strlen(service), tmp_sign0);
- HMAC_SHA256(tmp_sign0, sizeof(tmp_sign0),
- request_type, strlen(request_type), tmp_sign1);
- HMAC_SHA256(tmp_sign1, sizeof(tmp_sign1),
- str_to_sign, strlen(str_to_sign), tmp_sign0);
+ HMAC_SHA256(secret, strlen(secret), date, strlen(date), sign0);
+ HMAC_SHA256(sign0, sizeof(sign0), region, strlen(region), sign1);
+ HMAC_SHA256(sign1, sizeof(sign1), service, strlen(service), sign0);
+ HMAC_SHA256(sign0, sizeof(sign0), request_type, strlen(request_type), sign1);
+ HMAC_SHA256(sign1, sizeof(sign1), str_to_sign, strlen(str_to_sign), sign0);
- sha256_to_hex(sha_hex, tmp_sign0, sizeof(sha_hex));
+ sha256_to_hex(sha_hex, sign0, sizeof(sha_hex));
+ /* provider 0 uppercase */
auth_headers = curl_maprintf("Authorization: %s4-HMAC-SHA256 "
"Credential=%s/%s, "
"SignedHeaders=%s, "
"Signature=%s\r\n"
- "X-%s-Date: %s\r\n",
- provider0_up,
+ "%s\r\n",
+ provider0,
user,
credential_scope,
- signed_headers,
+ Curl_dyn_ptr(&signed_headers),
sha_hex,
- provider1_mid,
- timestamp);
+ date_header);
if(!auth_headers) {
goto fail;
}
@@ -386,19 +511,14 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
ret = CURLE_OK;
fail:
- free(provider0_low);
- free(provider0_up);
- free(provider1_low);
- free(provider1_mid);
- free(region);
- free(service);
- free(canonical_headers);
- free(signed_headers);
+ Curl_dyn_free(&canonical_headers);
+ Curl_dyn_free(&signed_headers);
free(canonical_request);
free(request_type);
free(credential_scope);
free(str_to_sign);
free(secret);
+ free(date_header);
return ret;
}
diff --git a/Utilities/cmcurl/lib/http_aws_sigv4.h b/Utilities/cmcurl/lib/http_aws_sigv4.h
index 886b31440f..85755e937b 100644
--- a/Utilities/cmcurl/lib/http_aws_sigv4.h
+++ b/Utilities/cmcurl/lib/http_aws_sigv4.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/http_chunks.c b/Utilities/cmcurl/lib/http_chunks.c
index 6bafcd9777..0b836851ac 100644
--- a/Utilities/cmcurl/lib/http_chunks.c
+++ b/Utilities/cmcurl/lib/http_chunks.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -98,7 +100,7 @@ void Curl_httpchunk_init(struct Curl_easy *data)
CHUNKcode Curl_httpchunk_read(struct Curl_easy *data,
char *datap,
ssize_t datalen,
- ssize_t *wrotep,
+ ssize_t *wrote,
CURLcode *extrap)
{
CURLcode result = CURLE_OK;
@@ -107,7 +109,6 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data,
struct SingleRequest *k = &data->req;
size_t piece;
curl_off_t length = (curl_off_t)datalen;
- size_t *wrote = (size_t *)wrotep;
*wrote = 0; /* nothing's written yet */
@@ -124,7 +125,7 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data,
while(length) {
switch(ch->state) {
case CHUNK_HEX:
- if(isxdigit_ascii(*datap)) {
+ if(ISXDIGIT(*datap)) {
if(ch->hexindex < CHUNK_MAXNUM_LEN) {
ch->hexbuffer[ch->hexindex] = *datap;
datap++;
diff --git a/Utilities/cmcurl/lib/http_chunks.h b/Utilities/cmcurl/lib/http_chunks.h
index 741a9a3bc3..2cf5507c21 100644
--- a/Utilities/cmcurl/lib/http_chunks.h
+++ b/Utilities/cmcurl/lib/http_chunks.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
struct connectdata;
diff --git a/Utilities/cmcurl/lib/http_digest.c b/Utilities/cmcurl/lib/http_digest.c
index 34bb5a8e08..a71c6b7cfb 100644
--- a/Utilities/cmcurl/lib/http_digest.c
+++ b/Utilities/cmcurl/lib/http_digest.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -56,11 +58,11 @@ CURLcode Curl_input_digest(struct Curl_easy *data,
digest = &data->state.digest;
}
- if(!checkprefix("Digest", header) || !ISSPACE(header[6]))
+ if(!checkprefix("Digest", header) || !ISBLANK(header[6]))
return CURLE_BAD_CONTENT_ENCODING;
header += strlen("Digest");
- while(*header && ISSPACE(*header))
+ while(*header && ISBLANK(*header))
header++;
return Curl_auth_decode_digest_http_message(header, digest);
diff --git a/Utilities/cmcurl/lib/http_digest.h b/Utilities/cmcurl/lib/http_digest.h
index 89438d1a1f..eea90b7439 100644
--- a/Utilities/cmcurl/lib/http_digest.h
+++ b/Utilities/cmcurl/lib/http_digest.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/http_negotiate.c b/Utilities/cmcurl/lib/http_negotiate.c
index 888d3b24a2..5909f85b0d 100644
--- a/Utilities/cmcurl/lib/http_negotiate.c
+++ b/Utilities/cmcurl/lib/http_negotiate.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -82,7 +84,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
/* Obtain the input token, if any */
header += strlen("Negotiate");
- while(*header && ISSPACE(*header))
+ while(*header && ISBLANK(*header))
header++;
len = strlen(header);
diff --git a/Utilities/cmcurl/lib/http_negotiate.h b/Utilities/cmcurl/lib/http_negotiate.h
index 2640a3ee01..6e2096c697 100644
--- a/Utilities/cmcurl/lib/http_negotiate.h
+++ b/Utilities/cmcurl/lib/http_negotiate.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
diff --git a/Utilities/cmcurl/lib/http_ntlm.c b/Utilities/cmcurl/lib/http_ntlm.c
index bb7e5360f9..5a6a977905 100644
--- a/Utilities/cmcurl/lib/http_ntlm.c
+++ b/Utilities/cmcurl/lib/http_ntlm.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -27,7 +29,7 @@
/*
* NTLM details:
*
- * https://davenport.sourceforge.io/ntlm.html
+ * https://davenport.sourceforge.net/ntlm.html
* https://www.innovation.ch/java/ntlm.html
*/
diff --git a/Utilities/cmcurl/lib/http_ntlm.h b/Utilities/cmcurl/lib/http_ntlm.h
index 5b4fa00baa..cec63b82c3 100644
--- a/Utilities/cmcurl/lib/http_ntlm.h
+++ b/Utilities/cmcurl/lib/http_ntlm.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/http_proxy.c b/Utilities/cmcurl/lib/http_proxy.c
index ed08193e1e..cc20b3a801 100644
--- a/Utilities/cmcurl/lib/http_proxy.c
+++ b/Utilities/cmcurl/lib/http_proxy.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -210,10 +212,8 @@ void Curl_connect_done(struct Curl_easy *data)
Curl_dyn_free(&s->rcvbuf);
Curl_dyn_free(&s->req);
- /* restore the protocol pointer, if not already done */
- if(s->prot_save)
- data->req.p.http = s->prot_save;
- s->prot_save = NULL;
+ /* restore the protocol pointer */
+ data->req.p.http = s->prot_save;
data->info.httpcode = 0; /* clear it as it might've been used for the
proxy */
data->req.ignorebody = FALSE;
@@ -391,8 +391,8 @@ static CURLcode CONNECT(struct Curl_easy *data,
if(!result)
/* send to debug callback! */
- result = Curl_debug(data, CURLINFO_HEADER_OUT,
- k->upload_fromhere, bytes_written);
+ Curl_debug(data, CURLINFO_HEADER_OUT,
+ k->upload_fromhere, bytes_written);
s->nsend -= bytes_written;
k->upload_fromhere += bytes_written;
diff --git a/Utilities/cmcurl/lib/http_proxy.h b/Utilities/cmcurl/lib/http_proxy.h
index 67543b589b..1e650ee571 100644
--- a/Utilities/cmcurl/lib/http_proxy.h
+++ b/Utilities/cmcurl/lib/http_proxy.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/idn_win32.c b/Utilities/cmcurl/lib/idn_win32.c
index 0914e1f25a..2433d927ee 100644
--- a/Utilities/cmcurl/lib/idn_win32.c
+++ b/Utilities/cmcurl/lib/idn_win32.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -65,10 +67,10 @@ WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
#define IDN_MAX_LENGTH 255
-bool curl_win32_idn_to_ascii(const char *in, char **out);
-bool curl_win32_ascii_to_idn(const char *in, char **out);
+bool Curl_win32_idn_to_ascii(const char *in, char **out);
+bool Curl_win32_ascii_to_idn(const char *in, char **out);
-bool curl_win32_idn_to_ascii(const char *in, char **out)
+bool Curl_win32_idn_to_ascii(const char *in, char **out)
{
bool success = FALSE;
@@ -91,7 +93,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out)
return success;
}
-bool curl_win32_ascii_to_idn(const char *in, char **out)
+bool Curl_win32_ascii_to_idn(const char *in, char **out)
{
bool success = FALSE;
diff --git a/Utilities/cmcurl/lib/if2ip.c b/Utilities/cmcurl/lib/if2ip.c
index 1d34531932..c29194878f 100644
--- a/Utilities/cmcurl/lib/if2ip.c
+++ b/Utilities/cmcurl/lib/if2ip.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/if2ip.h b/Utilities/cmcurl/lib/if2ip.h
index a360d4a0e4..5d15459e98 100644
--- a/Utilities/cmcurl/lib/if2ip.h
+++ b/Utilities/cmcurl/lib/if2ip.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/imap.c b/Utilities/cmcurl/lib/imap.c
index 817513becf..ffa08bf7a4 100644
--- a/Utilities/cmcurl/lib/imap.c
+++ b/Utilities/cmcurl/lib/imap.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC2195 CRAM-MD5 authentication
* RFC2595 Using TLS with IMAP, POP3 and ACAP
* RFC2831 DIGEST-MD5 authentication
@@ -81,6 +83,7 @@
#include "bufref.h"
#include "curl_sasl.h"
#include "warnless.h"
+#include "curl_ctype.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -1883,22 +1886,17 @@ static char *imap_atom(const char *str, bool escape_only)
*/
static bool imap_is_bchar(char ch)
{
+ /* Performing the alnum check with this macro is faster because of ASCII
+ arithmetic */
+ if(ISALNUM(ch))
+ return true;
+
switch(ch) {
/* bchar */
case ':': case '@': case '/':
/* bchar -> achar */
case '&': case '=':
- /* bchar -> achar -> uchar -> unreserved */
- case '0': case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': case '8': case '9':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
- case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
- case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
- case 'V': case 'W': case 'X': case 'Y': case 'Z':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
- case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
- case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
- case 'v': case 'w': case 'x': case 'y': case 'z':
+ /* bchar -> achar -> uchar -> unreserved (without alphanumeric) */
case '-': case '.': case '_': case '~':
/* bchar -> achar -> uchar -> sub-delims-sh */
case '!': case '$': case '\'': case '(': case ')': case '*':
diff --git a/Utilities/cmcurl/lib/imap.h b/Utilities/cmcurl/lib/imap.h
index ef6515d8c2..43cc1e98fc 100644
--- a/Utilities/cmcurl/lib/imap.h
+++ b/Utilities/cmcurl/lib/imap.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "pingpong.h"
diff --git a/Utilities/cmcurl/lib/inet_ntop.c b/Utilities/cmcurl/lib/inet_ntop.c
index b5f9b808af..024f8da36d 100644
--- a/Utilities/cmcurl/lib/inet_ntop.c
+++ b/Utilities/cmcurl/lib/inet_ntop.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1996-2021 Internet Software Consortium.
+ * Copyright (C) 1996-2022 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
@@ -13,6 +13,8 @@
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * SPDX-License-Identifier: ISC
*/
/*
* Original code by Paul Vixie. "curlified" by Gisle Vanem.
diff --git a/Utilities/cmcurl/lib/inet_ntop.h b/Utilities/cmcurl/lib/inet_ntop.h
index 067632aaee..18fbd8ba3a 100644
--- a/Utilities/cmcurl/lib/inet_ntop.h
+++ b/Utilities/cmcurl/lib/inet_ntop.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/inet_pton.c b/Utilities/cmcurl/lib/inet_pton.c
index ada57af289..47fb77834d 100644
--- a/Utilities/cmcurl/lib/inet_pton.c
+++ b/Utilities/cmcurl/lib/inet_pton.c
@@ -1,6 +1,6 @@
/* This is from the BIND 4.9.4 release, modified to compile by itself */
-/* Copyright (c) 1996 - 2021 by Internet Software Consortium.
+/* Copyright (c) 2003 - 2022 by 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
@@ -14,6 +14,8 @@
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
+ *
+ * SPDX-License-Identifier: ISC
*/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/inet_pton.h b/Utilities/cmcurl/lib/inet_pton.h
index ec1237309f..92ae93ea1f 100644
--- a/Utilities/cmcurl/lib/inet_pton.h
+++ b/Utilities/cmcurl/lib/inet_pton.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/krb5.c b/Utilities/cmcurl/lib/krb5.c
index dee94c92ee..1c993c10d8 100644
--- a/Utilities/cmcurl/lib/krb5.c
+++ b/Utilities/cmcurl/lib/krb5.c
@@ -5,6 +5,8 @@
* Copyright (c) 2004 - 2022 Daniel Stenberg
* All rights reserved.
*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -140,11 +142,8 @@ krb5_decode(void *app_data, void *buf, int len,
enc.value = buf;
enc.length = len;
maj = gss_unwrap(&min, *context, &enc, &dec, NULL, NULL);
- if(maj != GSS_S_COMPLETE) {
- if(len >= 4)
- strcpy(buf, "599 ");
+ if(maj != GSS_S_COMPLETE)
return -1;
- }
memcpy(buf, dec.value, dec.length);
len = curlx_uztosi(dec.length);
@@ -506,6 +505,7 @@ static CURLcode read_data(struct connectdata *conn,
{
int len;
CURLcode result;
+ int nread;
result = socket_read(fd, &len, sizeof(len));
if(result)
@@ -514,7 +514,10 @@ static CURLcode read_data(struct connectdata *conn,
if(len) {
/* only realloc if there was a length */
len = ntohl(len);
- buf->data = Curl_saferealloc(buf->data, len);
+ if(len > CURL_MAX_INPUT_LENGTH)
+ len = 0;
+ else
+ buf->data = Curl_saferealloc(buf->data, len);
}
if(!len || !buf->data)
return CURLE_OUT_OF_MEMORY;
@@ -522,8 +525,11 @@ static CURLcode read_data(struct connectdata *conn,
result = socket_read(fd, buf->data, len);
if(result)
return result;
- buf->size = conn->mech->decode(conn->app_data, buf->data, len,
- conn->data_prot, conn);
+ nread = conn->mech->decode(conn->app_data, buf->data, len,
+ conn->data_prot, conn);
+ if(nread < 0)
+ return CURLE_RECV_ERROR;
+ buf->size = (size_t)nread;
buf->index = 0;
return CURLE_OK;
}
diff --git a/Utilities/cmcurl/lib/ldap.c b/Utilities/cmcurl/lib/ldap.c
index 03ea14e1f1..b073349042 100644
--- a/Utilities/cmcurl/lib/ldap.c
+++ b/Utilities/cmcurl/lib/ldap.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -35,6 +37,18 @@
* OpenLDAP library versions, USE_OPENLDAP shall not be defined.
*/
+/* Wincrypt must be included before anything that could include OpenSSL. */
+#if defined(USE_WIN32_CRYPTO)
+#include <wincrypt.h>
+/* Undefine wincrypt conflicting symbols for BoringSSL. */
+#undef X509_NAME
+#undef X509_EXTENSIONS
+#undef PKCS7_ISSUER_AND_SERIAL
+#undef PKCS7_SIGNER_INFO
+#undef OCSP_REQUEST
+#undef OCSP_RESPONSE
+#endif
+
#ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */
# include <winldap.h>
# ifndef LDAP_VENDOR_NAME
@@ -342,7 +356,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
#ifdef HAVE_LDAP_SSL
#ifdef USE_WIN32_LDAP
/* Win32 LDAP SDK doesn't support insecure mode without CA! */
- server = ldap_sslinit(host, (int)conn->port, 1);
+ server = ldap_sslinit(host, conn->port, 1);
ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
#else
int ldap_option;
@@ -388,9 +402,9 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
result = CURLE_SSL_CERTPROBLEM;
goto quit;
}
- server = ldapssl_init(host, (int)conn->port, 1);
+ server = ldapssl_init(host, conn->port, 1);
if(!server) {
- failf(data, "LDAP local: Cannot connect to %s:%ld",
+ failf(data, "LDAP local: Cannot connect to %s:%u",
conn->host.dispname, conn->port);
result = CURLE_COULDNT_CONNECT;
goto quit;
@@ -429,9 +443,9 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
result = CURLE_SSL_CERTPROBLEM;
goto quit;
}
- server = ldap_init(host, (int)conn->port);
+ server = ldap_init(host, conn->port);
if(!server) {
- failf(data, "LDAP local: Cannot connect to %s:%ld",
+ failf(data, "LDAP local: Cannot connect to %s:%u",
conn->host.dispname, conn->port);
result = CURLE_COULDNT_CONNECT;
goto quit;
@@ -470,9 +484,9 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
goto quit;
}
else {
- server = ldap_init(host, (int)conn->port);
+ server = ldap_init(host, conn->port);
if(!server) {
- failf(data, "LDAP local: Cannot connect to %s:%ld",
+ failf(data, "LDAP local: Cannot connect to %s:%u",
conn->host.dispname, conn->port);
result = CURLE_COULDNT_CONNECT;
goto quit;
diff --git a/Utilities/cmcurl/lib/libcurl.rc b/Utilities/cmcurl/lib/libcurl.rc
index fde6c8cae1..23134a7102 100644
--- a/Utilities/cmcurl/lib/libcurl.rc
+++ b/Utilities/cmcurl/lib/libcurl.rc
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <winver.h>
#include "../include/curl/curlver.h"
diff --git a/Utilities/cmcurl/lib/llist.c b/Utilities/cmcurl/lib/llist.c
index e78da7da82..fa2d366cb4 100644
--- a/Utilities/cmcurl/lib/llist.c
+++ b/Utilities/cmcurl/lib/llist.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/llist.h b/Utilities/cmcurl/lib/llist.h
index ceae2dd1b7..2fcb91ca50 100644
--- a/Utilities/cmcurl/lib/llist.h
+++ b/Utilities/cmcurl/lib/llist.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/md4.c b/Utilities/cmcurl/lib/md4.c
index 117cce4fd9..e976fe7bdc 100644
--- a/Utilities/cmcurl/lib/md4.c
+++ b/Utilities/cmcurl/lib/md4.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -30,7 +32,8 @@
#ifdef USE_OPENSSL
#include <openssl/opensslconf.h>
-#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
+#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) && \
+ !defined(USE_AMISSL)
/* OpenSSL 3.0.0 marks the MD4 functions as deprecated */
#define OPENSSL_NO_MD4
#endif
@@ -39,7 +42,7 @@
#ifdef USE_WOLFSSL
#include <wolfssl/options.h>
#ifdef NO_MD4
-#define OPENSSL_NO_MD4
+#define WOLFSSL_NO_MD4
#endif
#endif
@@ -82,9 +85,11 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
md4_digest(ctx, MD4_DIGEST_SIZE, result);
}
-#elif (defined(USE_OPENSSL) || defined(USE_WOLFSSL)) && \
- !defined(OPENSSL_NO_MD4)
/* When OpenSSL or wolfSSL is available, we use their MD4 functions. */
+#elif defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4)
+#include <wolfssl/openssl/md4.h>
+
+#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
#include <openssl/md4.h>
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
diff --git a/Utilities/cmcurl/lib/md5.c b/Utilities/cmcurl/lib/md5.c
index d2ca240fcd..5be639929d 100644
--- a/Utilities/cmcurl/lib/md5.c
+++ b/Utilities/cmcurl/lib/md5.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -39,7 +41,7 @@
#endif
#endif /* USE_MBEDTLS */
-#if defined(USE_OPENSSL) && !defined(USE_AMISSL)
+#ifdef USE_OPENSSL
#include <openssl/opensslconf.h>
#if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_DEPRECATED_3_0)
#define USE_OPENSSL_MD5
diff --git a/Utilities/cmcurl/lib/memdebug.c b/Utilities/cmcurl/lib/memdebug.c
index 050c5d4b2f..15fb491559 100644
--- a/Utilities/cmcurl/lib/memdebug.c
+++ b/Utilities/cmcurl/lib/memdebug.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -127,7 +129,8 @@ static bool countcheck(const char *func, int line, const char *source)
return FALSE; /* allow this */
}
-void *curl_dbg_malloc(size_t wantedsize, int line, const char *source)
+ALLOC_FUNC void *curl_dbg_malloc(size_t wantedsize,
+ int line, const char *source)
{
struct memdebug *mem;
size_t size;
@@ -153,8 +156,8 @@ void *curl_dbg_malloc(size_t wantedsize, int line, const char *source)
return (mem ? mem->mem : NULL);
}
-void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size,
- int line, const char *source)
+ALLOC_FUNC void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size,
+ int line, const char *source)
{
struct memdebug *mem;
size_t size, user_size;
@@ -181,7 +184,8 @@ void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size,
return (mem ? mem->mem : NULL);
}
-char *curl_dbg_strdup(const char *str, int line, const char *source)
+ALLOC_FUNC char *curl_dbg_strdup(const char *str,
+ int line, const char *source)
{
char *mem;
size_t len;
@@ -205,7 +209,8 @@ char *curl_dbg_strdup(const char *str, int line, const char *source)
}
#if defined(WIN32) && defined(UNICODE)
-wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source)
+ALLOC_FUNC wchar_t *curl_dbg_wcsdup(const wchar_t *str,
+ int line, const char *source)
{
wchar_t *mem;
size_t wsiz, bsiz;
@@ -408,8 +413,8 @@ int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source)
return res;
}
-FILE *curl_dbg_fopen(const char *file, const char *mode,
- int line, const char *source)
+ALLOC_FUNC FILE *curl_dbg_fopen(const char *file, const char *mode,
+ int line, const char *source)
{
FILE *res = fopen(file, mode);
@@ -420,8 +425,8 @@ FILE *curl_dbg_fopen(const char *file, const char *mode,
return res;
}
-FILE *curl_dbg_fdopen(int filedes, const char *mode,
- int line, const char *source)
+ALLOC_FUNC FILE *curl_dbg_fdopen(int filedes, const char *mode,
+ int line, const char *source)
{
FILE *res = fdopen(filedes, mode);
if(source)
diff --git a/Utilities/cmcurl/lib/memdebug.h b/Utilities/cmcurl/lib/memdebug.h
index 8e88cea580..7fc90e83a0 100644
--- a/Utilities/cmcurl/lib/memdebug.h
+++ b/Utilities/cmcurl/lib/memdebug.h
@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -21,6 +21,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -28,21 +30,44 @@
* as well as the library. Do not mix with library internals!
*/
+#include <curl/curl.h>
+#include "functypes.h"
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+# define ALLOC_FUNC __attribute__((malloc))
+# define ALLOC_SIZE(s) __attribute__((alloc_size(s)))
+# define ALLOC_SIZE2(n, s) __attribute__((alloc_size(n, s)))
+#elif defined(_MSC_VER)
+# define ALLOC_FUNC __declspec(restrict)
+# define ALLOC_SIZE(s)
+# define ALLOC_SIZE2(n, s)
+#else
+# define ALLOC_FUNC
+# define ALLOC_SIZE(s)
+# define ALLOC_SIZE2(n, s)
+#endif
+
#define CURL_MT_LOGFNAME_BUFSIZE 512
extern FILE *curl_dbg_logfile;
/* memory functions */
-CURL_EXTERN void *curl_dbg_malloc(size_t size, int line, const char *source);
-CURL_EXTERN void *curl_dbg_calloc(size_t elements, size_t size, int line,
- const char *source);
-CURL_EXTERN void *curl_dbg_realloc(void *ptr, size_t size, int line,
- const char *source);
+CURL_EXTERN ALLOC_FUNC ALLOC_SIZE(1) void *curl_dbg_malloc(size_t size,
+ int line,
+ const char *source);
+CURL_EXTERN ALLOC_FUNC ALLOC_SIZE2(1, 2) void *curl_dbg_calloc(size_t elements,
+ size_t size, int line, const char *source);
+CURL_EXTERN ALLOC_SIZE(2) void *curl_dbg_realloc(void *ptr,
+ size_t size,
+ int line,
+ const char *source);
CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source);
-CURL_EXTERN char *curl_dbg_strdup(const char *str, int line, const char *src);
+CURL_EXTERN ALLOC_FUNC char *curl_dbg_strdup(const char *str, int line,
+ const char *src);
#if defined(WIN32) && defined(UNICODE)
-CURL_EXTERN wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line,
- const char *source);
+CURL_EXTERN ALLOC_FUNC wchar_t *curl_dbg_wcsdup(const wchar_t *str,
+ int line,
+ const char *source);
#endif
CURL_EXTERN void curl_dbg_memdebug(const char *logname);
@@ -77,10 +102,10 @@ CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd,
const char *source);
/* FILE functions */
-CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line,
- const char *source);
-CURL_EXTERN FILE *curl_dbg_fdopen(int filedes, const char *mode,
+CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_fopen(const char *file, const char *mode,
int line, const char *source);
+CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_fdopen(int filedes, const char *mode,
+ int line, const char *source);
CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source);
diff --git a/Utilities/cmcurl/lib/mime.c b/Utilities/cmcurl/lib/mime.c
index d6985d39c1..042141fc80 100644
--- a/Utilities/cmcurl/lib/mime.c
+++ b/Utilities/cmcurl/lib/mime.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -29,8 +31,9 @@
#include "urldata.h"
#include "sendf.h"
-#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
- !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
+#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \
+ !defined(CURL_DISABLE_SMTP) || \
+ !defined(CURL_DISABLE_IMAP))
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
#include <libgen.h>
@@ -1922,8 +1925,8 @@ void Curl_mime_unpause(curl_mimepart *part)
}
-#else /* !CURL_DISABLE_HTTP && !CURL_DISABLE_MIME ||
- !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
+#else /* !CURL_DISABLE_MIME && (!CURL_DISABLE_HTTP ||
+ !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP) */
/* Mime not compiled in: define stubs for externally-referenced functions. */
curl_mime *curl_mime_init(CURL *easy)
diff --git a/Utilities/cmcurl/lib/mime.h b/Utilities/cmcurl/lib/mime.h
index f2fc434c58..bafde29f40 100644
--- a/Utilities/cmcurl/lib/mime.h
+++ b/Utilities/cmcurl/lib/mime.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -132,8 +134,9 @@ struct curl_mimepart {
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
-#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
- !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
+#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \
+ !defined(CURL_DISABLE_SMTP) || \
+ !defined(CURL_DISABLE_IMAP))
/* Prototypes. */
void Curl_mime_initpart(struct curl_mimepart *part, struct Curl_easy *easy);
diff --git a/Utilities/cmcurl/lib/mprintf.c b/Utilities/cmcurl/lib/mprintf.c
index 13812010b3..8a7c17a7ff 100644
--- a/Utilities/cmcurl/lib/mprintf.c
+++ b/Utilities/cmcurl/lib/mprintf.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
*
* Purpose:
* A merge of Bjorn Reese's format() function and Daniel's dsprintf()
@@ -316,6 +318,11 @@ static int dprintf_Pass1(const char *format, struct va_stack *vto,
flags |= FLAGS_PREC;
precision = strtol(fmt, &fmt, 10);
}
+ if((flags & (FLAGS_PREC | FLAGS_PRECPARAM)) ==
+ (FLAGS_PREC | FLAGS_PRECPARAM))
+ /* it is not permitted to use both kinds of precision for the same
+ argument */
+ return 1;
break;
case 'h':
flags |= FLAGS_SHORT;
@@ -592,7 +599,7 @@ static int dprintf_formatf(
/* Do the actual %-code parsing */
if(dprintf_Pass1(format, vto, endpos, ap_save))
- return -1;
+ return 0;
end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
created for us */
@@ -954,11 +961,22 @@ static int dprintf_formatf(
else
*fptr++ = 'f';
- *fptr = 0; /* and a final zero termination */
+ *fptr = 0; /* and a final null-termination */
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-nonliteral"
+#endif
/* NOTE NOTE NOTE!! Not all sprintf implementations return number of
output characters */
+#ifdef HAVE_SNPRINTF
+ (snprintf)(work, sizeof(work), formatbuf, p->data.dnum);
+#else
(sprintf)(work, formatbuf, p->data.dnum);
+#endif
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
DEBUGASSERT(strlen(work) <= sizeof(work));
for(fptr = work; *fptr; fptr++)
OUTCHAR(*fptr);
@@ -1016,11 +1034,12 @@ int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
info.max = maxlength;
retcode = dprintf_formatf(&info, addbyter, format, ap_save);
- if((retcode != -1) && info.max) {
+ if(info.max) {
/* we terminate this with a zero byte */
if(info.max == info.length) {
/* we're at maximum, scrap the last letter */
info.buffer[-1] = 0;
+ DEBUGASSERT(retcode);
retcode--; /* don't count the nul byte */
}
else
@@ -1058,13 +1077,12 @@ extern int Curl_dyn_vprintf(struct dynbuf *dyn,
/* appends the formatted string, returns 0 on success, 1 on error */
int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save)
{
- int retcode;
struct asprintf info;
info.b = dyn;
info.fail = 0;
- retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
- if((-1 == retcode) || info.fail) {
+ (void)dprintf_formatf(&info, alloc_addbyter, format, ap_save);
+ if(info.fail) {
Curl_dyn_free(info.b);
return 1;
}
@@ -1073,15 +1091,14 @@ int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save)
char *curl_mvaprintf(const char *format, va_list ap_save)
{
- int retcode;
struct asprintf info;
struct dynbuf dyn;
info.b = &dyn;
Curl_dyn_init(info.b, DYN_APRINTF);
info.fail = 0;
- retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
- if((-1 == retcode) || info.fail) {
+ (void)dprintf_formatf(&info, alloc_addbyter, format, ap_save);
+ if(info.fail) {
Curl_dyn_free(info.b);
return NULL;
}
diff --git a/Utilities/cmcurl/lib/mqtt.c b/Utilities/cmcurl/lib/mqtt.c
index 9bcbaa1950..4f3d14386f 100644
--- a/Utilities/cmcurl/lib/mqtt.c
+++ b/Utilities/cmcurl/lib/mqtt.c
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -184,7 +186,7 @@ static int add_passwd(const char *passwd, const size_t plen,
return 0;
}
-/* add user to the CONN packet */
+/* add user to the CONNECT packet */
static int add_user(const char *username, const size_t ulen,
unsigned char *pkt, const size_t start, int remain_pos)
{
@@ -202,7 +204,7 @@ static int add_user(const char *username, const size_t ulen,
return 0;
}
-/* add client ID to the CONN packet */
+/* add client ID to the CONNECT packet */
static int add_client_id(const char *client_id, const size_t client_id_len,
char *pkt, const size_t start)
{
@@ -214,7 +216,7 @@ static int add_client_id(const char *client_id, const size_t client_id_len,
return 0;
}
-/* Set initial values of CONN packet */
+/* Set initial values of CONNECT packet */
static int init_connpack(char *packet, char *remain, int remain_pos)
{
/* Fixed header starts */
@@ -291,7 +293,7 @@ static CURLcode mqtt_connect(struct Curl_easy *data)
return CURLE_OUT_OF_MEMORY;
memset(packet, 0, packetlen);
- /* set initial values for CONN pack */
+ /* set initial values for the CONNECT packet */
pos = init_connpack(packet, remain, remain_pos);
result = Curl_rand_hex(data, (unsigned char *)&client_id[clen],
@@ -387,10 +389,18 @@ static CURLcode mqtt_get_topic(struct Curl_easy *data,
char **topic, size_t *topiclen)
{
char *path = data->state.up.path;
- if(strlen(path) > 1)
- return Curl_urldecode(path + 1, 0, topic, topiclen, REJECT_NADA);
- failf(data, "No MQTT topic found. Forgot to URL encode it?");
- return CURLE_URL_MALFORMAT;
+ CURLcode result = CURLE_URL_MALFORMAT;
+ if(strlen(path) > 1) {
+ result = Curl_urldecode(path + 1, 0, topic, topiclen, REJECT_NADA);
+ if(!result && (*topiclen > 0xffff)) {
+ failf(data, "Too long MQTT topic");
+ result = CURLE_URL_MALFORMAT;
+ }
+ }
+ else
+ failf(data, "No MQTT topic found. Forgot to URL encode it?");
+
+ return result;
}
static CURLcode mqtt_subscribe(struct Curl_easy *data)
@@ -688,7 +698,7 @@ static CURLcode mqtt_do(struct Curl_easy *data, bool *done)
result = mqtt_connect(data);
if(result) {
- failf(data, "Error %d sending MQTT CONN request", result);
+ failf(data, "Error %d sending MQTT CONNECT request", result);
return result;
}
mqstate(data, MQTT_FIRST, MQTT_CONNACK);
diff --git a/Utilities/cmcurl/lib/mqtt.h b/Utilities/cmcurl/lib/mqtt.h
index fb52c72326..c400d9b14e 100644
--- a/Utilities/cmcurl/lib/mqtt.h
+++ b/Utilities/cmcurl/lib/mqtt.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019 - 2020, Björn Stenberg, <bjorn@haxx.se>
+ * Copyright (C) 2019 - 2022, Björn Stenberg, <bjorn@haxx.se>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_MQTT
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
index 8e58d785a9..51acba73ac 100644
--- a/Utilities/cmcurl/lib/multi.c
+++ b/Utilities/cmcurl/lib/multi.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -43,7 +45,6 @@
#include "multihandle.h"
#include "sigpipe.h"
#include "vtls/vtls.h"
-#include "connect.h"
#include "http_proxy.h"
#include "http2.h"
#include "socketpair.h"
@@ -53,6 +54,22 @@
#include "curl_memory.h"
#include "memdebug.h"
+#ifdef __APPLE__
+
+#define wakeup_write write
+#define wakeup_read read
+#define wakeup_close close
+#define wakeup_create pipe
+
+#else /* __APPLE__ */
+
+#define wakeup_write swrite
+#define wakeup_read sread
+#define wakeup_close sclose
+#define wakeup_create(p) Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, p)
+
+#endif /* __APPLE__ */
+
/*
CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every
@@ -66,6 +83,10 @@
#define CURL_CONNECTION_HASH_SIZE 97
#endif
+#ifndef CURL_DNS_HASH_SIZE
+#define CURL_DNS_HASH_SIZE 71
+#endif
+
#define CURL_MULTI_HANDLE 0x000bab1e
#define GOOD_MULTI_HANDLE(x) \
@@ -370,7 +391,8 @@ static CURLMcode multi_addmsg(struct Curl_multi *multi,
}
struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
- int chashsize) /* connection hash */
+ int chashsize, /* connection hash */
+ int dnssize) /* dns hash */
{
struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
@@ -379,7 +401,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
multi->magic = CURL_MULTI_HANDLE;
- Curl_init_dnscache(&multi->hostcache);
+ Curl_init_dnscache(&multi->hostcache, dnssize);
sh_init(&multi->sockhash, hashsize);
@@ -394,7 +416,6 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
/* -1 means it not set by user, use the default value */
multi->maxconnects = -1;
multi->max_concurrent_streams = 100;
- multi->ipv6_works = Curl_ipv6works(NULL);
#ifdef USE_WINSOCK
multi->wsa_event = WSACreateEvent();
@@ -402,14 +423,14 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
goto error;
#else
#ifdef ENABLE_WAKEUP
- if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) {
+ if(wakeup_create(multi->wakeup_pair) < 0) {
multi->wakeup_pair[0] = CURL_SOCKET_BAD;
multi->wakeup_pair[1] = CURL_SOCKET_BAD;
}
else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 ||
curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) {
- sclose(multi->wakeup_pair[0]);
- sclose(multi->wakeup_pair[1]);
+ wakeup_close(multi->wakeup_pair[0]);
+ wakeup_close(multi->wakeup_pair[1]);
multi->wakeup_pair[0] = CURL_SOCKET_BAD;
multi->wakeup_pair[1] = CURL_SOCKET_BAD;
}
@@ -433,7 +454,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
struct Curl_multi *curl_multi_init(void)
{
return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
- CURL_CONNECTION_HASH_SIZE);
+ CURL_CONNECTION_HASH_SIZE,
+ CURL_DNS_HASH_SIZE);
}
CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
@@ -627,7 +649,7 @@ static CURLcode multi_done(struct Curl_easy *data,
if(CURLE_ABORTED_BY_CALLBACK != result) {
/* avoid this if we already aborted by callback to avoid this calling
another callback */
- CURLcode rc = Curl_pgrsDone(data);
+ int rc = Curl_pgrsDone(data);
if(!result && rc)
result = CURLE_ABORTED_BY_CALLBACK;
}
@@ -729,7 +751,7 @@ static int close_connect_only(struct Curl_easy *data,
if(data->state.lastconnect_id != conn->connection_id)
return 0;
- if(!conn->bits.connect_only)
+ if(!conn->connect_only)
return 1;
connclose(conn, "Removing connect-only easy handle");
@@ -826,6 +848,24 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
/* Remove the association between the connection and the handle */
Curl_detach_connection(data);
+ if(data->set.connect_only && !data->multi_easy) {
+ /* This removes a handle that was part the multi interface that used
+ CONNECT_ONLY, that connection is now left alive but since this handle
+ has bits.close set nothing can use that transfer anymore and it is
+ forbidden from reuse. And this easy handle cannot find the connection
+ anymore once removed from the multi handle
+
+ Better close the connection here, at once.
+ */
+ struct connectdata *c;
+ curl_socket_t s;
+ s = Curl_getconnectinfo(data, &c);
+ if((s != CURL_SOCKET_BAD) && c) {
+ Curl_conncache_remove_conn(data, c, TRUE);
+ Curl_disconnect(data, c, TRUE);
+ }
+ }
+
if(data->state.lastconnect_id != -1) {
/* Mark any connect-only connection for closure */
Curl_conncache_foreach(data, data->state.conn_cache,
@@ -1307,16 +1347,19 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
pollrc = Curl_poll(ufds, nfds, 0); /* just pre-check with WinSock */
else
pollrc = 0;
- if(pollrc <= 0) /* now wait... if not ready during the pre-check above */
- WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
#else
pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */
#endif
+ if(pollrc < 0)
+ return CURLM_UNRECOVERABLE_POLL;
if(pollrc > 0) {
retcode = pollrc;
#ifdef USE_WINSOCK
}
+ else { /* now wait... if not ready during the pre-check (pollrc == 0) */
+ WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
+ }
/* With WinSock, we have to run the following section unconditionally
to call WSAEventSelect(fd, event, 0) on all the sockets */
{
@@ -1328,20 +1371,23 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
unsigned r = ufds[curlfds + i].revents;
unsigned short mask = 0;
#ifdef USE_WINSOCK
+ curl_socket_t s = extra_fds[i].fd;
wsa_events.lNetworkEvents = 0;
- if(WSAEnumNetworkEvents(extra_fds[i].fd, NULL, &wsa_events) == 0) {
+ if(WSAEnumNetworkEvents(s, NULL, &wsa_events) == 0) {
if(wsa_events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE))
mask |= CURL_WAIT_POLLIN;
if(wsa_events.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE))
mask |= CURL_WAIT_POLLOUT;
if(wsa_events.lNetworkEvents & FD_OOB)
mask |= CURL_WAIT_POLLPRI;
- if(ret && pollrc <= 0 && wsa_events.lNetworkEvents)
+ if(ret && !pollrc && wsa_events.lNetworkEvents)
retcode++;
}
- WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0);
- if(pollrc <= 0)
+ WSAEventSelect(s, multi->wsa_event, 0);
+ if(!pollrc) {
+ extra_fds[i].revents = mask;
continue;
+ }
#endif
if(r & POLLIN)
mask |= CURL_WAIT_POLLIN;
@@ -1364,7 +1410,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) {
wsa_events.lNetworkEvents = 0;
if(WSAEnumNetworkEvents(sockbunch[i], NULL, &wsa_events) == 0) {
- if(ret && pollrc <= 0 && wsa_events.lNetworkEvents)
+ if(ret && !pollrc && wsa_events.lNetworkEvents)
retcode++;
}
WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
@@ -1391,7 +1437,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
data from it until it receives an error (except EINTR).
In normal cases it will get EAGAIN or EWOULDBLOCK
when there is no more data, breaking the loop. */
- nread = sread(multi->wakeup_pair[0], buf, sizeof(buf));
+ nread = wakeup_read(multi->wakeup_pair[0], buf, sizeof(buf));
if(nread <= 0) {
if(nread < 0 && EINTR == SOCKERRNO)
continue;
@@ -1484,7 +1530,7 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
that will call curl_multi_wait(). If swrite() returns that it
would block, it's considered successful because it means that
previous calls to this function will wake up the poll(). */
- if(swrite(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
+ if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
int err = SOCKERRNO;
int return_success;
#ifdef USE_WINSOCK
@@ -2096,7 +2142,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
}
- if(data->set.connect_only) {
+ if(data->set.connect_only == 1) {
/* keep connection open for application to use the socket */
connkeep(data->conn, "CONNECT_ONLY");
multistate(data, MSTATE_DONE);
@@ -2720,8 +2766,8 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
WSACloseEvent(multi->wsa_event);
#else
#ifdef ENABLE_WAKEUP
- sclose(multi->wakeup_pair[0]);
- sclose(multi->wakeup_pair[1]);
+ wakeup_close(multi->wakeup_pair[0]);
+ wakeup_close(multi->wakeup_pair[1]);
#endif
#endif
free(multi);
diff --git a/Utilities/cmcurl/lib/multihandle.h b/Utilities/cmcurl/lib/multihandle.h
index db7f130efd..a997784ea3 100644
--- a/Utilities/cmcurl/lib/multihandle.h
+++ b/Utilities/cmcurl/lib/multihandle.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "llist.h"
@@ -148,11 +150,13 @@ struct Curl_multi {
0 is used for read, 1 is used for write */
#endif
#endif
- /* multiplexing wanted */
- bool multiplexing;
- bool recheckstate; /* see Curl_multi_connchanged */
+#define IPV6_UNKNOWN 0
+#define IPV6_DEAD 1
+#define IPV6_WORKS 2
+ unsigned char ipv6_up; /* IPV6_* defined */
+ bool multiplexing; /* multiplexing wanted */
+ bool recheckstate; /* see Curl_multi_connchanged */
bool in_callback; /* true while executing a callback */
- bool ipv6_works;
#ifdef USE_OPENSSL
bool ssl_seeded;
#endif
diff --git a/Utilities/cmcurl/lib/multiif.h b/Utilities/cmcurl/lib/multiif.h
index 5a8c358bc4..0cb9d4f7f2 100644
--- a/Utilities/cmcurl/lib/multiif.h
+++ b/Utilities/cmcurl/lib/multiif.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -40,8 +42,9 @@ bool Curl_is_in_callback(struct Curl_easy *easy);
CURLcode Curl_preconnect(struct Curl_easy *data);
/* Internal version of curl_multi_init() accepts size parameters for the
- socket and connection hashes */
-struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize);
+ socket, connection and dns hashes */
+struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize,
+ int dnssize);
/* the write bits start at bit 16 for the *getsock() bitmap */
#define GETSOCK_WRITEBITSTART 16
diff --git a/Utilities/cmcurl/lib/netrc.c b/Utilities/cmcurl/lib/netrc.c
index 0a4ae2cdca..4461b8492f 100644
--- a/Utilities/cmcurl/lib/netrc.c
+++ b/Utilities/cmcurl/lib/netrc.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -31,6 +33,7 @@
#include "netrc.h"
#include "strtok.h"
#include "strcase.h"
+#include "curl_get_line.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -56,8 +59,6 @@ enum host_lookup_state {
static int parsenetrc(const char *host,
char **loginp,
char **passwordp,
- bool *login_changed,
- bool *password_changed,
char *netrcfile)
{
FILE *file;
@@ -71,31 +72,87 @@ static int parsenetrc(const char *host,
char state_login = 0; /* Found a login keyword */
char state_password = 0; /* Found a password keyword */
- int state_our_login = FALSE; /* With specific_login, found *our* login
- name */
+ int state_our_login = TRUE; /* With specific_login, found *our* login
+ name (or login-less line) */
DEBUGASSERT(netrcfile);
file = fopen(netrcfile, FOPEN_READTEXT);
if(file) {
- char *tok;
- char *tok_buf;
bool done = FALSE;
char netrcbuffer[4096];
int netrcbuffsize = (int)sizeof(netrcbuffer);
- while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
+ while(!done && Curl_get_line(netrcbuffer, netrcbuffsize, file)) {
+ char *tok;
+ char *tok_end;
+ bool quoted;
if(state == MACDEF) {
if((netrcbuffer[0] == '\n') || (netrcbuffer[0] == '\r'))
state = NOTHING;
else
continue;
}
- tok = strtok_r(netrcbuffer, " \t\n", &tok_buf);
- if(tok && *tok == '#')
- /* treat an initial hash as a comment line */
- continue;
+ tok = netrcbuffer;
while(tok) {
+ while(ISBLANK(*tok))
+ tok++;
+ /* tok is first non-space letter */
+ if(!*tok || (*tok == '#'))
+ /* end of line or the rest is a comment */
+ break;
+
+ /* leading double-quote means quoted string */
+ quoted = (*tok == '\"');
+
+ tok_end = tok;
+ if(!quoted) {
+ while(!ISSPACE(*tok_end))
+ tok_end++;
+ *tok_end = 0;
+ }
+ else {
+ bool escape = FALSE;
+ bool endquote = FALSE;
+ char *store = tok;
+ tok_end++; /* pass the leading quote */
+ while(*tok_end) {
+ char s = *tok_end;
+ if(escape) {
+ escape = FALSE;
+ switch(s) {
+ case 'n':
+ s = '\n';
+ break;
+ case 'r':
+ s = '\r';
+ break;
+ case 't':
+ s = '\t';
+ break;
+ }
+ }
+ else if(s == '\\') {
+ escape = TRUE;
+ tok_end++;
+ continue;
+ }
+ else if(s == '\"') {
+ tok_end++; /* pass the ending quote */
+ endquote = TRUE;
+ break;
+ }
+ *store++ = s;
+ tok_end++;
+ }
+ *store = 0;
+ if(escape || !endquote) {
+ /* bad syntax, get out */
+ retcode = NETRC_FAILED;
+ goto out;
+ }
+ }
+
if((login && *login) && (password && *password)) {
done = TRUE;
break;
@@ -140,9 +197,9 @@ static int parsenetrc(const char *host,
/* we are now parsing sub-keywords concerning "our" host */
if(state_login) {
if(specific_login) {
- state_our_login = strcasecompare(login, tok);
+ state_our_login = !Curl_timestrcmp(login, tok);
}
- else if(!login || strcmp(login, tok)) {
+ else if(!login || Curl_timestrcmp(login, tok)) {
if(login_alloc) {
free(login);
login_alloc = FALSE;
@@ -158,7 +215,7 @@ static int parsenetrc(const char *host,
}
else if(state_password) {
if((state_our_login || !specific_login)
- && (!password || strcmp(password, tok))) {
+ && (!password || Curl_timestrcmp(password, tok))) {
if(password_alloc) {
free(password);
password_alloc = FALSE;
@@ -183,27 +240,22 @@ static int parsenetrc(const char *host,
}
break;
} /* switch (state) */
-
- tok = strtok_r(NULL, " \t\n", &tok_buf);
- } /* while(tok) */
- } /* while fgets() */
+ tok = ++tok_end;
+ }
+ } /* while Curl_get_line() */
out:
if(!retcode) {
/* success */
- *login_changed = FALSE;
- *password_changed = FALSE;
if(login_alloc) {
if(*loginp)
free(*loginp);
*loginp = login;
- *login_changed = TRUE;
}
if(password_alloc) {
if(*passwordp)
free(*passwordp);
*passwordp = password;
- *password_changed = TRUE;
}
}
else {
@@ -224,17 +276,16 @@ static int parsenetrc(const char *host,
* *loginp and *passwordp MUST be allocated if they aren't NULL when passed
* in.
*/
-int Curl_parsenetrc(const char *host,
- char **loginp,
- char **passwordp,
- bool *login_changed,
- bool *password_changed,
+int Curl_parsenetrc(const char *host, char **loginp, char **passwordp,
char *netrcfile)
{
int retcode = 1;
char *filealloc = NULL;
if(!netrcfile) {
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+ char pwbuf[1024];
+#endif
char *home = NULL;
char *homea = curl_getenv("HOME"); /* portable environment reader */
if(homea) {
@@ -243,7 +294,6 @@ int Curl_parsenetrc(const char *host,
}
else {
struct passwd pw, *pw_res;
- char pwbuf[1024];
if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
&& pw_res) {
home = pw.pw_dir;
@@ -256,6 +306,13 @@ int Curl_parsenetrc(const char *host,
if(pw) {
home = pw->pw_dir;
}
+#elif defined(_WIN32)
+ }
+ else {
+ homea = curl_getenv("USERPROFILE");
+ if(homea) {
+ home = homea;
+ }
#endif
}
@@ -268,8 +325,7 @@ int Curl_parsenetrc(const char *host,
free(homea);
return -1;
}
- retcode = parsenetrc(host, loginp, passwordp, login_changed,
- password_changed, filealloc);
+ retcode = parsenetrc(host, loginp, passwordp, filealloc);
free(filealloc);
#ifdef WIN32
if(retcode == NETRC_FILE_MISSING) {
@@ -279,16 +335,14 @@ int Curl_parsenetrc(const char *host,
free(homea);
return -1;
}
- retcode = parsenetrc(host, loginp, passwordp, login_changed,
- password_changed, filealloc);
+ retcode = parsenetrc(host, loginp, passwordp, filealloc);
free(filealloc);
}
#endif
free(homea);
}
else
- retcode = parsenetrc(host, loginp, passwordp, login_changed,
- password_changed, netrcfile);
+ retcode = parsenetrc(host, loginp, passwordp, netrcfile);
return retcode;
}
diff --git a/Utilities/cmcurl/lib/netrc.h b/Utilities/cmcurl/lib/netrc.h
index 4938a5916a..53d0056721 100644
--- a/Utilities/cmcurl/lib/netrc.h
+++ b/Utilities/cmcurl/lib/netrc.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,18 +20,16 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#ifndef CURL_DISABLE_NETRC
/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
-int Curl_parsenetrc(const char *host,
- char **loginp,
- char **passwordp,
- bool *login_changed,
- bool *password_changed,
- char *filename);
+int Curl_parsenetrc(const char *host, char **loginp,
+ char **passwordp, char *filename);
/* Assume: (*passwordp)[0]=0, host[0] != 0.
* If (*loginp)[0] = 0, search for login and password within a machine
* section in the netrc.
diff --git a/Utilities/cmcurl/lib/nonblock.c b/Utilities/cmcurl/lib/nonblock.c
index 28f6e75881..ce73af31c1 100644
--- a/Utilities/cmcurl/lib/nonblock.c
+++ b/Utilities/cmcurl/lib/nonblock.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/nonblock.h b/Utilities/cmcurl/lib/nonblock.h
index 761dab4f6d..a42f443a49 100644
--- a/Utilities/cmcurl/lib/nonblock.h
+++ b/Utilities/cmcurl/lib/nonblock.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <curl/curl.h> /* for curl_socket_t */
diff --git a/Utilities/cmcurl/lib/noproxy.c b/Utilities/cmcurl/lib/noproxy.c
new file mode 100644
index 0000000000..81f1e09934
--- /dev/null
+++ b/Utilities/cmcurl/lib/noproxy.c
@@ -0,0 +1,222 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_PROXY
+
+#include "inet_pton.h"
+#include "strcase.h"
+#include "noproxy.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+/*
+ * Curl_cidr4_match() returns TRUE if the given IPv4 address is within the
+ * specified CIDR address range.
+ */
+UNITTEST bool Curl_cidr4_match(const char *ipv4, /* 1.2.3.4 address */
+ const char *network, /* 1.2.3.4 address */
+ unsigned int bits)
+{
+ unsigned int address = 0;
+ unsigned int check = 0;
+
+ if(bits > 32)
+ /* strange input */
+ return FALSE;
+
+ if(1 != Curl_inet_pton(AF_INET, ipv4, &address))
+ return FALSE;
+ if(1 != Curl_inet_pton(AF_INET, network, &check))
+ return FALSE;
+
+ if(bits && (bits != 32)) {
+ unsigned int mask = 0xffffffff << (32 - bits);
+ unsigned int haddr = htonl(address);
+ unsigned int hcheck = htonl(check);
+#if 0
+ fprintf(stderr, "Host %s (%x) network %s (%x) bits %u mask %x => %x\n",
+ ipv4, haddr, network, hcheck, bits, mask,
+ (haddr ^ hcheck) & mask);
+#endif
+ if((haddr ^ hcheck) & mask)
+ return FALSE;
+ return TRUE;
+ }
+ return (address == check);
+}
+
+UNITTEST bool Curl_cidr6_match(const char *ipv6,
+ const char *network,
+ unsigned int bits)
+{
+#ifdef ENABLE_IPV6
+ int bytes;
+ int rest;
+ unsigned char address[16];
+ unsigned char check[16];
+
+ if(!bits)
+ bits = 128;
+
+ bytes = bits/8;
+ rest = bits & 0x07;
+ if(1 != Curl_inet_pton(AF_INET6, ipv6, address))
+ return FALSE;
+ if(1 != Curl_inet_pton(AF_INET6, network, check))
+ return FALSE;
+ if((bytes > 16) || ((bytes == 16) && rest))
+ return FALSE;
+ if(bytes && memcmp(address, check, bytes))
+ return FALSE;
+ if(rest && !((address[bytes] ^ check[bytes]) & (0xff << (8 - rest))))
+ return FALSE;
+
+ return TRUE;
+#else
+ (void)ipv6;
+ (void)network;
+ (void)bits;
+ return FALSE;
+#endif
+}
+
+enum nametype {
+ TYPE_HOST,
+ TYPE_IPV4,
+ TYPE_IPV6
+};
+
+/****************************************************************
+* Checks if the host is in the noproxy list. returns TRUE if it matches and
+* therefore the proxy should NOT be used.
+****************************************************************/
+bool Curl_check_noproxy(const char *name, const char *no_proxy)
+{
+ /* no_proxy=domain1.dom,host.domain2.dom
+ * (a comma-separated list of hosts which should
+ * not be proxied, or an asterisk to override
+ * all proxy variables)
+ */
+ if(no_proxy && no_proxy[0]) {
+ const char *p = no_proxy;
+ size_t namelen;
+ enum nametype type = TYPE_HOST;
+ char hostip[128];
+ if(!strcmp("*", no_proxy))
+ return TRUE;
+
+ /* NO_PROXY was specified and it wasn't just an asterisk */
+
+ if(name[0] == '[') {
+ char *endptr;
+ /* IPv6 numerical address */
+ endptr = strchr(name, ']');
+ if(!endptr)
+ return FALSE;
+ name++;
+ namelen = endptr - name;
+ if(namelen >= sizeof(hostip))
+ return FALSE;
+ memcpy(hostip, name, namelen);
+ hostip[namelen] = 0;
+ name = hostip;
+ type = TYPE_IPV6;
+ }
+ else {
+ unsigned int address;
+ if(1 == Curl_inet_pton(AF_INET, name, &address))
+ type = TYPE_IPV4;
+ namelen = strlen(name);
+ }
+
+ while(*p) {
+ const char *token;
+ size_t tokenlen = 0;
+ bool match = FALSE;
+
+ /* pass blanks */
+ while(*p && ISBLANK(*p))
+ p++;
+
+ token = p;
+ /* pass over the pattern */
+ while(*p && !ISBLANK(*p) && (*p != ',')) {
+ p++;
+ tokenlen++;
+ }
+
+ if(tokenlen) {
+ switch(type) {
+ case TYPE_HOST:
+ if(*token == '.') {
+ ++token;
+ --tokenlen;
+ /* tailmatch */
+ match = (tokenlen <= namelen) &&
+ strncasecompare(token, name + (namelen - tokenlen), namelen);
+ }
+ else
+ match = (tokenlen == namelen) &&
+ strncasecompare(token, name, namelen);
+ break;
+ case TYPE_IPV4:
+ /* FALLTHROUGH */
+ case TYPE_IPV6: {
+ const char *check = token;
+ char *slash = strchr(check, '/');
+ unsigned int bits = 0;
+ char checkip[128];
+ /* if the slash is part of this token, use it */
+ if(slash && (slash < &check[tokenlen])) {
+ bits = atoi(slash + 1);
+ /* copy the check name to a temp buffer */
+ if(tokenlen >= sizeof(checkip))
+ break;
+ memcpy(checkip, check, tokenlen);
+ checkip[ slash - check ] = 0;
+ check = checkip;
+ }
+ if(type == TYPE_IPV6)
+ match = Curl_cidr6_match(name, check, bits);
+ else
+ match = Curl_cidr4_match(name, check, bits);
+ break;
+ }
+ }
+ if(match)
+ return TRUE;
+ } /* if(tokenlen) */
+ while(*p == ',')
+ p++;
+ } /* while(*p) */
+ } /* NO_PROXY was specified and it wasn't just an asterisk */
+
+ return FALSE;
+}
+
+#endif /* CURL_DISABLE_PROXY */
diff --git a/Utilities/cmcurl/lib/dotdot.h b/Utilities/cmcurl/lib/noproxy.h
index ac1ea363e1..8800a21276 100644
--- a/Utilities/cmcurl/lib/dotdot.h
+++ b/Utilities/cmcurl/lib/noproxy.h
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_DOTDOT_H
-#define HEADER_CURL_DOTDOT_H
+#ifndef HEADER_CURL_NOPROXY_H
+#define HEADER_CURL_NOPROXY_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,25 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
-char *Curl_dedotdotify(const char *input);
-#endif /* HEADER_CURL_DOTDOT_H */
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_PROXY
+
+#ifdef DEBUGBUILD
+
+UNITTEST bool Curl_cidr4_match(const char *ipv4, /* 1.2.3.4 address */
+ const char *network, /* 1.2.3.4 address */
+ unsigned int bits);
+UNITTEST bool Curl_cidr6_match(const char *ipv6,
+ const char *network,
+ unsigned int bits);
+#endif
+
+bool Curl_check_noproxy(const char *name, const char *no_proxy);
+
+#endif
+
+#endif /* HEADER_CURL_NOPROXY_H */
diff --git a/Utilities/cmcurl/lib/openldap.c b/Utilities/cmcurl/lib/openldap.c
index 4e92567706..3a93b6728d 100644
--- a/Utilities/cmcurl/lib/openldap.c
+++ b/Utilities/cmcurl/lib/openldap.c
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -1066,8 +1068,8 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
if(!binary) {
/* check for leading or trailing whitespace */
- if(ISSPACE(bvals[i].bv_val[0]) ||
- ISSPACE(bvals[i].bv_val[bvals[i].bv_len - 1]))
+ if(ISBLANK(bvals[i].bv_val[0]) ||
+ ISBLANK(bvals[i].bv_val[bvals[i].bv_len - 1]))
binval = 1;
else {
/* check for unprintable characters */
diff --git a/Utilities/cmcurl/lib/parsedate.c b/Utilities/cmcurl/lib/parsedate.c
index 3c38f2c4c2..5ed88195fb 100644
--- a/Utilities/cmcurl/lib/parsedate.c
+++ b/Utilities/cmcurl/lib/parsedate.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
A brief summary of the date string formats this parser groks:
diff --git a/Utilities/cmcurl/lib/parsedate.h b/Utilities/cmcurl/lib/parsedate.h
index a99faf9e36..4e4347754d 100644
--- a/Utilities/cmcurl/lib/parsedate.h
+++ b/Utilities/cmcurl/lib/parsedate.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
extern const char * const Curl_wkday[7];
diff --git a/Utilities/cmcurl/lib/pingpong.c b/Utilities/cmcurl/lib/pingpong.c
index e08c1d8663..d4e6be98c4 100644
--- a/Utilities/cmcurl/lib/pingpong.c
+++ b/Utilities/cmcurl/lib/pingpong.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* 'pingpong' is for generic back-and-forth support functions used by FTP,
* IMAP, POP3, SMTP and whatever more that likes them.
*
@@ -328,7 +330,7 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data,
else if(gotbytes <= 0) {
keepon = FALSE;
result = CURLE_RECV_ERROR;
- failf(data, "response reading failed");
+ failf(data, "response reading failed (errno: %d)", SOCKERRNO);
}
else {
/* we got a whole chunk of data, which can be anything from one
@@ -396,7 +398,8 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data,
}
else if(keepon) {
- if((perline == gotbytes) && (gotbytes > data->set.buffer_size/2)) {
+ if((perline == gotbytes) &&
+ (gotbytes > (ssize_t)data->set.buffer_size/2)) {
/* We got an excessive line without newlines and we need to deal
with it. We keep the first bytes of the line then we throw
away the rest. */
diff --git a/Utilities/cmcurl/lib/pingpong.h b/Utilities/cmcurl/lib/pingpong.h
index 8f56f3f865..cefae073a6 100644
--- a/Utilities/cmcurl/lib/pingpong.h
+++ b/Utilities/cmcurl/lib/pingpong.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/pop3.c b/Utilities/cmcurl/lib/pop3.c
index 2c1b06c07f..3151a3f56a 100644
--- a/Utilities/cmcurl/lib/pop3.c
+++ b/Utilities/cmcurl/lib/pop3.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC1734 POP3 Authentication
* RFC1939 POP3 protocol
* RFC2195 CRAM-MD5 authentication
diff --git a/Utilities/cmcurl/lib/pop3.h b/Utilities/cmcurl/lib/pop3.h
index 17629ee2df..bb0645f9bf 100644
--- a/Utilities/cmcurl/lib/pop3.h
+++ b/Utilities/cmcurl/lib/pop3.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2009 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "pingpong.h"
diff --git a/Utilities/cmcurl/lib/progress.c b/Utilities/cmcurl/lib/progress.c
index f5ef6bd526..4a1e1daa81 100644
--- a/Utilities/cmcurl/lib/progress.c
+++ b/Utilities/cmcurl/lib/progress.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/progress.h b/Utilities/cmcurl/lib/progress.h
index ac4ebc0980..a129315147 100644
--- a/Utilities/cmcurl/lib/progress.h
+++ b/Utilities/cmcurl/lib/progress.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "timeval.h"
diff --git a/Utilities/cmcurl/lib/psl.c b/Utilities/cmcurl/lib/psl.c
index e46091863f..60c98a4ca4 100644
--- a/Utilities/cmcurl/lib/psl.c
+++ b/Utilities/cmcurl/lib/psl.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/psl.h b/Utilities/cmcurl/lib/psl.h
index c10367471d..34f0a5cae8 100644
--- a/Utilities/cmcurl/lib/psl.h
+++ b/Utilities/cmcurl/lib/psl.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifdef USE_LIBPSL
diff --git a/Utilities/cmcurl/lib/quic.h b/Utilities/cmcurl/lib/quic.h
index f92720f5d6..b35774735e 100644
--- a/Utilities/cmcurl/lib/quic.h
+++ b/Utilities/cmcurl/lib/quic.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -54,6 +56,7 @@ void Curl_quic_done(struct Curl_easy *data, bool premature);
bool Curl_quic_data_pending(const struct Curl_easy *data);
void Curl_quic_disconnect(struct Curl_easy *data,
struct connectdata *conn, int tempindex);
+CURLcode Curl_quic_idle(struct Curl_easy *data);
#else /* ENABLE_QUIC */
#define Curl_quic_done_sending(x)
diff --git a/Utilities/cmcurl/lib/rand.c b/Utilities/cmcurl/lib/rand.c
index 8da1e8d968..2e7e7e8238 100644
--- a/Utilities/cmcurl/lib/rand.c
+++ b/Utilities/cmcurl/lib/rand.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -36,6 +38,64 @@
#include "curl_memory.h"
#include "memdebug.h"
+#ifdef WIN32
+
+#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
+# define HAVE_MINGW_ORIGINAL
+#endif
+
+#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 && \
+ !defined(HAVE_MINGW_ORIGINAL)
+# define HAVE_WIN_BCRYPTGENRANDOM
+# include <bcrypt.h>
+# ifdef _MSC_VER
+# pragma comment(lib, "bcrypt.lib")
+# endif
+# ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG
+# define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002
+# endif
+# ifndef STATUS_SUCCESS
+# define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
+# endif
+#elif defined(USE_WIN32_CRYPTO)
+# include <wincrypt.h>
+# ifdef _MSC_VER
+# pragma comment(lib, "advapi32.lib")
+# endif
+#endif
+
+CURLcode Curl_win32_random(unsigned char *entropy, size_t length)
+{
+ memset(entropy, 0, length);
+
+#if defined(HAVE_WIN_BCRYPTGENRANDOM)
+ if(BCryptGenRandom(NULL, entropy, (ULONG)length,
+ BCRYPT_USE_SYSTEM_PREFERRED_RNG) != STATUS_SUCCESS)
+ return CURLE_FAILED_INIT;
+
+ return CURLE_OK;
+#elif defined(USE_WIN32_CRYPTO)
+ {
+ HCRYPTPROV hCryptProv = 0;
+
+ if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+ return CURLE_FAILED_INIT;
+
+ if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) {
+ CryptReleaseContext(hCryptProv, 0UL);
+ return CURLE_FAILED_INIT;
+ }
+
+ CryptReleaseContext(hCryptProv, 0UL);
+ }
+ return CURLE_OK;
+#else
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
+#endif
+
static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
{
unsigned int r;
@@ -71,7 +131,15 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
/* ---- non-cryptographic version following ---- */
-#ifdef RANDOM_FILE
+#ifdef WIN32
+ if(!seeded) {
+ result = Curl_win32_random((unsigned char *)rnd, sizeof(*rnd));
+ if(result != CURLE_NOT_BUILT_IN)
+ return result;
+ }
+#endif
+
+#if defined(RANDOM_FILE) && !defined(WIN32)
if(!seeded) {
/* if there's a random file to read a seed from, use it */
int fd = open(RANDOM_FILE, O_RDONLY);
@@ -106,7 +174,8 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
* 'rndptr' points to.
*
* If libcurl is built without TLS support or with a TLS backend that lacks a
- * proper random API (Gskit or mbedTLS), this function will use "weak" random.
+ * proper random API (rustls, Gskit or mbedTLS), this function will use "weak"
+ * random.
*
* When built *with* TLS support and a backend that offers strong random, it
* will return error if it cannot provide strong random values.
@@ -143,7 +212,7 @@ CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num)
/*
* Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random
- * hexadecimal digits PLUS a zero terminating byte. It must be an odd number
+ * hexadecimal digits PLUS a null-terminating byte. It must be an odd number
* size.
*/
@@ -166,7 +235,7 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
/* make sure it fits in the local buffer and that it is an odd number! */
return CURLE_BAD_FUNCTION_ARGUMENT;
- num--; /* save one for zero termination */
+ num--; /* save one for null-termination */
result = Curl_rand(data, buffer, num/2);
if(result)
diff --git a/Utilities/cmcurl/lib/rand.h b/Utilities/cmcurl/lib/rand.h
index 02d95d8e64..30fc29615a 100644
--- a/Utilities/cmcurl/lib/rand.h
+++ b/Utilities/cmcurl/lib/rand.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -40,10 +42,16 @@ CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num);
/*
* Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random
- * hexadecimal digits PLUS a zero terminating byte. It must be an odd number
+ * hexadecimal digits PLUS a null-terminating byte. It must be an odd number
* size.
*/
CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
size_t num);
+#ifdef WIN32
+/* Random generator shared between the Schannel vtls and Curl_rand*()
+ functions */
+CURLcode Curl_win32_random(unsigned char *entropy, size_t length);
+#endif
+
#endif /* HEADER_CURL_RAND_H */
diff --git a/Utilities/cmcurl/lib/rename.c b/Utilities/cmcurl/lib/rename.c
index f858d43695..cfb3699fb7 100644
--- a/Utilities/cmcurl/lib/rename.c
+++ b/Utilities/cmcurl/lib/rename.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2020 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "rename.h"
diff --git a/Utilities/cmcurl/lib/rename.h b/Utilities/cmcurl/lib/rename.h
index 534f7471c8..9958e2cd23 100644
--- a/Utilities/cmcurl/lib/rename.h
+++ b/Utilities/cmcurl/lib/rename.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2020 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
int Curl_rename(const char *oldpath, const char *newpath);
diff --git a/Utilities/cmcurl/lib/rtsp.c b/Utilities/cmcurl/lib/rtsp.c
index 726bfb9ae1..6d3bf97e6c 100644
--- a/Utilities/cmcurl/lib/rtsp.c
+++ b/Utilities/cmcurl/lib/rtsp.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -792,7 +794,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header)
/* Find the first non-space letter */
start = header + 8;
- while(*start && ISSPACE(*start))
+ while(*start && ISBLANK(*start))
start++;
if(!*start) {
diff --git a/Utilities/cmcurl/lib/rtsp.h b/Utilities/cmcurl/lib/rtsp.h
index da11ade043..377c828605 100644
--- a/Utilities/cmcurl/lib/rtsp.h
+++ b/Utilities/cmcurl/lib/rtsp.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifdef USE_HYPER
#define CURL_DISABLE_RTSP 1
diff --git a/Utilities/cmcurl/lib/select.c b/Utilities/cmcurl/lib/select.c
index a48da82bac..2ac0746772 100644
--- a/Utilities/cmcurl/lib/select.c
+++ b/Utilities/cmcurl/lib/select.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -308,8 +310,12 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
else
pending_ms = 0;
r = poll(ufds, nfds, pending_ms);
- if(r <= 0)
+ if(r <= 0) {
+ if((r == -1) && (SOCKERRNO == EINTR))
+ /* make EINTR from select or poll not a "lethal" error */
+ r = 0;
return r;
+ }
for(i = 0; i < nfds; i++) {
if(ufds[i].fd == CURL_SOCKET_BAD)
@@ -352,8 +358,12 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
value).
*/
r = our_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
- if(r <= 0)
+ if(r <= 0) {
+ if((r == -1) && (SOCKERRNO == EINTR))
+ /* make EINTR from select or poll not a "lethal" error */
+ r = 0;
return r;
+ }
r = 0;
for(i = 0; i < nfds; i++) {
diff --git a/Utilities/cmcurl/lib/select.h b/Utilities/cmcurl/lib/select.h
index f4bcba30fb..f2cf8bbd9f 100644
--- a/Utilities/cmcurl/lib/select.h
+++ b/Utilities/cmcurl/lib/select.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -34,8 +36,7 @@
* Definition of pollfd struct and constants for platforms lacking them.
*/
-#if !defined(HAVE_STRUCT_POLLFD) && \
- !defined(HAVE_SYS_POLL_H) && \
+#if !defined(HAVE_SYS_POLL_H) && \
!defined(HAVE_POLL_H) && \
!defined(POLLIN)
diff --git a/Utilities/cmcurl/lib/sendf.c b/Utilities/cmcurl/lib/sendf.c
index d7d4d8abd4..d26b7e7cd7 100644
--- a/Utilities/cmcurl/lib/sendf.c
+++ b/Utilities/cmcurl/lib/sendf.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -46,13 +48,14 @@
#include "strdup.h"
#include "http2.h"
#include "headers.h"
+#include "ws.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
-#ifdef CURL_DO_LINEEND_CONV
+#if defined(CURL_DO_LINEEND_CONV) && !defined(CURL_DISABLE_FTP)
/*
* convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
* (\n), with special processing for CRLF sequences that are split between two
@@ -132,7 +135,7 @@ static size_t convert_lineends(struct Curl_easy *data,
}
return size;
}
-#endif /* CURL_DO_LINEEND_CONV */
+#endif /* CURL_DO_LINEEND_CONV && !CURL_DISABLE_FTP */
#ifdef USE_RECV_BEFORE_SEND_WORKAROUND
bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
@@ -243,7 +246,7 @@ void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
DEBUGASSERT(!strchr(fmt, '\n'));
if(data && data->set.verbose) {
va_list ap;
- size_t len;
+ int len;
char buffer[MAXINFO + 2];
va_start(ap, fmt);
len = mvsnprintf(buffer, MAXINFO, fmt, ap);
@@ -263,7 +266,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
DEBUGASSERT(!strchr(fmt, '\n'));
if(data->set.verbose || data->set.errorbuffer) {
va_list ap;
- size_t len;
+ int len;
char error[CURL_ERROR_SIZE + 2];
va_start(ap, fmt);
len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
@@ -494,6 +497,9 @@ static CURLcode pausewrite(struct Curl_easy *data,
}
}
DEBUGASSERT(i < 3);
+ if(i >= 3)
+ /* There are more types to store than what fits: very bad */
+ return CURLE_OUT_OF_MEMORY;
}
else
i = 0;
@@ -529,6 +535,7 @@ static CURLcode chop_write(struct Curl_easy *data,
curl_write_callback writebody = NULL;
char *ptr = optr;
size_t len = olen;
+ void *writebody_ptr = data->set.out;
if(!len)
return CURLE_OK;
@@ -539,8 +546,18 @@ static CURLcode chop_write(struct Curl_easy *data,
return pausewrite(data, type, ptr, len);
/* Determine the callback(s) to use. */
- if(type & CLIENTWRITE_BODY)
+ if(type & CLIENTWRITE_BODY) {
+#ifdef USE_WEBSOCKETS
+ if(conn->handler->protocol & (CURLPROTO_WS|CURLPROTO_WSS)) {
+ struct HTTP *ws = data->req.p.http;
+ writebody = Curl_ws_writecb;
+ ws->ws.data = data;
+ writebody_ptr = ws;
+ }
+ else
+#endif
writebody = data->set.fwrite_func;
+ }
if((type & CLIENTWRITE_HEADER) &&
(data->set.fwrite_header || data->set.writeheader)) {
/*
@@ -558,7 +575,7 @@ static CURLcode chop_write(struct Curl_easy *data,
if(writebody) {
size_t wrote;
Curl_set_in_callback(data, true);
- wrote = writebody(ptr, 1, chunklen, data->set.out);
+ wrote = writebody(ptr, 1, chunklen, writebody_ptr);
Curl_set_in_callback(data, false);
if(CURL_WRITEFUNC_PAUSE == wrote) {
@@ -581,18 +598,20 @@ static CURLcode chop_write(struct Curl_easy *data,
len -= chunklen;
}
+#ifndef CURL_DISABLE_HTTP
/* HTTP header, but not status-line */
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
(type & CLIENTWRITE_HEADER) && !(type & CLIENTWRITE_STATUS) ) {
- CURLcode result =
- Curl_headers_push(data, optr,
- type & CLIENTWRITE_CONNECT ? CURLH_CONNECT :
- (type & CLIENTWRITE_1XX ? CURLH_1XX :
- (type & CLIENTWRITE_TRAILER ? CURLH_TRAILER :
- CURLH_HEADER)));
+ unsigned char htype = (unsigned char)
+ (type & CLIENTWRITE_CONNECT ? CURLH_CONNECT :
+ (type & CLIENTWRITE_1XX ? CURLH_1XX :
+ (type & CLIENTWRITE_TRAILER ? CURLH_TRAILER :
+ CURLH_HEADER)));
+ CURLcode result = Curl_headers_push(data, optr, htype);
if(result)
return result;
}
+#endif
if(writeheader) {
size_t wrote;
@@ -605,8 +624,10 @@ static CURLcode chop_write(struct Curl_easy *data,
/* here we pass in the HEADER bit only since if this was body as well
then it was passed already and clearly that didn't trigger the
pause, so this is saved for later with the HEADER bit only */
- return pausewrite(data, CLIENTWRITE_HEADER, optr, olen);
-
+ return pausewrite(data, CLIENTWRITE_HEADER |
+ (type & (CLIENTWRITE_STATUS|CLIENTWRITE_CONNECT|
+ CLIENTWRITE_1XX|CLIENTWRITE_TRAILER)),
+ optr, olen);
if(wrote != olen) {
failf(data, "Failed writing header");
return CURLE_WRITE_ERROR;
@@ -631,22 +652,15 @@ CURLcode Curl_client_write(struct Curl_easy *data,
char *ptr,
size_t len)
{
- struct connectdata *conn = data->conn;
-
- if(!len)
- return CURLE_OK;
-
+#if !defined(CURL_DISABLE_FTP) && defined(CURL_DO_LINEEND_CONV)
/* FTP data may need conversion. */
if((type & CLIENTWRITE_BODY) &&
- (conn->handler->protocol & PROTO_FAMILY_FTP) &&
- conn->proto.ftpc.transfertype == 'A') {
-
-#ifdef CURL_DO_LINEEND_CONV
+ (data->conn->handler->protocol & PROTO_FAMILY_FTP) &&
+ data->conn->proto.ftpc.transfertype == 'A') {
/* convert end-of-line markers */
len = convert_lineends(data, ptr, len);
-#endif /* CURL_DO_LINEEND_CONV */
}
-
+#endif
return chop_write(data, type, ptr, len);
}
@@ -714,17 +728,17 @@ CURLcode Curl_read(struct Curl_easy *data, /* transfer */
}
/* return 0 on success */
-int Curl_debug(struct Curl_easy *data, curl_infotype type,
- char *ptr, size_t size)
+void Curl_debug(struct Curl_easy *data, curl_infotype type,
+ char *ptr, size_t size)
{
- int rc = 0;
if(data->set.verbose) {
static const char s_infotype[CURLINFO_END][3] = {
"* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
if(data->set.fdebug) {
+ bool inCallback = Curl_is_in_callback(data);
Curl_set_in_callback(data, true);
- rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
- Curl_set_in_callback(data, false);
+ (void)(*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
+ Curl_set_in_callback(data, inCallback);
}
else {
switch(type) {
@@ -739,5 +753,4 @@ int Curl_debug(struct Curl_easy *data, curl_infotype type,
}
}
}
- return rc;
}
diff --git a/Utilities/cmcurl/lib/sendf.h b/Utilities/cmcurl/lib/sendf.h
index 6676003a91..7c4c1280a0 100644
--- a/Utilities/cmcurl/lib/sendf.h
+++ b/Utilities/cmcurl/lib/sendf.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -87,8 +89,8 @@ CURLcode Curl_write_plain(struct Curl_easy *data,
ssize_t *written);
/* the function used to output verbose information */
-int Curl_debug(struct Curl_easy *data, curl_infotype type,
- char *ptr, size_t size);
+void Curl_debug(struct Curl_easy *data, curl_infotype type,
+ char *ptr, size_t size);
#endif /* HEADER_CURL_SENDF_H */
diff --git a/Utilities/cmcurl/lib/setopt.c b/Utilities/cmcurl/lib/setopt.c
index 05e1a544df..5b5975485c 100644
--- a/Utilities/cmcurl/lib/setopt.c
+++ b/Utilities/cmcurl/lib/setopt.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -146,6 +148,40 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
#define C_SSLVERSION_VALUE(x) (x & 0xffff)
#define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
+static CURLcode protocol2num(const char *str, curl_prot_t *val)
+{
+ if(!str)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ if(curl_strequal(str, "all")) {
+ *val = ~(curl_prot_t) 0;
+ return CURLE_OK;
+ }
+
+ *val = 0;
+
+ do {
+ const char *token = str;
+ size_t tlen;
+
+ str = strchr(str, ',');
+ tlen = str? (size_t) (str - token): strlen(token);
+ if(tlen) {
+ const struct Curl_handler *h = Curl_builtin_scheme(token, tlen);
+
+ if(!h)
+ return CURLE_UNSUPPORTED_PROTOCOL;
+
+ *val |= h->protocol;
+ }
+ } while(str++);
+
+ if(!*val)
+ /* no protocol listed */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ return CURLE_OK;
+}
+
/*
* Do not make Curl_vsetopt() static: it is called from
* packages/OS400/ccsidcurl.c.
@@ -155,9 +191,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
char *argptr;
CURLcode result = CURLE_OK;
long arg;
-#ifdef ENABLE_IPV6
unsigned long uarg;
-#endif
curl_off_t bigsize;
switch(option) {
@@ -165,7 +199,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
arg = va_arg(param, long);
if(arg < -1)
return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.dns_cache_timeout = arg;
+ else if(arg > INT_MAX)
+ arg = INT_MAX;
+
+ data->set.dns_cache_timeout = (int)arg;
break;
case CURLOPT_DNS_USE_GLOBAL_CACHE:
/* deprecated */
@@ -203,19 +240,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
#endif
case CURLOPT_RANDOM_FILE:
- /*
- * This is the path name to a file that contains random data to seed
- * the random SSL stuff with. The file is only used for reading.
- */
- result = Curl_setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
- va_arg(param, char *));
break;
case CURLOPT_EGDSOCKET:
- /*
- * The Entropy Gathering Daemon socket pathname
- */
- result = Curl_setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
- va_arg(param, char *));
break;
case CURLOPT_MAXCONNECTS:
/*
@@ -318,12 +344,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
case CURLOPT_SERVER_RESPONSE_TIMEOUT:
/*
- * Option that specifies how quickly an server response must be obtained
+ * Option that specifies how quickly a server response must be obtained
* before it is considered failure. For pingpong protocols.
*/
arg = va_arg(param, long);
if((arg >= 0) && (arg <= (INT_MAX/1000)))
- data->set.server_response_timeout = arg * 1000;
+ data->set.server_response_timeout = (unsigned int)arg * 1000;
else
return CURLE_BAD_FUNCTION_ARGUMENT;
break;
@@ -353,7 +379,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
arg = va_arg(param, long);
if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST))
return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.use_netrc = (enum CURL_NETRC_OPTION)arg;
+ data->set.use_netrc = (unsigned char)arg;
break;
case CURLOPT_NETRC_FILE:
/*
@@ -625,8 +651,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
}
else
data->set.method = HTTPREQ_GET;
+ data->set.upload = FALSE;
break;
+#ifndef CURL_DISABLE_MIME
case CURLOPT_HTTPPOST:
/*
* Set to make us do HTTP POST
@@ -635,6 +663,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.method = HTTPREQ_POST_FORM;
data->set.opt_no_body = FALSE; /* this is implied */
break;
+#endif
case CURLOPT_AWS_SIGV4:
/*
@@ -650,18 +679,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.httpauth = CURLAUTH_AWS_SIGV4;
break;
- case CURLOPT_MIMEPOST:
- /*
- * Set to make us do MIME/form POST
- */
- result = Curl_mime_set_subparts(&data->set.mimepost,
- va_arg(param, curl_mime *), FALSE);
- if(!result) {
- data->set.method = HTTPREQ_POST_MIME;
- data->set.opt_no_body = FALSE; /* this is implied */
- }
- break;
-
case CURLOPT_REFERER:
/*
* String to set in the HTTP Referer: field.
@@ -683,13 +700,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
va_arg(param, char *));
break;
- case CURLOPT_HTTPHEADER:
- /*
- * Set a list with HTTP headers to use (or replace internals with)
- */
- data->set.headers = va_arg(param, struct curl_slist *);
- break;
-
#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXYHEADER:
/*
@@ -927,6 +937,36 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
#endif /* CURL_DISABLE_HTTP */
+#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \
+ !defined(CURL_DISABLE_IMAP)
+# if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MIME)
+ case CURLOPT_HTTPHEADER:
+ /*
+ * Set a list with HTTP headers to use (or replace internals with)
+ */
+ data->set.headers = va_arg(param, struct curl_slist *);
+ break;
+# endif
+
+# ifndef CURL_DISABLE_MIME
+ case CURLOPT_MIMEPOST:
+ /*
+ * Set to make us do MIME POST
+ */
+ result = Curl_mime_set_subparts(&data->set.mimepost,
+ va_arg(param, curl_mime *), FALSE);
+ if(!result) {
+ data->set.method = HTTPREQ_POST_MIME;
+ data->set.opt_no_body = FALSE; /* this is implied */
+ }
+ break;
+
+ case CURLOPT_MIME_OPTIONS:
+ data->set.mime_options = (unsigned int)va_arg(param, long);
+ break;
+# endif
+#endif
+
case CURLOPT_HTTPAUTH:
/*
* Set HTTP Authentication type BITMASK.
@@ -1115,13 +1155,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
}
break;
-#endif /* CURL_DISABLE_PROXY */
case CURLOPT_SOCKS5_AUTH:
data->set.socks5auth = va_arg(param, unsigned long);
if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
result = CURLE_NOT_BUILT_IN;
break;
+#endif /* CURL_DISABLE_PROXY */
+
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
case CURLOPT_SOCKS5_GSSAPI_NEC:
/*
@@ -1270,7 +1311,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
(arg > CURLFTP_CREATE_DIR_RETRY))
result = CURLE_BAD_FUNCTION_ARGUMENT;
else
- data->set.ftp_create_missing_dirs = (int)arg;
+ data->set.ftp_create_missing_dirs = (unsigned char)arg;
break;
case CURLOPT_READDATA:
/*
@@ -1360,12 +1401,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
case CURLOPT_PORT:
/*
- * The port number to use when getting the URL
+ * The port number to use when getting the URL. 0 disables it.
*/
arg = va_arg(param, long);
if((arg < 0) || (arg > 65535))
return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.use_port = arg;
+ data->set.use_port = (unsigned short)arg;
break;
case CURLOPT_TIMEOUT:
/*
@@ -1374,16 +1415,16 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
*/
arg = va_arg(param, long);
if((arg >= 0) && (arg <= (INT_MAX/1000)))
- data->set.timeout = arg * 1000;
+ data->set.timeout = (unsigned int)arg * 1000;
else
return CURLE_BAD_FUNCTION_ARGUMENT;
break;
case CURLOPT_TIMEOUT_MS:
- arg = va_arg(param, long);
- if(arg < 0)
- return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.timeout = arg;
+ uarg = va_arg(param, unsigned long);
+ if(uarg >= UINT_MAX)
+ uarg = UINT_MAX;
+ data->set.timeout = (unsigned int)uarg;
break;
case CURLOPT_CONNECTTIMEOUT:
@@ -1392,27 +1433,29 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
*/
arg = va_arg(param, long);
if((arg >= 0) && (arg <= (INT_MAX/1000)))
- data->set.connecttimeout = arg * 1000;
+ data->set.connecttimeout = (unsigned int)arg * 1000;
else
return CURLE_BAD_FUNCTION_ARGUMENT;
break;
case CURLOPT_CONNECTTIMEOUT_MS:
- arg = va_arg(param, long);
- if(arg < 0)
- return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.connecttimeout = arg;
+ uarg = va_arg(param, unsigned long);
+ if(uarg >= UINT_MAX)
+ uarg = UINT_MAX;
+ data->set.connecttimeout = (unsigned int)uarg;
break;
+#ifndef CURL_DISABLE_FTP
case CURLOPT_ACCEPTTIMEOUT_MS:
/*
- * The maximum time you allow curl to wait for server connect
+ * The maximum time for curl to wait for FTP server connect
*/
- arg = va_arg(param, long);
- if(arg < 0)
- return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.accepttimeout = arg;
+ uarg = va_arg(param, unsigned long);
+ if(uarg >= UINT_MAX)
+ uarg = UINT_MAX;
+ data->set.accepttimeout = (unsigned int)uarg;
break;
+#endif
case CURLOPT_USERPWD:
/*
@@ -1612,13 +1655,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
* Set data write callback
*/
data->set.fwrite_func = va_arg(param, curl_write_callback);
- if(!data->set.fwrite_func) {
- data->set.is_fwrite_set = 0;
+ if(!data->set.fwrite_func)
/* When set to NULL, reset to our internal default function */
data->set.fwrite_func = (curl_write_callback)fwrite;
- }
- else
- data->set.is_fwrite_set = 1;
break;
case CURLOPT_READFUNCTION:
/*
@@ -2166,7 +2205,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
else if(arg < READBUFFER_MIN)
arg = READBUFFER_MIN;
- data->set.buffer_size = arg;
+ data->set.buffer_size = (int)arg;
break;
case CURLOPT_UPLOAD_BUFFERSIZE:
@@ -2360,9 +2399,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_CONNECT_ONLY:
/*
- * No data transfer, set up connection and let application use the socket
+ * No data transfer.
+ * (1) - only do connection
+ * (2) - do first get request but get no content
*/
- data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
+ arg = va_arg(param, long);
+ if(arg > 2)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.connect_only = (unsigned char)arg;
break;
case CURLOPT_SOCKOPTFUNCTION:
@@ -2435,7 +2479,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
#ifdef USE_SSH
/* we only include SSH options if explicitly built to support SSH */
case CURLOPT_SSH_AUTH_TYPES:
- data->set.ssh_auth_types = va_arg(param, long);
+ data->set.ssh_auth_types = (unsigned int)va_arg(param, long);
break;
case CURLOPT_SSH_PUBLIC_KEYFILE:
@@ -2478,7 +2522,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
va_arg(param, char *));
break;
+#ifdef USE_LIBSSH2
+ case CURLOPT_SSH_HOSTKEYFUNCTION:
+ /* the callback to check the hostkey without the knownhost file */
+ data->set.ssh_hostkeyfunc = va_arg(param, curl_sshhostkeycallback);
+ break;
+ case CURLOPT_SSH_HOSTKEYDATA:
+ /*
+ * Custom client data to pass to the SSH keyfunc callback
+ */
+ data->set.ssh_hostkeyfunc_userp = va_arg(param, void *);
+ break;
+#endif
case CURLOPT_SSH_KEYFUNCTION:
/* setting to NULL is fine since the ssh.c functions themselves will
then revert to use the internal default */
@@ -2523,7 +2579,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
arg = va_arg(param, long);
if((arg < 0) || (arg > 0777))
return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.new_file_perms = arg;
+ data->set.new_file_perms = (unsigned int)arg;
break;
case CURLOPT_NEW_DIRECTORY_PERMS:
@@ -2533,7 +2589,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
arg = va_arg(param, long);
if((arg < 0) || (arg > 0777))
return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.new_directory_perms = arg;
+ data->set.new_directory_perms = (unsigned int)arg;
break;
#endif
@@ -2558,16 +2614,36 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
transfer, which thus helps the app which takes URLs from users or other
external inputs and want to restrict what protocol(s) to deal
with. Defaults to CURLPROTO_ALL. */
- data->set.allowed_protocols = va_arg(param, long);
+ data->set.allowed_protocols = (curl_prot_t)va_arg(param, long);
break;
case CURLOPT_REDIR_PROTOCOLS:
/* set the bitmask for the protocols that libcurl is allowed to follow to,
as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
to be set in both bitmasks to be allowed to get redirected to. */
- data->set.redir_protocols = va_arg(param, long);
+ data->set.redir_protocols = (curl_prot_t)va_arg(param, long);
break;
+ case CURLOPT_PROTOCOLS_STR: {
+ curl_prot_t prot;
+ argptr = va_arg(param, char *);
+ result = protocol2num(argptr, &prot);
+ if(result)
+ return result;
+ data->set.allowed_protocols = prot;
+ break;
+ }
+
+ case CURLOPT_REDIR_PROTOCOLS_STR: {
+ curl_prot_t prot;
+ argptr = va_arg(param, char *);
+ result = protocol2num(argptr, &prot);
+ if(result)
+ return result;
+ data->set.redir_protocols = prot;
+ break;
+ }
+
case CURLOPT_DEFAULT_PROTOCOL:
/* Set the protocol to use when the URL doesn't include any protocol */
result = Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL],
@@ -2596,13 +2672,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
#endif
-#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
- !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
- case CURLOPT_MIME_OPTIONS:
- data->set.mime_options = va_arg(param, long);
- break;
-#endif
-
case CURLOPT_SASL_AUTHZID:
/* Authorization identity (identity to act as) */
result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID],
@@ -2833,13 +2902,17 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
arg = va_arg(param, long);
if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.tcp_keepidle = arg;
+ else if(arg > INT_MAX)
+ arg = INT_MAX;
+ data->set.tcp_keepidle = (int)arg;
break;
case CURLOPT_TCP_KEEPINTVL:
arg = va_arg(param, long);
if(arg < 0)
return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.tcp_keepintvl = arg;
+ else if(arg > INT_MAX)
+ arg = INT_MAX;
+ data->set.tcp_keepintvl = (int)arg;
break;
case CURLOPT_TCP_FASTOPEN:
#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \
@@ -2850,7 +2923,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
#endif
break;
case CURLOPT_SSL_ENABLE_NPN:
- data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
case CURLOPT_SSL_ENABLE_ALPN:
data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
@@ -2906,10 +2978,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS:
- arg = va_arg(param, long);
- if(arg < 0)
- return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.happy_eyeballs_timeout = arg;
+ uarg = va_arg(param, unsigned long);
+ if(uarg >= UINT_MAX)
+ uarg = UINT_MAX;
+ data->set.happy_eyeballs_timeout = (unsigned int)uarg;
break;
#ifndef CURL_DISABLE_SHUFFLE_DNS
case CURLOPT_DNS_SHUFFLE_ADDRESSES:
@@ -3026,6 +3098,15 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_PREREQDATA:
data->set.prereq_userp = va_arg(param, void *);
break;
+#ifdef USE_WEBSOCKETS
+ case CURLOPT_WS_OPTIONS: {
+ bool raw;
+ arg = va_arg(param, long);
+ raw = (arg & CURLWS_RAW_MODE);
+ data->set.ws_raw_mode = raw;
+ break;
+ }
+#endif
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_UNKNOWN_OPTION;
diff --git a/Utilities/cmcurl/lib/setopt.h b/Utilities/cmcurl/lib/setopt.h
index affbfd9960..ffc77a71dc 100644
--- a/Utilities/cmcurl/lib/setopt.h
+++ b/Utilities/cmcurl/lib/setopt.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
CURLcode Curl_setstropt(char **charp, const char *s);
diff --git a/Utilities/cmcurl/lib/setup-os400.h b/Utilities/cmcurl/lib/setup-os400.h
index 8c97371e4d..6023ca20de 100644
--- a/Utilities/cmcurl/lib/setup-os400.h
+++ b/Utilities/cmcurl/lib/setup-os400.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
diff --git a/Utilities/cmcurl/lib/setup-vms.h b/Utilities/cmcurl/lib/setup-vms.h
index a6710d9076..b570683d78 100644
--- a/Utilities/cmcurl/lib/setup-vms.h
+++ b/Utilities/cmcurl/lib/setup-vms.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* */
diff --git a/Utilities/cmcurl/lib/setup-win32.h b/Utilities/cmcurl/lib/setup-win32.h
index fa8742f3b1..bc5f8efc3c 100644
--- a/Utilities/cmcurl/lib/setup-win32.h
+++ b/Utilities/cmcurl/lib/setup-win32.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -35,10 +37,21 @@
#ifdef HAVE_WINDOWS_H
# if defined(UNICODE) && !defined(_UNICODE)
-# define _UNICODE
+# error "UNICODE is defined but _UNICODE is not defined"
# endif
# if defined(_UNICODE) && !defined(UNICODE)
-# define UNICODE
+# error "_UNICODE is defined but UNICODE is not defined"
+# endif
+/*
+ * Don't include unneeded stuff in Windows headers to avoid compiler
+ * warnings and macro clashes.
+ * Make sure to define this macro before including any Windows headers.
+ */
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# ifndef NOGDI
+# define NOGDI
# endif
# include <winerror.h>
# include <windows.h>
diff --git a/Utilities/cmcurl/lib/sha256.c b/Utilities/cmcurl/lib/sha256.c
index 1e879f60f6..60720f5b13 100644
--- a/Utilities/cmcurl/lib/sha256.c
+++ b/Utilities/cmcurl/lib/sha256.c
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/share.c b/Utilities/cmcurl/lib/share.c
index 403563fdd6..1a083e72a0 100644
--- a/Utilities/cmcurl/lib/share.c
+++ b/Utilities/cmcurl/lib/share.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -39,7 +41,7 @@ curl_share_init(void)
if(share) {
share->magic = CURL_GOOD_SHARE;
share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
- Curl_init_dnscache(&share->hostcache);
+ Curl_init_dnscache(&share->hostcache, 23);
}
return share;
diff --git a/Utilities/cmcurl/lib/share.h b/Utilities/cmcurl/lib/share.h
index 222e34ba6e..32be41691a 100644
--- a/Utilities/cmcurl/lib/share.h
+++ b/Utilities/cmcurl/lib/share.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/sigpipe.h b/Utilities/cmcurl/lib/sigpipe.h
index d6ec5fca3c..d12b31764d 100644
--- a/Utilities/cmcurl/lib/sigpipe.h
+++ b/Utilities/cmcurl/lib/sigpipe.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/slist.c b/Utilities/cmcurl/lib/slist.c
index 907c203f38..6c80722c77 100644
--- a/Utilities/cmcurl/lib/slist.c
+++ b/Utilities/cmcurl/lib/slist.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/slist.h b/Utilities/cmcurl/lib/slist.h
index 3114259cfe..4e5834c90a 100644
--- a/Utilities/cmcurl/lib/slist.h
+++ b/Utilities/cmcurl/lib/slist.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
diff --git a/Utilities/cmcurl/lib/smb.c b/Utilities/cmcurl/lib/smb.c
index 8f44704a2c..a62e858143 100644
--- a/Utilities/cmcurl/lib/smb.c
+++ b/Utilities/cmcurl/lib/smb.c
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -32,7 +34,7 @@
#include <process.h>
#ifdef CURL_WINDOWS_APP
#define getpid GetCurrentProcessId
-#elif !defined(MSDOS)
+#elif defined(WIN32)
#define getpid _getpid
#endif
#endif
diff --git a/Utilities/cmcurl/lib/smb.h b/Utilities/cmcurl/lib/smb.h
index 0e3c2ec112..919f3ac142 100644
--- a/Utilities/cmcurl/lib/smb.h
+++ b/Utilities/cmcurl/lib/smb.h
@@ -7,8 +7,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
- * Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
+ * Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -21,6 +21,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
enum smb_conn_state {
diff --git a/Utilities/cmcurl/lib/smtp.c b/Utilities/cmcurl/lib/smtp.c
index c736cfae19..6ebb41af66 100644
--- a/Utilities/cmcurl/lib/smtp.c
+++ b/Utilities/cmcurl/lib/smtp.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC1870 SMTP Service Extension for Message Size
* RFC2195 CRAM-MD5 authentication
* RFC2831 DIGEST-MD5 authentication
@@ -1818,7 +1820,9 @@ static CURLcode smtp_parse_address(struct Curl_easy *data, const char *fqma,
return result;
}
-CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread)
+CURLcode Curl_smtp_escape_eob(struct Curl_easy *data,
+ const ssize_t nread,
+ const ssize_t offset)
{
/* When sending a SMTP payload we must detect CRLF. sequences making sure
they are sent as CRLF.. instead, as a . on the beginning of a line will
@@ -1852,7 +1856,9 @@ CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread)
/* This loop can be improved by some kind of Boyer-Moore style of
approach but that is saved for later... */
- for(i = 0, si = 0; i < nread; i++) {
+ if(offset)
+ memcpy(scratch, data->req.upload_fromhere, offset);
+ for(i = offset, si = offset; i < nread; i++) {
if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i]) {
smtp->eob++;
diff --git a/Utilities/cmcurl/lib/smtp.h b/Utilities/cmcurl/lib/smtp.h
index 1fe45346ee..24c5589e43 100644
--- a/Utilities/cmcurl/lib/smtp.h
+++ b/Utilities/cmcurl/lib/smtp.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2009 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "pingpong.h"
@@ -91,6 +93,8 @@ extern const struct Curl_handler Curl_handler_smtps;
#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e"
#define SMTP_EOB_REPL_LEN 4
-CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread);
+CURLcode Curl_smtp_escape_eob(struct Curl_easy *data,
+ const ssize_t nread,
+ const ssize_t offset);
#endif /* HEADER_CURL_SMTP_H */
diff --git a/Utilities/cmcurl/lib/sockaddr.h b/Utilities/cmcurl/lib/sockaddr.h
index 84c08d9bb5..77ec833ee0 100644
--- a/Utilities/cmcurl/lib/sockaddr.h
+++ b/Utilities/cmcurl/lib/sockaddr.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/socketpair.c b/Utilities/cmcurl/lib/socketpair.c
index 409d2ad667..0f8798f087 100644
--- a/Utilities/cmcurl/lib/socketpair.c
+++ b/Utilities/cmcurl/lib/socketpair.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/socketpair.h b/Utilities/cmcurl/lib/socketpair.h
index cdcc0b921e..de70df673a 100644
--- a/Utilities/cmcurl/lib/socketpair.h
+++ b/Utilities/cmcurl/lib/socketpair.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,10 +20,14 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#ifndef HAVE_SOCKETPAIR
+#include <curl/curl.h>
+
int Curl_socketpair(int domain, int type, int protocol,
curl_socket_t socks[2]);
#else
diff --git a/Utilities/cmcurl/lib/socks.c b/Utilities/cmcurl/lib/socks.c
index d614ae59c6..52c29880a6 100644
--- a/Utilities/cmcurl/lib/socks.c
+++ b/Utilities/cmcurl/lib/socks.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/socks.h b/Utilities/cmcurl/lib/socks.h
index f30c610a86..ff83aa5614 100644
--- a/Utilities/cmcurl/lib/socks.h
+++ b/Utilities/cmcurl/lib/socks.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/socks_gssapi.c b/Utilities/cmcurl/lib/socks_gssapi.c
index 8ef2f8f374..f14099febf 100644
--- a/Utilities/cmcurl/lib/socks_gssapi.c
+++ b/Utilities/cmcurl/lib/socks_gssapi.c
@@ -5,8 +5,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
+ * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012, Markus Moeller, <markus_moeller@compuserve.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -51,7 +53,7 @@ static int check_gss_err(struct Curl_easy *data,
if(GSS_ERROR(major_status)) {
OM_uint32 maj_stat, min_stat;
OM_uint32 msg_ctx = 0;
- gss_buffer_desc status_string;
+ gss_buffer_desc status_string = GSS_C_EMPTY_BUFFER;
char buf[1024];
size_t len;
diff --git a/Utilities/cmcurl/lib/socks_sspi.c b/Utilities/cmcurl/lib/socks_sspi.c
index ffc8703468..210a0dfbc5 100644
--- a/Utilities/cmcurl/lib/socks_sspi.c
+++ b/Utilities/cmcurl/lib/socks_sspi.c
@@ -5,8 +5,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
+ * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012, 2011, Markus Moeller, <markus_moeller@compuserve.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/speedcheck.c b/Utilities/cmcurl/lib/speedcheck.c
index 841d256b48..3ddc43d2de 100644
--- a/Utilities/cmcurl/lib/speedcheck.c
+++ b/Utilities/cmcurl/lib/speedcheck.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/speedcheck.h b/Utilities/cmcurl/lib/speedcheck.h
index 1d4c7bfeff..cb44eb04ec 100644
--- a/Utilities/cmcurl/lib/speedcheck.h
+++ b/Utilities/cmcurl/lib/speedcheck.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/splay.c b/Utilities/cmcurl/lib/splay.c
index bcc0795212..33b44aa1c6 100644
--- a/Utilities/cmcurl/lib/splay.c
+++ b/Utilities/cmcurl/lib/splay.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1997 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1997 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -101,7 +103,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i,
struct Curl_tree *node)
{
static const struct curltime KEY_NOTUSED = {
- (time_t)-1, (unsigned int)-1
+ ~0, -1
}; /* will *NEVER* appear */
if(!node)
@@ -211,7 +213,7 @@ int Curl_splayremove(struct Curl_tree *t,
struct Curl_tree **newroot)
{
static const struct curltime KEY_NOTUSED = {
- (time_t)-1, (unsigned int)-1
+ ~0, -1
}; /* will *NEVER* appear */
struct Curl_tree *x;
diff --git a/Utilities/cmcurl/lib/splay.h b/Utilities/cmcurl/lib/splay.h
index eb9f65f1e0..015e2ca52f 100644
--- a/Utilities/cmcurl/lib/splay.h
+++ b/Utilities/cmcurl/lib/splay.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1997 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1997 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#include "timeval.h"
diff --git a/Utilities/cmcurl/lib/strcase.c b/Utilities/cmcurl/lib/strcase.c
index 692a3f14ae..09d2a8a961 100644
--- a/Utilities/cmcurl/lib/strcase.c
+++ b/Utilities/cmcurl/lib/strcase.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -26,25 +28,58 @@
#include "strcase.h"
-static char raw_tolower(char in);
+/* Mapping table to go from lowercase to uppercase for plain ASCII.*/
+static const unsigned char touppermap[256] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65,
+66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
+134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
+166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
+182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
+198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
+214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
+230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
+246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+};
+
+/* Mapping table to go from uppercase to lowercase for plain ASCII.*/
+static const unsigned char tolowermap[256] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95,
+96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+};
+
/* Portable, consistent toupper. Do not use toupper() because its behavior is
altered by the current locale. */
char Curl_raw_toupper(char in)
{
- if(in >= 'a' && in <= 'z')
- return (char)('A' + in - 'a');
- return in;
+ return touppermap[(unsigned char) in];
}
/* Portable, consistent tolower. Do not use tolower() because its behavior is
altered by the current locale. */
-static char raw_tolower(char in)
+char Curl_raw_tolower(char in)
{
- if(in >= 'A' && in <= 'Z')
- return (char)('a' + in - 'A');
- return in;
+ return tolowermap[(unsigned char) in];
}
/*
@@ -62,14 +97,15 @@ int Curl_strcasecompare(const char *first, const char *second)
while(*first && *second) {
if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
/* get out of the loop as soon as they don't match */
- break;
+ return 0;
first++;
second++;
}
- /* we do the comparison here (possibly again), just to make sure that if the
- loop above is skipped because one of the strings reached zero, we must not
- return this as a successful match */
- return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
+ /* If we're here either the strings are the same or the length is different.
+ We can just test if the "current" character is non-zero for one and zero
+ for the other. Note that the characters may not be exactly the same even
+ if they match, we only want to compare zero-ness. */
+ return !*first == !*second;
}
int Curl_safe_strcasecompare(const char *first, const char *second)
@@ -127,7 +163,7 @@ void Curl_strntolower(char *dest, const char *src, size_t n)
return;
do {
- *dest++ = raw_tolower(*src);
+ *dest++ = Curl_raw_tolower(*src);
} while(*src++ && --n);
}
@@ -141,6 +177,28 @@ bool Curl_safecmp(char *a, char *b)
return !a && !b;
}
+/*
+ * Curl_timestrcmp() returns 0 if the two strings are identical. The time this
+ * function spends is a function of the shortest string, not of the contents.
+ */
+int Curl_timestrcmp(const char *a, const char *b)
+{
+ int match = 0;
+ int i = 0;
+
+ if(a && b) {
+ while(1) {
+ match |= a[i]^b[i];
+ if(!a[i] || !b[i])
+ break;
+ i++;
+ }
+ }
+ else
+ return a || b;
+ return match;
+}
+
/* --- public functions --- */
int curl_strequal(const char *first, const char *second)
diff --git a/Utilities/cmcurl/lib/strcase.h b/Utilities/cmcurl/lib/strcase.h
index 2635f5117e..65a575385d 100644
--- a/Utilities/cmcurl/lib/strcase.h
+++ b/Utilities/cmcurl/lib/strcase.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <curl/curl.h>
@@ -41,6 +43,7 @@ int Curl_safe_strcasecompare(const char *first, const char *second);
int Curl_strncasecompare(const char *first, const char *second, size_t max);
char Curl_raw_toupper(char in);
+char Curl_raw_tolower(char in);
/* checkprefix() is a shorter version of the above, used when the first
argument is the string literal */
@@ -50,5 +53,6 @@ void Curl_strntoupper(char *dest, const char *src, size_t n);
void Curl_strntolower(char *dest, const char *src, size_t n);
bool Curl_safecmp(char *a, char *b);
+int Curl_timestrcmp(const char *first, const char *second);
#endif /* HEADER_CURL_STRCASE_H */
diff --git a/Utilities/cmcurl/lib/strdup.c b/Utilities/cmcurl/lib/strdup.c
index 85cf33b3ed..ac22b6ddaf 100644
--- a/Utilities/cmcurl/lib/strdup.c
+++ b/Utilities/cmcurl/lib/strdup.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/strdup.h b/Utilities/cmcurl/lib/strdup.h
index 8c8a6f20e1..fb46808b83 100644
--- a/Utilities/cmcurl/lib/strdup.h
+++ b/Utilities/cmcurl/lib/strdup.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/strerror.c b/Utilities/cmcurl/lib/strerror.c
index 781e26b69f..b9a51e26b9 100644
--- a/Utilities/cmcurl/lib/strerror.c
+++ b/Utilities/cmcurl/lib/strerror.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -263,9 +265,6 @@ curl_easy_strerror(CURLcode error)
case CURLE_TFTP_NOSUCHUSER:
return "TFTP: No such user";
- case CURLE_CONV_FAILED:
- return "Conversion failed";
-
case CURLE_REMOTE_FILE_NOT_FOUND:
return "Remote file not found";
@@ -317,6 +316,9 @@ curl_easy_strerror(CURLcode error)
case CURLE_SSL_CLIENTCERT:
return "SSL Client Certificate required";
+ case CURLE_UNRECOVERABLE_POLL:
+ return "Unrecoverable error in select/poll";
+
/* error codes not used by current libcurl */
case CURLE_OBSOLETE20:
case CURLE_OBSOLETE24:
@@ -329,6 +331,7 @@ curl_easy_strerror(CURLcode error)
case CURLE_OBSOLETE51:
case CURLE_OBSOLETE57:
case CURLE_OBSOLETE62:
+ case CURLE_OBSOLETE75:
case CURLE_OBSOLETE76:
case CURL_LAST:
break;
@@ -400,6 +403,9 @@ curl_multi_strerror(CURLMcode error)
case CURLM_ABORTED_BY_CALLBACK:
return "Operation was aborted by an application callback";
+ case CURLM_UNRECOVERABLE_POLL:
+ return "Unrecoverable error in select/poll";
+
case CURLM_LAST:
break;
}
@@ -470,7 +476,7 @@ curl_url_strerror(CURLUcode error)
return "Port number was not a decimal number between 0 and 65535";
case CURLUE_UNSUPPORTED_SCHEME:
- return "This libcurl build doesn't support the given URL scheme";
+ return "Unsupported URL scheme";
case CURLUE_URLDECODE:
return "URL decode error, most likely because of rubbish in the input";
@@ -524,7 +530,7 @@ curl_url_strerror(CURLUcode error)
return "Bad file:// URL";
case CURLUE_BAD_SLASHES:
- return "Unsupported number of slashes";
+ return "Unsupported number of slashes following scheme";
case CURLUE_BAD_SCHEME:
return "Bad scheme";
diff --git a/Utilities/cmcurl/lib/strerror.h b/Utilities/cmcurl/lib/strerror.h
index 96a7e27c51..658f16c10e 100644
--- a/Utilities/cmcurl/lib/strerror.h
+++ b/Utilities/cmcurl/lib/strerror.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "urldata.h"
diff --git a/Utilities/cmcurl/lib/strtok.c b/Utilities/cmcurl/lib/strtok.c
index d53e587ab3..6120bcc28e 100644
--- a/Utilities/cmcurl/lib/strtok.c
+++ b/Utilities/cmcurl/lib/strtok.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/strtok.h b/Utilities/cmcurl/lib/strtok.h
index 831ef0c009..641a3daed8 100644
--- a/Utilities/cmcurl/lib/strtok.h
+++ b/Utilities/cmcurl/lib/strtok.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#include <stddef.h>
diff --git a/Utilities/cmcurl/lib/strtoofft.c b/Utilities/cmcurl/lib/strtoofft.c
index ac87cfc5bd..30deb8c05b 100644
--- a/Utilities/cmcurl/lib/strtoofft.c
+++ b/Utilities/cmcurl/lib/strtoofft.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <errno.h>
@@ -85,7 +87,7 @@ static curl_off_t strtooff(const char *nptr, char **endptr, int base)
/* Skip leading whitespace. */
end = (char *)nptr;
- while(ISSPACE(end[0])) {
+ while(ISBLANK(end[0])) {
end++;
}
@@ -220,9 +222,9 @@ CURLofft curlx_strtoofft(const char *str, char **endp, int base,
errno = 0;
*num = 0; /* clear by default */
- while(*str && ISSPACE(*str))
+ while(*str && ISBLANK(*str))
str++;
- if('-' == *str) {
+ if(('-' == *str) || (ISSPACE(*str))) {
if(endp)
*endp = (char *)str; /* didn't actually move */
return CURL_OFFT_INVAL; /* nothing parsed */
diff --git a/Utilities/cmcurl/lib/strtoofft.h b/Utilities/cmcurl/lib/strtoofft.h
index 4d22ba36c9..311dae4403 100644
--- a/Utilities/cmcurl/lib/strtoofft.h
+++ b/Utilities/cmcurl/lib/strtoofft.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/system_win32.c b/Utilities/cmcurl/lib/system_win32.c
index 9a6dd9cef6..bede9c7dcd 100644
--- a/Utilities/cmcurl/lib/system_win32.c
+++ b/Utilities/cmcurl/lib/system_win32.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2016 - 2021, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2016 - 2022, 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
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/system_win32.h b/Utilities/cmcurl/lib/system_win32.h
index 69e0c812c0..167804e3c5 100644
--- a/Utilities/cmcurl/lib/system_win32.h
+++ b/Utilities/cmcurl/lib/system_win32.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2016 - 2020, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2016 - 2022, 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
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/telnet.c b/Utilities/cmcurl/lib/telnet.c
index 2abfcd952a..923c7f82bd 100644
--- a/Utilities/cmcurl/lib/telnet.c
+++ b/Utilities/cmcurl/lib/telnet.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/telnet.h b/Utilities/cmcurl/lib/telnet.h
index 1427473a9f..6dd99b48dc 100644
--- a/Utilities/cmcurl/lib/telnet.h
+++ b/Utilities/cmcurl/lib/telnet.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_TELNET
extern const struct Curl_handler Curl_handler_telnet;
diff --git a/Utilities/cmcurl/lib/tftp.c b/Utilities/cmcurl/lib/tftp.c
index 7f2c88b71e..9e6d9490ed 100644
--- a/Utilities/cmcurl/lib/tftp.c
+++ b/Utilities/cmcurl/lib/tftp.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/tftp.h b/Utilities/cmcurl/lib/tftp.h
index 4b5bea2757..3f1fda6382 100644
--- a/Utilities/cmcurl/lib/tftp.h
+++ b/Utilities/cmcurl/lib/tftp.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef CURL_DISABLE_TFTP
extern const struct Curl_handler Curl_handler_tftp;
diff --git a/Utilities/cmcurl/lib/timediff.c b/Utilities/cmcurl/lib/timediff.c
index 003477c63c..c5893187dd 100644
--- a/Utilities/cmcurl/lib/timediff.c
+++ b/Utilities/cmcurl/lib/timediff.c
@@ -18,10 +18,14 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "timediff.h"
+#include <limits.h>
+
/*
* Converts number of milliseconds into a timeval structure.
*
diff --git a/Utilities/cmcurl/lib/timediff.h b/Utilities/cmcurl/lib/timediff.h
index fcd5f05636..90e547457f 100644
--- a/Utilities/cmcurl/lib/timediff.h
+++ b/Utilities/cmcurl/lib/timediff.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/timeval.c b/Utilities/cmcurl/lib/timeval.c
index ca98fe50e5..647d7b0fc5 100644
--- a/Utilities/cmcurl/lib/timeval.c
+++ b/Utilities/cmcurl/lib/timeval.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "timeval.h"
diff --git a/Utilities/cmcurl/lib/timeval.h b/Utilities/cmcurl/lib/timeval.h
index dce32f4cde..8d4fef4e17 100644
--- a/Utilities/cmcurl/lib/timeval.h
+++ b/Utilities/cmcurl/lib/timeval.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c
index 315da876c4..441da73429 100644
--- a/Utilities/cmcurl/lib/transfer.c
+++ b/Utilities/cmcurl/lib/transfer.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -202,6 +204,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
}
#endif
+#ifndef CURL_DISABLE_HTTP
/* if we are transmitting trailing data, we don't need to write
a chunk size so we skip this */
if(data->req.upload_chunky &&
@@ -211,7 +214,6 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
}
-#ifndef CURL_DISABLE_HTTP
if(data->state.trailers_state == TRAILERS_SENDING) {
/* if we're here then that means that we already sent the last empty chunk
but we didn't send a final CR LF, so we sent 0 CR LF. We then start
@@ -267,6 +269,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
return CURLE_READ_ERROR;
}
+#ifndef CURL_DISABLE_HTTP
if(!data->req.forbidchunk && data->req.upload_chunky) {
/* if chunked Transfer-Encoding
* build chunk:
@@ -317,15 +320,12 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
/* always append ASCII CRLF to the data unless
we have a valid trailer callback */
-#ifndef CURL_DISABLE_HTTP
if((nread-hexlen) == 0 &&
data->set.trailer_callback != NULL &&
data->state.trailers_state == TRAILERS_NONE) {
data->state.trailers_state = TRAILERS_INITIALIZED;
}
- else
-#endif
- {
+ else {
memcpy(data->req.upload_fromhere + nread,
endofline_network,
strlen(endofline_network));
@@ -333,7 +333,6 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
}
}
-#ifndef CURL_DISABLE_HTTP
if(data->state.trailers_state == TRAILERS_SENDING &&
!trailers_left(data)) {
Curl_dyn_free(&data->state.trailers_buf);
@@ -345,7 +344,6 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
infof(data, "Signaling end of chunked upload after trailers.");
}
else
-#endif
if((nread - hexlen) == 0 &&
data->state.trailers_state != TRAILERS_INITIALIZED) {
/* mark this as done once this chunk is transferred */
@@ -357,6 +355,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes,
if(added_crlf)
nread += strlen(endofline_network); /* for the added end of line */
}
+#endif
*nreadp = nread;
@@ -540,6 +539,13 @@ static CURLcode readwrite_data(struct Curl_easy *data,
bool is_http2 = ((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
(conn->httpversion == 20));
#endif
+ bool is_http3 =
+#ifdef ENABLE_QUIC
+ ((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+ (conn->httpversion == 30));
+#else
+ FALSE;
+#endif
if(
#ifdef USE_NGHTTP2
@@ -550,6 +556,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
for a particular stream. */
!is_http2 &&
#endif
+ !is_http3 && /* Same reason mentioned above. */
k->size != -1 && !k->header) {
/* make sure we don't read too much */
curl_off_t totalleft = k->size - k->bytecount;
@@ -597,6 +604,9 @@ static CURLcode readwrite_data(struct Curl_easy *data,
DEBUGF(infof(data, "nread == 0, stream closed, bailing"));
else
#endif
+ if(is_http3 && !nread)
+ DEBUGF(infof(data, "nread == 0, stream closed, bailing"));
+ else
DEBUGF(infof(data, "nread <= 0, server closed connection, bailing"));
k->keepon &= ~KEEP_RECV;
break;
@@ -754,7 +764,13 @@ static CURLcode readwrite_data(struct Curl_easy *data,
if(nread < 0) /* this should be unusual */
nread = 0;
- k->keepon &= ~KEEP_RECV; /* we're done reading */
+ /* HTTP/3 over QUIC should keep reading until QUIC connection
+ is closed. In contrast to HTTP/2 which can stop reading
+ from TCP connection, HTTP/3 over QUIC needs ACK from server
+ to ensure stream closure. It should keep reading. */
+ if(!is_http3) {
+ k->keepon &= ~KEEP_RECV; /* we're done reading */
+ }
}
k->bytecount += nread;
@@ -900,6 +916,9 @@ static void win_update_buffer_size(curl_socket_t sockfd)
#define win_update_buffer_size(x)
#endif
+#define curl_upload_refill_watermark(data) \
+ ((ssize_t)((data)->set.upload_buffer_size >> 5))
+
/*
* Send data to upload to the server, when the socket is writable.
*/
@@ -921,13 +940,25 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
do {
curl_off_t nbody;
+ ssize_t offset = 0;
+
+ if(0 != k->upload_present &&
+ k->upload_present < curl_upload_refill_watermark(data) &&
+ !k->upload_chunky &&/*(variable sized chunked header; append not safe)*/
+ !k->upload_done && /*!(k->upload_done once k->upload_present sent)*/
+ !(k->writebytecount + k->upload_present - k->pendingheader ==
+ data->state.infilesize)) {
+ offset = k->upload_present;
+ }
/* only read more data if there's no upload data already
- present in the upload buffer */
- if(0 == k->upload_present) {
+ present in the upload buffer, or if appending to upload buffer */
+ if(0 == k->upload_present || offset) {
result = Curl_get_upload_buffer(data);
if(result)
return result;
+ if(offset && k->upload_fromhere != data->state.ulbuf)
+ memmove(data->state.ulbuf, k->upload_fromhere, offset);
/* init the "upload from here" pointer */
k->upload_fromhere = data->state.ulbuf;
@@ -960,12 +991,14 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
sending_http_headers = FALSE;
}
- result = Curl_fillreadbuffer(data, data->set.upload_buffer_size,
+ k->upload_fromhere += offset;
+ result = Curl_fillreadbuffer(data, data->set.upload_buffer_size-offset,
&fillcount);
+ k->upload_fromhere -= offset;
if(result)
return result;
- nread = fillcount;
+ nread = offset + fillcount;
}
else
nread = 0; /* we're done uploading/reading */
@@ -1007,7 +1040,9 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
* That means the hex values for ASCII CR (0x0d) & LF (0x0a)
* must be used instead of the escape sequences \r & \n.
*/
- for(i = 0, si = 0; i < nread; i++, si++) {
+ if(offset)
+ memcpy(data->state.scratch, k->upload_fromhere, offset);
+ for(i = offset, si = offset; i < nread; i++, si++) {
if(k->upload_fromhere[i] == 0x0a) {
data->state.scratch[si++] = 0x0d;
data->state.scratch[si] = 0x0a;
@@ -1037,12 +1072,12 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
#ifndef CURL_DISABLE_SMTP
if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
- result = Curl_smtp_escape_eob(data, nread);
+ result = Curl_smtp_escape_eob(data, nread, offset);
if(result)
return result;
}
#endif /* CURL_DISABLE_SMTP */
- } /* if 0 == k->upload_present */
+ } /* if 0 == k->upload_present or appended to upload buffer */
else {
/* We have a partial buffer left from a previous "round". Use
that instead of reading more data */
@@ -1153,10 +1188,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
else
fd_write = CURL_SOCKET_BAD;
+#if defined(USE_HTTP2) || defined(USE_HTTP3)
if(data->state.drain) {
select_res |= CURL_CSELECT_IN;
DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data"));
}
+#endif
if(!select_res) /* Call for select()/poll() only, if read/write/error
status is not known. */
@@ -1222,6 +1259,14 @@ CURLcode Curl_readwrite(struct connectdata *conn,
infof(data, "Done waiting for 100-continue");
}
}
+
+#ifdef ENABLE_QUIC
+ if(conn->transport == TRNSPRT_QUIC) {
+ result = Curl_quic_idle(data);
+ if(result)
+ return result;
+ }
+#endif
}
if(Curl_pgrsUpdate(data))
@@ -1394,7 +1439,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
if(result)
return result;
- data->state.wildcardmatch = data->set.wildcard_enabled;
+ data->state.requests = 0;
data->state.followlocation = 0; /* reset the location-follow counter */
data->state.this_is_a_follow = FALSE; /* reset this */
data->state.errorbuf = FALSE; /* no error has occurred */
@@ -1416,10 +1461,11 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
else
data->state.infilesize = 0;
+#ifndef CURL_DISABLE_COOKIES
/* If there is a list of cookie files to read, do it now! */
if(data->state.cookielist)
Curl_cookie_loadfiles(data);
-
+#endif
/* If there is a list of host pairs to deal with */
if(data->state.resolve)
result = Curl_loadhostpairs(data);
@@ -1449,6 +1495,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
data->state.authproxy.picked &= data->state.authproxy.want;
#ifndef CURL_DISABLE_FTP
+ data->state.wildcardmatch = data->set.wildcard_enabled;
if(data->state.wildcardmatch) {
struct WildcardData *wc = &data->wildcard;
if(wc->state < CURLWC_INIT) {
@@ -1562,7 +1609,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
data->state.referer_alloc = FALSE;
}
- /* Make a copy of the URL without crenditals and fragment */
+ /* Make a copy of the URL without credentials and fragment */
u = curl_url();
if(!u)
return CURLE_OUT_OF_MEMORY;
@@ -1590,7 +1637,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
if((type != FOLLOW_RETRY) &&
(data->req.httpcode != 401) && (data->req.httpcode != 407) &&
- Curl_is_absolute_url(newurl, NULL, 0))
+ Curl_is_absolute_url(newurl, NULL, 0, FALSE))
/* If this is not redirect due to a 401 or 407 response and an absolute
URL: don't allow a custom port number */
disallowport = TRUE;
@@ -1599,10 +1646,14 @@ CURLcode Curl_follow(struct Curl_easy *data,
uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl,
(type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME :
((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) |
- CURLU_ALLOW_SPACE);
+ CURLU_ALLOW_SPACE |
+ (data->set.path_as_is ? CURLU_PATH_AS_IS : 0));
if(uc) {
- if(type != FOLLOW_FAKE)
+ if(type != FOLLOW_FAKE) {
+ failf(data, "The redirect target URL could not be parsed: %s",
+ curl_url_strerror(uc));
return Curl_uc_to_curlcode(uc);
+ }
/* the URL could not be parsed for some reason, but since this is FAKE
mode, just duplicate the field as-is */
@@ -1649,7 +1700,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
return Curl_uc_to_curlcode(uc);
}
- p = Curl_builtin_scheme(scheme);
+ p = Curl_builtin_scheme(scheme, CURL_ZERO_TERMINATED);
if(p && (p->protocol != data->info.conn_protocol)) {
infof(data, "Clear auth, redirects scheme from %s to %s",
data->info.conn_scheme, scheme);
@@ -1813,10 +1864,12 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
return CURLE_OK;
if((data->req.bytecount + data->req.headerbytecount == 0) &&
- conn->bits.reuse &&
- (!data->set.opt_no_body
- || (conn->handler->protocol & PROTO_FAMILY_HTTP)) &&
- (data->set.rtspreq != RTSPREQ_RECEIVE))
+ conn->bits.reuse &&
+ (!data->set.opt_no_body || (conn->handler->protocol & PROTO_FAMILY_HTTP))
+#ifndef CURL_DISABLE_RTSP
+ && (data->set.rtspreq != RTSPREQ_RECEIVE)
+#endif
+ )
/* We got no data, we attempted to re-use a connection. For HTTP this
can be a retry so we try again regardless if we expected a body.
For other protocols we only try again only if we expected a body.
@@ -1888,11 +1941,14 @@ Curl_setup_transfer(
struct SingleRequest *k = &data->req;
struct connectdata *conn = data->conn;
struct HTTP *http = data->req.p.http;
- bool httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
- (http->sending == HTTPSEND_REQUEST));
+ bool httpsending;
+
DEBUGASSERT(conn != NULL);
DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
+ httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
+ (http->sending == HTTPSEND_REQUEST));
+
if(conn->bits.multiplex || conn->httpversion == 20 || httpsending) {
/* when multiplexing, the read/write sockets need to be the same! */
conn->sockfd = sockindex == -1 ?
diff --git a/Utilities/cmcurl/lib/transfer.h b/Utilities/cmcurl/lib/transfer.h
index 56d2fd1ee3..65fe68e812 100644
--- a/Utilities/cmcurl/lib/transfer.h
+++ b/Utilities/cmcurl/lib/transfer.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#define Curl_headersep(x) ((((x)==':') || ((x)==';')))
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
index 6b31d4b131..be5ffca2d8 100644
--- a/Utilities/cmcurl/lib/url.c
+++ b/Utilities/cmcurl/lib/url.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -71,10 +73,11 @@
#endif
#elif defined(USE_WIN32_IDN)
-/* prototype for curl_win32_idn_to_ascii() */
-bool curl_win32_idn_to_ascii(const char *in, char **out);
+/* prototype for Curl_win32_idn_to_ascii() */
+bool Curl_win32_idn_to_ascii(const char *in, char **out);
#endif /* USE_LIBIDN2 */
+#include "doh.h"
#include "urldata.h"
#include "netrc.h"
@@ -103,6 +106,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "urlapi-int.h"
#include "system_win32.h"
#include "hsts.h"
+#include "noproxy.h"
/* And now for the protocols */
#include "ftp.h"
@@ -125,7 +129,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "http_proxy.h"
#include "conncache.h"
#include "multihandle.h"
-#include "dotdot.h"
#include "strdup.h"
#include "setopt.h"
#include "altsvc.h"
@@ -147,6 +150,13 @@ static void conn_free(struct connectdata *conn);
# error READBUFFER_SIZE is too small
#endif
+#ifdef USE_UNIX_SOCKETS
+#define UNIX_SOCKET_PREFIX "localhost"
+#endif
+
+/* Reject URLs exceeding this length */
+#define MAX_URL_LEN 0xffff
+
/*
* get_protocol_family()
*
@@ -158,7 +168,7 @@ static void conn_free(struct connectdata *conn);
*
* Returns the family as a single bit protocol identifier.
*/
-static unsigned int get_protocol_family(const struct Curl_handler *h)
+static curl_prot_t get_protocol_family(const struct Curl_handler *h)
{
DEBUGASSERT(h);
DEBUGASSERT(h->family);
@@ -182,6 +192,16 @@ static const struct Curl_handler * const protocols[] = {
&Curl_handler_http,
#endif
+#ifdef USE_WEBSOCKETS
+#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
+ &Curl_handler_wss,
+#endif
+
+#ifndef CURL_DISABLE_HTTP
+ &Curl_handler_ws,
+#endif
+#endif
+
#ifndef CURL_DISABLE_FTP
&Curl_handler_ftp,
#endif
@@ -433,6 +453,7 @@ CURLcode Curl_close(struct Curl_easy **datap)
Curl_safefree(data->info.wouldredirect);
/* this destroys the channel and we cannot use it anymore after this */
+ Curl_resolver_cancel(data);
Curl_resolver_cleanup(data->state.async.resolver);
Curl_http2_cleanup_dependencies(data);
@@ -495,7 +516,6 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
/* use fread as default function to read input */
set->fread_func_set = (curl_read_callback)fread;
set->is_fread_set = 0;
- set->is_fwrite_set = 0;
set->seek_func = ZERO_NULL;
set->seek_client = ZERO_NULL;
@@ -505,7 +525,9 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->maxredirs = -1; /* allow any amount by default */
set->method = HTTPREQ_GET; /* Default HTTP request */
+#ifndef CURL_DISABLE_RTSP
set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
+#endif
#ifndef CURL_DISABLE_FTP
set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
@@ -521,10 +543,12 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->proxyport = 0;
set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
- set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
+#ifndef CURL_DISABLE_PROXY
+ set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
/* SOCKS5 proxy auth defaults to username/password + GSS-API */
set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI;
+#endif
/* make libcurl quiet by default: */
set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
@@ -544,8 +568,8 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
#ifdef USE_TLS_SRP
set->ssl.primary.authtype = CURL_TLSAUTH_NONE;
#endif
- set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
- type */
+ /* defaults to any auth type */
+ set->ssh_auth_types = CURLSSH_AUTH_DEFAULT;
set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
default */
#ifndef CURL_DISABLE_PROXY
@@ -554,11 +578,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->new_file_perms = 0644; /* Default permissions */
set->new_directory_perms = 0755; /* Default permissions */
-
- /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
- define since we internally only use the lower 16 bits for the passed
- in bitmask to not conflict with the private bits */
- set->allowed_protocols = CURLPROTO_ALL;
+ set->allowed_protocols = (curl_prot_t) CURLPROTO_ALL;
set->redir_protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP |
CURLPROTO_FTPS;
@@ -598,22 +618,23 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
#endif
}
+#ifndef CURL_DISABLE_FTP
set->wildcard_enabled = FALSE;
set->chunk_bgn = ZERO_NULL;
set->chunk_end = ZERO_NULL;
+ set->fnmatch = ZERO_NULL;
+#endif
set->tcp_keepalive = FALSE;
set->tcp_keepintvl = 60;
set->tcp_keepidle = 60;
set->tcp_fastopen = FALSE;
set->tcp_nodelay = TRUE;
- set->ssl_enable_npn = TRUE;
set->ssl_enable_alpn = TRUE;
set->expect_100_timeout = 1000L; /* Wait for a second by default. */
set->sep_headers = TRUE; /* separated header lists by default */
set->buffer_size = READBUFFER_SIZE;
set->upload_buffer_size = UPLOADBUFFER_DEFAULT;
set->happy_eyeballs_timeout = CURL_HET_DEFAULT;
- set->fnmatch = ZERO_NULL;
set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT;
set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
set->maxage_conn = 118;
@@ -730,15 +751,6 @@ static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
DEBUGASSERT(data);
infof(data, "Closing connection %ld", conn->connection_id);
-#ifndef USE_HYPER
- if(conn->connect_state && conn->connect_state->prot_save) {
- /* If this was closed with a CONNECT in progress, cleanup this temporary
- struct arrangement */
- data->req.p.http = NULL;
- Curl_safefree(conn->connect_state->prot_save);
- }
-#endif
-
/* possible left-overs from the async name resolvers */
Curl_resolver_cancel(data);
@@ -853,7 +865,7 @@ void Curl_disconnect(struct Curl_easy *data,
/* Cleanup NEGOTIATE connection-related data */
Curl_http_auth_cleanup_negotiate(conn);
- if(conn->bits.connect_only)
+ if(conn->connect_only)
/* treat the connection as dead in CONNECT_ONLY situations */
dead_connection = TRUE;
@@ -937,19 +949,11 @@ socks_proxy_info_matches(const struct proxy_info *data,
/* the user information is case-sensitive
or at least it is not defined as case-insensitive
see https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1 */
- if(!data->user != !needle->user)
- return FALSE;
- /* curl_strequal does a case insentive comparison, so do not use it here! */
- if(data->user &&
- needle->user &&
- strcmp(data->user, needle->user) != 0)
- return FALSE;
- if(!data->passwd != !needle->passwd)
- return FALSE;
- /* curl_strequal does a case insentive comparison, so do not use it here! */
- if(data->passwd &&
- needle->passwd &&
- strcmp(data->passwd, needle->passwd) != 0)
+
+ /* curl_strequal does a case insensitive comparison,
+ so do not use it here! */
+ if(Curl_timestrcmp(data->user, needle->user) ||
+ Curl_timestrcmp(data->passwd, needle->passwd))
return FALSE;
return TRUE;
}
@@ -1100,12 +1104,17 @@ static void prune_dead_connections(struct Curl_easy *data)
}
}
+#ifdef USE_SSH
static bool ssh_config_matches(struct connectdata *one,
struct connectdata *two)
{
return (Curl_safecmp(one->proto.sshc.rsa, two->proto.sshc.rsa) &&
Curl_safecmp(one->proto.sshc.rsa_pub, two->proto.sshc.rsa_pub));
}
+#else
+#define ssh_config_matches(x,y) FALSE
+#endif
+
/*
* Given one filled in connection struct (named needle), this function should
* detect if there already is one that has all the significant details
@@ -1194,7 +1203,7 @@ ConnectionExists(struct Curl_easy *data,
check = curr->ptr;
curr = curr->next;
- if(check->bits.connect_only || check->bits.close)
+ if(check->connect_only || check->bits.close)
/* connect-only or to-be-closed connections will not be reused */
continue;
@@ -1346,10 +1355,10 @@ ConnectionExists(struct Curl_easy *data,
if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
/* This protocol requires credentials per connection,
so verify that we're using the same name and password as well */
- if(strcmp(needle->user, check->user) ||
- strcmp(needle->passwd, check->passwd) ||
- !Curl_safecmp(needle->sasl_authzid, check->sasl_authzid) ||
- !Curl_safecmp(needle->oauth_bearer, check->oauth_bearer)) {
+ if(Curl_timestrcmp(needle->user, check->user) ||
+ Curl_timestrcmp(needle->passwd, check->passwd) ||
+ Curl_timestrcmp(needle->sasl_authzid, check->sasl_authzid) ||
+ Curl_timestrcmp(needle->oauth_bearer, check->oauth_bearer)) {
/* one of them was different */
continue;
}
@@ -1425,8 +1434,8 @@ ConnectionExists(struct Curl_easy *data,
possible. (Especially we must not reuse the same connection if
partway through a handshake!) */
if(wantNTLMhttp) {
- if(strcmp(needle->user, check->user) ||
- strcmp(needle->passwd, check->passwd)) {
+ if(Curl_timestrcmp(needle->user, check->user) ||
+ Curl_timestrcmp(needle->passwd, check->passwd)) {
/* we prefer a credential match, but this is at least a connection
that can be reused and "upgraded" to NTLM */
@@ -1448,8 +1457,10 @@ ConnectionExists(struct Curl_easy *data,
if(!check->http_proxy.user || !check->http_proxy.passwd)
continue;
- if(strcmp(needle->http_proxy.user, check->http_proxy.user) ||
- strcmp(needle->http_proxy.passwd, check->http_proxy.passwd))
+ if(Curl_timestrcmp(needle->http_proxy.user,
+ check->http_proxy.user) ||
+ Curl_timestrcmp(needle->http_proxy.passwd,
+ check->http_proxy.passwd))
continue;
}
else if(check->proxy_ntlm_state != NTLMSTATE_NONE) {
@@ -1621,7 +1632,7 @@ CURLcode Curl_idnconvert_hostname(struct Curl_easy *data,
#elif defined(USE_WIN32_IDN)
char *ace_hostname = NULL;
- if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) {
+ if(Curl_win32_idn_to_ascii(host->name, &ace_hostname)) {
host->encalloc = ace_hostname;
/* change the name pointer to point to the encoded hostname */
host->name = host->encalloc;
@@ -1652,7 +1663,7 @@ void Curl_free_idnconverted_hostname(struct hostname *host)
}
#elif defined(USE_WIN32_IDN)
free(host->encalloc); /* must be freed with free() since this was
- allocated by curl_win32_idn_to_ascii */
+ allocated by Curl_win32_idn_to_ascii */
host->encalloc = NULL;
#else
(void)host;
@@ -1770,19 +1781,15 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
conn->ssl_config.ssl_options = data->set.ssl.primary.ssl_options;
-#ifdef USE_TLS_SRP
-#endif
#ifndef CURL_DISABLE_PROXY
conn->proxy_ssl_config.verifystatus =
data->set.proxy_ssl.primary.verifystatus;
conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
conn->proxy_ssl_config.ssl_options = data->set.proxy_ssl.primary.ssl_options;
-#ifdef USE_TLS_SRP
-#endif
#endif
conn->ip_version = data->set.ipver;
- conn->bits.connect_only = data->set.connect_only;
+ conn->connect_only = data->set.connect_only;
conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
@@ -1826,15 +1833,18 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
}
/* returns the handler if the given scheme is built-in */
-const struct Curl_handler *Curl_builtin_scheme(const char *scheme)
+const struct Curl_handler *Curl_builtin_scheme(const char *scheme,
+ size_t schemelen)
{
const struct Curl_handler * const *pp;
const struct Curl_handler *p;
/* Scan protocol handler table and match against 'scheme'. The handler may
be changed later when the protocol specific setup function is called. */
+ if(schemelen == CURL_ZERO_TERMINATED)
+ schemelen = strlen(scheme);
for(pp = protocols; (p = *pp) != NULL; pp++)
- if(strcasecompare(p->scheme, scheme))
- /* Protocol found in table. Check if allowed */
+ if(strncasecompare(p->scheme, scheme, schemelen) && !p->scheme[schemelen])
+ /* Protocol found in table. */
return p;
return NULL; /* not found */
}
@@ -1844,7 +1854,8 @@ static CURLcode findprotocol(struct Curl_easy *data,
struct connectdata *conn,
const char *protostr)
{
- const struct Curl_handler *p = Curl_builtin_scheme(protostr);
+ const struct Curl_handler *p = Curl_builtin_scheme(protostr,
+ CURL_ZERO_TERMINATED);
if(p && /* Protocol found in table. Check if allowed */
(data->set.allowed_protocols & p->protocol)) {
@@ -1968,7 +1979,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
if(data->set.str[STRING_DEFAULT_PROTOCOL] &&
- !Curl_is_absolute_url(data->state.url, NULL, 0)) {
+ !Curl_is_absolute_url(data->state.url, NULL, 0, TRUE)) {
char *url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL],
data->state.url);
if(!url)
@@ -2012,10 +2023,60 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
if(!strcasecompare("file", data->state.up.scheme))
return CURLE_OUT_OF_MEMORY;
}
+ else if(strlen(data->state.up.hostname) > MAX_URL_LEN) {
+ failf(data, "Too long host name (maximum is %d)", MAX_URL_LEN);
+ return CURLE_URL_MALFORMAT;
+ }
+ hostname = data->state.up.hostname;
+
+ if(hostname && hostname[0] == '[') {
+ /* This looks like an IPv6 address literal. See if there is an address
+ scope. */
+ size_t hlen;
+ conn->bits.ipv6_ip = TRUE;
+ /* cut off the brackets! */
+ hostname++;
+ hlen = strlen(hostname);
+ hostname[hlen - 1] = 0;
+
+ zonefrom_url(uh, data, conn);
+ }
+
+ /* make sure the connect struct gets its own copy of the host name */
+ conn->host.rawalloc = strdup(hostname ? hostname : "");
+ if(!conn->host.rawalloc)
+ return CURLE_OUT_OF_MEMORY;
+ conn->host.name = conn->host.rawalloc;
+
+ /*************************************************************
+ * IDN-convert the hostnames
+ *************************************************************/
+ result = Curl_idnconvert_hostname(data, &conn->host);
+ if(result)
+ return result;
+ if(conn->bits.conn_to_host) {
+ result = Curl_idnconvert_hostname(data, &conn->conn_to_host);
+ if(result)
+ return result;
+ }
+#ifndef CURL_DISABLE_PROXY
+ if(conn->bits.httpproxy) {
+ result = Curl_idnconvert_hostname(data, &conn->http_proxy.host);
+ if(result)
+ return result;
+ }
+ if(conn->bits.socksproxy) {
+ result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host);
+ if(result)
+ return result;
+ }
+#endif
#ifndef CURL_DISABLE_HSTS
+ /* HSTS upgrade */
if(data->hsts && strcasecompare("http", data->state.up.scheme)) {
- if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) {
+ /* This MUST use the IDN decoded name */
+ if(Curl_hsts(data->hsts, conn->host.name, TRUE)) {
char *url;
Curl_safefree(data->state.up.scheme);
uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0);
@@ -2066,7 +2127,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
return Curl_uc_to_curlcode(uc);
}
- if(!data->state.aptr.user) {
+ if(!data->set.str[STRING_USERNAME]) {
/* we don't use the URL API's URL decoder option here since it rejects
control codes and we want to allow them for some schemes in the user
and password fields */
@@ -2101,7 +2162,8 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
else if(uc != CURLUE_NO_OPTIONS)
return Curl_uc_to_curlcode(uc);
- uc = curl_url_get(uh, CURLUPART_PATH, &data->state.up.path, 0);
+ uc = curl_url_get(uh, CURLUPART_PATH, &data->state.up.path,
+ CURLU_URLENCODE);
if(uc)
return Curl_uc_to_curlcode(uc);
@@ -2115,31 +2177,11 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
unsigned long port = strtoul(data->state.up.port, NULL, 10);
conn->port = conn->remote_port =
(data->set.use_port && data->state.allow_port) ?
- (int)data->set.use_port : curlx_ultous(port);
+ data->set.use_port : curlx_ultous(port);
}
(void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0);
- hostname = data->state.up.hostname;
- if(hostname && hostname[0] == '[') {
- /* This looks like an IPv6 address literal. See if there is an address
- scope. */
- size_t hlen;
- conn->bits.ipv6_ip = TRUE;
- /* cut off the brackets! */
- hostname++;
- hlen = strlen(hostname);
- hostname[hlen - 1] = 0;
-
- zonefrom_url(uh, data, conn);
- }
-
- /* make sure the connect struct gets its own copy of the host name */
- conn->host.rawalloc = strdup(hostname ? hostname : "");
- if(!conn->host.rawalloc)
- return CURLE_OUT_OF_MEMORY;
- conn->host.name = conn->host.rawalloc;
-
#ifdef ENABLE_IPV6
if(data->set.scope_id)
/* Override any scope that was set above. */
@@ -2237,83 +2279,6 @@ void Curl_free_request_state(struct Curl_easy *data)
#ifndef CURL_DISABLE_PROXY
-/****************************************************************
-* Checks if the host is in the noproxy list. returns true if it matches
-* and therefore the proxy should NOT be used.
-****************************************************************/
-static bool check_noproxy(const char *name, const char *no_proxy)
-{
- /* no_proxy=domain1.dom,host.domain2.dom
- * (a comma-separated list of hosts which should
- * not be proxied, or an asterisk to override
- * all proxy variables)
- */
- if(no_proxy && no_proxy[0]) {
- size_t tok_start;
- size_t tok_end;
- const char *separator = ", ";
- size_t no_proxy_len;
- size_t namelen;
- char *endptr;
- if(strcasecompare("*", no_proxy)) {
- return TRUE;
- }
-
- /* NO_PROXY was specified and it wasn't just an asterisk */
-
- no_proxy_len = strlen(no_proxy);
- if(name[0] == '[') {
- /* IPv6 numerical address */
- endptr = strchr(name, ']');
- if(!endptr)
- return FALSE;
- name++;
- namelen = endptr - name;
- }
- else
- namelen = strlen(name);
-
- for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
- while(tok_start < no_proxy_len &&
- strchr(separator, no_proxy[tok_start]) != NULL) {
- /* Look for the beginning of the token. */
- ++tok_start;
- }
-
- if(tok_start == no_proxy_len)
- break; /* It was all trailing separator chars, no more tokens. */
-
- for(tok_end = tok_start; tok_end < no_proxy_len &&
- strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
- /* Look for the end of the token. */
- ;
-
- /* To match previous behavior, where it was necessary to specify
- * ".local.com" to prevent matching "notlocal.com", we will leave
- * the '.' off.
- */
- if(no_proxy[tok_start] == '.')
- ++tok_start;
-
- if((tok_end - tok_start) <= namelen) {
- /* Match the last part of the name to the domain we are checking. */
- const char *checkn = name + namelen - (tok_end - tok_start);
- if(strncasecompare(no_proxy + tok_start, checkn,
- tok_end - tok_start)) {
- if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
- /* We either have an exact match, or the previous character is a .
- * so it is within the same domain, so no proxy for this host.
- */
- return TRUE;
- }
- }
- } /* if((tok_end - tok_start) <= namelen) */
- } /* for(tok_start = 0; tok_start < no_proxy_len;
- tok_start = tok_end + 1) */
- } /* NO_PROXY was specified and it wasn't just an asterisk */
-
- return FALSE;
-}
#ifndef CURL_DISABLE_HTTP
/****************************************************************
@@ -2353,7 +2318,7 @@ static char *detect_proxy(struct Curl_easy *data,
/* Now, build <protocol>_proxy and check for such a one to use */
while(*protop)
- *envp++ = (char)tolower((int)*protop++);
+ *envp++ = Curl_raw_tolower(*protop++);
/* append _proxy */
strcpy(envp, "_proxy");
@@ -2411,13 +2376,18 @@ static CURLcode parse_proxy(struct Curl_easy *data,
int port = -1;
char *proxyuser = NULL;
char *proxypasswd = NULL;
- char *host;
+ char *host = NULL;
bool sockstype;
CURLUcode uc;
struct proxy_info *proxyinfo;
CURLU *uhp = curl_url();
CURLcode result = CURLE_OK;
char *scheme = NULL;
+#ifdef USE_UNIX_SOCKETS
+ char *path = NULL;
+ bool is_unix_proxy = FALSE;
+#endif
+
if(!uhp) {
result = CURLE_OUT_OF_MEMORY;
@@ -2542,21 +2512,54 @@ static CURLcode parse_proxy(struct Curl_easy *data,
result = CURLE_OUT_OF_MEMORY;
goto error;
}
- Curl_safefree(proxyinfo->host.rawalloc);
- proxyinfo->host.rawalloc = host;
- if(host[0] == '[') {
- /* this is a numerical IPv6, strip off the brackets */
- size_t len = strlen(host);
- host[len-1] = 0; /* clear the trailing bracket */
- host++;
- zonefrom_url(uhp, data, conn);
+#ifdef USE_UNIX_SOCKETS
+ if(sockstype && strcasecompare(UNIX_SOCKET_PREFIX, host)) {
+ uc = curl_url_get(uhp, CURLUPART_PATH, &path, CURLU_URLDECODE);
+ if(uc) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ /* path will be "/", if no path was was found */
+ if(strcmp("/", path)) {
+ is_unix_proxy = TRUE;
+ free(host);
+ host = aprintf(UNIX_SOCKET_PREFIX"%s", path);
+ if(!host) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ Curl_safefree(proxyinfo->host.rawalloc);
+ proxyinfo->host.rawalloc = host;
+ proxyinfo->host.name = host;
+ host = NULL;
+ }
+ }
+
+ if(!is_unix_proxy) {
+#endif
+ Curl_safefree(proxyinfo->host.rawalloc);
+ proxyinfo->host.rawalloc = host;
+ if(host[0] == '[') {
+ /* this is a numerical IPv6, strip off the brackets */
+ size_t len = strlen(host);
+ host[len-1] = 0; /* clear the trailing bracket */
+ host++;
+ zonefrom_url(uhp, data, conn);
+ }
+ proxyinfo->host.name = host;
+ host = NULL;
+#ifdef USE_UNIX_SOCKETS
}
- proxyinfo->host.name = host;
+#endif
error:
free(proxyuser);
free(proxypasswd);
+ free(host);
free(scheme);
+#ifdef USE_UNIX_SOCKETS
+ free(path);
+#endif
curl_url_cleanup(uhp);
return result;
}
@@ -2644,8 +2647,8 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
}
}
- if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ?
- data->set.str[STRING_NOPROXY] : no_proxy)) {
+ if(Curl_check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ?
+ data->set.str[STRING_NOPROXY] : no_proxy)) {
Curl_safefree(proxy);
Curl_safefree(socksproxy);
}
@@ -2683,16 +2686,16 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
* connection that may exist registered to the same proxy host.
***********************************************************************/
if(proxy || socksproxy) {
+ curl_proxytype ptype = (curl_proxytype)conn->http_proxy.proxytype;
if(proxy) {
- result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
+ result = parse_proxy(data, conn, proxy, ptype);
Curl_safefree(proxy); /* parse_proxy copies the proxy string */
if(result)
goto out;
}
if(socksproxy) {
- result = parse_proxy(data, conn, socksproxy,
- conn->socks_proxy.proxytype);
+ result = parse_proxy(data, conn, socksproxy, ptype);
/* parse_proxy copies the socks proxy string */
Curl_safefree(socksproxy);
if(result)
@@ -2842,15 +2845,15 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len,
(psep && psep > osep ? (size_t)(psep - osep) :
(size_t)(login + len - osep)) - 1 : 0);
- /* Allocate the user portion buffer */
- if(userp && ulen) {
+ /* Allocate the user portion buffer, which can be zero length */
+ if(userp) {
ubuf = malloc(ulen + 1);
if(!ubuf)
result = CURLE_OUT_OF_MEMORY;
}
/* Allocate the password portion buffer */
- if(!result && passwdp && plen) {
+ if(!result && passwdp && psep) {
pbuf = malloc(plen + 1);
if(!pbuf) {
free(ubuf);
@@ -2913,7 +2916,7 @@ static CURLcode parse_remote_port(struct Curl_easy *data,
/* if set, we use this instead of the port possibly given in the URL */
char portbuf[16];
CURLUcode uc;
- conn->remote_port = (unsigned short)data->set.use_port;
+ conn->remote_port = data->set.use_port;
msnprintf(portbuf, sizeof(portbuf), "%d", conn->remote_port);
uc = curl_url_set(data->state.uh, CURLUPART_PORT, portbuf, 0);
if(uc)
@@ -2935,14 +2938,6 @@ static CURLcode override_login(struct Curl_easy *data,
char **passwdp = &conn->passwd;
char **optionsp = &conn->options;
-#ifndef CURL_DISABLE_NETRC
- if(data->set.use_netrc == CURL_NETRC_REQUIRED && data->state.aptr.user) {
- Curl_safefree(*userp);
- Curl_safefree(*passwdp);
- Curl_safefree(data->state.aptr.user); /* disable user+password */
- }
-#endif
-
if(data->set.str[STRING_OPTIONS]) {
free(*optionsp);
*optionsp = strdup(data->set.str[STRING_OPTIONS]);
@@ -2951,29 +2946,31 @@ static CURLcode override_login(struct Curl_easy *data,
}
#ifndef CURL_DISABLE_NETRC
+ if(data->set.use_netrc == CURL_NETRC_REQUIRED) {
+ Curl_safefree(*userp);
+ Curl_safefree(*passwdp);
+ }
conn->bits.netrc = FALSE;
if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) {
- bool netrc_user_changed = FALSE;
- bool netrc_passwd_changed = FALSE;
int ret;
bool url_provided = FALSE;
- if(data->state.up.user) {
- /* there was a user name in the URL */
- userp = &data->state.up.user;
+ if(data->state.aptr.user) {
+ /* there was a user name in the URL. Use the URL decoded version */
+ userp = &data->state.aptr.user;
url_provided = TRUE;
}
ret = Curl_parsenetrc(conn->host.name,
userp, passwdp,
- &netrc_user_changed, &netrc_passwd_changed,
data->set.str[STRING_NETRC_FILE]);
if(ret > 0) {
infof(data, "Couldn't find host %s in the %s file; using defaults",
conn->host.name, data->set.str[STRING_NETRC_FILE]);
}
else if(ret < 0) {
- return CURLE_OUT_OF_MEMORY;
+ failf(data, ".netrc parser error");
+ return CURLE_READ_ERROR;
}
else {
/* set bits.netrc TRUE to remember that we got the name from a .netrc
@@ -2986,29 +2983,35 @@ static CURLcode override_login(struct Curl_easy *data,
conn->user = strdup(*userp);
if(!conn->user)
return CURLE_OUT_OF_MEMORY;
- /* don't update the user name below */
- userp = NULL;
+ }
+ /* no user was set but a password, set a blank user */
+ if(userp && !*userp && *passwdp) {
+ *userp = strdup("");
+ if(!*userp)
+ return CURLE_OUT_OF_MEMORY;
}
}
#endif
/* for updated strings, we update them in the URL */
- if(userp) {
- if(*userp) {
- CURLcode result = Curl_setstropt(&data->state.aptr.user, *userp);
+ if(*userp) {
+ CURLcode result;
+ if(data->state.aptr.user != *userp) {
+ /* nothing to do then */
+ result = Curl_setstropt(&data->state.aptr.user, *userp);
if(result)
return result;
}
- if(data->state.aptr.user) {
- uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user,
- CURLU_URLENCODE);
- if(uc)
- return Curl_uc_to_curlcode(uc);
- if(!*userp) {
- *userp = strdup(data->state.aptr.user);
- if(!*userp)
- return CURLE_OUT_OF_MEMORY;
- }
+ }
+ if(data->state.aptr.user) {
+ uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user,
+ CURLU_URLENCODE);
+ if(uc)
+ return Curl_uc_to_curlcode(uc);
+ if(!*userp) {
+ *userp = strdup(data->state.aptr.user);
+ if(!*userp)
+ return CURLE_OUT_OF_MEMORY;
}
}
if(*passwdp) {
@@ -3361,131 +3364,166 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
return result;
}
-/*************************************************************
- * Resolve the address of the server or proxy
- *************************************************************/
-static CURLcode resolve_server(struct Curl_easy *data,
- struct connectdata *conn,
- bool *async)
+#ifdef USE_UNIX_SOCKETS
+static CURLcode resolve_unix(struct Curl_easy *data,
+ struct connectdata *conn,
+ char *unix_path)
{
- CURLcode result = CURLE_OK;
+ struct Curl_dns_entry *hostaddr = NULL;
+ bool longpath = FALSE;
+
+ DEBUGASSERT(unix_path);
+ DEBUGASSERT(conn->dns_entry == NULL);
+
+ /* Unix domain sockets are local. The host gets ignored, just use the
+ * specified domain socket address. Do not cache "DNS entries". There is
+ * no DNS involved and we already have the filesystem path available. */
+ hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
+ if(!hostaddr)
+ return CURLE_OUT_OF_MEMORY;
+
+ hostaddr->addr = Curl_unix2addr(unix_path, &longpath,
+ conn->bits.abstract_unix_socket);
+ if(!hostaddr->addr) {
+ if(longpath)
+ /* Long paths are not supported for now */
+ failf(data, "Unix socket path too long: '%s'", unix_path);
+ free(hostaddr);
+ return longpath ? CURLE_COULDNT_RESOLVE_HOST : CURLE_OUT_OF_MEMORY;
+ }
+
+ hostaddr->inuse++;
+ conn->dns_entry = hostaddr;
+ return CURLE_OK;
+}
+#endif
+
+#ifndef CURL_DISABLE_PROXY
+static CURLcode resolve_proxy(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool *async)
+{
+ struct Curl_dns_entry *hostaddr = NULL;
+ struct hostname *host;
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ int rc;
- DEBUGASSERT(conn);
- DEBUGASSERT(data);
- /*************************************************************
- * Resolve the name of the server or proxy
- *************************************************************/
- if(conn->bits.reuse)
- /* We're reusing the connection - no need to resolve anything, and
- idnconvert_hostname() was called already in create_conn() for the re-use
- case. */
- *async = FALSE;
+ DEBUGASSERT(conn->dns_entry == NULL);
- else {
- /* this is a fresh connect */
- int rc;
- struct Curl_dns_entry *hostaddr = NULL;
+ host = conn->bits.socksproxy ? &conn->socks_proxy.host :
+ &conn->http_proxy.host;
-#ifdef USE_UNIX_SOCKETS
- if(conn->unix_domain_socket) {
- /* Unix domain sockets are local. The host gets ignored, just use the
- * specified domain socket address. Do not cache "DNS entries". There is
- * no DNS involved and we already have the filesystem path available */
- const char *path = conn->unix_domain_socket;
-
- hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
- if(!hostaddr)
- result = CURLE_OUT_OF_MEMORY;
- else {
- bool longpath = FALSE;
- hostaddr->addr = Curl_unix2addr(path, &longpath,
- conn->bits.abstract_unix_socket);
- if(hostaddr->addr)
- hostaddr->inuse++;
- else {
- /* Long paths are not supported for now */
- if(longpath) {
- failf(data, "Unix socket path too long: '%s'", path);
- result = CURLE_COULDNT_RESOLVE_HOST;
- }
- else
- result = CURLE_OUT_OF_MEMORY;
- free(hostaddr);
- hostaddr = NULL;
- }
- }
- }
- else
+ conn->hostname_resolve = strdup(host->name);
+ if(!conn->hostname_resolve)
+ return CURLE_OUT_OF_MEMORY;
+
+ rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
+ &hostaddr, timeout_ms);
+ conn->dns_entry = hostaddr;
+ if(rc == CURLRESOLV_PENDING)
+ *async = TRUE;
+ else if(rc == CURLRESOLV_TIMEDOUT)
+ return CURLE_OPERATION_TIMEDOUT;
+ else if(!hostaddr) {
+ failf(data, "Couldn't resolve proxy '%s'", host->dispname);
+ return CURLE_COULDNT_RESOLVE_PROXY;
+ }
+
+ return CURLE_OK;
+}
#endif
- if(!CONN_IS_PROXIED(conn)) {
- struct hostname *connhost;
- if(conn->bits.conn_to_host)
- connhost = &conn->conn_to_host;
- else
- connhost = &conn->host;
+static CURLcode resolve_host(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool *async)
+{
+ struct Curl_dns_entry *hostaddr = NULL;
+ struct hostname *connhost;
+ timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
+ int rc;
- /* If not connecting via a proxy, extract the port from the URL, if it is
- * there, thus overriding any defaults that might have been set above. */
- if(conn->bits.conn_to_port)
- conn->port = conn->conn_to_port;
- else
- conn->port = conn->remote_port;
+ DEBUGASSERT(conn->dns_entry == NULL);
- /* Resolve target host right on */
- conn->hostname_resolve = strdup(connhost->name);
- if(!conn->hostname_resolve)
- return CURLE_OUT_OF_MEMORY;
- rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
- &hostaddr, timeout_ms);
- if(rc == CURLRESOLV_PENDING)
- *async = TRUE;
-
- else if(rc == CURLRESOLV_TIMEDOUT) {
- failf(data, "Failed to resolve host '%s' with timeout after %ld ms",
- connhost->dispname,
- Curl_timediff(Curl_now(), data->progress.t_startsingle));
- result = CURLE_OPERATION_TIMEDOUT;
- }
- else if(!hostaddr) {
- failf(data, "Could not resolve host: %s", connhost->dispname);
- result = CURLE_COULDNT_RESOLVE_HOST;
- /* don't return yet, we need to clean up the timeout first */
- }
- }
-#ifndef CURL_DISABLE_PROXY
- else {
- /* This is a proxy that hasn't been resolved yet. */
+ connhost = conn->bits.conn_to_host ? &conn->conn_to_host : &conn->host;
- struct hostname * const host = conn->bits.socksproxy ?
- &conn->socks_proxy.host : &conn->http_proxy.host;
+ /* If not connecting via a proxy, extract the port from the URL, if it is
+ * there, thus overriding any defaults that might have been set above. */
+ conn->port = conn->bits.conn_to_port ? conn->conn_to_port :
+ conn->remote_port;
- /* resolve proxy */
- conn->hostname_resolve = strdup(host->name);
- if(!conn->hostname_resolve)
- return CURLE_OUT_OF_MEMORY;
- rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
- &hostaddr, timeout_ms);
+ /* Resolve target host right on */
+ conn->hostname_resolve = strdup(connhost->name);
+ if(!conn->hostname_resolve)
+ return CURLE_OUT_OF_MEMORY;
- if(rc == CURLRESOLV_PENDING)
- *async = TRUE;
+ rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
+ &hostaddr, timeout_ms);
+ conn->dns_entry = hostaddr;
+ if(rc == CURLRESOLV_PENDING)
+ *async = TRUE;
+ else if(rc == CURLRESOLV_TIMEDOUT) {
+ failf(data, "Failed to resolve host '%s' with timeout after %ld ms",
+ connhost->dispname,
+ Curl_timediff(Curl_now(), data->progress.t_startsingle));
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ else if(!hostaddr) {
+ failf(data, "Could not resolve host: %s", connhost->dispname);
+ return CURLE_COULDNT_RESOLVE_HOST;
+ }
- else if(rc == CURLRESOLV_TIMEDOUT)
- result = CURLE_OPERATION_TIMEDOUT;
+ return CURLE_OK;
+}
- else if(!hostaddr) {
- failf(data, "Couldn't resolve proxy '%s'", host->dispname);
- result = CURLE_COULDNT_RESOLVE_PROXY;
- /* don't return yet, we need to clean up the timeout first */
- }
- }
+/* Perform a fresh resolve */
+static CURLcode resolve_fresh(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool *async)
+{
+#ifdef USE_UNIX_SOCKETS
+ char *unix_path = conn->unix_domain_socket;
+
+#ifndef CURL_DISABLE_PROXY
+ if(!unix_path && conn->socks_proxy.host.name &&
+ !strncmp(UNIX_SOCKET_PREFIX"/",
+ conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX)))
+ unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1;
#endif
- DEBUGASSERT(conn->dns_entry == NULL);
- conn->dns_entry = hostaddr;
+
+ if(unix_path) {
+ conn->transport = TRNSPRT_UNIX;
+ return resolve_unix(data, conn, unix_path);
}
+#endif
- return result;
+#ifndef CURL_DISABLE_PROXY
+ if(CONN_IS_PROXIED(conn))
+ return resolve_proxy(data, conn, async);
+#endif
+
+ return resolve_host(data, conn, async);
+}
+
+/*************************************************************
+ * Resolve the address of the server or proxy
+ *************************************************************/
+static CURLcode resolve_server(struct Curl_easy *data,
+ struct connectdata *conn,
+ bool *async)
+{
+ DEBUGASSERT(conn);
+ DEBUGASSERT(data);
+
+ /* Resolve the name of the server or proxy */
+ if(conn->bits.reuse) {
+ /* We're reusing the connection - no need to resolve anything, and
+ idnconvert_hostname() was called already in create_conn() for the re-use
+ case. */
+ *async = FALSE;
+ return CURLE_OK;
+ }
+
+ return resolve_fresh(data, conn, async);
}
/*
@@ -3502,17 +3540,6 @@ static void reuse_conn(struct Curl_easy *data,
**established** from the primary socket to a remote address. */
char local_ip[MAX_IPADR_LEN] = "";
int local_port = -1;
-#ifndef CURL_DISABLE_PROXY
- Curl_free_idnconverted_hostname(&old_conn->http_proxy.host);
- Curl_free_idnconverted_hostname(&old_conn->socks_proxy.host);
-
- free(old_conn->http_proxy.host.rawalloc);
- free(old_conn->socks_proxy.host.rawalloc);
- Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
-#endif
- /* free the SSL config struct from this connection struct as this was
- allocated in vain and is targeted for destruction */
- Curl_free_primary_ssl_config(&old_conn->ssl_config);
/* get the user+password information from the old_conn struct since it may
* be new for this request even when we re-use an existing connection */
@@ -3543,20 +3570,17 @@ static void reuse_conn(struct Curl_easy *data,
old_conn->http_proxy.passwd = NULL;
old_conn->socks_proxy.passwd = NULL;
}
- Curl_safefree(old_conn->http_proxy.user);
- Curl_safefree(old_conn->socks_proxy.user);
- Curl_safefree(old_conn->http_proxy.passwd);
- Curl_safefree(old_conn->socks_proxy.passwd);
#endif
- /* host can change, when doing keepalive with a proxy or if the case is
- different this time etc */
Curl_free_idnconverted_hostname(&conn->host);
Curl_free_idnconverted_hostname(&conn->conn_to_host);
Curl_safefree(conn->host.rawalloc);
Curl_safefree(conn->conn_to_host.rawalloc);
conn->host = old_conn->host;
+ old_conn->host.rawalloc = NULL;
+ old_conn->host.encalloc = NULL;
conn->conn_to_host = old_conn->conn_to_host;
+ old_conn->conn_to_host.rawalloc = NULL;
conn->conn_to_port = old_conn->conn_to_port;
conn->remote_port = old_conn->remote_port;
Curl_safefree(conn->hostname_resolve);
@@ -3576,15 +3600,7 @@ static void reuse_conn(struct Curl_easy *data,
/* re-use init */
conn->bits.reuse = TRUE; /* yes, we're re-using here */
- Curl_safefree(old_conn->user);
- Curl_safefree(old_conn->passwd);
- Curl_safefree(old_conn->options);
- Curl_safefree(old_conn->localdev);
- Curl_llist_destroy(&old_conn->easyq, NULL);
-
-#ifdef USE_UNIX_SOCKETS
- Curl_safefree(old_conn->unix_domain_socket);
-#endif
+ conn_free(old_conn);
}
/**
@@ -3714,29 +3730,6 @@ static CURLcode create_conn(struct Curl_easy *data,
if(result)
goto out;
- /*************************************************************
- * IDN-convert the hostnames
- *************************************************************/
- result = Curl_idnconvert_hostname(data, &conn->host);
- if(result)
- goto out;
- if(conn->bits.conn_to_host) {
- result = Curl_idnconvert_hostname(data, &conn->conn_to_host);
- if(result)
- goto out;
- }
-#ifndef CURL_DISABLE_PROXY
- if(conn->bits.httpproxy) {
- result = Curl_idnconvert_hostname(data, &conn->http_proxy.host);
- if(result)
- goto out;
- }
- if(conn->bits.socksproxy) {
- result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host);
- if(result)
- goto out;
- }
-#endif
/*************************************************************
* Check whether the host and the "connect to host" are equal.
@@ -3834,8 +3827,6 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE];
data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT];
- data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
- data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
data->set.ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST];
data->set.ssl.primary.cipher_list13 =
@@ -3849,9 +3840,6 @@ static CURLcode create_conn(struct Curl_easy *data,
#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
- data->set.proxy_ssl.primary.random_file =
- data->set.str[STRING_SSL_RANDOM_FILE];
- data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
data->set.proxy_ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
data->set.proxy_ssl.primary.cipher_list13 =
@@ -3934,10 +3922,6 @@ static CURLcode create_conn(struct Curl_easy *data,
* allocated before we can move along and use the previously existing one.
*/
reuse_conn(data, conn, conn_temp);
-#ifdef USE_SSL
- free(conn->ssl_extra);
-#endif
- free(conn); /* we don't need this anymore */
conn = conn_temp;
*in_connect = conn;
@@ -3958,13 +3942,11 @@ static CURLcode create_conn(struct Curl_easy *data,
be able to do that if we have reached the limit of how many
connections we are allowed to open. */
- if(conn->handler->flags & PROTOPT_ALPN_NPN) {
+ if(conn->handler->flags & PROTOPT_ALPN) {
/* The protocol wants it, so set the bits if enabled in the easy handle
(default) */
if(data->set.ssl_enable_alpn)
conn->bits.tls_enable_alpn = TRUE;
- if(data->set.ssl_enable_npn)
- conn->bits.tls_enable_npn = TRUE;
}
if(waitpipe)
diff --git a/Utilities/cmcurl/lib/url.h b/Utilities/cmcurl/lib/url.h
index 59a1c24919..ba4270d523 100644
--- a/Utilities/cmcurl/lib/url.h
+++ b/Utilities/cmcurl/lib/url.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -44,7 +46,8 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len,
char **userptr, char **passwdptr,
char **optionsptr);
-const struct Curl_handler *Curl_builtin_scheme(const char *scheme);
+const struct Curl_handler *Curl_builtin_scheme(const char *scheme,
+ size_t schemelen);
bool Curl_is_ASCII_name(const char *hostname);
CURLcode Curl_idnconvert_hostname(struct Curl_easy *data,
diff --git a/Utilities/cmcurl/lib/urlapi-int.h b/Utilities/cmcurl/lib/urlapi-int.h
index bd6b601751..43a83ef6e4 100644
--- a/Utilities/cmcurl/lib/urlapi-int.h
+++ b/Utilities/cmcurl/lib/urlapi-int.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,13 +20,17 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
-bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen);
+size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen,
+ bool guess_scheme);
#ifdef DEBUGBUILD
-CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, bool);
+CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
+ bool has_scheme);
#endif
#endif /* HEADER_CURL_URLAPI_INT_H */
diff --git a/Utilities/cmcurl/lib/urlapi.c b/Utilities/cmcurl/lib/urlapi.c
index 2a36de6a58..7dac81c85c 100644
--- a/Utilities/cmcurl/lib/urlapi.c
+++ b/Utilities/cmcurl/lib/urlapi.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -25,12 +27,12 @@
#include "urldata.h"
#include "urlapi-int.h"
#include "strcase.h"
-#include "dotdot.h"
#include "url.h"
#include "escape.h"
#include "curl_ctype.h"
#include "inet_pton.h"
#include "inet_ntop.h"
+#include "strdup.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -66,9 +68,6 @@ struct Curl_URL {
char *path;
char *query;
char *fragment;
-
- char *scratch; /* temporary scratch area */
- char *temppath; /* temporary path pointer */
long portnum; /* the numerical version */
};
@@ -86,8 +85,6 @@ static void free_urlhandle(struct Curl_URL *u)
free(u->path);
free(u->query);
free(u->fragment);
- free(u->scratch);
- free(u->temppath);
}
/*
@@ -119,91 +116,50 @@ static const char *find_host_sep(const char *url)
}
/*
- * Decide in an encoding-independent manner whether a character in an
- * URL must be escaped. The same criterion must be used in strlen_url()
- * and strcpy_url().
+ * Decide in an encoding-independent manner whether a character in a URL must
+ * be escaped. This is used in urlencode_str().
*/
static bool urlchar_needs_escaping(int c)
{
return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c));
}
-/*
- * strlen_url() returns the length of the given URL if the spaces within the
- * URL were properly URL encoded.
- * URL encoding should be skipped for host names, otherwise IDN resolution
- * will fail.
- */
-static size_t strlen_url(const char *url, bool relative)
-{
- const unsigned char *ptr;
- size_t newlen = 0;
- bool left = TRUE; /* left side of the ? */
- const unsigned char *host_sep = (const unsigned char *) url;
-
- if(!relative)
- host_sep = (const unsigned char *) find_host_sep(url);
-
- for(ptr = (unsigned char *)url; *ptr; ptr++) {
-
- if(ptr < host_sep) {
- ++newlen;
- continue;
- }
-
- if(*ptr == ' ') {
- if(left)
- newlen += 3;
- else
- newlen++;
- continue;
- }
-
- if (*ptr == '?')
- left = FALSE;
-
- if(urlchar_needs_escaping(*ptr))
- newlen += 2;
-
- newlen++;
- }
-
- return newlen;
-}
-
-/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in
- * the source URL accordingly.
+/* urlencode_str() writes data into an output dynbuf and URL-encodes the
+ * spaces in the source URL accordingly.
+ *
* URL encoding should be skipped for host names, otherwise IDN resolution
* will fail.
*/
-static void strcpy_url(char *output, const char *url, bool relative)
+static CURLUcode urlencode_str(struct dynbuf *o, const char *url,
+ size_t len, bool relative,
+ bool query)
{
/* we must add this with whitespace-replacing */
- bool left = TRUE;
+ bool left = !query;
const unsigned char *iptr;
- char *optr = output;
const unsigned char *host_sep = (const unsigned char *) url;
if(!relative)
host_sep = (const unsigned char *) find_host_sep(url);
for(iptr = (unsigned char *)url; /* read from here */
- *iptr; /* until zero byte */
- iptr++) {
+ len; iptr++, len--) {
if(iptr < host_sep) {
- *optr++ = *iptr;
+ if(Curl_dyn_addn(o, iptr, 1))
+ return CURLUE_OUT_OF_MEMORY;
continue;
}
if(*iptr == ' ') {
if(left) {
- *optr++='%'; /* add a '%' */
- *optr++='2'; /* add a '2' */
- *optr++='0'; /* add a '0' */
+ if(Curl_dyn_addn(o, "%20", 3))
+ return CURLUE_OUT_OF_MEMORY;
+ }
+ else {
+ if(Curl_dyn_addn(o, "+", 1))
+ return CURLUE_OUT_OF_MEMORY;
}
- else
- *optr++='+'; /* add a '+' here */
continue;
}
@@ -211,22 +167,28 @@ static void strcpy_url(char *output, const char *url, bool relative)
left = FALSE;
if(urlchar_needs_escaping(*iptr)) {
- msnprintf(optr, 4, "%%%02x", *iptr);
- optr += 3;
+ if(Curl_dyn_addf(o, "%%%02x", *iptr))
+ return CURLUE_OUT_OF_MEMORY;
+ }
+ else {
+ if(Curl_dyn_addn(o, iptr, 1))
+ return CURLUE_OUT_OF_MEMORY;
}
- else
- *optr++ = *iptr;
}
- *optr = 0; /* null-terminate output buffer */
+ return CURLUE_OK;
}
/*
- * Returns true if the given URL is absolute (as opposed to relative). Returns
- * the scheme in the buffer if TRUE and 'buf' is non-NULL. The buflen must
- * be larger than MAX_SCHEME_LEN if buf is set.
+ * Returns the length of the scheme if the given URL is absolute (as opposed
+ * to relative). Stores the scheme in the buffer if TRUE and 'buf' is
+ * non-NULL. The buflen must be larger than MAX_SCHEME_LEN if buf is set.
+ *
+ * If 'guess_scheme' is TRUE, it means the URL might be provided without
+ * scheme.
*/
-bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
+size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen,
+ bool guess_scheme)
{
int i;
DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN));
@@ -234,8 +196,8 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
if(buf)
buf[0] = 0; /* always leave a defined value in buf */
#ifdef WIN32
- if(STARTS_WITH_DRIVE_PREFIX(url))
- return FALSE;
+ if(guess_scheme && STARTS_WITH_DRIVE_PREFIX(url))
+ return 0;
#endif
for(i = 0; i < MAX_SCHEME_LEN; ++i) {
char s = url[i];
@@ -248,16 +210,22 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
break;
}
}
- if(i && (url[i] == ':') && (url[i + 1] == '/')) {
+ if(i && (url[i] == ':') && ((url[i + 1] == '/') || !guess_scheme)) {
+ /* If this does not guess scheme, the scheme always ends with the colon so
+ that this also detects data: URLs etc. In guessing mode, data: could
+ be the host name "data" with a specified port number. */
+
+ /* the length of the scheme is the name part only */
+ size_t len = i;
if(buf) {
buf[i] = 0;
while(i--) {
- buf[i] = (char)TOLOWER(url[i]);
+ buf[i] = Curl_raw_tolower(url[i]);
}
}
- return TRUE;
+ return len;
}
- return FALSE;
+ return 0;
}
/*
@@ -265,34 +233,26 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
* URL-encodes any spaces.
* The returned pointer must be freed by the caller unless NULL
* (returns NULL on out of memory).
+ *
+ * Note that this function destroys the 'base' string.
*/
-static char *concat_url(const char *base, const char *relurl)
+static char *concat_url(char *base, const char *relurl)
{
/***
TRY to append this new path to the old URL
to the right of the host part. Oh crap, this is doomed to cause
problems in the future...
*/
- char *newest;
+ struct dynbuf newest;
char *protsep;
char *pathsep;
- size_t newlen;
bool host_changed = FALSE;
-
const char *useurl = relurl;
- size_t urllen;
-
- /* we must make our own copy of the URL to play with, as it may
- point to read-only data */
- char *url_clone = strdup(base);
-
- if(!url_clone)
- return NULL; /* skip out of this NOW */
/* protsep points to the start of the host name */
- protsep = strstr(url_clone, "//");
+ protsep = strstr(base, "//");
if(!protsep)
- protsep = url_clone;
+ protsep = base;
else
protsep += 2; /* pass the slashes */
@@ -385,38 +345,24 @@ static char *concat_url(const char *base, const char *relurl)
}
}
- /* If the new part contains a space, this is a mighty stupid redirect
- but we still make an effort to do "right". To the left of a '?'
- letter we replace each space with %20 while it is replaced with '+'
- on the right side of the '?' letter.
- */
- newlen = strlen_url(useurl, !host_changed);
-
- urllen = strlen(url_clone);
-
- newest = malloc(urllen + 1 + /* possible slash */
- newlen + 1 /* zero byte */);
-
- if(!newest) {
- free(url_clone); /* don't leak this */
- return NULL;
- }
+ Curl_dyn_init(&newest, CURL_MAX_INPUT_LENGTH);
/* copy over the root url part */
- memcpy(newest, url_clone, urllen);
+ if(Curl_dyn_add(&newest, base))
+ return NULL;
/* check if we need to append a slash */
if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0]))
;
- else
- newest[urllen++]='/';
+ else {
+ if(Curl_dyn_addn(&newest, "/", 1))
+ return NULL;
+ }
/* then append the new piece on the right side */
- strcpy_url(&newest[urllen], useurl, !host_changed);
-
- free(url_clone);
+ urlencode_str(&newest, useurl, strlen(useurl), !host_changed, FALSE);
- return newest;
+ return Curl_dyn_ptr(&newest);
}
/* scan for byte values < 31 or 127 */
@@ -450,7 +396,7 @@ static bool junkscan(const char *part, unsigned int flags)
*
*/
static CURLUcode parse_hostname_login(struct Curl_URL *u,
- char **hostname,
+ struct dynbuf *host,
unsigned int flags)
{
CURLUcode result = CURLUE_OK;
@@ -460,27 +406,31 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
char *optionsp = NULL;
const struct Curl_handler *h = NULL;
- /* At this point, we're hoping all the other special cases have
- * been taken care of, so conn->host.name is at most
- * [user[:password][;options]]@]hostname
+ /* At this point, we assume all the other special cases have been taken
+ * care of, so the host is at most
+ *
+ * [user[:password][;options]]@]hostname
*
* We need somewhere to put the embedded details, so do that first.
*/
- char *ptr = strchr(*hostname, '@');
- char *login = *hostname;
+ char *login = Curl_dyn_ptr(host);
+ char *ptr;
+ DEBUGASSERT(login);
+
+ ptr = strchr(login, '@');
if(!ptr)
goto out;
/* We will now try to extract the
* possible login information in a string like:
* ftp://user:password@ftp.my.site:8021/README */
- *hostname = ++ptr;
+ ptr++;
/* if this is a known scheme, get some details */
if(u->scheme)
- h = Curl_builtin_scheme(u->scheme);
+ h = Curl_builtin_scheme(u->scheme, CURL_ZERO_TERMINATED);
/* We could use the login information in the URL so extract it. Only parse
options if the handler says we should. Note that 'h' might be NULL! */
@@ -522,6 +472,10 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
u->options = optionsp;
}
+ /* move the name to the start of the host buffer */
+ if(Curl_dyn_tail(host, strlen(ptr)))
+ return CURLUE_OUT_OF_MEMORY;
+
return CURLUE_OK;
out:
@@ -535,13 +489,13 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
return result;
}
-UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
+UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
bool has_scheme)
{
char *portptr = NULL;
char endbracket;
int len;
-
+ char *hostname = Curl_dyn_ptr(host);
/*
* Find the end of an IPv6 address, either on the ']' ending bracket or
* a percent-encoded zone index.
@@ -578,6 +532,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
char *rest;
long port;
char portbuf[7];
+ size_t keep = portptr - hostname;
/* Browser behavior adaptation. If there's a colon with no digits after,
just cut off the name there which makes us ignore the colon and just
@@ -586,15 +541,15 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
Don't do it if the URL has no scheme, to make something that looks like
a scheme not work!
*/
- if(!portptr[1]) {
- *portptr = '\0';
+ Curl_dyn_setlen(host, keep);
+ portptr++;
+ if(!*portptr)
return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER;
- }
- if(!ISDIGIT(portptr[1]))
+ if(!ISDIGIT(*portptr))
return CURLUE_BAD_PORT_NUMBER;
- port = strtol(portptr + 1, &rest, 10); /* Port number must be decimal */
+ port = strtol(portptr, &rest, 10); /* Port number must be decimal */
if(port > 0xffff)
return CURLUE_BAD_PORT_NUMBER;
@@ -602,7 +557,6 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
if(rest[0])
return CURLUE_BAD_PORT_NUMBER;
- *portptr++ = '\0'; /* cut off the name there */
*rest = 0;
/* generate a new port number string to get rid of leading zeroes etc */
msnprintf(portbuf, sizeof(portbuf), "%ld", port);
@@ -615,12 +569,15 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
return CURLUE_OK;
}
-static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
+static CURLUcode hostname_check(struct Curl_URL *u, char *hostname,
+ size_t hlen) /* length of hostname */
{
size_t len;
- size_t hlen = strlen(hostname);
+ DEBUGASSERT(hostname);
- if(hostname[0] == '[') {
+ if(!hostname[0])
+ return CURLUE_NO_HOST;
+ else if(hostname[0] == '[') {
const char *l = "0123456789abcdefABCDEF:.";
if(hlen < 4) /* '[::]' is the shortest possible valid string */
return CURLUE_BAD_IPV6;
@@ -679,13 +636,11 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
}
else {
/* letters from the second string are not ok */
- len = strcspn(hostname, " \r\n\t/:#?!@");
+ len = strcspn(hostname, " \r\n\t/:#?!@{}[]\\$\'\"^`*<>=;,");
if(hlen != len)
/* hostname with bad content */
return CURLUE_BAD_HOSTNAME;
}
- if(!hostname[0])
- return CURLUE_NO_HOST;
return CURLUE_OK;
}
@@ -779,79 +734,230 @@ static bool ipv4_normalize(const char *hostname, char *outp, size_t olen)
return TRUE;
}
-/* return strdup'ed version in 'outp', possibly percent decoded */
-static CURLUcode decode_host(char *hostname, char **outp)
+/* if necessary, replace the host content with a URL decoded version */
+static CURLUcode decode_host(struct dynbuf *host)
{
char *per = NULL;
- if(hostname[0] != '[')
+ const char *hostname = Curl_dyn_ptr(host);
+ if(hostname[0] == '[')
/* only decode if not an ipv6 numerical */
- per = strchr(hostname, '%');
- if(!per) {
- *outp = strdup(hostname);
- if(!*outp)
- return CURLUE_OUT_OF_MEMORY;
- }
+ return CURLUE_OK;
+ per = strchr(hostname, '%');
+ if(!per)
+ /* nothing to decode */
+ return CURLUE_OK;
else {
- /* might be encoded */
+ /* encoded */
size_t dlen;
- CURLcode result = Curl_urldecode(hostname, 0, outp, &dlen, REJECT_CTRL);
+ char *decoded;
+ CURLcode result = Curl_urldecode(hostname, 0, &decoded, &dlen,
+ REJECT_CTRL);
if(result)
return CURLUE_BAD_HOSTNAME;
+ Curl_dyn_reset(host);
+ result = Curl_dyn_addn(host, decoded, dlen);
+ free(decoded);
+ if(result)
+ return CURLUE_OUT_OF_MEMORY;
}
return CURLUE_OK;
}
-static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
+/*
+ * "Remove Dot Segments"
+ * https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4
+ */
+
+/*
+ * dedotdotify()
+ * @unittest: 1395
+ *
+ * This function gets a null-terminated path with dot and dotdot sequences
+ * passed in and strips them off according to the rules in RFC 3986 section
+ * 5.2.4.
+ *
+ * The function handles a query part ('?' + stuff) appended but it expects
+ * that fragments ('#' + stuff) have already been cut off.
+ *
+ * RETURNS
+ *
+ * an allocated dedotdotified output string
+ */
+UNITTEST char *dedotdotify(const char *input, size_t clen);
+UNITTEST char *dedotdotify(const char *input, size_t clen)
{
- char *path;
- bool path_alloced = FALSE;
+ char *out = malloc(clen + 1);
+ char *outptr;
+ const char *orginput = input;
+ char *queryp;
+ if(!out)
+ return NULL; /* out of memory */
+
+ *out = 0; /* null-terminates, for inputs like "./" */
+ outptr = out;
+
+ if(!*input)
+ /* zero length input string, return that */
+ return out;
+
+ /*
+ * To handle query-parts properly, we must find it and remove it during the
+ * dotdot-operation and then append it again at the end to the output
+ * string.
+ */
+ queryp = strchr(input, '?');
+
+ do {
+ bool dotdot = TRUE;
+ if(*input == '.') {
+ /* A. If the input buffer begins with a prefix of "../" or "./", then
+ remove that prefix from the input buffer; otherwise, */
+
+ if(!strncmp("./", input, 2)) {
+ input += 2;
+ clen -= 2;
+ }
+ else if(!strncmp("../", input, 3)) {
+ input += 3;
+ clen -= 3;
+ }
+ /* D. if the input buffer consists only of "." or "..", then remove
+ that from the input buffer; otherwise, */
+
+ else if(!strcmp(".", input) || !strcmp("..", input) ||
+ !strncmp(".?", input, 2) || !strncmp("..?", input, 3)) {
+ *out = 0;
+ break;
+ }
+ else
+ dotdot = FALSE;
+ }
+ else if(*input == '/') {
+ /* B. if the input buffer begins with a prefix of "/./" or "/.", where
+ "." is a complete path segment, then replace that prefix with "/" in
+ the input buffer; otherwise, */
+ if(!strncmp("/./", input, 3)) {
+ input += 2;
+ clen -= 2;
+ }
+ else if(!strcmp("/.", input) || !strncmp("/.?", input, 3)) {
+ *outptr++ = '/';
+ *outptr = 0;
+ break;
+ }
+
+ /* C. if the input buffer begins with a prefix of "/../" or "/..",
+ where ".." is a complete path segment, then replace that prefix with
+ "/" in the input buffer and remove the last segment and its
+ preceding "/" (if any) from the output buffer; otherwise, */
+
+ else if(!strncmp("/../", input, 4)) {
+ input += 3;
+ clen -= 3;
+ /* remove the last segment from the output buffer */
+ while(outptr > out) {
+ outptr--;
+ if(*outptr == '/')
+ break;
+ }
+ *outptr = 0; /* null-terminate where it stops */
+ }
+ else if(!strcmp("/..", input) || !strncmp("/..?", input, 4)) {
+ /* remove the last segment from the output buffer */
+ while(outptr > out) {
+ outptr--;
+ if(*outptr == '/')
+ break;
+ }
+ *outptr++ = '/';
+ *outptr = 0; /* null-terminate where it stops */
+ break;
+ }
+ else
+ dotdot = FALSE;
+ }
+ else
+ dotdot = FALSE;
+
+ if(!dotdot) {
+ /* E. move the first path segment in the input buffer to the end of
+ the output buffer, including the initial "/" character (if any) and
+ any subsequent characters up to, but not including, the next "/"
+ character or the end of the input buffer. */
+
+ do {
+ *outptr++ = *input++;
+ clen--;
+ } while(*input && (*input != '/') && (*input != '?'));
+ *outptr = 0;
+ }
+
+ /* continue until end of input string OR, if there is a terminating
+ query part, stop there */
+ } while(*input && (!queryp || (input < queryp)));
+
+ if(queryp) {
+ size_t qlen;
+ /* There was a query part, append that to the output. */
+ size_t oindex = queryp - orginput;
+ qlen = strlen(&orginput[oindex]);
+ memcpy(outptr, &orginput[oindex], qlen + 1); /* include zero byte */
+ }
+
+ return out;
+}
+
+static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
+{
+ const char *path;
+ size_t pathlen;
bool uncpath = FALSE;
- char *hostname;
char *query = NULL;
char *fragment = NULL;
- CURLUcode result;
- bool url_has_scheme = FALSE;
char schemebuf[MAX_SCHEME_LEN + 1];
const char *schemep = NULL;
size_t schemelen = 0;
size_t urllen;
+ CURLUcode result = CURLUE_OK;
+ size_t fraglen = 0;
+ struct dynbuf host;
DEBUGASSERT(url);
+ Curl_dyn_init(&host, CURL_MAX_INPUT_LENGTH);
+
/*************************************************************
* Parse the URL.
************************************************************/
/* allocate scratch area */
urllen = strlen(url);
- if(urllen > CURL_MAX_INPUT_LENGTH)
+ if(urllen > CURL_MAX_INPUT_LENGTH) {
/* excessive input length */
- return CURLUE_MALFORMED_INPUT;
-
- path = u->scratch = malloc(urllen * 2 + 2);
- if(!path)
- return CURLUE_OUT_OF_MEMORY;
-
- hostname = &path[urllen + 1];
- hostname[0] = 0;
-
- if(Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf))) {
- url_has_scheme = TRUE;
- schemelen = strlen(schemebuf);
+ result = CURLUE_MALFORMED_INPUT;
+ goto fail;
}
+ schemelen = Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf),
+ flags & (CURLU_GUESS_SCHEME|
+ CURLU_DEFAULT_SCHEME));
+
/* handle the file: scheme */
- if(url_has_scheme && !strcmp(schemebuf, "file")) {
- if(urllen <= 6)
+ if(schemelen && !strcmp(schemebuf, "file")) {
+ if(urllen <= 6) {
/* file:/ is not enough to actually be a complete file: URL */
- return CURLUE_BAD_FILE_URL;
+ result = CURLUE_BAD_FILE_URL;
+ goto fail;
+ }
/* path has been allocated large enough to hold this */
- strcpy(path, &url[5]);
+ path = (char *)&url[5];
- u->scheme = strdup("file");
- if(!u->scheme)
- return CURLUE_OUT_OF_MEMORY;
+ schemep = u->scheme = strdup("file");
+ if(!u->scheme) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
/* Extra handling URLs with an authority component (i.e. that start with
* "file://")
@@ -861,7 +967,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
*/
if(path[0] == '/' && path[1] == '/') {
/* swallow the two slashes */
- char *ptr = &path[2];
+ const char *ptr = &path[2];
/*
* According to RFC 8089, a file: URL can be reliably dereferenced if:
@@ -897,13 +1003,17 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
chars, and the delimiting slash character must be appended to the
host name */
path = strpbrk(ptr, "/\\:*?\"<>|");
- if(!path || *path != '/')
- return CURLUE_BAD_FILE_URL;
+ if(!path || *path != '/') {
+ result = CURLUE_BAD_FILE_URL;
+ goto fail;
+ }
len = path - ptr;
if(len) {
- memcpy(hostname, ptr, len);
- hostname[len] = 0;
+ if(Curl_dyn_addn(&host, ptr, len)) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
uncpath = TRUE;
}
@@ -911,7 +1021,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
#else
/* Invalid file://hostname/, expected localhost or 127.0.0.1 or
none */
- return CURLUE_BAD_FILE_URL;
+ result = CURLUE_BAD_FILE_URL;
+ goto fail;
#endif
}
}
@@ -920,7 +1031,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
}
if(!uncpath)
- hostname = NULL; /* no host for file: URLs by default */
+ /* no host for file: URLs by default */
+ Curl_dyn_reset(&host);
#if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__)
/* Don't allow Windows drive letters when not in Windows.
@@ -928,13 +1040,14 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) ||
STARTS_WITH_URL_DRIVE_PREFIX(path)) {
/* File drive letters are only accepted in MSDOS/Windows */
- return CURLUE_BAD_FILE_URL;
+ result = CURLUE_BAD_FILE_URL;
+ goto fail;
}
#else
/* If the path starts with a slash and a drive letter, ditch the slash */
if('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) {
/* This cannot be done with strcpy, as the memory chunks overlap! */
- memmove(path, &path[1], strlen(&path[1]) + 1);
+ path++;
}
#endif
@@ -944,32 +1057,39 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
const char *p;
const char *hostp;
size_t len;
- path[0] = 0;
- if(url_has_scheme) {
+ if(schemelen) {
int i = 0;
p = &url[schemelen + 1];
while(p && (*p == '/') && (i < 4)) {
p++;
i++;
}
- if((i < 1) || (i>3))
- /* less than one or more than three slashes */
- return CURLUE_BAD_SLASHES;
schemep = schemebuf;
- if(!Curl_builtin_scheme(schemep) &&
- !(flags & CURLU_NON_SUPPORT_SCHEME))
- return CURLUE_UNSUPPORTED_SCHEME;
+ if(!Curl_builtin_scheme(schemep, CURL_ZERO_TERMINATED) &&
+ !(flags & CURLU_NON_SUPPORT_SCHEME)) {
+ result = CURLUE_UNSUPPORTED_SCHEME;
+ goto fail;
+ }
- if(junkscan(schemep, flags))
- return CURLUE_BAD_SCHEME;
+ if((i < 1) || (i>3)) {
+ /* less than one or more than three slashes */
+ result = CURLUE_BAD_SLASHES;
+ goto fail;
+ }
+ if(junkscan(schemep, flags)) {
+ result = CURLUE_BAD_SCHEME;
+ goto fail;
+ }
}
else {
/* no scheme! */
- if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME)))
- return CURLUE_BAD_SCHEME;
+ if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME))) {
+ result = CURLUE_BAD_SCHEME;
+ goto fail;
+ }
if(flags & CURLU_DEFAULT_SCHEME)
schemep = DEFAULT_SCHEME;
@@ -986,122 +1106,169 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
len = p - hostp;
if(len) {
- memcpy(hostname, hostp, len);
- hostname[len] = 0;
+ if(Curl_dyn_addn(&host, hostp, len)) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
}
else {
- if(!(flags & CURLU_NO_AUTHORITY))
- return CURLUE_NO_HOST;
+ if(!(flags & CURLU_NO_AUTHORITY)) {
+ result = CURLUE_NO_HOST;
+ goto fail;
+ }
}
- strcpy(path, p);
+ path = (char *)p;
if(schemep) {
u->scheme = strdup(schemep);
- if(!u->scheme)
- return CURLUE_OUT_OF_MEMORY;
+ if(!u->scheme) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
}
}
- if((flags & CURLU_URLENCODE) && path[0]) {
- /* worst case output length is 3x the original! */
- char *newp = malloc(strlen(path) * 3);
- if(!newp)
- return CURLUE_OUT_OF_MEMORY;
- path_alloced = TRUE;
- strcpy_url(newp, path, TRUE); /* consider it relative */
- u->temppath = path = newp;
- }
-
fragment = strchr(path, '#');
if(fragment) {
- *fragment++ = 0;
- if(junkscan(fragment, flags))
- return CURLUE_BAD_FRAGMENT;
- if(fragment[0]) {
- u->fragment = strdup(fragment);
- if(!u->fragment)
- return CURLUE_OUT_OF_MEMORY;
+ fraglen = strlen(fragment);
+ if(fraglen > 1) {
+ /* skip the leading '#' in the copy but include the terminating null */
+ u->fragment = Curl_memdup(fragment + 1, fraglen);
+ if(!u->fragment) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
+
+ if(junkscan(u->fragment, flags)) {
+ result = CURLUE_BAD_FRAGMENT;
+ goto fail;
+ }
}
}
query = strchr(path, '?');
- if(query) {
- *query++ = 0;
- if(junkscan(query, flags))
- return CURLUE_BAD_QUERY;
- /* done even if the query part is a blank string */
- u->query = strdup(query);
- if(!u->query)
- return CURLUE_OUT_OF_MEMORY;
- }
+ if(query && (!fragment || (query < fragment))) {
+ size_t qlen = strlen(query) - fraglen; /* includes '?' */
+ pathlen = strlen(path) - qlen - fraglen;
+ if(qlen > 1) {
+ if(qlen && (flags & CURLU_URLENCODE)) {
+ struct dynbuf enc;
+ Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
+ /* skip the leading question mark */
+ if(urlencode_str(&enc, query + 1, qlen - 1, TRUE, TRUE)) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
+ u->query = Curl_dyn_ptr(&enc);
+ }
+ else {
+ u->query = Curl_memdup(query + 1, qlen);
+ if(!u->query) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
+ u->query[qlen - 1] = 0;
+ }
- if(junkscan(path, flags))
- return CURLUE_BAD_PATH;
+ if(junkscan(u->query, flags)) {
+ result = CURLUE_BAD_QUERY;
+ goto fail;
+ }
+ }
+ else {
+ /* single byte query */
+ u->query = strdup("");
+ if(!u->query) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
+ }
+ }
+ else
+ pathlen = strlen(path) - fraglen;
+
+ if(pathlen && (flags & CURLU_URLENCODE)) {
+ struct dynbuf enc;
+ Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
+ if(urlencode_str(&enc, path, pathlen, TRUE, FALSE)) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
+ pathlen = Curl_dyn_len(&enc);
+ path = u->path = Curl_dyn_ptr(&enc);
+ }
- if(!path[0])
- /* if there's no path left set, unset */
+ if(!pathlen) {
+ /* there is no path left, unset */
path = NULL;
+ }
else {
+ if(!u->path) {
+ u->path = Curl_memdup(path, pathlen + 1);
+ if(!u->path) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
+ u->path[pathlen] = 0;
+ path = u->path;
+ }
+ else if(flags & CURLU_URLENCODE)
+ /* it might have encoded more than just the path so cut it */
+ u->path[pathlen] = 0;
+
+ if(junkscan(u->path, flags)) {
+ result = CURLUE_BAD_PATH;
+ goto fail;
+ }
+
if(!(flags & CURLU_PATH_AS_IS)) {
/* remove ../ and ./ sequences according to RFC3986 */
- char *newp = Curl_dedotdotify(path);
- if(!newp)
- return CURLUE_OUT_OF_MEMORY;
-
- if(strcmp(newp, path)) {
- /* if we got a new version */
- if(path_alloced)
- Curl_safefree(u->temppath);
- u->temppath = path = newp;
- path_alloced = TRUE;
+ char *newp = dedotdotify((char *)path, pathlen);
+ if(!newp) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
}
- else
- free(newp);
+ free(u->path);
+ u->path = newp;
}
-
- u->path = path_alloced?path:strdup(path);
- if(!u->path)
- return CURLUE_OUT_OF_MEMORY;
- u->temppath = NULL; /* used now */
}
- if(hostname) {
+ if(Curl_dyn_len(&host)) {
char normalized_ipv4[sizeof("255.255.255.255") + 1];
/*
* Parse the login details and strip them out of the host name.
*/
- result = parse_hostname_login(u, &hostname, flags);
+ result = parse_hostname_login(u, &host, flags);
+ if(!result)
+ result = Curl_parse_port(u, &host, schemelen);
if(result)
- return result;
+ goto fail;
- result = Curl_parse_port(u, hostname, url_has_scheme);
- if(result)
- return result;
-
- if(junkscan(hostname, flags))
- return CURLUE_BAD_HOSTNAME;
+ if(junkscan(Curl_dyn_ptr(&host), flags)) {
+ result = CURLUE_BAD_HOSTNAME;
+ goto fail;
+ }
- if(0 == strlen(hostname) && (flags & CURLU_NO_AUTHORITY)) {
- /* Skip hostname check, it's allowed to be empty. */
- u->host = strdup("");
+ if(ipv4_normalize(Curl_dyn_ptr(&host),
+ normalized_ipv4, sizeof(normalized_ipv4))) {
+ Curl_dyn_reset(&host);
+ if(Curl_dyn_add(&host, normalized_ipv4)) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
}
else {
- if(ipv4_normalize(hostname, normalized_ipv4, sizeof(normalized_ipv4)))
- u->host = strdup(normalized_ipv4);
- else {
- result = decode_host(hostname, &u->host);
- if(result)
- return result;
- result = hostname_check(u, u->host);
- if(result)
- return result;
- }
+ result = decode_host(&host);
+ if(!result)
+ result = hostname_check(u, Curl_dyn_ptr(&host), Curl_dyn_len(&host));
+ if(result)
+ goto fail;
}
- if(!u->host)
- return CURLUE_OUT_OF_MEMORY;
+
if((flags & CURLU_GUESS_SCHEME) && !schemep) {
+ const char *hostname = Curl_dyn_ptr(&host);
/* legacy curl-style guess based on host name */
if(checkprefix("ftp.", hostname))
schemep = "ftp";
@@ -1119,27 +1286,26 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
schemep = "http";
u->scheme = strdup(schemep);
- if(!u->scheme)
- return CURLUE_OUT_OF_MEMORY;
+ if(!u->scheme) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
+ }
+ }
+ }
+ else if(flags & CURLU_NO_AUTHORITY) {
+ /* allowed to be empty. */
+ if(Curl_dyn_add(&host, "")) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto fail;
}
}
- Curl_safefree(u->scratch);
- Curl_safefree(u->temppath);
-
- return CURLUE_OK;
-}
+ u->host = Curl_dyn_ptr(&host);
-/*
- * Parse the URL and set the relevant members of the Curl_URL struct.
- */
-static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
-{
- CURLUcode result = seturl(url, u, flags);
- if(result) {
- free_urlhandle(u);
- memset(u, 0, sizeof(struct Curl_URL));
- }
+ return result;
+ fail:
+ Curl_dyn_free(&host);
+ free_urlhandle(u);
return result;
}
@@ -1157,8 +1323,6 @@ static CURLUcode parseurl_and_replace(const char *url, CURLU *u,
free_urlhandle(u);
*u = tmpurl;
}
- else
- free_urlhandle(&tmpurl);
return result;
}
@@ -1257,7 +1421,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
/* there's no stored port number, but asked to deliver
a default one for the scheme */
const struct Curl_handler *h =
- Curl_builtin_scheme(u->scheme);
+ Curl_builtin_scheme(u->scheme, CURL_ZERO_TERMINATED);
if(h) {
msnprintf(portbuf, sizeof(portbuf), "%u", h->defport);
ptr = portbuf;
@@ -1267,7 +1431,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
/* there is a stored port number, but ask to inhibit if
it matches the default one for the scheme */
const struct Curl_handler *h =
- Curl_builtin_scheme(u->scheme);
+ Curl_builtin_scheme(u->scheme, CURL_ZERO_TERMINATED);
if(h && (h->defport == u->portnum) &&
(flags & CURLU_NO_DEFAULT_PORT))
ptr = NULL;
@@ -1313,7 +1477,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
else
return CURLUE_NO_SCHEME;
- h = Curl_builtin_scheme(scheme);
+ h = Curl_builtin_scheme(scheme, CURL_ZERO_TERMINATED);
if(!port && (flags & CURLU_DEFAULT_PORT)) {
/* there's no stored port number, but asked to deliver
a default one for the scheme */
@@ -1336,14 +1500,13 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
if(u->host[0] == '[') {
if(u->zoneid) {
/* make it '[ host %25 zoneid ]' */
+ struct dynbuf enc;
size_t hostlen = strlen(u->host);
- size_t alen = hostlen + 3 + strlen(u->zoneid) + 1;
- allochost = malloc(alen);
- if(!allochost)
+ Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
+ if(Curl_dyn_addf(&enc, "%.*s%%25%s]", (int)hostlen - 1, u->host,
+ u->zoneid))
return CURLUE_OUT_OF_MEMORY;
- memcpy(allochost, u->host, hostlen - 1);
- msnprintf(&allochost[hostlen - 1], alen - hostlen + 1,
- "%%25%s]", u->zoneid);
+ allochost = Curl_dyn_ptr(&enc);
}
}
else if(urlencode) {
@@ -1354,32 +1517,32 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
else {
/* only encode '%' in output host name */
char *host = u->host;
- size_t pcount = 0;
+ bool percent = FALSE;
/* first, count number of percents present in the name */
while(*host) {
- if(*host == '%')
- pcount++;
+ if(*host == '%') {
+ percent = TRUE;
+ break;
+ }
host++;
}
- /* if there were percents, encode the host name */
- if(pcount) {
- size_t hostlen = strlen(u->host);
- size_t alen = hostlen + 2 * pcount + 1;
- char *o = allochost = malloc(alen);
- if(!allochost)
- return CURLUE_OUT_OF_MEMORY;
-
+ /* if there were percent(s), encode the host name */
+ if(percent) {
+ struct dynbuf enc;
+ CURLcode result;
+ Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
host = u->host;
while(*host) {
- if(*host == '%') {
- memcpy(o, "%25", 3);
- o += 3;
- host++;
- continue;
- }
- *o++ = *host++;
+ if(*host == '%')
+ result = Curl_dyn_addn(&enc, "%25", 3);
+ else
+ result = Curl_dyn_addn(&enc, host, 1);
+ if(result)
+ return CURLUE_OUT_OF_MEMORY;
+ host++;
}
- *o = '\0';
+ free(u->host);
+ u->host = Curl_dyn_ptr(&enc);
}
}
@@ -1412,13 +1575,15 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
break;
}
if(ptr) {
- *part = strdup(ptr);
+ size_t partlen = strlen(ptr);
+ size_t i = 0;
+ *part = Curl_memdup(ptr, partlen + 1);
if(!*part)
return CURLUE_OUT_OF_MEMORY;
if(plusdecode) {
/* convert + to space */
- char *plus;
- for(plus = *part; *plus; ++plus) {
+ char *plus = *part;
+ for(i = 0; i < partlen; ++plus, i++) {
if(*plus == '+')
*plus = ' ';
}
@@ -1435,7 +1600,18 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
return CURLUE_URLDECODE;
}
*part = decoded;
+ partlen = dlen;
}
+ if(urlencode) {
+ struct dynbuf enc;
+ Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
+ if(urlencode_str(&enc, *part, partlen, TRUE,
+ what == CURLUPART_QUERY))
+ return CURLUE_OUT_OF_MEMORY;
+ free(*part);
+ *part = Curl_dyn_ptr(&enc);
+ }
+
return CURLUE_OK;
}
else
@@ -1497,6 +1673,10 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
if(storep && *storep) {
Curl_safefree(*storep);
}
+ else if(!storep) {
+ free_urlhandle(u);
+ memset(u, 0, sizeof(struct Curl_URL));
+ }
return CURLUE_OK;
}
@@ -1507,7 +1687,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_BAD_SCHEME;
if(!(flags & CURLU_NON_SUPPORT_SCHEME) &&
/* verify that it is a fine scheme */
- !Curl_builtin_scheme(part))
+ !Curl_builtin_scheme(part, CURL_ZERO_TERMINATED))
return CURLUE_UNSUPPORTED_SCHEME;
storep = &u->scheme;
urlencode = FALSE; /* never */
@@ -1573,7 +1753,9 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
/* if the new thing is absolute or the old one is not
* (we could not get an absolute url in 'oldurl'),
* then replace the existing with the new. */
- if(Curl_is_absolute_url(part, NULL, 0)
+ if(Curl_is_absolute_url(part, NULL, 0,
+ flags & (CURLU_GUESS_SCHEME|
+ CURLU_DEFAULT_SCHEME))
|| curl_url_get(u, CURLUPART_URL, &oldurl, flags)) {
return parseurl_and_replace(part, u, flags);
}
@@ -1603,14 +1785,16 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
if(urlencode) {
const unsigned char *i;
- char *o;
- char *enc = malloc(nalloc * 3 + 1); /* for worst case! */
- if(!enc)
- return CURLUE_OUT_OF_MEMORY;
- for(i = (const unsigned char *)part, o = enc; *i; i++) {
+ struct dynbuf enc;
+
+ Curl_dyn_init(&enc, nalloc * 3 + 1);
+
+ for(i = (const unsigned char *)part; *i; i++) {
+ CURLcode result;
if((*i == ' ') && plusencode) {
- *o = '+';
- o++;
+ result = Curl_dyn_addn(&enc, "+", 1);
+ if(result)
+ return CURLUE_OUT_OF_MEMORY;
}
else if(Curl_isunreserved(*i) ||
((*i == '/') && urlskipslash) ||
@@ -1618,16 +1802,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
if((*i == '=') && equalsencode)
/* only skip the first equals sign */
equalsencode = FALSE;
- *o = *i;
- o++;
+ result = Curl_dyn_addn(&enc, i, 1);
+ if(result)
+ return CURLUE_OUT_OF_MEMORY;
}
else {
- msnprintf(o, 4, "%%%02x", *i);
- o += 3;
+ result = Curl_dyn_addf(&enc, "%%%02x", *i);
+ if(result)
+ return CURLUE_OUT_OF_MEMORY;
}
}
- *o = 0; /* null-terminate */
- newp = enc;
+ newp = Curl_dyn_ptr(&enc);
}
else {
char *p;
@@ -1639,8 +1824,8 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
/* make sure percent encoded are lower case */
if((*p == '%') && ISXDIGIT(p[1]) && ISXDIGIT(p[2]) &&
(ISUPPER(p[1]) || ISUPPER(p[2]))) {
- p[1] = (char)TOLOWER(p[1]);
- p[2] = (char)TOLOWER(p[2]);
+ p[1] = Curl_raw_tolower(p[1]);
+ p[2] = Curl_raw_tolower(p[2]);
p += 3;
}
else
@@ -1649,34 +1834,41 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
}
if(appendquery) {
- /* Append the string onto the old query. Add a '&' separator if none is
- present at the end of the exsting query already */
+ /* Append the 'newp' string onto the old query. Add a '&' separator if
+ none is present at the end of the existing query already */
+
size_t querylen = u->query ? strlen(u->query) : 0;
bool addamperand = querylen && (u->query[querylen -1] != '&');
if(querylen) {
- size_t newplen = strlen(newp);
- char *p = malloc(querylen + addamperand + newplen + 1);
- if(!p) {
- free((char *)newp);
- return CURLUE_OUT_OF_MEMORY;
+ struct dynbuf enc;
+ Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
+
+ if(Curl_dyn_addn(&enc, u->query, querylen)) /* add original query */
+ goto nomem;
+
+ if(addamperand) {
+ if(Curl_dyn_addn(&enc, "&", 1))
+ goto nomem;
}
- strcpy(p, u->query); /* original query */
- if(addamperand)
- p[querylen] = '&'; /* ampersand */
- strcpy(&p[querylen + addamperand], newp); /* new suffix */
+ if(Curl_dyn_add(&enc, newp))
+ goto nomem;
free((char *)newp);
free(*storep);
- *storep = p;
+ *storep = Curl_dyn_ptr(&enc);
return CURLUE_OK;
+ nomem:
+ free((char *)newp);
+ return CURLUE_OUT_OF_MEMORY;
}
}
if(what == CURLUPART_HOST) {
- if(0 == strlen(newp) && (flags & CURLU_NO_AUTHORITY)) {
+ size_t n = strlen(newp);
+ if(!n && (flags & CURLU_NO_AUTHORITY)) {
/* Skip hostname check, it's allowed to be empty. */
}
else {
- if(hostname_check(u, (char *)newp)) {
+ if(hostname_check(u, (char *)newp, n)) {
free((char *)newp);
return CURLUE_BAD_HOSTNAME;
}
diff --git a/Utilities/cmcurl/lib/urldata.h b/Utilities/cmcurl/lib/urldata.h
index 584434d774..1d430b5e88 100644
--- a/Utilities/cmcurl/lib/urldata.h
+++ b/Utilities/cmcurl/lib/urldata.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* This file is for lib internal stuff */
@@ -51,6 +53,33 @@
#define PORT_GOPHER 70
#define PORT_MQTT 1883
+#ifdef USE_WEBSOCKETS
+/* CURLPROTO_GOPHERS (29) is the highest publicly used protocol bit number,
+ * the rest are internal information. If we use higher bits we only do this on
+ * platforms that have a >= 64 bit type and then we use such a type for the
+ * protocol fields in the protocol handler.
+ */
+#define CURLPROTO_WS (1<<30)
+#define CURLPROTO_WSS ((curl_prot_t)1<<31)
+#else
+#define CURLPROTO_WS 0
+#define CURLPROTO_WSS 0
+#endif
+
+/* This should be undefined once we need bit 32 or higher */
+#define PROTO_TYPE_SMALL
+
+#ifndef PROTO_TYPE_SMALL
+typedef curl_off_t curl_prot_t;
+#else
+typedef unsigned int curl_prot_t;
+#endif
+
+/* This mask is for all the old protocols that are provided and defined in the
+ public header and shall exclude protocols added since which are not exposed
+ in the API */
+#define CURLPROTO_MASK (0x3ffffff)
+
#define DICT_MATCH "/MATCH:"
#define DICT_MATCH2 "/M:"
#define DICT_MATCH3 "/FIND:"
@@ -64,7 +93,8 @@
/* Convenience defines for checking protocols or their SSL based version. Each
protocol handler should only ever have a single CURLPROTO_ in its protocol
field. */
-#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS)
+#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_WS| \
+ CURLPROTO_WSS)
#define PROTO_FAMILY_FTP (CURLPROTO_FTP|CURLPROTO_FTPS)
#define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S)
#define PROTO_FAMILY_SMB (CURLPROTO_SMB|CURLPROTO_SMBS)
@@ -155,10 +185,10 @@ typedef CURLcode (*Curl_datastream)(struct Curl_easy *data,
# endif
#endif
-#ifdef HAVE_LIBSSH2_H
+#ifdef USE_LIBSSH2
#include <libssh2.h>
#include <libssh2_sftp.h>
-#endif /* HAVE_LIBSSH2_H */
+#endif /* USE_LIBSSH2 */
#define READBUFFER_SIZE CURL_MAX_WRITE_SIZE
#define READBUFFER_MAX CURL_MAX_READ_SIZE
@@ -180,15 +210,6 @@ typedef CURLcode (*Curl_datastream)(struct Curl_easy *data,
#define GOOD_EASY_HANDLE(x) \
((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
-/* the type we use for storing a single boolean bit */
-#ifdef _MSC_VER
-typedef bool bit;
-#define BIT(x) bool x
-#else
-typedef unsigned int bit;
-#define BIT(x) bit x:1
-#endif
-
#ifdef HAVE_GSSAPI
/* Types needed for krb5-ftp connections */
struct krb5buffer {
@@ -248,8 +269,6 @@ struct ssl_primary_config {
char *CAfile; /* certificate to verify peer against */
char *issuercert; /* optional issuer certificate filename */
char *clientcert;
- char *random_file; /* path to file containing "random" data */
- char *egdsocket; /* path to file containing the EGD daemon socket */
char *cipher_list; /* list of ciphers to use */
char *cipher_list13; /* list of TLS 1.3 cipher suites to use */
char *pinned_key;
@@ -327,11 +346,11 @@ struct digestdata {
char *nonce;
char *cnonce;
char *realm;
- int algo;
char *opaque;
char *qop;
char *algorithm;
int nc; /* nonce count */
+ unsigned char algo;
BIT(stale); /* set true for re-negotiation */
BIT(userhash);
#endif
@@ -516,9 +535,7 @@ struct ConnectBits {
connection */
BIT(multiplex); /* connection is multiplexed */
BIT(tcp_fastopen); /* use TCP Fast Open */
- BIT(tls_enable_npn); /* TLS NPN extension? */
BIT(tls_enable_alpn); /* TLS ALPN extension? */
- BIT(connect_only);
#ifndef CURL_DISABLE_DOH
BIT(doh);
#endif
@@ -563,7 +580,7 @@ struct Curl_async {
struct Curl_dns_entry *dns;
struct thread_data *tdata;
void *resolver; /* resolver state, if it is used in the URL state -
- ares_channel f.e. */
+ ares_channel e.g. */
int port;
int status; /* if done is TRUE, this is the status from the callback */
BIT(done); /* set TRUE when the lookup is complete */
@@ -584,8 +601,9 @@ enum expect100 {
enum upgrade101 {
UPGR101_INIT, /* default state */
- UPGR101_REQUESTED, /* upgrade requested */
- UPGR101_RECEIVED, /* response received */
+ UPGR101_WS, /* upgrade to WebSockets requested */
+ UPGR101_H2, /* upgrade to HTTP/2 requested */
+ UPGR101_RECEIVED, /* 101 response received */
UPGR101_WORKING /* talking upgraded protocol */
};
@@ -607,23 +625,6 @@ enum doh_slots {
DOH_PROBE_SLOTS
};
-/* one of these for each DoH request */
-struct dnsprobe {
- CURL *easy;
- int dnstype;
- unsigned char dohbuffer[512];
- size_t dohlen;
- struct dynbuf serverdoh;
-};
-
-struct dohdata {
- struct curl_slist *headers;
- struct dnsprobe probe[DOH_PROBE_SLOTS];
- unsigned int pending; /* still outstanding requests */
- int port;
- const char *host;
-};
-
/*
* Request specific data in the easy handle (Curl_easy). Previously,
* these members were on the connectdata struct but since a conn struct may
@@ -707,6 +708,7 @@ struct SingleRequest {
#ifndef CURL_DISABLE_DOH
struct dohdata *doh; /* DoH specific data for this request */
#endif
+ unsigned char setcookies;
BIT(header); /* incoming data has HTTP header */
BIT(content_range); /* set TRUE if Content-Range: was found */
BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding
@@ -804,10 +806,10 @@ struct Curl_handler {
void (*attach)(struct Curl_easy *data, struct connectdata *conn);
int defport; /* Default port. */
- unsigned int protocol; /* See CURLPROTO_* - this needs to be the single
- specific protocol bit */
- unsigned int family; /* single bit for protocol family; basically the
- non-TLS name of the protocol this is */
+ curl_prot_t protocol; /* See CURLPROTO_* - this needs to be the single
+ specific protocol bit */
+ curl_prot_t family; /* single bit for protocol family; basically the
+ non-TLS name of the protocol this is */
unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */
};
@@ -828,7 +830,7 @@ struct Curl_handler {
url query strings (?foo=bar) ! */
#define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per
request instead of per connection */
-#define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */
+#define PROTOPT_ALPN (1<<8) /* set ALPN for this */
#define PROTOPT_STREAM (1<<9) /* a protocol with individual logical streams */
#define PROTOPT_URLOPTIONS (1<<10) /* allow options part in the userinfo field
of the URL */
@@ -864,7 +866,8 @@ struct postponed_data {
struct proxy_info {
struct hostname host;
long port;
- curl_proxytype proxytype; /* what kind of proxy that is in use */
+ unsigned char proxytype; /* curl_proxytype: what kind of proxy that is in
+ use */
char *user; /* proxy user name string, allocated */
char *passwd; /* proxy password string, allocated */
};
@@ -903,6 +906,11 @@ struct connstate {
unsigned char *outp; /* send from this pointer */
};
+#define TRNSPRT_TCP 3
+#define TRNSPRT_UDP 4
+#define TRNSPRT_QUIC 5
+#define TRNSPRT_UNIX 6
+
/*
* The connectdata struct contains all fields and variables that should be
* unique for an entire connection.
@@ -940,15 +948,6 @@ struct connectdata {
cache entry remains locked. It gets unlocked in multi_done() */
struct Curl_addrinfo *ip_addr;
struct Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
-#ifdef ENABLE_IPV6
- unsigned int scope_id; /* Scope id for IPv6 */
-#endif
-
- enum {
- TRNSPRT_TCP = 3,
- TRNSPRT_UDP = 4,
- TRNSPRT_QUIC = 5
- } transport;
#ifdef ENABLE_QUIC
struct quicsocket hequic[2]; /* two, for happy eyeballs! */
@@ -964,13 +963,6 @@ struct connectdata {
struct proxy_info socks_proxy;
struct proxy_info http_proxy;
#endif
- int port; /* which port to use locally - to connect to */
- int remote_port; /* the remote port, not the proxy port! */
- int conn_to_port; /* the remote port to connect to. valid only if
- bits.conn_to_port is set */
- unsigned short secondary_port; /* secondary socket remote port to connect to
- (ftp) */
-
/* 'primary_ip' and 'primary_port' get filled with peer's numerical
ip address and port number whenever an outgoing connection is
*attempted* from the primary socket to a remote address. When more
@@ -979,14 +971,11 @@ struct connectdata {
these are updated with data which comes directly from the socket. */
char primary_ip[MAX_IPADR_LEN];
- unsigned char ip_version; /* copied from the Curl_easy at creation time */
-
char *user; /* user name string, allocated */
char *passwd; /* password string, allocated */
char *options; /* options string, allocated */
char *sasl_authzid; /* authorization identity string, allocated */
char *oauth_bearer; /* OAUTH2 bearer, allocated */
- unsigned char httpversion; /* the HTTP version*10 reported by the server */
struct curltime now; /* "current" time */
struct curltime created; /* creation time */
struct curltime lastused; /* when returned to the connection cache */
@@ -1013,8 +1002,6 @@ struct connectdata {
#endif
struct ConnectBits bits; /* various state-flags for this connection */
- /* The field below gets set in Curl_connecthost */
- int num_addr; /* number of addresses to try to connect to */
/* connecttime: when connect() is called on the current IP address. Used to
be able to track when to move on to try next IP - but only when the multi
interface is used. */
@@ -1042,9 +1029,9 @@ struct connectdata {
#ifdef HAVE_GSSAPI
BIT(sec_complete); /* if Kerberos is enabled for this connection */
- enum protection_level command_prot;
- enum protection_level data_prot;
- enum protection_level request_data_prot;
+ unsigned char command_prot; /* enum protection_level */
+ unsigned char data_prot; /* enum protection_level */
+ unsigned char request_data_prot; /* enum protection_level */
size_t buffer_size;
struct krb5buffer in_buffer;
void *app_data;
@@ -1091,18 +1078,38 @@ struct connectdata {
struct dynbuf trailer;
union {
+#ifndef CURL_DISABLE_FTP
struct ftp_conn ftpc;
+#endif
+#ifndef CURL_DISABLE_HTTP
struct http_conn httpc;
+#endif
+#ifdef USE_SSH
struct ssh_conn sshc;
+#endif
+#ifndef CURL_DISABLE_TFTP
struct tftp_state_data *tftpc;
+#endif
+#ifndef CURL_DISABLE_IMAP
struct imap_conn imapc;
+#endif
+#ifndef CURL_DISABLE_POP3
struct pop3_conn pop3c;
+#endif
+#ifndef CURL_DISABLE_SMTP
struct smtp_conn smtpc;
+#endif
+#ifndef CURL_DISABLE_RTSP
struct rtsp_conn rtspc;
+#endif
+#ifndef CURL_DISABLE_SMB
struct smb_conn smbc;
+#endif
void *rtmp;
struct ldapconninfo *ldapc;
+#ifndef CURL_DISABLE_MQTT
struct mqtt_conn mqtt;
+#endif
} proto;
struct http_connect_state *connect_state; /* for HTTP CONNECT */
@@ -1123,12 +1130,27 @@ struct connectdata {
int localportrange;
int cselect_bits; /* bitmask of socket events */
int waitfor; /* current READ/WRITE bits to wait for */
- int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */
-
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
int socks5_gssapi_enctype;
#endif
+ /* The field below gets set in Curl_connecthost */
+ int num_addr; /* number of addresses to try to connect to */
+ int port; /* which port to use locally - to connect to */
+ int remote_port; /* the remote port, not the proxy port! */
+ int conn_to_port; /* the remote port to connect to. valid only if
+ bits.conn_to_port is set */
+#ifdef ENABLE_IPV6
+ unsigned int scope_id; /* Scope id for IPv6 */
+#endif
unsigned short localport;
+ unsigned short secondary_port; /* secondary socket remote port to connect to
+ (ftp) */
+ unsigned char alpn; /* APLN TLS negotiated protocol, a CURL_HTTP_VERSION*
+ value */
+ unsigned char transport; /* one of the TRNSPRT_* defines */
+ unsigned char ip_version; /* copied from the Curl_easy at creation time */
+ unsigned char httpversion; /* the HTTP version*10 reported by the server */
+ unsigned char connect_only;
};
/* The end of connectdata. */
@@ -1288,6 +1310,7 @@ typedef enum {
EXPIRE_TIMEOUT,
EXPIRE_TOOFAST,
EXPIRE_QUIC,
+ EXPIRE_FTP_ACCEPT,
EXPIRE_LAST /* not an actual timer, used as a marker only */
} expire_id;
@@ -1341,7 +1364,7 @@ struct UrlState {
This is strdup()ed data. */
char *first_host;
int first_remote_port;
- unsigned int first_remote_protocol;
+ curl_prot_t first_remote_protocol;
int retrycount; /* number of retries on a new connection */
struct Curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
@@ -1356,9 +1379,10 @@ struct UrlState {
/* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */
void (*prev_signal)(int sig);
#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
struct digestdata digest; /* state data for host Digest auth */
struct digestdata proxydigest; /* state data for proxy Digest auth */
-
+#endif
struct auth authhost; /* auth details for host */
struct auth authproxy; /* auth details for proxy */
#ifdef USE_CURL_ASYNC
@@ -1374,7 +1398,7 @@ struct UrlState {
struct Curl_llist timeoutlist; /* list of pending timeouts */
struct time_node expires[EXPIRE_LAST]; /* nodes for each expire type */
- /* a place to store the most recently set FTP entrypath */
+ /* a place to store the most recently set (S)FTP entrypath */
char *most_recent_ftp_entrypath;
unsigned char httpwant; /* when non-zero, a specific HTTP version requested
to be used in the library's request(s) */
@@ -1393,30 +1417,37 @@ struct UrlState {
this syntax. */
curl_off_t resume_from; /* continue [ftp] transfer from here */
+#ifndef CURL_DISABLE_RTSP
/* This RTSP state information survives requests and connections */
long rtsp_next_client_CSeq; /* the session's next client CSeq */
long rtsp_next_server_CSeq; /* the session's next server CSeq */
long rtsp_CSeq_recv; /* most recent CSeq received */
+#endif
curl_off_t infilesize; /* size of file to upload, -1 means unknown.
Copied from set.filesize at start of operation */
-
+#if defined(USE_HTTP2) || defined(USE_HTTP3)
size_t drain; /* Increased when this stream has data to read, even if its
socket is not necessarily is readable. Decreased when
checked. */
+#endif
curl_read_callback fread_func; /* read callback/function */
void *in; /* CURLOPT_READDATA */
-
+#ifdef USE_HTTP2
struct Curl_easy *stream_depends_on;
int stream_weight;
+#endif
CURLU *uh; /* URL handle for the current parsed URL */
struct urlpieces up;
- Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
+ unsigned char httpreq; /* Curl_HttpReq; what kind of HTTP request (if any)
+ is this */
char *url; /* work URL, copied from UserDefined */
char *referer; /* referer string */
+#ifndef CURL_DISABLE_COOKIES
struct curl_slist *cookielist; /* list of cookie files set by
curl_easy_setopt(COOKIEFILE) calls */
+#endif
struct curl_slist *resolve; /* set to point to the set.resolve list when
this should be dealt with in pretransfer */
#ifndef CURL_DISABLE_HTTP
@@ -1425,9 +1456,10 @@ struct UrlState {
headers */
struct Curl_llist httphdrs; /* received headers */
struct curl_header headerout; /* for external purposes */
-#endif
+ struct Curl_header_store *prevhead; /* the latest added header */
trailers_state trailers_state; /* whether we are sending trailers
- and what stage are we at */
+ and what stage are we at */
+#endif
#ifdef USE_HYPER
bool hconnect; /* set if a CONNECT request */
CURLcode hresult; /* used to pass return codes back from hyper callbacks */
@@ -1471,7 +1503,6 @@ struct UrlState {
is always set TRUE when curl_easy_perform() is called. */
BIT(authproblem); /* TRUE if there's some problem authenticating */
/* set after initial USER failure, to prevent an authentication loop */
- BIT(ftp_trying_alternative);
BIT(wildcardmatch); /* enable wildcard matching */
BIT(expect100header); /* TRUE if we added Expect: 100-continue */
BIT(disableexpect); /* TRUE if Expect: is disabled due to a previous
@@ -1548,8 +1579,6 @@ enum dupstring {
STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */
STRING_SSL_CIPHER13_LIST, /* list of TLS 1.3 ciphers to use */
STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */
- STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */
- STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
STRING_USERAGENT, /* User-Agent string */
STRING_SSL_CRLFILE, /* crl file to check certificate */
STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */
@@ -1632,16 +1661,15 @@ struct UserDefined {
void *out; /* CURLOPT_WRITEDATA */
void *in_set; /* CURLOPT_READDATA */
void *writeheader; /* write the header to this if non-NULL */
- void *rtp_out; /* write RTP to this if non-NULL */
- long use_port; /* which port to use (when not using default) */
+ unsigned short use_port; /* which port to use (when not using default) */
unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */
unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */
+#ifndef CURL_DISABLE_PROXY
unsigned long socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */
+#endif
long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1
for infinity */
- int keep_post; /* keep POSTs as POSTs after a 30x request; each
- bit represents a request, from 301 to 303 */
void *postfields; /* if POST, set the fields' values here */
curl_seek_callback seek_func; /* function that seeks the input */
curl_off_t postfieldsize; /* if POST, this might have a size to use instead
@@ -1679,16 +1707,17 @@ struct UserDefined {
#endif
void *progress_client; /* pointer to pass to the progress callback */
void *ioctl_client; /* pointer to pass to the ioctl callback */
- long timeout; /* in milliseconds, 0 means no timeout */
- long connecttimeout; /* in milliseconds, 0 means no timeout */
- long accepttimeout; /* in milliseconds, 0 means no timeout */
- long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */
- long server_response_timeout; /* in milliseconds, 0 means no timeout */
+ unsigned int timeout; /* ms, 0 means no timeout */
+ unsigned int connecttimeout; /* ms, 0 means no timeout */
+ unsigned int happy_eyeballs_timeout; /* ms, 0 is a valid value */
+ unsigned int server_response_timeout; /* ms, 0 means no timeout */
long maxage_conn; /* in seconds, max idle time to allow a connection that
is to be reused */
long maxlifetime_conn; /* in seconds, max time since creation to allow a
connection that is to be reused */
+#ifndef CURL_DISABLE_TFTP
long tftp_blksize; /* in bytes, 0 means use default */
+#endif
curl_off_t filesize; /* size of file to upload, -1 means unknown */
long low_speed_limit; /* bytes/second */
long low_speed_time; /* number of seconds */
@@ -1708,15 +1737,17 @@ struct UserDefined {
the transfer on source host */
struct curl_slist *source_postquote; /* in 3rd party transfer mode - after
the transfer on source host */
+#ifndef CURL_DISABLE_TELNET
struct curl_slist *telnet_options; /* linked list of telnet options */
+#endif
struct curl_slist *resolve; /* list of names to add/remove from
DNS cache */
struct curl_slist *connect_to; /* list of host:port mappings to override
the hostname and port to connect to */
- curl_TimeCond timecondition; /* kind of time/date comparison */
- curl_proxytype proxytype; /* what kind of proxy that is in use */
time_t timevalue; /* what time to compare with */
- Curl_HttpReq method; /* what kind of HTTP request (if any) is this */
+ unsigned char timecondition; /* kind of time comparison: curl_TimeCond */
+ unsigned char proxytype; /* what kind of proxy: curl_proxytype */
+ unsigned char method; /* what kind of HTTP request: Curl_HttpReq */
unsigned char httpwant; /* when non-zero, a specific HTTP version requested
to be used in the library's request(s) */
struct ssl_config_data ssl; /* user defined SSL stuff */
@@ -1724,8 +1755,8 @@ struct UserDefined {
struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */
#endif
struct ssl_general_config general_ssl; /* general user defined SSL stuff */
- long dns_cache_timeout; /* DNS cache timeout */
- long buffer_size; /* size of receive buffer to use */
+ int dns_cache_timeout; /* DNS cache timeout (seconds) */
+ unsigned int buffer_size; /* size of receive buffer to use */
unsigned int upload_buffer_size; /* size of upload buffer to use,
keep it >= CURL_MAX_WRITE_SIZE */
void *private_data; /* application-private data */
@@ -1734,36 +1765,46 @@ struct UserDefined {
file 0 - whatever, 1 - v2, 2 - v6 */
curl_off_t max_filesize; /* Maximum file size to download */
#ifndef CURL_DISABLE_FTP
- curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */
- curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
- curl_ftpccc ftp_ccc; /* FTP CCC options */
+ unsigned char ftp_filemethod; /* how to get to a file: curl_ftpfile */
+ unsigned char ftpsslauth; /* what AUTH XXX to try: curl_ftpauth */
+ unsigned char ftp_ccc; /* FTP CCC options: curl_ftpccc */
+ unsigned int accepttimeout; /* in milliseconds, 0 means no timeout */
+#endif
+ /* Desppie the name ftp_create_missing_dirs is for FTP(S) and SFTP
+ 1 - create directories that don't exist
+ 2 - the same but also allow MKD to fail once
+ */
+ unsigned char ftp_create_missing_dirs;
+#ifdef USE_LIBSSH2
+ curl_sshhostkeycallback ssh_hostkeyfunc; /* hostkey check callback */
+ void *ssh_hostkeyfunc_userp; /* custom pointer to callback */
#endif
- int ftp_create_missing_dirs; /* 1 - create directories that don't exist
- 2 - the same but also allow MKD to fail once
- */
+
curl_sshkeycallback ssh_keyfunc; /* key matching callback */
void *ssh_keyfunc_userp; /* custom pointer to callback */
#ifndef CURL_DISABLE_NETRC
- enum CURL_NETRC_OPTION
- use_netrc; /* defined in include/curl.h */
+ unsigned char use_netrc; /* enum CURL_NETRC_OPTION values */
#endif
curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
IMAP or POP3 or others! */
- long new_file_perms; /* Permissions to use when creating remote files */
- long new_directory_perms; /* Permissions to use when creating remote dirs */
- long ssh_auth_types; /* allowed SSH auth types */
+ unsigned int new_file_perms; /* when creating remote files */
+ unsigned int new_directory_perms; /* when creating remote dirs */
+ int ssh_auth_types; /* allowed SSH auth types */
char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
struct curl_blob *blobs[BLOB_LAST];
#ifdef ENABLE_IPV6
unsigned int scope_id; /* Scope id for IPv6 */
#endif
- long allowed_protocols;
- long redir_protocols;
- long mime_options; /* Mime option flags. */
- struct curl_slist *mail_rcpt; /* linked list of mail recipients */
+ curl_prot_t allowed_protocols;
+ curl_prot_t redir_protocols;
+ unsigned int mime_options; /* Mime option flags. */
+
+#ifndef CURL_DISABLE_RTSP
+ void *rtp_out; /* write RTP to this if non-NULL */
/* Common RTSP header options */
Curl_RtspReq rtspreq; /* RTSP request type */
- long rtspversion; /* like httpversion, for RTSP */
+#endif
+#ifndef CURL_DISABLE_FTP
curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer
starts */
curl_chunk_end_callback chunk_end; /* called after part transferring
@@ -1771,38 +1812,48 @@ struct UserDefined {
curl_fnmatch_callback fnmatch; /* callback to decide which file corresponds
to pattern (e.g. if WILDCARDMATCH is on) */
void *fnmatch_data;
-
+#endif
long gssapi_delegation; /* GSS-API credential delegation, see the
documentation of CURLOPT_GSSAPI_DELEGATION */
- long tcp_keepidle; /* seconds in idle before sending keepalive probe */
- long tcp_keepintvl; /* seconds between TCP keepalive probes */
+ int tcp_keepidle; /* seconds in idle before sending keepalive probe */
+ int tcp_keepintvl; /* seconds between TCP keepalive probes */
size_t maxconnects; /* Max idle connections in the connection cache */
long expect_100_timeout; /* in milliseconds */
+#ifdef USE_HTTP2
struct Curl_easy *stream_depends_on;
int stream_weight;
struct Curl_http2_dep *stream_dependents;
-
+#endif
curl_resolver_start_callback resolver_start; /* optional callback called
before resolver start */
void *resolver_start_client; /* pointer to pass to resolver start callback */
long upkeep_interval_ms; /* Time between calls for connection upkeep. */
multidone_func fmultidone;
+#ifndef CURL_DISABLE_DOH
struct Curl_easy *dohfor; /* this is a DoH request for that transfer */
+#endif
CURLU *uh; /* URL handle for the current parsed URL */
void *trailer_data; /* pointer to pass to trailer data callback */
curl_trailer_callback trailer_callback; /* trailing data callback */
+ char keep_post; /* keep POSTs as POSTs after a 30x request; each
+ bit represents a request, from 301 to 303 */
+#ifndef CURL_DISABLE_SMTP
+ struct curl_slist *mail_rcpt; /* linked list of mail recipients */
+ BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some
+ recipients */
+#endif
+ unsigned char connect_only; /* make connection/request, then let
+ application use the socket */
BIT(is_fread_set); /* has read callback been set to non-NULL? */
- BIT(is_fwrite_set); /* has write callback been set to non-NULL? */
- BIT(free_referer); /* set TRUE if 'referer' points to a string we
- allocated */
+#ifndef CURL_DISABLE_TFTP
BIT(tftp_no_options); /* do not send TFTP options requests */
+#endif
BIT(sep_headers); /* handle host and proxy headers separately */
BIT(cookiesession); /* new cookie session? */
BIT(crlf); /* convert crlf on ftp upload(?) */
- BIT(strip_path_slash); /* strip off initial slash from path */
BIT(ssh_compression); /* enable SSH compression */
/* Here follows boolean settings that define how to behave during
@@ -1820,6 +1871,7 @@ struct UserDefined {
BIT(ftp_use_pret); /* if PRET is to be used before PASV or not */
BIT(ftp_skip_ip); /* skip the IP address the FTP server passes on to
us */
+ BIT(wildcard_enabled); /* enable wildcard matching */
#endif
BIT(hide_progress); /* don't use the progress meter */
BIT(http_fail_on_error); /* fail on HTTP error codes >= 400 */
@@ -1840,7 +1892,6 @@ struct UserDefined {
BIT(no_signal); /* do not use any signal/alarm handler */
BIT(tcp_nodelay); /* whether to enable TCP_NODELAY or not */
BIT(ignorecl); /* ignore content length */
- BIT(connect_only); /* make connection, let application use the socket */
BIT(http_te_skip); /* pass the raw body data to the user, even when
transfer-encoded (chunked, compressed) */
BIT(http_ce_skip); /* pass the raw body data to the user, even when
@@ -1851,10 +1902,8 @@ struct UserDefined {
BIT(socks5_gssapi_nec); /* Flag to support NEC SOCKS5 server */
#endif
BIT(sasl_ir); /* Enable/disable SASL initial response */
- BIT(wildcard_enabled); /* enable wildcard matching */
BIT(tcp_keepalive); /* use TCP keepalives */
BIT(tcp_fastopen); /* use TCP Fast Open */
- BIT(ssl_enable_npn); /* TLS NPN extension? */
BIT(ssl_enable_alpn);/* TLS ALPN extension? */
BIT(path_as_is); /* allow dotdots? */
BIT(pipewait); /* wait for multiplex status before starting a new
@@ -1874,8 +1923,9 @@ struct UserDefined {
BIT(doh_verifystatus); /* DoH certificate status verification */
#endif
BIT(http09_allowed); /* allow HTTP/0.9 responses */
- BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some
- recipients */
+#ifdef USE_WEBSOCKETS
+ BIT(ws_raw_mode);
+#endif
};
struct Names {
@@ -1937,10 +1987,12 @@ struct Curl_easy {
#endif
struct SingleRequest req; /* Request-specific data */
struct UserDefined set; /* values set by the libcurl user */
+#ifndef CURL_DISABLE_COOKIES
struct CookieInfo *cookies; /* the cookies, read from files and servers.
NOTE that the 'cookie' field in the
UserDefined struct defines if the "engine"
is to be used or not. */
+#endif
#ifndef CURL_DISABLE_HSTS
struct hsts *hsts;
#endif
diff --git a/Utilities/cmcurl/lib/vauth/cleartext.c b/Utilities/cmcurl/lib/vauth/cleartext.c
index d17e16f108..b82b171467 100644
--- a/Utilities/cmcurl/lib/vauth/cleartext.c
+++ b/Utilities/cmcurl/lib/vauth/cleartext.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC4616 PLAIN authentication
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
*
diff --git a/Utilities/cmcurl/lib/vauth/cram.c b/Utilities/cmcurl/lib/vauth/cram.c
index 9ddb0ac379..475d31b8d7 100644
--- a/Utilities/cmcurl/lib/vauth/cram.c
+++ b/Utilities/cmcurl/lib/vauth/cram.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC2195 CRAM-MD5 authentication
*
***************************************************************************/
diff --git a/Utilities/cmcurl/lib/vauth/digest.c b/Utilities/cmcurl/lib/vauth/digest.c
index d4616095da..f945e8b6c9 100644
--- a/Utilities/cmcurl/lib/vauth/digest.c
+++ b/Utilities/cmcurl/lib/vauth/digest.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC2831 DIGEST-MD5 authentication
* RFC7616 DIGEST-SHA256, DIGEST-SHA512-256 authentication
*
@@ -47,6 +49,15 @@
#include "curl_memory.h"
#include "memdebug.h"
+#define SESSION_ALGO 1 /* for algos with this bit set */
+
+#define ALGO_MD5 0
+#define ALGO_MD5SESS (ALGO_MD5 | SESSION_ALGO)
+#define ALGO_SHA256 2
+#define ALGO_SHA256SESS (ALGO_SHA256 | SESSION_ALGO)
+#define ALGO_SHA512_256 4
+#define ALGO_SHA512_256SESS (ALGO_SHA512_256 | SESSION_ALGO)
+
#if !defined(USE_WINDOWS_SSPI)
#define DIGEST_QOP_VALUE_AUTH (1 << 0)
#define DIGEST_QOP_VALUE_AUTH_INT (1 << 1)
@@ -79,44 +90,50 @@ bool Curl_auth_digest_get_pair(const char *str, char *value, char *content,
}
for(c = DIGEST_MAX_CONTENT_LENGTH - 1; *str && c--; str++) {
- switch(*str) {
- case '\\':
- if(!escape) {
- /* possibly the start of an escaped quote */
- escape = TRUE;
- *content++ = '\\'; /* Even though this is an escape character, we still
- store it as-is in the target buffer */
- continue;
- }
- break;
-
- case ',':
- if(!starts_with_quote) {
- /* This signals the end of the content if we didn't get a starting
- quote and then we do "sloppy" parsing */
- c = 0; /* the end */
- continue;
- }
- break;
-
- case '\r':
- case '\n':
- /* end of string */
- c = 0;
- continue;
+ if(!escape) {
+ switch(*str) {
+ case '\\':
+ if(starts_with_quote) {
+ /* the start of an escaped quote */
+ escape = TRUE;
+ continue;
+ }
+ break;
+
+ case ',':
+ if(!starts_with_quote) {
+ /* This signals the end of the content if we didn't get a starting
+ quote and then we do "sloppy" parsing */
+ c = 0; /* the end */
+ continue;
+ }
+ break;
- case '\"':
- if(!escape && starts_with_quote) {
+ case '\r':
+ case '\n':
/* end of string */
+ if(starts_with_quote)
+ return FALSE; /* No closing quote */
c = 0;
continue;
+
+ case '\"':
+ if(starts_with_quote) {
+ /* end of string */
+ c = 0;
+ continue;
+ }
+ else
+ return FALSE;
+ break;
}
- break;
}
escape = FALSE;
*content++ = *str;
}
+ if(escape)
+ return FALSE; /* No character after backslash */
*content = 0;
*endptr = str;
@@ -365,7 +382,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
if(!(qop_values & DIGEST_QOP_VALUE_AUTH))
return CURLE_BAD_CONTENT_ENCODING;
- /* Generate 32 random hex chars, 32 bytes + 1 zero termination */
+ /* Generate 32 random hex chars, 32 bytes + 1 null-termination */
result = Curl_rand_hex(data, (unsigned char *)cnonce, sizeof(cnonce));
if(result)
return result;
@@ -504,7 +521,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
char content[DIGEST_MAX_CONTENT_LENGTH];
/* Pass all additional spaces here */
- while(*chlg && ISSPACE(*chlg))
+ while(*chlg && ISBLANK(*chlg))
chlg++;
/* Extract a value=content pair */
@@ -543,6 +560,9 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
token = strtok_r(tmp, ",", &tok_buf);
while(token) {
+ /* Pass additional spaces here */
+ while(*token && ISBLANK(*token))
+ token++;
if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
foundAuth = TRUE;
}
@@ -575,17 +595,17 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
return CURLE_OUT_OF_MEMORY;
if(strcasecompare(content, "MD5-sess"))
- digest->algo = CURLDIGESTALGO_MD5SESS;
+ digest->algo = ALGO_MD5SESS;
else if(strcasecompare(content, "MD5"))
- digest->algo = CURLDIGESTALGO_MD5;
+ digest->algo = ALGO_MD5;
else if(strcasecompare(content, "SHA-256"))
- digest->algo = CURLDIGESTALGO_SHA256;
+ digest->algo = ALGO_SHA256;
else if(strcasecompare(content, "SHA-256-SESS"))
- digest->algo = CURLDIGESTALGO_SHA256SESS;
+ digest->algo = ALGO_SHA256SESS;
else if(strcasecompare(content, "SHA-512-256"))
- digest->algo = CURLDIGESTALGO_SHA512_256;
+ digest->algo = ALGO_SHA512_256;
else if(strcasecompare(content, "SHA-512-256-SESS"))
- digest->algo = CURLDIGESTALGO_SHA512_256SESS;
+ digest->algo = ALGO_SHA512_256SESS;
else
return CURLE_BAD_CONTENT_ENCODING;
}
@@ -602,7 +622,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
break; /* We're done here */
/* Pass all additional spaces here */
- while(*chlg && ISSPACE(*chlg))
+ while(*chlg && ISBLANK(*chlg))
chlg++;
/* Allow the list to be comma-separated */
@@ -620,6 +640,10 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
if(!digest->nonce)
return CURLE_BAD_CONTENT_ENCODING;
+ /* "<algo>-sess" protocol versions require "auth" or "auth-int" qop */
+ if(!digest->qop && (digest->algo & SESSION_ALGO))
+ return CURLE_BAD_CONTENT_ENCODING;
+
return CURLE_OK;
}
@@ -664,6 +688,8 @@ static CURLcode auth_create_digest_http_message(
char *cnonce = NULL;
size_t cnonce_sz = 0;
char *userp_quoted;
+ char *realm_quoted;
+ char *nonce_quoted;
char *response = NULL;
char *hashthis = NULL;
char *tmp = NULL;
@@ -687,7 +713,7 @@ static CURLcode auth_create_digest_http_message(
}
if(digest->userhash) {
- hashthis = aprintf("%s:%s", userp, digest->realm);
+ hashthis = aprintf("%s:%s", userp, digest->realm ? digest->realm : "");
if(!hashthis)
return CURLE_OUT_OF_MEMORY;
@@ -707,7 +733,8 @@ static CURLcode auth_create_digest_http_message(
unq(nonce-value) ":" unq(cnonce-value)
*/
- hashthis = aprintf("%s:%s:%s", userp, digest->realm, passwdp);
+ hashthis = aprintf("%s:%s:%s", userp, digest->realm ? digest->realm : "",
+ passwdp);
if(!hashthis)
return CURLE_OUT_OF_MEMORY;
@@ -715,9 +742,7 @@ static CURLcode auth_create_digest_http_message(
free(hashthis);
convert_to_ascii(hashbuf, ha1);
- if(digest->algo == CURLDIGESTALGO_MD5SESS ||
- digest->algo == CURLDIGESTALGO_SHA256SESS ||
- digest->algo == CURLDIGESTALGO_SHA512_256SESS) {
+ if(digest->algo & SESSION_ALGO) {
/* nonce and cnonce are OUTSIDE the hash */
tmp = aprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce);
if(!tmp)
@@ -786,16 +811,33 @@ static CURLcode auth_create_digest_http_message(
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
Digest parameters are all quoted strings. Username which is provided by
- the user will need double quotes and backslashes within it escaped. For
- the other fields, this shouldn't be an issue. realm, nonce, and opaque
- are copied as is from the server, escapes and all. cnonce is generated
- with web-safe characters. uri is already percent encoded. nc is 8 hex
+ the user will need double quotes and backslashes within it escaped.
+ realm, nonce, and opaque will need backslashes as well as they were
+ de-escaped when copied from request header. cnonce is generated with
+ web-safe characters. uri is already percent encoded. nc is 8 hex
characters. algorithm and qop with standard values only contain web-safe
characters.
*/
userp_quoted = auth_digest_string_quoted(digest->userhash ? userh : userp);
if(!userp_quoted)
return CURLE_OUT_OF_MEMORY;
+ if(digest->realm)
+ realm_quoted = auth_digest_string_quoted(digest->realm);
+ else {
+ realm_quoted = malloc(1);
+ if(realm_quoted)
+ realm_quoted[0] = 0;
+ }
+ if(!realm_quoted) {
+ free(userp_quoted);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ nonce_quoted = auth_digest_string_quoted(digest->nonce);
+ if(!nonce_quoted) {
+ free(realm_quoted);
+ free(userp_quoted);
+ return CURLE_OUT_OF_MEMORY;
+ }
if(digest->qop) {
response = aprintf("username=\"%s\", "
@@ -807,18 +849,16 @@ static CURLcode auth_create_digest_http_message(
"qop=%s, "
"response=\"%s\"",
userp_quoted,
- digest->realm,
- digest->nonce,
+ realm_quoted,
+ nonce_quoted,
uripath,
digest->cnonce,
digest->nc,
digest->qop,
request_digest);
- if(strcasecompare(digest->qop, "auth"))
- digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0
- padded which tells to the server how many times you are
- using the same nonce in the qop=auth mode */
+ /* Increment nonce-count to use another nc value for the next request */
+ digest->nc++;
}
else {
response = aprintf("username=\"%s\", "
@@ -827,20 +867,29 @@ static CURLcode auth_create_digest_http_message(
"uri=\"%s\", "
"response=\"%s\"",
userp_quoted,
- digest->realm,
- digest->nonce,
+ realm_quoted,
+ nonce_quoted,
uripath,
request_digest);
}
+ free(nonce_quoted);
+ free(realm_quoted);
free(userp_quoted);
if(!response)
return CURLE_OUT_OF_MEMORY;
/* Add the optional fields */
if(digest->opaque) {
+ char *opaque_quoted;
/* Append the opaque */
- tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque);
+ opaque_quoted = auth_digest_string_quoted(digest->opaque);
+ if(!opaque_quoted) {
+ free(response);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ tmp = aprintf("%s, opaque=\"%s\"", response, opaque_quoted);
free(response);
+ free(opaque_quoted);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
@@ -902,28 +951,18 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
struct digestdata *digest,
char **outptr, size_t *outlen)
{
- switch(digest->algo) {
- case CURLDIGESTALGO_MD5:
- case CURLDIGESTALGO_MD5SESS:
+ if(digest->algo <= ALGO_MD5SESS)
return auth_create_digest_http_message(data, userp, passwdp,
request, uripath, digest,
outptr, outlen,
auth_digest_md5_to_ascii,
Curl_md5it);
-
- case CURLDIGESTALGO_SHA256:
- case CURLDIGESTALGO_SHA256SESS:
- case CURLDIGESTALGO_SHA512_256:
- case CURLDIGESTALGO_SHA512_256SESS:
- return auth_create_digest_http_message(data, userp, passwdp,
- request, uripath, digest,
- outptr, outlen,
- auth_digest_sha256_to_ascii,
- Curl_sha256it);
-
- default:
- return CURLE_UNSUPPORTED_PROTOCOL;
- }
+ DEBUGASSERT(digest->algo <= ALGO_SHA512_256SESS);
+ return auth_create_digest_http_message(data, userp, passwdp,
+ request, uripath, digest,
+ outptr, outlen,
+ auth_digest_sha256_to_ascii,
+ Curl_sha256it);
}
/*
@@ -946,7 +985,7 @@ void Curl_auth_digest_cleanup(struct digestdata *digest)
Curl_safefree(digest->algorithm);
digest->nc = 0;
- digest->algo = CURLDIGESTALGO_MD5; /* default algorithm */
+ digest->algo = ALGO_MD5; /* default algorithm */
digest->stale = FALSE; /* default means normal, not stale */
digest->userhash = FALSE;
}
diff --git a/Utilities/cmcurl/lib/vauth/digest.h b/Utilities/cmcurl/lib/vauth/digest.h
index ee373cd82e..d785bdd91b 100644
--- a/Utilities/cmcurl/lib/vauth/digest.h
+++ b/Utilities/cmcurl/lib/vauth/digest.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <curl/curl.h>
@@ -29,15 +31,6 @@
#define DIGEST_MAX_VALUE_LENGTH 256
#define DIGEST_MAX_CONTENT_LENGTH 1024
-enum {
- CURLDIGESTALGO_MD5,
- CURLDIGESTALGO_MD5SESS,
- CURLDIGESTALGO_SHA256,
- CURLDIGESTALGO_SHA256SESS,
- CURLDIGESTALGO_SHA512_256,
- CURLDIGESTALGO_SHA512_256SESS
-};
-
/* This is used to extract the realm from a challenge message */
bool Curl_auth_digest_get_pair(const char *str, char *value, char *content,
const char **endptr);
diff --git a/Utilities/cmcurl/lib/vauth/digest_sspi.c b/Utilities/cmcurl/lib/vauth/digest_sspi.c
index 94f8f8c0df..89a9db52c7 100644
--- a/Utilities/cmcurl/lib/vauth/digest_sspi.c
+++ b/Utilities/cmcurl/lib/vauth/digest_sspi.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2014 - 2016, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2015 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC2831 DIGEST-MD5 authentication
*
***************************************************************************/
@@ -257,7 +259,7 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg,
char content[DIGEST_MAX_CONTENT_LENGTH];
/* Pass all additional spaces here */
- while(*chlg && ISSPACE(*chlg))
+ while(*chlg && ISBLANK(*chlg))
chlg++;
/* Extract a value=content pair */
@@ -290,7 +292,7 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg,
break; /* We're done here */
/* Pass all additional spaces here */
- while(*chlg && ISSPACE(*chlg))
+ while(*chlg && ISBLANK(*chlg))
chlg++;
/* Allow the list to be comma-separated */
@@ -331,7 +333,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
char value[DIGEST_MAX_VALUE_LENGTH];
char content[DIGEST_MAX_CONTENT_LENGTH];
- while(*p && ISSPACE(*p))
+ while(*p && ISBLANK(*p))
p++;
if(!Curl_auth_digest_get_pair(p, value, content, &p))
@@ -343,7 +345,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
break;
}
- while(*p && ISSPACE(*p))
+ while(*p && ISBLANK(*p))
p++;
if(',' == *p)
@@ -429,8 +431,8 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
has changed then delete that context. */
if((userp && !digest->user) || (!userp && digest->user) ||
(passwdp && !digest->passwd) || (!passwdp && digest->passwd) ||
- (userp && digest->user && strcmp(userp, digest->user)) ||
- (passwdp && digest->passwd && strcmp(passwdp, digest->passwd))) {
+ (userp && digest->user && Curl_timestrcmp(userp, digest->user)) ||
+ (passwdp && digest->passwd && Curl_timestrcmp(passwdp, digest->passwd))) {
if(digest->http_context) {
s_pSecFn->DeleteSecurityContext(digest->http_context);
Curl_safefree(digest->http_context);
diff --git a/Utilities/cmcurl/lib/vauth/gsasl.c b/Utilities/cmcurl/lib/vauth/gsasl.c
index 40fef53c93..a73c644434 100644
--- a/Utilities/cmcurl/lib/vauth/gsasl.c
+++ b/Utilities/cmcurl/lib/vauth/gsasl.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2020 - 2021, Simon Josefsson, <simon@josefsson.org>, et al.
+ * Copyright (C) 2020 - 2022, Simon Josefsson, <simon@josefsson.org>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC5802 SCRAM-SHA-1 authentication
*
***************************************************************************/
@@ -34,7 +36,8 @@
#include <gsasl.h>
-/* The last #include files should be: */
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
diff --git a/Utilities/cmcurl/lib/vauth/krb5_gssapi.c b/Utilities/cmcurl/lib/vauth/krb5_gssapi.c
index 67d43bd567..bac78049dc 100644
--- a/Utilities/cmcurl/lib/vauth/krb5_gssapi.c
+++ b/Utilities/cmcurl/lib/vauth/krb5_gssapi.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2015 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
*
***************************************************************************/
diff --git a/Utilities/cmcurl/lib/vauth/krb5_sspi.c b/Utilities/cmcurl/lib/vauth/krb5_sspi.c
index c652fd7365..895b4a1937 100644
--- a/Utilities/cmcurl/lib/vauth/krb5_sspi.c
+++ b/Utilities/cmcurl/lib/vauth/krb5_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2021, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2022, 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
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
*
***************************************************************************/
diff --git a/Utilities/cmcurl/lib/vauth/ntlm.c b/Utilities/cmcurl/lib/vauth/ntlm.c
index 115f70b0e1..c10fa6caaf 100644
--- a/Utilities/cmcurl/lib/vauth/ntlm.c
+++ b/Utilities/cmcurl/lib/vauth/ntlm.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -27,7 +29,7 @@
/*
* NTLM details:
*
- * https://davenport.sourceforge.io/ntlm.html
+ * https://davenport.sourceforge.net/ntlm.html
* https://www.innovation.ch/java/ntlm.html
*/
@@ -62,6 +64,10 @@
/* "NTLMSSP" signature is always in ASCII regardless of the platform */
#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
+/* The fixed host name we provide, in order to not leak our real local host
+ name. Copy the name used by Firefox. */
+#define NTLM_HOSTNAME "WORKSTATION"
+
#if DEBUG_ME
# define DEBUG_OUT(x) x
static void ntlm_print_flags(FILE *handle, unsigned long flags)
@@ -521,6 +527,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
userlen = strlen(user);
+#ifndef NTLM_HOSTNAME
/* Get the machine's un-qualified host name as NTLM doesn't like the fully
qualified domain name */
if(Curl_gethostname(host, sizeof(host))) {
@@ -530,6 +537,10 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
else {
hostlen = strlen(host);
}
+#else
+ (void)msnprintf(host, sizeof(host), "%s", NTLM_HOSTNAME);
+ hostlen = sizeof(NTLM_HOSTNAME)-1;
+#endif
if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
unsigned char ntbuffer[0x18];
@@ -589,7 +600,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
/* A safer but less compatible alternative is:
* Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
- * See https://davenport.sourceforge.io/ntlm.html#ntlmVersion2 */
+ * See https://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
}
if(unicode) {
@@ -647,7 +658,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
/* LanManager response */
/* NT response */
- 0, /* zero termination */
+ 0, /* null-termination */
0, 0, 0, /* type-3 long, the 24 upper bits */
SHORTPAIR(0x18), /* LanManager response length, twice */
diff --git a/Utilities/cmcurl/lib/vauth/ntlm.h b/Utilities/cmcurl/lib/vauth/ntlm.h
index 8ec23ad4f5..4dfda55453 100644
--- a/Utilities/cmcurl/lib/vauth/ntlm.h
+++ b/Utilities/cmcurl/lib/vauth/ntlm.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -32,7 +34,8 @@
/* Stuff only required for curl_ntlm_msgs.c */
#ifdef BUILDING_CURL_NTLM_MSGS_C
-/* Flag bits definitions based on https://davenport.sourceforge.io/ntlm.html */
+/* Flag bits definitions based on
+ https://davenport.sourceforge.net/ntlm.html */
#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
/* Indicates that Unicode strings are supported for use in security buffer
diff --git a/Utilities/cmcurl/lib/vauth/ntlm_sspi.c b/Utilities/cmcurl/lib/vauth/ntlm_sspi.c
index 3e39dad315..193576acaa 100644
--- a/Utilities/cmcurl/lib/vauth/ntlm_sspi.c
+++ b/Utilities/cmcurl/lib/vauth/ntlm_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vauth/oauth2.c b/Utilities/cmcurl/lib/vauth/oauth2.c
index a5f16a0bf4..1604b303e0 100644
--- a/Utilities/cmcurl/lib/vauth/oauth2.c
+++ b/Utilities/cmcurl/lib/vauth/oauth2.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC6749 OAuth 2.0 Authorization Framework
*
***************************************************************************/
diff --git a/Utilities/cmcurl/lib/vauth/spnego_gssapi.c b/Utilities/cmcurl/lib/vauth/spnego_gssapi.c
index 8c1a3edd04..25dff967d1 100644
--- a/Utilities/cmcurl/lib/vauth/spnego_gssapi.c
+++ b/Utilities/cmcurl/lib/vauth/spnego_gssapi.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC4178 Simple and Protected GSS-API Negotiation Mechanism
*
***************************************************************************/
diff --git a/Utilities/cmcurl/lib/vauth/spnego_sspi.c b/Utilities/cmcurl/lib/vauth/spnego_sspi.c
index d219d8bb24..d845caca6c 100644
--- a/Utilities/cmcurl/lib/vauth/spnego_sspi.c
+++ b/Utilities/cmcurl/lib/vauth/spnego_sspi.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
* RFC4178 Simple and Protected GSS-API Negotiation Mechanism
*
***************************************************************************/
diff --git a/Utilities/cmcurl/lib/vauth/vauth.c b/Utilities/cmcurl/lib/vauth/vauth.c
index 3624fb0c4a..58fe05139d 100644
--- a/Utilities/cmcurl/lib/vauth/vauth.c
+++ b/Utilities/cmcurl/lib/vauth/vauth.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2021, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2022, 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
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -25,6 +27,8 @@
#include <curl/curl.h>
#include "vauth.h"
+#include "urldata.h"
+#include "strcase.h"
#include "curl_multibyte.h"
#include "curl_printf.h"
@@ -142,3 +146,18 @@ bool Curl_auth_user_contains_domain(const char *user)
return valid;
}
+
+/*
+ * Curl_auth_ollowed_to_host() tells if authentication, cookies or other
+ * "sensitive data" can (still) be sent to this host.
+ */
+bool Curl_auth_allowed_to_host(struct Curl_easy *data)
+{
+ struct connectdata *conn = data->conn;
+ return (!data->state.this_is_a_follow ||
+ data->set.allow_auth_to_other_hosts ||
+ (data->state.first_host &&
+ strcasecompare(data->state.first_host, conn->host.name) &&
+ (data->state.first_remote_port == conn->remote_port) &&
+ (data->state.first_remote_protocol == conn->handler->protocol)));
+}
diff --git a/Utilities/cmcurl/lib/vauth/vauth.h b/Utilities/cmcurl/lib/vauth/vauth.h
index 6e1237834a..af27f01dfb 100644
--- a/Utilities/cmcurl/lib/vauth/vauth.h
+++ b/Utilities/cmcurl/lib/vauth/vauth.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <curl/curl.h>
@@ -52,6 +54,12 @@ struct gsasldata;
#define GSS_ERROR(status) ((status) & 0x80000000)
#endif
+/*
+ * Curl_auth_allowed_to_host() tells if authentication, cookies or other
+ * "sensitive data" can (still) be sent to this host.
+ */
+bool Curl_auth_allowed_to_host(struct Curl_easy *data);
+
/* This is used to build a SPN string */
#if !defined(USE_WINDOWS_SSPI)
char *Curl_auth_build_spn(const char *service, const char *host,
@@ -222,7 +230,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
CURLcode Curl_auth_create_spnego_message(struct negotiatedata *nego,
char **outptr, size_t *outlen);
-/* This is used to clean up the SPNEGO specifiec data */
+/* This is used to clean up the SPNEGO specific data */
void Curl_auth_cleanup_spnego(struct negotiatedata *nego);
#endif /* USE_SPNEGO */
diff --git a/Utilities/cmcurl/lib/version.c b/Utilities/cmcurl/lib/version.c
index 5e3e428c54..cb44eb4063 100644
--- a/Utilities/cmcurl/lib/version.c
+++ b/Utilities/cmcurl/lib/version.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -29,6 +31,7 @@
#include "vssh/ssh.h"
#include "quic.h"
#include "curl_printf.h"
+#include "easy_lock.h"
#ifdef USE_ARES
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
@@ -50,7 +53,7 @@
#include <librtmp/rtmp.h>
#endif
-#ifdef HAVE_ZLIB_H
+#ifdef HAVE_LIBZ
#include <cm3p/zlib.h>
#endif
@@ -335,6 +338,11 @@ static const char * const protocols[] = {
#endif
#ifdef USE_LIBRTMP
"rtmp",
+ "rtmpe",
+ "rtmps",
+ "rtmpt",
+ "rtmpte",
+ "rtmpts",
#endif
#ifndef CURL_DISABLE_RTSP
"rtsp",
@@ -364,6 +372,12 @@ static const char * const protocols[] = {
#ifndef CURL_DISABLE_TFTP
"tftp",
#endif
+#ifdef USE_WEBSOCKETS
+ "ws",
+#endif
+#if defined(USE_SSL) && defined(USE_WEBSOCKETS)
+ "wss",
+#endif
NULL
};
@@ -451,6 +465,9 @@ static curl_version_info_data version_info = {
#if defined(USE_GSASL)
| CURL_VERSION_GSASL
#endif
+#if defined(GLOBAL_INIT_IS_THREADSAFE)
+ | CURL_VERSION_THREADSAFE
+#endif
,
NULL, /* ssl_version */
0, /* ssl_version_num, this is kept at zero */
diff --git a/Utilities/cmcurl/lib/version_win32.c b/Utilities/cmcurl/lib/version_win32.c
index afdb1d6a72..e8f14f9dff 100644
--- a/Utilities/cmcurl/lib/version_win32.c
+++ b/Utilities/cmcurl/lib/version_win32.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/version_win32.h b/Utilities/cmcurl/lib/version_win32.h
index 38af87fa09..7a9a6a14f1 100644
--- a/Utilities/cmcurl/lib/version_win32.h
+++ b/Utilities/cmcurl/lib/version_win32.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2016 - 2021, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2016 - 2022, 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
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vquic/msh3.c b/Utilities/cmcurl/lib/vquic/msh3.c
index f7bd315be1..c3e58e726a 100644
--- a/Utilities/cmcurl/lib/vquic/msh3.c
+++ b/Utilities/cmcurl/lib/vquic/msh3.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -25,7 +27,6 @@
#ifdef USE_MSH3
#include "urldata.h"
-#include "curl_printf.h"
#include "timeval.h"
#include "multiif.h"
#include "sendf.h"
@@ -33,6 +34,11 @@
#include "h2h3.h"
#include "msh3.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
/* #define DEBUG_HTTP3 1 */
#ifdef DEBUG_HTTP3
#define H3BUGF(x) x
@@ -108,7 +114,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
socklen_t addrlen)
{
struct quicsocket *qs = &conn->hequic[sockindex];
- bool unsecure = !conn->ssl_config.verifypeer;
+ bool insecure = !conn->ssl_config.verifypeer;
memset(qs, 0, sizeof(*qs));
(void)sockfd;
@@ -126,7 +132,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
qs->conn = MsH3ConnectionOpen(qs->api,
conn->host.name,
(uint16_t)conn->remote_port,
- unsecure);
+ insecure);
if(!qs->conn) {
failf(data, "can't create msh3 connection");
if(qs->api) {
@@ -220,13 +226,8 @@ static unsigned int msh3_conncheck(struct Curl_easy *data,
return CONNRESULT_NONE;
}
-static void msh3_cleanup(struct quicsocket *qs, struct HTTP *stream)
+static void disconnect(struct quicsocket *qs)
{
- if(stream && stream->recv_buf) {
- free(stream->recv_buf);
- stream->recv_buf = ZERO_NULL;
- msh3_lock_uninitialize(&stream->recv_lock);
- }
if(qs->conn) {
MsH3ConnectionClose(qs->conn);
qs->conn = ZERO_NULL;
@@ -240,18 +241,20 @@ static void msh3_cleanup(struct quicsocket *qs, struct HTTP *stream)
static CURLcode msh3_disconnect(struct Curl_easy *data,
struct connectdata *conn, bool dead_connection)
{
+ (void)data;
(void)dead_connection;
H3BUGF(infof(data, "disconnecting (msh3)"));
- msh3_cleanup(conn->quic, data->req.p.http);
+ disconnect(conn->quic);
return CURLE_OK;
}
void Curl_quic_disconnect(struct Curl_easy *data, struct connectdata *conn,
int tempindex)
{
+ (void)data;
if(conn->transport == TRNSPRT_QUIC) {
- H3BUGF(infof(data, "disconnecting (curl)"));
- msh3_cleanup(&conn->hequic[tempindex], data->req.p.http);
+ H3BUGF(infof(data, "disconnecting QUIC index %u", tempindex));
+ disconnect(&conn->hequic[tempindex]);
}
}
@@ -286,7 +289,6 @@ static void MSH3_CALL msh3_header_received(MSH3_REQUEST *Request,
struct HTTP *stream = IfContext;
size_t total_len;
(void)Request;
- H3BUGF(printf("* msh3_header_received\n"));
if(stream->recv_header_complete) {
H3BUGF(printf("* ignoring header after data\n"));
@@ -379,9 +381,6 @@ static void MSH3_CALL msh3_shutdown(MSH3_REQUEST *Request, void *IfContext)
(void)stream;
}
-static_assert(sizeof(MSH3_HEADER) == sizeof(struct h2h3pseudo),
- "Sizes must match for cast below to work");
-
static ssize_t msh3_stream_send(struct Curl_easy *data,
int sockindex,
const void *mem,
@@ -394,6 +393,9 @@ static ssize_t msh3_stream_send(struct Curl_easy *data,
struct h2h3req *hreq;
(void)sockindex;
+ /* Sizes must match for cast below to work" */
+ DEBUGASSERT(sizeof(MSH3_HEADER) == sizeof(struct h2h3pseudo));
+
H3BUGF(infof(data, "msh3_stream_send %zu", len));
if(!stream->req) {
@@ -488,9 +490,19 @@ CURLcode Curl_quic_done_sending(struct Curl_easy *data)
void Curl_quic_done(struct Curl_easy *data, bool premature)
{
- (void)data;
+ struct HTTP *stream = data->req.p.http;
(void)premature;
H3BUGF(infof(data, "Curl_quic_done"));
+ if(stream) {
+ if(stream->recv_buf) {
+ Curl_safefree(stream->recv_buf);
+ msh3_lock_uninitialize(&stream->recv_lock);
+ }
+ if(stream->req) {
+ MsH3RequestClose(stream->req);
+ stream->req = ZERO_NULL;
+ }
+ }
}
bool Curl_quic_data_pending(const struct Curl_easy *data)
@@ -500,4 +512,16 @@ bool Curl_quic_data_pending(const struct Curl_easy *data)
return stream->recv_header_len || stream->recv_data_len;
}
+/*
+ * Called from transfer.c:Curl_readwrite when neither HTTP level read
+ * nor write is performed. It is a good place to handle timer expiry
+ * for QUIC transport.
+ */
+CURLcode Curl_quic_idle(struct Curl_easy *data)
+{
+ (void)data;
+ H3BUGF(infof(data, "Curl_quic_idle"));
+ return CURLE_OK;
+}
+
#endif /* USE_MSH3 */
diff --git a/Utilities/cmcurl/lib/vquic/msh3.h b/Utilities/cmcurl/lib/vquic/msh3.h
index bacdcb1321..ce884d92dd 100644
--- a/Utilities/cmcurl/lib/vquic/msh3.h
+++ b/Utilities/cmcurl/lib/vquic/msh3.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vquic/ngtcp2.c b/Utilities/cmcurl/lib/vquic/ngtcp2.c
index f1a64eea85..097cca44b0 100644
--- a/Utilities/cmcurl/lib/vquic/ngtcp2.c
+++ b/Utilities/cmcurl/lib/vquic/ngtcp2.c
@@ -18,21 +18,29 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_NGTCP2
#include <ngtcp2/ngtcp2.h>
-#include <ngtcp2/ngtcp2_crypto.h>
#include <nghttp3/nghttp3.h>
#ifdef USE_OPENSSL
#include <openssl/err.h>
+#ifdef OPENSSL_IS_BORINGSSL
+#include <ngtcp2/ngtcp2_crypto_boringssl.h>
+#else
#include <ngtcp2/ngtcp2_crypto_openssl.h>
+#endif
#include "vtls/openssl.h"
#elif defined(USE_GNUTLS)
#include <ngtcp2/ngtcp2_crypto_gnutls.h>
#include "vtls/gtls.h"
+#elif defined(USE_WOLFSSL)
+#include <ngtcp2/ngtcp2_crypto_wolfssl.h>
+#include "vtls/wolfssl.h"
#endif
#include "urldata.h"
#include "sendf.h"
@@ -96,17 +104,32 @@ struct h3out {
"+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \
"+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \
"%DISABLE_TLS13_COMPAT_MODE"
+#elif defined(USE_WOLFSSL)
+#define QUIC_CIPHERS \
+ "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \
+ "POLY1305_SHA256:TLS_AES_128_CCM_SHA256"
+#define QUIC_GROUPS "P-256:P-384:P-521"
#endif
+/* ngtcp2 default congestion controller does not perform pacing. Limit
+ the maximum packet burst to MAX_PKT_BURST packets. */
+#define MAX_PKT_BURST 10
+
static CURLcode ng_process_ingress(struct Curl_easy *data,
curl_socket_t sockfd,
struct quicsocket *qs);
static CURLcode ng_flush_egress(struct Curl_easy *data, int sockfd,
struct quicsocket *qs);
static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
- size_t datalen, void *user_data,
+ uint64_t datalen, void *user_data,
void *stream_user_data);
+static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref)
+{
+ struct quicsocket *qs = conn_ref->user_data;
+ return qs->qconn;
+}
+
static ngtcp2_tstamp timestamp(void)
{
struct curltime ct = Curl_now();
@@ -187,91 +210,44 @@ static int keylog_callback(gnutls_session_t session, const char *label,
Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size);
return 0;
}
-#endif
-
-static int init_ngh3_conn(struct quicsocket *qs);
-
-static int write_client_handshake(struct quicsocket *qs,
- ngtcp2_crypto_level level,
- const uint8_t *data, size_t len)
-{
- int rv;
-
- rv = ngtcp2_conn_submit_crypto_data(qs->qconn, level, data, len);
- if(rv) {
- H3BUGF(fprintf(stderr, "write_client_handshake failed\n"));
- }
- assert(0 == rv);
-
- return 1;
-}
-
-#ifdef USE_OPENSSL
-static int quic_set_encryption_secrets(SSL *ssl,
- OSSL_ENCRYPTION_LEVEL ossl_level,
- const uint8_t *rx_secret,
- const uint8_t *tx_secret,
- size_t secretlen)
-{
- struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
- int level = ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
-
- if(ngtcp2_crypto_derive_and_install_rx_key(
- qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
- return 0;
-
- if(ngtcp2_crypto_derive_and_install_tx_key(
- qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
- return 0;
-
- if(level == NGTCP2_CRYPTO_LEVEL_APPLICATION) {
- if(init_ngh3_conn(qs) != CURLE_OK)
- return 0;
- }
-
- return 1;
-}
-
-static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
- const uint8_t *data, size_t len)
-{
- struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
- ngtcp2_crypto_level level =
- ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
-
- return write_client_handshake(qs, level, data, len);
-}
-
-static int quic_flush_flight(SSL *ssl)
+#elif defined(USE_WOLFSSL)
+#if defined(HAVE_SECRET_CALLBACK)
+static void keylog_callback(const WOLFSSL *ssl, const char *line)
{
(void)ssl;
- return 1;
-}
-
-static int quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level,
- uint8_t alert)
-{
- struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
- (void)level;
-
- qs->tls_alert = alert;
- return 1;
+ Curl_tls_keylog_write_line(line);
}
+#endif
+#endif
-static SSL_QUIC_METHOD quic_method = {quic_set_encryption_secrets,
- quic_add_handshake_data,
- quic_flush_flight, quic_send_alert};
+static int init_ngh3_conn(struct quicsocket *qs);
+#ifdef USE_OPENSSL
static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method());
- SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
- SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
+#ifdef OPENSSL_IS_BORINGSSL
+ if(ngtcp2_crypto_boringssl_configure_client_context(ssl_ctx) != 0) {
+ failf(data, "ngtcp2_crypto_boringssl_configure_client_context failed");
+ return NULL;
+ }
+#else
+ if(ngtcp2_crypto_openssl_configure_client_context(ssl_ctx) != 0) {
+ failf(data, "ngtcp2_crypto_openssl_configure_client_context failed");
+ return NULL;
+ }
+#endif
SSL_CTX_set_default_verify_paths(ssl_ctx);
+#ifdef OPENSSL_IS_BORINGSSL
+ if(SSL_CTX_set1_curves_list(ssl_ctx, QUIC_GROUPS) != 1) {
+ failf(data, "SSL_CTX_set1_curves_list failed");
+ return NULL;
+ }
+#else
if(SSL_CTX_set_ciphersuites(ssl_ctx, QUIC_CIPHERS) != 1) {
char error_buffer[256];
ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer));
@@ -283,8 +259,7 @@ static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
failf(data, "SSL_CTX_set1_groups_list failed");
return NULL;
}
-
- SSL_CTX_set_quic_method(ssl_ctx, &quic_method);
+#endif
/* Open the file if a TLS or QUIC backend has not done this before. */
Curl_tls_keylog_open();
@@ -353,7 +328,7 @@ static int quic_init_ssl(struct quicsocket *qs)
DEBUGASSERT(!qs->ssl);
qs->ssl = SSL_new(qs->sslctx);
- SSL_set_app_data(qs->ssl, qs);
+ SSL_set_app_data(qs->ssl, &qs->conn_ref);
SSL_set_connect_state(qs->ssl);
SSL_set_quic_use_legacy_codepoint(qs->ssl, 0);
@@ -367,107 +342,6 @@ static int quic_init_ssl(struct quicsocket *qs)
return 0;
}
#elif defined(USE_GNUTLS)
-static int secret_func(gnutls_session_t ssl,
- gnutls_record_encryption_level_t gtls_level,
- const void *rx_secret,
- const void *tx_secret, size_t secretlen)
-{
- struct quicsocket *qs = gnutls_session_get_ptr(ssl);
- int level =
- ngtcp2_crypto_gnutls_from_gnutls_record_encryption_level(gtls_level);
-
- if(level != NGTCP2_CRYPTO_LEVEL_EARLY &&
- ngtcp2_crypto_derive_and_install_rx_key(
- qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
- return 0;
-
- if(ngtcp2_crypto_derive_and_install_tx_key(
- qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
- return 0;
-
- if(level == NGTCP2_CRYPTO_LEVEL_APPLICATION) {
- if(init_ngh3_conn(qs) != CURLE_OK)
- return -1;
- }
-
- return 0;
-}
-
-static int read_func(gnutls_session_t ssl,
- gnutls_record_encryption_level_t gtls_level,
- gnutls_handshake_description_t htype, const void *data,
- size_t len)
-{
- struct quicsocket *qs = gnutls_session_get_ptr(ssl);
- ngtcp2_crypto_level level =
- ngtcp2_crypto_gnutls_from_gnutls_record_encryption_level(gtls_level);
- int rv;
-
- if(htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC)
- return 0;
-
- rv = write_client_handshake(qs, level, data, len);
- if(rv == 0)
- return -1;
-
- return 0;
-}
-
-static int alert_read_func(gnutls_session_t ssl,
- gnutls_record_encryption_level_t gtls_level,
- gnutls_alert_level_t alert_level,
- gnutls_alert_description_t alert_desc)
-{
- struct quicsocket *qs = gnutls_session_get_ptr(ssl);
- (void)gtls_level;
- (void)alert_level;
-
- qs->tls_alert = alert_desc;
- return 1;
-}
-
-static int tp_recv_func(gnutls_session_t ssl, const uint8_t *data,
- size_t data_size)
-{
- struct quicsocket *qs = gnutls_session_get_ptr(ssl);
- ngtcp2_transport_params params;
-
- if(ngtcp2_decode_transport_params(
- &params, NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
- data, data_size) != 0)
- return -1;
-
- if(ngtcp2_conn_set_remote_transport_params(qs->qconn, &params) != 0)
- return -1;
-
- return 0;
-}
-
-static int tp_send_func(gnutls_session_t ssl, gnutls_buffer_t extdata)
-{
- struct quicsocket *qs = gnutls_session_get_ptr(ssl);
- uint8_t paramsbuf[64];
- ngtcp2_transport_params params;
- ssize_t nwrite;
- int rc;
-
- ngtcp2_conn_get_local_transport_params(qs->qconn, &params);
- nwrite = ngtcp2_encode_transport_params(
- paramsbuf, sizeof(paramsbuf), NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
- &params);
- if(nwrite < 0) {
- H3BUGF(fprintf(stderr, "ngtcp2_encode_transport_params: %s\n",
- ngtcp2_strerror((int)nwrite)));
- return -1;
- }
-
- rc = gnutls_buffer_append_data(extdata, paramsbuf, nwrite);
- if(rc < 0)
- return rc;
-
- return (int)nwrite;
-}
-
static int quic_init_ssl(struct quicsocket *qs)
{
gnutls_datum_t alpn[2];
@@ -478,26 +352,17 @@ static int quic_init_ssl(struct quicsocket *qs)
DEBUGASSERT(!qs->ssl);
gnutls_init(&qs->ssl, GNUTLS_CLIENT);
- gnutls_session_set_ptr(qs->ssl, qs);
+ gnutls_session_set_ptr(qs->ssl, &qs->conn_ref);
- rc = gnutls_priority_set_direct(qs->ssl, QUIC_PRIORITY, NULL);
- if(rc < 0) {
- H3BUGF(fprintf(stderr, "gnutls_priority_set_direct failed: %s\n",
- gnutls_strerror(rc)));
+ if(ngtcp2_crypto_gnutls_configure_client_session(qs->ssl) != 0) {
+ H3BUGF(fprintf(stderr,
+ "ngtcp2_crypto_gnutls_configure_client_session failed\n"));
return 1;
}
- gnutls_handshake_set_secret_function(qs->ssl, secret_func);
- gnutls_handshake_set_read_function(qs->ssl, read_func);
- gnutls_alert_set_read_function(qs->ssl, alert_read_func);
-
- rc = gnutls_session_ext_register(qs->ssl, "QUIC Transport Parameters",
- NGTCP2_TLSEXT_QUIC_TRANSPORT_PARAMETERS_V1, GNUTLS_EXT_TLS,
- tp_recv_func, tp_send_func, NULL, NULL, NULL,
- GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_CLIENT_HELLO |
- GNUTLS_EXT_FLAG_EE);
+ rc = gnutls_priority_set_direct(qs->ssl, QUIC_PRIORITY, NULL);
if(rc < 0) {
- H3BUGF(fprintf(stderr, "gnutls_session_ext_register failed: %s\n",
+ H3BUGF(fprintf(stderr, "gnutls_priority_set_direct failed: %s\n",
gnutls_strerror(rc)));
return 1;
}
@@ -546,7 +411,105 @@ static int quic_init_ssl(struct quicsocket *qs)
gnutls_server_name_set(qs->ssl, GNUTLS_NAME_DNS, hostname, strlen(hostname));
return 0;
}
+#elif defined(USE_WOLFSSL)
+
+static WOLFSSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
+{
+ struct connectdata *conn = data->conn;
+ WOLFSSL_CTX *ssl_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
+
+ if(ngtcp2_crypto_wolfssl_configure_client_context(ssl_ctx) != 0) {
+ failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed");
+ return NULL;
+ }
+
+ wolfSSL_CTX_set_default_verify_paths(ssl_ctx);
+
+ if(wolfSSL_CTX_set_cipher_list(ssl_ctx, QUIC_CIPHERS) != 1) {
+ char error_buffer[256];
+ ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer));
+ failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer);
+ return NULL;
+ }
+
+ if(wolfSSL_CTX_set1_groups_list(ssl_ctx, (char *)QUIC_GROUPS) != 1) {
+ failf(data, "SSL_CTX_set1_groups_list failed");
+ return NULL;
+ }
+
+ /* Open the file if a TLS or QUIC backend has not done this before. */
+ Curl_tls_keylog_open();
+ if(Curl_tls_keylog_enabled()) {
+#if defined(HAVE_SECRET_CALLBACK)
+ wolfSSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
+#else
+ failf(data, "wolfSSL was built without keylog callback");
+ return NULL;
+#endif
+ }
+
+ if(conn->ssl_config.verifypeer) {
+ const char * const ssl_cafile = conn->ssl_config.CAfile;
+ const char * const ssl_capath = conn->ssl_config.CApath;
+
+ if(ssl_cafile || ssl_capath) {
+ wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
+ /* tell wolfSSL where to find CA certificates that are used to verify
+ the server's certificate. */
+ if(!wolfSSL_CTX_load_verify_locations(ssl_ctx, ssl_cafile, ssl_capath)) {
+ /* Fail if we insist on successfully verifying the server. */
+ failf(data, "error setting certificate verify locations:"
+ " CAfile: %s CApath: %s",
+ ssl_cafile ? ssl_cafile : "none",
+ ssl_capath ? ssl_capath : "none");
+ return NULL;
+ }
+ infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
+ infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
+ }
+#ifdef CURL_CA_FALLBACK
+ else {
+ /* verifying the peer without any CA certificates won't work so
+ use wolfssl's built-in default as fallback */
+ wolfSSL_CTX_set_default_verify_paths(ssl_ctx);
+ }
#endif
+ }
+ else {
+ wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
+ }
+
+ return ssl_ctx;
+}
+
+/** SSL callbacks ***/
+
+static int quic_init_ssl(struct quicsocket *qs)
+{
+ const uint8_t *alpn = NULL;
+ size_t alpnlen = 0;
+ /* this will need some attention when HTTPS proxy over QUIC get fixed */
+ const char * const hostname = qs->conn->host.name;
+
+ DEBUGASSERT(!qs->ssl);
+ qs->ssl = SSL_new(qs->sslctx);
+
+ wolfSSL_set_app_data(qs->ssl, &qs->conn_ref);
+ wolfSSL_set_connect_state(qs->ssl);
+ wolfSSL_set_quic_use_legacy_codepoint(qs->ssl, 0);
+
+ alpn = (const uint8_t *)H3_ALPN_H3_29 H3_ALPN_H3;
+ alpnlen = sizeof(H3_ALPN_H3_29) - 1 + sizeof(H3_ALPN_H3) - 1;
+ if(alpn)
+ wolfSSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen);
+
+ /* set SNI */
+ wolfSSL_UseSNI(qs->ssl, WOLFSSL_SNI_HOST_NAME,
+ hostname, (unsigned short)strlen(hostname));
+
+ return 0;
+}
+#endif /* defined(USE_WOLFSSL) */
static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data)
{
@@ -571,7 +534,7 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
void *user_data, void *stream_user_data)
{
struct quicsocket *qs = (struct quicsocket *)user_data;
- ssize_t nconsumed;
+ nghttp3_ssize nconsumed;
int fin = (flags & NGTCP2_STREAM_DATA_FLAG_FIN) ? 1 : 0;
(void)offset;
(void)stream_user_data;
@@ -579,6 +542,9 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
nconsumed =
nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin);
if(nconsumed < 0) {
+ ngtcp2_connection_close_error_set_application_error(
+ &qs->last_error, nghttp3_err_infer_quic_app_error_code((int)nconsumed),
+ NULL, 0);
return NGTCP2_ERR_CALLBACK_FAILURE;
}
@@ -629,6 +595,8 @@ static int cb_stream_close(ngtcp2_conn *tconn, uint32_t flags,
rv = nghttp3_conn_close_stream(qs->h3conn, stream_id,
app_error_code);
if(rv) {
+ ngtcp2_connection_close_error_set_application_error(
+ &qs->last_error, nghttp3_err_infer_quic_app_error_code(rv), NULL, 0);
return NGTCP2_ERR_CALLBACK_FAILURE;
}
@@ -735,6 +703,23 @@ static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
return 0;
}
+static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_crypto_level level,
+ void *user_data)
+{
+ struct quicsocket *qs = (struct quicsocket *)user_data;
+ (void)tconn;
+
+ if(level != NGTCP2_CRYPTO_LEVEL_APPLICATION) {
+ return 0;
+ }
+
+ if(init_ngh3_conn(qs) != CURLE_OK) {
+ return NGTCP2_ERR_CALLBACK_FAILURE;
+ }
+
+ return 0;
+}
+
static ngtcp2_callbacks ng_callbacks = {
ngtcp2_crypto_client_initial_cb,
NULL, /* recv_client_initial */
@@ -773,6 +758,9 @@ static ngtcp2_callbacks ng_callbacks = {
ngtcp2_crypto_get_path_challenge_data_cb,
cb_stream_stop_sending,
NULL, /* version_negotiation */
+ cb_recv_rx_key,
+ NULL, /* recv_tx_key */
+ NULL, /* early_data_rejected */
};
/*
@@ -818,6 +806,10 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
result = quic_set_client_cert(data, qs);
if(result)
return result;
+#elif defined(USE_WOLFSSL)
+ qs->sslctx = quic_ssl_ctx(data);
+ if(!qs->sslctx)
+ return CURLE_QUIC_CONNECT_ERROR;
#endif
if(quic_init_ssl(qs))
@@ -855,6 +847,29 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
ngtcp2_conn_set_tls_native_handle(qs->qconn, qs->ssl);
+ ngtcp2_connection_close_error_default(&qs->last_error);
+
+#if defined(__linux__) && defined(UDP_SEGMENT) && defined(HAVE_SENDMSG)
+ qs->no_gso = FALSE;
+#else
+ qs->no_gso = TRUE;
+#endif
+
+ qs->num_blocked_pkt = 0;
+ qs->num_blocked_pkt_sent = 0;
+ memset(&qs->blocked_pkt, 0, sizeof(qs->blocked_pkt));
+
+ qs->pktbuflen = NGTCP2_MAX_PMTUD_UDP_PAYLOAD_SIZE * MAX_PKT_BURST;
+ qs->pktbuf = malloc(qs->pktbuflen);
+ if(!qs->pktbuf) {
+ ngtcp2_conn_del(qs->qconn);
+ qs->qconn = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ qs->conn_ref.get_conn = get_conn;
+ qs->conn_ref.user_data = qs;
+
return CURLE_OK;
}
@@ -899,18 +914,14 @@ static void qs_disconnect(struct quicsocket *qs)
char buffer[NGTCP2_MAX_UDP_PAYLOAD_SIZE];
ngtcp2_tstamp ts;
ngtcp2_ssize rc;
- ngtcp2_connection_close_error errorcode;
if(!qs->conn) /* already closed */
return;
- ngtcp2_connection_close_error_set_application_error(&errorcode,
- NGHTTP3_H3_NO_ERROR,
- NULL, 0);
ts = timestamp();
rc = ngtcp2_conn_write_connection_close(qs->qconn, NULL, /* path */
NULL, /* pkt_info */
(uint8_t *)buffer, sizeof(buffer),
- &errorcode, ts);
+ &qs->last_error, ts);
if(rc > 0) {
while((send(qs->conn->sock[FIRSTSOCKET], buffer, rc, 0) == -1) &&
SOCKERRNO == EINTR);
@@ -926,6 +937,8 @@ static void qs_disconnect(struct quicsocket *qs)
SSL_free(qs->ssl);
#elif defined(USE_GNUTLS)
gnutls_deinit(qs->ssl);
+#elif defined(USE_WOLFSSL)
+ wolfSSL_free(qs->ssl);
#endif
qs->ssl = NULL;
#ifdef USE_GNUTLS
@@ -934,10 +947,13 @@ static void qs_disconnect(struct quicsocket *qs)
qs->cred = NULL;
}
#endif
+ free(qs->pktbuf);
nghttp3_conn_del(qs->h3conn);
ngtcp2_conn_del(qs->qconn);
#ifdef USE_OPENSSL
SSL_CTX_free(qs->sslctx);
+#elif defined(USE_WOLFSSL)
+ wolfSSL_CTX_free(qs->sslctx);
#endif
}
@@ -1006,6 +1022,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
H3BUGF(infof(data, "cb_h3_stream_close CALLED"));
stream->closed = TRUE;
+ stream->error3 = app_error_code;
Curl_expire(data, 0, EXPIRE_QUIC);
/* make sure that ngh3_stream_recv is called again to complete the transfer
even if there are no more packets to be received from the server. */
@@ -1117,6 +1134,10 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
return -1;
}
}
+
+ if(stream->status_code / 100 != 1) {
+ stream->bodystarted = TRUE;
+ }
return 0;
}
@@ -1139,9 +1160,10 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
if(token == NGHTTP3_QPACK_TOKEN__STATUS) {
char line[14]; /* status line is always 13 characters long */
size_t ncopy;
- int status = decode_status_code(h3val.base, h3val.len);
- DEBUGASSERT(status != -1);
- ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", status);
+ stream->status_code = decode_status_code(h3val.base, h3val.len);
+ DEBUGASSERT(stream->status_code != -1);
+ ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n",
+ stream->status_code);
result = write_data(stream, line, ncopy);
if(result) {
return -1;
@@ -1171,16 +1193,36 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
return 0;
}
-static int cb_h3_send_stop_sending(nghttp3_conn *conn, int64_t stream_id,
- uint64_t app_error_code,
- void *user_data,
- void *stream_user_data)
+static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id,
+ uint64_t app_error_code, void *user_data,
+ void *stream_user_data)
{
+ struct quicsocket *qs = user_data;
+ int rv;
+ (void)conn;
+ (void)stream_user_data;
+
+ rv = ngtcp2_conn_shutdown_stream_read(qs->qconn, stream_id, app_error_code);
+ if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
+ return NGTCP2_ERR_CALLBACK_FAILURE;
+ }
+
+ return 0;
+}
+
+static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t stream_id,
+ uint64_t app_error_code, void *user_data,
+ void *stream_user_data) {
+ struct quicsocket *qs = user_data;
+ int rv;
(void)conn;
- (void)stream_id;
- (void)app_error_code;
- (void)user_data;
(void)stream_user_data;
+
+ rv = ngtcp2_conn_shutdown_stream_write(qs->qconn, stream_id, app_error_code);
+ if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) {
+ return NGTCP2_ERR_CALLBACK_FAILURE;
+ }
+
return 0;
}
@@ -1195,9 +1237,9 @@ static nghttp3_callbacks ngh3_callbacks = {
NULL, /* begin_trailers */
cb_h3_recv_header,
NULL, /* end_trailers */
- cb_h3_send_stop_sending,
+ cb_h3_stop_sending,
NULL, /* end_stream */
- NULL, /* reset_stream */
+ cb_h3_reset_stream,
NULL /* shutdown */
};
@@ -1333,6 +1375,24 @@ static ssize_t ngh3_stream_recv(struct Curl_easy *data,
}
if(stream->closed) {
+ if(stream->error3 != NGHTTP3_H3_NO_ERROR) {
+ failf(data,
+ "HTTP/3 stream %" PRId64 " was not closed cleanly: (err %" PRIu64
+ ")",
+ stream->stream3_id, stream->error3);
+ *curlcode = CURLE_HTTP3;
+ return -1;
+ }
+
+ if(!stream->bodystarted) {
+ failf(data,
+ "HTTP/3 stream %" PRId64 " was closed cleanly, but before getting"
+ " all response header fields, treated as error",
+ stream->stream3_id);
+ *curlcode = CURLE_HTTP3;
+ return -1;
+ }
+
*curlcode = CURLE_OK;
return 0;
}
@@ -1344,7 +1404,7 @@ static ssize_t ngh3_stream_recv(struct Curl_easy *data,
/* this amount of data has now been acked on this stream */
static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
- size_t datalen, void *user_data,
+ uint64_t datalen, void *user_data,
void *stream_user_data)
{
struct Curl_easy *data = stream_user_data;
@@ -1368,10 +1428,10 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
return 0;
}
-static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
- nghttp3_vec *vec, size_t veccnt,
- uint32_t *pflags, void *user_data,
- void *stream_user_data)
+static nghttp3_ssize cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
+ nghttp3_vec *vec, size_t veccnt,
+ uint32_t *pflags, void *user_data,
+ void *stream_user_data)
{
struct Curl_easy *data = stream_user_data;
size_t nread;
@@ -1482,6 +1542,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem,
nva[i].namelen = hreq->header[i].namelen;
nva[i].value = (unsigned char *)hreq->header[i].value;
nva[i].valuelen = hreq->header[i].valuelen;
+ nva[i].flags = NGHTTP3_NV_FLAG_NONE;
}
}
@@ -1550,6 +1611,11 @@ static ssize_t ngh3_stream_send(struct Curl_easy *data,
curl_socket_t sockfd = conn->sock[sockindex];
struct HTTP *stream = data->req.p.http;
+ if(stream->closed) {
+ *curlcode = CURLE_HTTP3;
+ return -1;
+ }
+
if(!stream->h3req) {
CURLcode result = http_request(data, mem, len);
if(result) {
@@ -1626,12 +1692,23 @@ static CURLcode ng_has_connected(struct Curl_easy *data,
if(result)
return result;
infof(data, "Verified certificate just fine");
-#else
+#elif defined(USE_GNUTLS)
result = Curl_gtls_verifyserver(data, conn, conn->quic->ssl, FIRSTSOCKET);
+#elif defined(USE_WOLFSSL)
+ char *snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
+ if(!snihost ||
+ (wolfSSL_check_domain_name(conn->quic->ssl, snihost) == SSL_FAILURE))
+ return CURLE_PEER_FAILED_VERIFICATION;
+ infof(data, "Verified certificate just fine");
#endif
}
else
infof(data, "Skipped certificate verification");
+#ifdef USE_OPENSSL
+ if(data->set.ssl.certinfo)
+ /* asked to gather certificate info */
+ (void)Curl_ossl_certchain(data, conn->quic->ssl);
+#endif
return result;
}
@@ -1704,7 +1781,17 @@ static CURLcode ng_process_ingress(struct Curl_easy *data,
rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts);
if(rv) {
- /* TODO Send CONNECTION_CLOSE if possible */
+ if(!qs->last_error.error_code) {
+ if(rv == NGTCP2_ERR_CRYPTO) {
+ ngtcp2_connection_close_error_set_transport_error_tls_alert(
+ &qs->last_error, ngtcp2_conn_get_tls_alert(qs->qconn), NULL, 0);
+ }
+ else {
+ ngtcp2_connection_close_error_set_transport_error_liberr(
+ &qs->last_error, rv, NULL, 0);
+ }
+ }
+
if(rv == NGTCP2_ERR_CRYPTO)
/* this is a "TLS problem", but a failed certificate verification
is a common reason for this */
@@ -1716,32 +1803,231 @@ static CURLcode ng_process_ingress(struct Curl_easy *data,
return CURLE_OK;
}
+static CURLcode do_sendmsg(size_t *sent, struct Curl_easy *data, int sockfd,
+ struct quicsocket *qs, const uint8_t *pkt,
+ size_t pktlen, size_t gsolen);
+
+static CURLcode send_packet_no_gso(size_t *psent, struct Curl_easy *data,
+ int sockfd, struct quicsocket *qs,
+ const uint8_t *pkt, size_t pktlen,
+ size_t gsolen)
+{
+ const uint8_t *p, *end = pkt + pktlen;
+ size_t sent;
+
+ *psent = 0;
+
+ for(p = pkt; p < end; p += gsolen) {
+ size_t len = CURLMIN(gsolen, (size_t)(end - p));
+ CURLcode curlcode = do_sendmsg(&sent, data, sockfd, qs, p, len, len);
+ if(curlcode != CURLE_OK) {
+ return curlcode;
+ }
+ *psent += sent;
+ }
+
+ return CURLE_OK;
+}
+
+static CURLcode do_sendmsg(size_t *psent, struct Curl_easy *data, int sockfd,
+ struct quicsocket *qs, const uint8_t *pkt,
+ size_t pktlen, size_t gsolen)
+{
+#ifdef HAVE_SENDMSG
+ struct iovec msg_iov;
+ struct msghdr msg = {0};
+ ssize_t sent;
+#if defined(__linux__) && defined(UDP_SEGMENT)
+ uint8_t msg_ctrl[32];
+ struct cmsghdr *cm;
+#endif
+
+ *psent = 0;
+ msg_iov.iov_base = (uint8_t *)pkt;
+ msg_iov.iov_len = pktlen;
+ msg.msg_iov = &msg_iov;
+ msg.msg_iovlen = 1;
+
+#if defined(__linux__) && defined(UDP_SEGMENT)
+ if(pktlen > gsolen) {
+ /* Only set this, when we need it. macOS, for example,
+ * does not seem to like a msg_control of length 0. */
+ msg.msg_control = msg_ctrl;
+ assert(sizeof(msg_ctrl) >= CMSG_SPACE(sizeof(uint16_t)));
+ msg.msg_controllen = CMSG_SPACE(sizeof(uint16_t));
+ cm = CMSG_FIRSTHDR(&msg);
+ cm->cmsg_level = SOL_UDP;
+ cm->cmsg_type = UDP_SEGMENT;
+ cm->cmsg_len = CMSG_LEN(sizeof(uint16_t));
+ *(uint16_t *)(void *)CMSG_DATA(cm) = gsolen & 0xffff;
+ }
+#endif
+
+
+ while((sent = sendmsg(sockfd, &msg, 0)) == -1 && SOCKERRNO == EINTR)
+ ;
+
+ if(sent == -1) {
+ switch(SOCKERRNO) {
+ case EAGAIN:
+#if EAGAIN != EWOULDBLOCK
+ case EWOULDBLOCK:
+#endif
+ return CURLE_AGAIN;
+ case EMSGSIZE:
+ /* UDP datagram is too large; caused by PMTUD. Just let it be lost. */
+ break;
+ case EIO:
+ if(pktlen > gsolen) {
+ /* GSO failure */
+ failf(data, "sendmsg() returned %zd (errno %d); disable GSO", sent,
+ SOCKERRNO);
+ qs->no_gso = TRUE;
+ return send_packet_no_gso(psent, data, sockfd, qs, pkt, pktlen,
+ gsolen);
+ }
+ /* FALLTHROUGH */
+ default:
+ failf(data, "sendmsg() returned %zd (errno %d)", sent, SOCKERRNO);
+ return CURLE_SEND_ERROR;
+ }
+ }
+ else {
+ assert(pktlen == (size_t)sent);
+ }
+#else
+ ssize_t sent;
+ (void)qs;
+ (void)gsolen;
+
+ *psent = 0;
+
+ while((sent = send(sockfd, (const char *)pkt, pktlen, 0)) == -1 &&
+ SOCKERRNO == EINTR)
+ ;
+
+ if(sent == -1) {
+ if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
+ return CURLE_AGAIN;
+ }
+ else {
+ failf(data, "send() returned %zd (errno %d)", sent, SOCKERRNO);
+ if(SOCKERRNO != EMSGSIZE) {
+ return CURLE_SEND_ERROR;
+ }
+ /* UDP datagram is too large; caused by PMTUD. Just let it be
+ lost. */
+ }
+ }
+#endif
+
+ *psent = pktlen;
+
+ return CURLE_OK;
+}
+
+static CURLcode send_packet(size_t *psent, struct Curl_easy *data, int sockfd,
+ struct quicsocket *qs, const uint8_t *pkt,
+ size_t pktlen, size_t gsolen)
+{
+ if(qs->no_gso && pktlen > gsolen) {
+ return send_packet_no_gso(psent, data, sockfd, qs, pkt, pktlen, gsolen);
+ }
+
+ return do_sendmsg(psent, data, sockfd, qs, pkt, pktlen, gsolen);
+}
+
+static void push_blocked_pkt(struct quicsocket *qs, const uint8_t *pkt,
+ size_t pktlen, size_t gsolen)
+{
+ struct blocked_pkt *blkpkt;
+
+ assert(qs->num_blocked_pkt <
+ sizeof(qs->blocked_pkt) / sizeof(qs->blocked_pkt[0]));
+
+ blkpkt = &qs->blocked_pkt[qs->num_blocked_pkt++];
+
+ blkpkt->pkt = pkt;
+ blkpkt->pktlen = pktlen;
+ blkpkt->gsolen = gsolen;
+}
+
+static CURLcode send_blocked_pkt(struct Curl_easy *data, int sockfd,
+ struct quicsocket *qs)
+{
+ size_t sent;
+ CURLcode curlcode;
+ struct blocked_pkt *blkpkt;
+
+ for(; qs->num_blocked_pkt_sent < qs->num_blocked_pkt;
+ ++qs->num_blocked_pkt_sent) {
+ blkpkt = &qs->blocked_pkt[qs->num_blocked_pkt_sent];
+ curlcode = send_packet(&sent, data, sockfd, qs, blkpkt->pkt,
+ blkpkt->pktlen, blkpkt->gsolen);
+
+ if(curlcode) {
+ if(curlcode == CURLE_AGAIN) {
+ blkpkt->pkt += sent;
+ blkpkt->pktlen -= sent;
+ }
+ return curlcode;
+ }
+ }
+
+ qs->num_blocked_pkt = 0;
+ qs->num_blocked_pkt_sent = 0;
+
+ return CURLE_OK;
+}
+
static CURLcode ng_flush_egress(struct Curl_easy *data,
int sockfd,
struct quicsocket *qs)
{
int rv;
- ssize_t sent;
- ssize_t outlen;
- uint8_t out[NGTCP2_MAX_UDP_PAYLOAD_SIZE];
+ size_t sent;
+ ngtcp2_ssize outlen;
+ uint8_t *outpos = qs->pktbuf;
+ size_t max_udp_payload_size =
+ ngtcp2_conn_get_max_tx_udp_payload_size(qs->qconn);
+ size_t path_max_udp_payload_size =
+ ngtcp2_conn_get_path_max_tx_udp_payload_size(qs->qconn);
+ size_t max_pktcnt =
+ CURLMIN(MAX_PKT_BURST, qs->pktbuflen / max_udp_payload_size);
+ size_t pktcnt = 0;
+ size_t gsolen;
ngtcp2_path_storage ps;
ngtcp2_tstamp ts = timestamp();
ngtcp2_tstamp expiry;
ngtcp2_duration timeout;
int64_t stream_id;
- ssize_t veccnt;
+ nghttp3_ssize veccnt;
int fin;
nghttp3_vec vec[16];
- ssize_t ndatalen;
+ ngtcp2_ssize ndatalen;
uint32_t flags;
+ CURLcode curlcode;
rv = ngtcp2_conn_handle_expiry(qs->qconn, ts);
if(rv) {
failf(data, "ngtcp2_conn_handle_expiry returned error: %s",
ngtcp2_strerror(rv));
+ ngtcp2_connection_close_error_set_transport_error_liberr(&qs->last_error,
+ rv, NULL, 0);
return CURLE_SEND_ERROR;
}
+ if(qs->num_blocked_pkt) {
+ curlcode = send_blocked_pkt(data, sockfd, qs);
+ if(curlcode) {
+ if(curlcode == CURLE_AGAIN) {
+ Curl_expire(data, 1, EXPIRE_QUIC);
+ return CURLE_OK;
+ }
+ return curlcode;
+ }
+ }
+
ngtcp2_path_storage_zero(&ps);
for(;;) {
@@ -1755,39 +2041,45 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
if(veccnt < 0) {
failf(data, "nghttp3_conn_writev_stream returned error: %s",
nghttp3_strerror((int)veccnt));
+ ngtcp2_connection_close_error_set_application_error(
+ &qs->last_error,
+ nghttp3_err_infer_quic_app_error_code((int)veccnt), NULL, 0);
return CURLE_SEND_ERROR;
}
}
flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
(fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
- outlen = ngtcp2_conn_writev_stream(qs->qconn, &ps.path, NULL, out,
- sizeof(out),
+ outlen = ngtcp2_conn_writev_stream(qs->qconn, &ps.path, NULL, outpos,
+ max_udp_payload_size,
&ndatalen, flags, stream_id,
(const ngtcp2_vec *)vec, veccnt, ts);
if(outlen == 0) {
+ if(outpos != qs->pktbuf) {
+ curlcode = send_packet(&sent, data, sockfd, qs, qs->pktbuf,
+ outpos - qs->pktbuf, gsolen);
+ if(curlcode) {
+ if(curlcode == CURLE_AGAIN) {
+ push_blocked_pkt(qs, qs->pktbuf + sent, outpos - qs->pktbuf - sent,
+ gsolen);
+ Curl_expire(data, 1, EXPIRE_QUIC);
+ return CURLE_OK;
+ }
+ return curlcode;
+ }
+ }
+
break;
}
if(outlen < 0) {
switch(outlen) {
case NGTCP2_ERR_STREAM_DATA_BLOCKED:
assert(ndatalen == -1);
- rv = nghttp3_conn_block_stream(qs->h3conn, stream_id);
- if(rv) {
- failf(data, "nghttp3_conn_block_stream returned error: %s\n",
- nghttp3_strerror(rv));
- return CURLE_SEND_ERROR;
- }
+ nghttp3_conn_block_stream(qs->h3conn, stream_id);
continue;
case NGTCP2_ERR_STREAM_SHUT_WR:
assert(ndatalen == -1);
- rv = nghttp3_conn_shutdown_stream_write(qs->h3conn, stream_id);
- if(rv) {
- failf(data,
- "nghttp3_conn_shutdown_stream_write returned error: %s\n",
- nghttp3_strerror(rv));
- return CURLE_SEND_ERROR;
- }
+ nghttp3_conn_shutdown_stream_write(qs->h3conn, stream_id);
continue;
case NGTCP2_ERR_WRITE_MORE:
assert(ndatalen >= 0);
@@ -1802,6 +2094,8 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
assert(ndatalen == -1);
failf(data, "ngtcp2_conn_writev_stream returned error: %s",
ngtcp2_strerror((int)outlen));
+ ngtcp2_connection_close_error_set_transport_error_liberr(
+ &qs->last_error, (int)outlen, NULL, 0);
return CURLE_SEND_ERROR;
}
}
@@ -1814,20 +2108,61 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
}
}
- while((sent = send(sockfd, (const char *)out, outlen, 0)) == -1 &&
- SOCKERRNO == EINTR)
- ;
+ outpos += outlen;
- if(sent == -1) {
- if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
- /* TODO Cache packet */
- break;
+ if(pktcnt == 0) {
+ gsolen = outlen;
+ }
+ else if((size_t)outlen > gsolen ||
+ (gsolen > path_max_udp_payload_size &&
+ (size_t)outlen != gsolen)) {
+ /* Packet larger than path_max_udp_payload_size is PMTUD probe
+ packet and it might not be sent because of EMSGSIZE. Send
+ them separately to minimize the loss. */
+ curlcode = send_packet(&sent, data, sockfd, qs, qs->pktbuf,
+ outpos - outlen - qs->pktbuf, gsolen);
+ if(curlcode) {
+ if(curlcode == CURLE_AGAIN) {
+ push_blocked_pkt(qs, qs->pktbuf + sent,
+ outpos - outlen - qs->pktbuf - sent, gsolen);
+ push_blocked_pkt(qs, outpos - outlen, outlen, outlen);
+ Curl_expire(data, 1, EXPIRE_QUIC);
+ return CURLE_OK;
+ }
+ return curlcode;
}
- else {
- failf(data, "send() returned %zd (errno %d)", sent,
- SOCKERRNO);
- return CURLE_SEND_ERROR;
+ curlcode = send_packet(&sent, data, sockfd, qs, outpos - outlen, outlen,
+ outlen);
+ if(curlcode) {
+ if(curlcode == CURLE_AGAIN) {
+ assert(0 == sent);
+ push_blocked_pkt(qs, outpos - outlen, outlen, outlen);
+ Curl_expire(data, 1, EXPIRE_QUIC);
+ return CURLE_OK;
+ }
+ return curlcode;
+ }
+
+ pktcnt = 0;
+ outpos = qs->pktbuf;
+ continue;
+ }
+
+ if(++pktcnt >= max_pktcnt || (size_t)outlen < gsolen) {
+ curlcode = send_packet(&sent, data, sockfd, qs, qs->pktbuf,
+ outpos - qs->pktbuf, gsolen);
+ if(curlcode) {
+ if(curlcode == CURLE_AGAIN) {
+ push_blocked_pkt(qs, qs->pktbuf + sent, outpos - qs->pktbuf - sent,
+ gsolen);
+ Curl_expire(data, 1, EXPIRE_QUIC);
+ return CURLE_OK;
+ }
+ return curlcode;
}
+
+ pktcnt = 0;
+ outpos = qs->pktbuf;
}
}
@@ -1894,4 +2229,26 @@ bool Curl_quic_data_pending(const struct Curl_easy *data)
return Curl_dyn_len(&stream->overflow) > 0;
}
+/*
+ * Called from transfer.c:Curl_readwrite when neither HTTP level read
+ * nor write is performed. It is a good place to handle timer expiry
+ * for QUIC transport.
+ */
+CURLcode Curl_quic_idle(struct Curl_easy *data)
+{
+ struct connectdata *conn = data->conn;
+ curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+ struct quicsocket *qs = conn->quic;
+
+ if(ngtcp2_conn_get_expiry(qs->qconn) > timestamp()) {
+ return CURLE_OK;
+ }
+
+ if(ng_flush_egress(data, sockfd, qs)) {
+ return CURLE_SEND_ERROR;
+ }
+
+ return CURLE_OK;
+}
+
#endif
diff --git a/Utilities/cmcurl/lib/vquic/ngtcp2.h b/Utilities/cmcurl/lib/vquic/ngtcp2.h
index 501453042b..6539f5fef3 100644
--- a/Utilities/cmcurl/lib/vquic/ngtcp2.h
+++ b/Utilities/cmcurl/lib/vquic/ngtcp2.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,20 +20,36 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_NGTCP2
-#include <ngtcp2/ngtcp2.h>
+#ifdef HAVE_NETINET_UDP_H
+#include <netinet/udp.h>
+#endif
+
+#include <ngtcp2/ngtcp2_crypto.h>
#include <nghttp3/nghttp3.h>
#ifdef USE_OPENSSL
#include <openssl/ssl.h>
#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
+#elif defined(USE_WOLFSSL)
+#include <wolfssl/options.h>
+#include <wolfssl/ssl.h>
+#include <wolfssl/quic.h>
#endif
+struct blocked_pkt {
+ const uint8_t *pkt;
+ size_t pktlen;
+ size_t gsolen;
+};
+
struct quicsocket {
struct connectdata *conn; /* point back to the connection */
ngtcp2_conn *qconn;
@@ -42,17 +58,29 @@ struct quicsocket {
uint32_t version;
ngtcp2_settings settings;
ngtcp2_transport_params transport_params;
+ ngtcp2_connection_close_error last_error;
+ ngtcp2_crypto_conn_ref conn_ref;
#ifdef USE_OPENSSL
SSL_CTX *sslctx;
SSL *ssl;
#elif defined(USE_GNUTLS)
gnutls_certificate_credentials_t cred;
gnutls_session_t ssl;
+#elif defined(USE_WOLFSSL)
+ WOLFSSL_CTX *sslctx;
+ WOLFSSL *ssl;
#endif
- /* the last TLS alert description generated by the local endpoint */
- uint8_t tls_alert;
struct sockaddr_storage local_addr;
socklen_t local_addrlen;
+ bool no_gso;
+ uint8_t *pktbuf;
+ size_t pktbuflen;
+ /* the number of entries in blocked_pkt */
+ size_t num_blocked_pkt;
+ /* the number of processed entries in blocked_pkt */
+ size_t num_blocked_pkt_sent;
+ /* the packets blocked by sendmsg (EAGAIN or EWOULDBLOCK) */
+ struct blocked_pkt blocked_pkt[2];
nghttp3_conn *h3conn;
nghttp3_settings h3settings;
diff --git a/Utilities/cmcurl/lib/vquic/quiche.c b/Utilities/cmcurl/lib/vquic/quiche.c
index bfdc966a85..a52a7e8e21 100644
--- a/Utilities/cmcurl/lib/vquic/quiche.c
+++ b/Utilities/cmcurl/lib/vquic/quiche.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -201,23 +203,31 @@ static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
- const char * const ssl_cafile = conn->ssl_config.CAfile;
- const char * const ssl_capath = conn->ssl_config.CApath;
-
if(conn->ssl_config.verifypeer) {
- SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
- /* tell OpenSSL where to find CA certificates that are used to verify
- the server's certificate. */
- if(!SSL_CTX_load_verify_locations(ssl_ctx, ssl_cafile, ssl_capath)) {
- /* Fail if we insist on successfully verifying the server. */
- failf(data, "error setting certificate verify locations:"
- " CAfile: %s CApath: %s",
- ssl_cafile ? ssl_cafile : "none",
- ssl_capath ? ssl_capath : "none");
- return NULL;
+ const char * const ssl_cafile = conn->ssl_config.CAfile;
+ const char * const ssl_capath = conn->ssl_config.CApath;
+ if(ssl_cafile || ssl_capath) {
+ SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
+ /* tell OpenSSL where to find CA certificates that are used to verify
+ the server's certificate. */
+ if(!SSL_CTX_load_verify_locations(ssl_ctx, ssl_cafile, ssl_capath)) {
+ /* Fail if we insist on successfully verifying the server. */
+ failf(data, "error setting certificate verify locations:"
+ " CAfile: %s CApath: %s",
+ ssl_cafile ? ssl_cafile : "none",
+ ssl_capath ? ssl_capath : "none");
+ return NULL;
+ }
+ infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
+ infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
+ }
+#ifdef CURL_CA_FALLBACK
+ else {
+ /* verifying the peer without any CA certificates won't work so
+ use openssl's built-in default as fallback */
+ SSL_CTX_set_default_verify_paths(ssl_ctx);
}
- infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
- infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
+#endif
}
}
return ssl_ctx;
@@ -248,6 +258,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
struct quicsocket *qs = &conn->hequic[sockindex];
char ipbuf[40];
int port;
+ int rv;
#ifdef DEBUG_QUICHE
/* initialize debug log callback only once */
@@ -293,8 +304,16 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
if(result)
return result;
+ qs->local_addrlen = sizeof(qs->local_addr);
+ rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr,
+ &qs->local_addrlen);
+ if(rv == -1)
+ return CURLE_QUIC_CONNECT_ERROR;
+
qs->conn = quiche_conn_new_with_tls((const uint8_t *) qs->scid,
- sizeof(qs->scid), NULL, 0, addr, addrlen,
+ sizeof(qs->scid), NULL, 0,
+ (struct sockaddr *)&qs->local_addr,
+ qs->local_addrlen, addr, addrlen,
qs->cfg, qs->ssl, false);
if(!qs->conn) {
failf(data, "can't create quiche connection");
@@ -397,6 +416,10 @@ static CURLcode quiche_has_connected(struct Curl_easy *data,
qs->cfg = NULL;
qs->conn = NULL;
}
+ if(data->set.ssl.certinfo)
+ /* asked to gather certificate info */
+ (void)Curl_ossl_certchain(data, qs->ssl);
+
return CURLE_OK;
fail:
quiche_h3_config_free(qs->h3config);
@@ -468,6 +491,8 @@ static CURLcode process_ingress(struct Curl_easy *data, int sockfd,
recv_info.from = (struct sockaddr *) &from;
recv_info.from_len = from_len;
+ recv_info.to = (struct sockaddr *) &qs->local_addr;
+ recv_info.to_len = qs->local_addrlen;
recvd = quiche_conn_recv(qs->conn, buf, recvd, &recv_info);
if(recvd == QUICHE_ERR_DONE)
@@ -856,4 +881,15 @@ bool Curl_quic_data_pending(const struct Curl_easy *data)
return FALSE;
}
+/*
+ * Called from transfer.c:Curl_readwrite when neither HTTP level read
+ * nor write is performed. It is a good place to handle timer expiry
+ * for QUIC transport.
+ */
+CURLcode Curl_quic_idle(struct Curl_easy *data)
+{
+ (void)data;
+ return CURLE_OK;
+}
+
#endif
diff --git a/Utilities/cmcurl/lib/vquic/quiche.h b/Utilities/cmcurl/lib/vquic/quiche.h
index 759a20bbac..2da65f5f48 100644
--- a/Utilities/cmcurl/lib/vquic/quiche.h
+++ b/Utilities/cmcurl/lib/vquic/quiche.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -47,6 +49,8 @@ struct quicsocket {
SSL_CTX *sslctx;
SSL *ssl;
bool h3_recving; /* TRUE when in h3-body-reading state */
+ struct sockaddr_storage local_addr;
+ socklen_t local_addrlen;
};
#endif
diff --git a/Utilities/cmcurl/lib/vquic/vquic.c b/Utilities/cmcurl/lib/vquic/vquic.c
index be2a65f454..e52a4f301d 100644
--- a/Utilities/cmcurl/lib/vquic/vquic.c
+++ b/Utilities/cmcurl/lib/vquic/vquic.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vquic/vquic.h b/Utilities/cmcurl/lib/vquic/vquic.h
index 3df138f10e..8f599a8f49 100644
--- a/Utilities/cmcurl/lib/vquic/vquic.h
+++ b/Utilities/cmcurl/lib/vquic/vquic.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vssh/libssh.c b/Utilities/cmcurl/lib/vssh/libssh.c
index 7bf2b04176..0105e4079c 100644
--- a/Utilities/cmcurl/lib/vssh/libssh.c
+++ b/Utilities/cmcurl/lib/vssh/libssh.c
@@ -21,6 +21,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -94,6 +96,13 @@
#include "curl_memory.h"
#include "memdebug.h"
+/* in 0.10.0 or later, ignore deprecated warnings */
+#if defined(__GNUC__) && \
+ (LIBSSH_VERSION_MINOR >= 10) || \
+ (LIBSSH_VERSION_MAJOR > 0)
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
/* A recent macro provided by libssh. Or make our own. */
#ifndef SSH_STRING_FREE_CHAR
#define SSH_STRING_FREE_CHAR(x) \
@@ -954,10 +963,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
rc = sftp_init(sshc->sftp_session);
if(rc != SSH_OK) {
- rc = sftp_get_error(sshc->sftp_session);
failf(data, "Failure initializing sftp session: %s",
ssh_get_error(sshc->ssh_session));
- MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc));
+ MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(SSH_FX_FAILURE));
break;
}
state(data, SSH_SFTP_REALPATH);
@@ -1658,7 +1666,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
if(from_t == CURL_OFFT_FLOW) {
return CURLE_RANGE_ERROR;
}
- while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+ while(*ptr && (ISBLANK(*ptr) || (*ptr == '-')))
ptr++;
to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
if(to_t == CURL_OFFT_FLOW) {
@@ -1970,10 +1978,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
ssh_disconnect(sshc->ssh_session);
- /* conn->sock[FIRSTSOCKET] is closed by ssh_disconnect behind our back,
- explicitly mark it as closed with the memdebug macro: */
- fake_sclose(conn->sock[FIRSTSOCKET]);
- conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;
+ if(!ssh_version(SSH_VERSION_INT(0, 10, 0))) {
+ /* conn->sock[FIRSTSOCKET] is closed by ssh_disconnect behind our back,
+ explicitly mark it as closed with the memdebug macro. This libssh
+ bug is fixed in 0.10.0. */
+ fake_sclose(conn->sock[FIRSTSOCKET]);
+ conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;
+ }
SSH_STRING_FREE_CHAR(sshc->homedir);
data->state.most_recent_ftp_entrypath = NULL;
@@ -2906,32 +2917,33 @@ static void sftp_quote_stat(struct Curl_easy *data)
}
sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
}
- else if(strncasecompare(cmd, "atime", 5)) {
+ else if(strncasecompare(cmd, "atime", 5) ||
+ strncasecompare(cmd, "mtime", 5)) {
time_t date = Curl_getdate_capped(sshc->quote_path1);
+ bool fail = FALSE;
if(date == -1) {
- Curl_safefree(sshc->quote_path1);
- Curl_safefree(sshc->quote_path2);
- failf(data, "Syntax error: incorrect access date format");
- state(data, SSH_SFTP_CLOSE);
- sshc->nextstate = SSH_NO_STATE;
- sshc->actualcode = CURLE_QUOTE_ERROR;
- return;
+ failf(data, "incorrect date format for %.*s", 5, cmd);
+ fail = TRUE;
}
- sshc->quote_attrs->atime = (uint32_t)date;
- sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME;
- }
- else if(strncasecompare(cmd, "mtime", 5)) {
- time_t date = Curl_getdate_capped(sshc->quote_path1);
- if(date == -1) {
+#if SIZEOF_TIME_T > 4
+ else if(date > 0xffffffff) {
+ failf(data, "date overflow");
+ fail = TRUE; /* avoid setting a capped time */
+ }
+#endif
+ if(fail) {
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
- failf(data, "Syntax error: incorrect modification date format");
state(data, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
return;
}
- sshc->quote_attrs->mtime = (uint32_t)date;
+ if(strncasecompare(cmd, "atime", 5))
+ sshc->quote_attrs->atime = (uint32_t)date;
+ else /* mtime */
+ sshc->quote_attrs->mtime = (uint32_t)date;
+
sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME;
}
@@ -2956,7 +2968,7 @@ void Curl_ssh_cleanup(void)
void Curl_ssh_version(char *buffer, size_t buflen)
{
- (void)msnprintf(buffer, buflen, "libssh/%s", CURL_LIBSSH_VERSION);
+ (void)msnprintf(buffer, buflen, "libssh/%s", ssh_version(0));
}
#endif /* USE_LIBSSH */
diff --git a/Utilities/cmcurl/lib/vssh/libssh2.c b/Utilities/cmcurl/lib/vssh/libssh2.c
index d269263864..5a2c0f8bbf 100644
--- a/Utilities/cmcurl/lib/vssh/libssh2.c
+++ b/Utilities/cmcurl/lib/vssh/libssh2.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* #define CURL_LIBSSH2_DEBUG */
@@ -437,9 +439,45 @@ static int sshkeycallback(struct Curl_easy *easy,
#else
#define session_startup(x,y) libssh2_session_startup(x, (int)y)
#endif
+static int convert_ssh2_keytype(int sshkeytype)
+{
+ int keytype = CURLKHTYPE_UNKNOWN;
+ switch(sshkeytype) {
+ case LIBSSH2_HOSTKEY_TYPE_RSA:
+ keytype = CURLKHTYPE_RSA;
+ break;
+ case LIBSSH2_HOSTKEY_TYPE_DSS:
+ keytype = CURLKHTYPE_DSS;
+ break;
+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
+ keytype = CURLKHTYPE_ECDSA;
+ break;
+#endif
+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
+ keytype = CURLKHTYPE_ECDSA;
+ break;
+#endif
+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521
+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
+ keytype = CURLKHTYPE_ECDSA;
+ break;
+#endif
+#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
+ case LIBSSH2_HOSTKEY_TYPE_ED25519:
+ keytype = CURLKHTYPE_ED25519;
+ break;
+#endif
+ }
+ return keytype;
+}
static CURLcode ssh_knownhost(struct Curl_easy *data)
{
+ int sshkeytype = 0;
+ size_t keylen = 0;
+ int rc = 0;
CURLcode result = CURLE_OK;
#ifdef HAVE_LIBSSH2_KNOWNHOST_API
@@ -448,11 +486,8 @@ static CURLcode ssh_knownhost(struct Curl_easy *data)
struct connectdata *conn = data->conn;
struct ssh_conn *sshc = &conn->proto.sshc;
struct libssh2_knownhost *host = NULL;
- int rc;
- int keytype;
- size_t keylen;
const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
- &keylen, &keytype);
+ &keylen, &sshkeytype);
int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
int keybit = 0;
@@ -464,12 +499,12 @@ static CURLcode ssh_knownhost(struct Curl_easy *data)
*/
enum curl_khmatch keymatch;
curl_sshkeycallback func =
- data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
+ data->set.ssh_keyfunc ? data->set.ssh_keyfunc : sshkeycallback;
struct curl_khkey knownkey;
struct curl_khkey *knownkeyp = NULL;
struct curl_khkey foundkey;
- switch(keytype) {
+ switch(sshkeytype) {
case LIBSSH2_HOSTKEY_TYPE_RSA:
keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
break;
@@ -533,16 +568,14 @@ static CURLcode ssh_knownhost(struct Curl_easy *data)
if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
knownkey.key = host->key;
knownkey.len = 0;
- knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
- CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+ knownkey.keytype = convert_ssh2_keytype(sshkeytype);
knownkeyp = &knownkey;
}
/* setup 'foundkey' */
foundkey.key = remotekey;
foundkey.len = keylen;
- foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
- CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+ foundkey.keytype = convert_ssh2_keytype(sshkeytype);
/*
* if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
@@ -639,7 +672,7 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
#ifdef LIBSSH2_HOSTKEY_HASH_SHA256
/* The fingerprint points to static storage (!), don't free() it. */
fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
- LIBSSH2_HOSTKEY_HASH_SHA256);
+ LIBSSH2_HOSTKEY_HASH_SHA256);
#else
const char *hostkey;
size_t len = 0;
@@ -654,8 +687,8 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
if(!fingerprint) {
failf(data,
- "Denied establishing ssh session: sha256 fingerprint "
- "not available");
+ "Denied establishing ssh session: sha256 fingerprint "
+ "not available");
state(data, SSH_SESSION_FREE);
sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
return sshc->actualcode;
@@ -715,7 +748,7 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
const char *fingerprint = NULL;
fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
- LIBSSH2_HOSTKEY_HASH_MD5);
+ LIBSSH2_HOSTKEY_HASH_MD5);
if(fingerprint) {
/* The fingerprint points to static storage (!), don't free() it. */
@@ -748,7 +781,31 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
}
if(!pubkey_md5 && !pubkey_sha256) {
- return ssh_knownhost(data);
+ if(data->set.ssh_hostkeyfunc) {
+ size_t keylen = 0;
+ int sshkeytype = 0;
+ int rc = 0;
+ /* we handle the process to the callback*/
+ const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
+ &keylen, &sshkeytype);
+ if(remotekey) {
+ int keytype = convert_ssh2_keytype(sshkeytype);
+ Curl_set_in_callback(data, true);
+ rc = data->set.ssh_hostkeyfunc(data->set.ssh_hostkeyfunc_userp,
+ keytype, remotekey, keylen);
+ Curl_set_in_callback(data, false);
+ if(rc!= CURLKHMATCH_OK) {
+ state(data, SSH_SESSION_FREE);
+ }
+ }
+ else {
+ state(data, SSH_SESSION_FREE);
+ }
+ return CURLE_OK;
+ }
+ else {
+ return ssh_knownhost(data);
+ }
}
else {
/* as we already matched, we skip the check for known hosts */
@@ -1698,32 +1755,35 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
break;
}
}
- else if(strncasecompare(cmd, "atime", 5)) {
+ else if(strncasecompare(cmd, "atime", 5) ||
+ strncasecompare(cmd, "mtime", 5)) {
time_t date = Curl_getdate_capped(sshc->quote_path1);
+ bool fail = FALSE;
+
if(date == -1) {
- Curl_safefree(sshc->quote_path1);
- Curl_safefree(sshc->quote_path2);
- failf(data, "Syntax error: incorrect access date format");
- state(data, SSH_SFTP_CLOSE);
- sshc->nextstate = SSH_NO_STATE;
- sshc->actualcode = CURLE_QUOTE_ERROR;
- break;
+ failf(data, "incorrect date format for %.*s", 5, cmd);
+ fail = TRUE;
}
- sshp->quote_attrs.atime = (unsigned long)date;
- sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
- }
- else if(strncasecompare(cmd, "mtime", 5)) {
- time_t date = Curl_getdate_capped(sshc->quote_path1);
- if(date == -1) {
+#if SIZEOF_TIME_T > SIZEOF_LONG
+ if(date > 0xffffffff) {
+ /* if 'long' can't old >32bit, this date cannot be sent */
+ failf(data, "date overflow");
+ fail = TRUE;
+ }
+#endif
+ if(fail) {
Curl_safefree(sshc->quote_path1);
Curl_safefree(sshc->quote_path2);
- failf(data, "Syntax error: incorrect modification date format");
state(data, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = CURLE_QUOTE_ERROR;
break;
}
- sshp->quote_attrs.mtime = (unsigned long)date;
+ if(strncasecompare(cmd, "atime", 5))
+ sshp->quote_attrs.atime = (unsigned long)date;
+ else /* mtime */
+ sshp->quote_attrs.mtime = (unsigned long)date;
+
sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
}
@@ -2278,7 +2338,8 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
((sshp->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
LIBSSH2_SFTP_S_IFLNK)) {
Curl_dyn_init(&sshp->readdir_link, PATH_MAX);
- result = Curl_dyn_add(&sshp->readdir_link, sshp->path);
+ result = Curl_dyn_addf(&sshp->readdir_link, "%s%s", sshp->path,
+ sshp->readdir_filename);
state(data, SSH_SFTP_READDIR_LINK);
if(!result)
break;
@@ -2445,7 +2506,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
if(from_t == CURL_OFFT_FLOW)
return CURLE_RANGE_ERROR;
- while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+ while(*ptr && (ISBLANK(*ptr) || (*ptr == '-')))
ptr++;
to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
if(to_t == CURL_OFFT_FLOW)
diff --git a/Utilities/cmcurl/lib/vssh/ssh.h b/Utilities/cmcurl/lib/vssh/ssh.h
index 30d82e5764..13bb8aa2d6 100644
--- a/Utilities/cmcurl/lib/vssh/ssh.h
+++ b/Utilities/cmcurl/lib/vssh/ssh.h
@@ -20,14 +20,16 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
-#if defined(HAVE_LIBSSH2_H)
+#if defined(USE_LIBSSH2)
#include <libssh2.h>
#include <libssh2_sftp.h>
-#elif defined(HAVE_LIBSSH_LIBSSH_H)
+#elif defined(USE_LIBSSH)
#include <libssh/libssh.h>
#include <libssh/sftp.h>
#elif defined(USE_WOLFSSH)
@@ -209,11 +211,7 @@ struct ssh_conn {
#endif /* USE_LIBSSH */
};
-#if defined(USE_LIBSSH)
-
-#define CURL_LIBSSH_VERSION ssh_version(0)
-
-#elif defined(USE_LIBSSH2)
+#if defined(USE_LIBSSH2)
/* Feature detection based on version numbers to better work with
non-configure platforms */
diff --git a/Utilities/cmcurl/lib/vssh/wolfssh.c b/Utilities/cmcurl/lib/vssh/wolfssh.c
index 85f2941966..c2f85f3fe5 100644
--- a/Utilities/cmcurl/lib/vssh/wolfssh.c
+++ b/Utilities/cmcurl/lib/vssh/wolfssh.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/bearssl.c b/Utilities/cmcurl/lib/vtls/bearssl.c
index 91f4416e8f..1221ce8c84 100644
--- a/Utilities/cmcurl/lib/vtls/bearssl.c
+++ b/Utilities/cmcurl/lib/vtls/bearssl.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -74,9 +76,9 @@ struct cafile_parser {
#define CAFILE_SOURCE_PATH 1
#define CAFILE_SOURCE_BLOB 2
struct cafile_source {
- const int type;
- const char * const data;
- const size_t len;
+ int type;
+ const char *data;
+ size_t len;
};
static void append_dn(void *ctx, const void *buf, size_t len)
@@ -616,11 +618,11 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
}
if(ca_info_blob) {
- struct cafile_source source = {
- CAFILE_SOURCE_BLOB,
- ca_info_blob->data,
- ca_info_blob->len,
- };
+ struct cafile_source source;
+ source.type = CAFILE_SOURCE_BLOB;
+ source.data = ca_info_blob->data;
+ source.len = ca_info_blob->len;
+
ret = load_cafile(&source, &backend->anchors, &backend->anchors_len);
if(ret != CURLE_OK) {
if(verifypeer) {
@@ -633,11 +635,11 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
}
if(ssl_cafile) {
- struct cafile_source source = {
- CAFILE_SOURCE_PATH,
- ssl_cafile,
- 0,
- };
+ struct cafile_source source;
+ source.type = CAFILE_SOURCE_PATH;
+ source.data = ssl_cafile;
+ source.len = 0;
+
ret = load_cafile(&source, &backend->anchors, &backend->anchors_len);
if(ret != CURLE_OK) {
if(verifypeer) {
@@ -873,14 +875,14 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data,
#ifdef USE_HTTP2
if(!strcmp(protocol, ALPN_H2))
- conn->negnpn = CURL_HTTP_VERSION_2;
+ conn->alpn = CURL_HTTP_VERSION_2;
else
#endif
if(!strcmp(protocol, ALPN_HTTP_1_1))
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ conn->alpn = CURL_HTTP_VERSION_1_1;
else
infof(data, "ALPN, unrecognized protocol %s", protocol);
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
else
diff --git a/Utilities/cmcurl/lib/vtls/bearssl.h b/Utilities/cmcurl/lib/vtls/bearssl.h
index d72b7d0e26..5125359961 100644
--- a/Utilities/cmcurl/lib/vtls/bearssl.h
+++ b/Utilities/cmcurl/lib/vtls/bearssl.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019 - 2020, Michael Forney, <mforney@mforney.org>
+ * Copyright (C) 2019 - 2022, Michael Forney, <mforney@mforney.org>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/gskit.c b/Utilities/cmcurl/lib/vtls/gskit.c
index 7a65f92f20..4ee4edea6c 100644
--- a/Utilities/cmcurl/lib/vtls/gskit.c
+++ b/Utilities/cmcurl/lib/vtls/gskit.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/gskit.h b/Utilities/cmcurl/lib/vtls/gskit.h
index 202df7e07c..cf923f6b85 100644
--- a/Utilities/cmcurl/lib/vtls/gskit.h
+++ b/Utilities/cmcurl/lib/vtls/gskit.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/gtls.c b/Utilities/cmcurl/lib/vtls/gtls.c
index dd82755852..cf3dbc5238 100644
--- a/Utilities/cmcurl/lib/vtls/gtls.c
+++ b/Utilities/cmcurl/lib/vtls/gtls.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -43,6 +45,7 @@
#include "inet_pton.h"
#include "gtls.h"
#include "vtls.h"
+#include "vauth/vauth.h"
#include "parsedate.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
@@ -446,7 +449,7 @@ gtls_connect_step1(struct Curl_easy *data,
#ifdef USE_GNUTLS_SRP
if((SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) &&
- Curl_allow_auth_to_host(data)) {
+ Curl_auth_allowed_to_host(data)) {
infof(data, "Using TLS-SRP username: %s",
SSL_SET_OPTION(primary.username));
@@ -1272,19 +1275,19 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
if(proto.size == ALPN_H2_LENGTH &&
!memcmp(ALPN_H2, proto.data,
ALPN_H2_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_2;
+ conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(proto.size == ALPN_HTTP_1_1_LENGTH &&
!memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ conn->alpn = CURL_HTTP_VERSION_1_1;
}
}
else
infof(data, VTLS_INFOF_NO_ALPN);
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
diff --git a/Utilities/cmcurl/lib/vtls/gtls.h b/Utilities/cmcurl/lib/vtls/gtls.h
index 642d5f093a..abade73f80 100644
--- a/Utilities/cmcurl/lib/vtls/gtls.h
+++ b/Utilities/cmcurl/lib/vtls/gtls.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/hostcheck.c b/Utilities/cmcurl/lib/vtls/hostcheck.c
index 8dc97a27d0..2a648f20a9 100644
--- a/Utilities/cmcurl/lib/vtls/hostcheck.c
+++ b/Utilities/cmcurl/lib/vtls/hostcheck.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/hostcheck.h b/Utilities/cmcurl/lib/vtls/hostcheck.h
index aa966403dd..d3c4eab56d 100644
--- a/Utilities/cmcurl/lib/vtls/hostcheck.h
+++ b/Utilities/cmcurl/lib/vtls/hostcheck.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include <curl/curl.h>
diff --git a/Utilities/cmcurl/lib/vtls/keylog.c b/Utilities/cmcurl/lib/vtls/keylog.c
index a45945f8f5..1952a690ca 100644
--- a/Utilities/cmcurl/lib/vtls/keylog.c
+++ b/Utilities/cmcurl/lib/vtls/keylog.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,10 +18,13 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#include "keylog.h"
+#include <curl/curl.h>
/* The last #include files should be: */
#include "curl_memory.h"
diff --git a/Utilities/cmcurl/lib/vtls/keylog.h b/Utilities/cmcurl/lib/vtls/keylog.h
index 63626da90a..5d3c675b3e 100644
--- a/Utilities/cmcurl/lib/vtls/keylog.h
+++ b/Utilities/cmcurl/lib/vtls/keylog.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls.c b/Utilities/cmcurl/lib/vtls/mbedtls.c
index b60b9cac50..fbde8976eb 100644
--- a/Utilities/cmcurl/lib/vtls/mbedtls.c
+++ b/Utilities/cmcurl/lib/vtls/mbedtls.c
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -819,19 +821,19 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
#ifdef USE_HTTP2
if(!strncmp(next_protocol, ALPN_H2, ALPN_H2_LENGTH) &&
!next_protocol[ALPN_H2_LENGTH]) {
- conn->negnpn = CURL_HTTP_VERSION_2;
+ conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) &&
!next_protocol[ALPN_HTTP_1_1_LENGTH]) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ conn->alpn = CURL_HTTP_VERSION_1_1;
}
}
else {
infof(data, VTLS_INFOF_NO_ALPN);
}
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls.h b/Utilities/cmcurl/lib/vtls/mbedtls.h
index 1abd331ea9..ec3b43bf9c 100644
--- a/Utilities/cmcurl/lib/vtls/mbedtls.h
+++ b/Utilities/cmcurl/lib/vtls/mbedtls.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
@@ -21,6 +21,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.c b/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.c
index 751755c239..3971e69b25 100644
--- a/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.c
+++ b/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2013 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.h b/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.h
index e40dfc8d6a..3a50d03817 100644
--- a/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.h
+++ b/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2013 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
@@ -21,6 +21,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/nss.c b/Utilities/cmcurl/lib/vtls/nss.c
index cb0509ff5b..12cf618f56 100644
--- a/Utilities/cmcurl/lib/vtls/nss.c
+++ b/Utilities/cmcurl/lib/vtls/nss.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -334,7 +336,7 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc *model,
char name[MAX_CIPHER_LENGTH + 1];
size_t len;
bool found = FALSE;
- while((*cipher) && (ISSPACE(*cipher)))
+ while((*cipher) && (ISBLANK(*cipher)))
++cipher;
end = strpbrk(cipher, ":, ");
@@ -848,7 +850,7 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
unsigned int buflen;
SSLNextProtoState state;
- if(!conn->bits.tls_enable_npn && !conn->bits.tls_enable_alpn) {
+ if(!conn->bits.tls_enable_alpn) {
return;
}
@@ -869,21 +871,21 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
infof(data, VTLS_INFOF_ALPN_ACCEPTED_LEN_1STR, buflen, buf);
break;
#endif
- case SSL_NEXT_PROTO_NEGOTIATED:
- infof(data, "NPN, server accepted to use %.*s", buflen, buf);
+ default:
+ /* ignore SSL_NEXT_PROTO_NEGOTIATED */
break;
}
#ifdef USE_HTTP2
if(buflen == ALPN_H2_LENGTH &&
!memcmp(ALPN_H2, buf, ALPN_H2_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_2;
+ conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(buflen == ALPN_HTTP_1_1_LENGTH &&
!memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ conn->alpn = CURL_HTTP_VERSION_1_1;
}
/* This callback might get called when PR_Recv() is used within
@@ -891,7 +893,7 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
* be any "bundle" associated with the connection anymore.
*/
if(conn->bundle)
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
}
@@ -934,8 +936,8 @@ static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data,
if(cipherInfo.symCipher != ssl_calg_aes_gcm)
goto end;
- /* Enforce ALPN or NPN to do False Start, as an indicator of server
- * compatibility. */
+ /* Enforce ALPN to do False Start, as an indicator of server
+ compatibility. */
rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn,
&negotiatedExtension);
if(rv != SECSuccess || !negotiatedExtension) {
@@ -2134,12 +2136,6 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
}
#endif
-#ifdef SSL_ENABLE_NPN
- if(SSL_OptionSet(backend->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
- ? PR_TRUE : PR_FALSE) != SECSuccess)
- goto error;
-#endif
-
#ifdef SSL_ENABLE_ALPN
if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
? PR_TRUE : PR_FALSE) != SECSuccess)
@@ -2158,15 +2154,15 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
}
#endif
-#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN)
- if(conn->bits.tls_enable_npn || conn->bits.tls_enable_alpn) {
+#if defined(SSL_ENABLE_ALPN)
+ if(conn->bits.tls_enable_alpn) {
int cur = 0;
unsigned char protocols[128];
#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
- && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
+ && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
#endif
) {
protocols[cur++] = ALPN_H2_LENGTH;
diff --git a/Utilities/cmcurl/lib/vtls/nssg.h b/Utilities/cmcurl/lib/vtls/nssg.h
index 37b364647b..454a38f1fb 100644
--- a/Utilities/cmcurl/lib/vtls/nssg.h
+++ b/Utilities/cmcurl/lib/vtls/nssg.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index 5d1203b759..0dc695d7f4 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -27,7 +29,7 @@
#include "curl_setup.h"
-#ifdef USE_OPENSSL
+#if defined(USE_QUICHE) || defined(USE_OPENSSL)
#include <limits.h>
@@ -53,6 +55,7 @@
#include "slist.h"
#include "select.h"
#include "vtls.h"
+#include "vauth/vauth.h"
#include "keylog.h"
#include "strcase.h"
#include "hostcheck.h"
@@ -76,10 +79,6 @@
#include <openssl/buffer.h>
#include <openssl/pkcs12.h>
-#ifdef USE_AMISSL
-#include "amigaos.h"
-#endif
-
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP)
#include <openssl/ocsp.h>
#endif
@@ -275,6 +274,344 @@ struct ssl_backend_data {
#endif
};
+#define push_certinfo(_label, _num) \
+do { \
+ long info_len = BIO_get_mem_data(mem, &ptr); \
+ Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \
+ if(1 != BIO_reset(mem)) \
+ break; \
+} while(0)
+
+static void pubkey_show(struct Curl_easy *data,
+ BIO *mem,
+ int num,
+ const char *type,
+ const char *name,
+ const BIGNUM *bn)
+{
+ char *ptr;
+ char namebuf[32];
+
+ msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
+
+ if(bn)
+ BN_print(mem, bn);
+ push_certinfo(namebuf, num);
+}
+
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#define print_pubkey_BN(_type, _name, _num) \
+ pubkey_show(data, mem, _num, #_type, #_name, _name)
+
+#else
+#define print_pubkey_BN(_type, _name, _num) \
+do { \
+ if(_type->_name) { \
+ pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
+ } \
+} while(0)
+#endif
+
+static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
+{
+ int i, ilen;
+
+ ilen = (int)len;
+ if(ilen < 0)
+ return 1; /* buffer too big */
+
+ i = i2t_ASN1_OBJECT(buf, ilen, a);
+
+ if(i >= ilen)
+ return 1; /* buffer too small */
+
+ return 0;
+}
+
+static void X509V3_ext(struct Curl_easy *data,
+ int certnum,
+ CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
+{
+ int i;
+
+ if((int)sk_X509_EXTENSION_num(exts) <= 0)
+ /* no extensions, bail out */
+ return;
+
+ for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) {
+ ASN1_OBJECT *obj;
+ X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+ BUF_MEM *biomem;
+ char namebuf[128];
+ BIO *bio_out = BIO_new(BIO_s_mem());
+
+ if(!bio_out)
+ return;
+
+ obj = X509_EXTENSION_get_object(ext);
+
+ asn1_object_dump(obj, namebuf, sizeof(namebuf));
+
+ if(!X509V3_EXT_print(bio_out, ext, 0, 0))
+ ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
+
+ BIO_get_mem_ptr(bio_out, &biomem);
+ Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data,
+ biomem->length);
+ BIO_free(bio_out);
+ }
+}
+
+#ifdef OPENSSL_IS_BORINGSSL
+typedef size_t numcert_t;
+#else
+typedef int numcert_t;
+#endif
+
+CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl)
+{
+ CURLcode result;
+ STACK_OF(X509) *sk;
+ int i;
+ numcert_t numcerts;
+ BIO *mem;
+
+ DEBUGASSERT(ssl);
+
+ sk = SSL_get_peer_cert_chain(ssl);
+ if(!sk) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ numcerts = sk_X509_num(sk);
+
+ result = Curl_ssl_init_certinfo(data, (int)numcerts);
+ if(result) {
+ return result;
+ }
+
+ mem = BIO_new(BIO_s_mem());
+ if(!mem) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ for(i = 0; i < (int)numcerts; i++) {
+ ASN1_INTEGER *num;
+ X509 *x = sk_X509_value(sk, i);
+ EVP_PKEY *pubkey = NULL;
+ int j;
+ char *ptr;
+ const ASN1_BIT_STRING *psig = NULL;
+
+ X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
+ push_certinfo("Subject", i);
+
+ X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
+ push_certinfo("Issuer", i);
+
+ BIO_printf(mem, "%lx", X509_get_version(x));
+ push_certinfo("Version", i);
+
+ num = X509_get_serialNumber(x);
+ if(num->type == V_ASN1_NEG_INTEGER)
+ BIO_puts(mem, "-");
+ for(j = 0; j < num->length; j++)
+ BIO_printf(mem, "%02x", num->data[j]);
+ push_certinfo("Serial Number", i);
+
+#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
+ {
+ const X509_ALGOR *sigalg = NULL;
+ X509_PUBKEY *xpubkey = NULL;
+ ASN1_OBJECT *pubkeyoid = NULL;
+
+ X509_get0_signature(&psig, &sigalg, x);
+ if(sigalg) {
+ i2a_ASN1_OBJECT(mem, sigalg->algorithm);
+ push_certinfo("Signature Algorithm", i);
+ }
+
+ xpubkey = X509_get_X509_PUBKEY(x);
+ if(xpubkey) {
+ X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey);
+ if(pubkeyoid) {
+ i2a_ASN1_OBJECT(mem, pubkeyoid);
+ push_certinfo("Public Key Algorithm", i);
+ }
+ }
+
+ X509V3_ext(data, i, X509_get0_extensions(x));
+ }
+#else
+ {
+ /* before OpenSSL 1.0.2 */
+ X509_CINF *cinf = x->cert_info;
+
+ i2a_ASN1_OBJECT(mem, cinf->signature->algorithm);
+ push_certinfo("Signature Algorithm", i);
+
+ i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm);
+ push_certinfo("Public Key Algorithm", i);
+
+ X509V3_ext(data, i, cinf->extensions);
+
+ psig = x->signature;
+ }
+#endif
+
+ ASN1_TIME_print(mem, X509_get0_notBefore(x));
+ push_certinfo("Start date", i);
+
+ ASN1_TIME_print(mem, X509_get0_notAfter(x));
+ push_certinfo("Expire date", i);
+
+ pubkey = X509_get_pubkey(x);
+ if(!pubkey)
+ infof(data, " Unable to load public key");
+ else {
+ int pktype;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+ pktype = EVP_PKEY_id(pubkey);
+#else
+ pktype = pubkey->type;
+#endif
+ switch(pktype) {
+ case EVP_PKEY_RSA:
+ {
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ RSA *rsa;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+ rsa = EVP_PKEY_get0_RSA(pubkey);
+#else
+ rsa = pubkey->pkey.rsa;
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
+
+ {
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(n);
+ DECLARE_PKEY_PARAM_BIGNUM(e);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e);
+#else
+ RSA_get0_key(rsa, &n, &e, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
+ BIO_printf(mem, "%d", BN_num_bits(n));
+#else
+ BIO_printf(mem, "%d", BN_num_bits(rsa->n));
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
+ push_certinfo("RSA Public Key", i);
+ print_pubkey_BN(rsa, n, i);
+ print_pubkey_BN(rsa, e, i);
+ FREE_PKEY_PARAM_BIGNUM(n);
+ FREE_PKEY_PARAM_BIGNUM(e);
+ }
+
+ break;
+ }
+ case EVP_PKEY_DSA:
+ {
+#ifndef OPENSSL_NO_DSA
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ DSA *dsa;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+ dsa = EVP_PKEY_get0_DSA(pubkey);
+#else
+ dsa = pubkey->pkey.dsa;
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
+ {
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(p);
+ DECLARE_PKEY_PARAM_BIGNUM(q);
+ DECLARE_PKEY_PARAM_BIGNUM(g);
+ DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
+ DSA_get0_pqg(dsa, &p, &q, &g);
+ DSA_get0_key(dsa, &pub_key, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
+ print_pubkey_BN(dsa, p, i);
+ print_pubkey_BN(dsa, q, i);
+ print_pubkey_BN(dsa, g, i);
+ print_pubkey_BN(dsa, pub_key, i);
+ FREE_PKEY_PARAM_BIGNUM(p);
+ FREE_PKEY_PARAM_BIGNUM(q);
+ FREE_PKEY_PARAM_BIGNUM(g);
+ FREE_PKEY_PARAM_BIGNUM(pub_key);
+ }
+#endif /* !OPENSSL_NO_DSA */
+ break;
+ }
+ case EVP_PKEY_DH:
+ {
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ DH *dh;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+ dh = EVP_PKEY_get0_DH(pubkey);
+#else
+ dh = pubkey->pkey.dh;
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
+ {
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(p);
+ DECLARE_PKEY_PARAM_BIGNUM(q);
+ DECLARE_PKEY_PARAM_BIGNUM(g);
+ DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
+ DH_get0_pqg(dh, &p, &q, &g);
+ DH_get0_key(dh, &pub_key, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
+ print_pubkey_BN(dh, p, i);
+ print_pubkey_BN(dh, q, i);
+ print_pubkey_BN(dh, g, i);
+#else
+ print_pubkey_BN(dh, p, i);
+ print_pubkey_BN(dh, g, i);
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
+ print_pubkey_BN(dh, pub_key, i);
+ FREE_PKEY_PARAM_BIGNUM(p);
+ FREE_PKEY_PARAM_BIGNUM(q);
+ FREE_PKEY_PARAM_BIGNUM(g);
+ FREE_PKEY_PARAM_BIGNUM(pub_key);
+ }
+ break;
+ }
+ }
+ EVP_PKEY_free(pubkey);
+ }
+
+ if(psig) {
+ for(j = 0; j < psig->length; j++)
+ BIO_printf(mem, "%02x:", psig->data[j]);
+ push_certinfo("Signature", i);
+ }
+
+ PEM_write_bio_X509(mem, x);
+ push_certinfo("Cert", i);
+ }
+
+ BIO_free(mem);
+
+ return CURLE_OK;
+}
+
+#endif /* quiche or OpenSSL */
+
+#ifdef USE_OPENSSL
+
static bool ossl_associate_connection(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
@@ -486,36 +823,19 @@ static CURLcode ossl_seed(struct Curl_easy *data)
return CURLE_SSL_CONNECT_ERROR;
#else
-#ifndef RANDOM_FILE
- /* if RANDOM_FILE isn't defined, we only perform this if an option tells
- us to! */
- if(data->set.str[STRING_SSL_RANDOM_FILE])
-#define RANDOM_FILE "" /* doesn't matter won't be used */
+#ifdef RANDOM_FILE
+ RAND_load_file(RANDOM_FILE, RAND_LOAD_LENGTH);
+ if(rand_enough())
+ return CURLE_OK;
#endif
- {
- /* let the option override the define */
- RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
- data->set.str[STRING_SSL_RANDOM_FILE]:
- RANDOM_FILE),
- RAND_LOAD_LENGTH);
- if(rand_enough())
- return CURLE_OK;
- }
-#if defined(HAVE_RAND_EGD)
- /* only available in OpenSSL 0.9.5 and later */
+#if defined(HAVE_RAND_EGD) && defined(EGD_SOCKET)
+ /* available in OpenSSL 0.9.5 and later */
/* EGD_SOCKET is set at configure time or not at all */
-#ifndef EGD_SOCKET
- /* If we don't have the define set, we only do this if the egd-option
- is set */
- if(data->set.str[STRING_SSL_EGDSOCKET])
-#define EGD_SOCKET "" /* doesn't matter won't be used */
-#endif
{
/* If there's an option and a define, the option overrides the
define */
- int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
- data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
+ int ret = RAND_egd(EGD_SOCKET);
if(-1 != ret) {
if(rand_enough())
return CURLE_OK;
@@ -814,9 +1134,10 @@ int cert_stuff(struct Curl_easy *data,
SSL_CTX_use_certificate_chain_file(ctx, cert_file);
if(cert_use_result != 1) {
failf(data,
- "could not load PEM client certificate, " OSSL_PACKAGE
+ "could not load PEM client certificate from %s, " OSSL_PACKAGE
" error %s, "
"(no key found, wrong pass phrase, or wrong file format?)",
+ (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file),
ossl_strerror(ERR_get_error(), error_buffer,
sizeof(error_buffer)) );
return 0;
@@ -834,9 +1155,10 @@ int cert_stuff(struct Curl_easy *data,
SSL_CTX_use_certificate_file(ctx, cert_file, file_type);
if(cert_use_result != 1) {
failf(data,
- "could not load ASN1 client certificate, " OSSL_PACKAGE
+ "could not load ASN1 client certificate from %s, " OSSL_PACKAGE
" error %s, "
"(no key found, wrong pass phrase, or wrong file format?)",
+ (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file),
ossl_strerror(ERR_get_error(), error_buffer,
sizeof(error_buffer)) );
return 0;
@@ -889,8 +1211,9 @@ int cert_stuff(struct Curl_easy *data,
}
if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
- failf(data, "unable to set client certificate");
- X509_free(params.cert);
+ failf(data, "unable to set client certificate [%s]",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)));
return 0;
}
X509_free(params.cert); /* we don't need the handle any more... */
@@ -1013,11 +1336,7 @@ int cert_stuff(struct Curl_easy *data,
fail:
EVP_PKEY_free(pri);
X509_free(x509);
-#ifdef USE_AMISSL
- sk_X509_pop_free(ca, Curl_amiga_X509_free);
-#else
sk_X509_pop_free(ca, X509_free);
-#endif
if(!cert_done)
return 0; /* failure! */
break;
@@ -2276,14 +2595,6 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
# define HAS_ALPN 1
#endif
-/* Check for OpenSSL 1.0.1 which has NPN support. */
-#undef HAS_NPN
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L \
- && !defined(OPENSSL_NO_TLSEXT) \
- && !defined(OPENSSL_NO_NEXTPROTONEG)
-# define HAS_NPN 1
-#endif
-
/* Check for OpenSSL 1.1.0 which has set_{min,max}_proto_version(). */
#undef HAS_MODERN_SET_PROTO_VER
#if OPENSSL_VERSION_NUMBER >= 0x10100000L \
@@ -2292,64 +2603,6 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
# define HAS_MODERN_SET_PROTO_VER 1
#endif
-#ifdef HAS_NPN
-
-/*
- * in is a list of length prefixed strings. this function has to select
- * the protocol we want to use from the list and write its string into out.
- */
-
-static int
-select_next_protocol(unsigned char **out, unsigned char *outlen,
- const unsigned char *in, unsigned int inlen,
- const char *key, unsigned int keylen)
-{
- unsigned int i;
- for(i = 0; i + keylen <= inlen; i += in[i] + 1) {
- if(memcmp(&in[i + 1], key, keylen) == 0) {
- *out = (unsigned char *) &in[i + 1];
- *outlen = in[i];
- return 0;
- }
- }
- return -1;
-}
-
-static int
-select_next_proto_cb(SSL *ssl,
- unsigned char **out, unsigned char *outlen,
- const unsigned char *in, unsigned int inlen,
- void *arg)
-{
- struct Curl_easy *data = (struct Curl_easy *)arg;
- struct connectdata *conn = data->conn;
- (void)ssl;
-
-#ifdef USE_HTTP2
- if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
- !select_next_protocol(out, outlen, in, inlen, ALPN_H2, ALPN_H2_LENGTH)) {
- infof(data, "NPN, negotiated HTTP2 (%s)", ALPN_H2);
- conn->negnpn = CURL_HTTP_VERSION_2;
- return SSL_TLSEXT_ERR_OK;
- }
-#endif
-
- if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1,
- ALPN_HTTP_1_1_LENGTH)) {
- infof(data, "NPN, negotiated HTTP1.1");
- conn->negnpn = CURL_HTTP_VERSION_1_1;
- return SSL_TLSEXT_ERR_OK;
- }
-
- infof(data, "NPN, no overlap, use HTTP1.1");
- *out = (unsigned char *)ALPN_HTTP_1_1;
- *outlen = ALPN_HTTP_1_1_LENGTH;
- conn->negnpn = CURL_HTTP_VERSION_1_1;
-
- return SSL_TLSEXT_ERR_OK;
-}
-#endif /* HAS_NPN */
-
#ifdef HAS_MODERN_SET_PROTO_VER
static CURLcode
set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
@@ -2840,11 +3093,6 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
SSL_CTX_set_options(backend->ctx, ctx_options);
-#ifdef HAS_NPN
- if(conn->bits.tls_enable_npn)
- SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, data);
-#endif
-
#ifdef HAS_ALPN
if(conn->bits.tls_enable_alpn) {
int cur = 0;
@@ -2934,7 +3182,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#ifdef USE_OPENSSL_SRP
if((ssl_authtype == CURL_TLSAUTH_SRP) &&
- Curl_allow_auth_to_host(data)) {
+ Curl_auth_allowed_to_host(data)) {
char * const ssl_username = SSL_SET_OPTION(primary.username);
char * const ssl_password = SSL_SET_OPTION(primary.password);
infof(data, "Using TLS-SRP username: %s", ssl_username);
@@ -3472,19 +3720,19 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
#ifdef USE_HTTP2
if(len == ALPN_H2_LENGTH &&
!memcmp(ALPN_H2, neg_protocol, len)) {
- conn->negnpn = CURL_HTTP_VERSION_2;
+ conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(len == ALPN_HTTP_1_1_LENGTH &&
!memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ conn->alpn = CURL_HTTP_VERSION_1_1;
}
}
else
infof(data, VTLS_INFOF_NO_ALPN);
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
@@ -3493,342 +3741,6 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
}
}
-static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
-{
- int i, ilen;
-
- ilen = (int)len;
- if(ilen < 0)
- return 1; /* buffer too big */
-
- i = i2t_ASN1_OBJECT(buf, ilen, a);
-
- if(i >= ilen)
- return 1; /* buffer too small */
-
- return 0;
-}
-
-#define push_certinfo(_label, _num) \
-do { \
- long info_len = BIO_get_mem_data(mem, &ptr); \
- Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \
- if(1 != BIO_reset(mem)) \
- break; \
-} while(0)
-
-static void pubkey_show(struct Curl_easy *data,
- BIO *mem,
- int num,
- const char *type,
- const char *name,
- const BIGNUM *bn)
-{
- char *ptr;
- char namebuf[32];
-
- msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
-
- if(bn)
- BN_print(mem, bn);
- push_certinfo(namebuf, num);
-}
-
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
-#define print_pubkey_BN(_type, _name, _num) \
- pubkey_show(data, mem, _num, #_type, #_name, _name)
-
-#else
-#define print_pubkey_BN(_type, _name, _num) \
-do { \
- if(_type->_name) { \
- pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
- } \
-} while(0)
-#endif
-
-static void X509V3_ext(struct Curl_easy *data,
- int certnum,
- CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
-{
- int i;
-
- if((int)sk_X509_EXTENSION_num(exts) <= 0)
- /* no extensions, bail out */
- return;
-
- for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) {
- ASN1_OBJECT *obj;
- X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
- BUF_MEM *biomem;
- char namebuf[128];
- BIO *bio_out = BIO_new(BIO_s_mem());
-
- if(!bio_out)
- return;
-
- obj = X509_EXTENSION_get_object(ext);
-
- asn1_object_dump(obj, namebuf, sizeof(namebuf));
-
- if(!X509V3_EXT_print(bio_out, ext, 0, 0))
- ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
-
- BIO_get_mem_ptr(bio_out, &biomem);
- Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data,
- biomem->length);
- BIO_free(bio_out);
- }
-}
-
-#ifdef OPENSSL_IS_BORINGSSL
-typedef size_t numcert_t;
-#else
-typedef int numcert_t;
-#endif
-
-static CURLcode get_cert_chain(struct Curl_easy *data,
- struct ssl_connect_data *connssl)
-{
- CURLcode result;
- STACK_OF(X509) *sk;
- int i;
- numcert_t numcerts;
- BIO *mem;
- struct ssl_backend_data *backend = connssl->backend;
-
- DEBUGASSERT(backend);
-
- sk = SSL_get_peer_cert_chain(backend->handle);
- if(!sk) {
- return CURLE_OUT_OF_MEMORY;
- }
-
- numcerts = sk_X509_num(sk);
-
- result = Curl_ssl_init_certinfo(data, (int)numcerts);
- if(result) {
- return result;
- }
-
- mem = BIO_new(BIO_s_mem());
- if(!mem) {
- return CURLE_OUT_OF_MEMORY;
- }
-
- for(i = 0; i < (int)numcerts; i++) {
- ASN1_INTEGER *num;
- X509 *x = sk_X509_value(sk, i);
- EVP_PKEY *pubkey = NULL;
- int j;
- char *ptr;
- const ASN1_BIT_STRING *psig = NULL;
-
- X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
- push_certinfo("Subject", i);
-
- X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
- push_certinfo("Issuer", i);
-
- BIO_printf(mem, "%lx", X509_get_version(x));
- push_certinfo("Version", i);
-
- num = X509_get_serialNumber(x);
- if(num->type == V_ASN1_NEG_INTEGER)
- BIO_puts(mem, "-");
- for(j = 0; j < num->length; j++)
- BIO_printf(mem, "%02x", num->data[j]);
- push_certinfo("Serial Number", i);
-
-#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
- {
- const X509_ALGOR *sigalg = NULL;
- X509_PUBKEY *xpubkey = NULL;
- ASN1_OBJECT *pubkeyoid = NULL;
-
- X509_get0_signature(&psig, &sigalg, x);
- if(sigalg) {
- i2a_ASN1_OBJECT(mem, sigalg->algorithm);
- push_certinfo("Signature Algorithm", i);
- }
-
- xpubkey = X509_get_X509_PUBKEY(x);
- if(xpubkey) {
- X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey);
- if(pubkeyoid) {
- i2a_ASN1_OBJECT(mem, pubkeyoid);
- push_certinfo("Public Key Algorithm", i);
- }
- }
-
- X509V3_ext(data, i, X509_get0_extensions(x));
- }
-#else
- {
- /* before OpenSSL 1.0.2 */
- X509_CINF *cinf = x->cert_info;
-
- i2a_ASN1_OBJECT(mem, cinf->signature->algorithm);
- push_certinfo("Signature Algorithm", i);
-
- i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm);
- push_certinfo("Public Key Algorithm", i);
-
- X509V3_ext(data, i, cinf->extensions);
-
- psig = x->signature;
- }
-#endif
-
- ASN1_TIME_print(mem, X509_get0_notBefore(x));
- push_certinfo("Start date", i);
-
- ASN1_TIME_print(mem, X509_get0_notAfter(x));
- push_certinfo("Expire date", i);
-
- pubkey = X509_get_pubkey(x);
- if(!pubkey)
- infof(data, " Unable to load public key");
- else {
- int pktype;
-#ifdef HAVE_OPAQUE_EVP_PKEY
- pktype = EVP_PKEY_id(pubkey);
-#else
- pktype = pubkey->type;
-#endif
- switch(pktype) {
- case EVP_PKEY_RSA:
- {
-#ifndef HAVE_EVP_PKEY_GET_PARAMS
- RSA *rsa;
-#ifdef HAVE_OPAQUE_EVP_PKEY
- rsa = EVP_PKEY_get0_RSA(pubkey);
-#else
- rsa = pubkey->pkey.rsa;
-#endif /* HAVE_OPAQUE_EVP_PKEY */
-#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
-
- {
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
- DECLARE_PKEY_PARAM_BIGNUM(n);
- DECLARE_PKEY_PARAM_BIGNUM(e);
-#ifdef HAVE_EVP_PKEY_GET_PARAMS
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e);
-#else
- RSA_get0_key(rsa, &n, &e, NULL);
-#endif /* HAVE_EVP_PKEY_GET_PARAMS */
- BIO_printf(mem, "%d", BN_num_bits(n));
-#else
- BIO_printf(mem, "%d", BN_num_bits(rsa->n));
-#endif /* HAVE_OPAQUE_RSA_DSA_DH */
- push_certinfo("RSA Public Key", i);
- print_pubkey_BN(rsa, n, i);
- print_pubkey_BN(rsa, e, i);
- FREE_PKEY_PARAM_BIGNUM(n);
- FREE_PKEY_PARAM_BIGNUM(e);
- }
-
- break;
- }
- case EVP_PKEY_DSA:
- {
-#ifndef OPENSSL_NO_DSA
-#ifndef HAVE_EVP_PKEY_GET_PARAMS
- DSA *dsa;
-#ifdef HAVE_OPAQUE_EVP_PKEY
- dsa = EVP_PKEY_get0_DSA(pubkey);
-#else
- dsa = pubkey->pkey.dsa;
-#endif /* HAVE_OPAQUE_EVP_PKEY */
-#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
- {
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
- DECLARE_PKEY_PARAM_BIGNUM(p);
- DECLARE_PKEY_PARAM_BIGNUM(q);
- DECLARE_PKEY_PARAM_BIGNUM(g);
- DECLARE_PKEY_PARAM_BIGNUM(pub_key);
-#ifdef HAVE_EVP_PKEY_GET_PARAMS
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
-#else
- DSA_get0_pqg(dsa, &p, &q, &g);
- DSA_get0_key(dsa, &pub_key, NULL);
-#endif /* HAVE_EVP_PKEY_GET_PARAMS */
-#endif /* HAVE_OPAQUE_RSA_DSA_DH */
- print_pubkey_BN(dsa, p, i);
- print_pubkey_BN(dsa, q, i);
- print_pubkey_BN(dsa, g, i);
- print_pubkey_BN(dsa, pub_key, i);
- FREE_PKEY_PARAM_BIGNUM(p);
- FREE_PKEY_PARAM_BIGNUM(q);
- FREE_PKEY_PARAM_BIGNUM(g);
- FREE_PKEY_PARAM_BIGNUM(pub_key);
- }
-#endif /* !OPENSSL_NO_DSA */
- break;
- }
- case EVP_PKEY_DH:
- {
-#ifndef HAVE_EVP_PKEY_GET_PARAMS
- DH *dh;
-#ifdef HAVE_OPAQUE_EVP_PKEY
- dh = EVP_PKEY_get0_DH(pubkey);
-#else
- dh = pubkey->pkey.dh;
-#endif /* HAVE_OPAQUE_EVP_PKEY */
-#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
- {
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
- DECLARE_PKEY_PARAM_BIGNUM(p);
- DECLARE_PKEY_PARAM_BIGNUM(q);
- DECLARE_PKEY_PARAM_BIGNUM(g);
- DECLARE_PKEY_PARAM_BIGNUM(pub_key);
-#ifdef HAVE_EVP_PKEY_GET_PARAMS
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
-#else
- DH_get0_pqg(dh, &p, &q, &g);
- DH_get0_key(dh, &pub_key, NULL);
-#endif /* HAVE_EVP_PKEY_GET_PARAMS */
- print_pubkey_BN(dh, p, i);
- print_pubkey_BN(dh, q, i);
- print_pubkey_BN(dh, g, i);
-#else
- print_pubkey_BN(dh, p, i);
- print_pubkey_BN(dh, g, i);
-#endif /* HAVE_OPAQUE_RSA_DSA_DH */
- print_pubkey_BN(dh, pub_key, i);
- FREE_PKEY_PARAM_BIGNUM(p);
- FREE_PKEY_PARAM_BIGNUM(q);
- FREE_PKEY_PARAM_BIGNUM(g);
- FREE_PKEY_PARAM_BIGNUM(pub_key);
- }
- break;
- }
- }
- EVP_PKEY_free(pubkey);
- }
-
- if(psig) {
- for(j = 0; j < psig->length; j++)
- BIO_printf(mem, "%02x:", psig->data[j]);
- push_certinfo("Signature", i);
- }
-
- PEM_write_bio_X509(mem, x);
- push_certinfo("Cert", i);
- }
-
- BIO_free(mem);
-
- return CURLE_OK;
-}
-
/*
* Heavily modified from:
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
@@ -3923,8 +3835,8 @@ static CURLcode servercert(struct Curl_easy *data,
}
if(data->set.ssl.certinfo)
- /* we've been asked to gather certificate info! */
- (void)get_cert_chain(data, connssl);
+ /* asked to gather certificate info */
+ (void)Curl_ossl_certchain(data, connssl->backend->handle);
backend->server_cert = SSL_get1_peer_certificate(backend->handle);
if(!backend->server_cert) {
@@ -4467,7 +4379,7 @@ static size_t ossl_version(char *buffer, size_t size)
}
count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver);
for(p = buffer; *p; ++p) {
- if(ISSPACE(*p))
+ if(ISBLANK(*p))
*p = '_';
}
return count;
@@ -4479,7 +4391,13 @@ static size_t ossl_version(char *buffer, size_t size)
(LIBRESSL_VERSION_NUMBER>>12)&0xff);
#endif
#elif defined(OPENSSL_IS_BORINGSSL)
+#ifdef CURL_BORINGSSL_VERSION
+ return msnprintf(buffer, size, "%s/%s",
+ OSSL_PACKAGE,
+ CURL_BORINGSSL_VERSION);
+#else
return msnprintf(buffer, size, OSSL_PACKAGE);
+#endif
#elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING)
return msnprintf(buffer, size, "%s/%s",
OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING));
diff --git a/Utilities/cmcurl/lib/vtls/openssl.h b/Utilities/cmcurl/lib/vtls/openssl.h
index 0a7536ea3e..9df4ecddba 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.h
+++ b/Utilities/cmcurl/lib/vtls/openssl.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -29,6 +31,7 @@
* This header should only be needed to get included by vtls.c, openssl.c
* and ngtcp2.c
*/
+#include <openssl/ssl.h>
#include "urldata.h"
@@ -51,5 +54,7 @@ CURLcode Curl_ossl_set_client_cert(struct Curl_easy *data,
const struct curl_blob *key_blob,
const char *key_type, char *key_passwd);
+CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl);
+
#endif /* USE_OPENSSL */
#endif /* HEADER_CURL_SSLUSE_H */
diff --git a/Utilities/cmcurl/lib/vtls/rustls.c b/Utilities/cmcurl/lib/vtls/rustls.c
index 16970b7c36..77a49f1ab4 100644
--- a/Utilities/cmcurl/lib/vtls/rustls.c
+++ b/Utilities/cmcurl/lib/vtls/rustls.c
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -413,20 +415,20 @@ cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn,
#ifdef USE_HTTP2
if(len == ALPN_H2_LENGTH && 0 == memcmp(ALPN_H2, protocol, len)) {
infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, ALPN_H2);
- conn->negnpn = CURL_HTTP_VERSION_2;
+ conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(len == ALPN_HTTP_1_1_LENGTH &&
0 == memcmp(ALPN_HTTP_1_1, protocol, len)) {
infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, ALPN_HTTP_1_1);
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ conn->alpn = CURL_HTTP_VERSION_1_1;
}
else {
infof(data, "ALPN, negotiated an unrecognized protocol");
}
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
diff --git a/Utilities/cmcurl/lib/vtls/rustls.h b/Utilities/cmcurl/lib/vtls/rustls.h
index 056211dd8b..6b393dd639 100644
--- a/Utilities/cmcurl/lib/vtls/rustls.h
+++ b/Utilities/cmcurl/lib/vtls/rustls.h
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2020 - 2021, Jacob Hoffman-Andrews,
+ * Copyright (C) 2020 - 2022, Jacob Hoffman-Andrews,
* <github@hoffman-andrews.com>
*
* This software is licensed as described in the file COPYING, which
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#ifndef HEADER_CURL_RUSTLS_H
#define HEADER_CURL_RUSTLS_H
diff --git a/Utilities/cmcurl/lib/vtls/schannel.c b/Utilities/cmcurl/lib/vtls/schannel.c
index dfec66d51f..454eb79674 100644
--- a/Utilities/cmcurl/lib/vtls/schannel.c
+++ b/Utilities/cmcurl/lib/vtls/schannel.c
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -51,6 +53,7 @@
#include "curl_printf.h"
#include "multiif.h"
#include "version_win32.h"
+#include "rand.h"
/* The last #include file should be: */
#include "curl_memory.h"
@@ -81,8 +84,35 @@
#endif
#endif
-#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX)
-#define HAS_CLIENT_CERT_PATH
+#ifndef BCRYPT_CHACHA20_POLY1305_ALGORITHM
+#define BCRYPT_CHACHA20_POLY1305_ALGORITHM L"CHACHA20_POLY1305"
+#endif
+
+#ifndef BCRYPT_CHAIN_MODE_CCM
+#define BCRYPT_CHAIN_MODE_CCM L"ChainingModeCCM"
+#endif
+
+#ifndef BCRYPT_CHAIN_MODE_GCM
+#define BCRYPT_CHAIN_MODE_GCM L"ChainingModeGCM"
+#endif
+
+#ifndef BCRYPT_AES_ALGORITHM
+#define BCRYPT_AES_ALGORITHM L"AES"
+#endif
+
+#ifndef BCRYPT_SHA256_ALGORITHM
+#define BCRYPT_SHA256_ALGORITHM L"SHA256"
+#endif
+
+#ifndef BCRYPT_SHA384_ALGORITHM
+#define BCRYPT_SHA384_ALGORITHM L"SHA384"
+#endif
+
+/* Workaround broken compilers like MinGW.
+ Return the number of elements in a statically sized array.
+*/
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#endif
#ifdef HAS_CLIENT_CERT_PATH
@@ -117,6 +147,10 @@
#define SP_PROT_TLS1_2_CLIENT 0x00000800
#endif
+#ifndef SP_PROT_TLS1_3_CLIENT
+#define SP_PROT_TLS1_3_CLIENT 0x00002000
+#endif
+
#ifndef SCH_USE_STRONG_CRYPTO
#define SCH_USE_STRONG_CRYPTO 0x00400000
#endif
@@ -147,6 +181,10 @@
#define ALG_CLASS_DHASH ALG_CLASS_HASH
#endif
+#ifndef PKCS12_NO_PERSIST_KEY
+#define PKCS12_NO_PERSIST_KEY 0x00008000
+#endif
+
static Curl_recv schannel_recv;
static Curl_send schannel_send;
@@ -171,7 +209,7 @@ static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
}
static CURLcode
-set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct Curl_easy *data,
+set_ssl_version_min_max(DWORD *enabled_protocols, struct Curl_easy *data,
struct connectdata *conn)
{
long ssl_version = SSL_CONN_CONFIG(version);
@@ -181,23 +219,44 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct Curl_easy *data,
switch(ssl_version_max) {
case CURL_SSLVERSION_MAX_NONE:
case CURL_SSLVERSION_MAX_DEFAULT:
- ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+
+ /* Windows Server 2022 and newer (including Windows 11) support TLS 1.3
+ built-in. Previous builds of Windows 10 had broken TLS 1.3
+ implementations that could be enabled via registry.
+ */
+ if(curlx_verify_windows_version(10, 0, 20348, PLATFORM_WINNT,
+ VERSION_GREATER_THAN_EQUAL)) {
+ ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3;
+ }
+ else /* Windows 10 and older */
+ ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+
break;
}
+
for(; i <= (ssl_version_max >> 16); ++i) {
switch(i) {
case CURL_SSLVERSION_TLSv1_0:
- schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT;
+ (*enabled_protocols) |= SP_PROT_TLS1_0_CLIENT;
break;
case CURL_SSLVERSION_TLSv1_1:
- schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT;
+ (*enabled_protocols) |= SP_PROT_TLS1_1_CLIENT;
break;
case CURL_SSLVERSION_TLSv1_2:
- schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
+ (*enabled_protocols) |= SP_PROT_TLS1_2_CLIENT;
break;
case CURL_SSLVERSION_TLSv1_3:
- failf(data, "schannel: TLS 1.3 is not yet supported");
- return CURLE_SSL_CONNECT_ERROR;
+
+ /* Windows Server 2022 and newer */
+ if(curlx_verify_windows_version(10, 0, 20348, PLATFORM_WINNT,
+ VERSION_GREATER_THAN_EQUAL)) {
+ (*enabled_protocols) |= SP_PROT_TLS1_3_CLIENT;
+ break;
+ }
+ else { /* Windows 10 and older */
+ failf(data, "schannel: TLS 1.3 not supported on Windows prior to 11");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
}
}
return CURLE_OK;
@@ -214,8 +273,12 @@ get_alg_id_by_name(char *name)
{
char tmp[LONGEST_ALG_ID] = { 0 };
char *nameEnd = strchr(name, ':');
- size_t n = nameEnd ? min((size_t)(nameEnd - name), LONGEST_ALG_ID - 1) : \
- min(strlen(name), LONGEST_ALG_ID - 1);
+ size_t n = nameEnd ? (size_t)(nameEnd - name) : strlen(name);
+
+ /* reject too-long alg names */
+ if(n > (LONGEST_ALG_ID - 1))
+ return 0;
+
strncpy(tmp, name, n);
tmp[n] = 0;
CIPHEROPTION(CALG_MD2);
@@ -383,13 +446,13 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
else if(_tcsncmp(path, TEXT("Users"), store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_USERS;
else if(_tcsncmp(path, TEXT("CurrentUserGroupPolicy"),
- store_name_len) == 0)
+ store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY;
else if(_tcsncmp(path, TEXT("LocalMachineGroupPolicy"),
- store_name_len) == 0)
+ store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY;
else if(_tcsncmp(path, TEXT("LocalMachineEnterprise"),
- store_name_len) == 0)
+ store_name_len) == 0)
*store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE;
else
return CURLE_SSL_CERTPROBLEM;
@@ -419,49 +482,52 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- SCHANNEL_CRED schannel_cred;
- ALG_ID algIds[NUM_CIPHERS];
+
+#ifdef HAS_CLIENT_CERT_PATH
PCCERT_CONTEXT client_certs[1] = { NULL };
+ HCERTSTORE client_cert_store = NULL;
+#endif
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
+
+ /* setup Schannel API options */
+ DWORD flags = 0;
+ DWORD enabled_protocols = 0;
+
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
- /* setup Schannel API options */
- memset(&schannel_cred, 0, sizeof(schannel_cred));
- schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
-
if(conn->ssl_config.verifypeer) {
#ifdef HAS_MANUAL_VERIFY_API
if(backend->use_manual_cred_validation)
- schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION;
+ flags = SCH_CRED_MANUAL_CRED_VALIDATION;
else
#endif
- schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
+ flags = SCH_CRED_AUTO_CRED_VALIDATION;
if(SSL_SET_OPTION(no_revoke)) {
- schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+ flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
DEBUGF(infof(data, "schannel: disabled server certificate revocation "
"checks"));
}
else if(SSL_SET_OPTION(revoke_best_effort)) {
- schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+ flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN;
DEBUGF(infof(data, "schannel: ignore revocation offline errors"));
}
else {
- schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+ flags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
DEBUGF(infof(data,
"schannel: checking server certificate revocation"));
}
}
else {
- schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+ flags = SCH_CRED_MANUAL_CRED_VALIDATION |
SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
DEBUGF(infof(data,
@@ -469,15 +535,15 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
}
if(!conn->ssl_config.verifyhost) {
- schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
+ flags |= SCH_CRED_NO_SERVERNAME_CHECK;
DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from "
"comparing the supplied target name with the subject "
"names in server certificates."));
}
if(!SSL_SET_OPTION(auto_client_cert)) {
- schannel_cred.dwFlags &= ~SCH_CRED_USE_DEFAULT_CREDS;
- schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
+ flags &= ~SCH_CRED_USE_DEFAULT_CREDS;
+ flags |= SCH_CRED_NO_DEFAULT_CREDS;
infof(data, "schannel: disabled automatic use of client certificate");
}
else
@@ -491,7 +557,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
- result = set_ssl_version_min_max(&schannel_cred, data, conn);
+ result = set_ssl_version_min_max(&enabled_protocols, data, conn);
if(result != CURLE_OK)
return result;
break;
@@ -505,16 +571,6 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
return CURLE_SSL_CONNECT_ERROR;
}
- if(SSL_CONN_CONFIG(cipher_list)) {
- result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list),
- algIds);
- if(CURLE_OK != result) {
- failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
- return result;
- }
- }
-
-
#ifdef HAS_CLIENT_CERT_PATH
/* client certificate */
if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
@@ -540,7 +596,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
result = get_cert_location(cert_path, &cert_store_name,
- &cert_store_path, &cert_thumbprint_str);
+ &cert_store_path, &cert_thumbprint_str);
if(result && (data->set.ssl.primary.clientcert[0]!='\0'))
fInCert = fopen(data->set.ssl.primary.clientcert, "rb");
@@ -555,18 +611,18 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
}
if((fInCert || blob) && (data->set.ssl.cert_type) &&
- (!strcasecompare(data->set.ssl.cert_type, "P12"))) {
+ (!strcasecompare(data->set.ssl.cert_type, "P12"))) {
failf(data, "schannel: certificate format compatibility error "
- " for %s",
- blob ? "(memory blob)" : data->set.ssl.primary.clientcert);
+ " for %s",
+ blob ? "(memory blob)" : data->set.ssl.primary.clientcert);
curlx_unicodefree(cert_path);
return CURLE_SSL_CERTPROBLEM;
}
if(fInCert || blob) {
/* Reading a .P12 or .pfx file, like the example at bottom of
- https://social.msdn.microsoft.com/Forums/windowsdesktop/
- en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5
+ https://social.msdn.microsoft.com/Forums/windowsdesktop/
+ en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5
*/
CRYPT_DATA_BLOB datablob;
WCHAR* pszPassword;
@@ -594,7 +650,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
fclose(fInCert);
if(!continue_reading) {
failf(data, "schannel: Failed to read cert file %s",
- data->set.ssl.primary.clientcert);
+ data->set.ssl.primary.clientcert);
free(certdata);
return CURLE_SSL_CERTPROBLEM;
}
@@ -610,16 +666,23 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
if(pszPassword) {
if(pwd_len > 0)
str_w_len = MultiByteToWideChar(CP_UTF8,
- MB_ERR_INVALID_CHARS,
- data->set.ssl.key_passwd, (int)pwd_len,
- pszPassword, (int)(pwd_len + 1));
+ MB_ERR_INVALID_CHARS,
+ data->set.ssl.key_passwd,
+ (int)pwd_len,
+ pszPassword, (int)(pwd_len + 1));
if((str_w_len >= 0) && (str_w_len <= (int)pwd_len))
pszPassword[str_w_len] = 0;
else
pszPassword[0] = 0;
- cert_store = PFXImportCertStore(&datablob, pszPassword, 0);
+ if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
+ VERSION_GREATER_THAN_EQUAL))
+ cert_store = PFXImportCertStore(&datablob, pszPassword,
+ PKCS12_NO_PERSIST_KEY);
+ else
+ cert_store = PFXImportCertStore(&datablob, pszPassword, 0);
+
free(pszPassword);
}
if(!blob)
@@ -648,9 +711,6 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
CertCloseStore(cert_store, 0);
return CURLE_SSL_CERTPROBLEM;
}
-
- schannel_cred.cCreds = 1;
- schannel_cred.paCred = client_certs;
}
else {
cert_store =
@@ -688,17 +748,13 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
curlx_unicodefree(cert_path);
- if(client_certs[0]) {
- schannel_cred.cCreds = 1;
- schannel_cred.paCred = client_certs;
- }
- else {
+ if(!client_certs[0]) {
/* CRYPT_E_NOT_FOUND / E_INVALIDARG */
CertCloseStore(cert_store, 0);
return CURLE_SSL_CERTPROBLEM;
}
}
- CertCloseStore(cert_store, 0);
+ client_cert_store = cert_store;
}
#else
if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
@@ -713,22 +769,279 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
if(!backend->cred) {
failf(data, "schannel: unable to allocate memory");
+#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0])
CertFreeCertificateContext(client_certs[0]);
+ if(client_cert_store)
+ CertCloseStore(client_cert_store, 0);
+#endif
return CURLE_OUT_OF_MEMORY;
}
backend->cred->refcount = 1;
- sspi_status =
- s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
- SECPKG_CRED_OUTBOUND, NULL,
- &schannel_cred, NULL, NULL,
- &backend->cred->cred_handle,
- &backend->cred->time_stamp);
+#ifdef HAS_CLIENT_CERT_PATH
+ /* Since we did not persist the key, we need to extend the store's
+ * lifetime until the end of the connection
+ */
+ backend->cred->client_cert_store = client_cert_store;
+#endif
+ /* Windows 10, 1809 (a.k.a. Windows 10 build 17763) */
+ if(curlx_verify_windows_version(10, 0, 17763, PLATFORM_WINNT,
+ VERSION_GREATER_THAN_EQUAL)) {
+
+ char *ciphers13 = 0;
+
+ bool disable_aes_gcm_sha384 = FALSE;
+ bool disable_aes_gcm_sha256 = FALSE;
+ bool disable_chacha_poly = FALSE;
+ bool disable_aes_ccm_8_sha256 = FALSE;
+ bool disable_aes_ccm_sha256 = FALSE;
+
+ SCH_CREDENTIALS credentials = { 0 };
+ TLS_PARAMETERS tls_parameters = { 0 };
+ CRYPTO_SETTINGS crypto_settings[4] = { 0 };
+ UNICODE_STRING blocked_ccm_modes[1] = { 0 };
+ UNICODE_STRING blocked_gcm_modes[1] = { 0 };
+
+ int crypto_settings_idx = 0;
+
+
+ /* If TLS 1.3 ciphers are explicitly listed, then
+ * disable all the ciphers and re-enable which
+ * ciphers the user has provided.
+ */
+ ciphers13 = SSL_CONN_CONFIG(cipher_list13);
+ if(ciphers13) {
+ const int remaining_ciphers = 5;
+
+ /* detect which remaining ciphers to enable
+ and then disable everything else.
+ */
+
+ char *startCur = ciphers13;
+ int algCount = 0;
+ char tmp[LONGEST_ALG_ID] = { 0 };
+ char *nameEnd;
+ size_t n;
+
+ disable_aes_gcm_sha384 = TRUE;
+ disable_aes_gcm_sha256 = TRUE;
+ disable_chacha_poly = TRUE;
+ disable_aes_ccm_8_sha256 = TRUE;
+ disable_aes_ccm_sha256 = TRUE;
+
+ while(startCur && (0 != *startCur) && (algCount < remaining_ciphers)) {
+ nameEnd = strchr(startCur, ':');
+ n = nameEnd ? (size_t)(nameEnd - startCur) : strlen(startCur);
+
+ /* reject too-long cipher names */
+ if(n > (LONGEST_ALG_ID - 1)) {
+ failf(data, "Cipher name too long, not checked.");
+ return CURLE_SSL_CIPHER;
+ }
+
+ strncpy(tmp, startCur, n);
+ tmp[n] = 0;
+
+ if(disable_aes_gcm_sha384
+ && !strcmp("TLS_AES_256_GCM_SHA384", tmp)) {
+ disable_aes_gcm_sha384 = FALSE;
+ }
+ else if(disable_aes_gcm_sha256
+ && !strcmp("TLS_AES_128_GCM_SHA256", tmp)) {
+ disable_aes_gcm_sha256 = FALSE;
+ }
+ else if(disable_chacha_poly
+ && !strcmp("TLS_CHACHA20_POLY1305_SHA256", tmp)) {
+ disable_chacha_poly = FALSE;
+ }
+ else if(disable_aes_ccm_8_sha256
+ && !strcmp("TLS_AES_128_CCM_8_SHA256", tmp)) {
+ disable_aes_ccm_8_sha256 = FALSE;
+ }
+ else if(disable_aes_ccm_sha256
+ && !strcmp("TLS_AES_128_CCM_SHA256", tmp)) {
+ disable_aes_ccm_sha256 = FALSE;
+ }
+ else {
+ failf(data, "Passed in an unknown TLS 1.3 cipher.");
+ return CURLE_SSL_CIPHER;
+ }
+
+ startCur = nameEnd;
+ if(startCur)
+ startCur++;
+
+ algCount++;
+ }
+ }
+
+ if(disable_aes_gcm_sha384 && disable_aes_gcm_sha256
+ && disable_chacha_poly && disable_aes_ccm_8_sha256
+ && disable_aes_ccm_sha256) {
+ failf(data, "All available TLS 1.3 ciphers were disabled.");
+ return CURLE_SSL_CIPHER;
+ }
+
+ /* Disable TLS_AES_128_CCM_8_SHA256 and/or TLS_AES_128_CCM_SHA256 */
+ if(disable_aes_ccm_8_sha256 || disable_aes_ccm_sha256) {
+ /*
+ Disallow AES_CCM algorithm.
+ */
+ blocked_ccm_modes[0].Length = sizeof(BCRYPT_CHAIN_MODE_CCM);
+ blocked_ccm_modes[0].MaximumLength = sizeof(BCRYPT_CHAIN_MODE_CCM);
+ blocked_ccm_modes[0].Buffer = (PWSTR)BCRYPT_CHAIN_MODE_CCM;
+
+ crypto_settings[crypto_settings_idx].eAlgorithmUsage =
+ TlsParametersCngAlgUsageCipher;
+ crypto_settings[crypto_settings_idx].rgstrChainingModes =
+ blocked_ccm_modes;
+ crypto_settings[crypto_settings_idx].cChainingModes =
+ ARRAYSIZE(blocked_ccm_modes);
+ crypto_settings[crypto_settings_idx].strCngAlgId.Length =
+ sizeof(BCRYPT_AES_ALGORITHM);
+ crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength =
+ sizeof(BCRYPT_AES_ALGORITHM);
+ crypto_settings[crypto_settings_idx].strCngAlgId.Buffer =
+ (PWSTR)BCRYPT_AES_ALGORITHM;
+
+ /* only disabling one of the CCM modes */
+ if(disable_aes_ccm_8_sha256 != disable_aes_ccm_sha256) {
+ if(disable_aes_ccm_8_sha256)
+ crypto_settings[crypto_settings_idx].dwMinBitLength = 128;
+ else /* disable_aes_ccm_sha256 */
+ crypto_settings[crypto_settings_idx].dwMaxBitLength = 64;
+ }
+
+ crypto_settings_idx++;
+ }
+
+ /* Disable TLS_AES_256_GCM_SHA384 and/or TLS_AES_128_GCM_SHA256 */
+ if(disable_aes_gcm_sha384 || disable_aes_gcm_sha256) {
+
+ /*
+ Disallow AES_GCM algorithm
+ */
+ blocked_gcm_modes[0].Length = sizeof(BCRYPT_CHAIN_MODE_GCM);
+ blocked_gcm_modes[0].MaximumLength = sizeof(BCRYPT_CHAIN_MODE_GCM);
+ blocked_gcm_modes[0].Buffer = (PWSTR)BCRYPT_CHAIN_MODE_GCM;
+
+ /* if only one is disabled, then explicitly disable the
+ digest cipher suite (sha384 or sha256) */
+ if(disable_aes_gcm_sha384 != disable_aes_gcm_sha256) {
+ crypto_settings[crypto_settings_idx].eAlgorithmUsage =
+ TlsParametersCngAlgUsageDigest;
+ crypto_settings[crypto_settings_idx].strCngAlgId.Length =
+ sizeof(disable_aes_gcm_sha384 ?
+ BCRYPT_SHA384_ALGORITHM : BCRYPT_SHA256_ALGORITHM);
+ crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength =
+ sizeof(disable_aes_gcm_sha384 ?
+ BCRYPT_SHA384_ALGORITHM : BCRYPT_SHA256_ALGORITHM);
+ crypto_settings[crypto_settings_idx].strCngAlgId.Buffer =
+ (PWSTR)(disable_aes_gcm_sha384 ?
+ BCRYPT_SHA384_ALGORITHM : BCRYPT_SHA256_ALGORITHM);
+ }
+ else { /* Disable both AES_GCM ciphers */
+ crypto_settings[crypto_settings_idx].eAlgorithmUsage =
+ TlsParametersCngAlgUsageCipher;
+ crypto_settings[crypto_settings_idx].strCngAlgId.Length =
+ sizeof(BCRYPT_AES_ALGORITHM);
+ crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength =
+ sizeof(BCRYPT_AES_ALGORITHM);
+ crypto_settings[crypto_settings_idx].strCngAlgId.Buffer =
+ (PWSTR)BCRYPT_AES_ALGORITHM;
+ }
+
+ crypto_settings[crypto_settings_idx].rgstrChainingModes =
+ blocked_gcm_modes;
+ crypto_settings[crypto_settings_idx].cChainingModes = 1;
+
+ crypto_settings_idx++;
+ }
+
+ /*
+ Disable ChaCha20-Poly1305.
+ */
+ if(disable_chacha_poly) {
+ crypto_settings[crypto_settings_idx].eAlgorithmUsage =
+ TlsParametersCngAlgUsageCipher;
+ crypto_settings[crypto_settings_idx].strCngAlgId.Length =
+ sizeof(BCRYPT_CHACHA20_POLY1305_ALGORITHM);
+ crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength =
+ sizeof(BCRYPT_CHACHA20_POLY1305_ALGORITHM);
+ crypto_settings[crypto_settings_idx].strCngAlgId.Buffer =
+ (PWSTR)BCRYPT_CHACHA20_POLY1305_ALGORITHM;
+ crypto_settings_idx++;
+ }
+
+ tls_parameters.pDisabledCrypto = crypto_settings;
+
+ /* The number of blocked suites */
+ tls_parameters.cDisabledCrypto = crypto_settings_idx;
+ credentials.pTlsParameters = &tls_parameters;
+ credentials.cTlsParameters = 1;
+
+ credentials.dwVersion = SCH_CREDENTIALS_VERSION;
+ credentials.dwFlags = flags | SCH_USE_STRONG_CRYPTO;
+
+ credentials.pTlsParameters->grbitDisabledProtocols =
+ (DWORD)~enabled_protocols;
+
+#ifdef HAS_CLIENT_CERT_PATH
+ if(client_certs[0]) {
+ credentials.cCreds = 1;
+ credentials.paCred = client_certs;
+ }
+#endif
+
+ sspi_status =
+ s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME,
+ SECPKG_CRED_OUTBOUND, NULL,
+ &credentials, NULL, NULL,
+ &backend->cred->cred_handle,
+ &backend->cred->time_stamp);
+ }
+ else {
+ /* Pre-Windows 10 1809 */
+ ALG_ID algIds[NUM_CIPHERS];
+ char *ciphers = SSL_CONN_CONFIG(cipher_list);
+ SCHANNEL_CRED schannel_cred = { 0 };
+ schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
+ schannel_cred.dwFlags = flags;
+ schannel_cred.grbitEnabledProtocols = enabled_protocols;
+
+ if(ciphers) {
+ result = set_ssl_ciphers(&schannel_cred, ciphers, algIds);
+ if(CURLE_OK != result) {
+ failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
+ return result;
+ }
+ }
+ else {
+ schannel_cred.dwFlags = flags | SCH_USE_STRONG_CRYPTO;
+ }
+
+#ifdef HAS_CLIENT_CERT_PATH
+ if(client_certs[0]) {
+ schannel_cred.cCreds = 1;
+ schannel_cred.paCred = client_certs;
+ }
+#endif
+
+ sspi_status =
+ s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME,
+ SECPKG_CRED_OUTBOUND, NULL,
+ &schannel_cred, NULL, NULL,
+ &backend->cred->cred_handle,
+ &backend->cred->time_stamp);
+ }
+
+#ifdef HAS_CLIENT_CERT_PATH
if(client_certs[0])
CertFreeCertificateContext(client_certs[0]);
+#endif
if(sspi_status != SEC_E_OK) {
char buffer[STRERROR_LEN];
@@ -1016,6 +1329,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
backend->recv_unrecoverable_err = CURLE_OK;
backend->recv_sspi_close_notify = false;
backend->recv_connection_closed = false;
+ backend->recv_renegotiating = false;
backend->encdata_is_incomplete = false;
/* continue to second handshake step */
@@ -1415,6 +1729,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
if(alpn_result.ProtoNegoStatus ==
SecApplicationProtocolNegotiationStatus_Success) {
+ unsigned char alpn = 0;
infof(data, VTLS_INFOF_ALPN_ACCEPTED_LEN_1STR,
alpn_result.ProtocolIdSize, alpn_result.ProtocolId);
@@ -1422,20 +1737,33 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
#ifdef USE_HTTP2
if(alpn_result.ProtocolIdSize == ALPN_H2_LENGTH &&
!memcmp(ALPN_H2, alpn_result.ProtocolId, ALPN_H2_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_2;
+ alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH &&
!memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId,
ALPN_HTTP_1_1_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ alpn = CURL_HTTP_VERSION_1_1;
}
+ if(backend->recv_renegotiating) {
+ if(alpn != conn->alpn) {
+ failf(data, "schannel: server selected an ALPN protocol too late");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+ else
+ conn->alpn = alpn;
+ }
+ else {
+ if(!backend->recv_renegotiating)
+ infof(data, VTLS_INFOF_NO_ALPN);
+ }
+
+ if(!backend->recv_renegotiating) {
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
- else
- infof(data, VTLS_INFOF_NO_ALPN);
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
- BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
@@ -1607,8 +1935,15 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
if(ssl_connect_done == connssl->connecting_state) {
connssl->state = ssl_connection_complete;
- conn->recv[sockindex] = schannel_recv;
- conn->send[sockindex] = schannel_send;
+ if(!connssl->backend->recv_renegotiating) {
+ /* On renegotiation, we don't want to reset the existing recv/send
+ * function pointers. They will have been set after the initial TLS
+ * handshake was completed. If they were subsequently modified, as
+ * is the case with HTTP/2, we don't want to override that change.
+ */
+ conn->recv[sockindex] = schannel_recv;
+ conn->send[sockindex] = schannel_send;
+ }
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
/* When SSPI is used in combination with Schannel
@@ -1990,17 +2325,14 @@ schannel_recv(struct Curl_easy *data, int sockindex,
infof(data, "schannel: can't renegotiate, an error is pending");
goto cleanup;
}
- if(backend->encdata_offset) {
- *err = CURLE_RECV_ERROR;
- infof(data, "schannel: can't renegotiate, "
- "encrypted data available");
- goto cleanup;
- }
+
/* begin renegotiation */
infof(data, "schannel: renegotiating SSL/TLS connection");
connssl->state = ssl_connection_negotiating;
connssl->connecting_state = ssl_connect_2_writing;
+ backend->recv_renegotiating = true;
*err = schannel_connect_common(data, conn, sockindex, FALSE, &done);
+ backend->recv_renegotiating = false;
if(*err) {
infof(data, "schannel: renegotiation failed");
goto cleanup;
@@ -2154,6 +2486,12 @@ static void schannel_session_free(void *ptr)
if(cred->refcount == 0) {
s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
curlx_unicodefree(cred->sni_hostname);
+#ifdef HAS_CLIENT_CERT_PATH
+ if(cred->client_cert_store) {
+ CertCloseStore(cred->client_cert_store, 0);
+ cred->client_cert_store = NULL;
+ }
+#endif
Curl_safefree(cred);
}
}
@@ -2296,21 +2634,9 @@ static size_t schannel_version(char *buffer, size_t size)
static CURLcode schannel_random(struct Curl_easy *data UNUSED_PARAM,
unsigned char *entropy, size_t length)
{
- HCRYPTPROV hCryptProv = 0;
-
(void)data;
- if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
- return CURLE_FAILED_INIT;
-
- if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) {
- CryptReleaseContext(hCryptProv, 0UL);
- return CURLE_FAILED_INIT;
- }
-
- CryptReleaseContext(hCryptProv, 0UL);
- return CURLE_OK;
+ return Curl_win32_random(entropy, length);
}
static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
@@ -2457,7 +2783,8 @@ const struct Curl_ssl Curl_ssl_schannel = {
#ifdef HAS_MANUAL_VERIFY_API
SSLSUPP_CAINFO_BLOB |
#endif
- SSLSUPP_PINNEDPUBKEY,
+ SSLSUPP_PINNEDPUBKEY |
+ SSLSUPP_TLS13_CIPHERSUITES,
sizeof(struct ssl_backend_data),
diff --git a/Utilities/cmcurl/lib/vtls/schannel.h b/Utilities/cmcurl/lib/vtls/schannel.h
index da60702771..24d7eff25b 100644
--- a/Utilities/cmcurl/lib/vtls/schannel.h
+++ b/Utilities/cmcurl/lib/vtls/schannel.h
@@ -21,11 +21,35 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_SCHANNEL
+#define SCHANNEL_USE_BLACKLISTS 1
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4201)
+#endif
+#include <subauth.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+/* Wincrypt must be included before anything that could include OpenSSL. */
+#if defined(USE_WIN32_CRYPTO)
+#include <wincrypt.h>
+/* Undefine wincrypt conflicting symbols for BoringSSL. */
+#undef X509_NAME
+#undef X509_EXTENSIONS
+#undef PKCS7_ISSUER_AND_SERIAL
+#undef PKCS7_SIGNER_INFO
+#undef OCSP_REQUEST
+#undef OCSP_RESPONSE
+#endif
+
#include <schnlsp.h>
#include <schannel.h>
#include "curl_sspi.h"
@@ -59,22 +83,87 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
/* structs to expose only in schannel.c and schannel_verify.c */
#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
+#include <wincrypt.h>
+
#ifdef __MINGW32__
-#include <_mingw.h>
#ifdef __MINGW64_VERSION_MAJOR
#define HAS_MANUAL_VERIFY_API
#endif
#else
-#include <wincrypt.h>
#ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN
#define HAS_MANUAL_VERIFY_API
#endif
#endif
+#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \
+ && !defined(DISABLE_SCHANNEL_CLIENT_CERT)
+#define HAS_CLIENT_CERT_PATH
+#endif
+
+#ifndef SCH_CREDENTIALS_VERSION
+
+#define SCH_CREDENTIALS_VERSION 0x00000005
+
+typedef enum _eTlsAlgorithmUsage
+{
+ TlsParametersCngAlgUsageKeyExchange,
+ TlsParametersCngAlgUsageSignature,
+ TlsParametersCngAlgUsageCipher,
+ TlsParametersCngAlgUsageDigest,
+ TlsParametersCngAlgUsageCertSig
+} eTlsAlgorithmUsage;
+
+typedef struct _CRYPTO_SETTINGS
+{
+ eTlsAlgorithmUsage eAlgorithmUsage;
+ UNICODE_STRING strCngAlgId;
+ DWORD cChainingModes;
+ PUNICODE_STRING rgstrChainingModes;
+ DWORD dwMinBitLength;
+ DWORD dwMaxBitLength;
+} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS;
+
+typedef struct _TLS_PARAMETERS
+{
+ DWORD cAlpnIds;
+ PUNICODE_STRING rgstrAlpnIds;
+ DWORD grbitDisabledProtocols;
+ DWORD cDisabledCrypto;
+ PCRYPTO_SETTINGS pDisabledCrypto;
+ DWORD dwFlags;
+} TLS_PARAMETERS, * PTLS_PARAMETERS;
+
+typedef struct _SCH_CREDENTIALS
+{
+ DWORD dwVersion;
+ DWORD dwCredFormat;
+ DWORD cCreds;
+ PCCERT_CONTEXT* paCred;
+ HCERTSTORE hRootStore;
+
+ DWORD cMappers;
+ struct _HMAPPER **aphMappers;
+
+ DWORD dwSessionLifespan;
+ DWORD dwFlags;
+ DWORD cTlsParameters;
+ PTLS_PARAMETERS pTlsParameters;
+} SCH_CREDENTIALS, * PSCH_CREDENTIALS;
+
+#define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16
+#define SCH_CRED_MAX_SUPPORTED_ALPN_IDS 16
+#define SCH_CRED_MAX_SUPPORTED_CRYPTO_SETTINGS 16
+#define SCH_CRED_MAX_SUPPORTED_CHAINING_MODES 16
+
+#endif
+
struct Curl_schannel_cred {
CredHandle cred_handle;
TimeStamp time_stamp;
TCHAR *sni_hostname;
+#ifdef HAS_CLIENT_CERT_PATH
+ HCERTSTORE client_cert_store;
+#endif
int refcount;
};
@@ -99,6 +188,7 @@ struct ssl_backend_data {
CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
bool recv_sspi_close_notify; /* true if connection closed by close_notify */
bool recv_connection_closed; /* true if connection closed, regardless how */
+ bool recv_renegotiating; /* true if recv is doing renegotiation */
bool use_alpn; /* true if ALPN is used for this connection */
#ifdef HAS_MANUAL_VERIFY_API
bool use_manual_cred_validation; /* true if manual cred validation is used */
diff --git a/Utilities/cmcurl/lib/vtls/schannel_verify.c b/Utilities/cmcurl/lib/vtls/schannel_verify.c
index 4dc2d14e56..1ac1d3eaf5 100644
--- a/Utilities/cmcurl/lib/vtls/schannel_verify.c
+++ b/Utilities/cmcurl/lib/vtls/schannel_verify.c
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
diff --git a/Utilities/cmcurl/lib/vtls/sectransp.c b/Utilities/cmcurl/lib/vtls/sectransp.c
index 2e57d83785..c764e3631b 100644
--- a/Utilities/cmcurl/lib/vtls/sectransp.c
+++ b/Utilities/cmcurl/lib/vtls/sectransp.c
@@ -19,6 +19,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -2845,18 +2847,18 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
#ifdef USE_HTTP2
if(chosenProtocol &&
!CFStringCompare(chosenProtocol, CFSTR(ALPN_H2), 0)) {
- conn->negnpn = CURL_HTTP_VERSION_2;
+ conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(chosenProtocol &&
!CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ conn->alpn = CURL_HTTP_VERSION_1_1;
}
else
infof(data, VTLS_INFOF_NO_ALPN);
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
/* chosenProtocol is a reference to the string within alpnArr
@@ -2964,7 +2966,7 @@ collect_server_cert(struct Curl_easy *data,
private API and doesn't work as expected. So we have to look for
a different symbol to make sure this code is only executed under
Lion or later. */
- if(SecTrustEvaluateAsync) {
+ if(SecTrustCopyPublicKey) {
#pragma unused(server_certs)
err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
diff --git a/Utilities/cmcurl/lib/vtls/sectransp.h b/Utilities/cmcurl/lib/vtls/sectransp.h
index 0febd6613a..2d53b7c480 100644
--- a/Utilities/cmcurl/lib/vtls/sectransp.h
+++ b/Utilities/cmcurl/lib/vtls/sectransp.h
@@ -8,7 +8,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
- * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -21,6 +21,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/vtls.c b/Utilities/cmcurl/lib/vtls/vtls.c
index e2d34388cc..9dee5aa3b3 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.c
+++ b/Utilities/cmcurl/lib/vtls/vtls.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/* This file is for implementing all "generic" SSL functions that all libcurl
@@ -143,11 +145,9 @@ Curl_ssl_config_matches(struct ssl_primary_config *data,
Curl_safecmp(data->CAfile, needle->CAfile) &&
Curl_safecmp(data->issuercert, needle->issuercert) &&
Curl_safecmp(data->clientcert, needle->clientcert) &&
- Curl_safecmp(data->random_file, needle->random_file) &&
- Curl_safecmp(data->egdsocket, needle->egdsocket) &&
#ifdef USE_TLS_SRP
- Curl_safecmp(data->username, needle->username) &&
- Curl_safecmp(data->password, needle->password) &&
+ !Curl_timestrcmp(data->username, needle->username) &&
+ !Curl_timestrcmp(data->password, needle->password) &&
(data->authtype == needle->authtype) &&
#endif
Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
@@ -182,8 +182,6 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
CLONE_STRING(CAfile);
CLONE_STRING(issuercert);
CLONE_STRING(clientcert);
- CLONE_STRING(random_file);
- CLONE_STRING(egdsocket);
CLONE_STRING(cipher_list);
CLONE_STRING(cipher_list13);
CLONE_STRING(pinned_key);
@@ -203,8 +201,6 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
Curl_safefree(sslc->CAfile);
Curl_safefree(sslc->issuercert);
Curl_safefree(sslc->clientcert);
- Curl_safefree(sslc->random_file);
- Curl_safefree(sslc->egdsocket);
Curl_safefree(sslc->cipher_list);
Curl_safefree(sslc->cipher_list13);
Curl_safefree(sslc->pinned_key);
@@ -223,13 +219,13 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
static int multissl_setup(const struct Curl_ssl *backend);
#endif
-int Curl_ssl_backend(void)
+curl_sslbackend Curl_ssl_backend(void)
{
#ifdef USE_SSL
multissl_setup(NULL);
return Curl_ssl->info.id;
#else
- return (int)CURLSSLBACKEND_NONE;
+ return CURLSSLBACKEND_NONE;
#endif
}
@@ -903,7 +899,7 @@ char *Curl_ssl_snihost(struct Curl_easy *data, const char *host, size_t *olen)
size_t len = strlen(host);
if(len && (host[len-1] == '.'))
len--;
- if((long)len >= data->set.buffer_size)
+ if(len >= data->set.buffer_size)
return NULL;
Curl_strntolower(data->state.buffer, host, len);
@@ -1460,8 +1456,10 @@ static int multissl_setup(const struct Curl_ssl *backend)
return 0;
}
-CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
- const curl_ssl_backend ***avail)
+/* This function is used to select the SSL backend to use. It is called by
+ curl_global_sslset (easy.c) which uses the global init lock. */
+CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
+ const curl_ssl_backend ***avail)
{
int i;
@@ -1490,8 +1488,8 @@ CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
}
#else /* USE_SSL */
-CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
- const curl_ssl_backend ***avail)
+CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
+ const curl_ssl_backend ***avail)
{
(void)id;
(void)name;
diff --git a/Utilities/cmcurl/lib/vtls/vtls.h b/Utilities/cmcurl/lib/vtls/vtls.h
index 6bd1e0dcd3..50c53b3fbd 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.h
+++ b/Utilities/cmcurl/lib/vtls/vtls.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -123,6 +125,9 @@ struct curl_slist *Curl_none_engines_list(struct Curl_easy *data);
bool Curl_none_false_start(void);
bool Curl_ssl_tls13_ciphersuites(void);
+CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
+ const curl_ssl_backend ***avail);
+
#include "openssl.h" /* OpenSSL versions */
#include "gtls.h" /* GnuTLS versions */
#include "nssg.h" /* NSS versions */
@@ -195,7 +200,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc);
ssl_connect_2_writing. */
int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks);
-int Curl_ssl_backend(void);
+curl_sslbackend Curl_ssl_backend(void);
#ifdef USE_SSL
int Curl_ssl_init(void);
diff --git a/Utilities/cmcurl/lib/vtls/wolfssl.c b/Utilities/cmcurl/lib/vtls/wolfssl.c
index da8cb82ce2..594c39a324 100644
--- a/Utilities/cmcurl/lib/vtls/wolfssl.c
+++ b/Utilities/cmcurl/lib/vtls/wolfssl.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -503,7 +505,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
SSL_free(backend->handle);
backend->handle = SSL_new(backend->ctx);
if(!backend->handle) {
- failf(data, "SSL: couldn't create a context");
+ failf(data, "SSL: couldn't create a handle");
return CURLE_OUT_OF_MEMORY;
}
@@ -761,17 +763,17 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
if(protocol_len == ALPN_HTTP_1_1_LENGTH &&
!memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ conn->alpn = CURL_HTTP_VERSION_1_1;
#ifdef USE_HTTP2
else if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
protocol_len == ALPN_H2_LENGTH &&
!memcmp(protocol, ALPN_H2, ALPN_H2_LENGTH))
- conn->negnpn = CURL_HTTP_VERSION_2;
+ conn->alpn = CURL_HTTP_VERSION_2;
#endif
else
infof(data, "ALPN, unrecognized protocol %.*s", protocol_len,
protocol);
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
else if(rc == SSL_ALPN_NOT_FOUND)
@@ -809,8 +811,10 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn,
if(SSL_SET_OPTION(primary.sessionid)) {
bool incache;
+ bool added = FALSE;
void *old_ssl_sessionid = NULL;
- SSL_SESSION *our_ssl_sessionid = SSL_get_session(backend->handle);
+ /* SSL_get1_session allocates memory that has to be freed. */
+ SSL_SESSION *our_ssl_sessionid = SSL_get1_session(backend->handle);
bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
if(our_ssl_sessionid) {
@@ -830,11 +834,20 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn,
0, sockindex, NULL);
if(result) {
Curl_ssl_sessionid_unlock(data);
+ SSL_SESSION_free(our_ssl_sessionid);
failf(data, "failed to store ssl session");
return result;
}
+ else {
+ added = TRUE;
+ }
}
Curl_ssl_sessionid_unlock(data);
+
+ if(!added) {
+ /* If the session info wasn't added to the cache, free our copy. */
+ SSL_SESSION_free(our_ssl_sessionid);
+ }
}
}
@@ -954,8 +967,7 @@ static ssize_t wolfssl_recv(struct Curl_easy *data,
static void wolfssl_session_free(void *ptr)
{
- (void)ptr;
- /* wolfSSL reuses sessions on own, no free */
+ SSL_SESSION_free(ptr);
}
diff --git a/Utilities/cmcurl/lib/vtls/wolfssl.h b/Utilities/cmcurl/lib/vtls/wolfssl.h
index d411e6913e..b2e7c3fde2 100644
--- a/Utilities/cmcurl/lib/vtls/wolfssl.h
+++ b/Utilities/cmcurl/lib/vtls/wolfssl.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/vtls/x509asn1.c b/Utilities/cmcurl/lib/vtls/x509asn1.c
index dfb938621c..0cfcbe87da 100644
--- a/Utilities/cmcurl/lib/vtls/x509asn1.c
+++ b/Utilities/cmcurl/lib/vtls/x509asn1.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -43,6 +45,7 @@
#include <curl/curl.h>
#include "urldata.h"
#include "strcase.h"
+#include "curl_ctype.h"
#include "hostcheck.h"
#include "vtls/vtls.h"
#include "sendf.h"
@@ -714,7 +717,7 @@ static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn)
/* Encode delimiter.
If attribute has a short uppercase name, delimiter is ", ". */
if(l) {
- for(p3 = str; isupper(*p3); p3++)
+ for(p3 = str; ISUPPER(*p3); p3++)
;
for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) {
if(l < buflen)
@@ -956,7 +959,7 @@ static int do_pubkey(struct Curl_easy *data, int certnum,
infof(data, " ECC Public Key (%lu bits)", len);
if(data->set.ssl.certinfo) {
char q[sizeof(len) * 8 / 3 + 1];
- msnprintf(q, sizeof(q), "%lu", len);
+ (void)msnprintf(q, sizeof(q), "%lu", len);
if(Curl_ssl_push_certinfo(data, certnum, "ECC Public Key", q))
return 1;
}
diff --git a/Utilities/cmcurl/lib/vtls/x509asn1.h b/Utilities/cmcurl/lib/vtls/x509asn1.h
index db7df0ef12..a18fa11530 100644
--- a/Utilities/cmcurl/lib/vtls/x509asn1.h
+++ b/Utilities/cmcurl/lib/vtls/x509asn1.h
@@ -21,6 +21,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/warnless.c b/Utilities/cmcurl/lib/warnless.c
index 0336a41d80..b00d7a5a26 100644
--- a/Utilities/cmcurl/lib/warnless.c
+++ b/Utilities/cmcurl/lib/warnless.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -37,6 +39,8 @@
#include "warnless.h"
+#include <limits.h>
+
#define CURL_MASK_UCHAR ((unsigned char)~0)
#define CURL_MASK_SCHAR (CURL_MASK_UCHAR >> 1)
diff --git a/Utilities/cmcurl/lib/warnless.h b/Utilities/cmcurl/lib/warnless.h
index 37ac5ba19f..4367099d92 100644
--- a/Utilities/cmcurl/lib/warnless.h
+++ b/Utilities/cmcurl/lib/warnless.h
@@ -20,6 +20,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/wildcard.c b/Utilities/cmcurl/lib/wildcard.c
index 105bcce4ed..a3e24b6784 100644
--- a/Utilities/cmcurl/lib/wildcard.c
+++ b/Utilities/cmcurl/lib/wildcard.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
diff --git a/Utilities/cmcurl/lib/wildcard.h b/Utilities/cmcurl/lib/wildcard.h
index 081be9ed93..21e933b9a4 100644
--- a/Utilities/cmcurl/lib/wildcard.h
+++ b/Utilities/cmcurl/lib/wildcard.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,11 +20,14 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
#ifndef CURL_DISABLE_FTP
+#include <curl/curl.h>
#include "llist.h"
/* list of wildcard process states */
diff --git a/Utilities/cmcurl/lib/ws.c b/Utilities/cmcurl/lib/ws.c
new file mode 100644
index 0000000000..a673446625
--- /dev/null
+++ b/Utilities/cmcurl/lib/ws.c
@@ -0,0 +1,757 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+#include <curl/curl.h>
+
+#ifdef USE_WEBSOCKETS
+
+#include "urldata.h"
+#include "dynbuf.h"
+#include "rand.h"
+#include "curl_base64.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "ws.h"
+#include "easyif.h"
+#include "transfer.h"
+#include "nonblock.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+struct wsfield {
+ const char *name;
+ const char *val;
+};
+
+CURLcode Curl_ws_request(struct Curl_easy *data, REQTYPE *req)
+{
+ unsigned int i;
+ CURLcode result = CURLE_OK;
+ unsigned char rand[16];
+ char *randstr;
+ size_t randlen;
+ char keyval[40];
+ struct SingleRequest *k = &data->req;
+ struct wsfield heads[]= {
+ {
+ /* The request MUST contain an |Upgrade| header field whose value
+ MUST include the "websocket" keyword. */
+ "Upgrade:", "websocket"
+ },
+ {
+ /* The request MUST contain a |Connection| header field whose value
+ MUST include the "Upgrade" token. */
+ "Connection:", "Upgrade",
+ },
+ {
+ /* The request MUST include a header field with the name
+ |Sec-WebSocket-Version|. The value of this header field MUST be
+ 13. */
+ "Sec-WebSocket-Version:", "13",
+ },
+ {
+ /* The request MUST include a header field with the name
+ |Sec-WebSocket-Key|. The value of this header field MUST be a nonce
+ consisting of a randomly selected 16-byte value that has been
+ base64-encoded (see Section 4 of [RFC4648]). The nonce MUST be
+ selected randomly for each connection. */
+ "Sec-WebSocket-Key:", NULL,
+ }
+ };
+ heads[3].val = &keyval[0];
+
+ /* 16 bytes random */
+ result = Curl_rand(data, (unsigned char *)rand, sizeof(rand));
+ if(result)
+ return result;
+ result = Curl_base64_encode((char *)rand, sizeof(rand), &randstr, &randlen);
+ if(result)
+ return result;
+ DEBUGASSERT(randlen < sizeof(keyval));
+ if(randlen >= sizeof(keyval))
+ return CURLE_FAILED_INIT;
+ strcpy(keyval, randstr);
+ free(randstr);
+ for(i = 0; !result && (i < sizeof(heads)/sizeof(heads[0])); i++) {
+ if(!Curl_checkheaders(data, STRCONST(heads[i].name))) {
+#ifdef USE_HYPER
+ char field[128];
+ msnprintf(field, sizeof(field), "%s %s", heads[i].name,
+ heads[i].val);
+ result = Curl_hyper_header(data, req, field);
+#else
+ (void)data;
+ result = Curl_dyn_addf(req, "%s %s\r\n", heads[i].name,
+ heads[i].val);
+#endif
+ }
+ }
+ k->upgr101 = UPGR101_WS;
+ Curl_dyn_init(&data->req.p.http->ws.buf, MAX_WS_SIZE * 2);
+ return result;
+}
+
+CURLcode Curl_ws_accept(struct Curl_easy *data)
+{
+ struct SingleRequest *k = &data->req;
+ struct HTTP *ws = data->req.p.http;
+ struct connectdata *conn = data->conn;
+ struct websocket *wsp = &data->req.p.http->ws;
+ CURLcode result;
+
+ /* Verify the Sec-WebSocket-Accept response.
+
+ The sent value is the base64 encoded version of a SHA-1 hash done on the
+ |Sec-WebSocket-Key| header field concatenated with
+ the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".
+ */
+
+ /* If the response includes a |Sec-WebSocket-Extensions| header field and
+ this header field indicates the use of an extension that was not present
+ in the client's handshake (the server has indicated an extension not
+ requested by the client), the client MUST Fail the WebSocket Connection.
+ */
+
+ /* If the response includes a |Sec-WebSocket-Protocol| header field
+ and this header field indicates the use of a subprotocol that was
+ not present in the client's handshake (the server has indicated a
+ subprotocol not requested by the client), the client MUST Fail
+ the WebSocket Connection. */
+
+ /* 4 bytes random */
+ result = Curl_rand(data, (unsigned char *)&ws->ws.mask, sizeof(ws->ws.mask));
+ if(result)
+ return result;
+
+ infof(data, "Received 101, switch to WebSocket; mask %02x%02x%02x%02x",
+ ws->ws.mask[0], ws->ws.mask[1], ws->ws.mask[2], ws->ws.mask[3]);
+ k->upgr101 = UPGR101_RECEIVED;
+
+ if(data->set.connect_only)
+ /* switch off non-blocking sockets */
+ (void)curlx_nonblock(conn->sock[FIRSTSOCKET], FALSE);
+
+ wsp->oleft = 0;
+ return result;
+}
+
+#define WSBIT_FIN 0x80
+#define WSBIT_OPCODE_CONT 0
+#define WSBIT_OPCODE_TEXT (1)
+#define WSBIT_OPCODE_BIN (2)
+#define WSBIT_OPCODE_CLOSE (8)
+#define WSBIT_OPCODE_PING (9)
+#define WSBIT_OPCODE_PONG (0xa)
+#define WSBIT_OPCODE_MASK (0xf)
+
+#define WSBIT_MASK 0x80
+
+/* remove the spent bytes from the beginning of the buffer as that part has
+ now been delivered to the application */
+static void ws_decode_clear(struct Curl_easy *data)
+{
+ struct websocket *wsp = &data->req.p.http->ws;
+ size_t spent = wsp->usedbuf;
+ size_t len = Curl_dyn_len(&wsp->buf);
+ size_t keep = len - spent;
+ DEBUGASSERT(len >= spent);
+ Curl_dyn_tail(&wsp->buf, keep);
+}
+
+/* ws_decode() decodes a binary frame into structured WebSocket data,
+
+ wpkt - the incoming raw data. If NULL, work on the already buffered data.
+ ilen - the size of the provided data, perhaps too little, perhaps too much
+ out - stored pointed to extracted data
+ olen - stored length of the extracted data
+ oleft - number of unread bytes pending to that belongs to this frame
+ more - if there is more data in there
+ flags - stored bitmask about the frame
+
+ Returns CURLE_AGAIN if there is only a partial frame in the buffer. Then it
+ stores the first part in the ->extra buffer to be used in the next call
+ when more data is provided.
+*/
+
+static CURLcode ws_decode(struct Curl_easy *data,
+ unsigned char *wpkt, size_t ilen,
+ unsigned char **out, size_t *olen,
+ curl_off_t *oleft,
+ bool *more,
+ unsigned int *flags)
+{
+ bool fin;
+ unsigned char opcode;
+ curl_off_t total;
+ size_t dataindex = 2;
+ curl_off_t plen; /* size of data in the buffer */
+ curl_off_t payloadsize;
+ struct websocket *wsp = &data->req.p.http->ws;
+ unsigned char *p;
+ CURLcode result;
+
+ *olen = 0;
+
+ /* add the incoming bytes, if any */
+ if(wpkt) {
+ result = Curl_dyn_addn(&wsp->buf, wpkt, ilen);
+ if(result)
+ return result;
+ }
+
+ plen = Curl_dyn_len(&wsp->buf);
+ if(plen < 2) {
+ /* the smallest possible frame is two bytes */
+ infof(data, "WS: plen == %u, EAGAIN", (int)plen);
+ return CURLE_AGAIN;
+ }
+
+ p = Curl_dyn_uptr(&wsp->buf);
+
+ fin = p[0] & WSBIT_FIN;
+ opcode = p[0] & WSBIT_OPCODE_MASK;
+ infof(data, "WS:%d received FIN bit %u", __LINE__, (int)fin);
+ *flags = 0;
+ switch(opcode) {
+ case WSBIT_OPCODE_CONT:
+ if(!fin)
+ *flags |= CURLWS_CONT;
+ infof(data, "WS: received OPCODE CONT");
+ break;
+ case WSBIT_OPCODE_TEXT:
+ infof(data, "WS: received OPCODE TEXT");
+ *flags |= CURLWS_TEXT;
+ break;
+ case WSBIT_OPCODE_BIN:
+ infof(data, "WS: received OPCODE BINARY");
+ *flags |= CURLWS_BINARY;
+ break;
+ case WSBIT_OPCODE_CLOSE:
+ infof(data, "WS: received OPCODE CLOSE");
+ *flags |= CURLWS_CLOSE;
+ break;
+ case WSBIT_OPCODE_PING:
+ infof(data, "WS: received OPCODE PING");
+ *flags |= CURLWS_PING;
+ break;
+ case WSBIT_OPCODE_PONG:
+ infof(data, "WS: received OPCODE PONG");
+ *flags |= CURLWS_PONG;
+ break;
+ }
+
+ if(p[1] & WSBIT_MASK) {
+ /* A client MUST close a connection if it detects a masked frame. */
+ failf(data, "WS: masked input frame");
+ return CURLE_RECV_ERROR;
+ }
+ payloadsize = p[1];
+ if(payloadsize == 126) {
+ if(plen < 4) {
+ infof(data, "WS:%d plen == %u, EAGAIN", __LINE__, (int)plen);
+ return CURLE_AGAIN; /* not enough data available */
+ }
+ payloadsize = (p[2] << 8) | p[3];
+ dataindex += 2;
+ }
+ else if(payloadsize == 127) {
+ /* 64 bit payload size */
+ if(plen < 10)
+ return CURLE_AGAIN;
+ if(p[2] & 80) {
+ failf(data, "WS: too large frame");
+ return CURLE_RECV_ERROR;
+ }
+ dataindex += 8;
+ payloadsize = ((curl_off_t)p[2] << 56) |
+ (curl_off_t)p[3] << 48 |
+ (curl_off_t)p[4] << 40 |
+ (curl_off_t)p[5] << 32 |
+ (curl_off_t)p[6] << 24 |
+ (curl_off_t)p[7] << 16 |
+ (curl_off_t)p[8] << 8 |
+ p[9];
+ }
+
+ total = dataindex + payloadsize;
+ if(total > plen) {
+ /* deliver a partial frame */
+ *oleft = total - dataindex;
+ payloadsize = total - dataindex;
+ }
+ else {
+ *oleft = 0;
+ if(plen > total)
+ /* there is another fragment after */
+ *more = TRUE;
+ }
+
+ /* point to the payload */
+ *out = &p[dataindex];
+
+ /* return the payload length */
+ *olen = payloadsize;
+
+ /* number of bytes "used" from the buffer */
+ wsp->usedbuf = dataindex + payloadsize;
+ infof(data, "WS: received %zu bytes payload (%zu left)",
+ payloadsize, *oleft);
+ return CURLE_OK;
+}
+
+/* Curl_ws_writecb() is the write callback for websocket traffic. The
+ websocket data is provided to this raw, in chunks. This function should
+ handle/decode the data and call the "real" underlying callback accordingly.
+*/
+size_t Curl_ws_writecb(char *buffer, size_t size /* 1 */,
+ size_t nitems, void *userp)
+{
+ struct HTTP *ws = (struct HTTP *)userp;
+ struct Curl_easy *data = ws->ws.data;
+ void *writebody_ptr = data->set.out;
+ if(data->set.ws_raw_mode)
+ return data->set.fwrite_func(buffer, size, nitems, writebody_ptr);
+ else if(nitems) {
+ unsigned char *frame = NULL;
+ size_t flen = 0;
+ size_t wrote = 0;
+ CURLcode result;
+ bool more; /* there's is more to parse in the buffer */
+ curl_off_t oleft;
+
+ decode:
+ more = FALSE;
+ oleft = ws->ws.frame.bytesleft;
+ if(!oleft) {
+ unsigned int recvflags;
+ result = ws_decode(data, (unsigned char *)buffer, nitems,
+ &frame, &flen, &oleft, &more, &recvflags);
+ if(result == CURLE_AGAIN)
+ /* insufficient amount of data, keep it for later */
+ return nitems;
+ else if(result) {
+ infof(data, "WS: decode error %d", (int)result);
+ return nitems - 1;
+ }
+ /* Store details about the frame to be reachable with curl_ws_meta()
+ from within the write callback */
+ ws->ws.frame.age = 0;
+ ws->ws.frame.offset = 0;
+ ws->ws.frame.flags = recvflags;
+ ws->ws.frame.bytesleft = oleft;
+ }
+ else {
+ if(nitems > (size_t)ws->ws.frame.bytesleft) {
+ nitems = ws->ws.frame.bytesleft;
+ more = TRUE;
+ }
+ else
+ more = FALSE;
+ ws->ws.frame.offset += nitems;
+ ws->ws.frame.bytesleft -= nitems;
+ frame = (unsigned char *)buffer;
+ flen = nitems;
+ }
+ if((ws->ws.frame.flags & CURLWS_PING) && !oleft) {
+ /* auto-respond to PINGs, only works for single-frame payloads atm */
+ size_t bytes;
+ infof(data, "WS: auto-respond to PING with a PONG");
+ DEBUGASSERT(frame);
+ /* send back the exact same content as a PONG */
+ result = curl_ws_send(data, frame, flen, &bytes, 0, CURLWS_PONG);
+ if(result)
+ return result;
+ }
+ else {
+ /* deliver the decoded frame to the user callback */
+ Curl_set_in_callback(data, true);
+ wrote = data->set.fwrite_func((char *)frame, 1, flen, writebody_ptr);
+ Curl_set_in_callback(data, false);
+ if(wrote != flen)
+ return 0;
+ }
+ if(oleft)
+ ws->ws.frame.offset += flen;
+ /* the websocket frame has been delivered */
+ ws_decode_clear(data);
+ if(more) {
+ /* there's more websocket data to deal with in the buffer */
+ buffer = NULL; /* the buffer as been drained already */
+ goto decode;
+ }
+ }
+ return nitems;
+}
+
+
+CURL_EXTERN CURLcode curl_ws_recv(struct Curl_easy *data, void *buffer,
+ size_t buflen, size_t *nread,
+ struct curl_ws_frame **metap)
+{
+ size_t bytes;
+ CURLcode result;
+ struct websocket *wsp = &data->req.p.http->ws;
+
+ *nread = 0;
+ *metap = NULL;
+ /* get a download buffer */
+ result = Curl_preconnect(data);
+ if(result)
+ return result;
+
+ do {
+ bool drain = FALSE; /* if there is pending buffered data to drain */
+ char *inbuf = data->state.buffer;
+ bytes = wsp->stillbuffer;
+ if(!bytes) {
+ result = curl_easy_recv(data, data->state.buffer,
+ data->set.buffer_size, &bytes);
+ if(result)
+ return result;
+ }
+ else {
+ /* the pending bytes can be found here */
+ inbuf = wsp->stillb;
+ drain = TRUE;
+ }
+ if(bytes) {
+ unsigned char *out;
+ size_t olen;
+ bool more;
+ unsigned int recvflags;
+ curl_off_t oleft = wsp->frame.bytesleft;
+
+ infof(data, "WS: got %u websocket bytes to decode", (int)bytes);
+ if(!oleft && !drain) {
+ result = ws_decode(data, (unsigned char *)inbuf, bytes,
+ &out, &olen, &oleft, &more, &recvflags);
+ if(result == CURLE_AGAIN)
+ /* a packet fragment only */
+ break;
+ else if(result)
+ return result;
+ wsp->frame.offset = 0;
+ wsp->frame.bytesleft = oleft;
+ wsp->frame.flags = recvflags;
+ }
+ else {
+ olen = oleft;
+ out = (unsigned char *)wsp->stillb;
+ recvflags = wsp->frame.flags;
+ if((curl_off_t)buflen < oleft)
+ /* there is still data left after this */
+ wsp->frame.bytesleft -= buflen;
+ else
+ wsp->frame.bytesleft = 0;
+ }
+
+ /* auto-respond to PINGs */
+ if((recvflags & CURLWS_PING) && !oleft) {
+ infof(data, "WS: auto-respond to PING with a PONG");
+ /* send back the exact same content as a PONG */
+ result = curl_ws_send(data, out, olen, &bytes, 0, CURLWS_PONG);
+ if(result)
+ return result;
+ }
+ else {
+ if(olen < buflen) {
+ /* copy the payload to the user buffer */
+ memcpy(buffer, out, olen);
+ *nread = olen;
+ if(!oleft)
+ /* websocket frame has been delivered */
+ ws_decode_clear(data);
+ }
+ else {
+ /* copy a partial payload */
+ memcpy(buffer, out, buflen);
+ *nread = buflen;
+ /* remember what is left and where */
+ wsp->stillbuffer = olen - buflen;
+ wsp->stillb = (char *)buffer + buflen;
+ }
+ wsp->frame.offset += *nread;
+ }
+ }
+ else
+ *nread = bytes;
+ break;
+ } while(1);
+ *metap = &wsp->frame;
+ return CURLE_OK;
+}
+
+static void ws_xor(struct Curl_easy *data,
+ const unsigned char *source,
+ unsigned char *dest,
+ size_t len)
+{
+ struct websocket *wsp = &data->req.p.http->ws;
+ size_t i;
+ /* append payload after the mask, XOR appropriately */
+ for(i = 0; i < len; i++) {
+ dest[i] = source[i] ^ wsp->mask[wsp->xori];
+ wsp->xori++;
+ wsp->xori &= 3;
+ }
+}
+
+/***
+ RFC 6455 Section 5.2
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-------+-+-------------+-------------------------------+
+ |F|R|R|R| opcode|M| Payload len | Extended payload length |
+ |I|S|S|S| (4) |A| (7) | (16/64) |
+ |N|V|V|V| |S| | (if payload len==126/127) |
+ | |1|2|3| |K| | |
+ +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
+ | Extended payload length continued, if payload len == 127 |
+ + - - - - - - - - - - - - - - - +-------------------------------+
+ | |Masking-key, if MASK set to 1 |
+ +-------------------------------+-------------------------------+
+ | Masking-key (continued) | Payload Data |
+ +-------------------------------- - - - - - - - - - - - - - - - +
+ : Payload Data continued ... :
+ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+ | Payload Data continued ... |
+ +---------------------------------------------------------------+
+*/
+
+static size_t ws_packethead(struct Curl_easy *data,
+ size_t len, unsigned int flags)
+{
+ struct HTTP *ws = data->req.p.http;
+ unsigned char *out = (unsigned char *)data->state.ulbuf;
+ unsigned char firstbyte = 0;
+ int outi;
+ unsigned char opcode;
+ if(flags & CURLWS_TEXT) {
+ opcode = WSBIT_OPCODE_TEXT;
+ infof(data, "WS: send OPCODE TEXT");
+ }
+ else if(flags & CURLWS_CLOSE) {
+ opcode = WSBIT_OPCODE_CLOSE;
+ infof(data, "WS: send OPCODE CLOSE");
+ }
+ else if(flags & CURLWS_PING) {
+ opcode = WSBIT_OPCODE_PING;
+ infof(data, "WS: send OPCODE PING");
+ }
+ else if(flags & CURLWS_PONG) {
+ opcode = WSBIT_OPCODE_PONG;
+ infof(data, "WS: send OPCODE PONG");
+ }
+ else {
+ opcode = WSBIT_OPCODE_BIN;
+ infof(data, "WS: send OPCODE BINARY");
+ }
+
+ if(!(flags & CURLWS_CONT)) {
+ /* if not marked as continuing, assume this is the final fragment */
+ firstbyte |= WSBIT_FIN | opcode;
+ ws->ws.contfragment = FALSE;
+ }
+ else if(ws->ws.contfragment) {
+ /* the previous fragment was not a final one and this isn't either, keep a
+ CONT opcode and no FIN bit */
+ firstbyte |= WSBIT_OPCODE_CONT;
+ }
+ else {
+ ws->ws.contfragment = TRUE;
+ }
+ out[0] = firstbyte;
+ if(len > 65535) {
+ out[1] = 127 | WSBIT_MASK;
+ out[2] = (len >> 8) & 0xff;
+ out[3] = len & 0xff;
+ outi = 10;
+ }
+ else if(len > 126) {
+ out[1] = 126 | WSBIT_MASK;
+ out[2] = (len >> 8) & 0xff;
+ out[3] = len & 0xff;
+ outi = 4;
+ }
+ else {
+ out[1] = (unsigned char)len | WSBIT_MASK;
+ outi = 2;
+ }
+
+ infof(data, "WS: send FIN bit %u (byte %02x)",
+ firstbyte & WSBIT_FIN ? 1 : 0,
+ firstbyte);
+ infof(data, "WS: send payload len %u", (int)len);
+
+ /* 4 bytes mask */
+ memcpy(&out[outi], &ws->ws.mask, 4);
+
+ if(data->set.upload_buffer_size < (len + 10))
+ return 0;
+
+ /* pass over the mask */
+ outi += 4;
+
+ ws->ws.xori = 0;
+ /* return packet size */
+ return outi;
+}
+
+CURL_EXTERN CURLcode curl_ws_send(struct Curl_easy *data, const void *buffer,
+ size_t buflen, size_t *sent,
+ curl_off_t totalsize,
+ unsigned int sendflags)
+{
+ CURLcode result;
+ size_t headlen;
+ char *out;
+ ssize_t written;
+ struct websocket *wsp = &data->req.p.http->ws;
+
+ if(!data->set.ws_raw_mode) {
+ result = Curl_get_upload_buffer(data);
+ if(result)
+ return result;
+ }
+ else {
+ if(totalsize || sendflags)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ if(data->set.ws_raw_mode) {
+ if(!buflen)
+ /* nothing to do */
+ return CURLE_OK;
+ /* raw mode sends exactly what was requested, and this is from within
+ the write callback */
+ if(Curl_is_in_callback(data))
+ result = Curl_write(data, data->conn->writesockfd, buffer, buflen,
+ &written);
+ else
+ result = Curl_senddata(data, buffer, buflen, &written);
+
+ infof(data, "WS: wanted to send %zu bytes, sent %zu bytes",
+ buflen, written);
+ *sent = written;
+ return result;
+ }
+
+ if(buflen > (data->set.upload_buffer_size - 10))
+ /* don't do more than this in one go */
+ buflen = data->set.upload_buffer_size - 10;
+
+ if(sendflags & CURLWS_OFFSET) {
+ if(totalsize) {
+ /* a frame series 'totalsize' bytes big, this is the first */
+ headlen = ws_packethead(data, totalsize, sendflags);
+ wsp->sleft = totalsize - buflen;
+ }
+ else {
+ headlen = 0;
+ if((curl_off_t)buflen > wsp->sleft) {
+ infof(data, "WS: unaligned frame size (sending %zu instead of %zu)",
+ buflen, wsp->sleft);
+ wsp->sleft = 0;
+ }
+ else
+ wsp->sleft -= buflen;
+ }
+ }
+ else
+ headlen = ws_packethead(data, buflen, sendflags);
+
+ /* headlen is the size of the frame header */
+ out = data->state.ulbuf;
+ if(buflen)
+ /* for PING and PONG etc there might not be a payload */
+ ws_xor(data, buffer, (unsigned char *)out + headlen, buflen);
+
+ if(data->set.connect_only)
+ result = Curl_senddata(data, out, buflen + headlen, &written);
+ else
+ result = Curl_write(data, data->conn->writesockfd, out,
+ buflen + headlen, &written);
+
+ infof(data, "WS: wanted to send %zu bytes, sent %zu bytes",
+ headlen + buflen, written);
+ *sent = written;
+
+ return result;
+}
+
+void Curl_ws_done(struct Curl_easy *data)
+{
+ struct websocket *wsp = &data->req.p.http->ws;
+ DEBUGASSERT(wsp);
+ Curl_dyn_free(&wsp->buf);
+}
+
+CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
+{
+ /* we only return something for websocket, called from within the callback
+ when not using raw mode */
+ if(GOOD_EASY_HANDLE(data) && Curl_is_in_callback(data) && data->req.p.http &&
+ !data->set.ws_raw_mode)
+ return &data->req.p.http->ws.frame;
+ return NULL;
+}
+
+#else
+
+CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
+ size_t *nread,
+ struct curl_ws_frame **metap)
+{
+ (void)curl;
+ (void)buffer;
+ (void)buflen;
+ (void)nread;
+ (void)metap;
+ return CURLE_OK;
+}
+
+CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer,
+ size_t buflen, size_t *sent,
+ curl_off_t framesize,
+ unsigned int sendflags)
+{
+ (void)curl;
+ (void)buffer;
+ (void)buflen;
+ (void)sent;
+ (void)framesize;
+ (void)sendflags;
+ return CURLE_OK;
+}
+
+CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data)
+{
+ (void)data;
+ return NULL;
+}
+#endif /* USE_WEBSOCKETS */
diff --git a/Utilities/cmcurl/lib/ws.h b/Utilities/cmcurl/lib/ws.h
new file mode 100644
index 0000000000..341242e50e
--- /dev/null
+++ b/Utilities/cmcurl/lib/ws.h
@@ -0,0 +1,69 @@
+#ifndef HEADER_CURL_WS_H
+#define HEADER_CURL_WS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_WEBSOCKETS
+
+#ifdef USE_HYPER
+#define REQTYPE void
+#else
+#define REQTYPE struct dynbuf
+#endif
+
+/* this is the largest single fragment size we support */
+#define MAX_WS_SIZE 65535
+
+/* part of 'struct HTTP', when used in the 'struct SingleRequest' in the
+ Curl_easy struct */
+struct websocket {
+ bool contfragment; /* set TRUE if the previous fragment sent was not final */
+ unsigned char mask[4]; /* 32 bit mask for this connection */
+ struct Curl_easy *data; /* used for write callback handling */
+ struct dynbuf buf;
+ size_t usedbuf; /* number of leading bytes in 'buf' the most recent complete
+ websocket frame uses */
+ struct curl_ws_frame frame; /* the struct used for frame state */
+ curl_off_t oleft; /* outstanding number of payload bytes left from the
+ server */
+ curl_off_t stillbuffer; /* number of bytes left in the buffer to deliver in
+ the next curl_ws_recv() call */
+ char *stillb; /* the stillbuffer pending bytes are here */
+ curl_off_t sleft; /* outstanding number of payload bytes left to send */
+ unsigned int xori; /* xor index */
+};
+
+CURLcode Curl_ws_request(struct Curl_easy *data, REQTYPE *req);
+CURLcode Curl_ws_accept(struct Curl_easy *data);
+
+size_t Curl_ws_writecb(char *buffer, size_t size, size_t nitems, void *userp);
+void Curl_ws_done(struct Curl_easy *data);
+
+#else
+#define Curl_ws_request(x,y) CURLE_OK
+#define Curl_ws_done(x) Curl_nop_stmt
+#endif
+
+#endif /* HEADER_CURL_WS_H */