tls: backends use connection filters for IO, enabling HTTPS-proxy
—
$ git checkout -f 55807e6c056f27846d70cec70ee6ac3f0e5b3bbe
Previous HEAD position was 4506cbf7f2 INSTALL: update operating systems and CPU archs
HEAD is now at 55807e6c05 tls: backends use connection filters for IO, enabling HTTPS-proxy
$ git clean -fdx
Removing Makefile
Removing Makefile.in
Removing aclocal.m4
Removing autom4te.cache/
Removing compile
Removing config.guess
Removing config.log
Removing config.status
Removing config.sub
Removing configure
Removing curl-config
Removing depcomp
Removing docs/Makefile
Removing docs/Makefile.in
Removing docs/cmdline-opts/Makefile
Removing docs/cmdline-opts/Makefile.in
Removing docs/curl.1
Removing docs/examples/.deps/
Removing docs/examples/Makefile
Removing docs/examples/Makefile.in
Removing docs/libcurl/Makefile
Removing docs/libcurl/Makefile.in
Removing docs/libcurl/opts/Makefile
Removing docs/libcurl/opts/Makefile.in
Removing include/Makefile
Removing include/Makefile.in
Removing include/curl/Makefile
Removing include/curl/Makefile.in
Removing install-sh
Removing lib/.deps/
Removing lib/.dirstamp
Removing lib/.libs/
Removing lib/Makefile
Removing lib/Makefile.in
Removing lib/curl_config.h
Removing lib/curl_config.h.in
Removing lib/curl_multibyte.o
Removing lib/dynbuf.o
Removing lib/libcurl.la
Removing lib/libcurl.plist
Removing lib/libcurl.vers
Removing lib/libcurl_la-altsvc.lo
Removing lib/libcurl_la-altsvc.o
Removing lib/libcurl_la-amigaos.lo
Removing lib/libcurl_la-amigaos.o
Removing lib/libcurl_la-asyn-ares.lo
Removing lib/libcurl_la-asyn-ares.o
Removing lib/libcurl_la-asyn-thread.lo
Removing lib/libcurl_la-asyn-thread.o
Removing lib/libcurl_la-base64.lo
Removing lib/libcurl_la-base64.o
Removing lib/libcurl_la-bufref.lo
Removing lib/libcurl_la-bufref.o
Removing lib/libcurl_la-c-hyper.lo
Removing lib/libcurl_la-c-hyper.o
Removing lib/libcurl_la-cfilters.lo
Removing lib/libcurl_la-cfilters.o
Removing lib/libcurl_la-conncache.lo
Removing lib/libcurl_la-conncache.o
Removing lib/libcurl_la-connect.lo
Removing lib/libcurl_la-connect.o
Removing lib/libcurl_la-content_encoding.lo
Removing lib/libcurl_la-content_encoding.o
Removing lib/libcurl_la-cookie.lo
Removing lib/libcurl_la-cookie.o
Removing lib/libcurl_la-curl_addrinfo.lo
Removing lib/libcurl_la-curl_addrinfo.o
Removing lib/libcurl_la-curl_des.lo
Removing lib/libcurl_la-curl_des.o
Removing lib/libcurl_la-curl_endian.lo
Removing lib/libcurl_la-curl_endian.o
Removing lib/libcurl_la-curl_fnmatch.lo
Removing lib/libcurl_la-curl_fnmatch.o
Removing lib/libcurl_la-curl_get_line.lo
Removing lib/libcurl_la-curl_get_line.o
Removing lib/libcurl_la-curl_gethostname.lo
Removing lib/libcurl_la-curl_gethostname.o
Removing lib/libcurl_la-curl_gssapi.lo
Removing lib/libcurl_la-curl_gssapi.o
Removing lib/libcurl_la-curl_memrchr.lo
Removing lib/libcurl_la-curl_memrchr.o
Removing lib/libcurl_la-curl_multibyte.lo
Removing lib/libcurl_la-curl_multibyte.o
Removing lib/libcurl_la-curl_ntlm_core.lo
Removing lib/libcurl_la-curl_ntlm_core.o
Removing lib/libcurl_la-curl_ntlm_wb.lo
Removing lib/libcurl_la-curl_ntlm_wb.o
Removing lib/libcurl_la-curl_path.lo
Removing lib/libcurl_la-curl_path.o
Removing lib/libcurl_la-curl_range.lo
Removing lib/libcurl_la-curl_range.o
Removing lib/libcurl_la-curl_rtmp.lo
Removing lib/libcurl_la-curl_rtmp.o
Removing lib/libcurl_la-curl_sasl.lo
Removing lib/libcurl_la-curl_sasl.o
Removing lib/libcurl_la-curl_sspi.lo
Removing lib/libcurl_la-curl_sspi.o
Removing lib/libcurl_la-curl_threads.lo
Removing lib/libcurl_la-curl_threads.o
Removing lib/libcurl_la-dict.lo
Removing lib/libcurl_la-dict.o
Removing lib/libcurl_la-doh.lo
Removing lib/libcurl_la-doh.o
Removing lib/libcurl_la-dynbuf.lo
Removing lib/libcurl_la-dynbuf.o
Removing lib/libcurl_la-easy.lo
Removing lib/libcurl_la-easy.o
Removing lib/libcurl_la-easygetopt.lo
Removing lib/libcurl_la-easygetopt.o
Removing lib/libcurl_la-easyoptions.lo
Removing lib/libcurl_la-easyoptions.o
Removing lib/libcurl_la-escape.lo
Removing lib/libcurl_la-escape.o
Removing lib/libcurl_la-file.lo
Removing lib/libcurl_la-file.o
Removing lib/libcurl_la-fileinfo.lo
Removing lib/libcurl_la-fileinfo.o
Removing lib/libcurl_la-fopen.lo
Removing lib/libcurl_la-fopen.o
Removing lib/libcurl_la-formdata.lo
Removing lib/libcurl_la-formdata.o
Removing lib/libcurl_la-ftp.lo
Removing lib/libcurl_la-ftp.o
Removing lib/libcurl_la-ftplistparser.lo
Removing lib/libcurl_la-ftplistparser.o
Removing lib/libcurl_la-getenv.lo
Removing lib/libcurl_la-getenv.o
Removing lib/libcurl_la-getinfo.lo
Removing lib/libcurl_la-getinfo.o
Removing lib/libcurl_la-gopher.lo
Removing lib/libcurl_la-gopher.o
Removing lib/libcurl_la-h2h3.lo
Removing lib/libcurl_la-h2h3.o
Removing lib/libcurl_la-hash.lo
Removing lib/libcurl_la-hash.o
Removing lib/libcurl_la-headers.lo
Removing lib/libcurl_la-headers.o
Removing lib/libcurl_la-hmac.lo
Removing lib/libcurl_la-hmac.o
Removing lib/libcurl_la-hostasyn.lo
Removing lib/libcurl_la-hostasyn.o
Removing lib/libcurl_la-hostip.lo
Removing lib/libcurl_la-hostip.o
Removing lib/libcurl_la-hostip4.lo
Removing lib/libcurl_la-hostip4.o
Removing lib/libcurl_la-hostip6.lo
Removing lib/libcurl_la-hostip6.o
Removing lib/libcurl_la-hostsyn.lo
Removing lib/libcurl_la-hostsyn.o
Removing lib/libcurl_la-hsts.lo
Removing lib/libcurl_la-hsts.o
Removing lib/libcurl_la-http.lo
Removing lib/libcurl_la-http.o
Removing lib/libcurl_la-http2.lo
Removing lib/libcurl_la-http2.o
Removing lib/libcurl_la-http_aws_sigv4.lo
Removing lib/libcurl_la-http_aws_sigv4.o
Removing lib/libcurl_la-http_chunks.lo
Removing lib/libcurl_la-http_chunks.o
Removing lib/libcurl_la-http_digest.lo
Removing lib/libcurl_la-http_digest.o
Removing lib/libcurl_la-http_negotiate.lo
Removing lib/libcurl_la-http_negotiate.o
Removing lib/libcurl_la-http_ntlm.lo
Removing lib/libcurl_la-http_ntlm.o
Removing lib/libcurl_la-http_proxy.lo
Removing lib/libcurl_la-http_proxy.o
Removing lib/libcurl_la-idn_win32.lo
Removing lib/libcurl_la-idn_win32.o
Removing lib/libcurl_la-if2ip.lo
Removing lib/libcurl_la-if2ip.o
Removing lib/libcurl_la-imap.lo
Removing lib/libcurl_la-imap.o
Removing lib/libcurl_la-inet_ntop.lo
Removing lib/libcurl_la-inet_ntop.o
Removing lib/libcurl_la-inet_pton.lo
Removing lib/libcurl_la-inet_pton.o
Removing lib/libcurl_la-krb5.lo
Removing lib/libcurl_la-krb5.o
Removing lib/libcurl_la-ldap.lo
Removing lib/libcurl_la-ldap.o
Removing lib/libcurl_la-llist.lo
Removing lib/libcurl_la-llist.o
Removing lib/libcurl_la-md4.lo
Removing lib/libcurl_la-md4.o
Removing lib/libcurl_la-md5.lo
Removing lib/libcurl_la-md5.o
Removing lib/libcurl_la-memdebug.lo
Removing lib/libcurl_la-memdebug.o
Removing lib/libcurl_la-mime.lo
Removing lib/libcurl_la-mime.o
Removing lib/libcurl_la-mprintf.lo
Removing lib/libcurl_la-mprintf.o
Removing lib/libcurl_la-mqtt.lo
Removing lib/libcurl_la-mqtt.o
Removing lib/libcurl_la-multi.lo
Removing lib/libcurl_la-multi.o
Removing lib/libcurl_la-netrc.lo
Removing lib/libcurl_la-netrc.o
Removing lib/libcurl_la-nonblock.lo
Removing lib/libcurl_la-nonblock.o
Removing lib/libcurl_la-noproxy.lo
Removing lib/libcurl_la-noproxy.o
Removing lib/libcurl_la-openldap.lo
Removing lib/libcurl_la-openldap.o
Removing lib/libcurl_la-parsedate.lo
Removing lib/libcurl_la-parsedate.o
Removing lib/libcurl_la-pingpong.lo
Removing lib/libcurl_la-pingpong.o
Removing lib/libcurl_la-pop3.lo
Removing lib/libcurl_la-pop3.o
Removing lib/libcurl_la-progress.lo
Removing lib/libcurl_la-progress.o
Removing lib/libcurl_la-psl.lo
Removing lib/libcurl_la-psl.o
Removing lib/libcurl_la-rand.lo
Removing lib/libcurl_la-rand.o
Removing lib/libcurl_la-rename.lo
Removing lib/libcurl_la-rename.o
Removing lib/libcurl_la-rtsp.lo
Removing lib/libcurl_la-rtsp.o
Removing lib/libcurl_la-select.lo
Removing lib/libcurl_la-select.o
Removing lib/libcurl_la-sendf.lo
Removing lib/libcurl_la-sendf.o
Removing lib/libcurl_la-setopt.lo
Removing lib/libcurl_la-setopt.o
Removing lib/libcurl_la-sha256.lo
Removing lib/libcurl_la-sha256.o
Removing lib/libcurl_la-share.lo
Removing lib/libcurl_la-share.o
Removing lib/libcurl_la-slist.lo
Removing lib/libcurl_la-slist.o
Removing lib/libcurl_la-smb.lo
Removing lib/libcurl_la-smb.o
Removing lib/libcurl_la-smtp.lo
Removing lib/libcurl_la-smtp.o
Removing lib/libcurl_la-socketpair.lo
Removing lib/libcurl_la-socketpair.o
Removing lib/libcurl_la-socks.lo
Removing lib/libcurl_la-socks.o
Removing lib/libcurl_la-socks_gssapi.lo
Removing lib/libcurl_la-socks_gssapi.o
Removing lib/libcurl_la-socks_sspi.lo
Removing lib/libcurl_la-socks_sspi.o
Removing lib/libcurl_la-speedcheck.lo
Removing lib/libcurl_la-speedcheck.o
Removing lib/libcurl_la-splay.lo
Removing lib/libcurl_la-splay.o
Removing lib/libcurl_la-strcase.lo
Removing lib/libcurl_la-strcase.o
Removing lib/libcurl_la-strdup.lo
Removing lib/libcurl_la-strdup.o
Removing lib/libcurl_la-strerror.lo
Removing lib/libcurl_la-strerror.o
Removing lib/libcurl_la-strtok.lo
Removing lib/libcurl_la-strtok.o
Removing lib/libcurl_la-strtoofft.lo
Removing lib/libcurl_la-strtoofft.o
Removing lib/libcurl_la-system_win32.lo
Removing lib/libcurl_la-system_win32.o
Removing lib/libcurl_la-telnet.lo
Removing lib/libcurl_la-telnet.o
Removing lib/libcurl_la-tftp.lo
Removing lib/libcurl_la-tftp.o
Removing lib/libcurl_la-timediff.lo
Removing lib/libcurl_la-timediff.o
Removing lib/libcurl_la-timeval.lo
Removing lib/libcurl_la-timeval.o
Removing lib/libcurl_la-transfer.lo
Removing lib/libcurl_la-transfer.o
Removing lib/libcurl_la-url.lo
Removing lib/libcurl_la-url.o
Removing lib/libcurl_la-urlapi.lo
Removing lib/libcurl_la-urlapi.o
Removing lib/libcurl_la-version.lo
Removing lib/libcurl_la-version.o
Removing lib/libcurl_la-version_win32.lo
Removing lib/libcurl_la-version_win32.o
Removing lib/libcurl_la-warnless.lo
Removing lib/libcurl_la-warnless.o
Removing lib/libcurl_la-wildcard.lo
Removing lib/libcurl_la-wildcard.o
Removing lib/libcurl_la-ws.lo
Removing lib/libcurl_la-ws.o
Removing lib/nonblock.o
Removing lib/stamp-h1
Removing lib/strtoofft.o
Removing lib/timediff.o
Removing lib/vauth/.deps/
Removing lib/vauth/.dirstamp
Removing lib/vauth/libcurl_la-cleartext.lo
Removing lib/vauth/libcurl_la-cleartext.o
Removing lib/vauth/libcurl_la-cram.lo
Removing lib/vauth/libcurl_la-cram.o
Removing lib/vauth/libcurl_la-digest.lo
Removing lib/vauth/libcurl_la-digest.o
Removing lib/vauth/libcurl_la-digest_sspi.lo
Removing lib/vauth/libcurl_la-digest_sspi.o
Removing lib/vauth/libcurl_la-gsasl.lo
Removing lib/vauth/libcurl_la-gsasl.o
Removing lib/vauth/libcurl_la-krb5_gssapi.lo
Removing lib/vauth/libcurl_la-krb5_gssapi.o
Removing lib/vauth/libcurl_la-krb5_sspi.lo
Removing lib/vauth/libcurl_la-krb5_sspi.o
Removing lib/vauth/libcurl_la-ntlm.lo
Removing lib/vauth/libcurl_la-ntlm.o
Removing lib/vauth/libcurl_la-ntlm_sspi.lo
Removing lib/vauth/libcurl_la-ntlm_sspi.o
Removing lib/vauth/libcurl_la-oauth2.lo
Removing lib/vauth/libcurl_la-oauth2.o
Removing lib/vauth/libcurl_la-spnego_gssapi.lo
Removing lib/vauth/libcurl_la-spnego_gssapi.o
Removing lib/vauth/libcurl_la-spnego_sspi.lo
Removing lib/vauth/libcurl_la-spnego_sspi.o
Removing lib/vauth/libcurl_la-vauth.lo
Removing lib/vauth/libcurl_la-vauth.o
Removing lib/version_win32.o
Removing lib/vquic/.deps/
Removing lib/vquic/.dirstamp
Removing lib/vquic/libcurl_la-msh3.lo
Removing lib/vquic/libcurl_la-msh3.o
Removing lib/vquic/libcurl_la-ngtcp2.lo
Removing lib/vquic/libcurl_la-ngtcp2.o
Removing lib/vquic/libcurl_la-quiche.lo
Removing lib/vquic/libcurl_la-quiche.o
Removing lib/vquic/libcurl_la-vquic.lo
Removing lib/vquic/libcurl_la-vquic.o
Removing lib/vssh/.deps/
Removing lib/vssh/.dirstamp
Removing lib/vssh/libcurl_la-libssh.lo
Removing lib/vssh/libcurl_la-libssh.o
Removing lib/vssh/libcurl_la-libssh2.lo
Removing lib/vssh/libcurl_la-libssh2.o
Removing lib/vssh/libcurl_la-wolfssh.lo
Removing lib/vssh/libcurl_la-wolfssh.o
Removing lib/vtls/.deps/
Removing lib/vtls/.dirstamp
Removing lib/vtls/libcurl_la-bearssl.lo
Removing lib/vtls/libcurl_la-bearssl.o
Removing lib/vtls/libcurl_la-gskit.lo
Removing lib/vtls/libcurl_la-gskit.o
Removing lib/vtls/libcurl_la-gtls.lo
Removing lib/vtls/libcurl_la-gtls.o
Removing lib/vtls/libcurl_la-hostcheck.lo
Removing lib/vtls/libcurl_la-hostcheck.o
Removing lib/vtls/libcurl_la-keylog.lo
Removing lib/vtls/libcurl_la-keylog.o
Removing lib/vtls/libcurl_la-mbedtls.lo
Removing lib/vtls/libcurl_la-mbedtls.o
Removing lib/vtls/libcurl_la-mbedtls_threadlock.lo
Removing lib/vtls/libcurl_la-mbedtls_threadlock.o
Removing lib/vtls/libcurl_la-nss.lo
Removing lib/vtls/libcurl_la-nss.o
Removing lib/vtls/libcurl_la-openssl.lo
Removing lib/vtls/libcurl_la-openssl.o
Removing lib/vtls/libcurl_la-rustls.lo
Removing lib/vtls/libcurl_la-rustls.o
Removing lib/vtls/libcurl_la-schannel.lo
Removing lib/vtls/libcurl_la-schannel.o
Removing lib/vtls/libcurl_la-schannel_verify.lo
Removing lib/vtls/libcurl_la-schannel_verify.o
Removing lib/vtls/libcurl_la-sectransp.lo
Removing lib/vtls/libcurl_la-sectransp.o
Removing lib/vtls/libcurl_la-vtls.lo
Removing lib/vtls/libcurl_la-vtls.o
Removing lib/vtls/libcurl_la-wolfssl.lo
Removing lib/vtls/libcurl_la-wolfssl.o
Removing lib/vtls/libcurl_la-x509asn1.lo
Removing lib/vtls/libcurl_la-x509asn1.o
Removing lib/warnless.o
Removing libcurl.pc
Removing libtool
Removing ltmain.sh
Removing m4/libtool.m4
Removing m4/ltoptions.m4
Removing m4/ltsugar.m4
Removing m4/ltversion.m4
Removing m4/lt~obsolete.m4
Removing missing
Removing packages/Makefile
Removing packages/Makefile.in
Removing packages/vms/Makefile
Removing packages/vms/Makefile.in
Removing scripts/Makefile
Removing scripts/Makefile.in
Removing src/.deps/
Removing src/.libs/
Removing src/Makefile
Removing src/Makefile.in
Removing src/curl
Removing src/slist_wc.o
Removing src/tool_binmode.o
Removing src/tool_bname.o
Removing src/tool_cb_dbg.o
Removing src/tool_cb_hdr.o
Removing src/tool_cb_prg.o
Removing src/tool_cb_rea.o
Removing src/tool_cb_see.o
Removing src/tool_cb_wrt.o
Removing src/tool_cfgable.o
Removing src/tool_dirhie.o
Removing src/tool_doswin.o
Removing src/tool_easysrc.o
Removing src/tool_filetime.o
Removing src/tool_findfile.o
Removing src/tool_formparse.o
Removing src/tool_getparam.o
Removing src/tool_getpass.o
Removing src/tool_help.o
Removing src/tool_helpers.o
Removing src/tool_hugehelp.c
Removing src/tool_hugehelp.o
Removing src/tool_libinfo.o
Removing src/tool_listhelp.o
Removing src/tool_main.o
Removing src/tool_msgs.o
Removing src/tool_operate.o
Removing src/tool_operhlp.o
Removing src/tool_paramhlp.o
Removing src/tool_parsecfg.o
Removing src/tool_progress.o
Removing src/tool_setopt.o
Removing src/tool_sleep.o
Removing src/tool_strdup.o
Removing src/tool_urlglob.o
Removing src/tool_util.o
Removing src/tool_vms.o
Removing src/tool_writeout.o
Removing src/tool_writeout_json.o
Removing src/tool_xattr.o
Removing test-driver
Removing tests/Makefile
Removing tests/Makefile.in
Removing tests/certs/Makefile
Removing tests/certs/Makefile.in
Removing tests/certs/scripts/Makefile
Removing tests/certs/scripts/Makefile.in
Removing tests/configurehelp.pm
Removing tests/data/Makefile
Removing tests/data/Makefile.in
Removing tests/libtest/.deps/
Removing tests/libtest/Makefile
Removing tests/libtest/Makefile.in
Removing tests/server/.deps/
Removing tests/server/Makefile
Removing tests/server/Makefile.in
Removing tests/unit/.deps/
Removing tests/unit/Makefile
Removing tests/unit/Makefile.in
$ autoreconf -fi
libtoolize: putting auxiliary files in '.'.
libtoolize: copying file './ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: copying file 'm4/libtool.m4'
libtoolize: copying file 'm4/ltoptions.m4'
libtoolize: copying file 'm4/ltsugar.m4'
libtoolize: copying file 'm4/ltversion.m4'
libtoolize: copying file 'm4/lt~obsolete.m4'
libtoolize: Remember to add 'LT_INIT' to configure.ac.
configure.ac:123: installing './compile'
configure.ac:333: installing './config.guess'
configure.ac:333: installing './config.sub'
configure.ac:123: installing './install-sh'
configure.ac:129: installing './missing'
docs/examples/Makefile.am: installing './depcomp'
parallel-tests: installing './test-driver'
$ bash -c find . -name config.guess -exec cp /usr/share/misc/config.guess {} \;
$ bash -c find . -name config.sub -exec cp /usr/share/misc/config.sub {} \;
$ chmod +x configure
$ ./configure --disable-shared --without-ssl --disable-docs
checking whether to enable maintainer-specific portions of Makefiles... no
checking whether make supports nested variables... yes
checking whether to enable debug build options... no
checking whether to enable compiler optimizer... (assumed) yes
checking whether to enable strict compiler warnings... no
checking whether to enable compiler warnings as errors... no
checking whether to enable curl debug memory tracking... no
checking whether to enable hiding of library internal symbols... yes
checking whether to enable c-ares for DNS lookups... no
checking whether to disable dependency on -lrt... (assumed no)
checking whether to enable ECH support... no
checking for path separator... :
checking for sed... /usr/bin/sed
checking for grep... /usr/bin/grep
checking that grep -E works... yes
checking for ar... /usr/bin/ar
checking for a BSD-compatible install... /usr/bin/install -c
checking for gcc... ccache gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether ccache gcc accepts -g... yes
checking for ccache gcc option to enable C11 features... none needed
checking whether ccache gcc understands -c and -o together... yes
checking how to run the C preprocessor... ccache gcc -E
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for strings.h... yes
checking for sys/stat.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for stdatomic.h... yes
checking if _Atomic is available... yes
checking for a sed that does not truncate output... (cached) /usr/bin/sed
checking for code coverage support... no
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports the include directive... yes (GNU style)
checking dependency style of ccache gcc... gcc3
checking curl version... 7.87.0-DEV
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking for grep that handles long lines and -e... (cached) /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking if OS is AIX (to define _ALL_SOURCE)... no
checking if _THREAD_SAFE is already defined... no
checking if _THREAD_SAFE is actually needed... no
checking if _THREAD_SAFE is onwards defined... no
checking if _REENTRANT is already defined... no
checking if _REENTRANT is actually needed... no
checking if _REENTRANT is onwards defined... no
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking how to print strings... printf
checking for a sed that does not truncate output... (cached) /usr/bin/sed
checking for fgrep... /usr/bin/grep -F
checking for ld used by ccache gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from ccache gcc object... ok
checking for sysroot... no
checking for a working dd... /usr/bin/dd
checking how to truncate binary pipes... /usr/bin/dd bs=4096 count=1
checking for mt... mt
checking if mt is a manifest tool... no
checking for dlfcn.h... yes
checking for objdir... .libs
checking if ccache gcc supports -fno-rtti -fno-exceptions... no
checking for ccache gcc option to produce PIC... -fPIC -DPIC
checking if ccache gcc PIC flag -fPIC -DPIC works... yes
checking if ccache gcc static flag -static works... yes
checking if ccache gcc supports -c -o file.o... yes
checking if ccache gcc supports -c -o file.o... (cached) yes
checking whether the ccache gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... no
checking whether to build static libraries... yes
checking whether to build shared libraries with -version-info... yes
checking whether to build shared libraries with -no-undefined... no
checking whether to build shared libraries with -mimpure-text... no
checking whether to build shared libraries with PIC... yes
checking whether to build static libraries with PIC... yes
checking whether to build shared libraries only... no
checking whether to build static libraries only... yes
checking for windres... no
checking for inline... inline
checking if cpp -P is needed... yes
checking if cpp -P works... yes
checking if compiler is DEC/Compaq/HP C... no
checking if compiler is HP-UX C... no
checking if compiler is IBM C... no
checking if compiler is Intel C... no
checking if compiler is clang... no
checking if compiler is GNU C... yes
checking if compiler is LCC... no
checking if compiler is SGI MIPSpro C... no
checking if compiler is SGI MIPS C... no
checking if compiler is SunPro C... no
checking if compiler is Tiny C... no
checking if compiler accepts some basic options... yes
configure: compiler options added: -Werror-implicit-function-declaration
checking if compiler optimizer assumed setting might be used... yes
checking if compiler accepts optimizer enabling options... yes
configure: compiler options added: -O2
checking if compiler accepts strict warning options... yes
configure: compiler options added: -Wno-system-headers
checking if compiler halts on compilation errors... yes
checking if compiler halts on negative sized arrays... yes
checking if compiler halts on function prototype mismatch... yes
checking if compiler supports hiding library internal symbols... yes
checking for windows.h... no
checking whether build target is a native Windows one... no
checking whether build target supports WIN32 file API... no
checking whether build target supports WIN32 crypto API... no
checking for good-to-use Darwin CFLAGS... no
checking whether to link macOS CoreFoundation and SystemConfiguration framework... no
checking to see if the compiler supports __builtin_available()... no
checking whether to support http... yes
checking whether to support ftp... yes
checking whether to support file... yes
checking whether to support ldap... yes
checking whether to support ldaps... yes
checking whether to support rtsp... yes
checking whether to support proxies... yes
checking whether to support dict... yes
checking whether to support telnet... yes
checking whether to support tftp... yes
checking whether to support pop3... yes
checking whether to support imap... yes
checking whether to support smb... yes
checking whether to support smtp... yes
checking whether to support gopher... yes
checking whether to support mqtt... no
checking whether to provide built-in manual... yes
checking whether to enable generation of C code... yes
checking whether to use libgcc... no
checking if X/Open network library is required... no
checking for gethostbyname... yes
checking for windows.h... (cached) no
checking for winsock2.h... (cached) no
checking for proto/bsdsocket.h... no
checking for connect in libraries... yes
checking for sys/types.h... (cached) yes
checking for sys/time.h... yes
checking for monotonic clock_gettime... yes
checking for clock_gettime in libraries... no additional lib required
checking if monotonic clock_gettime works... yes
checking for pkg-config... /usr/bin/pkg-config
checking for zlib options with pkg-config... found
checking for zlib.h... yes
configure: found both libz and libz.h header
checking for BrotliDecoderDecompress in -lbrotlidec... no
checking for brotli/decode.h... no
checking for ZSTD_createDStream in -lzstd... no
checking for zstd.h... no
checking for lber.h... no
checking for ldap.h... no
checking for ldap_ssl.h... no
checking for LDAP libraries... cannot find LDAP libraries
checking whether to enable IPv6... yes
checking if struct sockaddr_in6 has sin6_scope_id member... yes
checking if argv can be written to... yes
checking if GSS-API support is requested... no
checking whether to enable Windows native SSL/TLS... no
checking whether to enable Secure Transport... no
checking whether to enable Amiga native SSL/TLS (AmiSSL v5)... no
checking for library containing psl_builtin... -lpsl
checking for library containing gsasl_init... no
checking for RTMP_Init in -lrtmp... no
checking whether versioned symbols are wanted... no
checking whether to enable Windows native IDN (Windows native builds only)... no
checking whether to build with libidn2... (assumed) yes
checking for pkg-config... (cached) /usr/bin/pkg-config
checking for libidn2 options with pkg-config... no
configure: IDN_LIBS: "-lidn2"
configure: IDN_LDFLAGS: ""
configure: IDN_CPPFLAGS: ""
configure: IDN_DIR: ""
checking if idn2_lookup_ul can be linked... no
checking for idn2.h... no
checking for pkg-config... (cached) /usr/bin/pkg-config
checking for libnghttp2 options with pkg-config... no
checking for nghttp2_session_set_local_window_size in -lnghttp2... no
checking for pkg-config... (cached) /usr/bin/pkg-config
checking for fish options with pkg-config... no
checking for sys/types.h... (cached) yes
checking for sys/time.h... (cached) yes
checking for sys/select.h... yes
checking for sys/socket.h... yes
checking for sys/ioctl.h... yes
checking for sys/uio.h... yes
checking for assert.h... yes
checking for unistd.h... (cached) yes
checking for stdlib.h... (cached) yes
checking for arpa/inet.h... yes
checking for net/if.h... yes
checking for netinet/in.h... yes
checking for netinet/in6.h... no
checking for sys/un.h... yes
checking for linux/tcp.h... yes
checking for netinet/tcp.h... yes
checking for netinet/udp.h... yes
checking for netdb.h... yes
checking for sys/sockio.h... no
checking for sys/stat.h... (cached) yes
checking for sys/param.h... yes
checking for termios.h... yes
checking for termio.h... yes
checking for fcntl.h... yes
checking for io.h... no
checking for pwd.h... yes
checking for utime.h... yes
checking for sys/utime.h... no
checking for sys/poll.h... yes
checking for poll.h... yes
checking for socket.h... no
checking for sys/resource.h... yes
checking for libgen.h... yes
checking for locale.h... yes
checking for errno.h... yes
checking for stdbool.h... yes
checking for arpa/tftp.h... yes
checking for sys/filio.h... no
checking for sys/wait.h... yes
checking for setjmp.h... yes
checking for an ANSI C-conforming const... yes
checking for compiler support of C99 variadic macro style... yes
checking for compiler support of old gcc variadic macro style... yes
checking for size_t... yes
checking for sys/types.h... (cached) yes
checking for sys/time.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for struct timeval... yes
checking run-time libs availability... fine
checking size of size_t... 8
checking size of long... 8
checking size of int... 4
checking size of time_t... 8
checking size of off_t... 8
checking size of curl_off_t... 8
checking for long long... yes
checking for ssize_t... yes
checking for bool... yes
checking for sa_family_t... yes
checking for suseconds_t... yes
checking if time_t is unsigned... no
checking for sys/types.h... (cached) yes
checking for poll.h... (cached) yes
checking for sys/poll.h... (cached) yes
checking for in_addr_t... yes
checking for struct sockaddr_storage... yes
checking for sys/select.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for select... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for recv... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for send... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for MSG_NOSIGNAL... yes
checking for sys/types.h... (cached) yes
checking for unistd.h... (cached) yes
checking if alarm can be linked... yes
checking if alarm is prototyped... yes
checking if alarm is compilable... yes
checking if alarm usage allowed... yes
checking if alarm might be used... yes
checking for sys/types.h... (cached) yes
checking for string.h... (cached) yes
checking for strings.h... (cached) yes
checking for sys/types.h... (cached) yes
checking for libgen.h... (cached) yes
checking if basename can be linked... yes
checking if basename is prototyped... yes
checking if basename is compilable... yes
checking if basename usage allowed... yes
checking if basename might be used... yes
checking for sys/types.h... (cached) yes
checking for socket.h... (cached) no
checking if closesocket can be linked... no
checking if closesocket might be used... no
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking if CloseSocket can be linked... no
checking if CloseSocket might be used... no
checking if connect can be linked... yes
checking if connect is prototyped... yes
checking if connect is compilable... yes
checking if connect usage allowed... yes
checking if connect might be used... yes
checking for sys/types.h... (cached) yes
checking for unistd.h... (cached) yes
checking for fcntl.h... (cached) yes
checking if fcntl can be linked... yes
checking if fcntl is prototyped... yes
checking if fcntl is compilable... yes
checking if fcntl usage allowed... yes
checking if fcntl might be used... yes
checking if fcntl O_NONBLOCK is compilable... yes
checking if fcntl O_NONBLOCK usage allowed... yes
checking if fcntl O_NONBLOCK might be used... yes
checking for windows.h... (cached) no
checking for winsock2.h... (cached) no
checking for ws2tcpip.h... (cached) no
checking for sys/types.h... (cached) yes
checking for netdb.h... (cached) yes
checking if freeaddrinfo can be linked... yes
checking if freeaddrinfo is prototyped... yes
checking if freeaddrinfo is compilable... yes
checking if freeaddrinfo usage allowed... yes
checking if freeaddrinfo might be used... yes
checking for sys/types.h... (cached) yes
checking for sys/xattr.h... yes
checking if fsetxattr can be linked... yes
checking if fsetxattr is prototyped... yes
checking if fsetxattr takes 5 args.... yes
checking if fsetxattr is compilable... yes
checking if fsetxattr usage allowed... yes
checking if fsetxattr might be used... yes
checking if ftruncate can be linked... yes
checking if ftruncate is prototyped... yes
checking if ftruncate is compilable... yes
checking if ftruncate usage allowed... yes
checking if ftruncate might be used... yes
checking for sys/types.h... (cached) yes
checking for stdlib.h... (cached) yes
checking if getaddrinfo can be linked... yes
checking if getaddrinfo is prototyped... yes
checking if getaddrinfo is compilable... yes
checking if getaddrinfo seems to work... yes
checking if getaddrinfo usage allowed... yes
checking if getaddrinfo might be used... yes
checking if getaddrinfo is threadsafe... yes
checking if gethostbyname can be linked... yes
checking if gethostbyname is prototyped... yes
checking if gethostbyname is compilable... yes
checking if gethostbyname usage allowed... yes
checking if gethostbyname might be used... yes
checking if gethostbyname_r can be linked... yes
checking if gethostbyname_r is prototyped... yes
checking if gethostbyname_r takes 3 args.... no
checking if gethostbyname_r takes 5 args.... no
checking if gethostbyname_r takes 6 args.... yes
checking if gethostbyname_r is compilable... yes
checking if gethostbyname_r usage allowed... yes
checking if gethostbyname_r might be used... yes
checking if gethostname can be linked... yes
checking if gethostname is prototyped... yes
checking if gethostname is compilable... yes
checking for gethostname arg 2 data type... size_t
checking if gethostname usage allowed... yes
checking if gethostname might be used... yes
checking if getpeername can be linked... yes
checking if getpeername is prototyped... yes
checking if getpeername is compilable... yes
checking if getpeername usage allowed... yes
checking if getpeername might be used... yes
checking if getsockname can be linked... yes
checking if getsockname is prototyped... yes
checking if getsockname is compilable... yes
checking if getsockname usage allowed... yes
checking if getsockname might be used... yes
checking for net/if.h... (cached) yes
checking if if_nametoindex can be linked... yes
checking if if_nametoindex is prototyped... yes
checking if if_nametoindex is compilable... yes
checking if if_nametoindex usage allowed... yes
checking if if_nametoindex might be used... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for netinet/in.h... (cached) yes
checking for ifaddrs.h... yes
checking if getifaddrs can be linked... yes
checking if getifaddrs is prototyped... yes
checking if getifaddrs is compilable... yes
checking if getifaddrs seems to work... yes
checking if getifaddrs usage allowed... yes
checking if getifaddrs might be used... yes
checking for sys/types.h... (cached) yes
checking for sys/time.h... (cached) yes
checking if gmtime_r can be linked... yes
checking if gmtime_r is prototyped... yes
checking if gmtime_r is compilable... yes
checking if gmtime_r seems to work... yes
checking if gmtime_r usage allowed... yes
checking if gmtime_r might be used... yes
checking for sys/types.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for netinet/in.h... (cached) yes
checking for arpa/inet.h... (cached) yes
checking if inet_ntop can be linked... yes
checking if inet_ntop is prototyped... yes
checking if inet_ntop is compilable... yes
checking if inet_ntop seems to work... yes
checking if inet_ntop usage allowed... yes
checking if inet_ntop might be used... yes
checking if inet_pton can be linked... yes
checking if inet_pton is prototyped... yes
checking if inet_pton is compilable... yes
checking if inet_pton seems to work... yes
checking if inet_pton usage allowed... yes
checking if inet_pton might be used... yes
checking if ioctlsocket can be linked... no
checking if ioctlsocket might be used... no
checking if IoctlSocket can be linked... no
checking if IoctlSocket might be used... no
checking if memrchr can be linked... yes
checking if memrchr is prototyped... no
checking if memrchr might be used... no
checking if poll can be linked... yes
checking if poll is prototyped... yes
checking if poll is compilable... yes
checking if poll seems to work... yes
checking if poll usage allowed... yes
checking if poll might be used... yes
checking for sys/types.h... (cached) yes
checking for signal.h... yes
checking if sigaction can be linked... yes
checking if sigaction is prototyped... yes
checking if sigaction is compilable... yes
checking if sigaction usage allowed... yes
checking if sigaction might be used... yes
checking if siginterrupt can be linked... yes
checking if siginterrupt is prototyped... yes
checking if siginterrupt is compilable... yes
checking if siginterrupt usage allowed... yes
checking if siginterrupt might be used... yes
checking if signal can be linked... yes
checking if signal is prototyped... yes
checking if signal is compilable... yes
checking if signal usage allowed... yes
checking if signal might be used... yes
checking for sys/types.h... (cached) yes
checking for setjmp.h... (cached) yes
checking if sigsetjmp can be linked... no
checking if sigsetjmp seems a macro... yes
checking if sigsetjmp is compilable... yes
checking if sigsetjmp usage allowed... yes
checking if sigsetjmp might be used... yes
checking if socket can be linked... yes
checking if socket is prototyped... yes
checking if socket is compilable... yes
checking if socket usage allowed... yes
checking if socket might be used... yes
checking if socketpair can be linked... yes
checking if socketpair is prototyped... yes
checking if socketpair is compilable... yes
checking if socketpair usage allowed... yes
checking if socketpair might be used... yes
checking if strcasecmp can be linked... yes
checking if strcasecmp is prototyped... yes
checking if strcasecmp is compilable... yes
checking if strcasecmp usage allowed... yes
checking if strcasecmp might be used... yes
checking if strcmpi can be linked... no
checking if strcmpi might be used... no
checking if strdup can be linked... yes
checking if strdup is prototyped... yes
checking if strdup is compilable... yes
checking if strdup usage allowed... yes
checking if strdup might be used... yes
checking if strerror_r can be linked... yes
checking if strerror_r is prototyped... yes
checking if strerror_r is compilable... yes
checking if strerror_r is glibc like... no
checking if strerror_r is POSIX like... yes
checking if strerror_r seems to work... yes
checking if strerror_r usage allowed... yes
checking if strerror_r might be used... yes
checking if stricmp can be linked... no
checking if stricmp might be used... no
checking if strtok_r can be linked... yes
checking if strtok_r is prototyped... yes
checking if strtok_r is compilable... yes
checking if strtok_r usage allowed... yes
checking if strtok_r might be used... yes
checking if strtoll can be linked... yes
checking if strtoll is prototyped... yes
checking if strtoll is compilable... yes
checking if strtoll usage allowed... yes
checking if strtoll might be used... yes
checking for ccache gcc options needed to detect all undeclared functions... none needed
checking whether getpwuid_r is declared... yes
checking for fnmatch... yes
checking for fchmod... yes
checking for fork... yes
checking for geteuid... yes
checking for getpass_r... no
checking deeper for getpass_r... but still no
checking for getppid... yes
checking for getpwuid... yes
checking for getpwuid_r... yes
checking for getrlimit... yes
checking for gettimeofday... yes
checking for if_nametoindex... yes
checking for mach_absolute_time... no
checking deeper for mach_absolute_time... but still no
checking for pipe... yes
checking for sched_yield... yes
checking for sendmsg... yes
checking for setlocale... yes
checking for setmode... no
checking deeper for setmode... but still no
checking for setrlimit... yes
checking for snprintf... yes
checking for utime... yes
checking for utimes... yes
checking how to set a socket into non-blocking mode... fcntl O_NONBLOCK
checking for perl... /usr/bin/perl
checking for gnroff... no
checking for nroff... /usr/bin/nroff
checking how to use *nroff to get plain text from man pages... -man
checking whether to enable the threaded resolver... yes
checking whether to use POSIX threads for threaded resolver... auto
checking for pthread.h... yes
checking for pthread_create... yes
checking convert -I options to -isystem... yes
checking whether to enable verbose strings... yes
checking whether to enable SSPI support (Windows native builds only)... no
checking whether to enable cryptographic authentication methods... yes
checking whether to support NTLM... yes
checking whether to enable NTLM delegation to winbind's helper... no
checking whether to enable TLS-SRP authentication... yes
checking whether to enable Unix domain sockets... auto
checking for struct sockaddr_un.sun_path... yes
checking whether to support cookies... yes
checking whether to support socketpair... yes
checking whether to support HTTP authentication... yes
checking whether to support DoH... yes
checking whether to support the MIME API... yes
checking whether to support date parsing... yes
checking whether to support netrc parsing... yes
checking whether to support progress-meter... yes
checking whether to support DNS shuffling... yes
checking whether to support curl_easy_option*... yes
checking whether to support alt-svc... yes
checking whether to support headers-api... yes
configure: disables HSTS due to lack of SSL
checking whether to support WebSockets... no
checking whether hiding of library internal symbols will actually happen... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating docs/Makefile
config.status: creating docs/examples/Makefile
config.status: creating docs/libcurl/Makefile
config.status: creating docs/libcurl/opts/Makefile
config.status: creating docs/cmdline-opts/Makefile
config.status: creating include/Makefile
config.status: creating include/curl/Makefile
config.status: creating src/Makefile
config.status: creating lib/Makefile
config.status: creating scripts/Makefile
config.status: creating lib/libcurl.vers
config.status: creating lib/libcurl.plist
config.status: creating tests/Makefile
config.status: creating tests/certs/Makefile
config.status: creating tests/certs/scripts/Makefile
config.status: creating tests/data/Makefile
config.status: creating tests/server/Makefile
config.status: creating tests/libtest/Makefile
config.status: creating tests/unit/Makefile
config.status: creating packages/Makefile
config.status: creating packages/vms/Makefile
config.status: creating curl-config
config.status: creating libcurl.pc
config.status: creating lib/curl_config.h
config.status: executing depfiles commands
config.status: executing libtool commands
configure: amending lib/Makefile
configure: amending src/Makefile
configure: amending tests/unit/Makefile
configure: amending tests/server/Makefile
configure: amending tests/libtest/Makefile
configure: amending docs/examples/Makefile
configure: Configured to build curl/libcurl:
Host setup: x86_64-pc-linux-gnu
Install prefix: /usr/local
Compiler: ccache gcc
CFLAGS: -Werror-implicit-function-declaration -O2 -Wno-system-headers
CPPFLAGS:
LDFLAGS:
LIBS: -lpsl -lz
curl version: 7.87.0-DEV
SSL: no (--with-{openssl,gnutls,nss,mbedtls,wolfssl,schannel,secure-transport,amissl,bearssl,rustls} )
SSH: no (--with-{libssh,libssh2})
zlib: enabled
brotli: no (--with-brotli)
zstd: no (--with-zstd)
GSS-API: no (--with-gssapi)
GSASL: no (libgsasl not found)
TLS-SRP: no (--enable-tls-srp)
resolver: POSIX threaded
IPv6: enabled
Unix sockets: enabled
IDN: no (--with-{libidn2,winidn})
Build libcurl: Shared=no, Static=yes
Built-in manual: enabled
--libcurl option: enabled (--disable-libcurl-option)
Verbose errors: enabled (--disable-verbose)
Code coverage: disabled
SSPI: no (--enable-sspi)
ca cert bundle: no
ca cert path:
ca fallback:
LDAP: no (--enable-ldap / --with-ldap-lib / --with-lber-lib)
LDAPS: no (--enable-ldaps)
RTSP: enabled
RTMP: no (--with-librtmp)
PSL: enabled
Alt-svc: enabled (--disable-alt-svc)
Headers API: enabled (--disable-headers-api)
HSTS: no (--enable-hsts)
HTTP1: enabled (internal)
HTTP2: no (--with-nghttp2, --with-hyper)
HTTP3: no (--with-ngtcp2, --with-quiche --with-msh3)
ECH: no (--enable-ech)
WebSockets: no (--enable-websockets)
Protocols: DICT FILE FTP GOPHER HTTP IMAP MQTT POP3 RTSP SMTP TELNET TFTP
Features: AsynchDNS IPv6 Largefile PSL UnixSockets alt-svc libz threadsafe
configure: WARNING: unrecognized options: --disable-docs
configure: WARNING: Cannot find libraries for LDAP support: LDAP disabled
configure: WARNING: libgsasl was not found
configure: WARNING: Cannot find libraries for IDN support: IDN disabled
configure: WARNING: unrecognized options: --disable-docs
$ make -j3
Making all in lib
make[1]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/lib'
make all-am
make[2]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/lib'
CC libcurl_la-altsvc.lo
CC libcurl_la-amigaos.lo
CC libcurl_la-asyn-ares.lo
CC libcurl_la-base64.lo
CC libcurl_la-asyn-thread.lo
CC libcurl_la-bufref.lo
CC libcurl_la-c-hyper.lo
CC libcurl_la-cfilters.lo
CC libcurl_la-conncache.lo
CC libcurl_la-connect.lo
CC libcurl_la-content_encoding.lo
CC libcurl_la-cookie.lo
CC libcurl_la-curl_addrinfo.lo
CC libcurl_la-curl_des.lo
CC libcurl_la-curl_endian.lo
CC libcurl_la-curl_fnmatch.lo
CC libcurl_la-curl_get_line.lo
CC libcurl_la-curl_gethostname.lo
CC libcurl_la-curl_gssapi.lo
CC libcurl_la-curl_memrchr.lo
CC libcurl_la-curl_multibyte.lo
CC libcurl_la-curl_ntlm_core.lo
CC libcurl_la-curl_ntlm_wb.lo
CC libcurl_la-curl_path.lo
CC libcurl_la-curl_range.lo
CC libcurl_la-curl_rtmp.lo
CC libcurl_la-curl_sasl.lo
CC libcurl_la-curl_sspi.lo
CC libcurl_la-curl_threads.lo
CC libcurl_la-dict.lo
CC libcurl_la-doh.lo
CC libcurl_la-dynbuf.lo
CC libcurl_la-easy.lo
CC libcurl_la-easygetopt.lo
CC libcurl_la-easyoptions.lo
CC libcurl_la-escape.lo
CC libcurl_la-file.lo
CC libcurl_la-fileinfo.lo
CC libcurl_la-fopen.lo
CC libcurl_la-formdata.lo
CC libcurl_la-ftp.lo
CC libcurl_la-ftplistparser.lo
CC libcurl_la-getenv.lo
CC libcurl_la-getinfo.lo
CC libcurl_la-gopher.lo
CC libcurl_la-h2h3.lo
CC libcurl_la-hash.lo
CC libcurl_la-headers.lo
CC libcurl_la-hmac.lo
CC libcurl_la-hostasyn.lo
CC libcurl_la-hostip.lo
CC libcurl_la-hostip4.lo
CC libcurl_la-hostip6.lo
CC libcurl_la-hostsyn.lo
CC libcurl_la-hsts.lo
CC libcurl_la-http.lo
CC libcurl_la-http2.lo
CC libcurl_la-http_chunks.lo
CC libcurl_la-http_digest.lo
CC libcurl_la-http_negotiate.lo
CC libcurl_la-http_ntlm.lo
CC libcurl_la-http_proxy.lo
CC libcurl_la-http_aws_sigv4.lo
CC libcurl_la-idn_win32.lo
CC libcurl_la-if2ip.lo
CC libcurl_la-imap.lo
CC libcurl_la-inet_ntop.lo
CC libcurl_la-inet_pton.lo
CC libcurl_la-krb5.lo
CC libcurl_la-ldap.lo
CC libcurl_la-llist.lo
CC libcurl_la-md4.lo
CC libcurl_la-memdebug.lo
CC libcurl_la-md5.lo
CC libcurl_la-mime.lo
CC libcurl_la-mprintf.lo
CC libcurl_la-mqtt.lo
CC libcurl_la-multi.lo
CC libcurl_la-netrc.lo
CC libcurl_la-nonblock.lo
CC libcurl_la-noproxy.lo
CC libcurl_la-openldap.lo
CC libcurl_la-parsedate.lo
CC libcurl_la-pingpong.lo
CC libcurl_la-pop3.lo
CC libcurl_la-progress.lo
CC libcurl_la-psl.lo
CC libcurl_la-rand.lo
CC libcurl_la-rename.lo
CC libcurl_la-rtsp.lo
CC libcurl_la-select.lo
CC libcurl_la-sendf.lo
CC libcurl_la-setopt.lo
CC libcurl_la-sha256.lo
CC libcurl_la-share.lo
CC libcurl_la-slist.lo
CC libcurl_la-smb.lo
CC libcurl_la-smtp.lo
CC libcurl_la-socketpair.lo
CC libcurl_la-socks.lo
CC libcurl_la-socks_gssapi.lo
CC libcurl_la-socks_sspi.lo
CC libcurl_la-speedcheck.lo
CC libcurl_la-splay.lo
CC libcurl_la-strcase.lo
CC libcurl_la-strdup.lo
CC libcurl_la-strerror.lo
CC libcurl_la-strtok.lo
CC libcurl_la-strtoofft.lo
CC libcurl_la-system_win32.lo
CC libcurl_la-telnet.lo
CC libcurl_la-tftp.lo
CC libcurl_la-timediff.lo
CC libcurl_la-timeval.lo
CC libcurl_la-transfer.lo
CC libcurl_la-url.lo
CC libcurl_la-urlapi.lo
CC libcurl_la-version.lo
CC libcurl_la-version_win32.lo
CC libcurl_la-warnless.lo
CC libcurl_la-wildcard.lo
CC libcurl_la-ws.lo
CC vauth/libcurl_la-cleartext.lo
CC vauth/libcurl_la-cram.lo
CC vauth/libcurl_la-digest.lo
CC vauth/libcurl_la-digest_sspi.lo
CC vauth/libcurl_la-gsasl.lo
CC vauth/libcurl_la-krb5_gssapi.lo
CC vauth/libcurl_la-krb5_sspi.lo
CC vauth/libcurl_la-ntlm.lo
CC vauth/libcurl_la-ntlm_sspi.lo
CC vauth/libcurl_la-oauth2.lo
CC vauth/libcurl_la-spnego_gssapi.lo
CC vauth/libcurl_la-spnego_sspi.lo
CC vauth/libcurl_la-vauth.lo
CC vtls/libcurl_la-bearssl.lo
CC vtls/libcurl_la-gskit.lo
CC vtls/libcurl_la-gtls.lo
CC vtls/libcurl_la-hostcheck.lo
CC vtls/libcurl_la-keylog.lo
CC vtls/libcurl_la-mbedtls.lo
CC vtls/libcurl_la-mbedtls_threadlock.lo
CC vtls/libcurl_la-nss.lo
CC vtls/libcurl_la-openssl.lo
CC vtls/libcurl_la-rustls.lo
CC vtls/libcurl_la-schannel.lo
CC vtls/libcurl_la-schannel_verify.lo
CC vtls/libcurl_la-sectransp.lo
CC vtls/libcurl_la-vtls.lo
CC vtls/libcurl_la-wolfssl.lo
CC vtls/libcurl_la-x509asn1.lo
CC vquic/libcurl_la-msh3.lo
CC vquic/libcurl_la-ngtcp2.lo
CC vquic/libcurl_la-quiche.lo
CC vquic/libcurl_la-vquic.lo
CC vssh/libcurl_la-libssh.lo
CC vssh/libcurl_la-libssh2.lo
CC vssh/libcurl_la-wolfssh.lo
CCLD libcurl.la
make[2]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/lib'
make[1]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/lib'
Making all in src
make[1]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/src'
Making all in ../docs
make[2]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/docs'
Making all in .
make[3]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/docs'
if test "..x" != "..x" -a -e "./curl.1"; then \
/usr/bin/install -c -m 644 "./curl.1" /root/asi_db/builds/curl/_worktrees/w0/docs/curl.1; fi
cd cmdline-opts && make
make[4]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/docs/cmdline-opts'
generate ../../docs/curl.1
make[4]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/docs/cmdline-opts'
make[3]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/docs'
Making all in cmdline-opts
make[3]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/docs/cmdline-opts'
make[3]: Nothing to be done for 'all'.
make[3]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/docs/cmdline-opts'
make[2]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/docs'
make[2]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0/src'
CC slist_wc.o
CC tool_binmode.o
CC tool_bname.o
CC tool_cb_dbg.o
CC tool_cb_hdr.o
CC tool_cb_prg.o
CC tool_cb_see.o
CC tool_cb_rea.o
CC tool_cb_wrt.o
CC tool_dirhie.o
CC tool_cfgable.o
CC tool_doswin.o
CC tool_easysrc.o
CC tool_filetime.o
CC tool_findfile.o
CC tool_formparse.o
CC tool_getparam.o
CC tool_getpass.o
CC tool_help.o
CC tool_helpers.o
HUGE tool_hugehelp.c
CC tool_libinfo.o
CC tool_listhelp.o
CC tool_main.o
CC tool_msgs.o
CC tool_operate.o
CC tool_operhlp.o
CC tool_paramhlp.o
CC tool_parsecfg.o
CC tool_progress.o
CC tool_strdup.o
CC tool_setopt.o
CC tool_sleep.o
CC tool_urlglob.o
CC tool_util.o
CC tool_vms.o
CC tool_writeout.o
CC tool_writeout_json.o
CC tool_xattr.o
CC ../lib/strtoofft.o
CC ../lib/timediff.o
CC ../lib/nonblock.o
CC ../lib/warnless.o
CC ../lib/curl_multibyte.o
CC ../lib/version_win32.o
CC ../lib/dynbuf.o
CC tool_hugehelp.o
CCLD curl
make[2]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/src'
make[1]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0/src'
make[1]: Entering directory '/root/asi_db/builds/curl/_worktrees/w0'
make[1]: Nothing to be done for 'all-am'.
make[1]: Leaving directory '/root/asi_db/builds/curl/_worktrees/w0'
| @@ -1463,7 +1463,10 @@ _add_if("TLS-SRP" USE_TLS_SRP) | |
| _add_if("HTTP2" USE_NGHTTP2) | |
| _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)) |
| + | # TODO wolfSSL only support this from v5.0.0 onwards |
| + | _add_if("HTTPS-proxy" SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS OR USE_NSS |
| + | OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR |
| + | USE_MBEDTLS OR USE_SECTRANSP)) |
| _add_if("unicode" ENABLE_UNICODE) | |
| _add_if("threadsafe" HAVE_ATOMIC OR (WIN32 AND | |
| HAVE_WIN32_WINNT GREATER_EQUAL 0x600)) | |
| @@ -4387,8 +4387,17 @@ fi | |
| dnl if not explicitly turned off, HTTPS-proxy comes with some TLS backends | |
| if test "x$https_proxy" != "xno"; then | |
| - | if test "x$OPENSSL_ENABLED" = "x1" -o "x$GNUTLS_ENABLED" = "x1" \ |
| - | -o "x$NSS_ENABLED" = "x1"; then |
| + | if test "x$OPENSSL_ENABLED" = "x1" \ |
| + | -o "x$GNUTLS_ENABLED" = "x1" \ |
| + | -o "x$NSS_ENABLED" = "x1" \ |
| + | -o "x$SECURETRANSPORT_ENABLED" = "x1" \ |
| + | -o "x$RUSTLS_ENABLED" = "x1" \ |
| + | -o "x$BEARSSL_ENABLED" = "x1" \ |
| + | -o "x$SCHANNEL_ENABLED" = "x1" \ |
| + | -o "x$GNUTLS_ENABLED" = "x1" \ |
| + | -o "x$MBEDTLS_ENABLED" = "x1"; then |
| + | SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy" |
| + | elif test "x$WOLFSSL_ENABLED" = "x1" -a "x$WOLFSSL_FULL_BIO" = "x1"; then |
| SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy" | |
| fi | |
| fi | |
| @@ -134,7 +134,6 @@ void Curl_conn_cf_discard_all(struct Curl_easy *data, | |
| struct Curl_cfilter *cfn, *cf = conn->cfilter[index]; | |
| if(cf) { | |
| - | DEBUGF(infof(data, CMSGI(conn, index, "Curl_conn_cf_discard_all()"))); |
| conn->cfilter[index] = NULL; | |
| while(cf) { | |
| cfn = cf->next; | |
| @@ -153,7 +152,6 @@ void Curl_conn_close(struct Curl_easy *data, int index) | |
| /* it is valid to call that without filters being present */ | |
| cf = data->conn->cfilter[index]; | |
| if(cf) { | |
| - | DEBUGF(infof(data, DMSGI(data, index, "close()"))); |
| cf->cft->close(cf, data); | |
| } | |
| } | |
| @@ -261,6 +259,18 @@ void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| free(cf); | |
| } | |
| + | ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, |
| + | const void *buf, size_t len, CURLcode *err) |
| + | { |
| + | return cf->cft->do_send(cf, data, buf, len, err); |
| + | } |
| + | |
| + | ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data, |
| + | char *buf, size_t len, CURLcode *err) |
| + | { |
| + | return cf->cft->do_recv(cf, data, buf, len, err); |
| + | } |
| + | |
| CURLcode Curl_conn_setup(struct Curl_easy *data, | |
| struct connectdata *conn, | |
| int sockindex, | |
| @@ -384,6 +394,21 @@ bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex) | |
| return FALSE; | |
| } | |
| + | bool Curl_conn_is_ssl(struct Curl_easy *data, int sockindex) |
| + | { |
| + | struct Curl_cfilter *cf = data->conn? data->conn->cfilter[sockindex] : NULL; |
| + | |
| + | (void)data; |
| + | for(; cf; cf = cf->next) { |
| + | if(cf->cft->flags & CF_TYPE_SSL) |
| + | return TRUE; |
| + | if(cf->cft->flags & CF_TYPE_IP_CONNECT) |
| + | return FALSE; |
| + | } |
| + | return FALSE; |
| + | } |
| + | |
| + | |
| bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex) | |
| { | |
| struct Curl_cfilter *cf; | |
| @@ -427,7 +452,6 @@ void Curl_conn_attach_data(struct connectdata *conn, | |
| for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) { | |
| cf = conn->cfilter[i]; | |
| if(cf) { | |
| - | DEBUGF(infof(data, DMSGI(data, i, "attach_data()"))); |
| while(cf) { | |
| cf->cft->attach_data(cf, data); | |
| cf = cf->next; | |
| @@ -445,7 +469,6 @@ void Curl_conn_detach_data(struct connectdata *conn, | |
| for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) { | |
| cf = conn->cfilter[i]; | |
| if(cf) { | |
| - | DEBUGF(infof(data, DMSGI(data, i, "detach_data()"))); |
| while(cf) { | |
| cf->cft->detach_data(cf, data); | |
| cf = cf->next; | |
| @@ -33,20 +33,20 @@ struct connectdata; | |
| /* Callback to destroy resources held by this filter instance. | |
| * Implementations MUST NOT chain calls to cf->next. | |
| */ | |
| - | typedef void Curl_cf_destroy_this(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data); |
| + | typedef void Curl_cft_destroy_this(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data); |
| /* Setup the connection for `data`, using destination `remotehost`. | |
| */ | |
| - | typedef CURLcode Curl_cf_setup(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data, |
| - | const struct Curl_dns_entry *remotehost); |
| - | typedef void Curl_cf_close(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data); |
| + | typedef CURLcode Curl_cft_setup(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data, |
| + | const struct Curl_dns_entry *remotehost); |
| + | typedef void Curl_cft_close(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data); |
| - | typedef CURLcode Curl_cf_connect(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data, |
| - | bool blocking, bool *done); |
| + | typedef CURLcode Curl_cft_connect(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data, |
| + | bool blocking, bool *done); |
| /* Return the hostname and port the connection goes to. | |
| * This may change with the connection state of filters when tunneling | |
| @@ -59,40 +59,40 @@ typedef CURLcode Curl_cf_connect(struct Curl_cfilter *cf, | |
| * this is owned by the connection. | |
| * @param pport on return, contains the port number | |
| */ | |
| - | typedef void Curl_cf_get_host(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data, |
| - | const char **phost, |
| - | const char **pdisplay_host, |
| - | int *pport); |
| + | typedef void Curl_cft_get_host(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data, |
| + | const char **phost, |
| + | const char **pdisplay_host, |
| + | int *pport); |
| /* Filters may return sockets and fdset flags they are waiting for. | |
| * The passes array has room for up to MAX_SOCKSPEREASYHANDLE sockets. | |
| * @return read/write fdset for index in socks | |
| * or GETSOCK_BLANK when nothing to wait on | |
| */ | |
| - | typedef int Curl_cf_get_select_socks(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data, |
| - | curl_socket_t *socks); |
| - | |
| - | typedef bool Curl_cf_data_pending(struct Curl_cfilter *cf, |
| - | const struct Curl_easy *data); |
| - | |
| - | typedef ssize_t Curl_cf_send(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data, /* transfer */ |
| - | const void *buf, /* data to write */ |
| - | size_t len, /* max amount to write */ |
| - | CURLcode *err); /* error to return */ |
| - | |
| - | typedef ssize_t Curl_cf_recv(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data, /* transfer */ |
| - | char *buf, /* store data here */ |
| - | size_t len, /* max amount to read */ |
| - | CURLcode *err); /* error to return */ |
| - | |
| - | typedef void Curl_cf_attach_data(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data); |
| - | typedef void Curl_cf_detach_data(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data); |
| + | typedef int Curl_cft_get_select_socks(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data, |
| + | curl_socket_t *socks); |
| + | |
| + | typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf, |
| + | const struct Curl_easy *data); |
| + | |
| + | typedef ssize_t Curl_cft_send(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data, /* transfer */ |
| + | const void *buf, /* data to write */ |
| + | size_t len, /* amount to write */ |
| + | CURLcode *err); /* error to return */ |
| + | |
| + | typedef ssize_t Curl_cft_recv(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data, /* transfer */ |
| + | char *buf, /* store data here */ |
| + | size_t len, /* amount to read */ |
| + | CURLcode *err); /* error to return */ |
| + | |
| + | typedef void Curl_cft_attach_data(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data); |
| + | typedef void Curl_cft_detach_data(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data); |
| /** | |
| * The easy handle `data` is being detached (no longer served) | |
| @@ -108,19 +108,19 @@ void Curl_conn_detach(struct connectdata *conn, struct Curl_easy *data); | |
| /* A connection filter type, e.g. specific implementation. */ | |
| struct Curl_cftype { | |
| - | const char *name; /* name of the filter type */ |
| - | long flags; /* flags of filter type */ |
| - | Curl_cf_destroy_this *destroy; /* destroy resources of this cf */ |
| - | Curl_cf_setup *setup; /* setup for a connection */ |
| - | Curl_cf_connect *connect; /* establish connection */ |
| - | Curl_cf_close *close; /* close conn */ |
| - | Curl_cf_get_host *get_host; /* host filter talks to */ |
| - | Curl_cf_get_select_socks *get_select_socks;/* sockets to select on */ |
| - | Curl_cf_data_pending *has_data_pending;/* conn has data pending */ |
| - | Curl_cf_send *do_send; /* send data */ |
| - | Curl_cf_recv *do_recv; /* receive data */ |
| - | Curl_cf_attach_data *attach_data; /* data is being handled here */ |
| - | Curl_cf_detach_data *detach_data; /* data is no longer handled here */ |
| + | const char *name; /* name of the filter type */ |
| + | long flags; /* flags of filter type */ |
| + | Curl_cft_destroy_this *destroy; /* destroy resources of this cf */ |
| + | Curl_cft_setup *setup; /* setup for a connection */ |
| + | Curl_cft_connect *connect; /* establish connection */ |
| + | Curl_cft_close *close; /* close conn */ |
| + | Curl_cft_get_host *get_host; /* host filter talks to */ |
| + | Curl_cft_get_select_socks *get_select_socks;/* sockets to select on */ |
| + | Curl_cft_data_pending *has_data_pending;/* conn has data pending */ |
| + | Curl_cft_send *do_send; /* send data */ |
| + | Curl_cft_recv *do_recv; /* receive data */ |
| + | Curl_cft_attach_data *attach_data; /* data is being handled here */ |
| + | Curl_cft_detach_data *detach_data; /* data is no longer handled here */ |
| }; | |
| /* A connection filter instance, e.g. registered at a connection */ | |
| @@ -198,6 +198,12 @@ void Curl_conn_cf_discard_all(struct Curl_easy *data, | |
| */ | |
| void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data); | |
| + | |
| + | ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, |
| + | const void *buf, size_t len, CURLcode *err); |
| + | ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data, |
| + | char *buf, size_t len, CURLcode *err); |
| + | |
| #define CURL_CF_SSL_DEFAULT -1 | |
| #define CURL_CF_SSL_DISABLE 0 | |
| #define CURL_CF_SSL_ENABLE 1 | |
| @@ -237,6 +243,13 @@ bool Curl_conn_is_connected(struct connectdata *conn, int sockindex); | |
| */ | |
| bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex); | |
| + | /** |
| + | * Determine if the connection is using SSL to the remote host |
| + | * (or will be once connected). This will return FALSE, if SSL |
| + | * is only used in proxying and not for the tunnel itself. |
| + | */ |
| + | bool Curl_conn_is_ssl(struct Curl_easy *data, int sockindex); |
| + | |
| /** | |
| * Close the filter chain at `sockindex` for connection `data->conn`. | |
| * Filters remain in place and may be connected again afterwards. | |
| @@ -1690,8 +1690,6 @@ static CURLcode socket_cf_connect(struct Curl_cfilter *cf, | |
| result = Curl_connecthost(data, conn, ctx->remotehost); | |
| if(!result) | |
| ctx->state = SCFST_WAITING; | |
| - | DEBUGF(infof(data, CFMSG(cf, "connect(INIT) -> %d, done=%d"), |
| - | result, *done)); |
| break; | |
| case SCFST_WAITING: | |
| result = is_connected(data, conn, sockindex, done); | |
| @@ -1704,13 +1702,9 @@ static CURLcode socket_cf_connect(struct Curl_cfilter *cf, | |
| ctx->state = SCFST_DONE; | |
| cf->connected = TRUE; | |
| } | |
| - | DEBUGF(infof(data, CFMSG(cf, "connect(WAIT) -> %d, done=%d"), |
| - | result, *done)); |
| break; | |
| case SCFST_DONE: | |
| *done = TRUE; | |
| - | DEBUGF(infof(data, CFMSG(cf, "connect(DONE) -> %d, done=%d"), |
| - | result, *done)); |
| break; | |
| } | |
| return result; | |
| @@ -1783,8 +1777,6 @@ static ssize_t socket_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| { | |
| ssize_t nwritten; | |
| nwritten = Curl_send_plain(data, cf->sockindex, buf, len, err); | |
| - | DEBUGF(infof(data, CFMSG(cf, "send(len=%ld) -> %ld, err=%d"), |
| - | len, nwritten, *err)); |
| return nwritten; | |
| } | |
| @@ -1793,7 +1785,6 @@ static ssize_t socket_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| { | |
| ssize_t nread; | |
| nread = Curl_recv_plain(data, cf->sockindex, buf, len, err); | |
| - | DEBUGF(infof(data, CFMSG(cf, "recv() -> %ld"), nread)); |
| return nread; | |
| } | |
| @@ -1802,7 +1793,6 @@ static void socket_cf_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| struct socket_cf_ctx *state = cf->ctx; | |
| (void)data; | |
| - | DEBUGF(infof(data, CFMSG(cf, "destroy()"))); |
| if(cf->connected) { | |
| socket_cf_close(cf, data); | |
| } | |
| @@ -2742,7 +2742,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, | |
| if((ftpcode == 234) || (ftpcode == 334)) { | |
| /* this was BLOCKING, keep it so for now */ | |
| bool done; | |
| - | if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) { |
| + | if(!Curl_conn_is_ssl(data, FIRSTSOCKET)) { |
| result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); | |
| if(result) { | |
| /* we failed and bail out */ | |
| @@ -172,8 +172,6 @@ static void tunnel_go_state(struct Curl_cfilter *cf, | |
| { | |
| if(ts->tunnel_state == new_state) | |
| return; | |
| - | DEBUGF(infof(data, CFMSG(cf, "tunnel %p go_state %d -> %d"), |
| - | ts, ts->tunnel_state, new_state)); |
| /* leaving this one */ | |
| switch(ts->tunnel_state) { | |
| case TUNNEL_CONNECT: | |
| @@ -488,7 +486,6 @@ static CURLcode recv_CONNECT_resp(struct Curl_easy *data, | |
| #define SELECT_OK 0 | |
| #define SELECT_ERROR 1 | |
| - | DEBUGF(infof(data, "CONNECT: recv response, keepon=%d", ts->keepon)); |
| error = SELECT_OK; | |
| *done = FALSE; | |
| @@ -642,7 +639,6 @@ static CURLcode recv_CONNECT_resp(struct Curl_easy *data, | |
| } | |
| } | |
| else { | |
| - | DEBUGF(infof(data, "CONNECT: no end of response headers")); |
| ts->keepon = KEEPON_DONE; | |
| } | |
| @@ -1085,8 +1081,6 @@ static CURLcode http_proxy_cf_connect(struct Curl_cfilter *cf, | |
| cf->ctx = ts; | |
| } | |
| - | DEBUGF(infof(data, CFMSG(cf, "connect(%s:%d, state=%d)"), |
| - | ts->hostname, ts->remote_port, ts->tunnel_state)); |
| result = CONNECT(cf, data, ts); | |
| if(result) | |
| goto out; | |
| @@ -1098,8 +1092,6 @@ out: | |
| cf->connected = TRUE; | |
| tunnel_free(cf, data); | |
| } | |
| - | DEBUGF(infof(data, CFMSG(cf, "connect(block=%d) -> %d, done=%d"), |
| - | blocking, result, *done)); |
| return result; | |
| } | |
| @@ -476,7 +476,7 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data, | |
| struct imap_conn *imapc = &conn->proto.imapc; | |
| CURLcode result; | |
| - | if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) { |
| + | if(!Curl_conn_is_ssl(data, FIRSTSOCKET)) { |
| result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); | |
| if(result) | |
| goto out; | |
| @@ -371,7 +371,7 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data, | |
| struct pop3_conn *pop3c = &conn->proto.pop3c; | |
| CURLcode result; | |
| - | if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) { |
| + | if(!Curl_conn_is_ssl(data, FIRSTSOCKET)) { |
| result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); | |
| if(result) | |
| goto out; | |
| @@ -398,7 +398,7 @@ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data) | |
| struct smtp_conn *smtpc = &conn->proto.smtpc; | |
| CURLcode result; | |
| - | if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) { |
| + | if(!Curl_conn_is_ssl(data, FIRSTSOCKET)) { |
| result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); | |
| if(result) | |
| goto out; | |
| @@ -764,11 +764,11 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf, | |
| { | |
| struct ssl_connect_data *connssl = cf->ctx; | |
| struct ssl_backend_data *backend = connssl->backend; | |
| - | curl_socket_t sockfd = cf->conn->sock[cf->sockindex]; |
| unsigned state; | |
| unsigned char *buf; | |
| size_t len; | |
| ssize_t ret; | |
| + | CURLcode result; |
| int err; | |
| DEBUGASSERT(backend); | |
| @@ -807,31 +807,21 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf, | |
| return CURLE_OK; | |
| if(state & BR_SSL_SENDREC) { | |
| buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len); | |
| - | ret = swrite(sockfd, buf, len); |
| - | if(ret == -1) { |
| - | if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { |
| - | if(connssl->state != ssl_connection_complete) |
| - | connssl->connecting_state = ssl_connect_2_writing; |
| - | return CURLE_AGAIN; |
| - | } |
| - | return CURLE_WRITE_ERROR; |
| + | ret = Curl_conn_cf_send(cf->next, data, (char *)buf, len, &result); |
| + | if(ret <= 0) { |
| + | return result; |
| } | |
| br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret); | |
| } | |
| else if(state & BR_SSL_RECVREC) { | |
| buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len); | |
| - | ret = sread(sockfd, buf, len); |
| + | ret = Curl_conn_cf_recv(cf->next, data, (char *)buf, len, &result); |
| if(ret == 0) { | |
| failf(data, "SSL: EOF without close notify"); | |
| return CURLE_READ_ERROR; | |
| } | |
| - | if(ret == -1) { |
| - | if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { |
| - | if(connssl->state != ssl_connection_complete) |
| - | connssl->connecting_state = ssl_connect_2_reading; |
| - | return CURLE_AGAIN; |
| - | } |
| - | return CURLE_READ_ERROR; |
| + | if(ret <= 0) { |
| + | return result; |
| } | |
| br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret); | |
| } | |
| @@ -1183,7 +1173,7 @@ static CURLcode bearssl_sha256sum(const unsigned char *input, | |
| const struct Curl_ssl Curl_ssl_bearssl = { | |
| { CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */ | |
| - | SSLSUPP_CAINFO_BLOB | SSLSUPP_SSL_CTX, |
| + | SSLSUPP_CAINFO_BLOB | SSLSUPP_SSL_CTX | SSLSUPP_HTTPS_PROXY, |
| sizeof(struct ssl_backend_data), | |
| Curl_none_init, /* init */ | |
| @@ -92,28 +92,40 @@ struct ssl_backend_data { | |
| #endif | |
| }; | |
| - | static ssize_t gtls_push(void *s, const void *buf, size_t len) |
| + | static ssize_t gtls_push(void *s, const void *buf, size_t blen) |
| { | |
| - | curl_socket_t sock = *(curl_socket_t *)s; |
| - | ssize_t ret = swrite(sock, buf, len); |
| - | return ret; |
| - | } |
| + | struct Curl_cfilter *cf = s; |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nwritten; |
| + | CURLcode result; |
| - | static ssize_t gtls_pull(void *s, void *buf, size_t len) |
| - | { |
| - | curl_socket_t sock = *(curl_socket_t *)s; |
| - | ssize_t ret = sread(sock, buf, len); |
| - | return ret; |
| + | DEBUGASSERT(data); |
| + | nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result); |
| + | if(nwritten < 0) { |
| + | gnutls_transport_set_errno(connssl->backend->session, |
| + | (CURLE_AGAIN == result)? EAGAIN : EINVAL); |
| + | nwritten = -1; |
| + | } |
| + | return nwritten; |
| } | |
| - | static ssize_t gtls_push_ssl(void *s, const void *buf, size_t len) |
| + | static ssize_t gtls_pull(void *s, void *buf, size_t blen) |
| { | |
| - | return gnutls_record_send((gnutls_session_t) s, buf, len); |
| - | } |
| + | struct Curl_cfilter *cf = s; |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nread; |
| + | CURLcode result; |
| - | static ssize_t gtls_pull_ssl(void *s, void *buf, size_t len) |
| - | { |
| - | return gnutls_record_recv((gnutls_session_t) s, buf, len); |
| + | DEBUGASSERT(data); |
| + | nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result); |
| + | if(nread < 0) { |
| + | gnutls_transport_set_errno(connssl->backend->session, |
| + | (CURLE_AGAIN == result)? EAGAIN : EINVAL); |
| + | nread = -1; |
| + | } |
| + | return nread; |
| } | |
| /* gtls_init() | |
| @@ -419,9 +431,6 @@ gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| const char *hostname = connssl->hostname; | |
| long * const certverifyresult = &ssl_config->certverifyresult; | |
| const char *tls13support; | |
| - | struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next); |
| - | struct ssl_connect_data *connssl_next = cf_ssl_next? |
| - | cf_ssl_next->ctx : NULL; |
| CURLcode result; | |
| DEBUGASSERT(backend); | |
| @@ -720,18 +729,10 @@ gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| } | |
| } | |
| - | if(connssl_next) { |
| - | DEBUGASSERT(connssl_next->backend); |
| - | transport_ptr = connssl_next->backend; |
| - | gnutls_transport_push = gtls_push_ssl; |
| - | gnutls_transport_pull = gtls_pull_ssl; |
| - | } |
| - | else { |
| - | /* file descriptor for the socket */ |
| - | transport_ptr = &cf->conn->sock[cf->sockindex]; |
| - | gnutls_transport_push = gtls_push; |
| - | gnutls_transport_pull = gtls_pull; |
| - | } |
| + | /* push/pull through filter chain */ |
| + | transport_ptr = cf; |
| + | gnutls_transport_push = gtls_push; |
| + | gnutls_transport_pull = gtls_pull; |
| /* set the connection handle */ | |
| gnutls_transport_set_ptr(session, transport_ptr); | |
| @@ -1352,20 +1353,25 @@ gtls_connect_common(struct Curl_cfilter *cf, | |
| bool nonblocking, | |
| bool *done) | |
| { | |
| - | int rc; |
| struct ssl_connect_data *connssl = cf->ctx; | |
| + | int rc; |
| + | CURLcode result = CURLE_OK; |
| /* Initiate the connection, if not already done */ | |
| if(ssl_connect_1 == connssl->connecting_state) { | |
| rc = gtls_connect_step1(cf, data); | |
| - | if(rc) |
| - | return rc; |
| + | if(rc) { |
| + | result = rc; |
| + | goto out; |
| + | } |
| } | |
| rc = handshake(cf, data, TRUE, nonblocking); | |
| - | if(rc) |
| + | if(rc) { |
| /* handshake() sets its own error message with failf() */ | |
| - | return rc; |
| + | result = rc; |
| + | goto out; |
| + | } |
| /* Finish connecting once the handshake is done */ | |
| if(ssl_connect_1 == connssl->connecting_state) { | |
| @@ -1374,13 +1380,16 @@ gtls_connect_common(struct Curl_cfilter *cf, | |
| DEBUGASSERT(backend); | |
| session = backend->session; | |
| rc = Curl_gtls_verifyserver(cf, data, session); | |
| - | if(rc) |
| - | return rc; |
| + | if(rc) { |
| + | result = rc; |
| + | goto out; |
| + | } |
| } | |
| + | out: |
| *done = ssl_connect_1 == connssl->connecting_state; | |
| - | return CURLE_OK; |
| + | return result; |
| } | |
| static CURLcode gtls_connect_nonblocking(struct Curl_cfilter *cf, | |
| @@ -1570,7 +1579,8 @@ static ssize_t gtls_recv(struct Curl_cfilter *cf, | |
| ret = gnutls_record_recv(backend->session, buf, buffersize); | |
| if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) { | |
| *curlcode = CURLE_AGAIN; | |
| - | return -1; |
| + | ret = -1; |
| + | goto out; |
| } | |
| if(ret == GNUTLS_E_REHANDSHAKE) { | |
| @@ -1582,7 +1592,8 @@ static ssize_t gtls_recv(struct Curl_cfilter *cf, | |
| *curlcode = result; | |
| else | |
| *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */ | |
| - | return -1; |
| + | ret = -1; |
| + | goto out; |
| } | |
| if(ret < 0) { | |
| @@ -1590,9 +1601,11 @@ static ssize_t gtls_recv(struct Curl_cfilter *cf, | |
| (int)ret, gnutls_strerror((int)ret)); | |
| *curlcode = CURLE_RECV_ERROR; | |
| - | return -1; |
| + | ret = -1; |
| + | goto out; |
| } | |
| + | out: |
| return ret; | |
| } | |
| @@ -156,6 +156,46 @@ static void mbed_debug(void *context, int level, const char *f_name, | |
| #else | |
| #endif | |
| + | static int bio_cf_write(void *bio, const unsigned char *buf, size_t blen) |
| + | { |
| + | struct Curl_cfilter *cf = bio; |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nwritten; |
| + | CURLcode result; |
| + | |
| + | DEBUGASSERT(data); |
| + | nwritten = Curl_conn_cf_send(cf->next, data, (char *)buf, blen, &result); |
| + | /* DEBUGF(infof(data, CFMSG(cf, "bio_cf_out_write(len=%d) -> %d, err=%d"), |
| + | blen, (int)nwritten, result)); */ |
| + | if(nwritten < 0 && CURLE_AGAIN == result) { |
| + | nwritten = MBEDTLS_ERR_SSL_WANT_WRITE; |
| + | } |
| + | return (int)nwritten; |
| + | } |
| + | |
| + | static int bio_cf_read(void *bio, unsigned char *buf, size_t blen) |
| + | { |
| + | struct Curl_cfilter *cf = bio; |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nread; |
| + | CURLcode result; |
| + | |
| + | DEBUGASSERT(data); |
| + | /* OpenSSL catches this case, so should we. */ |
| + | if(!buf) |
| + | return 0; |
| + | |
| + | nread = Curl_conn_cf_recv(cf->next, data, (char *)buf, blen, &result); |
| + | /* DEBUGF(infof(data, CFMSG(cf, "bio_cf_in_read(len=%d) -> %d, err=%d"), |
| + | blen, (int)nread, result)); */ |
| + | if(nread < 0 && CURLE_AGAIN == result) { |
| + | nread = MBEDTLS_ERR_SSL_WANT_READ; |
| + | } |
| + | return (int)nread; |
| + | } |
| + | |
| /* | |
| * profile | |
| */ | |
| @@ -551,9 +591,7 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random, | |
| &backend->ctr_drbg); | |
| - | mbedtls_ssl_set_bio(&backend->ssl, &cf->conn->sock[cf->sockindex], |
| - | mbedtls_net_send, |
| - | mbedtls_net_recv, |
| + | mbedtls_ssl_set_bio(&backend->ssl, cf, bio_cf_write, bio_cf_read, |
| NULL /* rev_timeout() */); | |
| mbedtls_ssl_conf_ciphersuites(&backend->config, | |
| @@ -902,7 +940,6 @@ static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| (void)data; | |
| DEBUGASSERT(backend); | |
| - | |
| ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len); | |
| if(ret < 0) { | |
| @@ -924,8 +961,8 @@ static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| struct ssl_connect_data *connssl = cf->ctx; | |
| struct ssl_backend_data *backend = connssl->backend; | |
| char buf[32]; | |
| - | (void) data; |
| + | (void)data; |
| DEBUGASSERT(backend); | |
| /* Maybe the server has already sent a close notify alert. | |
| @@ -1229,7 +1266,8 @@ const struct Curl_ssl Curl_ssl_mbedtls = { | |
| SSLSUPP_CA_PATH | | |
| SSLSUPP_CAINFO_BLOB | | |
| SSLSUPP_PINNEDPUBKEY | | |
| - | SSLSUPP_SSL_CTX, |
| + | SSLSUPP_SSL_CTX | |
| + | SSLSUPP_HTTPS_PROXY, |
| sizeof(struct ssl_backend_data), | |
| @@ -635,6 +635,166 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) | |
| #ifdef USE_OPENSSL | |
| + | #if USE_PRE_1_1_API |
| + | #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x2070000fL |
| + | #define BIO_set_init(x,v) ((x)->init=(v)) |
| + | #define BIO_get_data(x) ((x)->ptr) |
| + | #define BIO_set_data(x,v) ((x)->ptr=(v)) |
| + | #endif |
| + | #define BIO_get_shutdown(x) ((x)->shutdown) |
| + | #define BIO_set_shutdown(x,v) ((x)->shutdown=(v)) |
| + | #endif /* USE_PRE_1_1_API */ |
| + | |
| + | static int bio_cf_create(BIO *bio) |
| + | { |
| + | BIO_set_shutdown(bio, 1); |
| + | BIO_set_init(bio, 1); |
| + | #if USE_PRE_1_1_API |
| + | bio->num = -1; |
| + | #endif |
| + | BIO_set_data(bio, NULL); |
| + | return 1; |
| + | } |
| + | |
| + | static int bio_cf_destroy(BIO *bio) |
| + | { |
| + | if(!bio) |
| + | return 0; |
| + | return 1; |
| + | } |
| + | |
| + | static long bio_cf_ctrl(BIO *bio, int cmd, long num, void *ptr) |
| + | { |
| + | struct Curl_cfilter *cf = BIO_get_data(bio); |
| + | long ret = 1; |
| + | |
| + | (void)cf; |
| + | (void)ptr; |
| + | switch(cmd) { |
| + | case BIO_CTRL_GET_CLOSE: |
| + | ret = (long)BIO_get_shutdown(bio); |
| + | break; |
| + | case BIO_CTRL_SET_CLOSE: |
| + | BIO_set_shutdown(bio, (int)num); |
| + | break; |
| + | case BIO_CTRL_FLUSH: |
| + | /* we do no delayed writes, but if we ever would, this |
| + | * needs to trigger it. */ |
| + | ret = 1; |
| + | break; |
| + | case BIO_CTRL_DUP: |
| + | ret = 1; |
| + | break; |
| + | #ifdef BIO_CTRL_EOF |
| + | case BIO_CTRL_EOF: |
| + | /* EOF has been reached on input? */ |
| + | return (!cf->next || !cf->next->connected); |
| + | #endif |
| + | default: |
| + | ret = 0; |
| + | break; |
| + | } |
| + | return ret; |
| + | } |
| + | |
| + | static int bio_cf_out_write(BIO *bio, const char *buf, int blen) |
| + | { |
| + | struct Curl_cfilter *cf = BIO_get_data(bio); |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nwritten; |
| + | CURLcode result = CURLE_SEND_ERROR; |
| + | |
| + | DEBUGASSERT(data); |
| + | nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result); |
| + | /* DEBUGF(infof(data, CFMSG(cf, "bio_cf_out_write(len=%d) -> %d, err=%d"), |
| + | blen, (int)nwritten, result)); */ |
| + | BIO_clear_retry_flags(bio); |
| + | if(nwritten < 0) { |
| + | if(CURLE_AGAIN == result) { |
| + | BIO_set_retry_write(bio); |
| + | nwritten = 0; |
| + | } |
| + | else { |
| + | nwritten = -1; |
| + | } |
| + | } |
| + | return (int)nwritten; |
| + | } |
| + | |
| + | static int bio_cf_in_read(BIO *bio, char *buf, int blen) |
| + | { |
| + | struct Curl_cfilter *cf = BIO_get_data(bio); |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nread; |
| + | CURLcode result = CURLE_RECV_ERROR; |
| + | |
| + | DEBUGASSERT(data); |
| + | /* OpenSSL catches this case, so should we. */ |
| + | if(!buf) |
| + | return 0; |
| + | |
| + | nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result); |
| + | /* DEBUGF(infof(data, CFMSG(cf, "bio_cf_in_read(len=%d) -> %d, err=%d"), |
| + | blen, (int)nread, result)); */ |
| + | BIO_clear_retry_flags(bio); |
| + | if(nread < 0) { |
| + | if(CURLE_AGAIN == result) { |
| + | BIO_set_retry_read(bio); |
| + | nread = 0; |
| + | } |
| + | else { |
| + | nread = -1; |
| + | } |
| + | } |
| + | return (int)nread; |
| + | } |
| + | |
| + | static BIO_METHOD *bio_cf_method = NULL; |
| + | |
| + | #if USE_PRE_1_1_API |
| + | |
| + | static BIO_METHOD bio_cf_meth_1_0 = { |
| + | BIO_TYPE_MEM, |
| + | "OpenSSL CF BIO", |
| + | bio_cf_out_write, |
| + | bio_cf_in_read, |
| + | NULL, /* puts is never called */ |
| + | NULL, /* gets is never called */ |
| + | bio_cf_ctrl, |
| + | bio_cf_create, |
| + | bio_cf_destroy, |
| + | NULL |
| + | }; |
| + | |
| + | static void bio_cf_init_methods(void) |
| + | { |
| + | bio_cf_method = &bio_cf_meth_1_0; |
| + | } |
| + | |
| + | #define bio_cf_free_methods() Curl_nop_stmt |
| + | |
| + | #else |
| + | |
| + | static void bio_cf_init_methods(void) |
| + | { |
| + | bio_cf_method = BIO_meth_new(BIO_TYPE_MEM, "OpenSSL CF BIO"); |
| + | BIO_meth_set_write(bio_cf_method, &bio_cf_out_write); |
| + | BIO_meth_set_read(bio_cf_method, &bio_cf_in_read); |
| + | BIO_meth_set_ctrl(bio_cf_method, &bio_cf_ctrl); |
| + | BIO_meth_set_create(bio_cf_method, &bio_cf_create); |
| + | BIO_meth_set_destroy(bio_cf_method, &bio_cf_destroy); |
| + | } |
| + | |
| + | static void bio_cf_free_methods(void) |
| + | { |
| + | BIO_meth_free(bio_cf_method); |
| + | } |
| + | |
| + | #endif |
| + | |
| + | |
| static bool ossl_attach_data(struct Curl_cfilter *cf, | |
| struct Curl_easy *data); | |
| @@ -1602,6 +1762,7 @@ static int ossl_init(void) | |
| OpenSSL_add_all_algorithms(); | |
| #endif | |
| + | bio_cf_init_methods(); |
| Curl_tls_keylog_open(); | |
| /* Initialize the extra data indexes */ | |
| @@ -1647,6 +1808,7 @@ static void ossl_cleanup(void) | |
| #endif | |
| Curl_tls_keylog_close(); | |
| + | bio_cf_free_methods(); |
| } | |
| /* | |
| @@ -1803,21 +1965,17 @@ static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| DEBUGASSERT(backend); | |
| if(backend->handle) { | |
| - | char buf[32]; |
| set_logger(connssl, data); | |
| - | /* |
| - | * The conn->sock[0] socket is passed to openssl with SSL_set_fd(). Make |
| - | * sure the socket is not closed before calling OpenSSL functions that |
| - | * will use it. |
| - | */ |
| - | DEBUGASSERT(cf->conn->sock[FIRSTSOCKET] != CURL_SOCKET_BAD); |
| - | /* Maybe the server has already sent a close notify alert. |
| - | Read it to avoid an RST on the TCP connection. */ |
| - | (void)SSL_read(backend->handle, buf, (int)sizeof(buf)); |
| + | if(cf->next && cf->next->connected) { |
| + | char buf[32]; |
| + | /* Maybe the server has already sent a close notify alert. |
| + | Read it to avoid an RST on the TCP connection. */ |
| + | (void)SSL_read(backend->handle, buf, (int)sizeof(buf)); |
| - | (void)SSL_shutdown(backend->handle); |
| - | SSL_set_connect_state(backend->handle); |
| + | (void)SSL_shutdown(backend->handle); |
| + | SSL_set_connect_state(backend->handle); |
| + | } |
| SSL_free(backend->handle); | |
| backend->handle = NULL; | |
| @@ -2032,6 +2190,7 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, | |
| int port; | |
| size_t hostlen; | |
| + | (void)conn; |
| Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &dispname, &port); | |
| hostlen = strlen(hostname); | |
| @@ -3311,17 +3470,12 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, | |
| CURLcode result = CURLE_OK; | |
| char *ciphers; | |
| SSL_METHOD_QUAL SSL_METHOD *req_method = NULL; | |
| - | curl_socket_t sockfd = cf->conn->sock[cf->sockindex]; |
| struct ssl_connect_data *connssl = cf->ctx; | |
| ctx_option_t ctx_options = 0; | |
| void *ssl_sessionid = NULL; | |
| struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); | |
| struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); | |
| - | #ifndef CURL_DISABLE_PROXY |
| - | struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next); |
| - | struct ssl_connect_data *connssl_next = cf_ssl_next? |
| - | cf_ssl_next->ctx : NULL; |
| - | #endif |
| + | BIO *bio; |
| #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME | |
| bool sni; | |
| @@ -3382,7 +3536,12 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, | |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| - | DEBUGASSERT(!backend->ctx); |
| + | if(backend->ctx) { |
| + | /* This happens when an error was encountered before in this |
| + | * step and we are called to do it again. Get rid of any leftover |
| + | * from the previous call. */ |
| + | ossl_close(cf, data); |
| + | } |
| backend->ctx = SSL_CTX_new(req_method); | |
| if(!backend->ctx) { | |
| @@ -3707,24 +3866,12 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, | |
| Curl_ssl_sessionid_unlock(data); | |
| } | |
| - | #ifndef CURL_DISABLE_PROXY |
| - | if(connssl_next) { |
| - | BIO *const bio = BIO_new(BIO_f_ssl()); |
| - | DEBUGASSERT(connssl_next->backend); |
| - | DEBUGASSERT(ssl_connection_complete == connssl_next->state); |
| - | DEBUGASSERT(connssl_next->backend->handle != NULL); |
| - | DEBUGASSERT(bio != NULL); |
| - | BIO_set_ssl(bio, connssl_next->backend->handle, FALSE); |
| - | SSL_set_bio(backend->handle, bio, bio); |
| - | } |
| - | else |
| - | #endif |
| - | if(!SSL_set_fd(backend->handle, (int)sockfd)) { |
| - | /* pass the raw socket into the SSL layers */ |
| - | failf(data, "SSL: SSL_set_fd failed: %s", |
| - | ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer))); |
| - | return CURLE_SSL_CONNECT_ERROR; |
| - | } |
| + | bio = BIO_new(bio_cf_method); |
| + | if(!bio) |
| + | return CURLE_OUT_OF_MEMORY; |
| + | |
| + | BIO_set_data(bio, cf); |
| + | SSL_set_bio(backend->handle, bio, bio); |
| connssl->connecting_state = ssl_connect_2; | |
| @@ -4205,7 +4352,7 @@ static CURLcode ossl_connect_common(struct Curl_cfilter *cf, | |
| bool nonblocking, | |
| bool *done) | |
| { | |
| - | CURLcode result; |
| + | CURLcode result = CURLE_OK; |
| struct ssl_connect_data *connssl = cf->ctx; | |
| curl_socket_t sockfd = cf->conn->sock[cf->sockindex]; | |
| int what; | |
| @@ -4228,7 +4375,7 @@ static CURLcode ossl_connect_common(struct Curl_cfilter *cf, | |
| result = ossl_connect_step1(cf, data); | |
| if(result) | |
| - | return result; |
| + | goto out; |
| } | |
| while(ssl_connect_2 == connssl->connecting_state || | |
| @@ -4241,7 +4388,8 @@ static CURLcode ossl_connect_common(struct Curl_cfilter *cf, | |
| if(timeout_ms < 0) { | |
| /* no need to continue if time already is up */ | |
| failf(data, "SSL connection timeout"); | |
| - | return CURLE_OPERATION_TIMEDOUT; |
| + | result = CURLE_OPERATION_TIMEDOUT; |
| + | goto out; |
| } | |
| /* if ssl is expecting something, check if it's available. */ | |
| @@ -4258,16 +4406,19 @@ static CURLcode ossl_connect_common(struct Curl_cfilter *cf, | |
| if(what < 0) { | |
| /* fatal error */ | |
| failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); | |
| - | return CURLE_SSL_CONNECT_ERROR; |
| + | result = CURLE_SSL_CONNECT_ERROR; |
| + | goto out; |
| } | |
| if(0 == what) { | |
| if(nonblocking) { | |
| *done = FALSE; | |
| - | return CURLE_OK; |
| + | result = CURLE_OK; |
| + | goto out; |
| } | |
| /* timeout */ | |
| failf(data, "SSL connection timeout"); | |
| - | return CURLE_OPERATION_TIMEDOUT; |
| + | result = CURLE_OPERATION_TIMEDOUT; |
| + | goto out; |
| } | |
| /* socket is readable or writable */ | |
| } | |
| @@ -4283,14 +4434,14 @@ static CURLcode ossl_connect_common(struct Curl_cfilter *cf, | |
| (ssl_connect_2 == connssl->connecting_state || | |
| ssl_connect_2_reading == connssl->connecting_state || | |
| ssl_connect_2_writing == connssl->connecting_state))) | |
| - | return result; |
| + | goto out; |
| } /* repeat step2 until all transactions are done. */ | |
| if(ssl_connect_3 == connssl->connecting_state) { | |
| result = ossl_connect_step3(cf, data); | |
| if(result) | |
| - | return result; |
| + | goto out; |
| } | |
| if(ssl_connect_done == connssl->connecting_state) { | |
| @@ -4303,7 +4454,8 @@ static CURLcode ossl_connect_common(struct Curl_cfilter *cf, | |
| /* Reset our connect state machine */ | |
| connssl->connecting_state = ssl_connect_1; | |
| - | return CURLE_OK; |
| + | out: |
| + | return result; |
| } | |
| static CURLcode ossl_connect_nonblocking(struct Curl_cfilter *cf, | |
| @@ -4377,7 +4529,8 @@ static ssize_t ossl_send(struct Curl_cfilter *cf, | |
| should be called again later. This is basically an EWOULDBLOCK | |
| equivalent. */ | |
| *curlcode = CURLE_AGAIN; | |
| - | return -1; |
| + | rc = -1; |
| + | goto out; |
| case SSL_ERROR_SYSCALL: | |
| { | |
| int sockerr = SOCKERRNO; | |
| @@ -4393,7 +4546,8 @@ static ssize_t ossl_send(struct Curl_cfilter *cf, | |
| failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d", | |
| error_buffer, sockerr); | |
| *curlcode = CURLE_SEND_ERROR; | |
| - | return -1; |
| + | rc = -1; |
| + | goto out; |
| } | |
| case SSL_ERROR_SSL: { | |
| /* A failure in the SSL library occurred, usually a protocol error. | |
| @@ -4415,17 +4569,21 @@ static ssize_t ossl_send(struct Curl_cfilter *cf, | |
| failf(data, "SSL_write() error: %s", | |
| ossl_strerror(sslerror, error_buffer, sizeof(error_buffer))); | |
| *curlcode = CURLE_SEND_ERROR; | |
| - | return -1; |
| + | rc = -1; |
| + | goto out; |
| } | |
| default: | |
| /* a true error */ | |
| failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d", | |
| SSL_ERROR_to_str(err), SOCKERRNO); | |
| *curlcode = CURLE_SEND_ERROR; | |
| - | return -1; |
| + | rc = -1; |
| + | goto out; |
| } | |
| } | |
| *curlcode = CURLE_OK; | |
| + | |
| + | out: |
| return (ssize_t)rc; /* number of bytes */ | |
| } | |
| @@ -4451,6 +4609,7 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, | |
| buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; | |
| set_logger(connssl, data); | |
| nread = (ssize_t)SSL_read(backend->handle, buf, buffsize); | |
| + | |
| if(nread <= 0) { | |
| /* failed SSL_read */ | |
| int err = SSL_get_error(backend->handle, (int)nread); | |
| @@ -4469,7 +4628,8 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, | |
| case SSL_ERROR_WANT_WRITE: | |
| /* there's data pending, re-invoke SSL_read() */ | |
| *curlcode = CURLE_AGAIN; | |
| - | return -1; |
| + | nread = -1; |
| + | goto out; |
| default: | |
| /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return | |
| value/errno" */ | |
| @@ -4490,7 +4650,8 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, | |
| failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d", | |
| error_buffer, sockerr); | |
| *curlcode = CURLE_RECV_ERROR; | |
| - | return -1; |
| + | nread = -1; |
| + | goto out; |
| } | |
| /* For debug builds be a little stricter and error on any | |
| SSL_ERROR_SYSCALL. For example a server may have closed the connection | |
| @@ -4513,11 +4674,14 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf, | |
| " (Fatal because this is a curl debug build)", | |
| error_buffer, sockerr); | |
| *curlcode = CURLE_RECV_ERROR; | |
| - | return -1; |
| + | nread = -1; |
| + | goto out; |
| } | |
| #endif | |
| } | |
| } | |
| + | |
| + | out: |
| return nread; | |
| } | |
| @@ -81,26 +81,47 @@ cr_connect(struct Curl_cfilter *cf UNUSED_PARAM, | |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| + | struct io_ctx { |
| + | struct Curl_cfilter *cf; |
| + | struct Curl_easy *data; |
| + | }; |
| + | |
| static int | |
| read_cb(void *userdata, uint8_t *buf, uintptr_t len, uintptr_t *out_n) | |
| { | |
| - | ssize_t n = sread(*(int *)userdata, buf, len); |
| - | if(n < 0) { |
| - | return SOCKERRNO; |
| + | struct io_ctx *io_ctx = userdata; |
| + | CURLcode result; |
| + | int ret = 0; |
| + | ssize_t nread = Curl_conn_cf_recv(io_ctx->cf->next, io_ctx->data, |
| + | (char *)buf, len, &result); |
| + | if(nread < 0) { |
| + | nread = 0; |
| + | if(CURLE_AGAIN == result) |
| + | ret = EAGAIN; |
| + | else |
| + | ret = EINVAL; |
| } | |
| - | *out_n = n; |
| - | return 0; |
| + | *out_n = (int)nread; |
| + | return ret; |
| } | |
| static int | |
| write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n) | |
| { | |
| - | ssize_t n = swrite(*(int *)userdata, buf, len); |
| - | if(n < 0) { |
| - | return SOCKERRNO; |
| + | struct io_ctx *io_ctx = userdata; |
| + | CURLcode result; |
| + | int ret = 0; |
| + | ssize_t nwritten = Curl_conn_cf_send(io_ctx->cf->next, io_ctx->data, |
| + | (const char *)buf, len, &result); |
| + | if(nwritten < 0) { |
| + | nwritten = 0; |
| + | if(CURLE_AGAIN == result) |
| + | ret = EAGAIN; |
| + | else |
| + | ret = EINVAL; |
| } | |
| - | *out_n = n; |
| - | return 0; |
| + | *out_n = (int)nwritten; |
| + | return ret; |
| } | |
| /* | |
| @@ -122,6 +143,7 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| struct ssl_connect_data *const connssl = cf->ctx; | |
| struct ssl_backend_data *const backend = connssl->backend; | |
| struct rustls_connection *rconn = NULL; | |
| + | struct io_ctx io_ctx; |
| size_t n = 0; | |
| size_t tls_bytes_read = 0; | |
| @@ -133,10 +155,13 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| DEBUGASSERT(backend); | |
| rconn = backend->conn; | |
| - | io_error = rustls_connection_read_tls(rconn, read_cb, |
| - | &cf->conn->sock[cf->sockindex], &tls_bytes_read); |
| + | io_ctx.cf = cf; |
| + | io_ctx.data = data; |
| + | |
| + | io_error = rustls_connection_read_tls(rconn, read_cb, &io_ctx, |
| + | &tls_bytes_read); |
| if(io_error == EAGAIN || io_error == EWOULDBLOCK) { | |
| - | infof(data, "sread: EAGAIN or EWOULDBLOCK"); |
| + | infof(data, CFMSG(cf, "cr_recv: EAGAIN or EWOULDBLOCK")); |
| } | |
| else if(io_error) { | |
| char buffer[STRERROR_LEN]; | |
| @@ -146,7 +171,7 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| return -1; | |
| } | |
| - | infof(data, "cr_recv read %ld bytes from the network", tls_bytes_read); |
| + | infof(data, CFMSG(cf, "cr_recv: read %ld TLS bytes"), tls_bytes_read); |
| rresult = rustls_connection_process_new_packets(rconn); | |
| if(rresult != RUSTLS_RESULT_OK) { | |
| @@ -164,7 +189,8 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| plainlen - plain_bytes_copied, | |
| &n); | |
| if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) { | |
| - | infof(data, "cr_recv got PLAINTEXT_EMPTY. will try again later."); |
| + | infof(data, CFMSG(cf, "cr_recv: got PLAINTEXT_EMPTY. " |
| + | "will try again later.")); |
| backend->data_pending = FALSE; | |
| break; | |
| } | |
| @@ -181,7 +207,7 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| break; | |
| } | |
| else { | |
| - | infof(data, "cr_recv copied out %ld bytes of plaintext", n); |
| + | infof(data, CFMSG(cf, "cr_recv: got %ld plain bytes"), n); |
| plain_bytes_copied += n; | |
| } | |
| } | |
| @@ -222,6 +248,7 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| struct ssl_connect_data *const connssl = cf->ctx; | |
| struct ssl_backend_data *const backend = connssl->backend; | |
| struct rustls_connection *rconn = NULL; | |
| + | struct io_ctx io_ctx; |
| size_t plainwritten = 0; | |
| size_t tlswritten = 0; | |
| size_t tlswritten_total = 0; | |
| @@ -231,7 +258,7 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| DEBUGASSERT(backend); | |
| rconn = backend->conn; | |
| - | infof(data, "cr_send %ld bytes of plaintext", plainlen); |
| + | infof(data, CFMSG(cf, "cr_send: %ld plain bytes"), plainlen); |
| if(plainlen > 0) { | |
| rresult = rustls_connection_write(rconn, plainbuf, plainlen, | |
| @@ -248,11 +275,15 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| } | |
| } | |
| + | io_ctx.cf = cf; |
| + | io_ctx.data = data; |
| + | |
| while(rustls_connection_wants_write(rconn)) { | |
| - | io_error = rustls_connection_write_tls(rconn, write_cb, |
| - | &cf->conn->sock[cf->sockindex], &tlswritten); |
| + | io_error = rustls_connection_write_tls(rconn, write_cb, &io_ctx, |
| + | &tlswritten); |
| if(io_error == EAGAIN || io_error == EWOULDBLOCK) { | |
| - | infof(data, "swrite: EAGAIN after %ld bytes", tlswritten_total); |
| + | infof(data, CFMSG(cf, "cr_send: EAGAIN after %ld bytes"), |
| + | tlswritten_total); |
| *err = CURLE_AGAIN; | |
| return -1; | |
| } | |
| @@ -268,7 +299,7 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| *err = CURLE_WRITE_ERROR; | |
| return -1; | |
| } | |
| - | infof(data, "cr_send wrote %ld bytes to network", tlswritten); |
| + | infof(data, CFMSG(cf, "cr_send: wrote %ld TLS bytes"), tlswritten); |
| tlswritten_total += tlswritten; | |
| } | |
| @@ -606,7 +637,8 @@ static size_t cr_version(char *buffer, size_t size) | |
| const struct Curl_ssl Curl_ssl_rustls = { | |
| { CURLSSLBACKEND_RUSTLS, "rustls" }, | |
| SSLSUPP_CAINFO_BLOB | /* supports */ | |
| - | SSLSUPP_TLS13_CIPHERSUITES, |
| + | SSLSUPP_TLS13_CIPHERSUITES | |
| + | SSLSUPP_HTTPS_PROXY, |
| sizeof(struct ssl_backend_data), | |
| Curl_none_init, /* init */ | |
| @@ -1313,8 +1313,9 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| "sending %lu bytes.", outbuf.cbBuffer)); | |
| /* send initial handshake data which is now stored in output buffer */ | |
| - | result = Curl_write_plain(data, cf->conn->sock[cf->sockindex], |
| - | outbuf.pvBuffer, outbuf.cbBuffer, &written); |
| + | written = Curl_conn_cf_send(cf->next, data, |
| + | outbuf.pvBuffer, outbuf.cbBuffer, |
| + | &result); |
| s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); | |
| if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) { | |
| failf(data, "schannel: failed to send initial handshake data: " | |
| @@ -1411,12 +1412,12 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| for(;;) { | |
| if(doread) { | |
| /* read encrypted handshake data from socket */ | |
| - | result = Curl_read_plain(data, cf->conn->sock[cf->sockindex], |
| + | nread = Curl_conn_cf_recv(cf->next, data, |
| (char *) (backend->encdata_buffer + | |
| backend->encdata_offset), | |
| backend->encdata_length - | |
| backend->encdata_offset, | |
| - | &nread); |
| + | &result); |
| if(result == CURLE_AGAIN) { | |
| if(connssl->connecting_state != ssl_connect_2_writing) | |
| connssl->connecting_state = ssl_connect_2_reading; | |
| @@ -1500,9 +1501,9 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| "sending %lu bytes.", outbuf[i].cbBuffer)); | |
| /* send handshake token to server */ | |
| - | result = Curl_write_plain(data, cf->conn->sock[cf->sockindex], |
| - | outbuf[i].pvBuffer, outbuf[i].cbBuffer, |
| - | &written); |
| + | written = Curl_conn_cf_send(cf->next, data, |
| + | outbuf[i].pvBuffer, outbuf[i].cbBuffer, |
| + | &result); |
| if((result != CURLE_OK) || | |
| (outbuf[i].cbBuffer != (size_t) written)) { | |
| failf(data, "schannel: failed to send next handshake data: " | |
| @@ -1964,7 +1965,6 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| ssize_t written = -1; | |
| size_t data_len = 0; | |
| unsigned char *ptr = NULL; | |
| - | struct connectdata *conn = cf->conn; |
| struct ssl_connect_data *connssl = cf->ctx; | |
| SecBuffer outbuf[4]; | |
| SecBufferDesc outbuf_desc; | |
| @@ -2073,8 +2073,9 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| } | |
| /* socket is writable */ | |
| - | result = Curl_write_plain(data, conn->sock[cf->sockindex], |
| - | ptr + written, len - written, &this_write); |
| + | this_write = Curl_conn_cf_send(cf->next, data, |
| + | ptr + written, len - written, |
| + | &result); |
| if(result == CURLE_AGAIN) | |
| continue; | |
| else if(result != CURLE_OK) { | |
| @@ -2185,19 +2186,19 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| backend->encdata_offset, backend->encdata_length)); | |
| /* read encrypted data from socket */ | |
| - | *err = Curl_read_plain(data, cf->conn->sock[cf->sockindex], |
| - | (char *)(backend->encdata_buffer + |
| + | nread = Curl_conn_cf_recv(cf->next, data, |
| + | (char *)(backend->encdata_buffer + |
| backend->encdata_offset), | |
| - | size, &nread); |
| + | size, err); |
| if(*err) { | |
| nread = -1; | |
| if(*err == CURLE_AGAIN) | |
| DEBUGF(infof(data, | |
| - | "schannel: Curl_read_plain returned CURLE_AGAIN")); |
| + | "schannel: recv returned CURLE_AGAIN")); |
| else if(*err == CURLE_RECV_ERROR) | |
| - | infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR"); |
| + | infof(data, "schannel: recv returned CURLE_RECV_ERROR"); |
| else | |
| - | infof(data, "schannel: Curl_read_plain returned error %d", *err); |
| + | infof(data, "schannel: recv returned error %d", *err); |
| } | |
| else if(nread == 0) { | |
| backend->recv_connection_closed = true; | |
| @@ -2546,11 +2547,9 @@ static int schannel_shutdown(struct Curl_cfilter *cf, | |
| if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) { | |
| /* send close message which is in output buffer */ | |
| - | ssize_t written; |
| - | result = Curl_write_plain(data, cf->conn->sock[cf->sockindex], |
| - | outbuf.pvBuffer, outbuf.cbBuffer, |
| - | &written); |
| - | |
| + | ssize_t written = Curl_conn_cf_send(cf->next, data, |
| + | outbuf.pvBuffer, outbuf.cbBuffer, |
| + | &result); |
| s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); | |
| if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) { | |
| infof(data, "schannel: failed to send close msg: %s" | |
| @@ -2767,7 +2766,8 @@ const struct Curl_ssl Curl_ssl_schannel = { | |
| SSLSUPP_CAINFO_BLOB | | |
| #endif | |
| SSLSUPP_PINNEDPUBKEY | | |
| - | SSLSUPP_TLS13_CIPHERSUITES, |
| + | SSLSUPP_TLS13_CIPHERSUITES | |
| + | SSLSUPP_HTTPS_PROXY, |
| sizeof(struct ssl_backend_data), | |
| @@ -142,7 +142,6 @@ | |
| struct ssl_backend_data { | |
| SSLContextRef ssl_ctx; | |
| - | curl_socket_t ssl_sockfd; |
| bool ssl_direction; /* true if writing, false if reading */ | |
| size_t ssl_write_buffered_length; | |
| }; | |
| @@ -825,113 +824,62 @@ static const unsigned char ecDsaSecp384r1SpkiHeader[] = { | |
| #endif /* SECTRANSP_PINNEDPUBKEY_V1 */ | |
| #endif /* SECTRANSP_PINNEDPUBKEY */ | |
| - | /* The following two functions were ripped from Apple sample code, |
| - | * with some modifications: */ |
| - | static OSStatus SocketRead(SSLConnectionRef connection, |
| - | void *data, /* owned by |
| - | * caller, data |
| - | * RETURNED */ |
| - | size_t *dataLength) /* IN/OUT */ |
| + | static OSStatus bio_cf_in_read(SSLConnectionRef connection, |
| + | void *buf, |
| + | size_t *dataLength) /* IN/OUT */ |
| { | |
| - | size_t bytesToGo = *dataLength; |
| - | size_t initLen = bytesToGo; |
| - | UInt8 *currData = (UInt8 *)data; |
| - | struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; |
| + | struct Curl_cfilter *cf = (struct Curl_cfilter *)connection; |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| struct ssl_backend_data *backend = connssl->backend; | |
| - | int sock; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nread; |
| + | CURLcode result; |
| OSStatus rtn = noErr; | |
| - | size_t bytesRead; |
| - | ssize_t rrtn; |
| - | int theErr; |
| - | |
| - | DEBUGASSERT(backend); |
| - | sock = backend->ssl_sockfd; |
| - | *dataLength = 0; |
| - | |
| - | for(;;) { |
| - | bytesRead = 0; |
| - | rrtn = read(sock, currData, bytesToGo); |
| - | if(rrtn <= 0) { |
| - | /* this is guesswork... */ |
| - | theErr = errno; |
| - | if(rrtn == 0) { /* EOF = server hung up */ |
| - | /* the framework will turn this into errSSLClosedNoNotify */ |
| - | rtn = errSSLClosedGraceful; |
| - | } |
| - | else /* do the switch */ |
| - | switch(theErr) { |
| - | case ENOENT: |
| - | /* connection closed */ |
| - | rtn = errSSLClosedGraceful; |
| - | break; |
| - | case ECONNRESET: |
| - | rtn = errSSLClosedAbort; |
| - | break; |
| - | case EAGAIN: |
| - | rtn = errSSLWouldBlock; |
| - | backend->ssl_direction = false; |
| - | break; |
| - | default: |
| - | rtn = ioErr; |
| - | break; |
| - | } |
| - | break; |
| - | } |
| - | else { |
| - | bytesRead = rrtn; |
| - | } |
| - | bytesToGo -= bytesRead; |
| - | currData += bytesRead; |
| - | if(bytesToGo == 0) { |
| - | /* filled buffer with incoming data, done */ |
| - | break; |
| + | DEBUGASSERT(data); |
| + | nread = Curl_conn_cf_recv(cf->next, data, buf, *dataLength, &result); |
| + | if(nread < 0) { |
| + | switch(result) { |
| + | case CURLE_OK: |
| + | case CURLE_AGAIN: |
| + | rtn = errSSLWouldBlock; |
| + | backend->ssl_direction = false; |
| + | break; |
| + | default: |
| + | rtn = ioErr; |
| + | break; |
| } | |
| + | nread = 0; |
| } | |
| - | *dataLength = initLen - bytesToGo; |
| - | |
| + | *dataLength = nread; |
| return rtn; | |
| } | |
| - | static OSStatus SocketWrite(SSLConnectionRef connection, |
| - | const void *data, |
| - | size_t *dataLength) /* IN/OUT */ |
| + | static OSStatus bio_cf_out_write(SSLConnectionRef connection, |
| + | const void *buf, |
| + | size_t *dataLength) /* IN/OUT */ |
| { | |
| - | size_t bytesSent = 0; |
| - | struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; |
| + | struct Curl_cfilter *cf = (struct Curl_cfilter *)connection; |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| struct ssl_backend_data *backend = connssl->backend; | |
| - | int sock; |
| - | ssize_t length; |
| - | size_t dataLen = *dataLength; |
| - | const UInt8 *dataPtr = (UInt8 *)data; |
| - | OSStatus ortn; |
| - | int theErr; |
| - | |
| - | DEBUGASSERT(backend); |
| - | sock = backend->ssl_sockfd; |
| - | *dataLength = 0; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nwritten; |
| + | CURLcode result; |
| + | OSStatus ortn = noErr; |
| - | do { |
| - | length = write(sock, |
| - | (char *)dataPtr + bytesSent, |
| - | dataLen - bytesSent); |
| - | } while((length > 0) && |
| - | ( (bytesSent += length) < dataLen) ); |
| - | |
| - | if(length <= 0) { |
| - | theErr = errno; |
| - | if(theErr == EAGAIN) { |
| + | DEBUGASSERT(data); |
| + | nwritten = Curl_conn_cf_send(cf->next, data, buf, *dataLength, &result); |
| + | if(nwritten <= 0) { |
| + | if(result == CURLE_AGAIN) { |
| ortn = errSSLWouldBlock; | |
| backend->ssl_direction = true; | |
| } | |
| else { | |
| ortn = ioErr; | |
| } | |
| + | nwritten = 0; |
| } | |
| - | else { |
| - | ortn = noErr; |
| - | } |
| - | *dataLength = bytesSent; |
| + | *dataLength = nwritten; |
| return ortn; | |
| } | |
| @@ -1666,7 +1614,6 @@ static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data, | |
| static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf, | |
| struct Curl_easy *data) | |
| { | |
| - | curl_socket_t sockfd = cf->conn->sock[cf->sockindex]; |
| struct ssl_connect_data *connssl = cf->ctx; | |
| struct ssl_backend_data *backend = connssl->backend; | |
| struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); | |
| @@ -2132,18 +2079,13 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf, | |
| } | |
| } | |
| - | err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite); |
| + | err = SSLSetIOFuncs(backend->ssl_ctx, bio_cf_in_read, bio_cf_out_write); |
| if(err != noErr) { | |
| failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err); | |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| - | /* pass the raw socket into the SSL layers */ |
| - | /* We need to store the FD in a constant memory address, because |
| - | * SSLSetConnection() will not copy that address. I've found that |
| - | * conn->sock[sockindex] may change on its own. */ |
| - | backend->ssl_sockfd = sockfd; |
| - | err = SSLSetConnection(backend->ssl_ctx, connssl); |
| + | err = SSLSetConnection(backend->ssl_ctx, cf); |
| if(err != noErr) { | |
| failf(data, "SSL: SSLSetConnection() failed: %d", err); | |
| return CURLE_SSL_CONNECT_ERROR; | |
| @@ -3185,7 +3127,6 @@ static void sectransp_close(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ | |
| backend->ssl_ctx = NULL; | |
| } | |
| - | backend->ssl_sockfd = 0; |
| } | |
| static int sectransp_shutdown(struct Curl_cfilter *cf, | |
| @@ -3198,6 +3139,7 @@ static int sectransp_shutdown(struct Curl_cfilter *cf, | |
| int rc; | |
| char buf[120]; | |
| int loop = 10; /* avoid getting stuck */ | |
| + | CURLcode result; |
| DEBUGASSERT(backend); | |
| @@ -3231,12 +3173,10 @@ static int sectransp_shutdown(struct Curl_cfilter *cf, | |
| /* Something to read, let's do it and hope that it is the close | |
| notify alert from the server. No way to SSL_Read now, so use read(). */ | |
| - | nread = read(cf->conn->sock[cf->sockindex], buf, sizeof(buf)); |
| + | nread = Curl_conn_cf_recv(cf->next, data, buf, sizeof(buf), &result); |
| if(nread < 0) { | |
| - | char buffer[STRERROR_LEN]; |
| - | failf(data, "read: %s", |
| - | Curl_strerror(errno, buffer, sizeof(buffer))); |
| + | failf(data, "read: %s", curl_easy_strerror(result)); |
| rc = -1; | |
| } | |
| @@ -3494,10 +3434,9 @@ const struct Curl_ssl Curl_ssl_sectransp = { | |
| SSLSUPP_CAINFO_BLOB | | |
| SSLSUPP_CERTINFO | | |
| #ifdef SECTRANSP_PINNEDPUBKEY | |
| - | SSLSUPP_PINNEDPUBKEY, |
| - | #else |
| - | 0, |
| + | SSLSUPP_PINNEDPUBKEY | |
| #endif /* SECTRANSP_PINNEDPUBKEY */ | |
| + | SSLSUPP_HTTPS_PROXY, |
| sizeof(struct ssl_backend_data), | |
| @@ -3511,7 +3450,7 @@ const struct Curl_ssl Curl_ssl_sectransp = { | |
| Curl_none_cert_status_request, /* cert_status_request */ | |
| sectransp_connect, /* connect */ | |
| sectransp_connect_nonblocking, /* connect_nonblocking */ | |
| - | Curl_ssl_get_select_socks, /* getsock */ |
| + | Curl_ssl_get_select_socks, /* getsock */ |
| sectransp_get_internals, /* get_internals */ | |
| sectransp_close, /* close_one */ | |
| Curl_none_close_all, /* close_all */ | |
| @@ -297,11 +297,12 @@ static struct ssl_connect_data *cf_ctx_new(struct Curl_easy *data) | |
| { | |
| struct ssl_connect_data *ctx; | |
| + | (void)data; |
| ctx = calloc(1, sizeof(*ctx)); | |
| if(!ctx) | |
| return NULL; | |
| - | ctx->backend = calloc(1, Curl_ssl_get_backend_data_size(data)); |
| + | ctx->backend = calloc(1, Curl_ssl->sizeof_ssl_backend_data); |
| if(!ctx->backend) { | |
| free(ctx); | |
| return NULL; | |
| @@ -317,6 +318,13 @@ static void cf_ctx_free(struct ssl_connect_data *ctx) | |
| } | |
| } | |
| + | static void cf_ctx_set_data(struct Curl_cfilter *cf, |
| + | struct Curl_easy *data) |
| + | { |
| + | if(cf->ctx) |
| + | ((struct ssl_connect_data *)cf->ctx)->call_data = data; |
| + | } |
| + | |
| static CURLcode ssl_connect(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| { | |
| struct ssl_connect_data *connssl = cf->ctx; | |
| @@ -1467,29 +1475,19 @@ static void reinit_hostname(struct Curl_cfilter *cf) | |
| static void ssl_cf_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| { | |
| + | cf_ctx_set_data(cf, data); |
| cf_close(cf, data); | |
| cf_ctx_free(cf->ctx); | |
| - | } |
| - | |
| - | static CURLcode ssl_cf_setup(struct Curl_cfilter *cf, |
| - | struct Curl_easy *data, |
| - | const struct Curl_dns_entry *remotehost) |
| - | { |
| - | CURLcode result; |
| - | |
| - | result = cf->next->cft->setup(cf->next, data, remotehost); |
| - | if(result) |
| - | return result; |
| - | |
| - | /* TODO our setup */ |
| - | return result; |
| + | cf->ctx = NULL; |
| } | |
| static void ssl_cf_close(struct Curl_cfilter *cf, | |
| struct Curl_easy *data) | |
| { | |
| + | cf_ctx_set_data(cf, data); |
| cf_close(cf, data); | |
| cf->next->cft->close(cf->next, data); | |
| + | cf_ctx_set_data(cf, NULL); |
| } | |
| static CURLcode ssl_cf_connect(struct Curl_cfilter *cf, | |
| @@ -1504,6 +1502,7 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf, | |
| return CURLE_OK; | |
| } | |
| + | cf_ctx_set_data(cf, data); |
| (void)connssl; | |
| DEBUGASSERT(data->conn); | |
| DEBUGASSERT(data->conn == cf->conn); | |
| @@ -1512,7 +1511,7 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf, | |
| result = cf->next->cft->connect(cf->next, data, blocking, done); | |
| if(result || !*done) | |
| - | return result; |
| + | goto out; |
| /* TODO: right now we do not fully control when hostname is set, | |
| * assign it on each connect call. */ | |
| @@ -1533,15 +1532,23 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf, | |
| Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */ | |
| DEBUGASSERT(connssl->state == ssl_connection_complete); | |
| } | |
| + | out: |
| + | cf_ctx_set_data(cf, NULL); |
| return result; | |
| } | |
| static bool ssl_cf_data_pending(struct Curl_cfilter *cf, | |
| const struct Curl_easy *data) | |
| { | |
| + | bool result; |
| + | |
| + | cf_ctx_set_data(cf, (struct Curl_easy *)data); |
| if(cf->ctx && Curl_ssl->data_pending(cf, data)) | |
| - | return TRUE; |
| - | return cf->next->cft->has_data_pending(cf->next, data); |
| + | result = TRUE; |
| + | else |
| + | result = cf->next->cft->has_data_pending(cf->next, data); |
| + | cf_ctx_set_data(cf, NULL); |
| + | return result; |
| } | |
| static ssize_t ssl_cf_send(struct Curl_cfilter *cf, | |
| @@ -1551,9 +1558,9 @@ static ssize_t ssl_cf_send(struct Curl_cfilter *cf, | |
| ssize_t nwritten; | |
| *err = CURLE_OK; | |
| + | cf_ctx_set_data(cf, data); |
| nwritten = Curl_ssl->send_plain(cf, data, buf, len, err); | |
| - | DEBUGF(infof(data, CFMSG(cf, "send(len=%ld) -> %ld, code=%d"), |
| - | len, nwritten, *err)); |
| + | cf_ctx_set_data(cf, NULL); |
| return nwritten; | |
| } | |
| @@ -1564,9 +1571,9 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf, | |
| ssize_t nread; | |
| *err = CURLE_OK; | |
| + | cf_ctx_set_data(cf, data); |
| nread = Curl_ssl->recv_plain(cf, data, buf, len, err); | |
| - | DEBUGF(infof(data, CFMSG(cf, "recv -> %ld, code=%d"), |
| - | nread, *err)); |
| + | cf_ctx_set_data(cf, NULL); |
| return nread; | |
| } | |
| @@ -1574,20 +1581,21 @@ static int ssl_cf_get_select_socks(struct Curl_cfilter *cf, | |
| struct Curl_easy *data, | |
| curl_socket_t *socks) | |
| { | |
| - | /* TODO, this needs to work for other than SOCKETFIRST filters |
| - | * and also nested filters. Needs change of implementations. |
| - | * What we really want to know if the SSL implementation wants |
| - | * to READ or WRITE or needs nothing. |
| - | */ |
| - | (void)data; |
| - | return Curl_ssl->get_select_socks(cf, data, socks); |
| + | int result; |
| + | |
| + | cf_ctx_set_data(cf, data); |
| + | result = Curl_ssl->get_select_socks(cf, data, socks); |
| + | cf_ctx_set_data(cf, NULL); |
| + | return result; |
| } | |
| static void ssl_cf_attach_data(struct Curl_cfilter *cf, | |
| struct Curl_easy *data) | |
| { | |
| if(Curl_ssl->attach_data) { | |
| + | cf_ctx_set_data(cf, data); |
| Curl_ssl->attach_data(cf, data); | |
| + | cf_ctx_set_data(cf, NULL); |
| } | |
| } | |
| @@ -1595,7 +1603,9 @@ static void ssl_cf_detach_data(struct Curl_cfilter *cf, | |
| struct Curl_easy *data) | |
| { | |
| if(Curl_ssl->detach_data) { | |
| + | cf_ctx_set_data(cf, data); |
| Curl_ssl->detach_data(cf, data); | |
| + | cf_ctx_set_data(cf, NULL); |
| } | |
| } | |
| @@ -1603,7 +1613,7 @@ static const struct Curl_cftype cft_ssl = { | |
| "SSL", | |
| CF_TYPE_SSL, | |
| ssl_cf_destroy, | |
| - | ssl_cf_setup, |
| + | Curl_cf_def_setup, |
| ssl_cf_connect, | |
| ssl_cf_close, | |
| Curl_cf_def_get_host, | |
| @@ -1619,7 +1629,7 @@ static const struct Curl_cftype cft_ssl_proxy = { | |
| "SSL-PROXY", | |
| CF_TYPE_SSL, | |
| ssl_cf_destroy, | |
| - | ssl_cf_setup, |
| + | Curl_cf_def_setup, |
| ssl_cf_connect, | |
| ssl_cf_close, | |
| Curl_cf_def_get_host, | |
| @@ -1691,12 +1701,6 @@ out: | |
| #endif /* !CURL_DISABLE_PROXY */ | |
| - | size_t Curl_ssl_get_backend_data_size(struct Curl_easy *data) |
| - | { |
| - | (void)data; |
| - | return Curl_ssl->sizeof_ssl_backend_data; |
| - | } |
| - | |
| bool Curl_ssl_supports(struct Curl_easy *data, int option) | |
| { | |
| (void)data; | |
| @@ -1706,15 +1710,19 @@ bool Curl_ssl_supports(struct Curl_easy *data, int option) | |
| void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex, | |
| CURLINFO info, int n) | |
| { | |
| + | void *result = NULL; |
| (void)n; | |
| if(data->conn) { | |
| struct Curl_cfilter *cf; | |
| /* get first filter in chain, if any is present */ | |
| cf = Curl_ssl_cf_get_ssl(data->conn->cfilter[sockindex]); | |
| - | if(cf) |
| - | return Curl_ssl->get_internals(cf->ctx, info); |
| + | if(cf) { |
| + | cf_ctx_set_data(cf, data); |
| + | result = Curl_ssl->get_internals(cf->ctx, info); |
| + | cf_ctx_set_data(cf, NULL); |
| + | } |
| } | |
| - | return NULL; |
| + | return result; |
| } | |
| bool Curl_ssl_use(struct connectdata *conn, int sockindex) | |
| @@ -1722,22 +1730,6 @@ bool Curl_ssl_use(struct connectdata *conn, int sockindex) | |
| return Curl_ssl_cf_get_ssl(conn->cfilter[sockindex]) != NULL; | |
| } | |
| - | bool Curl_ssl_conn_is_ssl(struct Curl_easy *data, |
| - | int sockindex) |
| - | { |
| - | struct Curl_cfilter *cf = data->conn? data->conn->cfilter[sockindex] : NULL; |
| - | |
| - | /* TODO: this is an inomplete check. We might skip filters here that |
| - | * tunnel/transform and only use SSL for part of the connection. |
| - | */ |
| - | (void)data; |
| - | for(; cf; cf = cf->next) { |
| - | if(cf->cft == &cft_ssl) |
| - | return TRUE; |
| - | } |
| - | return FALSE; |
| - | } |
| - | |
| CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data, | |
| int sockindex) | |
| { | |
| @@ -165,14 +165,6 @@ CURLcode Curl_ssl_cfilter_proxy_add(struct Curl_easy *data, | |
| int sockindex); | |
| #endif /* !CURL_DISABLE_PROXY */ | |
| - | /** |
| - | * Return TRUE iff the filter chain `sockindex` at connection `conn` |
| - | * is using/prepared for SSL encryption. This tests the presence of the |
| - | * necessary filters and not their connectedness. |
| - | */ |
| - | bool Curl_ssl_conn_is_ssl(struct Curl_easy *data, |
| - | int sockindex); |
| - | |
| /** | |
| * Get the SSL configuration that is used on the connection. | |
| * This returns NULL if no SSL is configured. | |
| @@ -216,8 +208,6 @@ bool Curl_ssl_supports(struct Curl_easy *data, int ssl_option); | |
| void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex, | |
| CURLINFO info, int n); | |
| - | size_t Curl_ssl_get_backend_data_size(struct Curl_easy *data); |
| - | |
| bool Curl_ssl_use(struct connectdata *conn, int sockindex); | |
| #else /* if not USE_SSL */ | |
| @@ -238,9 +228,7 @@ bool Curl_ssl_use(struct connectdata *conn, int sockindex); | |
| #define Curl_ssl_false_start(a) FALSE | |
| #define Curl_ssl_get_internals(a,b,c,d) NULL | |
| #define Curl_ssl_supports(a,b) FALSE | |
| - | #define Curl_ssl_get_backend_data_size(a) 0 |
| #define Curl_ssl_use(a,b) FALSE | |
| - | #define Curl_ssl_conn_is_ssl(a,b) FALSE |
| #define Curl_ssl_cfilter_add(a,b,c) CURLE_NOT_BUILT_IN | |
| #define Curl_ssl_cfilter_proxy_add(a,b,c) CURLE_NOT_BUILT_IN | |
| #define Curl_ssl_get_config(a,b) NULL | |
| @@ -33,10 +33,15 @@ | |
| struct ssl_connect_data { | |
| ssl_connection_state state; | |
| ssl_connect_state connecting_state; | |
| - | const char *hostname; |
| - | const char *dispname; |
| - | int port; |
| - | struct ssl_backend_data *backend; |
| + | const char *hostname; /* hostnaem for verification */ |
| + | const char *dispname; /* display version of hostname */ |
| + | int port; /* remote port at origin */ |
| + | struct ssl_backend_data *backend; /* vtls backend specific props */ |
| + | struct Curl_easy *call_data; /* data handle used in current call, |
| + | * same as paramter passed, but available |
| + | * here for backend internal callbacks |
| + | * that need it. NULLed after at the |
| + | * end of each vtls filter invcocation. */ |
| }; | |
| @@ -85,9 +85,16 @@ | |
| #endif | |
| #endif | |
| + | #if defined(HAVE_WOLFSSL_FULL_BIO) && HAVE_WOLFSSL_FULL_BIO |
| + | #define USE_BIO_CHAIN |
| + | #else |
| + | #undef USE_BIO_CHAIN |
| + | #endif |
| + | |
| struct ssl_backend_data { | |
| SSL_CTX* ctx; | |
| SSL* handle; | |
| + | CURLcode io_result; |
| }; | |
| #ifdef OPENSSL_EXTRA | |
| @@ -239,6 +246,139 @@ static const struct group_name_map gnm[] = { | |
| }; | |
| #endif | |
| + | #ifdef USE_BIO_CHAIN |
| + | |
| + | static int bio_cf_create(WOLFSSL_BIO *bio) |
| + | { |
| + | wolfSSL_BIO_set_shutdown(bio, 1); |
| + | wolfSSL_BIO_set_init(bio, 1); |
| + | wolfSSL_BIO_set_data(bio, NULL); |
| + | return 1; |
| + | } |
| + | |
| + | static int bio_cf_destroy(WOLFSSL_BIO *bio) |
| + | { |
| + | if(!bio) |
| + | return 0; |
| + | return 1; |
| + | } |
| + | |
| + | static long bio_cf_ctrl(WOLFSSL_BIO *bio, int cmd, long num, void *ptr) |
| + | { |
| + | struct Curl_cfilter *cf = BIO_get_data(bio); |
| + | long ret = 1; |
| + | |
| + | (void)cf; |
| + | (void)ptr; |
| + | switch(cmd) { |
| + | case BIO_CTRL_GET_CLOSE: |
| + | ret = (long)wolfSSL_BIO_get_shutdown(bio); |
| + | break; |
| + | case BIO_CTRL_SET_CLOSE: |
| + | wolfSSL_BIO_set_shutdown(bio, (int)num); |
| + | break; |
| + | case BIO_CTRL_FLUSH: |
| + | /* we do no delayed writes, but if we ever would, this |
| + | * needs to trigger it. */ |
| + | ret = 1; |
| + | break; |
| + | case BIO_CTRL_DUP: |
| + | ret = 1; |
| + | break; |
| + | #ifdef BIO_CTRL_EOF |
| + | case BIO_CTRL_EOF: |
| + | /* EOF has been reached on input? */ |
| + | return (!cf->next || !cf->next->connected); |
| + | #endif |
| + | default: |
| + | ret = 0; |
| + | break; |
| + | } |
| + | return ret; |
| + | } |
| + | |
| + | static int bio_cf_out_write(WOLFSSL_BIO *bio, const char *buf, int blen) |
| + | { |
| + | struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio); |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nwritten; |
| + | CURLcode result = CURLE_OK; |
| + | |
| + | DEBUGASSERT(data); |
| + | nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result); |
| + | wolfSSL_BIO_clear_retry_flags(bio); |
| + | /* wolfSSL is limited in error handling and SSL_read() will |
| + | * return WANT_READ, even though retry was not indicated by |
| + | * the installed BIO. */ |
| + | connssl->backend->io_result = result; |
| + | if(nwritten < 0) { |
| + | if(CURLE_AGAIN == result) { |
| + | BIO_set_retry_read(bio); |
| + | nwritten = 0; |
| + | } |
| + | else { |
| + | nwritten = -1; |
| + | } |
| + | } |
| + | return (int)nwritten; |
| + | } |
| + | |
| + | static int bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen) |
| + | { |
| + | struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio); |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| + | struct Curl_easy *data = connssl->call_data; |
| + | ssize_t nread; |
| + | CURLcode result = CURLE_OK; |
| + | |
| + | DEBUGASSERT(data); |
| + | /* OpenSSL catches this case, so should we. */ |
| + | if(!buf) |
| + | return 0; |
| + | |
| + | nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result); |
| + | wolfSSL_BIO_clear_retry_flags(bio); |
| + | /* wolfSSL is limited in error handling and SSL_read() will |
| + | * return WANT_READ, even though retry was not indicated by |
| + | * the installed BIO. */ |
| + | connssl->backend->io_result = result; |
| + | if(nread < 0) { |
| + | if(CURLE_AGAIN == result) { |
| + | BIO_set_retry_read(bio); |
| + | nread = 0; |
| + | } |
| + | else { |
| + | nread = -1; |
| + | } |
| + | } |
| + | return (int)nread; |
| + | } |
| + | |
| + | static WOLFSSL_BIO_METHOD *bio_cf_method = NULL; |
| + | |
| + | static void bio_cf_init_methods(void) |
| + | { |
| + | bio_cf_method = wolfSSL_BIO_meth_new(BIO_TYPE_MEM, "wolfSSL CF BIO"); |
| + | wolfSSL_BIO_meth_set_write(bio_cf_method, &bio_cf_out_write); |
| + | wolfSSL_BIO_meth_set_read(bio_cf_method, &bio_cf_in_read); |
| + | wolfSSL_BIO_meth_set_ctrl(bio_cf_method, &bio_cf_ctrl); |
| + | wolfSSL_BIO_meth_set_create(bio_cf_method, &bio_cf_create); |
| + | wolfSSL_BIO_meth_set_destroy(bio_cf_method, &bio_cf_destroy); |
| + | } |
| + | |
| + | static void bio_cf_free_methods(void) |
| + | { |
| + | wolfSSL_BIO_meth_free(bio_cf_method); |
| + | } |
| + | |
| + | #else /* USE_BIO_CHAIN */ |
| + | |
| + | #define bio_cf_init_methods() Curl_nop_stmt |
| + | #define bio_cf_free_methods() Curl_nop_stmt |
| + | |
| + | #endif /* !USE_BIO_CHAIN */ |
| + | |
| /* | |
| * This function loads all the client/CA certificates and CRLs. Setup the TLS | |
| * layer and do all necessary magic. | |
| @@ -252,7 +392,6 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); | |
| const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); | |
| SSL_METHOD* req_method = NULL; | |
| - | curl_socket_t sockfd = cf->conn->sock[cf->sockindex]; |
| #ifdef HAVE_LIBOQS | |
| word16 oqsAlg = 0; | |
| size_t idx = 0; | |
| @@ -578,11 +717,24 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| Curl_ssl_sessionid_unlock(data); | |
| } | |
| + | #ifdef USE_BIO_CHAIN |
| + | { |
| + | WOLFSSL_BIO *bio; |
| + | |
| + | bio = BIO_new(bio_cf_method); |
| + | if(!bio) |
| + | return CURLE_OUT_OF_MEMORY; |
| + | |
| + | wolfSSL_BIO_set_data(bio, cf); |
| + | wolfSSL_set_bio(backend->handle, bio, bio); |
| + | } |
| + | #else /* USE_BIO_CHAIN */ |
| /* pass the raw socket into the SSL layer */ | |
| - | if(!SSL_set_fd(backend->handle, (int)sockfd)) { |
| + | if(!SSL_set_fd(backend->handle, (int)cf->conn->sock[cf->sockindex])) { |
| failf(data, "SSL: SSL_set_fd failed"); | |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| + | #endif /* !USE_BIO_CHAIN */ |
| connssl->connecting_state = ssl_connect_2; | |
| return CURLE_OK; | |
| @@ -642,7 +794,10 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) | |
| char error_buffer[WOLFSSL_MAX_ERROR_SZ]; | |
| int detail = SSL_get_error(backend->handle, ret); | |
| - | if(SSL_ERROR_WANT_READ == detail) { |
| + | if(backend->io_result != CURLE_OK && backend->io_result != CURLE_AGAIN) { |
| + | return backend->io_result; |
| + | } |
| + | else if(SSL_ERROR_WANT_READ == detail) { |
| connssl->connecting_state = ssl_connect_2_reading; | |
| return CURLE_OK; | |
| } | |
| @@ -870,6 +1025,10 @@ static ssize_t wolfssl_send(struct Curl_cfilter *cf, | |
| if(rc <= 0) { | |
| int err = SSL_get_error(backend->handle, rc); | |
| + | if(backend->io_result != CURLE_OK && backend->io_result != CURLE_AGAIN) { |
| + | *curlcode = backend->io_result; |
| + | return -1; |
| + | } |
| switch(err) { | |
| case SSL_ERROR_WANT_READ: | |
| case SSL_ERROR_WANT_WRITE: | |
| @@ -932,6 +1091,10 @@ static ssize_t wolfssl_recv(struct Curl_cfilter *cf, | |
| if(nread <= 0) { | |
| int err = SSL_get_error(backend->handle, nread); | |
| + | if(backend->io_result != CURLE_OK && backend->io_result != CURLE_AGAIN) { |
| + | *curlcode = backend->io_result; |
| + | return -1; |
| + | } |
| switch(err) { | |
| case SSL_ERROR_ZERO_RETURN: /* no more data */ | |
| break; | |
| @@ -972,15 +1135,20 @@ static size_t wolfssl_version(char *buffer, size_t size) | |
| static int wolfssl_init(void) | |
| { | |
| + | int ret; |
| + | |
| #ifdef OPENSSL_EXTRA | |
| Curl_tls_keylog_open(); | |
| #endif | |
| - | return (wolfSSL_Init() == SSL_SUCCESS); |
| + | ret = (wolfSSL_Init() == SSL_SUCCESS); |
| + | bio_cf_init_methods(); |
| + | return ret; |
| } | |
| static void wolfssl_cleanup(void) | |
| { | |
| + | bio_cf_free_methods(); |
| wolfSSL_Cleanup(); | |
| #ifdef OPENSSL_EXTRA | |
| Curl_tls_keylog_close(); | |
| @@ -1200,6 +1368,9 @@ const struct Curl_ssl Curl_ssl_wolfssl = { | |
| #ifdef KEEP_PEER_CERT | |
| SSLSUPP_PINNEDPUBKEY | | |
| + | #endif |
| + | #ifdef USE_BIO_CHAIN |
| + | SSLSUPP_HTTPS_PROXY | |
| #endif | |
| SSLSUPP_SSL_CTX, | |
| @@ -143,6 +143,15 @@ if test "x$OPT_WOLFSSL" != xno; then | |
| ] | |
| ) | |
| + | dnl if this symbol is present, we can make use of BIO filter chains |
| + | AC_CHECK_FUNC(wolfSSL_BIO_set_shutdown, |
| + | [ |
| + | AC_DEFINE(HAVE_WOLFSSL_FULL_BIO, 1, |
| + | [if you have wolfSSL_BIO_set_shutdown]) |
| + | WOLFSSL_FULL_BIO=1 |
| + | ] |
| + | ) |
| + | |
| if test -n "$wolfssllibpath"; then | |
| dnl when shared libs were found in a path that the run-time | |
| dnl linker doesn't search through, we need to add it to | |