diff options
Diffstat (limited to 'libs/libcurl/src')
114 files changed, 2899 insertions, 3584 deletions
diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt index 1d71e14904..911c9096dd 100644 --- a/libs/libcurl/src/CMakeLists.txt +++ b/libs/libcurl/src/CMakeLists.txt @@ -50,15 +50,6 @@ endif() # # strtoofft.c - specify later # ) -# # if we have Kerberos 4, right now this is never on -# #OPTION(CURL_KRB4 "Use Kerberos 4" OFF) -# IF(CURL_KRB4) -# SET(CSOURCES ${CSOURCES} -# krb4.c -# security.c -# ) -# ENDIF(CURL_KRB4) - # #OPTION(CURL_MALLOC_DEBUG "Debug mallocs in Curl" OFF) # MARK_AS_ADVANCED(CURL_MALLOC_DEBUG) # IF(CURL_MALLOC_DEBUG) diff --git a/libs/libcurl/src/Makefile.Watcom b/libs/libcurl/src/Makefile.Watcom deleted file mode 100644 index 6ea975b537..0000000000 --- a/libs/libcurl/src/Makefile.Watcom +++ /dev/null @@ -1,274 +0,0 @@ -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) 2005 - 2009, Gisle Vanem <gvanem@yahoo.no>. -# Copyright (C) 2005 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.haxx.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -#*************************************************************************** - -# -# Watcom / OpenWatcom / Win32 makefile for libcurl. -# - -.ERASE - -!if $(__VERSION__) < 1280 -!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!message ! This Open Watcom version is too old and is no longer supported ! -!message ! Please download latest version from www.openwatcom.org ! -!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!error Unsupported version of Open Watcom -!endif - -!ifndef %watcom -!error WATCOM environment variable not set! -!endif - -# In order to process Makefile.inc wmake must be called with -u switch! -!ifndef %MAKEFLAGS -!error You MUST call wmake with the -u switch! -!endif - -!ifdef %libname -LIBNAME = $(%libname) -!else -LIBNAME = libcurl -!endif -TARGETS = $(LIBNAME).dll $(LIBNAME).lib - -CC = wcc386 -LD = wlink -AR = wlib -RC = wrc - -!ifdef __LOADDLL__ -! loaddll wcc386 wccd386 -! loaddll wpp386 wppd386 -! loaddll wlib wlibd -! loaddll wlink wlinkd -!endif - -!ifdef __LINUX__ -CP = cp -MD = mkdir -p -!else -CP = copy 2>NUL -MD = mkdir -!endif -!if $(__VERSION__) > 1290 -RD = rm -rf -!else ifdef __UNIX__ -RD = rm -rf -!else -RD = rmdir /q /s 2>NUL -!endif - -SYS_INCL = -I"$(%watcom)/h/nt" -I"$(%watcom)/h" - -CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm & - -wcd=201 -bt=nt -d+ -dWIN32 & - -dBUILDING_LIBCURL -I. -I"../include" $(SYS_INCL) - -!ifdef %debug -DEBUG = -dDEBUG=1 -dDEBUGBUILD -CFLAGS += -d3 $(DEBUG) -!else -CFLAGS += -d0 -!endif - -!ifdef %use_ipv6 -CFLAGS += -d_WIN32_WINNT=0x0501 -dENABLE_IPV6 -!endif - -!ifdef %use_sspi -CFLAGS += -dUSE_WINDOWS_SSPI -!endif - -!ifdef %use_winssl -CFLAGS += -dUSE_WINDOWS_SSPI -CFLAGS += -DUSE_SCHANNEL -!endif - -!ifdef %use_winidn -CFLAGS += -dWINVER=0x0600 -dUSE_WIN32_IDN -! if $(__VERSION__) <= 1290 -CFLAGS += -dWANT_IDN_PROTOTYPES -! endif -!endif - -# -# Change to suite. -# -!ifdef %zlib_root -ZLIB_ROOT = $(%zlib_root) -!else -ZLIB_ROOT = ../../zlib-1.2.8 -!endif - -!ifdef %libssh2_root -LIBSSH2_ROOT = $(%libssh2_root) -!else -LIBSSH2_ROOT = ../../libssh2-1.5.0 -!endif - -!ifdef %librtmp_root -LIBRTMP_ROOT = $(%librtmp_root) -!else -LIBRTMP_ROOT = ../../rtmpdump-2.3 -!endif - -!ifdef %openssl_root -OPENSSL_ROOT = $(%openssl_root) -!else -OPENSSL_ROOT = ../../openssl-1.0.2a -!endif - -!ifdef %ares_root -ARES_ROOT = $(%ares_root) -!else -ARES_ROOT = ../ares -!endif - -!ifdef %use_zlib -CFLAGS += -dHAVE_ZLIB_H -dHAVE_LIBZ -I"$(ZLIB_ROOT)" -!endif - -!ifdef %use_rtmp -CFLAGS += -dUSE_LIBRTMP -I"$(LIBRTMP_ROOT)" -!endif - -!ifdef %use_ssh2 -CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H -I"$(LIBSSH2_ROOT)/include" -I"$(LIBSSH2_ROOT)/win32" -!endif - -!ifdef %use_ssl -CFLAGS += -wcd=138 -dUSE_OPENSSL -I"$(OPENSSL_ROOT)/inc32" -!endif - -!ifdef %use_ares -CFLAGS += -dUSE_ARES -I"$(ARES_ROOT)" -!endif - -!ifdef %use_watt32 -CFLAGS += -dUSE_WATT32 -I"$(%watt_root)/inc" -!endif - -OBJ_BASE = WC_Win32.obj -!if $(__VERSION__) > 1290 -OBJ_STAT = $(OBJ_BASE)/stat -OBJ_DYN = $(OBJ_BASE)/dyn -!else ifdef __UNIX__ -OBJ_STAT = $(OBJ_BASE)/stat -OBJ_DYN = $(OBJ_BASE)/dyn -!else -OBJ_STAT = $(OBJ_BASE)\stat -OBJ_DYN = $(OBJ_BASE)\dyn -!endif - -LINK_ARG = $(OBJ_DYN)/wlink.arg -LIB_ARG = $(OBJ_STAT)/wlib.arg - -!include Makefile.inc - -OBJS1 = ./$(CSOURCES:.c=.obj) -OBJS2 = $(OBJS1:vtls/=) -OBJS3 = $(OBJS2:vauth/=) -OBJS4 = $(OBJS3: = ./) -OBJS_STAT = $(OBJS4:./=$(OBJ_STAT)/) -OBJS_DYN = $(OBJS4:./=$(OBJ_DYN)/) - -RESOURCE = $(OBJ_DYN)/libcurl.res - -DIRS = $(OBJ_BASE) $(OBJ_BASE)/stat $(OBJ_BASE)/dyn - -.c : vauth vtls - -all: $(DIRS) $(TARGETS) .SYMBOLIC - @echo Welcome to libcurl - -clean: .SYMBOLIC - -rm -f $(OBJS_STAT) - -rm -f $(OBJS_DYN) - -rm -f $(RESOURCE) $(LINK_ARG) $(LIB_ARG) - -vclean distclean: clean .SYMBOLIC - -rm -f $(TARGETS) $(LIBNAME).map $(LIBNAME).sym - -$(RD) $(OBJ_STAT) - -$(RD) $(OBJ_DYN) - -$(RD) $(OBJ_BASE) - -$(DIRS): - -$(MD) $^@ - -$(LIBNAME).dll: $(OBJS_DYN) $(RESOURCE) $(__MAKEFILES__) - %create $(LINK_ARG) - @%append $(LINK_ARG) system nt dll -!ifdef %debug - @%append $(LINK_ARG) debug all - @%append $(LINK_ARG) option symfile -!endif - @%append $(LINK_ARG) option quiet, caseexact, eliminate - @%append $(LINK_ARG) option map=$(OBJ_DYN)/$(LIBNAME).map - @%append $(LINK_ARG) option implib=$(LIBNAME)_imp.lib - @%append $(LINK_ARG) option res=$(RESOURCE) - @for %f in ($(OBJS_DYN)) do @%append $(LINK_ARG) file %f - @%append $(LINK_ARG) library wldap32.lib -!ifdef %use_watt32 - @%append $(LINK_ARG) library '$(%watt_root)/lib/wattcpw_imp.lib' -!else - @%append $(LINK_ARG) library ws2_32.lib -!endif -!ifdef %use_zlib - @%append $(LINK_ARG) library '$(ZLIB_ROOT)/zlib.lib' -!endif -!ifdef %use_rtmp - @%append $(LINK_ARG) library '$(LIBRTMP_ROOT)/librtmp/librtmp.lib' -!endif -!ifdef %use_ssh2 - @%append $(LINK_ARG) library '$(LIBSSH2_ROOT)/win32/libssh2.lib' -!endif -!ifdef %use_ssl - @%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/libeay32.lib' - @%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/ssleay32.lib' -!endif -!ifdef %use_ares - @%append $(LINK_ARG) library '$(ARES_ROOT)/cares.lib' -!endif -!ifdef %use_winidn -! if $(__VERSION__) > 1290 - @%append $(LINK_ARG) library normaliz.lib -! else - @%append $(LINK_ARG) import '_IdnToAscii@20' 'NORMALIZ.DLL'.'IdnToAscii' - @%append $(LINK_ARG) import '_IdnToUnicode@20' 'NORMALIZ.DLL'.'IdnToUnicode' -! endif -!endif - $(LD) name $^@ @$(LINK_ARG) - -$(LIBNAME).lib: $(OBJS_STAT) - %create $(LIB_ARG) - @for %f in ($<) do @%append $(LIB_ARG) +- %f - $(AR) -q -b -c -pa $^@ @$(LIB_ARG) - -$(RESOURCE): libcurl.rc - $(RC) $(DEBUG) -q -r -zm -bt=nt -I"../include" $(SYS_INCL) $[@ -fo=$^@ - -.c{$(OBJ_DYN)}.obj: - $(CC) $(CFLAGS) -bd -br $[@ -fo=$^@ - -.c{$(OBJ_STAT)}.obj: - $(CC) $(CFLAGS) -DCURL_STATICLIB $[@ -fo=$^@ diff --git a/libs/libcurl/src/Makefile.am b/libs/libcurl/src/Makefile.am index f2886ec63c..78b068ffe1 100644 --- a/libs/libcurl/src/Makefile.am +++ b/libs/libcurl/src/Makefile.am @@ -27,7 +27,7 @@ EXTRA_DIST = Makefile.m32 config-win32.h config-win32ce.h \ config-plan9.h config-riscos.h config-mac.h curl_config.h.in \ makefile.dj config-dos.h libcurl.plist libcurl.rc config-amigaos.h \ makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h \ - config-os400.h setup-os400.h config-symbian.h Makefile.Watcom \ + config-os400.h setup-os400.h \ config-tpf.h mk-ca-bundle.pl mk-ca-bundle.vbs $(CMAKE_DIST) \ firefox-db2pem.sh config-vxworks.h Makefile.vxworks checksrc.pl \ setup-win32.h @@ -66,7 +66,7 @@ endif # Prevent LIBS from being used for all link targets LIBS = $(BLANK_AT_MAKETIME) -VERSIONINFO=-version-info 10:0:6 +VERSIONINFO=-version-info 11:0:7 # This flag accepts an argument of the form current[:revision[:age]]. So, # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to # 1. @@ -153,3 +153,6 @@ TIDY:=clang-tidy tidy: $(TIDY) $(CSOURCES) $(TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H + +optiontable: + perl optiontable.pl < $(top_srcdir)/include/curl/curl.h > easyoptions.c diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in index 3cdf666b3c..ca348fbaf5 100644 --- a/libs/libcurl/src/Makefile.in +++ b/libs/libcurl/src/Makefile.in @@ -215,20 +215,21 @@ am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \ libcurl_la-parsedate.lo libcurl_la-pingpong.lo \ libcurl_la-pop3.lo libcurl_la-progress.lo libcurl_la-psl.lo \ libcurl_la-doh.lo libcurl_la-rand.lo libcurl_la-rename.lo \ - libcurl_la-rtsp.lo libcurl_la-security.lo libcurl_la-select.lo \ - libcurl_la-sendf.lo libcurl_la-setopt.lo libcurl_la-sha256.lo \ - libcurl_la-share.lo libcurl_la-slist.lo libcurl_la-smb.lo \ - libcurl_la-smtp.lo libcurl_la-socketpair.lo \ - libcurl_la-socks.lo libcurl_la-socks_gssapi.lo \ - libcurl_la-socks_sspi.lo libcurl_la-speedcheck.lo \ - libcurl_la-splay.lo libcurl_la-strcase.lo libcurl_la-strdup.lo \ + libcurl_la-rtsp.lo libcurl_la-select.lo libcurl_la-sendf.lo \ + libcurl_la-setopt.lo libcurl_la-sha256.lo libcurl_la-share.lo \ + libcurl_la-slist.lo libcurl_la-smb.lo libcurl_la-smtp.lo \ + libcurl_la-socketpair.lo libcurl_la-socks.lo \ + libcurl_la-socks_gssapi.lo libcurl_la-socks_sspi.lo \ + libcurl_la-speedcheck.lo libcurl_la-splay.lo \ + libcurl_la-strcase.lo libcurl_la-strdup.lo \ libcurl_la-strerror.lo libcurl_la-strtok.lo \ libcurl_la-strtoofft.lo libcurl_la-system_win32.lo \ libcurl_la-telnet.lo libcurl_la-tftp.lo libcurl_la-timeval.lo \ libcurl_la-transfer.lo libcurl_la-urlapi.lo \ libcurl_la-version.lo libcurl_la-warnless.lo \ libcurl_la-wildcard.lo libcurl_la-x509asn1.lo \ - libcurl_la-dynbuf.lo libcurl_la-version_win32.lo + libcurl_la-dynbuf.lo libcurl_la-version_win32.lo \ + libcurl_la-easyoptions.lo libcurl_la-easygetopt.lo am__dirstamp = $(am__leading_dot)dirstamp am__objects_2 = vauth/libcurl_la-cleartext.lo vauth/libcurl_la-cram.lo \ vauth/libcurl_la-digest.lo vauth/libcurl_la-digest_sspi.lo \ @@ -303,22 +304,22 @@ am__objects_9 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \ libcurlu_la-pingpong.lo libcurlu_la-pop3.lo \ libcurlu_la-progress.lo libcurlu_la-psl.lo libcurlu_la-doh.lo \ libcurlu_la-rand.lo libcurlu_la-rename.lo libcurlu_la-rtsp.lo \ - libcurlu_la-security.lo libcurlu_la-select.lo \ - libcurlu_la-sendf.lo libcurlu_la-setopt.lo \ - libcurlu_la-sha256.lo libcurlu_la-share.lo \ - libcurlu_la-slist.lo libcurlu_la-smb.lo libcurlu_la-smtp.lo \ - libcurlu_la-socketpair.lo libcurlu_la-socks.lo \ - libcurlu_la-socks_gssapi.lo libcurlu_la-socks_sspi.lo \ - libcurlu_la-speedcheck.lo libcurlu_la-splay.lo \ - libcurlu_la-strcase.lo libcurlu_la-strdup.lo \ - libcurlu_la-strerror.lo libcurlu_la-strtok.lo \ - libcurlu_la-strtoofft.lo libcurlu_la-system_win32.lo \ - libcurlu_la-telnet.lo libcurlu_la-tftp.lo \ - libcurlu_la-timeval.lo libcurlu_la-transfer.lo \ - libcurlu_la-urlapi.lo libcurlu_la-version.lo \ - libcurlu_la-warnless.lo libcurlu_la-wildcard.lo \ - libcurlu_la-x509asn1.lo libcurlu_la-dynbuf.lo \ - libcurlu_la-version_win32.lo + libcurlu_la-select.lo libcurlu_la-sendf.lo \ + libcurlu_la-setopt.lo libcurlu_la-sha256.lo \ + libcurlu_la-share.lo libcurlu_la-slist.lo libcurlu_la-smb.lo \ + libcurlu_la-smtp.lo libcurlu_la-socketpair.lo \ + libcurlu_la-socks.lo libcurlu_la-socks_gssapi.lo \ + libcurlu_la-socks_sspi.lo libcurlu_la-speedcheck.lo \ + libcurlu_la-splay.lo libcurlu_la-strcase.lo \ + libcurlu_la-strdup.lo libcurlu_la-strerror.lo \ + libcurlu_la-strtok.lo libcurlu_la-strtoofft.lo \ + libcurlu_la-system_win32.lo libcurlu_la-telnet.lo \ + libcurlu_la-tftp.lo libcurlu_la-timeval.lo \ + libcurlu_la-transfer.lo libcurlu_la-urlapi.lo \ + libcurlu_la-version.lo libcurlu_la-warnless.lo \ + libcurlu_la-wildcard.lo libcurlu_la-x509asn1.lo \ + libcurlu_la-dynbuf.lo libcurlu_la-version_win32.lo \ + libcurlu_la-easyoptions.lo libcurlu_la-easygetopt.lo am__objects_10 = vauth/libcurlu_la-cleartext.lo \ vauth/libcurlu_la-cram.lo vauth/libcurlu_la-digest.lo \ vauth/libcurlu_la-digest_sspi.lo \ @@ -394,6 +395,8 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurl_la-dotdot.Plo \ ./$(DEPDIR)/libcurl_la-dynbuf.Plo \ ./$(DEPDIR)/libcurl_la-easy.Plo \ + ./$(DEPDIR)/libcurl_la-easygetopt.Plo \ + ./$(DEPDIR)/libcurl_la-easyoptions.Plo \ ./$(DEPDIR)/libcurl_la-escape.Plo \ ./$(DEPDIR)/libcurl_la-file.Plo \ ./$(DEPDIR)/libcurl_la-fileinfo.Plo \ @@ -443,7 +446,6 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurl_la-psl.Plo ./$(DEPDIR)/libcurl_la-rand.Plo \ ./$(DEPDIR)/libcurl_la-rename.Plo \ ./$(DEPDIR)/libcurl_la-rtsp.Plo \ - ./$(DEPDIR)/libcurl_la-security.Plo \ ./$(DEPDIR)/libcurl_la-select.Plo \ ./$(DEPDIR)/libcurl_la-sendf.Plo \ ./$(DEPDIR)/libcurl_la-setopt.Plo \ @@ -506,6 +508,8 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurlu_la-dotdot.Plo \ ./$(DEPDIR)/libcurlu_la-dynbuf.Plo \ ./$(DEPDIR)/libcurlu_la-easy.Plo \ + ./$(DEPDIR)/libcurlu_la-easygetopt.Plo \ + ./$(DEPDIR)/libcurlu_la-easyoptions.Plo \ ./$(DEPDIR)/libcurlu_la-escape.Plo \ ./$(DEPDIR)/libcurlu_la-file.Plo \ ./$(DEPDIR)/libcurlu_la-fileinfo.Plo \ @@ -557,7 +561,6 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurlu_la-rand.Plo \ ./$(DEPDIR)/libcurlu_la-rename.Plo \ ./$(DEPDIR)/libcurlu_la-rtsp.Plo \ - ./$(DEPDIR)/libcurlu_la-security.Plo \ ./$(DEPDIR)/libcurlu_la-select.Plo \ ./$(DEPDIR)/libcurlu_la-sendf.Plo \ ./$(DEPDIR)/libcurlu_la-setopt.Plo \ @@ -735,6 +738,7 @@ CURL_DISABLE_HTTP = @CURL_DISABLE_HTTP@ CURL_DISABLE_IMAP = @CURL_DISABLE_IMAP@ CURL_DISABLE_LDAP = @CURL_DISABLE_LDAP@ CURL_DISABLE_LDAPS = @CURL_DISABLE_LDAPS@ +CURL_DISABLE_MQTT = @CURL_DISABLE_MQTT@ CURL_DISABLE_POP3 = @CURL_DISABLE_POP3@ CURL_DISABLE_PROXY = @CURL_DISABLE_PROXY@ CURL_DISABLE_RTSP = @CURL_DISABLE_RTSP@ @@ -742,7 +746,6 @@ CURL_DISABLE_SMB = @CURL_DISABLE_SMB@ CURL_DISABLE_SMTP = @CURL_DISABLE_SMTP@ CURL_DISABLE_TELNET = @CURL_DISABLE_TELNET@ CURL_DISABLE_TFTP = @CURL_DISABLE_TFTP@ -CURL_ENABLE_MQTT = @CURL_ENABLE_MQTT@ CURL_LT_SHLIB_VERSIONED_FLAVOUR = @CURL_LT_SHLIB_VERSIONED_FLAVOUR@ CURL_NETWORK_AND_TIME_LIBS = @CURL_NETWORK_AND_TIME_LIBS@ CURL_NETWORK_LIBS = @CURL_NETWORK_LIBS@ @@ -944,7 +947,7 @@ EXTRA_DIST = Makefile.m32 config-win32.h config-win32ce.h \ config-plan9.h config-riscos.h config-mac.h curl_config.h.in \ makefile.dj config-dos.h libcurl.plist libcurl.rc config-amigaos.h \ makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h \ - config-os400.h setup-os400.h config-symbian.h Makefile.Watcom \ + config-os400.h setup-os400.h \ config-tpf.h mk-ca-bundle.pl mk-ca-bundle.vbs $(CMAKE_DIST) \ firefox-db2pem.sh config-vxworks.h Makefile.vxworks checksrc.pl \ setup-win32.h @@ -977,7 +980,7 @@ lib_LTLIBRARIES = libcurl.la # For the full guide on libcurl ABI rules, see docs/libcurl/ABI AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/lib \ -I$(top_srcdir)/lib $(am__append_1) -DBUILDING_LIBCURL -VERSIONINFO = -version-info 10:0:6 +VERSIONINFO = -version-info 11:0:7 AM_LDFLAGS = AM_CFLAGS = libcurl_la_CPPFLAGS_EXTRA = $(am__append_7) $(am__append_8) @@ -1021,19 +1024,19 @@ LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c \ http_ntlm.c http_proxy.c idn_win32.c if2ip.c imap.c inet_ntop.c inet_pton.c \ krb5.c ldap.c llist.c md4.c md5.c memdebug.c mime.c mprintf.c mqtt.c \ multi.c netrc.c non-ascii.c nonblock.c openldap.c parsedate.c pingpong.c \ - pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c security.c select.c \ + pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c select.c \ sendf.c setopt.c sha256.c share.c slist.c smb.c smtp.c socketpair.c socks.c \ socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c strdup.c \ strerror.c strtok.c strtoofft.c system_win32.c telnet.c tftp.c timeval.c \ transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c \ - version_win32.c + version_win32.c easyoptions.c easygetopt.c LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \ content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h \ curl_des.h curl_endian.h curl_fnmatch.h curl_get_line.h curl_gethostname.h \ curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memory.h \ curl_memrchr.h curl_multibyte.h curl_ntlm_core.h curl_ntlm_wb.h curl_path.h \ - curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_sec.h curl_setup.h \ + curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_krb5.h curl_setup.h \ curl_setup_once.h curl_sha256.h curl_sspi.h curl_threads.h curlx.h dict.h \ dotdot.h easyif.h escape.h file.h fileinfo.h formdata.h ftp.h url.h \ ftplistparser.h getinfo.h gopher.h hash.h hostcheck.h hostip.h http.h \ @@ -1045,7 +1048,7 @@ LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \ smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \ strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h \ timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h \ - x509asn1.h dynbuf.h version_win32.h + x509asn1.h dynbuf.h version_win32.h easyoptions.h LIB_RCFILES = libcurl.rc CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \ @@ -1369,6 +1372,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dotdot.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dynbuf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-easy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-easygetopt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-easyoptions.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-escape.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-file.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-fileinfo.Plo@am__quote@ # am--include-marker @@ -1420,7 +1425,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-rand.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-rename.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-rtsp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-security.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-select.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-sendf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-setopt.Plo@am__quote@ # am--include-marker @@ -1484,6 +1488,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dotdot.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dynbuf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-easy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-easygetopt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-easyoptions.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-escape.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-file.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-fileinfo.Plo@am__quote@ # am--include-marker @@ -1535,7 +1541,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-rand.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-rename.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-rtsp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-security.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-select.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-sendf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-setopt.Plo@am__quote@ # am--include-marker @@ -2243,13 +2248,6 @@ libcurl_la-rtsp.lo: rtsp.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-rtsp.lo `test -f 'rtsp.c' || echo '$(srcdir)/'`rtsp.c -libcurl_la-security.lo: security.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-security.lo -MD -MP -MF $(DEPDIR)/libcurl_la-security.Tpo -c -o libcurl_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-security.Tpo $(DEPDIR)/libcurl_la-security.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='security.c' object='libcurl_la-security.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c - libcurl_la-select.lo: select.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-select.lo -MD -MP -MF $(DEPDIR)/libcurl_la-select.Tpo -c -o libcurl_la-select.lo `test -f 'select.c' || echo '$(srcdir)/'`select.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-select.Tpo $(DEPDIR)/libcurl_la-select.Plo @@ -2467,6 +2465,20 @@ libcurl_la-version_win32.lo: version_win32.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-version_win32.lo `test -f 'version_win32.c' || echo '$(srcdir)/'`version_win32.c +libcurl_la-easyoptions.lo: easyoptions.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-easyoptions.lo -MD -MP -MF $(DEPDIR)/libcurl_la-easyoptions.Tpo -c -o libcurl_la-easyoptions.lo `test -f 'easyoptions.c' || echo '$(srcdir)/'`easyoptions.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-easyoptions.Tpo $(DEPDIR)/libcurl_la-easyoptions.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='easyoptions.c' object='libcurl_la-easyoptions.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-easyoptions.lo `test -f 'easyoptions.c' || echo '$(srcdir)/'`easyoptions.c + +libcurl_la-easygetopt.lo: easygetopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-easygetopt.lo -MD -MP -MF $(DEPDIR)/libcurl_la-easygetopt.Tpo -c -o libcurl_la-easygetopt.lo `test -f 'easygetopt.c' || echo '$(srcdir)/'`easygetopt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-easygetopt.Tpo $(DEPDIR)/libcurl_la-easygetopt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='easygetopt.c' object='libcurl_la-easygetopt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-easygetopt.lo `test -f 'easygetopt.c' || echo '$(srcdir)/'`easygetopt.c + vauth/libcurl_la-cleartext.lo: vauth/cleartext.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-cleartext.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-cleartext.Tpo -c -o vauth/libcurl_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-cleartext.Tpo vauth/$(DEPDIR)/libcurl_la-cleartext.Plo @@ -3272,13 +3284,6 @@ libcurlu_la-rtsp.lo: rtsp.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-rtsp.lo `test -f 'rtsp.c' || echo '$(srcdir)/'`rtsp.c -libcurlu_la-security.lo: security.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-security.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-security.Tpo -c -o libcurlu_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-security.Tpo $(DEPDIR)/libcurlu_la-security.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='security.c' object='libcurlu_la-security.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c - libcurlu_la-select.lo: select.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-select.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-select.Tpo -c -o libcurlu_la-select.lo `test -f 'select.c' || echo '$(srcdir)/'`select.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-select.Tpo $(DEPDIR)/libcurlu_la-select.Plo @@ -3496,6 +3501,20 @@ libcurlu_la-version_win32.lo: version_win32.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-version_win32.lo `test -f 'version_win32.c' || echo '$(srcdir)/'`version_win32.c +libcurlu_la-easyoptions.lo: easyoptions.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-easyoptions.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-easyoptions.Tpo -c -o libcurlu_la-easyoptions.lo `test -f 'easyoptions.c' || echo '$(srcdir)/'`easyoptions.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-easyoptions.Tpo $(DEPDIR)/libcurlu_la-easyoptions.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='easyoptions.c' object='libcurlu_la-easyoptions.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-easyoptions.lo `test -f 'easyoptions.c' || echo '$(srcdir)/'`easyoptions.c + +libcurlu_la-easygetopt.lo: easygetopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-easygetopt.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-easygetopt.Tpo -c -o libcurlu_la-easygetopt.lo `test -f 'easygetopt.c' || echo '$(srcdir)/'`easygetopt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-easygetopt.Tpo $(DEPDIR)/libcurlu_la-easygetopt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='easygetopt.c' object='libcurlu_la-easygetopt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-easygetopt.lo `test -f 'easygetopt.c' || echo '$(srcdir)/'`easygetopt.c + vauth/libcurlu_la-cleartext.lo: vauth/cleartext.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-cleartext.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-cleartext.Tpo -c -o vauth/libcurlu_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-cleartext.Tpo vauth/$(DEPDIR)/libcurlu_la-cleartext.Plo @@ -3899,6 +3918,8 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurl_la-dotdot.Plo -rm -f ./$(DEPDIR)/libcurl_la-dynbuf.Plo -rm -f ./$(DEPDIR)/libcurl_la-easy.Plo + -rm -f ./$(DEPDIR)/libcurl_la-easygetopt.Plo + -rm -f ./$(DEPDIR)/libcurl_la-easyoptions.Plo -rm -f ./$(DEPDIR)/libcurl_la-escape.Plo -rm -f ./$(DEPDIR)/libcurl_la-file.Plo -rm -f ./$(DEPDIR)/libcurl_la-fileinfo.Plo @@ -3950,7 +3971,6 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurl_la-rand.Plo -rm -f ./$(DEPDIR)/libcurl_la-rename.Plo -rm -f ./$(DEPDIR)/libcurl_la-rtsp.Plo - -rm -f ./$(DEPDIR)/libcurl_la-security.Plo -rm -f ./$(DEPDIR)/libcurl_la-select.Plo -rm -f ./$(DEPDIR)/libcurl_la-sendf.Plo -rm -f ./$(DEPDIR)/libcurl_la-setopt.Plo @@ -4014,6 +4034,8 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurlu_la-dotdot.Plo -rm -f ./$(DEPDIR)/libcurlu_la-dynbuf.Plo -rm -f ./$(DEPDIR)/libcurlu_la-easy.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-easygetopt.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-easyoptions.Plo -rm -f ./$(DEPDIR)/libcurlu_la-escape.Plo -rm -f ./$(DEPDIR)/libcurlu_la-file.Plo -rm -f ./$(DEPDIR)/libcurlu_la-fileinfo.Plo @@ -4065,7 +4087,6 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurlu_la-rand.Plo -rm -f ./$(DEPDIR)/libcurlu_la-rename.Plo -rm -f ./$(DEPDIR)/libcurlu_la-rtsp.Plo - -rm -f ./$(DEPDIR)/libcurlu_la-security.Plo -rm -f ./$(DEPDIR)/libcurlu_la-select.Plo -rm -f ./$(DEPDIR)/libcurlu_la-sendf.Plo -rm -f ./$(DEPDIR)/libcurlu_la-setopt.Plo @@ -4238,6 +4259,8 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurl_la-dotdot.Plo -rm -f ./$(DEPDIR)/libcurl_la-dynbuf.Plo -rm -f ./$(DEPDIR)/libcurl_la-easy.Plo + -rm -f ./$(DEPDIR)/libcurl_la-easygetopt.Plo + -rm -f ./$(DEPDIR)/libcurl_la-easyoptions.Plo -rm -f ./$(DEPDIR)/libcurl_la-escape.Plo -rm -f ./$(DEPDIR)/libcurl_la-file.Plo -rm -f ./$(DEPDIR)/libcurl_la-fileinfo.Plo @@ -4289,7 +4312,6 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurl_la-rand.Plo -rm -f ./$(DEPDIR)/libcurl_la-rename.Plo -rm -f ./$(DEPDIR)/libcurl_la-rtsp.Plo - -rm -f ./$(DEPDIR)/libcurl_la-security.Plo -rm -f ./$(DEPDIR)/libcurl_la-select.Plo -rm -f ./$(DEPDIR)/libcurl_la-sendf.Plo -rm -f ./$(DEPDIR)/libcurl_la-setopt.Plo @@ -4353,6 +4375,8 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurlu_la-dotdot.Plo -rm -f ./$(DEPDIR)/libcurlu_la-dynbuf.Plo -rm -f ./$(DEPDIR)/libcurlu_la-easy.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-easygetopt.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-easyoptions.Plo -rm -f ./$(DEPDIR)/libcurlu_la-escape.Plo -rm -f ./$(DEPDIR)/libcurlu_la-file.Plo -rm -f ./$(DEPDIR)/libcurlu_la-fileinfo.Plo @@ -4404,7 +4428,6 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurlu_la-rand.Plo -rm -f ./$(DEPDIR)/libcurlu_la-rename.Plo -rm -f ./$(DEPDIR)/libcurlu_la-rtsp.Plo - -rm -f ./$(DEPDIR)/libcurlu_la-security.Plo -rm -f ./$(DEPDIR)/libcurlu_la-select.Plo -rm -f ./$(DEPDIR)/libcurlu_la-sendf.Plo -rm -f ./$(DEPDIR)/libcurlu_la-setopt.Plo @@ -4549,6 +4572,9 @@ checksrc: tidy: $(TIDY) $(CSOURCES) $(TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H +optiontable: + perl optiontable.pl < $(top_srcdir)/include/curl/curl.h > easyoptions.c + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc index ae3f961cf9..a2fd57a831 100644 --- a/libs/libcurl/src/Makefile.inc +++ b/libs/libcurl/src/Makefile.inc @@ -56,19 +56,19 @@ LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c \ http_ntlm.c http_proxy.c idn_win32.c if2ip.c imap.c inet_ntop.c inet_pton.c \ krb5.c ldap.c llist.c md4.c md5.c memdebug.c mime.c mprintf.c mqtt.c \ multi.c netrc.c non-ascii.c nonblock.c openldap.c parsedate.c pingpong.c \ - pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c security.c select.c \ + pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c select.c \ sendf.c setopt.c sha256.c share.c slist.c smb.c smtp.c socketpair.c socks.c \ socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c strdup.c \ strerror.c strtok.c strtoofft.c system_win32.c telnet.c tftp.c timeval.c \ transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c \ - version_win32.c + version_win32.c easyoptions.c easygetopt.c LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \ content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h \ curl_des.h curl_endian.h curl_fnmatch.h curl_get_line.h curl_gethostname.h \ curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memory.h \ curl_memrchr.h curl_multibyte.h curl_ntlm_core.h curl_ntlm_wb.h curl_path.h \ - curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_sec.h curl_setup.h \ + curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_krb5.h curl_setup.h \ curl_setup_once.h curl_sha256.h curl_sspi.h curl_threads.h curlx.h dict.h \ dotdot.h easyif.h escape.h file.h fileinfo.h formdata.h ftp.h url.h \ ftplistparser.h getinfo.h gopher.h hash.h hostcheck.h hostip.h http.h \ @@ -80,7 +80,7 @@ LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \ smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \ strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h \ timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h \ - x509asn1.h dynbuf.h version_win32.h + x509asn1.h dynbuf.h version_win32.h easyoptions.h LIB_RCFILES = libcurl.rc diff --git a/libs/libcurl/src/Makefile.m32 b/libs/libcurl/src/Makefile.m32 index 02b31106c6..37887eed5d 100644 --- a/libs/libcurl/src/Makefile.m32 +++ b/libs/libcurl/src/Makefile.m32 @@ -298,7 +298,12 @@ endif ifdef ZSTD INCLUDES += -I"$(ZSTD_PATH)/include" CFLAGS += -DHAVE_ZSTD - DLL_LIBS += -L"$(ZSTD_PATH)/lib" -lzstd + DLL_LIBS += -L"$(ZSTD_PATH)/lib" + ifdef ZSTD_LIBS + DLL_LIBS += $(ZSTD_LIBS) + else + DLL_LIBS += -lzstd + endif endif ifdef BROTLI INCLUDES += -I"$(BROTLI_PATH)/include" diff --git a/libs/libcurl/src/altsvc.c b/libs/libcurl/src/altsvc.c index c2ec489d9e..d3deba3e83 100644 --- a/libs/libcurl/src/altsvc.c +++ b/libs/libcurl/src/altsvc.c @@ -302,11 +302,12 @@ CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl) * Curl_altsvc_cleanup() frees an altsvc cache instance and all associated * resources. */ -void Curl_altsvc_cleanup(struct altsvcinfo *altsvc) +void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp) { - struct curl_llist_element *e; - struct curl_llist_element *n; - if(altsvc) { + struct Curl_llist_element *e; + struct Curl_llist_element *n; + if(*altsvcp) { + struct altsvcinfo *altsvc = *altsvcp; for(e = altsvc->list.head; e; e = n) { struct altsvc *as = e->ptr; n = e->next; @@ -314,6 +315,7 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc) } free(altsvc->filename); free(altsvc); + *altsvcp = NULL; /* clear the pointer */ } } @@ -323,8 +325,8 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc) CURLcode Curl_altsvc_save(struct Curl_easy *data, struct altsvcinfo *altsvc, const char *file) { - struct curl_llist_element *e; - struct curl_llist_element *n; + struct Curl_llist_element *e; + struct Curl_llist_element *n; CURLcode result = CURLE_OK; FILE *out; char *tempstore; @@ -399,8 +401,8 @@ static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen) static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid, const char *srchost, unsigned short srcport) { - struct curl_llist_element *e; - struct curl_llist_element *n; + struct Curl_llist_element *e; + struct Curl_llist_element *n; for(e = asi->list.head; e; e = n) { struct altsvc *as = e->ptr; n = e->next; @@ -612,8 +614,8 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi, struct altsvc **dstentry, const int versions) /* one or more bits */ { - struct curl_llist_element *e; - struct curl_llist_element *n; + struct Curl_llist_element *e; + struct Curl_llist_element *n; time_t now = time(NULL); DEBUGASSERT(asi); DEBUGASSERT(srchost); diff --git a/libs/libcurl/src/altsvc.h b/libs/libcurl/src/altsvc.h index 578a4fbfb0..1aeb625ab4 100644 --- a/libs/libcurl/src/altsvc.h +++ b/libs/libcurl/src/altsvc.h @@ -46,12 +46,12 @@ struct altsvc { time_t expires; bool persist; int prio; - struct curl_llist_element node; + struct Curl_llist_element node; }; struct altsvcinfo { char *filename; - struct curl_llist list; /* list of entries */ + struct Curl_llist list; /* list of entries */ long flags; /* the publicly set bitmask */ }; @@ -61,7 +61,7 @@ CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file); CURLcode Curl_altsvc_save(struct Curl_easy *data, struct altsvcinfo *asi, const char *file); CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl); -void Curl_altsvc_cleanup(struct altsvcinfo *altsvc); +void Curl_altsvc_cleanup(struct altsvcinfo **altsvc); CURLcode Curl_altsvc_parse(struct Curl_easy *data, struct altsvcinfo *altsvc, const char *value, enum alpnid srcalpn, const char *srchost, @@ -74,5 +74,6 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi, #else /* disabled */ #define Curl_altsvc_save(a,b,c) +#define Curl_altsvc_cleanup(x) #endif /* CURL_DISABLE_HTTP || USE_ALTSVC */ #endif /* HEADER_CURL_ALTSVC_H */ diff --git a/libs/libcurl/src/asyn-ares.c b/libs/libcurl/src/asyn-ares.c index e65150744c..725d6cd5c8 100644 --- a/libs/libcurl/src/asyn-ares.c +++ b/libs/libcurl/src/asyn-ares.c @@ -67,8 +67,8 @@ #include "select.h" #include "progress.h" -# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ - (defined(WIN32) || defined(__SYMBIAN32__)) +# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ + defined(WIN32) # define CARES_STATICLIB # endif # include <ares.h> diff --git a/libs/libcurl/src/base64.c b/libs/libcurl/src/base64.c index 643cef6251..ec632e6f7a 100644 --- a/libs/libcurl/src/base64.c +++ b/libs/libcurl/src/base64.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,6 +26,9 @@ #if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \ !defined(CURL_DISABLE_LDAP) || \ + !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_POP3) || \ + !defined(CURL_DISABLE_IMAP) || \ !defined(CURL_DISABLE_DOH) || defined(USE_SSL) #include "urldata.h" /* for the Curl_easy definition */ diff --git a/libs/libcurl/src/checksrc.pl b/libs/libcurl/src/checksrc.pl index 498da94bbc..78b9cef5bd 100644 --- a/libs/libcurl/src/checksrc.pl +++ b/libs/libcurl/src/checksrc.pl @@ -52,7 +52,7 @@ my %warnings_extended = ( my %warnings = ( 'LONGLINE' => "Line longer than $max_column", 'TABS' => 'TAB characters not allowed', - 'TRAILINGSPACE' => 'Trailing white space on the line', + 'TRAILINGSPACE' => 'Trailing whitespace on the line', 'CPPCOMMENTS' => '// comment detected', 'SPACEBEFOREPAREN' => 'space before an open parenthesis', 'SPACEAFTERPAREN' => 'space after open parenthesis', @@ -82,6 +82,9 @@ my %warnings = ( 'SNPRINTF' => 'use of snprintf', 'ONELINECONDITION' => 'conditional block on the same line as the if()', 'TYPEDEFSTRUCT' => 'typedefed struct', + 'DOBRACE' => 'A single space between do and open brace', + 'BRACEWHILE' => 'A single space between open brace and while', + 'EXCLAMATIONSPACE' => 'Whitespace after exclamation mark in expression', ); sub readskiplist { @@ -397,7 +400,7 @@ sub scanfile { checkwarn("TABS", $line, length($1), $file, $l, "Contains TAB character", 1); } - # detect trailing white space + # detect trailing whitespace if($l =~ /^(.*)[ \t]+\z/) { checkwarn("TRAILINGSPACE", $line, length($1), $file, $l, "Trailing whitespace"); @@ -439,7 +442,7 @@ sub scanfile { # crude attempt to detect // comments without too many false # positives - if($l =~ /^([^"\*]*)[^:"]\/\//) { + if($l =~ /^(([^"\*]*)[^:"]|)\/\//) { checkwarn("CPPCOMMENTS", $line, length($1), $file, $l, "\/\/ comment"); } @@ -468,6 +471,14 @@ sub scanfile { } } + # check spaces in 'do {' + if($nostr =~ /^( *)do( *)\{/ && length($2) != 1) { + checkwarn("DOBRACE", $line, length($1) + 2, $file, $l, "one space after do before brace"); + } + # check spaces in 'do {' + elsif($nostr =~ /^( *)\}( *)while/ && length($2) != 1) { + checkwarn("BRACEWHILE", $line, length($1) + 2, $file, $l, "one space between brace and while"); + } if($nostr =~ /^((.*\s)(if) *\()(.*)\)(.*)/) { my $pos = length($1); my $postparen = $5; @@ -715,6 +726,12 @@ sub scanfile { "typedef'ed struct"); } + if($nostr =~ /(.*)! +(\w|\()/) { + checkwarn("EXCLAMATIONSPACE", + $line, length($1)+1, $file, $ol, + "space after exclamation mark"); + } + # check for more than one consecutive space before open brace or # question mark. Skip lines containing strings since they make it hard # due to artificially getting multiple spaces diff --git a/libs/libcurl/src/config-symbian.h b/libs/libcurl/src/config-symbian.h deleted file mode 100644 index 7f17dce252..0000000000 --- a/libs/libcurl/src/config-symbian.h +++ /dev/null @@ -1,793 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_SYMBIAN_H -#define HEADER_CURL_CONFIG_SYMBIAN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for Symbian */ -/* ================================================================ */ - -/* Location of default ca bundle */ -/* #define CURL_CA_BUNDLE "/etc/pki/tls/certs/ca-bundle.crt"*/ - -/* Location of default ca path */ -/* #undef CURL_CA_PATH */ - -/* to disable cookies support */ -/* #undef CURL_DISABLE_COOKIES */ - -/* to disable cryptographic authentication */ -/* #undef CURL_DISABLE_CRYPTO_AUTH */ - -/* to disable DICT */ -/* #undef CURL_DISABLE_DICT */ - -/* to disable FILE */ -/* #undef CURL_DISABLE_FILE */ - -/* to disable FTP */ -/* #undef CURL_DISABLE_FTP */ - -/* to disable HTTP */ -/* #undef CURL_DISABLE_HTTP */ - -/* to disable LDAP */ -#define CURL_DISABLE_LDAP 1 - -/* to disable LDAPS */ -#define CURL_DISABLE_LDAPS 1 - -/* to disable TELNET */ -/* #undef CURL_DISABLE_TELNET */ - -/* to disable TFTP */ -/* #undef CURL_DISABLE_TFTP */ - -/* to disable verbose strings */ -/* #define CURL_DISABLE_VERBOSE_STRINGS 1*/ - -/* Definition to make a library symbol externally visible. */ -/* #undef CURL_EXTERN_SYMBOL */ - -/* Use Windows LDAP implementation */ -/* #undef USE_WIN32_LDAP */ - -/* your Entropy Gathering Daemon socket pathname */ -/* #undef EGD_SOCKET */ - -/* Define if you want to enable IPv6 support */ -#define ENABLE_IPV6 1 - -/* Define if struct sockaddr_in6 has the sin6_scope_id member */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 size_t - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - -/* Define to 1 if you have the <alloca.h> header file. */ -/*#define HAVE_ALLOCA_H 1*/ - -/* Define to 1 if you have the <arpa/inet.h> header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the <arpa/tftp.h> header file. */ -/*#define HAVE_ARPA_TFTP_H 1*/ - -/* Define to 1 if you have the <assert.h> header file. */ -#define HAVE_ASSERT_H 1 - -/* Define to 1 if you have the `basename' function. */ -/*#define HAVE_BASENAME 1*/ - -/* Define to 1 if bool is an available type. */ -/*#define HAVE_BOOL_T 1*/ - -/* Define to 1 if you have the `closesocket' function. */ -/* #undef HAVE_CLOSESOCKET */ - -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ -/*#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1*/ - -/* Define to 1 if you have the <crypto.h> header file. */ -/* #undef HAVE_CRYPTO_H */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the <err.h> header file. */ -#define HAVE_ERR_H 1 - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the fcntl function. */ -#define HAVE_FCNTL 1 - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#define HAVE_FCNTL_O_NONBLOCK 1 - -/* Define to 1 if you have the `fork' function. */ -/*#define HAVE_FORK 1*/ - -/* Define to 1 if you have the `ftruncate' function. */ -#define HAVE_FTRUNCATE 1 - -/* Define if getaddrinfo exists and works */ -#define HAVE_GETADDRINFO 1 - -/* Define to 1 if you have the `geteuid' function. */ -#define HAVE_GETEUID 1 - -/* Define to 1 if you have the `gethostbyaddr' function. */ -#define HAVE_GETHOSTBYADDR 1 - -/* If you have gethostbyname */ -#define HAVE_GETHOSTBYNAME 1 - -/* Define to 1 if you have the `gethostbyname_r' function. */ -/* #undef HAVE_GETHOSTBYNAME_R */ - -/* gethostbyname_r() takes 3 args */ -/* #undef HAVE_GETHOSTBYNAME_R_3 */ - -/* gethostbyname_r() takes 5 args */ -/* #undef HAVE_GETHOSTBYNAME_R_5 */ - -/* gethostbyname_r() takes 6 args */ -/* #undef HAVE_GETHOSTBYNAME_R_6 */ - -/* Define to 1 if you have the getnameinfo function. */ -#define HAVE_GETNAMEINFO 1 - -/* Define to 1 if you have the `getpass_r' function. */ -/* #undef HAVE_GETPASS_R */ - -/* Define to 1 if you have the `getppid' function. */ -#define HAVE_GETPPID 1 - -/* Define to 1 if you have the `getprotobyname' function. */ -#define HAVE_GETPROTOBYNAME 1 - -/* Define to 1 if you have the `getpwuid' function. */ -#define HAVE_GETPWUID 1 - -/* Define to 1 if you have the `getrlimit' function. */ -/*#define HAVE_GETRLIMIT 1*/ - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* we have a glibc-style strerror_r() */ -/* #undef HAVE_GLIBC_STRERROR_R */ - -/* Define to 1 if you have the `gmtime_r' function. */ -#define HAVE_GMTIME_R 1 - -/* if you have the gssapi libraries */ -/* #undef HAVE_GSSAPI */ - -/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */ - -/* Define to 1 if you have the <gssapi/gssapi.h> header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_H */ - -/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */ - -/* if you have the GNU gssapi libraries */ -/* #undef HAVE_GSSGNU */ - -/* if you have the Heimdal gssapi libraries */ -/* #undef HAVE_GSSHEIMDAL */ - -/* if you have the MIT gssapi libraries */ -/* #undef HAVE_GSSMIT */ - -/* Define to 1 if you have the `idna_strerror' function. */ -/*#define HAVE_IDNA_STRERROR 1*/ - -/* Define to 1 if you have the `idn_free' function. */ -/*#define HAVE_IDN_FREE 1*/ - -/* Define to 1 if you have the <idn-free.h> header file. */ -/*#define HAVE_IDN_FREE_H 1*/ - -/* Define to 1 if you have the `inet_addr' function. */ -/*#define HAVE_INET_ADDR 1*/ - -/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -/*#define HAVE_INET_NTOP 1*/ - -/* Define to 1 if you have a IPv6 capable working inet_pton function. */ -/*#define HAVE_INET_PTON 1*/ - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the ioctl function. */ -#define HAVE_IOCTL 1 - -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#define HAVE_IOCTL_FIONBIO 1 - -/* Define to 1 if you have the ioctlsocket function. */ -/* #undef HAVE_IOCTLSOCKET */ - -/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -/* #undef HAVE_IOCTLSOCKET_FIONBIO */ - -/* Define to 1 if you have the IoctlSocket camel case function. */ -/* #undef HAVE_IOCTLSOCKET_CAMEL */ - -/* Define to 1 if you have a working IoctlSocket camel case FIONBIO - function. */ -/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ - -/* Define to 1 if you have the <io.h> header file. */ -/* #undef HAVE_IO_H */ - -/* if you have the Kerberos4 libraries (including -ldes) */ -/* #undef HAVE_KRB4 */ - -/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ -/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */ - -/* Define to 1 if you have the <krb.h> header file. */ -/* #undef HAVE_KRB_H */ - -/* Define to 1 if you have the lber.h header file. */ -/*#define HAVE_LBER_H 1*/ - -/* Define to 1 if you have the ldapssl.h header file. */ -/* #undef HAVE_LDAPSSL_H */ - -/* Define to 1 if you have the ldap.h header file. */ -/*#define HAVE_LDAP_H 1*/ - -/* Use LDAPS implementation */ -/*#define HAVE_LDAP_SSL 1*/ - -/* Define to 1 if you have the ldap_ssl.h header file. */ -/* #undef HAVE_LDAP_SSL_H */ - -/* Define to 1 if you have the `ldap_url_parse' function. */ -/*#define HAVE_LDAP_URL_PARSE 1*/ - -/* Define to 1 if you have the <libgen.h> header file. */ -/*#define HAVE_LIBGEN_H 1*/ - -/* Define to 1 if you have the `idn' library (-lidn). */ -/*#define HAVE_LIBIDN 1*/ - -/* Define to 1 if you have the `resolv' library (-lresolv). */ -/* #undef HAVE_LIBRESOLV */ - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -/* #undef HAVE_LIBRESOLVE */ - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the `ssh2' library (-lssh2). */ -/*#define HAVE_LIBSSH2 1*/ - -/* Define to 1 if you have the <libssh2.h> header file. */ -/*#define HAVE_LIBSSH2_H 1*/ - -/* if your compiler supports LL */ -#define HAVE_LL 1 - -/* Define to 1 if you have the <locale.h> header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you have the `localtime_r' function. */ -#define HAVE_LOCALTIME_R 1 - -/* Define to 1 if the compiler supports the 'long long' data type. */ -#define HAVE_LONGLONG 1 - -/* Define to 1 if you have the malloc.h header file. */ -/*#define HAVE_MALLOC_H 1*/ - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the MSG_NOSIGNAL flag. */ -/*#define HAVE_MSG_NOSIGNAL 1*/ - -/* Define to 1 if you have the <netdb.h> header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the <netinet/in.h> header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the <netinet/tcp.h> header file. */ -/*#define HAVE_NETINET_TCP_H 1*/ - -/* Define to 1 if you have the <net/if.h> header file. */ -#define HAVE_NET_IF_H 1 - -/* Define to 1 if NI_WITHSCOPEID exists and works. */ -/*#define HAVE_NI_WITHSCOPEID 1*/ - -/* we have no strerror_r() proto */ -/* #undef HAVE_NO_STRERROR_R_DECL */ - -/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE - */ -/* #undef HAVE_OLD_GSSMIT */ - -/* Define to 1 if you have the <openssl/crypto.h> header file. */ -/*#define HAVE_OPENSSL_CRYPTO_H 1*/ - -/* Define to 1 if you have the <openssl/err.h> header file. */ -/*#define HAVE_OPENSSL_ERR_H 1*/ - -/* Define to 1 if you have the <openssl/pem.h> header file. */ -/*#define HAVE_OPENSSL_PEM_H 1*/ - -/* Define to 1 if you have the <openssl/pkcs12.h> header file. */ -/*#define HAVE_OPENSSL_PKCS12_H 1*/ - -/* Define to 1 if you have the <openssl/rsa.h> header file. */ -/*#define HAVE_OPENSSL_RSA_H 1*/ - -/* Define to 1 if you have the <openssl/ssl.h> header file. */ -/*#define HAVE_OPENSSL_SSL_H 1*/ - -/* Define to 1 if you have the <openssl/x509.h> header file. */ -/*#define HAVE_OPENSSL_X509_H 1*/ - -/* Define to 1 if you have the <pem.h> header file. */ -/* #undef HAVE_PEM_H */ - -/* Define to 1 if you have the `perror' function. */ -#define HAVE_PERROR 1 - -/* Define to 1 if you have the `pipe' function. */ -#define HAVE_PIPE 1 - -/* Define to 1 if you have the `poll' function. */ -/*#define HAVE_POLL 1*/ - -/* If you have a fine poll */ -/*#define HAVE_POLL_FINE 1*/ - -/* Define to 1 if you have the <poll.h> header file. */ -/*#define HAVE_POLL_H 1*/ - -/* we have a POSIX-style strerror_r() */ -#define HAVE_POSIX_STRERROR_R 1 - -/* Define to 1 if you have the <pwd.h> header file. */ -#define HAVE_PWD_H 1 - -/* Define to 1 if you have the `RAND_egd' function. */ -#define HAVE_RAND_EGD 1 - -/* Define to 1 if you have the `RAND_screen' function. */ -/* #undef HAVE_RAND_SCREEN */ - -/* Define to 1 if you have the `RAND_status' function. */ -/*#define HAVE_RAND_STATUS 1*/ - -/* Define to 1 if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to 1 if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to 1 if you have the <rsa.h> header file. */ -/* #undef HAVE_RSA_H */ - -/* Define to 1 if you have the select function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to 1 if you have the <setjmp.h> header file. */ -#define HAVE_SETJMP_H 1 - -/* Define to 1 if you have the `setlocale' function. */ -#define HAVE_SETLOCALE 1 - -/* Define to 1 if you have the `setmode' function. */ -/* #undef HAVE_SETMODE */ - -/* Define to 1 if you have the `setrlimit' function. */ -/*#define HAVE_SETRLIMIT 1*/ - -/* Define to 1 if you have the setsockopt function. */ -/* #undef HAVE_SETSOCKOPT */ - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ - -/* Define to 1 if you have the <sgtty.h> header file. */ -/*#define HAVE_SGTTY_H 1*/ - -/* Define to 1 if you have the `sigaction' function. */ -/*#define HAVE_SIGACTION 1*/ - -/* Define to 1 if you have the `siginterrupt' function. */ -/*#define HAVE_SIGINTERRUPT 1*/ - -/* Define to 1 if you have the `signal' function. */ -/*#define HAVE_SIGNAL 1*/ - -/* Define to 1 if you have the <signal.h> header file. */ -#define HAVE_SIGNAL_H 1 - -/* If you have sigsetjmp */ -/*#define HAVE_SIGSETJMP 1*/ - -/* Define to 1 if sig_atomic_t is an available typedef. */ -/*#define HAVE_SIG_ATOMIC_T 1*/ - -/* Define to 1 if sig_atomic_t is already defined as volatile. */ -/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the <ssl.h> header file. */ -/* #undef HAVE_SSL_H */ - -/* Define to 1 if you have the <stdbool.h> header file. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdio.h> header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the `strcmpi' function. */ -/* #undef HAVE_STRCMPI */ - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the `stricmp' function. */ -/* #undef HAVE_STRICMP */ - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#define HAVE_STRLCPY 1 - -/* Define to 1 if you have the `strstr' function. */ -#define HAVE_STRSTR 1 - -/* Define to 1 if you have the `strtok_r' function. */ -#define HAVE_STRTOK_R 1 - -/* Define to 1 if you have the `strtoll' function. */ -#define HAVE_STRTOLL 1 - -/* if struct sockaddr_storage is defined */ -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 - -/* Define to 1 if you have the timeval struct. */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* Define to 1 if you have the <sys/filio.h> header file. */ -#define HAVE_SYS_FILIO_H 1 - -/* Define to 1 if you have the <sys/ioctl.h> header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the <sys/param.h> header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the <sys/poll.h> header file. */ -/*#define HAVE_SYS_POLL_H 1*/ - -/* Define to 1 if you have the <sys/resource.h> header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the <sys/select.h> header file. */ -#define HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the <sys/sockio.h> header file. */ -#define HAVE_SYS_SOCKIO_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/utime.h> header file. */ -/* #undef HAVE_SYS_UTIME_H */ - -/* Define to 1 if you have the <termios.h> header file. */ -/*#define HAVE_TERMIOS_H 1*/ - -/* Define to 1 if you have the <termio.h> header file. */ -/*#define HAVE_TERMIO_H 1*/ - -/* Define to 1 if you have the <time.h> header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the <tld.h> header file. */ -/*#define HAVE_TLD_H 1*/ - -/* Define to 1 if you have the `tld_strerror' function. */ -/*#define HAVE_TLD_STRERROR 1*/ - -/* Define to 1 if you have the `uname' function. */ -#define HAVE_UNAME 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `utime' function. */ -#define HAVE_UTIME 1 - -/* Define to 1 if you have the <utime.h> header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if compiler supports C99 variadic macro style. */ -#define HAVE_VARIADIC_MACROS_C99 1 - -/* Define to 1 if compiler supports old gcc variadic macro style. */ -/*#define HAVE_VARIADIC_MACROS_GCC 1*/ - -/* Define to 1 if you have the winber.h header file. */ -/* #undef HAVE_WINBER_H */ - -/* Define to 1 if you have the windows.h header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to 1 if you have the winldap.h header file. */ -/* #undef HAVE_WINLDAP_H */ - -/* Define to 1 if you have the winsock2.h header file. */ -/* #undef HAVE_WINSOCK2_H */ - -/* Define to 1 if you have the winsock.h header file. */ -/* #undef HAVE_WINSOCK_H */ - -/* Define this symbol if your OS supports changing the contents of argv */ -/*#define HAVE_WRITABLE_ARGV 1*/ - -/* Define to 1 if you have the ws2tcpip.h header file. */ -/* #undef HAVE_WS2TCPIP_H */ - -/* Define to 1 if you have the <x509.h> header file. */ -/* #undef HAVE_X509_H */ - -/* Define to 1 if you need the lber.h header file even with ldap.h */ -/* #undef NEED_LBER_H */ - -/* Define to 1 if you need the malloc.h header file even with stdlib.h */ -/* #undef NEED_MALLOC_H */ - -/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ -/* #undef NEED_REENTRANT */ - -/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ -/* #undef NEED_THREAD_SAFE */ - -/* cpu-machine-OS */ -#ifdef __WINS__ -#define OS "i386-pc-epoc32" -#elif __MARM__ -#define OS "arm-unknown-epoc32" -#else -/* This won't happen on any current Symbian version */ -#define OS "unknown-unknown-epoc32" -#endif - -/* Name of package */ -/*#define PACKAGE "curl"*/ - -/* Define to the address where bug reports for this package should be sent. */ -/*#define PACKAGE_BUGREPORT \ - "a suitable curl mailing list => https://curl.haxx.se/mail/"*/ - -/* Define to the full name of this package. */ -/*#define PACKAGE_NAME "curl"*/ - -/* Define to the full name and version of this package. */ -/*#define PACKAGE_STRING "curl -"*/ - -/* Define to the one symbol short name of this package. */ -/*#define PACKAGE_TARNAME "curl"*/ - -/* Define to the version of this package. */ -/*#define PACKAGE_VERSION "-"*/ - -/* a suitable file to read random data from */ -/*#define RANDOM_FILE "/dev/urandom"*/ - -#define RECV_TYPE_ARG1 int -#define RECV_TYPE_ARG2 void * -#define RECV_TYPE_ARG3 size_t -#define RECV_TYPE_ARG4 int -#define RECV_TYPE_RETV ssize_t - -#define RECVFROM_TYPE_ARG1 int -#define RECVFROM_TYPE_ARG2 void -#define RECVFROM_TYPE_ARG3 size_t -#define RECVFROM_TYPE_ARG4 int -#define RECVFROM_TYPE_ARG5 struct sockaddr -#define RECVFROM_TYPE_ARG6 size_t -#define RECVFROM_TYPE_RETV ssize_t -#define RECVFROM_TYPE_ARG2_IS_VOID 1 - -#define SEND_TYPE_ARG1 int -#define SEND_QUAL_ARG2 const -#define SEND_TYPE_ARG2 void * -#define SEND_TYPE_ARG3 size_t -#define SEND_TYPE_ARG4 int -#define SEND_TYPE_RETV ssize_t - - -/* Define as the return type of signal handlers (`int' or `void'). */ -/*#define RETSIGTYPE void*/ - -/* Define to the type of arg 1 for `select'. */ -#define SELECT_TYPE_ARG1 int - -/* Define to the type of args 2, 3 and 4 for `select'. */ -#define SELECT_TYPE_ARG234 (fd_set *) - -/* Define to the type of arg 5 for `select'. */ -#define SELECT_TYPE_ARG5 (struct timeval *) - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `off_t', as computed by sizeof. */ -#define SIZEOF_OFF_T 8 - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 4 - -/* The size of `time_t', as computed by sizeof. */ -#define SIZEOF_TIME_T 4 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#define TIME_WITH_SYS_TIME 1 - -/* Define if you want to enable c-ares support */ -/* #undef USE_ARES */ - -/* Define to disable non-blocking sockets */ -/* #undef USE_BLOCKING_SOCKETS */ - -/* if GnuTLS is enabled */ -/* #undef USE_GNUTLS */ - -/* if libSSH2 is in use */ -/*#define USE_LIBSSH2 1*/ - -/* If you want to build curl with the built-in manual */ -/*#define USE_MANUAL 1*/ - -/* if NSS is enabled */ -/* #undef USE_NSS */ - -/* to enable SSPI support */ -/* #undef USE_WINDOWS_SSPI */ - -/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */ -/* #undef USE_YASSLEMUL */ - -/* Version number of package */ -/*#define VERSION "7.18.2-CVS"*/ - -/* Define to avoid automatic inclusion of winsock.h */ -/* #undef WIN32_LEAN_AND_MEAN */ - -/* Define to 1 if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* # undef _ALL_SOURCE */ -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -#define _FILE_OFFSET_BITS 64 - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* type to use in place of in_addr_t if not defined */ -/* #undef in_addr_t */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ - -/* the signed version of size_t */ -/* #undef ssize_t */ - -/* Enabling curl debug mode when building in Symbian debug mode would work */ -/* except that debug mode introduces new exports that must be frozen. */ -#ifdef _DEBUG -/* #define CURLDEBUG */ -#endif - -/* sys/cdefs.h fails to define this for WINSCW prior to Symbian OS ver. 9.4 */ -#ifndef __LONG_LONG_SUPPORTED -#define __LONG_LONG_SUPPORTED -#endif - -/* Enable appropriate header only when zlib support is enabled */ -#ifdef HAVE_LIBZ -#define HAVE_ZLIB_H 1 -#endif - -#endif /* HEADER_CURL_CONFIG_SYMBIAN_H */ diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index 7ac33c51fe..316043d817 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -246,10 +246,6 @@ /* Define if you have the socket function. */ #define HAVE_SOCKET 1 -/* Define if libSSH2 is in use */ -#define USE_LIBSSH2 1 -#define HAVE_LIBSSH2_H 1 - /* Define if you have the strcasecmp function. */ /* #define HAVE_STRCASECMP 1 */ @@ -717,9 +713,6 @@ Vista # define CURL_DISABLE_LDAP 1 #endif -/* if SSL is enabled */ -#define USE_OPENSSL 1 - /* Define to use the Windows crypto library. */ #if !defined(CURL_WINDOWS_APP) #define USE_WIN32_CRYPTO diff --git a/libs/libcurl/src/conncache.c b/libs/libcurl/src/conncache.c index d21a00cfdd..c0e4d3e30f 100644 --- a/libs/libcurl/src/conncache.c +++ b/libs/libcurl/src/conncache.c @@ -59,7 +59,7 @@ static CURLcode bundle_create(struct connectbundle **bundlep) (*bundlep)->num_connections = 0; (*bundlep)->multiuse = BUNDLE_UNKNOWN; - Curl_llist_init(&(*bundlep)->conn_list, (curl_llist_dtor) conn_llist_dtor); + Curl_llist_init(&(*bundlep)->conn_list, (Curl_llist_dtor) conn_llist_dtor); return CURLE_OK; } @@ -87,7 +87,7 @@ static void bundle_add_conn(struct connectbundle *bundle, static int bundle_remove_conn(struct connectbundle *bundle, struct connectdata *conn) { - struct curl_llist_element *curr; + struct Curl_llist_element *curr; curr = bundle->conn_list.head; while(curr) { @@ -206,8 +206,8 @@ static bool conncache_add_bundle(struct conncache *connc, static void conncache_remove_bundle(struct conncache *connc, struct connectbundle *bundle) { - struct curl_hash_iterator iter; - struct curl_hash_element *he; + struct Curl_hash_iterator iter; + struct Curl_hash_element *he; if(!connc) return; @@ -320,9 +320,9 @@ bool Curl_conncache_foreach(struct Curl_easy *data, void *param, int (*func)(struct connectdata *conn, void *param)) { - struct curl_hash_iterator iter; - struct curl_llist_element *curr; - struct curl_hash_element *he; + struct Curl_hash_iterator iter; + struct Curl_llist_element *curr; + struct Curl_hash_element *he; if(!connc) return FALSE; @@ -363,15 +363,15 @@ bool Curl_conncache_foreach(struct Curl_easy *data, static struct connectdata * conncache_find_first_connection(struct conncache *connc) { - struct curl_hash_iterator iter; - struct curl_hash_element *he; + struct Curl_hash_iterator iter; + struct Curl_hash_element *he; struct connectbundle *bundle; Curl_hash_start_iterate(&connc->hash, &iter); he = Curl_hash_next_element(&iter); while(he) { - struct curl_llist_element *curr; + struct Curl_llist_element *curr; bundle = he->ptr; curr = bundle->conn_list.head; @@ -429,7 +429,7 @@ struct connectdata * Curl_conncache_extract_bundle(struct Curl_easy *data, struct connectbundle *bundle) { - struct curl_llist_element *curr; + struct Curl_llist_element *curr; timediff_t highscore = -1; timediff_t score; struct curltime now; @@ -477,9 +477,9 @@ struct connectdata * Curl_conncache_extract_oldest(struct Curl_easy *data) { struct conncache *connc = data->state.conn_cache; - struct curl_hash_iterator iter; - struct curl_llist_element *curr; - struct curl_hash_element *he; + struct Curl_hash_iterator iter; + struct Curl_llist_element *curr; + struct Curl_hash_element *he; timediff_t highscore =- 1; timediff_t score; struct curltime now; @@ -571,9 +571,9 @@ void Curl_conncache_close_all_connections(struct conncache *connc) /* Useful for debugging the connection cache */ void Curl_conncache_print(struct conncache *connc) { - struct curl_hash_iterator iter; - struct curl_llist_element *curr; - struct curl_hash_element *he; + struct Curl_hash_iterator iter; + struct Curl_llist_element *curr; + struct Curl_hash_element *he; if(!connc) return; diff --git a/libs/libcurl/src/conncache.h b/libs/libcurl/src/conncache.h index 3dda21cdc6..c3e9ff51b9 100644 --- a/libs/libcurl/src/conncache.h +++ b/libs/libcurl/src/conncache.h @@ -30,7 +30,7 @@ */ struct conncache { - struct curl_hash hash; + struct Curl_hash hash; size_t num_conn; long next_connection_id; struct curltime last_cleanup; @@ -66,7 +66,7 @@ struct conncache { struct connectbundle { int multiuse; /* supports multi-use */ size_t num_connections; /* Number of connections in the bundle */ - struct curl_llist conn_list; /* The connectdata members of the bundle */ + struct Curl_llist conn_list; /* The connectdata members of the bundle */ }; /* returns 1 on error, 0 is fine */ diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index b000b1b2c2..5f23b79ca0 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -83,11 +83,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifdef __SYMBIAN32__ -/* This isn't actually supported under Symbian OS */ -#undef SO_NOSIGPIPE -#endif - static bool verifyconnect(curl_socket_t sockfd, int *error); #if defined(__DragonFly__) || defined(HAVE_WINSOCK_H) @@ -746,8 +741,8 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex, bool *done) { CURLcode result = CURLE_OK; - #ifndef CURL_DISABLE_PROXY + CURLproxycode pxresult = CURLPX_OK; if(conn->bits.socksproxy) { /* for the secondary socket (FTP), use the "connect to host" * but ignore the "connect to port" (use the secondary port) @@ -767,20 +762,24 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex, switch(conn->socks_proxy.proxytype) { case CURLPROXY_SOCKS5: case CURLPROXY_SOCKS5_HOSTNAME: - result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd, - host, port, sockindex, conn, done); + pxresult = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd, + host, port, sockindex, conn, done); break; case CURLPROXY_SOCKS4: case CURLPROXY_SOCKS4A: - result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex, - conn, done); + pxresult = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex, + conn, done); break; default: failf(conn->data, "unknown proxytype option given"); result = CURLE_COULDNT_CONNECT; } /* switch proxytype */ + if(pxresult) { + result = CURLE_PROXY; + conn->data->info.pxcode = pxresult; + } } else #else @@ -1313,10 +1312,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ const struct Curl_dns_entry *remotehost) { struct Curl_easy *data = conn->data; - struct curltime before = Curl_now(); CURLcode result = CURLE_COULDNT_CONNECT; int i; - timediff_t timeout_ms = Curl_timeleft(data, &before, TRUE); + timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); if(timeout_ms < 0) { /* a precaution, no need to continue if time already is up */ @@ -1416,8 +1414,7 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, } return c->sock[FIRSTSOCKET]; } - else - return CURL_SOCKET_BAD; + return CURL_SOCKET_BAD; } /* diff --git a/libs/libcurl/src/content_encoding.c b/libs/libcurl/src/content_encoding.c index 2fc3d43c44..a6dce48804 100644 --- a/libs/libcurl/src/content_encoding.c +++ b/libs/libcurl/src/content_encoding.c @@ -28,10 +28,6 @@ #ifdef HAVE_ZLIB_H #include <zlib.h> -#ifdef __SYMBIAN32__ -/* zlib pollutes the namespace with this definition */ -#undef WIN32 -#endif #endif #ifdef HAVE_BROTLI diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake index dd870789ec..eca3734b0c 100644 --- a/libs/libcurl/src/curl_config.h.cmake +++ b/libs/libcurl/src/curl_config.h.cmake @@ -63,8 +63,8 @@ /* to disable LDAPS */ #cmakedefine CURL_DISABLE_LDAPS 1 -/* to enable MQTT */ -#undef CURL_ENABLE_MQTT +/* to disable MQTT */ +#cmakedefine CURL_DISABLE_MQTT 1 /* to disable POP3 */ #cmakedefine CURL_DISABLE_POP3 1 diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in index 2f5511a747..ab8651a511 100644 --- a/libs/libcurl/src/curl_config.h.in +++ b/libs/libcurl/src/curl_config.h.in @@ -33,6 +33,9 @@ /* to disable FTP */ #undef CURL_DISABLE_FTP +/* to disable curl_easy_options */ +#undef CURL_DISABLE_GETOPTIONS + /* to disable Gopher */ #undef CURL_DISABLE_GOPHER @@ -57,6 +60,9 @@ /* disable mime API */ #undef CURL_DISABLE_MIME +/* to disable MQTT */ +#undef CURL_DISABLE_MQTT + /* disable netrc parsing */ #undef CURL_DISABLE_NETRC @@ -87,6 +93,9 @@ /* to disable SMTP */ #undef CURL_DISABLE_SMTP +/* to disable socketpair support */ +#undef CURL_DISABLE_SOCKETPAIR + /* to disable TELNET */ #undef CURL_DISABLE_TELNET @@ -96,9 +105,6 @@ /* to disable verbose strings */ #undef CURL_DISABLE_VERBOSE_STRINGS -/* to enable MQTT */ -#undef CURL_ENABLE_MQTT - /* Definition to make a library symbol externally visible. */ #undef CURL_EXTERN_SYMBOL @@ -633,8 +639,8 @@ /* Define to 1 if you have the `SSLv2_client_method' function. */ #undef HAVE_SSLV2_CLIENT_METHOD -/* Define to 1 if you have the `SSL_get_esni_status' function. */ -#undef HAVE_SSL_GET_ESNI_STATUS +/* Define to 1 if you have the `SSL_get_ech_status' function. */ +#undef HAVE_SSL_GET_ECH_STATUS /* Define to 1 if you have the <ssl.h> header file. */ #undef HAVE_SSL_H @@ -978,8 +984,8 @@ /* if BearSSL is enabled */ #undef USE_BEARSSL -/* if ESNI support is available */ -#undef USE_ESNI +/* if ECH support is available */ +#undef USE_ECH /* if GnuTLS is enabled */ #undef USE_GNUTLS diff --git a/libs/libcurl/src/curl_get_line.c b/libs/libcurl/src/curl_get_line.c index c4194851ae..3c77be9a95 100644 --- a/libs/libcurl/src/curl_get_line.c +++ b/libs/libcurl/src/curl_get_line.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -22,6 +22,8 @@ #include "curl_setup.h" +#if !defined(CURL_DISABLE_COOKIES) && !defined(CURL_DISABLE_ALTSVC) + #include "curl_get_line.h" #include "curl_memory.h" /* The last #include file should be: */ @@ -53,3 +55,5 @@ char *Curl_get_line(char *buf, int len, FILE *input) } return NULL; } + +#endif /* if not disabled */ diff --git a/libs/libcurl/src/curl_gethostname.c b/libs/libcurl/src/curl_gethostname.c index 8337c72e81..5f1c9998fe 100644 --- a/libs/libcurl/src/curl_gethostname.c +++ b/libs/libcurl/src/curl_gethostname.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -48,7 +48,7 @@ * For libcurl static library release builds no overriding takes place. */ -int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) +int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen) { #ifndef HAVE_GETHOSTNAME diff --git a/libs/libcurl/src/curl_gethostname.h b/libs/libcurl/src/curl_gethostname.h index 8ae15e6c19..2d78bc54db 100644 --- a/libs/libcurl/src/curl_gethostname.h +++ b/libs/libcurl/src/curl_gethostname.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,6 +26,6 @@ #define HOSTNAME_MAX 1024 /* This returns the local machine's un-qualified hostname */ -int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen); +int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen); #endif /* HEADER_CURL_GETHOSTNAME_H */ diff --git a/libs/libcurl/src/curl_sec.h b/libs/libcurl/src/curl_krb5.h index 7bdde269b1..ae9b7e0d3e 100644 --- a/libs/libcurl/src/curl_sec.h +++ b/libs/libcurl/src/curl_krb5.h @@ -1,5 +1,5 @@ -#ifndef HEADER_CURL_SECURITY_H -#define HEADER_CURL_SECURITY_H +#ifndef HEADER_CURL_KRB5_H +#define HEADER_CURL_KRB5_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -44,8 +44,8 @@ int Curl_sec_read_msg(struct connectdata *conn, char *, void Curl_sec_end(struct connectdata *); CURLcode Curl_sec_login(struct connectdata *); int Curl_sec_request_prot(struct connectdata *conn, const char *level); - -extern struct Curl_sec_client_mech Curl_krb5_client_mech; +#else +#define Curl_sec_end(x) #endif -#endif /* HEADER_CURL_SECURITY_H */ +#endif /* HEADER_CURL_KRB5_H */ diff --git a/libs/libcurl/src/curl_ntlm_core.c b/libs/libcurl/src/curl_ntlm_core.c index 0eefb15879..defae772b4 100644 --- a/libs/libcurl/src/curl_ntlm_core.c +++ b/libs/libcurl/src/curl_ntlm_core.c @@ -22,7 +22,7 @@ #include "curl_setup.h" -#if defined(USE_NTLM) +#if defined(USE_CURL_NTLM_CORE) /* * NTLM details: @@ -50,8 +50,6 @@ in NTLM type-3 messages. */ -#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) - #if defined(USE_OPENSSL) || defined(USE_WOLFSSL) #ifdef USE_WOLFSSL @@ -744,6 +742,4 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash, #endif /* USE_NTRESPONSES */ -#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ - -#endif /* USE_NTLM */ +#endif /* USE_CURL_NTLM_CORE */ diff --git a/libs/libcurl/src/curl_ntlm_core.h b/libs/libcurl/src/curl_ntlm_core.h index 7895b64709..6d391c4cb6 100644 --- a/libs/libcurl/src/curl_ntlm_core.h +++ b/libs/libcurl/src/curl_ntlm_core.h @@ -24,7 +24,7 @@ #include "curl_setup.h" -#if defined(USE_NTLM) +#if defined(USE_CURL_NTLM_CORE) /* If NSS is the first available SSL backend (see order in curl_ntlm_core.c) then it must be initialized to be used by NTLM. */ @@ -36,8 +36,6 @@ #define NTLM_NEEDS_NSS_INIT #endif -#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) - #if defined(USE_OPENSSL) || defined(USE_WOLFSSL) #ifdef USE_WOLFSSL # include <wolfssl/options.h> @@ -102,8 +100,6 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash, #endif /* USE_NTRESPONSES */ -#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ - -#endif /* USE_NTLM */ +#endif /* USE_CURL_NTLM_CORE */ #endif /* HEADER_CURL_NTLM_CORE_H */ diff --git a/libs/libcurl/src/curl_path.c b/libs/libcurl/src/curl_path.c index fbd98cb39b..7b3fb27ab1 100644 --- a/libs/libcurl/src/curl_path.c +++ b/libs/libcurl/src/curl_path.c @@ -168,7 +168,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) *cpp = cp + i + strspn(cp + i, WHITESPACE); } else { - /* Read to end of filename - either to white space or terminator */ + /* Read to end of filename - either to whitespace or terminator */ end = strpbrk(cp, WHITESPACE); if(end == NULL) end = strchr(cp, '\0'); @@ -184,7 +184,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) (*path)[pathLength] = '\0'; cp += 3; } - /* Copy path name up until first "white space" */ + /* Copy path name up until first "whitespace" */ memcpy(&(*path)[pathLength], cp, (int)(end - cp)); pathLength += (int)(end - cp); (*path)[pathLength] = '\0'; diff --git a/libs/libcurl/src/curl_printf.h b/libs/libcurl/src/curl_printf.h index 0d37b8e572..9d2de7ba8c 100644 --- a/libs/libcurl/src/curl_printf.h +++ b/libs/libcurl/src/curl_printf.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_rtmp.c b/libs/libcurl/src/curl_rtmp.c index df8f2b1d95..32f11130a0 100644 --- a/libs/libcurl/src/curl_rtmp.c +++ b/libs/libcurl/src/curl_rtmp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com> * * This software is licensed as described in the file COPYING, which @@ -79,6 +79,7 @@ const struct Curl_handler Curl_handler_rtmp = { ZERO_NULL, /* connection_check */ PORT_RTMP, /* defport */ CURLPROTO_RTMP, /* protocol */ + CURLPROTO_RTMP, /* family */ PROTOPT_NONE /* flags*/ }; @@ -100,6 +101,7 @@ const struct Curl_handler Curl_handler_rtmpt = { ZERO_NULL, /* connection_check */ PORT_RTMPT, /* defport */ CURLPROTO_RTMPT, /* protocol */ + CURLPROTO_RTMPT, /* family */ PROTOPT_NONE /* flags*/ }; @@ -121,6 +123,7 @@ const struct Curl_handler Curl_handler_rtmpe = { ZERO_NULL, /* connection_check */ PORT_RTMP, /* defport */ CURLPROTO_RTMPE, /* protocol */ + CURLPROTO_RTMPE, /* family */ PROTOPT_NONE /* flags*/ }; @@ -142,6 +145,7 @@ const struct Curl_handler Curl_handler_rtmpte = { ZERO_NULL, /* connection_check */ PORT_RTMPT, /* defport */ CURLPROTO_RTMPTE, /* protocol */ + CURLPROTO_RTMPTE, /* family */ PROTOPT_NONE /* flags*/ }; @@ -163,6 +167,7 @@ const struct Curl_handler Curl_handler_rtmps = { ZERO_NULL, /* connection_check */ PORT_RTMPS, /* defport */ CURLPROTO_RTMPS, /* protocol */ + CURLPROTO_RTMP, /* family */ PROTOPT_NONE /* flags*/ }; @@ -184,6 +189,7 @@ const struct Curl_handler Curl_handler_rtmpts = { ZERO_NULL, /* connection_check */ PORT_RTMPS, /* defport */ CURLPROTO_RTMPTS, /* protocol */ + CURLPROTO_RTMPT, /* family */ PROTOPT_NONE /* flags*/ }; diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index 21c3f3487f..3872dbb655 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -38,8 +38,7 @@ * Define WIN32 when build target is Win32 API */ -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \ - !defined(__SYMBIAN32__) +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) #define WIN32 #endif @@ -88,10 +87,6 @@ # include "config-amigaos.h" #endif -#ifdef __SYMBIAN32__ -# include "config-symbian.h" -#endif - #ifdef __OS400__ # include "config-os400.h" #endif @@ -560,14 +555,6 @@ /* ---------------------------------------------------------------- */ /* - * When using WINSOCK, TELNET protocol requires WINSOCK2 API. - */ - -#if defined(USE_WINSOCK) && (USE_WINSOCK != 2) -# define CURL_DISABLE_TELNET 1 -#endif - -/* * msvc 6.0 does not have struct sockaddr_storage and * does not define IPPROTO_ESP in winsock2.h. But both * are available if PSDK is properly installed. @@ -637,13 +624,12 @@ int netware_init(void); /* Single point where USE_NTLM definition might be defined */ #if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH) -#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \ +#if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \ defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \ defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \ - defined(USE_MBEDTLS) || \ (defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT)) -#define USE_NTLM +#define USE_CURL_NTLM_CORE # if defined(USE_MBEDTLS) /* Get definition of MBEDTLS_MD4_C */ @@ -651,6 +637,10 @@ int netware_init(void); # endif #endif + +#if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI) +#define USE_NTLM +#endif #endif #ifdef CURL_WANTS_CA_BUNDLE_ENV @@ -702,7 +692,7 @@ int netware_init(void); defined(HAVE_WINSOCK_H) || \ defined(HAVE_WINSOCK2_H) || \ defined(HAVE_WS2TCPIP_H) -# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!" +# error "WinSock and lwIP TCP/IP stack definitions shall not coexist!" # endif #endif diff --git a/libs/libcurl/src/curl_threads.c b/libs/libcurl/src/curl_threads.c index b5f10a20ec..6f3815e711 100644 --- a/libs/libcurl/src/curl_threads.c +++ b/libs/libcurl/src/curl_threads.c @@ -41,14 +41,14 @@ #if defined(USE_THREADS_POSIX) -struct curl_actual_call { +struct Curl_actual_call { unsigned int (*func)(void *); void *arg; }; static void *curl_thread_create_thunk(void *arg) { - struct curl_actual_call *ac = arg; + struct Curl_actual_call *ac = arg; unsigned int (*func)(void *) = ac->func; void *real_arg = ac->arg; @@ -62,7 +62,7 @@ static void *curl_thread_create_thunk(void *arg) curl_thread_t Curl_thread_create(unsigned int (*func) (void *), void *arg) { curl_thread_t t = malloc(sizeof(pthread_t)); - struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call)); + struct Curl_actual_call *ac = malloc(sizeof(struct Curl_actual_call)); if(!(ac && t)) goto err; diff --git a/libs/libcurl/src/dict.c b/libs/libcurl/src/dict.c index f529b48f71..8dd4a90f7f 100644 --- a/libs/libcurl/src/dict.c +++ b/libs/libcurl/src/dict.c @@ -57,6 +57,7 @@ #include "escape.h" #include "progress.h" #include "dict.h" +#include "curl_printf.h" #include "strcase.h" #include "curl_memory.h" /* The last #include file should be: */ @@ -90,7 +91,8 @@ const struct Curl_handler Curl_handler_dict = { ZERO_NULL, /* connection_check */ PORT_DICT, /* defport */ CURLPROTO_DICT, /* protocol */ - PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ + CURLPROTO_DICT, /* family */ + PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ }; static char *unescape_word(struct Curl_easy *data, const char *inputbuff) @@ -126,6 +128,52 @@ static char *unescape_word(struct Curl_easy *data, const char *inputbuff) return dictp; } +/* sendf() sends formatted data to the server */ +static CURLcode sendf(curl_socket_t sockfd, struct connectdata *conn, + const char *fmt, ...) +{ + struct Curl_easy *data = conn->data; + ssize_t bytes_written; + size_t write_len; + CURLcode result = CURLE_OK; + char *s; + char *sptr; + va_list ap; + va_start(ap, fmt); + s = vaprintf(fmt, ap); /* returns an allocated string */ + va_end(ap); + if(!s) + return CURLE_OUT_OF_MEMORY; /* failure */ + + bytes_written = 0; + write_len = strlen(s); + sptr = s; + + for(;;) { + /* Write the buffer to the socket */ + result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written); + + if(result) + break; + + if(data->set.verbose) + Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written); + + if((size_t)bytes_written != write_len) { + /* if not all was written at once, we must advance the pointer, decrease + the size left and try again! */ + write_len -= bytes_written; + sptr += bytes_written; + } + else + break; + } + + free(s); /* free the output string */ + + return result; +} + static CURLcode dict_do(struct connectdata *conn, bool *done) { char *word; @@ -183,18 +231,16 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) if(!eword) return CURLE_OUT_OF_MEMORY; - result = Curl_sendf(sockfd, conn, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" - "MATCH " - "%s " /* database */ - "%s " /* strategy */ - "%s\r\n" /* word */ - "QUIT\r\n", - - database, - strategy, - eword - ); + result = sendf(sockfd, conn, + "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" + "MATCH " + "%s " /* database */ + "%s " /* strategy */ + "%s\r\n" /* word */ + "QUIT\r\n", + database, + strategy, + eword); free(eword); @@ -233,14 +279,14 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) if(!eword) return CURLE_OUT_OF_MEMORY; - result = Curl_sendf(sockfd, conn, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" - "DEFINE " - "%s " /* database */ - "%s\r\n" /* word */ - "QUIT\r\n", - database, - eword); + result = sendf(sockfd, conn, + "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" + "DEFINE " + "%s " /* database */ + "%s\r\n" /* word */ + "QUIT\r\n", + database, + eword); free(eword); @@ -261,10 +307,10 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) if(ppath[i] == ':') ppath[i] = ' '; } - result = Curl_sendf(sockfd, conn, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" - "%s\r\n" - "QUIT\r\n", ppath); + result = sendf(sockfd, conn, + "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" + "%s\r\n" + "QUIT\r\n", ppath); if(result) { failf(data, "Failed sending DICT request"); return result; diff --git a/libs/libcurl/src/doh.c b/libs/libcurl/src/doh.c index 8bc3428ff5..e8b0801109 100644 --- a/libs/libcurl/src/doh.c +++ b/libs/libcurl/src/doh.c @@ -57,12 +57,13 @@ static const char * const errors[]={ "Unexpected TYPE", "Unexpected CLASS", "No content", - "Bad ID" + "Bad ID", + "Name too long" }; static const char *doh_strerror(DOHcode code) { - if((code >= DOH_OK) && (code <= DOH_DNS_BAD_ID)) + if((code >= DOH_OK) && (code <= DOH_DNS_NAME_TOO_LONG)) return errors[code]; return "bad error code"; } @@ -348,6 +349,10 @@ static CURLcode dohprobe(struct Curl_easy *data, ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); if(data->set.ssl.fsslctxp) ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp); + if(data->set.str[STRING_SSL_EC_CURVES]) { + ERROR_CHECK_SETOPT(CURLOPT_SSL_EC_CURVES, + data->set.str[STRING_SSL_EC_CURVES]); + } doh->set.fmultidone = Curl_doh_done; doh->set.dohfor = data; /* identify for which transfer this is done */ diff --git a/libs/libcurl/src/dynbuf.c b/libs/libcurl/src/dynbuf.c index 38d370b078..b2465b8886 100644 --- a/libs/libcurl/src/dynbuf.c +++ b/libs/libcurl/src/dynbuf.c @@ -21,12 +21,11 @@ ***************************************************************************/ #include "curl_setup.h" -#include "strdup.h" #include "dynbuf.h" - -/* The last 3 #include files should be in this order */ #include "curl_printf.h" +#ifdef BUILDING_LIBCURL #include "curl_memory.h" +#endif #include "memdebug.h" #define MIN_FIRST_ALLOC 32 @@ -94,11 +93,15 @@ static CURLcode dyn_nappend(struct dynbuf *s, } if(a != s->allc) { - s->bufr = Curl_saferealloc(s->bufr, a); - if(!s->bufr) { + /* this logic is not using Curl_saferealloc() to make the tool not have to + include that as well when it uses this code */ + void *p = realloc(s->bufr, a); + if(!p) { + Curl_safefree(s->bufr); s->leng = s->allc = 0; return CURLE_OUT_OF_MEMORY; } + s->bufr = p; s->allc = a; } @@ -143,6 +146,7 @@ CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail) else { memmove(&s->bufr[0], &s->bufr[s->leng - trail], trail); s->leng = trail; + s->bufr[s->leng] = 0; } return CURLE_OK; @@ -173,15 +177,22 @@ CURLcode Curl_dyn_add(struct dynbuf *s, const char *str) } /* - * Append a string printf()-style + * Append a string vprintf()-style */ -CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...) +CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap) { +#ifdef BUILDING_LIBCURL + int rc; + DEBUGASSERT(s); + DEBUGASSERT(s->init == DYNINIT); + DEBUGASSERT(!s->leng || s->bufr); + rc = Curl_dyn_vprintf(s, fmt, ap); + + if(!rc) + return CURLE_OK; +#else char *str; - va_list ap; - va_start(ap, fmt); str = vaprintf(fmt, ap); /* this allocs a new string to append */ - va_end(ap); if(str) { CURLcode result = dyn_nappend(s, (unsigned char *)str, strlen(str)); @@ -190,10 +201,27 @@ CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...) } /* If we failed, we cleanup the whole buffer and return error */ Curl_dyn_free(s); +#endif return CURLE_OUT_OF_MEMORY; } /* + * Append a string printf()-style + */ +CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...) +{ + CURLcode result; + va_list ap; + DEBUGASSERT(s); + DEBUGASSERT(s->init == DYNINIT); + DEBUGASSERT(!s->leng || s->bufr); + va_start(ap, fmt); + result = Curl_dyn_vaddf(s, fmt, ap); + va_end(ap); + return result; +} + +/* * Returns a pointer to the buffer. */ char *Curl_dyn_ptr(const struct dynbuf *s) diff --git a/libs/libcurl/src/dynbuf.h b/libs/libcurl/src/dynbuf.h index ecc9957553..39b8595706 100644 --- a/libs/libcurl/src/dynbuf.h +++ b/libs/libcurl/src/dynbuf.h @@ -22,6 +22,23 @@ * ***************************************************************************/ +#ifndef BUILDING_LIBCURL +/* this renames the functions so that the tool code can use the same code + without getting symbol collisions */ +#define Curl_dyn_init(a,b) curlx_dyn_init(a,b) +#define Curl_dyn_add(a,b) curlx_dyn_add(a,b) +#define Curl_dyn_addn(a,b,c) curlx_dyn_addn(a,b,c) +#define Curl_dyn_addf curlx_dyn_addf +#define Curl_dyn_vaddf curlx_dyn_vaddf +#define Curl_dyn_free(a) curlx_dyn_free(a) +#define Curl_dyn_ptr(a) curlx_dyn_ptr(a) +#define Curl_dyn_uptr(a) curlx_dyn_uptr(a) +#define Curl_dyn_len(a) curlx_dyn_len(a) +#define Curl_dyn_reset(a) curlx_dyn_reset(a) +#define Curl_dyn_tail(a,b) curlx_dyn_tail(a,b) +#define curlx_dynbuf dynbuf /* for the struct name */ +#endif + struct dynbuf { char *bufr; /* point to a null-terminated allocated buffer */ size_t leng; /* number of bytes *EXCLUDING* the zero terminator */ @@ -40,12 +57,18 @@ CURLcode Curl_dyn_add(struct dynbuf *s, const char *str) WARN_UNUSED_RESULT; CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...) WARN_UNUSED_RESULT; +CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap) + WARN_UNUSED_RESULT; void Curl_dyn_reset(struct dynbuf *s); CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail); char *Curl_dyn_ptr(const struct dynbuf *s); unsigned char *Curl_dyn_uptr(const struct dynbuf *s); size_t Curl_dyn_len(const struct dynbuf *s); +/* returns 0 on success, -1 on error */ +/* The implementation of this function exists in mprintf.c */ +int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save); + /* Dynamic buffer max sizes */ #define DYN_DOH_RESPONSE 3000 #define DYN_DOH_CNAME 256 @@ -60,4 +83,6 @@ size_t Curl_dyn_len(const struct dynbuf *s); #define DYN_PROXY_CONNECT_HEADERS 16384 #define DYN_QLOG_NAME 1024 #define DYN_H1_TRAILER 4096 +#define DYN_PINGPPONG_CMD (64*1024) +#define DYN_IMAP_CMD (64*1024) #endif diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c index a69eb9e567..60e2befd76 100644 --- a/libs/libcurl/src/easy.c +++ b/libs/libcurl/src/easy.c @@ -78,6 +78,7 @@ #include "system_win32.h" #include "http2.h" #include "dynbuf.h" +#include "altsvc.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -105,7 +106,6 @@ static long init_flags; # pragma warning(disable:4232) /* MSVC extension, dllimport identity */ #endif -#ifndef __SYMBIAN32__ /* * If a memory-using function (like curl_getenv) is used before * curl_global_init() is called, we need to have these pointers set already. @@ -118,17 +118,6 @@ curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; #if defined(WIN32) && defined(UNICODE) curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; #endif -#else -/* - * Symbian OS doesn't support initialization to code in writable static data. - * Initialization will occur in the curl_global_init() call. - */ -curl_malloc_callback Curl_cmalloc; -curl_free_callback Curl_cfree; -curl_realloc_callback Curl_crealloc; -curl_strdup_callback Curl_cstrdup; -curl_calloc_callback Curl_ccalloc; -#endif #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__) # pragma warning(default:4232) /* MSVC extension, dllimport identity */ @@ -883,6 +872,15 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) goto fail; } +#ifdef USE_ALTSVC + if(data->asi) { + outcurl->asi = Curl_altsvc_init(); + if(!outcurl->asi) + goto fail; + if(outcurl->set.str[STRING_ALTSVC]) + (void)Curl_altsvc_load(outcurl->asi, outcurl->set.str[STRING_ALTSVC]); + } +#endif /* Clone the resolver handle, if present, for the new handle */ if(Curl_resolver_duphandle(outcurl, &outcurl->state.resolver, @@ -930,6 +928,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) Curl_dyn_free(&outcurl->state.headerb); Curl_safefree(outcurl->change.url); Curl_safefree(outcurl->change.referer); + Curl_altsvc_cleanup(&outcurl->asi); Curl_freeset(outcurl); free(outcurl); } @@ -958,6 +957,7 @@ void curl_easy_reset(struct Curl_easy *data) data->progress.flags |= PGRS_HIDE; data->state.current_speed = -1; /* init to negative == impossible */ + data->state.retrycount = 0; /* reset the retry counter */ /* zero out authentication data: */ memset(&data->state.authhost, 0, sizeof(struct auth)); @@ -1067,9 +1067,10 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) { Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */ - /* force a recv/send check of this connection, as the data might've been - read off the socket already */ - data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT; + if(!data->state.tempcount) + /* if not pausing again, force a recv/send check of this connection as + the data might've been read off the socket already */ + data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT; if(data->multi) Curl_update_timer(data->multi); } diff --git a/libs/libcurl/src/easygetopt.c b/libs/libcurl/src/easygetopt.c new file mode 100644 index 0000000000..cac8378e7e --- /dev/null +++ b/libs/libcurl/src/easygetopt.c @@ -0,0 +1,96 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ | | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * ___|___/|_| ______| + * + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "strcase.h" +#include "easyoptions.h" + +#ifndef CURL_DISABLE_GETOPTIONS + +/* Lookups easy options at runtime */ +static struct curl_easyoption *lookup(const char *name, CURLoption id) +{ + DEBUGASSERT(name || id); + DEBUGASSERT(!Curl_easyopts_check()); + if(name || id) { + struct curl_easyoption *o = &Curl_easyopts[0]; + do { + if(name) { + if(strcasecompare(o->name, name)) + return o; + } + else { + if((o->id == id) && !(o->flags & CURLOT_FLAG_ALIAS)) + /* don't match alias options */ + return o; + } + o++; + } while(o->name); + } + return NULL; +} + +const struct curl_easyoption *curl_easy_option_by_name(const char *name) +{ + /* when name is used, the id argument is ignored */ + return lookup(name, CURLOPT_LASTENTRY); +} + +const struct curl_easyoption *curl_easy_option_by_id(CURLoption id) +{ + return lookup(NULL, id); +} + +/* Iterates over available options */ +const struct curl_easyoption * +curl_easy_option_next(const struct curl_easyoption *prev) +{ + if(prev && prev->name) { + prev++; + if(prev->name) + return prev; + } + else if(!prev) + return &Curl_easyopts[0]; + return NULL; +} + +#else +const struct curl_easyoption *curl_easy_option_by_name(const char *name) +{ + (void)name; + return NULL; +} + +const struct curl_easyoption *curl_easy_option_by_id (CURLoption id) +{ + (void)id; + return NULL; +} + +const struct curl_easyoption * +curl_easy_option_next(const struct curl_easyoption *prev) +{ + (void)prev; + return NULL; +} +#endif diff --git a/libs/libcurl/src/easyoptions.c b/libs/libcurl/src/easyoptions.c new file mode 100644 index 0000000000..0ab6a3fc6d --- /dev/null +++ b/libs/libcurl/src/easyoptions.c @@ -0,0 +1,347 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ | | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * ___|___/|_| ______| + * + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This source code is generated by optiontable.pl - DO NOT EDIT BY HAND */ + +#include "curl_setup.h" +#include "easyoptions.h" + +/* all easy setopt options listed in alphabetical order */ +struct curl_easyoption Curl_easyopts[] = { + {"ABSTRACT_UNIX_SOCKET", CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOT_STRING, 0}, + {"ACCEPTTIMEOUT_MS", CURLOPT_ACCEPTTIMEOUT_MS, CURLOT_LONG, 0}, + {"ACCEPT_ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, 0}, + {"ADDRESS_SCOPE", CURLOPT_ADDRESS_SCOPE, CURLOT_LONG, 0}, + {"ALTSVC", CURLOPT_ALTSVC, CURLOT_STRING, 0}, + {"ALTSVC_CTRL", CURLOPT_ALTSVC_CTRL, CURLOT_LONG, 0}, + {"APPEND", CURLOPT_APPEND, CURLOT_LONG, 0}, + {"AUTOREFERER", CURLOPT_AUTOREFERER, CURLOT_LONG, 0}, + {"BUFFERSIZE", CURLOPT_BUFFERSIZE, CURLOT_LONG, 0}, + {"CAINFO", CURLOPT_CAINFO, CURLOT_STRING, 0}, + {"CAPATH", CURLOPT_CAPATH, CURLOT_STRING, 0}, + {"CERTINFO", CURLOPT_CERTINFO, CURLOT_LONG, 0}, + {"CHUNK_BGN_FUNCTION", CURLOPT_CHUNK_BGN_FUNCTION, CURLOT_FUNCTION, 0}, + {"CHUNK_DATA", CURLOPT_CHUNK_DATA, CURLOT_CBPTR, 0}, + {"CHUNK_END_FUNCTION", CURLOPT_CHUNK_END_FUNCTION, CURLOT_FUNCTION, 0}, + {"CLOSESOCKETDATA", CURLOPT_CLOSESOCKETDATA, CURLOT_CBPTR, 0}, + {"CLOSESOCKETFUNCTION", CURLOPT_CLOSESOCKETFUNCTION, CURLOT_FUNCTION, 0}, + {"CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT, CURLOT_LONG, 0}, + {"CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS, CURLOT_LONG, 0}, + {"CONNECT_ONLY", CURLOPT_CONNECT_ONLY, CURLOT_LONG, 0}, + {"CONNECT_TO", CURLOPT_CONNECT_TO, CURLOT_SLIST, 0}, + {"CONV_FROM_NETWORK_FUNCTION", CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOT_FUNCTION, 0}, + {"CONV_FROM_UTF8_FUNCTION", CURLOPT_CONV_FROM_UTF8_FUNCTION, + CURLOT_FUNCTION, 0}, + {"CONV_TO_NETWORK_FUNCTION", CURLOPT_CONV_TO_NETWORK_FUNCTION, + CURLOT_FUNCTION, 0}, + {"COOKIE", CURLOPT_COOKIE, CURLOT_STRING, 0}, + {"COOKIEFILE", CURLOPT_COOKIEFILE, CURLOT_STRING, 0}, + {"COOKIEJAR", CURLOPT_COOKIEJAR, CURLOT_STRING, 0}, + {"COOKIELIST", CURLOPT_COOKIELIST, CURLOT_STRING, 0}, + {"COOKIESESSION", CURLOPT_COOKIESESSION, CURLOT_LONG, 0}, + {"COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS, CURLOT_OBJECT, 0}, + {"CRLF", CURLOPT_CRLF, CURLOT_LONG, 0}, + {"CRLFILE", CURLOPT_CRLFILE, CURLOT_STRING, 0}, + {"CURLU", CURLOPT_CURLU, CURLOT_OBJECT, 0}, + {"CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST, CURLOT_STRING, 0}, + {"DEBUGDATA", CURLOPT_DEBUGDATA, CURLOT_CBPTR, 0}, + {"DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION, CURLOT_FUNCTION, 0}, + {"DEFAULT_PROTOCOL", CURLOPT_DEFAULT_PROTOCOL, CURLOT_STRING, 0}, + {"DIRLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, 0}, + {"DISALLOW_USERNAME_IN_URL", CURLOPT_DISALLOW_USERNAME_IN_URL, + CURLOT_LONG, 0}, + {"DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT, CURLOT_LONG, 0}, + {"DNS_INTERFACE", CURLOPT_DNS_INTERFACE, CURLOT_STRING, 0}, + {"DNS_LOCAL_IP4", CURLOPT_DNS_LOCAL_IP4, CURLOT_STRING, 0}, + {"DNS_LOCAL_IP6", CURLOPT_DNS_LOCAL_IP6, CURLOT_STRING, 0}, + {"DNS_SERVERS", CURLOPT_DNS_SERVERS, CURLOT_STRING, 0}, + {"DNS_SHUFFLE_ADDRESSES", CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOT_LONG, 0}, + {"DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOT_LONG, 0}, + {"DOH_URL", CURLOPT_DOH_URL, CURLOT_STRING, 0}, + {"EGDSOCKET", CURLOPT_EGDSOCKET, CURLOT_STRING, 0}, + {"ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, CURLOT_FLAG_ALIAS}, + {"ERRORBUFFER", CURLOPT_ERRORBUFFER, CURLOT_OBJECT, 0}, + {"EXPECT_100_TIMEOUT_MS", CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOT_LONG, 0}, + {"FAILONERROR", CURLOPT_FAILONERROR, CURLOT_LONG, 0}, + {"FILE", CURLOPT_WRITEDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, + {"FILETIME", CURLOPT_FILETIME, CURLOT_LONG, 0}, + {"FNMATCH_DATA", CURLOPT_FNMATCH_DATA, CURLOT_CBPTR, 0}, + {"FNMATCH_FUNCTION", CURLOPT_FNMATCH_FUNCTION, CURLOT_FUNCTION, 0}, + {"FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION, CURLOT_LONG, 0}, + {"FORBID_REUSE", CURLOPT_FORBID_REUSE, CURLOT_LONG, 0}, + {"FRESH_CONNECT", CURLOPT_FRESH_CONNECT, CURLOT_LONG, 0}, + {"FTPAPPEND", CURLOPT_APPEND, CURLOT_LONG, CURLOT_FLAG_ALIAS}, + {"FTPLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, CURLOT_FLAG_ALIAS}, + {"FTPPORT", CURLOPT_FTPPORT, CURLOT_STRING, 0}, + {"FTPSSLAUTH", CURLOPT_FTPSSLAUTH, CURLOT_VALUES, 0}, + {"FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT, CURLOT_STRING, 0}, + {"FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER, + CURLOT_STRING, 0}, + {"FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS, + CURLOT_LONG, 0}, + {"FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD, CURLOT_VALUES, 0}, + {"FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOT_LONG, 0}, + {"FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP, CURLOT_LONG, 0}, + {"FTP_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, CURLOT_FLAG_ALIAS}, + {"FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC, CURLOT_LONG, 0}, + {"FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT, CURLOT_LONG, 0}, + {"FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV, CURLOT_LONG, 0}, + {"FTP_USE_PRET", CURLOPT_FTP_USE_PRET, CURLOT_LONG, 0}, + {"GSSAPI_DELEGATION", CURLOPT_GSSAPI_DELEGATION, CURLOT_VALUES, 0}, + {"HAPPY_EYEBALLS_TIMEOUT_MS", CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, + CURLOT_LONG, 0}, + {"HAPROXYPROTOCOL", CURLOPT_HAPROXYPROTOCOL, CURLOT_LONG, 0}, + {"HEADER", CURLOPT_HEADER, CURLOT_LONG, 0}, + {"HEADERDATA", CURLOPT_HEADERDATA, CURLOT_CBPTR, 0}, + {"HEADERFUNCTION", CURLOPT_HEADERFUNCTION, CURLOT_FUNCTION, 0}, + {"HEADEROPT", CURLOPT_HEADEROPT, CURLOT_VALUES, 0}, + {"HTTP09_ALLOWED", CURLOPT_HTTP09_ALLOWED, CURLOT_LONG, 0}, + {"HTTP200ALIASES", CURLOPT_HTTP200ALIASES, CURLOT_SLIST, 0}, + {"HTTPAUTH", CURLOPT_HTTPAUTH, CURLOT_VALUES, 0}, + {"HTTPGET", CURLOPT_HTTPGET, CURLOT_LONG, 0}, + {"HTTPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, 0}, + {"HTTPPOST", CURLOPT_HTTPPOST, CURLOT_OBJECT, 0}, + {"HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL, CURLOT_LONG, 0}, + {"HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING, CURLOT_LONG, 0}, + {"HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING, CURLOT_LONG, 0}, + {"HTTP_VERSION", CURLOPT_HTTP_VERSION, CURLOT_VALUES, 0}, + {"IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH, CURLOT_LONG, 0}, + {"INFILE", CURLOPT_READDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, + {"INFILESIZE", CURLOPT_INFILESIZE, CURLOT_LONG, 0}, + {"INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE, CURLOT_OFF_T, 0}, + {"INTERFACE", CURLOPT_INTERFACE, CURLOT_STRING, 0}, + {"INTERLEAVEDATA", CURLOPT_INTERLEAVEDATA, CURLOT_CBPTR, 0}, + {"INTERLEAVEFUNCTION", CURLOPT_INTERLEAVEFUNCTION, CURLOT_FUNCTION, 0}, + {"IOCTLDATA", CURLOPT_IOCTLDATA, CURLOT_CBPTR, 0}, + {"IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION, CURLOT_FUNCTION, 0}, + {"IPRESOLVE", CURLOPT_IPRESOLVE, CURLOT_VALUES, 0}, + {"ISSUERCERT", CURLOPT_ISSUERCERT, CURLOT_STRING, 0}, + {"ISSUERCERT_BLOB", CURLOPT_ISSUERCERT_BLOB, CURLOT_BLOB, 0}, + {"KEEP_SENDING_ON_ERROR", CURLOPT_KEEP_SENDING_ON_ERROR, CURLOT_LONG, 0}, + {"KEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, 0}, + {"KRB4LEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, CURLOT_FLAG_ALIAS}, + {"KRBLEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, 0}, + {"LOCALPORT", CURLOPT_LOCALPORT, CURLOT_LONG, 0}, + {"LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE, CURLOT_LONG, 0}, + {"LOGIN_OPTIONS", CURLOPT_LOGIN_OPTIONS, CURLOT_STRING, 0}, + {"LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT, CURLOT_LONG, 0}, + {"LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME, CURLOT_LONG, 0}, + {"MAIL_AUTH", CURLOPT_MAIL_AUTH, CURLOT_STRING, 0}, + {"MAIL_FROM", CURLOPT_MAIL_FROM, CURLOT_STRING, 0}, + {"MAIL_RCPT", CURLOPT_MAIL_RCPT, CURLOT_SLIST, 0}, + {"MAIL_RCPT_ALLLOWFAILS", CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOT_LONG, 0}, + {"MAXAGE_CONN", CURLOPT_MAXAGE_CONN, CURLOT_LONG, 0}, + {"MAXCONNECTS", CURLOPT_MAXCONNECTS, CURLOT_LONG, 0}, + {"MAXFILESIZE", CURLOPT_MAXFILESIZE, CURLOT_LONG, 0}, + {"MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE, CURLOT_OFF_T, 0}, + {"MAXREDIRS", CURLOPT_MAXREDIRS, CURLOT_LONG, 0}, + {"MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE, CURLOT_OFF_T, 0}, + {"MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE, CURLOT_OFF_T, 0}, + {"MIMEPOST", CURLOPT_MIMEPOST, CURLOT_OBJECT, 0}, + {"NETRC", CURLOPT_NETRC, CURLOT_VALUES, 0}, + {"NETRC_FILE", CURLOPT_NETRC_FILE, CURLOT_STRING, 0}, + {"NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS, CURLOT_LONG, 0}, + {"NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS, CURLOT_LONG, 0}, + {"NOBODY", CURLOPT_NOBODY, CURLOT_LONG, 0}, + {"NOPROGRESS", CURLOPT_NOPROGRESS, CURLOT_LONG, 0}, + {"NOPROXY", CURLOPT_NOPROXY, CURLOT_STRING, 0}, + {"NOSIGNAL", CURLOPT_NOSIGNAL, CURLOT_LONG, 0}, + {"OPENSOCKETDATA", CURLOPT_OPENSOCKETDATA, CURLOT_CBPTR, 0}, + {"OPENSOCKETFUNCTION", CURLOPT_OPENSOCKETFUNCTION, CURLOT_FUNCTION, 0}, + {"PASSWORD", CURLOPT_PASSWORD, CURLOT_STRING, 0}, + {"PATH_AS_IS", CURLOPT_PATH_AS_IS, CURLOT_LONG, 0}, + {"PINNEDPUBLICKEY", CURLOPT_PINNEDPUBLICKEY, CURLOT_STRING, 0}, + {"PIPEWAIT", CURLOPT_PIPEWAIT, CURLOT_LONG, 0}, + {"PORT", CURLOPT_PORT, CURLOT_LONG, 0}, + {"POST", CURLOPT_POST, CURLOT_LONG, 0}, + {"POST301", CURLOPT_POSTREDIR, CURLOT_VALUES, CURLOT_FLAG_ALIAS}, + {"POSTFIELDS", CURLOPT_POSTFIELDS, CURLOT_OBJECT, 0}, + {"POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE, CURLOT_LONG, 0}, + {"POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE, CURLOT_OFF_T, 0}, + {"POSTQUOTE", CURLOPT_POSTQUOTE, CURLOT_SLIST, 0}, + {"POSTREDIR", CURLOPT_POSTREDIR, CURLOT_VALUES, 0}, + {"PREQUOTE", CURLOPT_PREQUOTE, CURLOT_SLIST, 0}, + {"PRE_PROXY", CURLOPT_PRE_PROXY, CURLOT_STRING, 0}, + {"PRIVATE", CURLOPT_PRIVATE, CURLOT_OBJECT, 0}, + {"PROGRESSDATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, + {"PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION, CURLOT_FUNCTION, 0}, + {"PROTOCOLS", CURLOPT_PROTOCOLS, CURLOT_LONG, 0}, + {"PROXY", CURLOPT_PROXY, CURLOT_STRING, 0}, + {"PROXYAUTH", CURLOPT_PROXYAUTH, CURLOT_VALUES, 0}, + {"PROXYHEADER", CURLOPT_PROXYHEADER, CURLOT_SLIST, 0}, + {"PROXYPASSWORD", CURLOPT_PROXYPASSWORD, CURLOT_STRING, 0}, + {"PROXYPORT", CURLOPT_PROXYPORT, CURLOT_LONG, 0}, + {"PROXYTYPE", CURLOPT_PROXYTYPE, CURLOT_VALUES, 0}, + {"PROXYUSERNAME", CURLOPT_PROXYUSERNAME, CURLOT_STRING, 0}, + {"PROXYUSERPWD", CURLOPT_PROXYUSERPWD, CURLOT_STRING, 0}, + {"PROXY_CAINFO", CURLOPT_PROXY_CAINFO, CURLOT_STRING, 0}, + {"PROXY_CAPATH", CURLOPT_PROXY_CAPATH, CURLOT_STRING, 0}, + {"PROXY_CRLFILE", CURLOPT_PROXY_CRLFILE, CURLOT_STRING, 0}, + {"PROXY_ISSUERCERT", CURLOPT_PROXY_ISSUERCERT, CURLOT_STRING, 0}, + {"PROXY_ISSUERCERT_BLOB", CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOT_BLOB, 0}, + {"PROXY_KEYPASSWD", CURLOPT_PROXY_KEYPASSWD, CURLOT_STRING, 0}, + {"PROXY_PINNEDPUBLICKEY", CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOT_STRING, 0}, + {"PROXY_SERVICE_NAME", CURLOPT_PROXY_SERVICE_NAME, CURLOT_STRING, 0}, + {"PROXY_SSLCERT", CURLOPT_PROXY_SSLCERT, CURLOT_STRING, 0}, + {"PROXY_SSLCERTTYPE", CURLOPT_PROXY_SSLCERTTYPE, CURLOT_STRING, 0}, + {"PROXY_SSLCERT_BLOB", CURLOPT_PROXY_SSLCERT_BLOB, CURLOT_BLOB, 0}, + {"PROXY_SSLKEY", CURLOPT_PROXY_SSLKEY, CURLOT_STRING, 0}, + {"PROXY_SSLKEYTYPE", CURLOPT_PROXY_SSLKEYTYPE, CURLOT_STRING, 0}, + {"PROXY_SSLKEY_BLOB", CURLOPT_PROXY_SSLKEY_BLOB, CURLOT_BLOB, 0}, + {"PROXY_SSLVERSION", CURLOPT_PROXY_SSLVERSION, CURLOT_VALUES, 0}, + {"PROXY_SSL_CIPHER_LIST", CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOT_STRING, 0}, + {"PROXY_SSL_OPTIONS", CURLOPT_PROXY_SSL_OPTIONS, CURLOT_LONG, 0}, + {"PROXY_SSL_VERIFYHOST", CURLOPT_PROXY_SSL_VERIFYHOST, CURLOT_LONG, 0}, + {"PROXY_SSL_VERIFYPEER", CURLOPT_PROXY_SSL_VERIFYPEER, CURLOT_LONG, 0}, + {"PROXY_TLS13_CIPHERS", CURLOPT_PROXY_TLS13_CIPHERS, CURLOT_STRING, 0}, + {"PROXY_TLSAUTH_PASSWORD", CURLOPT_PROXY_TLSAUTH_PASSWORD, + CURLOT_STRING, 0}, + {"PROXY_TLSAUTH_TYPE", CURLOPT_PROXY_TLSAUTH_TYPE, CURLOT_STRING, 0}, + {"PROXY_TLSAUTH_USERNAME", CURLOPT_PROXY_TLSAUTH_USERNAME, + CURLOT_STRING, 0}, + {"PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE, CURLOT_LONG, 0}, + {"PUT", CURLOPT_PUT, CURLOT_LONG, 0}, + {"QUOTE", CURLOPT_QUOTE, CURLOT_SLIST, 0}, + {"RANDOM_FILE", CURLOPT_RANDOM_FILE, CURLOT_STRING, 0}, + {"RANGE", CURLOPT_RANGE, CURLOT_STRING, 0}, + {"READDATA", CURLOPT_READDATA, CURLOT_CBPTR, 0}, + {"READFUNCTION", CURLOPT_READFUNCTION, CURLOT_FUNCTION, 0}, + {"REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS, CURLOT_LONG, 0}, + {"REFERER", CURLOPT_REFERER, CURLOT_STRING, 0}, + {"REQUEST_TARGET", CURLOPT_REQUEST_TARGET, CURLOT_STRING, 0}, + {"RESOLVE", CURLOPT_RESOLVE, CURLOT_SLIST, 0}, + {"RESOLVER_START_DATA", CURLOPT_RESOLVER_START_DATA, CURLOT_CBPTR, 0}, + {"RESOLVER_START_FUNCTION", CURLOPT_RESOLVER_START_FUNCTION, + CURLOT_FUNCTION, 0}, + {"RESUME_FROM", CURLOPT_RESUME_FROM, CURLOT_LONG, 0}, + {"RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE, CURLOT_OFF_T, 0}, + {"RTSPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, CURLOT_FLAG_ALIAS}, + {"RTSP_CLIENT_CSEQ", CURLOPT_RTSP_CLIENT_CSEQ, CURLOT_LONG, 0}, + {"RTSP_REQUEST", CURLOPT_RTSP_REQUEST, CURLOT_VALUES, 0}, + {"RTSP_SERVER_CSEQ", CURLOPT_RTSP_SERVER_CSEQ, CURLOT_LONG, 0}, + {"RTSP_SESSION_ID", CURLOPT_RTSP_SESSION_ID, CURLOT_STRING, 0}, + {"RTSP_STREAM_URI", CURLOPT_RTSP_STREAM_URI, CURLOT_STRING, 0}, + {"RTSP_TRANSPORT", CURLOPT_RTSP_TRANSPORT, CURLOT_STRING, 0}, + {"SASL_AUTHZID", CURLOPT_SASL_AUTHZID, CURLOT_STRING, 0}, + {"SASL_IR", CURLOPT_SASL_IR, CURLOT_LONG, 0}, + {"SEEKDATA", CURLOPT_SEEKDATA, CURLOT_CBPTR, 0}, + {"SEEKFUNCTION", CURLOPT_SEEKFUNCTION, CURLOT_FUNCTION, 0}, + {"SERVER_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT, + CURLOT_LONG, CURLOT_FLAG_ALIAS}, + {"SERVICE_NAME", CURLOPT_SERVICE_NAME, CURLOT_STRING, 0}, + {"SHARE", CURLOPT_SHARE, CURLOT_OBJECT, 0}, + {"SOCKOPTDATA", CURLOPT_SOCKOPTDATA, CURLOT_CBPTR, 0}, + {"SOCKOPTFUNCTION", CURLOPT_SOCKOPTFUNCTION, CURLOT_FUNCTION, 0}, + {"SOCKS5_AUTH", CURLOPT_SOCKS5_AUTH, CURLOT_LONG, 0}, + {"SOCKS5_GSSAPI_NEC", CURLOPT_SOCKS5_GSSAPI_NEC, CURLOT_LONG, 0}, + {"SOCKS5_GSSAPI_SERVICE", CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOT_STRING, 0}, + {"SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES, CURLOT_VALUES, 0}, + {"SSH_COMPRESSION", CURLOPT_SSH_COMPRESSION, CURLOT_LONG, 0}, + {"SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, + CURLOT_STRING, 0}, + {"SSH_KEYDATA", CURLOPT_SSH_KEYDATA, CURLOT_CBPTR, 0}, + {"SSH_KEYFUNCTION", CURLOPT_SSH_KEYFUNCTION, CURLOT_FUNCTION, 0}, + {"SSH_KNOWNHOSTS", CURLOPT_SSH_KNOWNHOSTS, CURLOT_STRING, 0}, + {"SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE, CURLOT_STRING, 0}, + {"SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE, CURLOT_STRING, 0}, + {"SSLCERT", CURLOPT_SSLCERT, CURLOT_STRING, 0}, + {"SSLCERTPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS}, + {"SSLCERTTYPE", CURLOPT_SSLCERTTYPE, CURLOT_STRING, 0}, + {"SSLCERT_BLOB", CURLOPT_SSLCERT_BLOB, CURLOT_BLOB, 0}, + {"SSLENGINE", CURLOPT_SSLENGINE, CURLOT_STRING, 0}, + {"SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT, CURLOT_LONG, 0}, + {"SSLKEY", CURLOPT_SSLKEY, CURLOT_STRING, 0}, + {"SSLKEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS}, + {"SSLKEYTYPE", CURLOPT_SSLKEYTYPE, CURLOT_STRING, 0}, + {"SSLKEY_BLOB", CURLOPT_SSLKEY_BLOB, CURLOT_BLOB, 0}, + {"SSLVERSION", CURLOPT_SSLVERSION, CURLOT_VALUES, 0}, + {"SSL_CIPHER_LIST", CURLOPT_SSL_CIPHER_LIST, CURLOT_STRING, 0}, + {"SSL_CTX_DATA", CURLOPT_SSL_CTX_DATA, CURLOT_CBPTR, 0}, + {"SSL_CTX_FUNCTION", CURLOPT_SSL_CTX_FUNCTION, CURLOT_FUNCTION, 0}, + {"SSL_EC_CURVES", CURLOPT_SSL_EC_CURVES, CURLOT_STRING, 0}, + {"SSL_ENABLE_ALPN", CURLOPT_SSL_ENABLE_ALPN, CURLOT_LONG, 0}, + {"SSL_ENABLE_NPN", CURLOPT_SSL_ENABLE_NPN, CURLOT_LONG, 0}, + {"SSL_FALSESTART", CURLOPT_SSL_FALSESTART, CURLOT_LONG, 0}, + {"SSL_OPTIONS", CURLOPT_SSL_OPTIONS, CURLOT_VALUES, 0}, + {"SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE, CURLOT_LONG, 0}, + {"SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST, CURLOT_LONG, 0}, + {"SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER, CURLOT_LONG, 0}, + {"SSL_VERIFYSTATUS", CURLOPT_SSL_VERIFYSTATUS, CURLOT_LONG, 0}, + {"STDERR", CURLOPT_STDERR, CURLOT_OBJECT, 0}, + {"STREAM_DEPENDS", CURLOPT_STREAM_DEPENDS, CURLOT_OBJECT, 0}, + {"STREAM_DEPENDS_E", CURLOPT_STREAM_DEPENDS_E, CURLOT_OBJECT, 0}, + {"STREAM_WEIGHT", CURLOPT_STREAM_WEIGHT, CURLOT_LONG, 0}, + {"SUPPRESS_CONNECT_HEADERS", CURLOPT_SUPPRESS_CONNECT_HEADERS, + CURLOT_LONG, 0}, + {"TCP_FASTOPEN", CURLOPT_TCP_FASTOPEN, CURLOT_LONG, 0}, + {"TCP_KEEPALIVE", CURLOPT_TCP_KEEPALIVE, CURLOT_LONG, 0}, + {"TCP_KEEPIDLE", CURLOPT_TCP_KEEPIDLE, CURLOT_LONG, 0}, + {"TCP_KEEPINTVL", CURLOPT_TCP_KEEPINTVL, CURLOT_LONG, 0}, + {"TCP_NODELAY", CURLOPT_TCP_NODELAY, CURLOT_LONG, 0}, + {"TELNETOPTIONS", CURLOPT_TELNETOPTIONS, CURLOT_SLIST, 0}, + {"TFTP_BLKSIZE", CURLOPT_TFTP_BLKSIZE, CURLOT_LONG, 0}, + {"TFTP_NO_OPTIONS", CURLOPT_TFTP_NO_OPTIONS, CURLOT_LONG, 0}, + {"TIMECONDITION", CURLOPT_TIMECONDITION, CURLOT_VALUES, 0}, + {"TIMEOUT", CURLOPT_TIMEOUT, CURLOT_LONG, 0}, + {"TIMEOUT_MS", CURLOPT_TIMEOUT_MS, CURLOT_LONG, 0}, + {"TIMEVALUE", CURLOPT_TIMEVALUE, CURLOT_LONG, 0}, + {"TIMEVALUE_LARGE", CURLOPT_TIMEVALUE_LARGE, CURLOT_OFF_T, 0}, + {"TLS13_CIPHERS", CURLOPT_TLS13_CIPHERS, CURLOT_STRING, 0}, + {"TLSAUTH_PASSWORD", CURLOPT_TLSAUTH_PASSWORD, CURLOT_STRING, 0}, + {"TLSAUTH_TYPE", CURLOPT_TLSAUTH_TYPE, CURLOT_STRING, 0}, + {"TLSAUTH_USERNAME", CURLOPT_TLSAUTH_USERNAME, CURLOT_STRING, 0}, + {"TRAILERDATA", CURLOPT_TRAILERDATA, CURLOT_CBPTR, 0}, + {"TRAILERFUNCTION", CURLOPT_TRAILERFUNCTION, CURLOT_FUNCTION, 0}, + {"TRANSFERTEXT", CURLOPT_TRANSFERTEXT, CURLOT_LONG, 0}, + {"TRANSFER_ENCODING", CURLOPT_TRANSFER_ENCODING, CURLOT_LONG, 0}, + {"UNIX_SOCKET_PATH", CURLOPT_UNIX_SOCKET_PATH, CURLOT_STRING, 0}, + {"UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH, CURLOT_LONG, 0}, + {"UPKEEP_INTERVAL_MS", CURLOPT_UPKEEP_INTERVAL_MS, CURLOT_LONG, 0}, + {"UPLOAD", CURLOPT_UPLOAD, CURLOT_LONG, 0}, + {"UPLOAD_BUFFERSIZE", CURLOPT_UPLOAD_BUFFERSIZE, CURLOT_LONG, 0}, + {"URL", CURLOPT_URL, CURLOT_STRING, 0}, + {"USERAGENT", CURLOPT_USERAGENT, CURLOT_STRING, 0}, + {"USERNAME", CURLOPT_USERNAME, CURLOT_STRING, 0}, + {"USERPWD", CURLOPT_USERPWD, CURLOT_STRING, 0}, + {"USE_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, 0}, + {"VERBOSE", CURLOPT_VERBOSE, CURLOT_LONG, 0}, + {"WILDCARDMATCH", CURLOPT_WILDCARDMATCH, CURLOT_LONG, 0}, + {"WRITEDATA", CURLOPT_WRITEDATA, CURLOT_CBPTR, 0}, + {"WRITEFUNCTION", CURLOPT_WRITEFUNCTION, CURLOT_FUNCTION, 0}, + {"WRITEHEADER", CURLOPT_HEADERDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, + {"XFERINFODATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, 0}, + {"XFERINFOFUNCTION", CURLOPT_XFERINFOFUNCTION, CURLOT_FUNCTION, 0}, + {"XOAUTH2_BEARER", CURLOPT_XOAUTH2_BEARER, CURLOT_STRING, 0}, + {NULL, CURLOPT_LASTENTRY, 0, 0} /* end of table */ +}; + +#ifdef DEBUGBUILD +/* + * Curl_easyopts_check() is a debug-only function that returns non-zero + * if this source file is not in sync with the options listed in curl/curl.h + */ +int Curl_easyopts_check(void) +{ + return (CURLOPT_LASTENTRY != (298 + 1)); +} +#endif diff --git a/libs/libcurl/src/easyoptions.h b/libs/libcurl/src/easyoptions.h new file mode 100644 index 0000000000..cd8b4100dc --- /dev/null +++ b/libs/libcurl/src/easyoptions.h @@ -0,0 +1,35 @@ +#ifndef HEADER_CURL_EASYOPTIONS_H +#define HEADER_CURL_EASYOPTIONS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* should probably go into the public header */ + +#include <curl/curl.h> + +/* generated table with all easy options */ +extern struct curl_easyoption Curl_easyopts[]; + +#ifdef DEBUGBUILD +int Curl_easyopts_check(void); +#endif +#endif diff --git a/libs/libcurl/src/file.c b/libs/libcurl/src/file.c index cd3e49c339..1872dfef0d 100644 --- a/libs/libcurl/src/file.c +++ b/libs/libcurl/src/file.c @@ -67,8 +67,7 @@ #include "curl_memory.h" #include "memdebug.h" -#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \ - defined(__SYMBIAN32__) +#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) #define DOS_FILESYSTEM 1 #endif @@ -112,6 +111,7 @@ const struct Curl_handler Curl_handler_file = { ZERO_NULL, /* connection_check */ 0, /* defport */ CURLPROTO_FILE, /* protocol */ + CURLPROTO_FILE, /* family */ PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */ }; diff --git a/libs/libcurl/src/fileinfo.h b/libs/libcurl/src/fileinfo.h index f4d8f3b90e..fdbad8bf2e 100644 --- a/libs/libcurl/src/fileinfo.h +++ b/libs/libcurl/src/fileinfo.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -27,7 +27,7 @@ struct fileinfo { struct curl_fileinfo info; - struct curl_llist_element list; + struct Curl_llist_element list; }; struct fileinfo *Curl_fileinfo_alloc(void); diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c index 9fadac5138..11031da6fb 100644 --- a/libs/libcurl/src/ftp.c +++ b/libs/libcurl/src/ftp.c @@ -59,7 +59,7 @@ #include "fileinfo.h" #include "ftplistparser.h" #include "curl_range.h" -#include "curl_sec.h" +#include "curl_krb5.h" #include "strtoofft.h" #include "strcase.h" #include "vtls/vtls.h" @@ -137,14 +137,10 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks); static CURLcode ftp_doing(struct connectdata *conn, bool *dophase_done); static CURLcode ftp_setup_connection(struct connectdata *conn); - static CURLcode init_wc_data(struct connectdata *conn); static CURLcode wc_statemach(struct connectdata *conn); - static void wc_data_dtor(void *ptr); - static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize); - static CURLcode ftp_readresp(curl_socket_t sockfd, struct pingpong *pp, int *ftpcode, @@ -152,12 +148,6 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, static CURLcode ftp_dophase_done(struct connectdata *conn, bool connected); -/* easy-to-use macro: */ -#define PPSENDF(x,y,z) result = Curl_pp_sendf(x,y,z); \ - if(result) \ - return result - - /* * FTP protocol handler. */ @@ -180,6 +170,7 @@ const struct Curl_handler Curl_handler_ftp = { ZERO_NULL, /* connection_check */ PORT_FTP, /* defport */ CURLPROTO_FTP, /* protocol */ + CURLPROTO_FTP, /* family */ PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP | PROTOPT_WILDCARD /* flags */ @@ -209,6 +200,7 @@ const struct Curl_handler Curl_handler_ftps = { ZERO_NULL, /* connection_check */ PORT_FTPS, /* defport */ CURLPROTO_FTPS, /* protocol */ + CURLPROTO_FTP, /* family */ PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD /* flags */ }; @@ -775,25 +767,22 @@ static void _state(struct connectdata *conn, static CURLcode ftp_state_user(struct connectdata *conn) { - CURLcode result; - /* send USER */ - PPSENDF(&conn->proto.ftpc.pp, "USER %s", conn->user?conn->user:""); - - state(conn, FTP_USER); - conn->data->state.ftp_trying_alternative = FALSE; - - return CURLE_OK; + CURLcode result = Curl_pp_sendf(&conn->proto.ftpc.pp, "USER %s", + conn->user?conn->user:""); + if(!result) { + state(conn, FTP_USER); + conn->data->state.ftp_trying_alternative = FALSE; + } + return result; } static CURLcode ftp_state_pwd(struct connectdata *conn) { - CURLcode result; - - /* send PWD to discover our entry point */ - PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD"); - state(conn, FTP_PWD); + CURLcode result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "PWD"); + if(!result) + state(conn, FTP_PWD); - return CURLE_OK; + return result; } /* For the FTP "protocol connect" and "doing" phases only */ @@ -881,16 +870,19 @@ static CURLcode ftp_state_cwd(struct connectdata *conn) where we ended up after login: */ ftpc->cwdcount = 0; /* we count this as the first path, then we add one for all upcoming ones in the ftp->dirs[] array */ - PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath); - state(conn, FTP_CWD); + result = Curl_pp_sendf(&ftpc->pp, "CWD %s", ftpc->entrypath); + if(!result) + state(conn, FTP_CWD); } else { if(ftpc->dirdepth) { ftpc->cwdcount = 1; /* issue the first CWD, the rest is sent when the CWD responses are received... */ - PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->cwdcount -1]); - state(conn, FTP_CWD); + result = Curl_pp_sendf(&ftpc->pp, "CWD %s", + ftpc->dirs[ftpc->cwdcount -1]); + if(!result) + state(conn, FTP_CWD); } else { /* No CWD necessary */ @@ -1326,12 +1318,12 @@ static CURLcode ftp_state_use_pasv(struct connectdata *conn) modeoff = conn->bits.ftp_use_epsv?0:1; - PPSENDF(&ftpc->pp, "%s", mode[modeoff]); - - ftpc->count1 = modeoff; - state(conn, FTP_PASV); - infof(conn->data, "Connect data stream passively\n"); - + result = Curl_pp_sendf(&ftpc->pp, "%s", mode[modeoff]); + if(!result) { + ftpc->count1 = modeoff; + state(conn, FTP_PASV); + infof(conn->data, "Connect data stream passively\n"); + } return result; } @@ -1364,23 +1356,23 @@ static CURLcode ftp_state_prepare_transfer(struct connectdata *conn) if(data->set.ftp_use_pret) { /* The user has requested that we send a PRET command to prepare the server for the upcoming PASV */ - if(!conn->proto.ftpc.file) { - PPSENDF(&conn->proto.ftpc.pp, "PRET %s", - data->set.str[STRING_CUSTOMREQUEST]? - data->set.str[STRING_CUSTOMREQUEST]: - (data->set.ftp_list_only?"NLST":"LIST")); - } - else if(data->set.upload) { - PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file); - } - else { - PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file); - } - state(conn, FTP_PRET); + struct ftp_conn *ftpc = &conn->proto.ftpc; + if(!conn->proto.ftpc.file) + result = Curl_pp_sendf(&ftpc->pp, "PRET %s", + data->set.str[STRING_CUSTOMREQUEST]? + data->set.str[STRING_CUSTOMREQUEST]: + (data->set.ftp_list_only?"NLST":"LIST")); + else if(data->set.upload) + result = Curl_pp_sendf(&ftpc->pp, "PRET STOR %s", + conn->proto.ftpc.file); + else + result = Curl_pp_sendf(&ftpc->pp, "PRET RETR %s", + conn->proto.ftpc.file); + if(!result) + state(conn, FTP_PRET); } - else { + else result = ftp_state_use_pasv(conn); - } } return result; } @@ -1396,9 +1388,9 @@ static CURLcode ftp_state_rest(struct connectdata *conn) /* Determine if server can respond to REST command and therefore whether it supports range */ - PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0); - - state(conn, FTP_REST); + result = Curl_pp_sendf(&ftpc->pp, "REST %d", 0); + if(!result) + state(conn, FTP_REST); } else result = ftp_state_prepare_transfer(conn); @@ -1416,9 +1408,9 @@ static CURLcode ftp_state_size(struct connectdata *conn) /* if a "head"-like request is being made (on a file) */ /* we know ftpc->file is a valid pointer to a file name */ - PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); - - state(conn, FTP_SIZE); + result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file); + if(!result) + state(conn, FTP_SIZE); } else result = ftp_state_rest(conn); @@ -1485,10 +1477,8 @@ static CURLcode ftp_state_list(struct connectdata *conn) result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd); free(cmd); - if(result) - return result; - - state(conn, FTP_LIST); + if(!result) + state(conn, FTP_LIST); return result; } @@ -1549,9 +1539,10 @@ static CURLcode ftp_state_mdtm(struct connectdata *conn) /* we have requested to get the modified-time of the file, this is a white spot as the MDTM is not mentioned in RFC959 */ - PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file); + result = Curl_pp_sendf(&ftpc->pp, "MDTM %s", ftpc->file); - state(conn, FTP_MDTM); + if(!result) + state(conn, FTP_MDTM); } else result = ftp_state_type(conn); @@ -1587,8 +1578,9 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn, if(data->state.resume_from < 0) { /* Got no given size to start from, figure it out */ - PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); - state(conn, FTP_STOR_SIZE); + result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file); + if(!result) + state(conn, FTP_STOR_SIZE); return result; } @@ -1650,10 +1642,10 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn, /* we've passed, proceed as normal */ } /* resume_from */ - PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s", - ftpc->file); - - state(conn, FTP_STOR); + result = Curl_pp_sendf(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s", + ftpc->file); + if(!result) + state(conn, FTP_STOR); return result; } @@ -1711,7 +1703,9 @@ static CURLcode ftp_state_quote(struct connectdata *conn, else ftpc->count2 = 0; /* failure means cancel operation */ - PPSENDF(&ftpc->pp, "%s", cmd); + result = Curl_pp_sendf(&ftpc->pp, "%s", cmd); + if(result) + return result; state(conn, instate); quote = TRUE; } @@ -1740,12 +1734,14 @@ static CURLcode ftp_state_quote(struct connectdata *conn, the server terminates it, otherwise the client stops if the received byte count exceeds the reported file size. Set option CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/ - PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); - state(conn, FTP_RETR); + result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file); + if(!result) + state(conn, FTP_RETR); } else { - PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); - state(conn, FTP_RETR_SIZE); + result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file); + if(!result) + state(conn, FTP_RETR_SIZE); } } } @@ -1782,10 +1778,12 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn) conn->bits.ftp_use_epsv = FALSE; conn->data->state.errorbuf = FALSE; /* allow error message to get rewritten */ - PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV"); - conn->proto.ftpc.count1++; - /* remain in/go to the FTP_PASV state */ - state(conn, FTP_PASV); + result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "PASV"); + if(!result) { + conn->proto.ftpc.count1++; + /* remain in/go to the FTP_PASV state */ + state(conn, FTP_PASV); + } return result; } @@ -1864,8 +1862,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, else if((ftpc->count1 == 1) && (ftpcode == 227)) { /* positive PASV response */ - unsigned int ip[4]; - unsigned int port[2]; + unsigned int ip[4] = {0, 0, 0, 0}; + unsigned int port[2] = {0, 0}; /* * Scan for a sequence of six comma-separated numbers and use them as @@ -2092,7 +2090,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn, break; case 550: /* "No such file or directory" */ failf(data, "Given file does not exist"); - result = CURLE_FTP_COULDNT_RETR_FILE; + result = CURLE_REMOTE_FILE_NOT_FOUND; break; } @@ -2229,15 +2227,16 @@ static CURLcode ftp_state_retr(struct connectdata *conn, infof(data, "Instructs server to resume from offset %" CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); - PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T, - data->state.resume_from); - - state(conn, FTP_RETR_REST); + result = Curl_pp_sendf(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T, + data->state.resume_from); + if(!result) + state(conn, FTP_RETR_REST); } else { /* no resume */ - PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); - state(conn, FTP_RETR); + result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file); + if(!result) + state(conn, FTP_RETR); } return result; @@ -2272,6 +2271,10 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn, (void)curlx_strtoofft(fdigit, NULL, 0, &filesize); } + else if(ftpcode == 550) { /* "No such file or directory" */ + failf(data, "The file does not exist"); + return CURLE_REMOTE_FILE_NOT_FOUND; + } if(instate == FTP_SIZE) { #ifdef CURL_FTP_HTTPSTYLE_HEAD @@ -2326,8 +2329,9 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn, result = CURLE_FTP_COULDNT_USE_REST; } else { - PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); - state(conn, FTP_RETR); + result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file); + if(!result) + state(conn, FTP_RETR); } break; } @@ -2504,7 +2508,7 @@ static CURLcode ftp_state_loggedin(struct connectdata *conn) { CURLcode result = CURLE_OK; - if(conn->ssl[FIRSTSOCKET].use) { + if(conn->bits.ftp_use_control_ssl) { /* PBSZ = PROTECTION BUFFER SIZE. The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says: @@ -2519,8 +2523,9 @@ static CURLcode ftp_state_loggedin(struct connectdata *conn) parameter of '0' to indicate that no buffering is taking place and the data connection should not be encapsulated. */ - PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0); - state(conn, FTP_PBSZ); + result = Curl_pp_sendf(&conn->proto.ftpc.pp, "PBSZ %d", 0); + if(!result) + state(conn, FTP_PBSZ); } else { result = ftp_state_pwd(conn); @@ -2542,8 +2547,9 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn, if((ftpcode == 331) && (ftpc->state == FTP_USER)) { /* 331 Password required for ... (the server requires to send the user's password too) */ - PPSENDF(&ftpc->pp, "PASS %s", conn->passwd?conn->passwd:""); - state(conn, FTP_PASS); + result = Curl_pp_sendf(&ftpc->pp, "PASS %s", conn->passwd?conn->passwd:""); + if(!result) + state(conn, FTP_PASS); } else if(ftpcode/100 == 2) { /* 230 User ... logged in. @@ -2552,8 +2558,10 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn, } else if(ftpcode == 332) { if(data->set.str[STRING_FTP_ACCOUNT]) { - PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]); - state(conn, FTP_ACCT); + result = Curl_pp_sendf(&ftpc->pp, "ACCT %s", + data->set.str[STRING_FTP_ACCOUNT]); + if(!result) + state(conn, FTP_ACCT); } else { failf(data, "ACCT requested but none available"); @@ -2569,11 +2577,13 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn, if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] && !conn->data->state.ftp_trying_alternative) { /* Ok, USER failed. Let's try the supplied command. */ - PPSENDF(&conn->proto.ftpc.pp, "%s", - conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); - conn->data->state.ftp_trying_alternative = TRUE; - state(conn, FTP_USER); - result = CURLE_OK; + result = + Curl_pp_sendf(&ftpc->pp, "%s", + conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); + if(!result) { + conn->data->state.ftp_trying_alternative = TRUE; + state(conn, FTP_USER); + } } else { failf(data, "Access denied: %03d", ftpcode); @@ -2649,14 +2659,8 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) } #endif - if(data->set.use_ssl && - (!conn->ssl[FIRSTSOCKET].use -#ifndef CURL_DISABLE_PROXY - || (conn->bits.proxy_ssl_connected[FIRSTSOCKET] && - !conn->proxy_ssl[FIRSTSOCKET].use) -#endif - )) { - /* We don't have a SSL/TLS connection yet, but FTPS is + if(data->set.use_ssl && !conn->bits.ftp_use_control_ssl) { + /* We don't have a SSL/TLS control connection yet, but FTPS is requested. Try a FTPS connection now */ ftpc->count3 = 0; @@ -2675,15 +2679,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) (int)data->set.ftpsslauth); return CURLE_UNKNOWN_OPTION; /* we don't know what to do */ } - PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]); - state(conn, FTP_AUTH); + result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]); + if(!result) + state(conn, FTP_AUTH); } - else { + else result = ftp_state_user(conn); - if(result) - return result; - } - break; case FTP_AUTH: @@ -2701,6 +2702,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) result = Curl_ssl_connect(conn, FIRSTSOCKET); if(!result) { conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */ + conn->bits.ftp_use_control_ssl = TRUE; /* SSL on control */ result = ftp_state_user(conn); } } @@ -2718,9 +2720,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) /* ignore the failure and continue */ result = ftp_state_user(conn); } - - if(result) - return result; break; case FTP_USER: @@ -2733,10 +2732,11 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) break; case FTP_PBSZ: - PPSENDF(&ftpc->pp, "PROT %c", - data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P'); - state(conn, FTP_PROT); - + result = + Curl_pp_sendf(&ftpc->pp, "PROT %c", + data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P'); + if(!result) + state(conn, FTP_PROT); break; case FTP_PROT: @@ -2753,14 +2753,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) if(data->set.ftp_ccc) { /* CCC - Clear Command Channel */ - PPSENDF(&ftpc->pp, "%s", "CCC"); - state(conn, FTP_CCC); + result = Curl_pp_sendf(&ftpc->pp, "%s", "CCC"); + if(!result) + state(conn, FTP_CCC); } - else { + else result = ftp_state_pwd(conn); - if(result) - return result; - } break; case FTP_CCC: @@ -2768,16 +2766,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) /* First shut down the SSL layer (note: this call will block) */ result = Curl_ssl_shutdown(conn, FIRSTSOCKET); - if(result) { + if(result) failf(conn->data, "Failed to clear the command channel (CCC)"); - return result; - } } - - /* Then continue as normal */ - result = ftp_state_pwd(conn); - if(result) - return result; + if(!result) + /* Then continue as normal */ + result = ftp_state_pwd(conn); break; case FTP_PWD: @@ -2843,7 +2837,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) systems. */ if(!ftpc->server_os && dir[0] != '/') { - result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST"); if(result) { free(dir); @@ -2939,12 +2932,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) if((ftpcode >= 400) && !ftpc->count2) { /* failure response code, and not allowed to fail */ failf(conn->data, "QUOT command failed with %03d", ftpcode); - return CURLE_QUOTE_ERROR; + result = CURLE_QUOTE_ERROR; } - result = ftp_state_quote(conn, FALSE, ftpc->state); - if(result) - return result; - + else + result = ftp_state_quote(conn, FALSE, ftpc->state); break; case FTP_CWD: @@ -2954,29 +2945,28 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) ftpc->cwdcount && !ftpc->count2) { /* try making it */ ftpc->count2++; /* counter to prevent CWD-MKD loops */ - PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->cwdcount - 1]); - state(conn, FTP_MKD); + result = Curl_pp_sendf(&ftpc->pp, "MKD %s", + ftpc->dirs[ftpc->cwdcount - 1]); + if(!result) + state(conn, FTP_MKD); } else { /* return failure */ failf(data, "Server denied you to change to the given directory"); ftpc->cwdfail = TRUE; /* don't remember this path as we failed to enter it */ - return CURLE_REMOTE_ACCESS_DENIED; + result = CURLE_REMOTE_ACCESS_DENIED; } } else { /* success */ ftpc->count2 = 0; - if(++ftpc->cwdcount <= ftpc->dirdepth) { + if(++ftpc->cwdcount <= ftpc->dirdepth) /* send next CWD */ - PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]); - } - else { + result = Curl_pp_sendf(&ftpc->pp, "CWD %s", + ftpc->dirs[ftpc->cwdcount - 1]); + else result = ftp_state_mdtm(conn); - if(result) - return result; - } } break; @@ -2984,11 +2974,14 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) if((ftpcode/100 != 2) && !ftpc->count3--) { /* failure to MKD the dir */ failf(data, "Failed to MKD dir: %03d", ftpcode); - return CURLE_REMOTE_ACCESS_DENIED; + result = CURLE_REMOTE_ACCESS_DENIED; + } + else { + state(conn, FTP_CWD); + /* send CWD */ + result = Curl_pp_sendf(&ftpc->pp, "CWD %s", + ftpc->dirs[ftpc->cwdcount - 1]); } - state(conn, FTP_CWD); - /* send CWD */ - PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]); break; case FTP_MDTM: @@ -3091,7 +3084,7 @@ static CURLcode ftp_block_statemach(struct connectdata *conn) * */ static CURLcode ftp_connect(struct connectdata *conn, - bool *done) /* see description above */ + bool *done) /* see description above */ { CURLcode result; struct ftp_conn *ftpc = &conn->proto.ftpc; @@ -3112,8 +3105,10 @@ static CURLcode ftp_connect(struct connectdata *conn, result = Curl_ssl_connect(conn, FIRSTSOCKET); if(result) return result; + conn->bits.ftp_use_control_ssl = TRUE; } + Curl_pp_setup(pp); /* once per transfer */ Curl_pp_init(pp); /* init the generic pingpong data */ /* When we connect, we start in the state where we await the 220 @@ -3297,9 +3292,18 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, if(!ftpc->dont_check) { /* 226 Transfer complete, 250 Requested file action okay, completed. */ - if((ftpcode != 226) && (ftpcode != 250)) { + switch(ftpcode) { + case 226: + case 250: + break; + case 552: + failf(data, "Exceeded storage allocation"); + result = CURLE_REMOTE_DISK_FULL; + break; + default: failf(data, "server did not report OK, got %d", ftpcode); result = CURLE_PARTIAL_FILE; + break; } } } @@ -3368,17 +3372,17 @@ static CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote) { struct curl_slist *item; - ssize_t nread; - int ftpcode; - CURLcode result; struct ftp_conn *ftpc = &conn->proto.ftpc; struct pingpong *pp = &ftpc->pp; item = quote; while(item) { if(item->data) { + ssize_t nread; char *cmd = item->data; bool acceptfail = FALSE; + CURLcode result; + int ftpcode = 0; /* if a command starts with an asterisk, which a legal FTP command never can, the command will be allowed to fail without it causing any @@ -3390,11 +3394,11 @@ CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote) acceptfail = TRUE; } - PPSENDF(&conn->proto.ftpc.pp, "%s", cmd); - - pp->response = Curl_now(); /* timeout relative now */ - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); + result = Curl_pp_sendf(&ftpc->pp, "%s", cmd); + if(!result) { + pp->response = Curl_now(); /* timeout relative now */ + result = Curl_GetFTPResponse(&nread, conn, &ftpcode); + } if(result) return result; @@ -3442,12 +3446,14 @@ static CURLcode ftp_nb_type(struct connectdata *conn, return ftp_state_type_resp(conn, 200, newstate); } - PPSENDF(&ftpc->pp, "TYPE %c", want); - state(conn, newstate); + result = Curl_pp_sendf(&ftpc->pp, "TYPE %c", want); + if(!result) { + state(conn, newstate); - /* keep track of our current transfer type */ - ftpc->transfertype = want; - return CURLE_OK; + /* keep track of our current transfer type */ + ftpc->transfertype = want; + } + return result; } /*************************************************************************** @@ -3947,64 +3953,6 @@ static CURLcode ftp_do(struct connectdata *conn, bool *done) return result; } - -CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd) -{ - ssize_t bytes_written; -#define SBUF_SIZE 1024 - char s[SBUF_SIZE]; - size_t write_len; - char *sptr = s; - CURLcode result = CURLE_OK; -#ifdef HAVE_GSSAPI - enum protection_level data_sec = conn->data_prot; -#endif - - if(!cmd) - return CURLE_BAD_FUNCTION_ARGUMENT; - - write_len = strlen(cmd); - if(!write_len || write_len > (sizeof(s) -3)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - memcpy(&s, cmd, write_len); - strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */ - write_len += 2; - bytes_written = 0; - - result = Curl_convert_to_network(conn->data, s, write_len); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) - return result; - - for(;;) { -#ifdef HAVE_GSSAPI - conn->data_prot = PROT_CMD; -#endif - result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, - &bytes_written); -#ifdef HAVE_GSSAPI - DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); - conn->data_prot = data_sec; -#endif - - if(result) - break; - - if(conn->data->set.verbose) - Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written); - - if(bytes_written != (ssize_t)write_len) { - write_len -= bytes_written; - sptr += bytes_written; - } - else - break; - } - - return result; -} - /*********************************************************************** * * ftp_quit() @@ -4068,22 +4016,14 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection) if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) { data->state.most_recent_ftp_entrypath = NULL; } - free(ftpc->entrypath); - ftpc->entrypath = NULL; + Curl_safefree(ftpc->entrypath); } freedirs(ftpc); - free(ftpc->prevpath); - ftpc->prevpath = NULL; - free(ftpc->server_os); - ftpc->server_os = NULL; - + Curl_safefree(ftpc->prevpath); + Curl_safefree(ftpc->server_os); Curl_pp_disconnect(pp); - -#ifdef HAVE_GSSAPI Curl_sec_end(conn); -#endif - return CURLE_OK; } diff --git a/libs/libcurl/src/ftp.h b/libs/libcurl/src/ftp.h index 06421c6a40..dbbdeb7cc9 100644 --- a/libs/libcurl/src/ftp.h +++ b/libs/libcurl/src/ftp.h @@ -31,7 +31,6 @@ extern const struct Curl_handler Curl_handler_ftp; extern const struct Curl_handler Curl_handler_ftps; #endif -CURLcode Curl_ftpsend(struct connectdata *, const char *cmd); CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn, int *ftpcode); #endif /* CURL_DISABLE_FTP */ diff --git a/libs/libcurl/src/ftplistparser.c b/libs/libcurl/src/ftplistparser.c index f399a4c272..c7b84a9ffd 100644 --- a/libs/libcurl/src/ftplistparser.c +++ b/libs/libcurl/src/ftplistparser.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -274,7 +274,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn, curl_fnmatch_callback compare; struct WildcardData *wc = &conn->data->wildcard; struct ftp_wc *ftpwc = wc->protdata; - struct curl_llist *llist = &wc->filelist; + struct Curl_llist *llist = &wc->filelist; struct ftp_parselist_data *parser = ftpwc->parser; bool add = TRUE; struct curl_fileinfo *finfo = &infop->info; @@ -418,8 +418,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, finfo->b_data[parser->item_length - 1] = 0; if(strncmp("total ", finfo->b_data, 6) == 0) { char *endptr = finfo->b_data + 6; - /* here we can deal with directory size, pass the leading white - spaces and then the digits */ + /* here we can deal with directory size, pass the leading + whitespace and then the digits */ while(ISSPACE(*endptr)) endptr++; while(ISDIGIT(*endptr)) diff --git a/libs/libcurl/src/getinfo.c b/libs/libcurl/src/getinfo.c index 82691dcc71..49e79e476f 100644 --- a/libs/libcurl/src/getinfo.c +++ b/libs/libcurl/src/getinfo.c @@ -269,6 +269,9 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, /* Return the local port of the most recent (primary) connection */ *param_longp = data->info.conn_local_port; break; + case CURLINFO_PROXY_ERROR: + *param_longp = (long)data->info.pxcode; + break; case CURLINFO_CONDITION_UNMET: if(data->info.httpcode == 304) *param_longp = 1L; diff --git a/libs/libcurl/src/gopher.c b/libs/libcurl/src/gopher.c index b4811b2894..ce7413133f 100644 --- a/libs/libcurl/src/gopher.c +++ b/libs/libcurl/src/gopher.c @@ -71,6 +71,7 @@ const struct Curl_handler Curl_handler_gopher = { ZERO_NULL, /* connection_check */ PORT_GOPHER, /* defport */ CURLPROTO_GOPHER, /* protocol */ + CURLPROTO_GOPHER, /* family */ PROTOPT_NONE /* flags */ }; @@ -170,9 +171,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) free(sel_org); if(!result) - /* We can use Curl_sendf to send the terminal \r\n relatively safely and - save allocing another string/doing another _write loop. */ - result = Curl_sendf(sockfd, conn, "\r\n"); + result = Curl_write(conn, sockfd, "\r\n", 2, &amount); if(result) { failf(data, "Failed sending Gopher request"); return result; diff --git a/libs/libcurl/src/hash.c b/libs/libcurl/src/hash.c index 421d68f769..8c1f6cd0a6 100644 --- a/libs/libcurl/src/hash.c +++ b/libs/libcurl/src/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -34,8 +34,8 @@ static void hash_element_dtor(void *user, void *element) { - struct curl_hash *h = (struct curl_hash *) user; - struct curl_hash_element *e = (struct curl_hash_element *) element; + struct Curl_hash *h = (struct Curl_hash *) user; + struct Curl_hash_element *e = (struct Curl_hash_element *) element; if(e->ptr) { h->dtor(e->ptr); @@ -54,11 +54,11 @@ hash_element_dtor(void *user, void *element) * @unittest: 1603 */ int -Curl_hash_init(struct curl_hash *h, +Curl_hash_init(struct Curl_hash *h, int slots, hash_function hfunc, comp_function comparator, - curl_hash_dtor dtor) + Curl_hash_dtor dtor) { if(!slots || !hfunc || !comparator ||!dtor) { return 1; /* failure */ @@ -70,22 +70,22 @@ Curl_hash_init(struct curl_hash *h, h->size = 0; h->slots = slots; - h->table = malloc(slots * sizeof(struct curl_llist)); + h->table = malloc(slots * sizeof(struct Curl_llist)); if(h->table) { int i; for(i = 0; i < slots; ++i) - Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor); + Curl_llist_init(&h->table[i], (Curl_llist_dtor) hash_element_dtor); return 0; /* fine */ } h->slots = 0; return 1; /* failure */ } -static struct curl_hash_element * +static struct Curl_hash_element * mk_hash_element(const void *key, size_t key_len, const void *p) { /* allocate the struct plus memory after it to store the key */ - struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element) + + struct Curl_hash_element *he = malloc(sizeof(struct Curl_hash_element) + key_len); if(he) { /* copy the key */ @@ -106,14 +106,14 @@ mk_hash_element(const void *key, size_t key_len, const void *p) * @unittest: 1603 */ void * -Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) +Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p) { - struct curl_hash_element *he; - struct curl_llist_element *le; - struct curl_llist *l = FETCH_LIST(h, key, key_len); + struct Curl_hash_element *he; + struct Curl_llist_element *le; + struct Curl_llist *l = FETCH_LIST(h, key, key_len); for(le = l->head; le; le = le->next) { - he = (struct curl_hash_element *) le->ptr; + he = (struct Curl_hash_element *) le->ptr; if(h->comp_func(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *)h); --h->size; @@ -136,13 +136,13 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) * * @unittest: 1603 */ -int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) +int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len) { - struct curl_llist_element *le; - struct curl_llist *l = FETCH_LIST(h, key, key_len); + struct Curl_llist_element *le; + struct Curl_llist *l = FETCH_LIST(h, key, key_len); for(le = l->head; le; le = le->next) { - struct curl_hash_element *he = le->ptr; + struct Curl_hash_element *he = le->ptr; if(h->comp_func(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *) h); --h->size; @@ -157,15 +157,15 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) * @unittest: 1603 */ void * -Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len) +Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len) { - struct curl_llist_element *le; - struct curl_llist *l; + struct Curl_llist_element *le; + struct Curl_llist *l; if(h) { l = FETCH_LIST(h, key, key_len); for(le = l->head; le; le = le->next) { - struct curl_hash_element *he = le->ptr; + struct Curl_hash_element *he = le->ptr; if(h->comp_func(he->key, he->key_len, key, key_len)) { return he->ptr; } @@ -177,17 +177,17 @@ Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len) #if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST) void -Curl_hash_apply(curl_hash *h, void *user, +Curl_hash_apply(Curl_hash *h, void *user, void (*cb)(void *user, void *ptr)) { - struct curl_llist_element *le; + struct Curl_llist_element *le; int i; for(i = 0; i < h->slots; ++i) { for(le = (h->table[i])->head; le; le = le->next) { - curl_hash_element *el = le->ptr; + Curl_hash_element *el = le->ptr; cb(user, el->ptr); } } @@ -202,7 +202,7 @@ Curl_hash_apply(curl_hash *h, void *user, * @unittest: 1603 */ void -Curl_hash_destroy(struct curl_hash *h) +Curl_hash_destroy(struct Curl_hash *h) { int i; @@ -220,19 +220,19 @@ Curl_hash_destroy(struct curl_hash *h) * @unittest: 1602 */ void -Curl_hash_clean(struct curl_hash *h) +Curl_hash_clean(struct Curl_hash *h) { Curl_hash_clean_with_criterium(h, NULL, NULL); } /* Cleans all entries that pass the comp function criteria. */ void -Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, +Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, int (*comp)(void *, void *)) { - struct curl_llist_element *le; - struct curl_llist_element *lnext; - struct curl_llist *list; + struct Curl_llist_element *le; + struct Curl_llist_element *lnext; + struct Curl_llist *list; int i; if(!h) @@ -242,7 +242,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, list = &h->table[i]; le = list->head; /* get first list entry */ while(le) { - struct curl_hash_element *he = le->ptr; + struct Curl_hash_element *he = le->ptr; lnext = le->next; /* ask the callback function if we shall remove this entry or not */ if(comp == NULL || comp(user, he->ptr)) { @@ -277,18 +277,18 @@ size_t Curl_str_key_compare(void *k1, size_t key1_len, return 0; } -void Curl_hash_start_iterate(struct curl_hash *hash, - struct curl_hash_iterator *iter) +void Curl_hash_start_iterate(struct Curl_hash *hash, + struct Curl_hash_iterator *iter) { iter->hash = hash; iter->slot_index = 0; iter->current_element = NULL; } -struct curl_hash_element * -Curl_hash_next_element(struct curl_hash_iterator *iter) +struct Curl_hash_element * +Curl_hash_next_element(struct Curl_hash_iterator *iter) { - struct curl_hash *h = iter->hash; + struct Curl_hash *h = iter->hash; /* Get the next element in the current list, if any */ if(iter->current_element) @@ -307,7 +307,7 @@ Curl_hash_next_element(struct curl_hash_iterator *iter) } if(iter->current_element) { - struct curl_hash_element *he = iter->current_element->ptr; + struct Curl_hash_element *he = iter->current_element->ptr; return he; } iter->current_element = NULL; @@ -315,11 +315,11 @@ Curl_hash_next_element(struct curl_hash_iterator *iter) } #if 0 /* useful function for debugging hashes and their contents */ -void Curl_hash_print(struct curl_hash *h, +void Curl_hash_print(struct Curl_hash *h, void (*func)(void *)) { - struct curl_hash_iterator iter; - struct curl_hash_element *he; + struct Curl_hash_iterator iter; + struct Curl_hash_element *he; int last_index = -1; if(!h) diff --git a/libs/libcurl/src/hash.h b/libs/libcurl/src/hash.h index 558d0f47ca..eb5104b85b 100644 --- a/libs/libcurl/src/hash.h +++ b/libs/libcurl/src/hash.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -41,59 +41,59 @@ typedef size_t (*comp_function) (void *key1, void *key2, size_t key2_len); -typedef void (*curl_hash_dtor)(void *); +typedef void (*Curl_hash_dtor)(void *); -struct curl_hash { - struct curl_llist *table; +struct Curl_hash { + struct Curl_llist *table; /* Hash function to be used for this hash table */ hash_function hash_func; /* Comparator function to compare keys */ comp_function comp_func; - curl_hash_dtor dtor; + Curl_hash_dtor dtor; int slots; size_t size; }; -struct curl_hash_element { - struct curl_llist_element list; +struct Curl_hash_element { + struct Curl_llist_element list; void *ptr; size_t key_len; char key[1]; /* allocated memory following the struct */ }; -struct curl_hash_iterator { - struct curl_hash *hash; +struct Curl_hash_iterator { + struct Curl_hash *hash; int slot_index; - struct curl_llist_element *current_element; + struct Curl_llist_element *current_element; }; -int Curl_hash_init(struct curl_hash *h, +int Curl_hash_init(struct Curl_hash *h, int slots, hash_function hfunc, comp_function comparator, - curl_hash_dtor dtor); + Curl_hash_dtor dtor); -void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p); -int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len); -void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len); -void Curl_hash_apply(struct curl_hash *h, void *user, +void *Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p); +int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len); +void *Curl_hash_pick(struct Curl_hash *, void *key, size_t key_len); +void Curl_hash_apply(struct Curl_hash *h, void *user, void (*cb)(void *user, void *ptr)); #define Curl_hash_count(h) ((h)->size) -void Curl_hash_destroy(struct curl_hash *h); -void Curl_hash_clean(struct curl_hash *h); -void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, +void Curl_hash_destroy(struct Curl_hash *h); +void Curl_hash_clean(struct Curl_hash *h); +void Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, int (*comp)(void *, void *)); size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num); size_t Curl_str_key_compare(void *k1, size_t key1_len, void *k2, size_t key2_len); -void Curl_hash_start_iterate(struct curl_hash *hash, - struct curl_hash_iterator *iter); -struct curl_hash_element * -Curl_hash_next_element(struct curl_hash_iterator *iter); +void Curl_hash_start_iterate(struct Curl_hash *hash, + struct Curl_hash_iterator *iter); +struct Curl_hash_element * +Curl_hash_next_element(struct Curl_hash_iterator *iter); -void Curl_hash_print(struct curl_hash *h, +void Curl_hash_print(struct Curl_hash *h, void (*func)(void *)); diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c index dd5916e338..57c8bd3d84 100644 --- a/libs/libcurl/src/hostip.c +++ b/libs/libcurl/src/hostip.c @@ -206,7 +206,7 @@ hostcache_timestamp_remove(void *datap, void *hc) * Prune the DNS cache. This assumes that a lock has already been taken. */ static void -hostcache_prune(struct curl_hash *hostcache, long cache_timeout, time_t now) +hostcache_prune(struct Curl_hash *hostcache, long cache_timeout, time_t now) { struct hostcache_prune_data user; @@ -843,7 +843,7 @@ static void freednsentry(void *freethis) /* * Curl_mk_dnscache() inits a new DNS cache and returns success/failure. */ -int Curl_mk_dnscache(struct curl_hash *hash) +int Curl_mk_dnscache(struct Curl_hash *hash) { return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare, freednsentry); @@ -857,7 +857,7 @@ int Curl_mk_dnscache(struct curl_hash *hash) */ void Curl_hostcache_clean(struct Curl_easy *data, - struct curl_hash *hash) + struct Curl_hash *hash) { if(data && data->share) Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h index 374b06c855..fb782d5638 100644 --- a/libs/libcurl/src/hostip.h +++ b/libs/libcurl/src/hostip.h @@ -59,9 +59,9 @@ struct connectdata; * Global DNS cache is general badness. Do not use. This will be removed in * a future version. Use the share interface instead! * - * Returns a struct curl_hash pointer on success, NULL on failure. + * Returns a struct Curl_hash pointer on success, NULL on failure. */ -struct curl_hash *Curl_global_host_cache_init(void); +struct Curl_hash *Curl_global_host_cache_init(void); struct Curl_dns_entry { struct Curl_addrinfo *addr; @@ -128,7 +128,7 @@ void Curl_resolv_unlock(struct Curl_easy *data, struct Curl_dns_entry *dns); /* init a new dns cache and return success */ -int Curl_mk_dnscache(struct curl_hash *hash); +int Curl_mk_dnscache(struct Curl_hash *hash); /* prune old entries from the DNS cache */ void Curl_hostcache_prune(struct Curl_easy *data); @@ -234,7 +234,7 @@ CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data, /* * Clean off entries from the cache */ -void Curl_hostcache_clean(struct Curl_easy *data, struct curl_hash *hash); +void Curl_hostcache_clean(struct Curl_easy *data, struct Curl_hash *hash); /* * Populate the cache with specified entries from CURLOPT_RESOLVE. diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c index 8fcdd436d7..e0be17d9ba 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.c @@ -125,6 +125,7 @@ const struct Curl_handler Curl_handler_http = { ZERO_NULL, /* connection_check */ PORT_HTTP, /* defport */ CURLPROTO_HTTP, /* protocol */ + CURLPROTO_HTTP, /* family */ PROTOPT_CREDSPERREQUEST | /* flags */ PROTOPT_USERPWDCTRL }; @@ -151,6 +152,7 @@ const struct Curl_handler Curl_handler_https = { ZERO_NULL, /* connection_check */ PORT_HTTPS, /* defport */ CURLPROTO_HTTPS, /* protocol */ + CURLPROTO_HTTP, /* family */ PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | /* flags */ PROTOPT_USERPWDCTRL }; @@ -1353,7 +1355,7 @@ Curl_compareheader(const char *headerline, /* line to check */ /* pass the header */ start = &headerline[hlen]; - /* pass all white spaces */ + /* pass all whitespace */ while(*start && ISSPACE(*start)) start++; diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index d316da8b6a..925d9828b2 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -300,6 +300,7 @@ static const struct Curl_handler Curl_handler_http2 = { http2_conncheck, /* connection_check */ PORT_HTTP, /* defport */ CURLPROTO_HTTP, /* protocol */ + CURLPROTO_HTTP, /* family */ PROTOPT_STREAM /* flags */ }; @@ -321,6 +322,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = { http2_conncheck, /* connection_check */ PORT_HTTP, /* defport */ CURLPROTO_HTTPS, /* protocol */ + CURLPROTO_HTTP, /* family */ PROTOPT_SSL | PROTOPT_STREAM /* flags */ }; @@ -1207,13 +1209,6 @@ void Curl_http2_done(struct Curl_easy *data, bool premature) } http->stream_id = 0; } - - if(0 == nghttp2_session_check_request_allowed(httpc->h2)) { - /* No more requests are allowed in the current session, so the connection - may not be reused. This is set when a GOAWAY frame has been received or - when the limit of stream identifiers has been reached. */ - connclose(data->conn, "http/2: No new requests allowed"); - } } /* @@ -1288,7 +1283,7 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req, binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN, httpc->local_settings, httpc->local_settings_num); - if(!binlen) { + if(binlen <= 0) { failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload"); Curl_dyn_free(req); return CURLE_FAILED_INIT; @@ -1371,6 +1366,14 @@ static int h2_process_pending_input(struct connectdata *conn, return -1; } + if(nghttp2_session_check_request_allowed(httpc->h2) == 0) { + /* No more requests are allowed in the current session, so + the connection may not be reused. This is set when a + GOAWAY frame has been received or when the limit of stream + identifiers has been reached. */ + connclose(conn, "http/2: No new requests allowed"); + } + if(should_close_session(httpc)) { H2BUGF(infof(data, "h2_process_pending_input: nothing to do in this session\n")); @@ -1383,7 +1386,6 @@ static int h2_process_pending_input(struct connectdata *conn, } return -1; } - return 0; } @@ -1564,8 +1566,6 @@ static int h2_session_send(struct Curl_easy *data, static ssize_t http2_recv(struct connectdata *conn, int sockindex, char *mem, size_t len, CURLcode *err) { - CURLcode result = CURLE_OK; - ssize_t rv; ssize_t nread; struct http_conn *httpc = &conn->proto.httpc; struct Curl_easy *data = conn->data; @@ -1632,8 +1632,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, /* We have paused nghttp2, but we have no pause data (see on_data_chunk_recv). */ httpc->pause_stream_id = 0; - if(h2_process_pending_input(conn, httpc, &result) != 0) { - *err = result; + if(h2_process_pending_input(conn, httpc, err) != 0) { return -1; } } @@ -1661,8 +1660,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, frames, then we have to call it again with 0-length data. Without this, on_stream_close callback will not be called, and stream could be hanged. */ - if(h2_process_pending_input(conn, httpc, &result) != 0) { - *err = result; + if(h2_process_pending_input(conn, httpc, err) != 0) { return -1; } } @@ -1688,7 +1686,6 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, return -1; } else { - char *inbuf; /* remember where to store incoming data for this stream and how big the buffer is */ stream->mem = mem; @@ -1697,16 +1694,15 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, if(httpc->inbuflen == 0) { nread = ((Curl_recv *)httpc->recv_underlying)( - conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result); + conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err); if(nread == -1) { - if(result != CURLE_AGAIN) + if(*err != CURLE_AGAIN) failf(data, "Failed receiving HTTP2 data"); else if(stream->closed) /* received when the stream was already closed! */ return http2_handle_stream_close(conn, data, stream, err); - *err = result; return -1; } @@ -1719,47 +1715,18 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, H2BUGF(infof(data, "nread=%zd\n", nread)); httpc->inbuflen = nread; - inbuf = httpc->inbuf; + + DEBUGASSERT(httpc->nread_inbuf == 0); } else { nread = httpc->inbuflen - httpc->nread_inbuf; - inbuf = httpc->inbuf + httpc->nread_inbuf; - + (void)nread; /* silence warning, used in debug */ H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n", nread)); } - rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread); - if(nghttp2_is_fatal((int)rv)) { - failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n", - rv, nghttp2_strerror((int)rv)); - *err = CURLE_RECV_ERROR; - return -1; - } - H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv)); - if(nread == rv) { - H2BUGF(infof(data, "All data in connection buffer processed\n")); - httpc->inbuflen = 0; - httpc->nread_inbuf = 0; - } - else { - httpc->nread_inbuf += rv; - H2BUGF(infof(data, "%zu bytes left in connection buffer\n", - httpc->inbuflen - httpc->nread_inbuf)); - } - /* Always send pending frames in nghttp2 session, because - nghttp2_session_mem_recv() may queue new frame */ - rv = h2_session_send(data, httpc->h2); - if(rv != 0) { - *err = CURLE_SEND_ERROR; - return -1; - } - - if(should_close_session(httpc)) { - H2BUGF(infof(data, "http2_recv: nothing to do in this session\n")); - *err = CURLE_HTTP2; + if(h2_process_pending_input(conn, httpc, err) != 0) return -1; - } } if(stream->memlen) { ssize_t retlen = stream->memlen; @@ -2112,7 +2079,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, h2_pri_spec(conn->data, &pri_spec); H2BUGF(infof(conn->data, "http2_send request allowed %d (easy handle %p)\n", - nghttp2_session_check_request_allowed(h2), (void *)conn->data)); + nghttp2_session_check_request_allowed(h2), (void *)conn->data)); switch(conn->data->state.httpreq) { case HTTPREQ_POST: @@ -2138,7 +2105,9 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, Curl_safefree(nva); if(stream_id < 0) { - H2BUGF(infof(conn->data, "http2_send() send error\n")); + H2BUGF(infof(conn->data, + "http2_send() nghttp2_submit_request error (%s)%d\n", + nghttp2_strerror(stream_id), stream_id)); *err = CURLE_SEND_ERROR; return -1; } @@ -2148,10 +2117,13 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, stream->stream_id = stream_id; /* this does not call h2_session_send() since there can not have been any - * priority upodate since the nghttp2_submit_request() call above */ + * priority update since the nghttp2_submit_request() call above */ rv = nghttp2_session_send(h2); - if(rv != 0) { + H2BUGF(infof(conn->data, + "http2_send() nghttp2_session_send error (%s)%d\n", + nghttp2_strerror(rv), rv)); + *err = CURLE_SEND_ERROR; return -1; } @@ -2236,7 +2208,6 @@ CURLcode Curl_http2_switched(struct connectdata *conn, CURLcode result; struct http_conn *httpc = &conn->proto.httpc; int rv; - ssize_t nproc; struct Curl_easy *data = conn->data; struct HTTP *stream = conn->data->req.protop; @@ -2310,41 +2281,13 @@ CURLcode Curl_http2_switched(struct connectdata *conn, if(nread) memcpy(httpc->inbuf, mem, nread); - httpc->inbuflen = nread; - - nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf, - httpc->inbuflen); - - if(nghttp2_is_fatal((int)nproc)) { - failf(data, "nghttp2_session_mem_recv() failed: %s(%d)", - nghttp2_strerror((int)nproc), (int)nproc); - return CURLE_HTTP2; - } - - H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc)); - - if((ssize_t)nread == nproc) { - httpc->inbuflen = 0; - httpc->nread_inbuf = 0; - } - else { - httpc->nread_inbuf += nproc; - } - /* Try to send some frames since we may read SETTINGS already. */ - rv = h2_session_send(data, httpc->h2); + httpc->inbuflen = nread; - if(rv != 0) { - failf(data, "nghttp2_session_send() failed: %s(%d)", - nghttp2_strerror(rv), rv); - return CURLE_HTTP2; - } + DEBUGASSERT(httpc->nread_inbuf == 0); - if(should_close_session(httpc)) { - H2BUGF(infof(data, - "nghttp2_session_send(): nothing to do in this session\n")); + if(-1 == h2_process_pending_input(conn, httpc, &result)) return CURLE_HTTP2; - } return CURLE_OK; } diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c index f188cbfc60..7c34d20648 100644 --- a/libs/libcurl/src/http_proxy.c +++ b/libs/libcurl/src/http_proxy.c @@ -425,7 +425,6 @@ static CURLcode CONNECT(struct connectdata *conn, } data->info.header_size += (long)perline; - data->req.headerbytecount += (long)perline; /* Newlines are CRLF, so the CR is ignored as the line isn't really terminated until the LF comes. Treat a following CR diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c index cad0e5908d..46367be103 100644 --- a/libs/libcurl/src/imap.c +++ b/libs/libcurl/src/imap.c @@ -132,6 +132,7 @@ const struct Curl_handler Curl_handler_imap = { ZERO_NULL, /* connection_check */ PORT_IMAP, /* defport */ CURLPROTO_IMAP, /* protocol */ + CURLPROTO_IMAP, /* family */ PROTOPT_CLOSEACTION| /* flags */ PROTOPT_URLOPTIONS }; @@ -159,6 +160,7 @@ const struct Curl_handler Curl_handler_imaps = { ZERO_NULL, /* connection_check */ PORT_IMAPS, /* defport */ CURLPROTO_IMAPS, /* protocol */ + CURLPROTO_IMAP, /* family */ PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ PROTOPT_URLOPTIONS }; @@ -1176,6 +1178,9 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, else { /* IMAP download */ data->req.maxdownload = size; + /* force a recv/send check of this connection, as the data might've been + read off the socket already */ + data->conn->cselect_bits = CURL_CSELECT_IN; Curl_setup_transfer(data, FIRSTSOCKET, size, FALSE, -1); } } @@ -1424,7 +1429,9 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done) imapc->preftype = IMAP_TYPE_ANY; Curl_sasl_init(&imapc->sasl, &saslimap); + Curl_dyn_init(&imapc->dyn, DYN_IMAP_CMD); /* Initialise the pingpong layer */ + Curl_pp_setup(pp); Curl_pp_init(pp); /* Parse the URL options */ @@ -1626,6 +1633,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection) /* Disconnect from the server */ Curl_pp_disconnect(&imapc->pp); + Curl_dyn_free(&imapc->dyn); /* Cleanup the SASL module */ Curl_sasl_cleanup(conn, imapc->sasl.authused); @@ -1727,30 +1735,25 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...) { CURLcode result = CURLE_OK; struct imap_conn *imapc = &conn->proto.imapc; - char *taggedfmt; - va_list ap; DEBUGASSERT(fmt); - /* Calculate the next command ID wrapping at 3 digits */ - imapc->cmdid = (imapc->cmdid + 1) % 1000; - /* Calculate the tag based on the connection ID and command ID */ msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d", - 'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid); - - /* Prefix the format with the tag */ - taggedfmt = aprintf("%s %s", imapc->resptag, fmt); - if(!taggedfmt) - return CURLE_OUT_OF_MEMORY; + 'A' + curlx_sltosi(conn->connection_id % 26), + (++imapc->cmdid)%1000); - /* Send the data with the tag */ - va_start(ap, fmt); - result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap); - va_end(ap); - - free(taggedfmt); + /* start with a blank buffer */ + Curl_dyn_reset(&imapc->dyn); + /* append tag + space + fmt */ + result = Curl_dyn_addf(&imapc->dyn, "%s %s", imapc->resptag, fmt); + if(!result) { + va_list ap; + va_start(ap, fmt); + result = Curl_pp_vsendf(&imapc->pp, Curl_dyn_ptr(&imapc->dyn), ap); + va_end(ap); + } return result; } diff --git a/libs/libcurl/src/imap.h b/libs/libcurl/src/imap.h index 4786f56241..8f373d2843 100644 --- a/libs/libcurl/src/imap.h +++ b/libs/libcurl/src/imap.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -75,13 +75,14 @@ struct imap_conn { bool preauth; /* Is this connection PREAUTH? */ struct SASL sasl; /* SASL-related parameters */ unsigned int preftype; /* Preferred authentication type */ - int cmdid; /* Last used command ID */ + unsigned int cmdid; /* Last used command ID */ char resptag[5]; /* Response tag to wait for */ bool tls_supported; /* StartTLS capability supported by server */ bool login_disabled; /* LOGIN command disabled by server */ bool ir_supported; /* Initial response supported by server */ char *mailbox; /* The last selected mailbox */ char *mailbox_uidvalidity; /* UIDVALIDITY parsed from select response */ + struct dynbuf dyn; /* for the IMAP commands */ }; extern const struct Curl_handler Curl_handler_imap; diff --git a/libs/libcurl/src/inet_pton.c b/libs/libcurl/src/inet_pton.c index 9c87a05620..4923cae245 100644 --- a/libs/libcurl/src/inet_pton.c +++ b/libs/libcurl/src/inet_pton.c @@ -1,6 +1,6 @@ /* This is from the BIND 4.9.4 release, modified to compile by itself */ -/* Copyright (c) 1996 - 2019 by Internet Software Consortium. +/* Copyright (c) 1996 - 2020 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -112,7 +112,7 @@ inet_pton4(const char *src, unsigned char *dst) if(val > 255) return (0); *tp = (unsigned char)val; - if(! saw_digit) { + if(!saw_digit) { if(++octets > 4) return (0); saw_digit = 1; diff --git a/libs/libcurl/src/krb5.c b/libs/libcurl/src/krb5.c index f50287aec6..ad6daeaa9e 100644 --- a/libs/libcurl/src/krb5.c +++ b/libs/libcurl/src/krb5.c @@ -2,7 +2,7 @@ * * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). - * Copyright (c) 2004 - 2019 Daniel Stenberg + * Copyright (c) 2004 - 2020 Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -45,14 +45,74 @@ #include "ftp.h" #include "curl_gssapi.h" #include "sendf.h" -#include "curl_sec.h" +#include "curl_krb5.h" #include "warnless.h" +#include "non-ascii.h" +#include "strcase.h" +#include "strdup.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" #include "memdebug.h" +static CURLcode ftpsend(struct connectdata *conn, const char *cmd) +{ + ssize_t bytes_written; +#define SBUF_SIZE 1024 + char s[SBUF_SIZE]; + size_t write_len; + char *sptr = s; + CURLcode result = CURLE_OK; +#ifdef HAVE_GSSAPI + enum protection_level data_sec = conn->data_prot; +#endif + + if(!cmd) + return CURLE_BAD_FUNCTION_ARGUMENT; + + write_len = strlen(cmd); + if(!write_len || write_len > (sizeof(s) -3)) + return CURLE_BAD_FUNCTION_ARGUMENT; + + memcpy(&s, cmd, write_len); + strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */ + write_len += 2; + bytes_written = 0; + + result = Curl_convert_to_network(conn->data, s, write_len); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(result) + return result; + + for(;;) { +#ifdef HAVE_GSSAPI + conn->data_prot = PROT_CMD; +#endif + result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, + &bytes_written); +#ifdef HAVE_GSSAPI + DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); + conn->data_prot = data_sec; +#endif + + if(result) + break; + + if(conn->data->set.verbose) + Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written); + + if(bytes_written != (ssize_t)write_len) { + write_len -= bytes_written; + sptr += bytes_written; + } + else + break; + } + + return result; +} + static int krb5_init(void *app_data) { @@ -183,7 +243,7 @@ krb5_auth(void *app_data, struct connectdata *conn) for(;;) { /* this really shouldn't be repeated here, but can't help it */ if(service == srv_host) { - result = Curl_ftpsend(conn, "AUTH GSSAPI"); + result = ftpsend(conn, "AUTH GSSAPI"); if(result) return -2; @@ -260,7 +320,7 @@ krb5_auth(void *app_data, struct connectdata *conn) cmd = aprintf("ADAT %s", p); if(cmd) - result = Curl_ftpsend(conn, cmd); + result = ftpsend(conn, cmd); else result = CURLE_OUT_OF_MEMORY; @@ -326,16 +386,524 @@ static void krb5_end(void *app_data) } } -struct Curl_sec_client_mech Curl_krb5_client_mech = { - "GSSAPI", - sizeof(gss_ctx_id_t), - krb5_init, - krb5_auth, - krb5_end, - krb5_check_prot, - krb5_overhead, - krb5_encode, - krb5_decode +static struct Curl_sec_client_mech Curl_krb5_client_mech = { + "GSSAPI", + sizeof(gss_ctx_id_t), + krb5_init, + krb5_auth, + krb5_end, + krb5_check_prot, + krb5_overhead, + krb5_encode, + krb5_decode +}; + +static const struct { + enum protection_level level; + const char *name; +} level_names[] = { + { PROT_CLEAR, "clear" }, + { PROT_SAFE, "safe" }, + { PROT_CONFIDENTIAL, "confidential" }, + { PROT_PRIVATE, "private" } }; +static enum protection_level +name_to_level(const char *name) +{ + int i; + for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++) + if(checkprefix(name, level_names[i].name)) + return level_names[i].level; + return PROT_NONE; +} + +/* Convert a protocol |level| to its char representation. + We take an int to catch programming mistakes. */ +static char level_to_char(int level) +{ + switch(level) { + case PROT_CLEAR: + return 'C'; + case PROT_SAFE: + return 'S'; + case PROT_CONFIDENTIAL: + return 'E'; + case PROT_PRIVATE: + return 'P'; + case PROT_CMD: + /* Fall through */ + default: + /* Those 2 cases should not be reached! */ + break; + } + DEBUGASSERT(0); + /* Default to the most secure alternative. */ + return 'P'; +} + +/* Send an FTP command defined by |message| and the optional arguments. The + function returns the ftp_code. If an error occurs, -1 is returned. */ +static int ftp_send_command(struct connectdata *conn, const char *message, ...) +{ + int ftp_code; + ssize_t nread = 0; + va_list args; + char print_buffer[50]; + + va_start(args, message); + mvsnprintf(print_buffer, sizeof(print_buffer), message, args); + va_end(args); + + if(ftpsend(conn, print_buffer)) { + ftp_code = -1; + } + else { + if(Curl_GetFTPResponse(&nread, conn, &ftp_code)) + ftp_code = -1; + } + + (void)nread; /* Unused */ + return ftp_code; +} + +/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode + saying whether an error occurred or CURLE_OK if |len| was read. */ +static CURLcode +socket_read(curl_socket_t fd, void *to, size_t len) +{ + char *to_p = to; + CURLcode result; + ssize_t nread = 0; + + while(len > 0) { + result = Curl_read_plain(fd, to_p, len, &nread); + if(!result) { + len -= nread; + to_p += nread; + } + else { + if(result == CURLE_AGAIN) + continue; + return result; + } + } + return CURLE_OK; +} + + +/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a + CURLcode saying whether an error occurred or CURLE_OK if |len| was + written. */ +static CURLcode +socket_write(struct connectdata *conn, curl_socket_t fd, const void *to, + size_t len) +{ + const char *to_p = to; + CURLcode result; + ssize_t written; + + while(len > 0) { + result = Curl_write_plain(conn, fd, to_p, len, &written); + if(!result) { + len -= written; + to_p += written; + } + else { + if(result == CURLE_AGAIN) + continue; + return result; + } + } + return CURLE_OK; +} + +static CURLcode read_data(struct connectdata *conn, + curl_socket_t fd, + struct krb5buffer *buf) +{ + int len; + CURLcode result; + + result = socket_read(fd, &len, sizeof(len)); + if(result) + return result; + + if(len) { + /* only realloc if there was a length */ + len = ntohl(len); + buf->data = Curl_saferealloc(buf->data, len); + } + if(!len || !buf->data) + return CURLE_OUT_OF_MEMORY; + + result = socket_read(fd, buf->data, len); + if(result) + return result; + buf->size = conn->mech->decode(conn->app_data, buf->data, len, + conn->data_prot, conn); + buf->index = 0; + return CURLE_OK; +} + +static size_t +buffer_read(struct krb5buffer *buf, void *data, size_t len) +{ + if(buf->size - buf->index < len) + len = buf->size - buf->index; + memcpy(data, (char *)buf->data + buf->index, len); + buf->index += len; + return len; +} + +/* Matches Curl_recv signature */ +static ssize_t sec_recv(struct connectdata *conn, int sockindex, + char *buffer, size_t len, CURLcode *err) +{ + size_t bytes_read; + size_t total_read = 0; + curl_socket_t fd = conn->sock[sockindex]; + + *err = CURLE_OK; + + /* Handle clear text response. */ + if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR) + return sread(fd, buffer, len); + + if(conn->in_buffer.eof_flag) { + conn->in_buffer.eof_flag = 0; + return 0; + } + + bytes_read = buffer_read(&conn->in_buffer, buffer, len); + len -= bytes_read; + total_read += bytes_read; + buffer += bytes_read; + + while(len > 0) { + if(read_data(conn, fd, &conn->in_buffer)) + return -1; + if(conn->in_buffer.size == 0) { + if(bytes_read > 0) + conn->in_buffer.eof_flag = 1; + return bytes_read; + } + bytes_read = buffer_read(&conn->in_buffer, buffer, len); + len -= bytes_read; + total_read += bytes_read; + buffer += bytes_read; + } + return total_read; +} + +/* Send |length| bytes from |from| to the |fd| socket taking care of encoding + and negotiating with the server. |from| can be NULL. */ +static void do_sec_send(struct connectdata *conn, curl_socket_t fd, + const char *from, int length) +{ + int bytes, htonl_bytes; /* 32-bit integers for htonl */ + char *buffer = NULL; + char *cmd_buffer; + size_t cmd_size = 0; + CURLcode error; + enum protection_level prot_level = conn->data_prot; + bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE; + + DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST); + + if(iscmd) { + if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5)) + prot_level = PROT_PRIVATE; + else + prot_level = conn->command_prot; + } + bytes = conn->mech->encode(conn->app_data, from, length, prot_level, + (void **)&buffer); + if(!buffer || bytes <= 0) + return; /* error */ + + if(iscmd) { + error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes), + &cmd_buffer, &cmd_size); + if(error) { + free(buffer); + return; /* error */ + } + if(cmd_size > 0) { + static const char *enc = "ENC "; + static const char *mic = "MIC "; + if(prot_level == PROT_PRIVATE) + socket_write(conn, fd, enc, 4); + else + socket_write(conn, fd, mic, 4); + + socket_write(conn, fd, cmd_buffer, cmd_size); + socket_write(conn, fd, "\r\n", 2); + infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic, + cmd_buffer); + free(cmd_buffer); + } + } + else { + htonl_bytes = htonl(bytes); + socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes)); + socket_write(conn, fd, buffer, curlx_sitouz(bytes)); + } + free(buffer); +} + +static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd, + const char *buffer, size_t length) +{ + ssize_t tx = 0, len = conn->buffer_size; + + len -= conn->mech->overhead(conn->app_data, conn->data_prot, + curlx_sztosi(len)); + if(len <= 0) + len = length; + while(length) { + if(length < (size_t)len) + len = length; + + do_sec_send(conn, fd, buffer, curlx_sztosi(len)); + length -= len; + buffer += len; + tx += len; + } + return tx; +} + +/* Matches Curl_send signature */ +static ssize_t sec_send(struct connectdata *conn, int sockindex, + const void *buffer, size_t len, CURLcode *err) +{ + curl_socket_t fd = conn->sock[sockindex]; + *err = CURLE_OK; + return sec_write(conn, fd, buffer, len); +} + +int Curl_sec_read_msg(struct connectdata *conn, char *buffer, + enum protection_level level) +{ + /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an + int */ + int decoded_len; + char *buf; + int ret_code = 0; + size_t decoded_sz = 0; + CURLcode error; + + if(!conn->mech) + /* not inititalized, return error */ + return -1; + + DEBUGASSERT(level > PROT_NONE && level < PROT_LAST); + + error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz); + if(error || decoded_sz == 0) + return -1; + + if(decoded_sz > (size_t)INT_MAX) { + free(buf); + return -1; + } + decoded_len = curlx_uztosi(decoded_sz); + + decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len, + level, conn); + if(decoded_len <= 0) { + free(buf); + return -1; + } + + if(conn->data->set.verbose) { + buf[decoded_len] = '\n'; + Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1); + } + + buf[decoded_len] = '\0'; + if(decoded_len <= 3) + /* suspiciously short */ + return 0; + + if(buf[3] != '-') + /* safe to ignore return code */ + (void)sscanf(buf, "%d", &ret_code); + + if(buf[decoded_len - 1] == '\n') + buf[decoded_len - 1] = '\0'; + strcpy(buffer, buf); + free(buf); + return ret_code; +} + +static int sec_set_protection_level(struct connectdata *conn) +{ + int code; + enum protection_level level = conn->request_data_prot; + + DEBUGASSERT(level > PROT_NONE && level < PROT_LAST); + + if(!conn->sec_complete) { + infof(conn->data, "Trying to change the protection level after the" + " completion of the data exchange.\n"); + return -1; + } + + /* Bail out if we try to set up the same level */ + if(conn->data_prot == level) + return 0; + + if(level) { + char *pbsz; + static unsigned int buffer_size = 1 << 20; /* 1048576 */ + + code = ftp_send_command(conn, "PBSZ %u", buffer_size); + if(code < 0) + return -1; + + if(code/100 != 2) { + failf(conn->data, "Failed to set the protection's buffer size."); + return -1; + } + conn->buffer_size = buffer_size; + + pbsz = strstr(conn->data->state.buffer, "PBSZ="); + if(pbsz) { + /* ignore return code, use default value if it fails */ + (void)sscanf(pbsz, "PBSZ=%u", &buffer_size); + if(buffer_size < conn->buffer_size) + conn->buffer_size = buffer_size; + } + } + + /* Now try to negiociate the protection level. */ + code = ftp_send_command(conn, "PROT %c", level_to_char(level)); + + if(code < 0) + return -1; + + if(code/100 != 2) { + failf(conn->data, "Failed to set the protection level."); + return -1; + } + + conn->data_prot = level; + if(level == PROT_PRIVATE) + conn->command_prot = level; + + return 0; +} + +int +Curl_sec_request_prot(struct connectdata *conn, const char *level) +{ + enum protection_level l = name_to_level(level); + if(l == PROT_NONE) + return -1; + DEBUGASSERT(l > PROT_NONE && l < PROT_LAST); + conn->request_data_prot = l; + return 0; +} + +static CURLcode choose_mech(struct connectdata *conn) +{ + int ret; + struct Curl_easy *data = conn->data; + void *tmp_allocation; + const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech; + + tmp_allocation = realloc(conn->app_data, mech->size); + if(tmp_allocation == NULL) { + failf(data, "Failed realloc of size %zu", mech->size); + mech = NULL; + return CURLE_OUT_OF_MEMORY; + } + conn->app_data = tmp_allocation; + + if(mech->init) { + ret = mech->init(conn->app_data); + if(ret) { + infof(data, "Failed initialization for %s. Skipping it.\n", + mech->name); + return CURLE_FAILED_INIT; + } + } + + infof(data, "Trying mechanism %s...\n", mech->name); + ret = ftp_send_command(conn, "AUTH %s", mech->name); + if(ret < 0) + return CURLE_COULDNT_CONNECT; + + if(ret/100 != 3) { + switch(ret) { + case 504: + infof(data, "Mechanism %s is not supported by the server (server " + "returned ftp code: 504).\n", mech->name); + break; + case 534: + infof(data, "Mechanism %s was rejected by the server (server returned " + "ftp code: 534).\n", mech->name); + break; + default: + if(ret/100 == 5) { + infof(data, "server does not support the security extensions\n"); + return CURLE_USE_SSL_FAILED; + } + break; + } + return CURLE_LOGIN_DENIED; + } + + /* Authenticate */ + ret = mech->auth(conn->app_data, conn); + + if(ret != AUTH_CONTINUE) { + if(ret != AUTH_OK) { + /* Mechanism has dumped the error to stderr, don't error here. */ + return CURLE_USE_SSL_FAILED; + } + DEBUGASSERT(ret == AUTH_OK); + + conn->mech = mech; + conn->sec_complete = 1; + conn->recv[FIRSTSOCKET] = sec_recv; + conn->send[FIRSTSOCKET] = sec_send; + conn->recv[SECONDARYSOCKET] = sec_recv; + conn->send[SECONDARYSOCKET] = sec_send; + conn->command_prot = PROT_SAFE; + /* Set the requested protection level */ + /* BLOCKING */ + (void)sec_set_protection_level(conn); + } + + return CURLE_OK; +} + +CURLcode +Curl_sec_login(struct connectdata *conn) +{ + return choose_mech(conn); +} + + +void +Curl_sec_end(struct connectdata *conn) +{ + if(conn->mech != NULL && conn->mech->end) + conn->mech->end(conn->app_data); + free(conn->app_data); + conn->app_data = NULL; + if(conn->in_buffer.data) { + free(conn->in_buffer.data); + conn->in_buffer.data = NULL; + conn->in_buffer.size = 0; + conn->in_buffer.index = 0; + conn->in_buffer.eof_flag = 0; + } + conn->sec_complete = 0; + conn->data_prot = PROT_CLEAR; + conn->mech = NULL; +} + #endif /* HAVE_GSSAPI && !CURL_DISABLE_FTP */ diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c index 512def659c..8d1ee6445c 100644 --- a/libs/libcurl/src/ldap.c +++ b/libs/libcurl/src/ldap.c @@ -150,6 +150,7 @@ const struct Curl_handler Curl_handler_ldap = { ZERO_NULL, /* connection_check */ PORT_LDAP, /* defport */ CURLPROTO_LDAP, /* protocol */ + CURLPROTO_LDAP, /* family */ PROTOPT_NONE /* flags */ }; @@ -176,6 +177,7 @@ const struct Curl_handler Curl_handler_ldaps = { ZERO_NULL, /* connection_check */ PORT_LDAPS, /* defport */ CURLPROTO_LDAPS, /* protocol */ + CURLPROTO_LDAP, /* family */ PROTOPT_SSL /* flags */ }; #endif @@ -257,6 +259,13 @@ static int ldap_win_bind(struct connectdata *conn, LDAP *server, } #endif /* #if defined(USE_WIN32_LDAP) */ +#if defined(USE_WIN32_LDAP) +#define FREE_ON_WINLDAP(x) curlx_unicodefree(x) +#else +#define FREE_ON_WINLDAP(x) +#endif + + static CURLcode Curl_ldap(struct connectdata *conn, bool *done) { CURLcode result = CURLE_OK; @@ -463,9 +472,6 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) } #ifdef USE_WIN32_LDAP ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); -#endif - -#ifdef USE_WIN32_LDAP rc = ldap_win_bind(conn, server, user, passwd); #else rc = ldap_simple_bind_s(server, user, passwd); @@ -507,7 +513,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) #if defined(USE_WIN32_LDAP) TCHAR *attribute; #else - char *attribute; /*! suspicious that this isn't 'const' */ + char *attribute; #endif int i; @@ -532,30 +538,22 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); if(result) { -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(name); -#endif + FREE_ON_WINLDAP(name); ldap_memfree(dn); - goto quit; } result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name, name_len); if(result) { -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(name); -#endif + FREE_ON_WINLDAP(name); ldap_memfree(dn); - goto quit; } result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); if(result) { -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(name); -#endif + FREE_ON_WINLDAP(name); ldap_memfree(dn); goto quit; @@ -563,9 +561,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) dlsize += name_len + 5; -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(name); -#endif + FREE_ON_WINLDAP(name); ldap_memfree(dn); } @@ -596,9 +592,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); if(result) { ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(attr); -#endif + FREE_ON_WINLDAP(attr); ldap_memfree(attribute); if(ber) ber_free(ber, 0); @@ -610,9 +604,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) (char *) attr, attr_len); if(result) { ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(attr); -#endif + FREE_ON_WINLDAP(attr); ldap_memfree(attribute); if(ber) ber_free(ber, 0); @@ -623,9 +615,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2); if(result) { ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(attr); -#endif + FREE_ON_WINLDAP(attr); ldap_memfree(attribute); if(ber) ber_free(ber, 0); @@ -645,9 +635,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) &val_b64_sz); if(result) { ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(attr); -#endif + FREE_ON_WINLDAP(attr); ldap_memfree(attribute); if(ber) ber_free(ber, 0); @@ -661,9 +649,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) free(val_b64); if(result) { ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(attr); -#endif + FREE_ON_WINLDAP(attr); ldap_memfree(attribute); if(ber) ber_free(ber, 0); @@ -679,9 +665,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) vals[i]->bv_len); if(result) { ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(attr); -#endif + FREE_ON_WINLDAP(attr); ldap_memfree(attribute); if(ber) ber_free(ber, 0); @@ -695,9 +679,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); if(result) { ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(attr); -#endif + FREE_ON_WINLDAP(attr); ldap_memfree(attribute); if(ber) ber_free(ber, 0); @@ -713,9 +695,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done) } /* Free the attribute as we are done with it */ -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(attr); -#endif + FREE_ON_WINLDAP(attr); ldap_memfree(attribute); result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); @@ -745,9 +725,7 @@ quit: ldapssl_client_deinit(); #endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */ -#if defined(USE_WIN32_LDAP) - curlx_unicodefree(host); -#endif + FREE_ON_WINLDAP(host); /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index 1b3d178c38..eab1efe31c 100644 --- a/libs/libcurl/src/libcurl.plist +++ b/libs/libcurl/src/libcurl.plist @@ -15,7 +15,7 @@ <string>se.haxx.curl.libcurl</string> <key>CFBundleVersion</key> - <string>7.72.0</string> + <string>7.73.0</string> <key>CFBundleName</key> <string>libcurl</string> @@ -27,9 +27,9 @@ <string>????</string> <key>CFBundleShortVersionString</key> - <string>libcurl 7.72.0</string> + <string>libcurl 7.73.0</string> <key>CFBundleGetInfoString</key> - <string>libcurl.plist 7.72.0</string> + <string>libcurl.plist 7.73.0</string> </dict> </plist> diff --git a/libs/libcurl/src/llist.c b/libs/libcurl/src/llist.c index e7c6f51dc7..0a2baa08ec 100644 --- a/libs/libcurl/src/llist.c +++ b/libs/libcurl/src/llist.c @@ -34,7 +34,7 @@ * @unittest: 1300 */ void -Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor) +Curl_llist_init(struct Curl_llist *l, Curl_llist_dtor dtor) { l->size = 0; l->dtor = dtor; @@ -54,9 +54,9 @@ Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor) * @unittest: 1300 */ void -Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e, +Curl_llist_insert_next(struct Curl_llist *list, struct Curl_llist_element *e, const void *p, - struct curl_llist_element *ne) + struct Curl_llist_element *ne) { ne->ptr = (void *) p; if(list->size == 0) { @@ -90,7 +90,7 @@ Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e, * @unittest: 1300 */ void -Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e, +Curl_llist_remove(struct Curl_llist *list, struct Curl_llist_element *e, void *user) { void *ptr; @@ -131,7 +131,7 @@ Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e, } void -Curl_llist_destroy(struct curl_llist *list, void *user) +Curl_llist_destroy(struct Curl_llist *list, void *user) { if(list) { while(list->size > 0) @@ -140,7 +140,7 @@ Curl_llist_destroy(struct curl_llist *list, void *user) } size_t -Curl_llist_count(struct curl_llist *list) +Curl_llist_count(struct Curl_llist *list) { return list->size; } diff --git a/libs/libcurl/src/llist.h b/libs/libcurl/src/llist.h index 0178c42598..91cfda1bcd 100644 --- a/libs/libcurl/src/llist.h +++ b/libs/libcurl/src/llist.h @@ -25,26 +25,26 @@ #include "curl_setup.h" #include <stddef.h> -typedef void (*curl_llist_dtor)(void *, void *); +typedef void (*Curl_llist_dtor)(void *, void *); -struct curl_llist_element { +struct Curl_llist_element { void *ptr; - struct curl_llist_element *prev; - struct curl_llist_element *next; + struct Curl_llist_element *prev; + struct Curl_llist_element *next; }; -struct curl_llist { - struct curl_llist_element *head; - struct curl_llist_element *tail; - curl_llist_dtor dtor; +struct Curl_llist { + struct Curl_llist_element *head; + struct Curl_llist_element *tail; + Curl_llist_dtor dtor; size_t size; }; -void Curl_llist_init(struct curl_llist *, curl_llist_dtor); -void Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *, - const void *, struct curl_llist_element *node); -void Curl_llist_remove(struct curl_llist *, struct curl_llist_element *, +void Curl_llist_init(struct Curl_llist *, Curl_llist_dtor); +void Curl_llist_insert_next(struct Curl_llist *, struct Curl_llist_element *, + const void *, struct Curl_llist_element *node); +void Curl_llist_remove(struct Curl_llist *, struct Curl_llist_element *, void *); -size_t Curl_llist_count(struct curl_llist *); -void Curl_llist_destroy(struct curl_llist *, void *); +size_t Curl_llist_count(struct Curl_llist *); +void Curl_llist_destroy(struct Curl_llist *, void *); #endif /* HEADER_CURL_LLIST_H */ diff --git a/libs/libcurl/src/memdebug.c b/libs/libcurl/src/memdebug.c index da75c9f5db..6c56084742 100644 --- a/libs/libcurl/src/memdebug.c +++ b/libs/libcurl/src/memdebug.c @@ -35,52 +35,6 @@ #include "curl_memory.h" #include "memdebug.h" -/* - * Until 2011-08-17 libcurl's Memory Tracking feature also performed - * automatic malloc and free filling operations using 0xA5 and 0x13 - * values. Our own preinitialization of dynamically allocated memory - * might be useful when not using third party memory debuggers, but - * on the other hand this would fool memory debuggers into thinking - * that all dynamically allocated memory is properly initialized. - * - * As a default setting, libcurl's Memory Tracking feature no longer - * performs preinitialization of dynamically allocated memory on its - * own. If you know what you are doing, and really want to retain old - * behavior, you can achieve this compiling with preprocessor symbols - * CURL_MT_MALLOC_FILL and CURL_MT_FREE_FILL defined with appropriate - * values. - */ - -#ifdef CURL_MT_MALLOC_FILL -# if (CURL_MT_MALLOC_FILL < 0) || (CURL_MT_MALLOC_FILL > 0xff) -# error "invalid CURL_MT_MALLOC_FILL or out of range" -# endif -#endif - -#ifdef CURL_MT_FREE_FILL -# if (CURL_MT_FREE_FILL < 0) || (CURL_MT_FREE_FILL > 0xff) -# error "invalid CURL_MT_FREE_FILL or out of range" -# endif -#endif - -#if defined(CURL_MT_MALLOC_FILL) && defined(CURL_MT_FREE_FILL) -# if (CURL_MT_MALLOC_FILL == CURL_MT_FREE_FILL) -# error "CURL_MT_MALLOC_FILL same as CURL_MT_FREE_FILL" -# endif -#endif - -#ifdef CURL_MT_MALLOC_FILL -# define mt_malloc_fill(buf,len) memset((buf), CURL_MT_MALLOC_FILL, (len)) -#else -# define mt_malloc_fill(buf,len) Curl_nop_stmt -#endif - -#ifdef CURL_MT_FREE_FILL -# define mt_free_fill(buf,len) memset((buf), CURL_MT_FREE_FILL, (len)) -#else -# define mt_free_fill(buf,len) Curl_nop_stmt -#endif - struct memdebug { size_t size; union { @@ -173,8 +127,6 @@ void *curl_dbg_malloc(size_t wantedsize, int line, const char *source) mem = (Curl_cmalloc)(size); if(mem) { - /* fill memory with junk */ - mt_malloc_fill(mem->mem, wantedsize); mem->size = wantedsize; } @@ -321,9 +273,6 @@ void curl_dbg_free(void *ptr, int line, const char *source) # pragma warning(pop) #endif - /* destroy */ - mt_free_fill(mem->mem, mem->size); - /* free for real */ (Curl_cfree)(mem); } diff --git a/libs/libcurl/src/mprintf.c b/libs/libcurl/src/mprintf.c index 80735be51b..6aceadc96f 100644 --- a/libs/libcurl/src/mprintf.c +++ b/libs/libcurl/src/mprintf.c @@ -99,12 +99,12 @@ static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; /* Upper-case digits. */ static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -#define OUTCHAR(x) \ - do{ \ +#define OUTCHAR(x) \ + do { \ if(stream((unsigned char)(x), (FILE *)data) != -1) \ - done++; \ - else \ - return done; /* return immediately on failure */ \ + done++; \ + else \ + return done; /* return immediately on failure */ \ } while(0) /* Data type to read from the arglist */ @@ -169,7 +169,7 @@ struct nsprintf { }; struct asprintf { - struct dynbuf b; + struct dynbuf *b; bool fail; /* if an alloc has failed and thus the output is not the complete data */ }; @@ -878,7 +878,7 @@ static int dprintf_formatf( OUTCHAR(' '); for(point = strnil; *point != '\0'; ++point) OUTCHAR(*point); - if(! (p->flags & FLAGS_LEFT)) + if(!(p->flags & FLAGS_LEFT)) while(width-- > 0) OUTCHAR(' '); } @@ -1042,50 +1042,61 @@ static int alloc_addbyter(int output, FILE *data) struct asprintf *infop = (struct asprintf *)data; unsigned char outc = (unsigned char)output; - if(Curl_dyn_addn(&infop->b, &outc, 1)) { + if(Curl_dyn_addn(infop->b, &outc, 1)) { infop->fail = 1; return -1; /* fail */ } return outc; /* fputc() returns like this on success */ } -char *curl_maprintf(const char *format, ...) +extern int Curl_dyn_vprintf(struct dynbuf *dyn, + const char *format, va_list ap_save); + +/* appends the formatted string, returns 0 on success, 1 on error */ +int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save) { - va_list ap_save; /* argument pointer */ int retcode; struct asprintf info; - Curl_dyn_init(&info.b, DYN_APRINTF); + info.b = dyn; info.fail = 0; - va_start(ap_save, format); retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - va_end(ap_save); if((-1 == retcode) || info.fail) { - Curl_dyn_free(&info.b); - return NULL; + Curl_dyn_free(info.b); + return 1; } - if(Curl_dyn_len(&info.b)) - return Curl_dyn_ptr(&info.b); - return strdup(""); + return 0; } char *curl_mvaprintf(const char *format, va_list ap_save) { int retcode; struct asprintf info; - Curl_dyn_init(&info.b, DYN_APRINTF); + struct dynbuf dyn; + info.b = &dyn; + Curl_dyn_init(info.b, DYN_APRINTF); info.fail = 0; retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); if((-1 == retcode) || info.fail) { - Curl_dyn_free(&info.b); + Curl_dyn_free(info.b); return NULL; } - if(Curl_dyn_len(&info.b)) - return Curl_dyn_ptr(&info.b); + if(Curl_dyn_len(info.b)) + return Curl_dyn_ptr(info.b); return strdup(""); } +char *curl_maprintf(const char *format, ...) +{ + va_list ap_save; + char *s; + va_start(ap_save, format); + s = curl_mvaprintf(format, ap_save); + va_end(ap_save); + return s; +} + static int storebuffer(int output, FILE *data) { char **buffer = (char **)data; diff --git a/libs/libcurl/src/mqtt.c b/libs/libcurl/src/mqtt.c index f6f4416140..c0e9a2b754 100644 --- a/libs/libcurl/src/mqtt.c +++ b/libs/libcurl/src/mqtt.c @@ -23,7 +23,7 @@ #include "curl_setup.h" -#ifdef CURL_ENABLE_MQTT +#ifndef CURL_DISABLE_MQTT #include "urldata.h" #include <curl/curl.h> @@ -86,6 +86,7 @@ const struct Curl_handler Curl_handler_mqtt = { ZERO_NULL, /* connection_check */ PORT_MQTT, /* defport */ CURLPROTO_MQTT, /* protocol */ + CURLPROTO_MQTT, /* family */ PROTOPT_NONE /* flags */ }; @@ -142,7 +143,7 @@ static CURLcode mqtt_connect(struct connectdata *conn) const size_t client_id_offset = 14; const size_t packetlen = client_id_offset + MQTT_CLIENTID_LEN; char client_id[MQTT_CLIENTID_LEN + 1] = "curl"; - const size_t curl_len = strlen("curl"); + const size_t clen = strlen("curl"); char packet[32] = { MQTT_MSG_CONNECT, /* packet type */ 0x00, /* remaining length */ @@ -156,8 +157,8 @@ static CURLcode mqtt_connect(struct connectdata *conn) packet[1] = (packetlen - 2) & 0x7f; packet[client_id_offset - 1] = MQTT_CLIENTID_LEN; - result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[curl_len], - MQTT_CLIENTID_LEN - curl_len + 1); + result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[clen], + MQTT_CLIENTID_LEN - clen + 1); memcpy(&packet[client_id_offset], client_id, MQTT_CLIENTID_LEN); infof(conn->data, "Using client id '%s'\n", client_id); if(!result) @@ -625,4 +626,4 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done) return result; } -#endif /* CURL_ENABLE_MQTT */ +#endif /* CURL_DISABLE_MQTT */ diff --git a/libs/libcurl/src/mqtt.h b/libs/libcurl/src/mqtt.h index 37463d58ad..37c0441358 100644 --- a/libs/libcurl/src/mqtt.h +++ b/libs/libcurl/src/mqtt.h @@ -22,7 +22,7 @@ * ***************************************************************************/ -#ifdef CURL_ENABLE_MQTT +#ifndef CURL_DISABLE_MQTT extern const struct Curl_handler Curl_handler_mqtt; #endif diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index 3c7fb85ed8..4cc7c5ae61 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -190,7 +190,7 @@ static void mstate(struct Curl_easy *data, CURLMstate state */ struct Curl_sh_entry { - struct curl_hash transfers; /* hash of transfers using this socket */ + struct Curl_hash transfers; /* hash of transfers using this socket */ unsigned int action; /* what combined action READ/WRITE this socket waits for */ void *socketp; /* settable by users with curl_multi_assign() */ @@ -204,7 +204,7 @@ struct Curl_sh_entry { #define SH_WRITE 2 /* look up a given socket in the socket hash, skip invalid sockets */ -static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh, +static struct Curl_sh_entry *sh_getentry(struct Curl_hash *sh, curl_socket_t s) { if(s != CURL_SOCKET_BAD) { @@ -238,7 +238,7 @@ static void trhash_dtor(void *nada) /* make sure this socket is present in the hash for this handle */ -static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh, +static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh, curl_socket_t s) { struct Curl_sh_entry *there = sh_getentry(sh, s); @@ -273,7 +273,7 @@ static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh, /* delete the given socket + handle from the hash */ static void sh_delentry(struct Curl_sh_entry *entry, - struct curl_hash *sh, curl_socket_t s) + struct Curl_hash *sh, curl_socket_t s) { Curl_hash_destroy(&entry->transfers); @@ -325,7 +325,7 @@ static size_t hash_fd(void *key, size_t key_length, size_t slots_num) * per call." * */ -static int sh_init(struct curl_hash *hash, int hashsize) +static int sh_init(struct Curl_hash *hash, int hashsize) { return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare, sh_freeentry); @@ -374,6 +374,11 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ multi->max_concurrent_streams = 100; multi->ipv6_works = Curl_ipv6works(NULL); +#ifdef USE_WINSOCK + multi->wsa_event = WSACreateEvent(); + if(multi->wsa_event == WSA_INVALID_EVENT) + goto error; +#else #ifdef ENABLE_WAKEUP if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) { multi->wakeup_pair[0] = CURL_SOCKET_BAD; @@ -387,6 +392,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ multi->wakeup_pair[1] = CURL_SOCKET_BAD; } #endif +#endif return multi; @@ -716,7 +722,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, struct Curl_easy *easy = data; bool premature; bool easy_owns_conn; - struct curl_llist_element *e; + struct Curl_llist_element *e; /* First, make some basic checks that the CURLM handle is a good handle */ if(!GOOD_MULTI_HANDLE(multi)) @@ -1081,11 +1087,17 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, unsigned int i; unsigned int nfds = 0; unsigned int curlfds; - bool ufds_malloc = FALSE; long timeout_internal; int retcode = 0; +#ifndef USE_WINSOCK struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; struct pollfd *ufds = &a_few_on_stack[0]; + bool ufds_malloc = FALSE; +#else + struct pollfd pre_poll; + WSANETWORKEVENTS wsa_events; + DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT); +#endif if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; @@ -1131,11 +1143,16 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, nfds += extra_nfds; /* add the externally provided ones */ #ifdef ENABLE_WAKEUP +#ifdef USE_WINSOCK + if(use_wakeup) { +#else if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { +#endif ++nfds; } #endif +#ifndef USE_WINSOCK if(nfds > NUM_POLLS_ON_STACK) { /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes big, so at 2^29 sockets this value might wrap. When a process gets @@ -1146,7 +1163,9 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, return CURLM_OUT_OF_MEMORY; ufds_malloc = TRUE; } + nfds = 0; +#endif /* only do the second loop if we found descriptors in the first stage run above */ @@ -1157,24 +1176,42 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, while(data) { bitmap = multi_getsock(data, sockbunch); - for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) { + for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) { curl_socket_t s = CURL_SOCKET_BAD; - +#ifdef USE_WINSOCK + long mask = 0; +#endif if(bitmap & GETSOCK_READSOCK(i)) { +#ifdef USE_WINSOCK + if(timeout_ms && SOCKET_READABLE(sockbunch[i], 0) > 0) + timeout_ms = 0; + mask |= FD_READ|FD_ACCEPT|FD_CLOSE; +#else ufds[nfds].fd = sockbunch[i]; ufds[nfds].events = POLLIN; ++nfds; +#endif s = sockbunch[i]; } if(bitmap & GETSOCK_WRITESOCK(i)) { +#ifdef USE_WINSOCK + if(timeout_ms && SOCKET_WRITABLE(sockbunch[i], 0) > 0) + timeout_ms = 0; + mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; +#else ufds[nfds].fd = sockbunch[i]; ufds[nfds].events = POLLOUT; ++nfds; +#endif s = sockbunch[i]; } if(s == CURL_SOCKET_BAD) { break; } +#ifdef USE_WINSOCK + if(WSAEventSelect(s, multi->wsa_event, mask) != 0) + return CURLM_INTERNAL_ERROR; +#endif } data = data->next; /* check next handle */ @@ -1183,6 +1220,37 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, /* Add external file descriptions from poll-like struct curl_waitfd */ for(i = 0; i < extra_nfds; i++) { +#ifdef USE_WINSOCK + long mask = 0; + extra_fds[i].revents = 0; + pre_poll.fd = extra_fds[i].fd; + pre_poll.events = 0; + pre_poll.revents = 0; + if(extra_fds[i].events & CURL_WAIT_POLLIN) { + mask |= FD_READ|FD_ACCEPT|FD_CLOSE; + pre_poll.events |= POLLIN; + } + if(extra_fds[i].events & CURL_WAIT_POLLPRI) { + mask |= FD_OOB; + pre_poll.events |= POLLPRI; + } + if(extra_fds[i].events & CURL_WAIT_POLLOUT) { + mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; + pre_poll.events |= POLLOUT; + } + if(Curl_poll(&pre_poll, 1, 0) > 0) { + if(pre_poll.revents & POLLIN) + extra_fds[i].revents |= CURL_WAIT_POLLIN; + if(pre_poll.revents & POLLPRI) + extra_fds[i].revents |= CURL_WAIT_POLLPRI; + if(pre_poll.revents & POLLOUT) + extra_fds[i].revents |= CURL_WAIT_POLLOUT; + if(extra_fds[i].revents) + timeout_ms = 0; + } + if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) + return CURLM_INTERNAL_ERROR; +#else ufds[nfds].fd = extra_fds[i].fd; ufds[nfds].events = 0; if(extra_fds[i].events & CURL_WAIT_POLLIN) @@ -1192,28 +1260,57 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, if(extra_fds[i].events & CURL_WAIT_POLLOUT) ufds[nfds].events |= POLLOUT; ++nfds; +#endif } #ifdef ENABLE_WAKEUP +#ifndef USE_WINSOCK if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { ufds[nfds].fd = multi->wakeup_pair[0]; ufds[nfds].events = POLLIN; ++nfds; } #endif +#endif if(nfds) { - int pollrc; /* wait... */ - pollrc = Curl_poll(ufds, nfds, timeout_ms); +#ifdef USE_WINSOCK + WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE); +#else + int pollrc = Curl_poll(ufds, nfds, timeout_ms); +#endif +#ifdef USE_WINSOCK + /* With Winsock, we have to run this unconditionally to call + WSAEventSelect(fd, event, 0) on all the sockets */ + { + retcode = 0; +#else if(pollrc > 0) { retcode = pollrc; +#endif /* copy revents results from the poll to the curl_multi_wait poll struct, the bit values of the actual underlying poll() implementation may not be the same as the ones in the public libcurl API! */ for(i = 0; i < extra_nfds; i++) { unsigned short mask = 0; +#ifdef USE_WINSOCK + wsa_events.lNetworkEvents = 0; + mask = extra_fds[i].revents; + if(WSAEnumNetworkEvents(extra_fds[i].fd, multi->wsa_event, + &wsa_events) == 0) { + if(wsa_events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)) + mask |= CURL_WAIT_POLLIN; + if(wsa_events.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE)) + mask |= CURL_WAIT_POLLOUT; + if(wsa_events.lNetworkEvents & FD_OOB) + mask |= CURL_WAIT_POLLPRI; + if(ret && wsa_events.lNetworkEvents != 0) + retcode++; + } + WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0); +#else unsigned r = ufds[curlfds + i].revents; if(r & POLLIN) @@ -1222,10 +1319,46 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, mask |= CURL_WAIT_POLLOUT; if(r & POLLPRI) mask |= CURL_WAIT_POLLPRI; - +#endif extra_fds[i].revents = mask; } +#ifdef USE_WINSOCK + /* Count up all our own sockets that had activity, + and remove them from the event. */ + if(curlfds) { + data = multi->easyp; + while(data) { + bitmap = multi_getsock(data, sockbunch); + + for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) { + if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) { + wsa_events.lNetworkEvents = 0; + if(WSAEnumNetworkEvents(sockbunch[i], multi->wsa_event, + &wsa_events) == 0) { + if(ret && wsa_events.lNetworkEvents != 0) + retcode++; + } + if(ret && !timeout_ms && wsa_events.lNetworkEvents == 0) { + if((bitmap & GETSOCK_READSOCK(i)) && + SOCKET_READABLE(sockbunch[i], 0) > 0) + retcode++; + else if((bitmap & GETSOCK_WRITESOCK(i)) && + SOCKET_WRITABLE(sockbunch[i], 0) > 0) + retcode++; + } + WSAEventSelect(sockbunch[i], multi->wsa_event, 0); + } + else + break; + } + + data = data->next; + } + } + + WSAResetEvent(multi->wsa_event); +#else #ifdef ENABLE_WAKEUP if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { if(ufds[curlfds + extra_nfds].revents & POLLIN) { @@ -1238,10 +1371,8 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, when there is no more data, breaking the loop. */ nread = sread(multi->wakeup_pair[0], buf, sizeof(buf)); if(nread <= 0) { -#ifndef USE_WINSOCK if(nread < 0 && EINTR == SOCKERRNO) continue; -#endif break; } } @@ -1250,11 +1381,14 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, } } #endif +#endif } } +#ifndef USE_WINSOCK if(ufds_malloc) free(ufds); +#endif if(ret) *ret = retcode; if(!extrawait || nfds) @@ -1309,6 +1443,10 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi) return CURLM_BAD_HANDLE; #ifdef ENABLE_WAKEUP +#ifdef USE_WINSOCK + if(WSASetEvent(multi->wsa_event)) + return CURLM_OK; +#else /* the wakeup_pair variable is only written during init and cleanup, making it safe to access from another thread after the init part and before cleanup */ @@ -1342,6 +1480,7 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi) } } #endif +#endif return CURLM_WAKEUP_FAILURE; } @@ -1562,7 +1701,7 @@ CURLcode Curl_preconnect(struct Curl_easy *data) static CURLMcode multi_runsingle(struct Curl_multi *multi, - struct curltime now, + struct curltime *nowp, struct Curl_easy *data) { struct Curl_message *msg = NULL; @@ -1603,7 +1742,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, (data->mstate < CURLM_STATE_COMPLETED)) { /* we need to wait for the connect state as only then is the start time stored, but we must not check already completed handles */ - timeout_ms = Curl_timeleft(data, &now, + timeout_ms = Curl_timeleft(data, nowp, (data->mstate <= CURLM_STATE_DO)? TRUE:FALSE); @@ -1612,25 +1751,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(data->mstate == CURLM_STATE_WAITRESOLVE) failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds", - Curl_timediff(now, data->progress.t_startsingle)); + Curl_timediff(*nowp, data->progress.t_startsingle)); else if(data->mstate == CURLM_STATE_WAITCONNECT) failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds", - Curl_timediff(now, data->progress.t_startsingle)); + Curl_timediff(*nowp, data->progress.t_startsingle)); else { struct SingleRequest *k = &data->req; if(k->size != -1) { failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_timediff(now, data->progress.t_startsingle), + Curl_timediff(*nowp, data->progress.t_startsingle), k->bytecount, k->size); } else { failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_timediff(now, data->progress.t_startsingle), + Curl_timediff(*nowp, data->progress.t_startsingle), k->bytecount); } } @@ -1655,7 +1794,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(!result) { /* after init, go CONNECT */ multistate(data, CURLM_STATE_CONNECT); - Curl_pgrsTime(data, TIMER_STARTOP); + *nowp = Curl_pgrsTime(data, TIMER_STARTOP); rc = CURLM_CALL_MULTI_PERFORM; } break; @@ -1672,7 +1811,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(result) break; - Curl_pgrsTime(data, TIMER_STARTSINGLE); + *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE); if(data->set.timeout) Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT); @@ -2080,7 +2219,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(Curl_pgrsUpdate(data->conn)) result = CURLE_ABORTED_BY_CALLBACK; else - result = Curl_speedcheck(data, now); + result = Curl_speedcheck(data, *nowp); if(!result) { send_timeout_ms = 0; @@ -2090,7 +2229,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->progress.ul_limit_size, data->set.max_send_speed, data->progress.ul_limit_start, - now); + *nowp); recv_timeout_ms = 0; if(data->set.max_recv_speed > 0) @@ -2099,11 +2238,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->progress.dl_limit_size, data->set.max_recv_speed, data->progress.dl_limit_start, - now); + *nowp); if(!send_timeout_ms && !recv_timeout_ms) { multistate(data, CURLM_STATE_PERFORM); - Curl_ratelimit(data, now); + Curl_ratelimit(data, *nowp); } else if(send_timeout_ms >= recv_timeout_ms) Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); @@ -2125,7 +2264,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->progress.ul_limit_size, data->set.max_send_speed, data->progress.ul_limit_start, - now); + *nowp); /* check if over recv speed */ recv_timeout_ms = 0; @@ -2134,10 +2273,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->progress.dl_limit_size, data->set.max_recv_speed, data->progress.dl_limit_start, - now); + *nowp); if(send_timeout_ms || recv_timeout_ms) { - Curl_ratelimit(data, now); + Curl_ratelimit(data, *nowp); multistate(data, CURLM_STATE_TOOFAST); if(send_timeout_ms >= recv_timeout_ms) Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); @@ -2417,7 +2556,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) SIGPIPE_VARIABLE(pipe_st); sigpipe_ignore(data, &pipe_st); - result = multi_runsingle(multi, now, data); + result = multi_runsingle(multi, &now, data); sigpipe_restore(&pipe_st); if(result) @@ -2500,10 +2639,14 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) Curl_hash_destroy(&multi->hostcache); Curl_psl_destroy(&multi->psl); +#ifdef USE_WINSOCK + WSACloseEvent(multi->wsa_event); +#else #ifdef ENABLE_WAKEUP sclose(multi->wakeup_pair[0]); sclose(multi->wakeup_pair[1]); #endif +#endif free(multi); return CURLM_OK; @@ -2531,7 +2674,7 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue) !multi->in_callback && Curl_llist_count(&multi->msglist)) { /* there is one or more messages in the list */ - struct curl_llist_element *e; + struct Curl_llist_element *e; /* extract the head of the list to return */ e = multi->msglist.head; @@ -2761,15 +2904,15 @@ static CURLMcode add_next_timeout(struct curltime now, struct Curl_easy *d) { struct curltime *tv = &d->state.expiretime; - struct curl_llist *list = &d->state.timeoutlist; - struct curl_llist_element *e; + struct Curl_llist *list = &d->state.timeoutlist; + struct Curl_llist_element *e; struct time_node *node = NULL; /* move over the timeout list for this specific handle and remove all timeouts that are now passed tense and store the next pending timeout in *tv */ for(e = list->head; e;) { - struct curl_llist_element *n = e->next; + struct Curl_llist_element *n = e->next; timediff_t diff; node = (struct time_node *)e->ptr; diff = Curl_timediff(node->time, now); @@ -2839,8 +2982,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi, and just move on. */ ; else { - struct curl_hash_iterator iter; - struct curl_hash_element *he; + struct Curl_hash_iterator iter; + struct Curl_hash_element *he; /* the socket can be shared by many transfers, iterate */ Curl_hash_start_iterate(&entry->transfers, &iter); @@ -2887,7 +3030,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi, SIGPIPE_VARIABLE(pipe_st); sigpipe_ignore(data, &pipe_st); - result = multi_runsingle(multi, now, data); + result = multi_runsingle(multi, &now, data); sigpipe_restore(&pipe_st); if(CURLM_OK >= result) { @@ -3123,8 +3266,8 @@ void Curl_update_timer(struct Curl_multi *multi) static void multi_deltimeout(struct Curl_easy *data, expire_id eid) { - struct curl_llist_element *e; - struct curl_llist *timeoutlist = &data->state.timeoutlist; + struct Curl_llist_element *e; + struct Curl_llist *timeoutlist = &data->state.timeoutlist; /* find and remove the specific node from the list */ for(e = timeoutlist->head; e; e = e->next) { struct time_node *n = (struct time_node *)e->ptr; @@ -3147,11 +3290,11 @@ multi_addtimeout(struct Curl_easy *data, struct curltime *stamp, expire_id eid) { - struct curl_llist_element *e; + struct Curl_llist_element *e; struct time_node *node; - struct curl_llist_element *prev = NULL; + struct Curl_llist_element *prev = NULL; size_t n; - struct curl_llist *timeoutlist = &data->state.timeoutlist; + struct Curl_llist *timeoutlist = &data->state.timeoutlist; node = &data->state.expires[eid]; @@ -3278,7 +3421,7 @@ void Curl_expire_clear(struct Curl_easy *data) if(nowp->tv_sec || nowp->tv_usec) { /* Since this is an cleared time, we must remove the previous entry from the splay tree */ - struct curl_llist *list = &data->state.timeoutlist; + struct Curl_llist *list = &data->state.timeoutlist; int rc; rc = Curl_splayremovebyaddr(multi->timetree, @@ -3349,7 +3492,7 @@ void Curl_multiuse_state(struct connectdata *conn, static void process_pending_handles(struct Curl_multi *multi) { - struct curl_llist_element *e = multi->pending.head; + struct Curl_llist_element *e = multi->pending.head; if(e) { struct Curl_easy *data = e->ptr; diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h index 9d73df0812..c70a1ce09a 100644 --- a/libs/libcurl/src/multihandle.h +++ b/libs/libcurl/src/multihandle.h @@ -27,7 +27,7 @@ #include "socketpair.h" struct Curl_message { - struct curl_llist_element list; + struct Curl_llist_element list; /* the 'CURLMsg' is the part that is visible to the external user */ struct CURLMsg extmsg; }; @@ -67,11 +67,11 @@ typedef enum { #define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) -#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS) +#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS) && \ + !defined(CURL_DISABLE_SOCKETPAIR) #define ENABLE_WAKEUP #endif - /* value for MAXIMUM CONCURRENT STREAMS upper limit */ #define INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1) @@ -89,9 +89,9 @@ struct Curl_multi { int num_alive; /* amount of easy handles that are added but have not yet reached COMPLETE state */ - struct curl_llist msglist; /* a list of messages from completed transfers */ + struct Curl_llist msglist; /* a list of messages from completed transfers */ - struct curl_llist pending; /* Curl_easys that are in the + struct Curl_llist pending; /* Curl_easys that are in the CURLM_STATE_CONNECT_PEND state */ /* callback function and user data pointer for the *socket() API */ @@ -103,7 +103,7 @@ struct Curl_multi { void *push_userp; /* Hostname cache */ - struct curl_hash hostcache; + struct Curl_hash hostcache; #ifdef USE_LIBPSL /* PSL cache. */ @@ -117,7 +117,7 @@ struct Curl_multi { /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note the pluralis form, there can be more than one easy handle waiting on the same actual socket) */ - struct curl_hash sockhash; + struct Curl_hash sockhash; /* Shared connection cache (bundles)*/ struct conncache conn_cache; @@ -138,10 +138,14 @@ struct Curl_multi { previous callback */ unsigned int max_concurrent_streams; +#ifdef USE_WINSOCK + WSAEVENT wsa_event; /* winsock event used for waits */ +#else #ifdef ENABLE_WAKEUP curl_socket_t wakeup_pair[2]; /* socketpair() used for wakeup 0 is used for read, 1 is used for write */ #endif +#endif /* multiplexing wanted */ bool multiplexing; bool recheckstate; /* see Curl_multi_connchanged */ diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c index 782d6a08e7..2aff4f6037 100644 --- a/libs/libcurl/src/openldap.c +++ b/libs/libcurl/src/openldap.c @@ -107,6 +107,7 @@ const struct Curl_handler Curl_handler_ldap = { ZERO_NULL, /* connection_check */ PORT_LDAP, /* defport */ CURLPROTO_LDAP, /* protocol */ + CURLPROTO_LDAP, /* family */ PROTOPT_NONE /* flags */ }; @@ -132,7 +133,8 @@ const struct Curl_handler Curl_handler_ldaps = { ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ PORT_LDAPS, /* defport */ - CURLPROTO_LDAP, /* protocol */ + CURLPROTO_LDAPS, /* protocol */ + CURLPROTO_LDAP, /* family */ PROTOPT_SSL /* flags */ }; #endif diff --git a/libs/libcurl/src/parsedate.c b/libs/libcurl/src/parsedate.c index 4c7a40c4c5..dd6150b44e 100644 --- a/libs/libcurl/src/parsedate.c +++ b/libs/libcurl/src/parsedate.c @@ -275,48 +275,21 @@ enum assume { DATE_TIME }; -/* this is a clone of 'struct tm' but with all fields we don't need or use - cut out */ -struct my_tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; /* full year */ -}; - -/* struct tm to time since epoch in GMT time zone. - * This is similar to the standard mktime function but for GMT only, and - * doesn't suffer from the various bugs and portability problems that - * some systems' implementations have. - * - * Returns 0 on success, otherwise non-zero. +/* + * time2epoch: time stamp to seconds since epoch in GMT time zone. Similar to + * mktime but for GMT only. */ -static void my_timegm(struct my_tm *tm, time_t *t) +static time_t time2epoch(int sec, int min, int hour, + int mday, int mon, int year) { static const int month_days_cumulative [12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - int month, year, leap_days; - - year = tm->tm_year; - month = tm->tm_mon; - if(month < 0) { - year += (11 - month) / 12; - month = 11 - (11 - month) % 12; - } - else if(month >= 12) { - year -= month / 12; - month = month % 12; - } - - leap_days = year - (tm->tm_mon <= 1); + int leap_days = year - (mon <= 1); leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400) - (1969 / 4) + (1969 / 100) - (1969 / 400)); - - *t = ((((time_t) (year - 1970) * 365 - + leap_days + month_days_cumulative[month] + tm->tm_mday - 1) * 24 - + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; + return ((((time_t) (year - 1970) * 365 + + leap_days + month_days_cumulative[mon] + mday - 1) * 24 + + hour) * 60 + min) * 60 + sec; } /* @@ -341,7 +314,6 @@ static int parsedate(const char *date, time_t *output) int secnum = -1; int yearnum = -1; int tzoff = -1; - struct my_tm tm; enum assume dignext = DATE_MDAY; const char *indate = date; /* save the original pointer */ int part = 0; /* max 6 parts */ @@ -533,18 +505,11 @@ static int parsedate(const char *date, time_t *output) (hournum > 23) || (minnum > 59) || (secnum > 60)) return PARSEDATE_FAIL; /* clearly an illegal date */ - tm.tm_sec = secnum; - tm.tm_min = minnum; - tm.tm_hour = hournum; - tm.tm_mday = mdaynum; - tm.tm_mon = monnum; - tm.tm_year = yearnum; - - /* my_timegm() returns a time_t. time_t is often 32 bits, sometimes even on + /* time2epoch() returns a time_t. time_t is often 32 bits, sometimes even on architectures that feature 64 bit 'long' but ultimately time_t is the correct data type to use. */ - my_timegm(&tm, &t); + t = time2epoch(secnum, minnum, hournum, mdaynum, monnum, yearnum); /* Add the time zone diff between local time zone and GMT. */ if(tzoff == -1) diff --git a/libs/libcurl/src/pingpong.c b/libs/libcurl/src/pingpong.c index 3143315219..5a06674ad1 100644 --- a/libs/libcurl/src/pingpong.c +++ b/libs/libcurl/src/pingpong.c @@ -146,7 +146,11 @@ void Curl_pp_init(struct pingpong *pp) pp->response = Curl_now(); /* start response time-out now! */ } - +/* setup for the coming transfer */ +void Curl_pp_setup(struct pingpong *pp) +{ + Curl_dyn_init(&pp->sendbuf, DYN_PINGPPONG_CMD); +} /*********************************************************************** * @@ -162,9 +166,8 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp, const char *fmt, va_list args) { - ssize_t bytes_written; + ssize_t bytes_written = 0; size_t write_len; - char *fmt_crlf; char *s; CURLcode result; struct connectdata *conn = pp->conn; @@ -181,48 +184,42 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp, if(!conn) /* can't send without a connection! */ return CURLE_SEND_ERROR; - data = conn->data; - fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */ - if(!fmt_crlf) - return CURLE_OUT_OF_MEMORY; - - s = vaprintf(fmt_crlf, args); /* trailing CRLF appended */ - free(fmt_crlf); - if(!s) - return CURLE_OUT_OF_MEMORY; + Curl_dyn_reset(&pp->sendbuf); + result = Curl_dyn_vaddf(&pp->sendbuf, fmt, args); + if(result) + return result; - bytes_written = 0; - write_len = strlen(s); + /* append CRLF */ + result = Curl_dyn_addn(&pp->sendbuf, "\r\n", 2); + if(result) + return result; + write_len = Curl_dyn_len(&pp->sendbuf); + s = Curl_dyn_ptr(&pp->sendbuf); Curl_pp_init(pp); result = Curl_convert_to_network(data, s, write_len); /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) { - free(s); + if(result) return result; - } #ifdef HAVE_GSSAPI conn->data_prot = PROT_CMD; #endif result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len, - &bytes_written); + &bytes_written); + if(result) + return result; #ifdef HAVE_GSSAPI data_sec = conn->data_prot; DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); conn->data_prot = data_sec; #endif - if(result) { - free(s); - return result; - } - - if(conn->data->set.verbose) - Curl_debug(conn->data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written); + if(data->set.verbose) + Curl_debug(data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written); if(bytes_written != (ssize_t)write_len) { /* the whole chunk was not sent, keep it around and adjust sizes */ @@ -231,7 +228,6 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp, pp->sendleft = write_len - bytes_written; } else { - free(s); pp->sendthis = NULL; pp->sendleft = pp->sendsize = 0; pp->response = Curl_now(); @@ -493,7 +489,6 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp) pp->sendleft -= written; } else { - free(pp->sendthis); pp->sendthis = NULL; pp->sendleft = pp->sendsize = 0; pp->response = Curl_now(); @@ -503,15 +498,15 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp) CURLcode Curl_pp_disconnect(struct pingpong *pp) { - free(pp->cache); - pp->cache = NULL; + Curl_dyn_free(&pp->sendbuf); + Curl_safefree(pp->cache); return CURLE_OK; } bool Curl_pp_moredata(struct pingpong *pp) { return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ? - TRUE : FALSE; + TRUE : FALSE; } #endif diff --git a/libs/libcurl/src/pingpong.h b/libs/libcurl/src/pingpong.h index e874799d44..855815afd5 100644 --- a/libs/libcurl/src/pingpong.h +++ b/libs/libcurl/src/pingpong.h @@ -64,6 +64,7 @@ struct pingpong { milliseconds we await for a server response. */ struct connectdata *conn; /* points to the connectdata struct that this belongs to */ + struct dynbuf sendbuf; /* Function pointers the protocols MUST implement and provide for the pingpong layer to function */ @@ -86,6 +87,9 @@ CURLcode Curl_pp_statemach(struct pingpong *pp, bool block, /* initialize stuff to prepare for reading a fresh new response */ void Curl_pp_init(struct pingpong *pp); +/* setup for the transfer */ +void Curl_pp_setup(struct pingpong *pp); + /* Returns timeout in ms. 0 or negative number means the timeout has already triggered */ timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting); diff --git a/libs/libcurl/src/pop3.c b/libs/libcurl/src/pop3.c index 9ff5c78fd0..5a73545823 100644 --- a/libs/libcurl/src/pop3.c +++ b/libs/libcurl/src/pop3.c @@ -128,6 +128,7 @@ const struct Curl_handler Curl_handler_pop3 = { ZERO_NULL, /* connection_check */ PORT_POP3, /* defport */ CURLPROTO_POP3, /* protocol */ + CURLPROTO_POP3, /* family */ PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ PROTOPT_URLOPTIONS }; @@ -155,6 +156,7 @@ const struct Curl_handler Curl_handler_pop3s = { ZERO_NULL, /* connection_check */ PORT_POP3S, /* defport */ CURLPROTO_POP3S, /* protocol */ + CURLPROTO_POP3, /* family */ PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */ }; @@ -1091,6 +1093,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done) Curl_sasl_init(&pop3c->sasl, &saslpop3); /* Initialise the pingpong layer */ + Curl_pp_setup(pp); Curl_pp_init(pp); /* Parse the URL options */ diff --git a/libs/libcurl/src/progress.c b/libs/libcurl/src/progress.c index 8951384481..eced74c9f9 100644 --- a/libs/libcurl/src/progress.c +++ b/libs/libcurl/src/progress.c @@ -164,9 +164,13 @@ void Curl_pgrsResetTransferSizes(struct Curl_easy *data) } /* + * + * Curl_pgrsTime(). Store the current time at the given label. This fetches a + * fresh "now" and returns it. + * * @unittest: 1399 */ -void Curl_pgrsTime(struct Curl_easy *data, timerid timer) +struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer) { struct curltime now = Curl_now(); timediff_t *delta = NULL; @@ -209,7 +213,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer) * changing the t_starttransfer time. */ if(data->progress.is_t_startransfer_set) { - return; + return now; } else { data->progress.is_t_startransfer_set = true; @@ -228,6 +232,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer) us = 1; /* make sure at least one microsecond passed */ *delta += us; } + return now; } void Curl_pgrsStartNow(struct Curl_easy *data) diff --git a/libs/libcurl/src/progress.h b/libs/libcurl/src/progress.h index 3515ac6d5c..c19d966d31 100644 --- a/libs/libcurl/src/progress.h +++ b/libs/libcurl/src/progress.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -49,7 +49,7 @@ void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size); void Curl_ratelimit(struct Curl_easy *data, struct curltime now); int Curl_pgrsUpdate(struct connectdata *); void Curl_pgrsResetTransferSizes(struct Curl_easy *data); -void Curl_pgrsTime(struct Curl_easy *data, timerid timer); +struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer); timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, curl_off_t startsize, curl_off_t limit, diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c index dbd7dc6a6d..46c3c4f8f4 100644 --- a/libs/libcurl/src/rtsp.c +++ b/libs/libcurl/src/rtsp.c @@ -106,6 +106,7 @@ const struct Curl_handler Curl_handler_rtsp = { rtsp_conncheck, /* connection_check */ PORT_RTSP, /* defport */ CURLPROTO_RTSP, /* protocol */ + CURLPROTO_RTSP, /* family */ PROTOPT_NONE /* flags */ }; diff --git a/libs/libcurl/src/security.c b/libs/libcurl/src/security.c deleted file mode 100644 index fbfa707413..0000000000 --- a/libs/libcurl/src/security.c +++ /dev/null @@ -1,579 +0,0 @@ -/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for - * use in Curl. His latest changes were done 2000-09-18. - * - * It has since been patched and modified a lot by Daniel Stenberg - * <daniel@haxx.se> to make it better applied to curl conditions, and to make - * it not use globals, pollute name space and more. This source code awaits a - * rewrite to work around the paragraph 2 in the BSD licenses as explained - * below. - * - * Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * - * Copyright (C) 2001 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. */ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP -#ifdef HAVE_GSSAPI - -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif - -#include <limits.h> - -#include "urldata.h" -#include "curl_base64.h" -#include "curl_memory.h" -#include "curl_sec.h" -#include "ftp.h" -#include "sendf.h" -#include "strcase.h" -#include "warnless.h" -#include "strdup.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -static const struct { - enum protection_level level; - const char *name; -} level_names[] = { - { PROT_CLEAR, "clear" }, - { PROT_SAFE, "safe" }, - { PROT_CONFIDENTIAL, "confidential" }, - { PROT_PRIVATE, "private" } -}; - -static enum protection_level -name_to_level(const char *name) -{ - int i; - for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++) - if(checkprefix(name, level_names[i].name)) - return level_names[i].level; - return PROT_NONE; -} - -/* Convert a protocol |level| to its char representation. - We take an int to catch programming mistakes. */ -static char level_to_char(int level) -{ - switch(level) { - case PROT_CLEAR: - return 'C'; - case PROT_SAFE: - return 'S'; - case PROT_CONFIDENTIAL: - return 'E'; - case PROT_PRIVATE: - return 'P'; - case PROT_CMD: - /* Fall through */ - default: - /* Those 2 cases should not be reached! */ - break; - } - DEBUGASSERT(0); - /* Default to the most secure alternative. */ - return 'P'; -} - -/* Send an FTP command defined by |message| and the optional arguments. The - function returns the ftp_code. If an error occurs, -1 is returned. */ -static int ftp_send_command(struct connectdata *conn, const char *message, ...) -{ - int ftp_code; - ssize_t nread = 0; - va_list args; - char print_buffer[50]; - - va_start(args, message); - mvsnprintf(print_buffer, sizeof(print_buffer), message, args); - va_end(args); - - if(Curl_ftpsend(conn, print_buffer)) { - ftp_code = -1; - } - else { - if(Curl_GetFTPResponse(&nread, conn, &ftp_code)) - ftp_code = -1; - } - - (void)nread; /* Unused */ - return ftp_code; -} - -/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode - saying whether an error occurred or CURLE_OK if |len| was read. */ -static CURLcode -socket_read(curl_socket_t fd, void *to, size_t len) -{ - char *to_p = to; - CURLcode result; - ssize_t nread = 0; - - while(len > 0) { - result = Curl_read_plain(fd, to_p, len, &nread); - if(!result) { - len -= nread; - to_p += nread; - } - else { - if(result == CURLE_AGAIN) - continue; - return result; - } - } - return CURLE_OK; -} - - -/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a - CURLcode saying whether an error occurred or CURLE_OK if |len| was - written. */ -static CURLcode -socket_write(struct connectdata *conn, curl_socket_t fd, const void *to, - size_t len) -{ - const char *to_p = to; - CURLcode result; - ssize_t written; - - while(len > 0) { - result = Curl_write_plain(conn, fd, to_p, len, &written); - if(!result) { - len -= written; - to_p += written; - } - else { - if(result == CURLE_AGAIN) - continue; - return result; - } - } - return CURLE_OK; -} - -static CURLcode read_data(struct connectdata *conn, - curl_socket_t fd, - struct krb5buffer *buf) -{ - int len; - CURLcode result; - - result = socket_read(fd, &len, sizeof(len)); - if(result) - return result; - - if(len) { - /* only realloc if there was a length */ - len = ntohl(len); - buf->data = Curl_saferealloc(buf->data, len); - } - if(!len || !buf->data) - return CURLE_OUT_OF_MEMORY; - - result = socket_read(fd, buf->data, len); - if(result) - return result; - buf->size = conn->mech->decode(conn->app_data, buf->data, len, - conn->data_prot, conn); - buf->index = 0; - return CURLE_OK; -} - -static size_t -buffer_read(struct krb5buffer *buf, void *data, size_t len) -{ - if(buf->size - buf->index < len) - len = buf->size - buf->index; - memcpy(data, (char *)buf->data + buf->index, len); - buf->index += len; - return len; -} - -/* Matches Curl_recv signature */ -static ssize_t sec_recv(struct connectdata *conn, int sockindex, - char *buffer, size_t len, CURLcode *err) -{ - size_t bytes_read; - size_t total_read = 0; - curl_socket_t fd = conn->sock[sockindex]; - - *err = CURLE_OK; - - /* Handle clear text response. */ - if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR) - return sread(fd, buffer, len); - - if(conn->in_buffer.eof_flag) { - conn->in_buffer.eof_flag = 0; - return 0; - } - - bytes_read = buffer_read(&conn->in_buffer, buffer, len); - len -= bytes_read; - total_read += bytes_read; - buffer += bytes_read; - - while(len > 0) { - if(read_data(conn, fd, &conn->in_buffer)) - return -1; - if(conn->in_buffer.size == 0) { - if(bytes_read > 0) - conn->in_buffer.eof_flag = 1; - return bytes_read; - } - bytes_read = buffer_read(&conn->in_buffer, buffer, len); - len -= bytes_read; - total_read += bytes_read; - buffer += bytes_read; - } - return total_read; -} - -/* Send |length| bytes from |from| to the |fd| socket taking care of encoding - and negotiating with the server. |from| can be NULL. */ -static void do_sec_send(struct connectdata *conn, curl_socket_t fd, - const char *from, int length) -{ - int bytes, htonl_bytes; /* 32-bit integers for htonl */ - char *buffer = NULL; - char *cmd_buffer; - size_t cmd_size = 0; - CURLcode error; - enum protection_level prot_level = conn->data_prot; - bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE; - - DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST); - - if(iscmd) { - if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5)) - prot_level = PROT_PRIVATE; - else - prot_level = conn->command_prot; - } - bytes = conn->mech->encode(conn->app_data, from, length, prot_level, - (void **)&buffer); - if(!buffer || bytes <= 0) - return; /* error */ - - if(iscmd) { - error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes), - &cmd_buffer, &cmd_size); - if(error) { - free(buffer); - return; /* error */ - } - if(cmd_size > 0) { - static const char *enc = "ENC "; - static const char *mic = "MIC "; - if(prot_level == PROT_PRIVATE) - socket_write(conn, fd, enc, 4); - else - socket_write(conn, fd, mic, 4); - - socket_write(conn, fd, cmd_buffer, cmd_size); - socket_write(conn, fd, "\r\n", 2); - infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic, - cmd_buffer); - free(cmd_buffer); - } - } - else { - htonl_bytes = htonl(bytes); - socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes)); - socket_write(conn, fd, buffer, curlx_sitouz(bytes)); - } - free(buffer); -} - -static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd, - const char *buffer, size_t length) -{ - ssize_t tx = 0, len = conn->buffer_size; - - len -= conn->mech->overhead(conn->app_data, conn->data_prot, - curlx_sztosi(len)); - if(len <= 0) - len = length; - while(length) { - if(length < (size_t)len) - len = length; - - do_sec_send(conn, fd, buffer, curlx_sztosi(len)); - length -= len; - buffer += len; - tx += len; - } - return tx; -} - -/* Matches Curl_send signature */ -static ssize_t sec_send(struct connectdata *conn, int sockindex, - const void *buffer, size_t len, CURLcode *err) -{ - curl_socket_t fd = conn->sock[sockindex]; - *err = CURLE_OK; - return sec_write(conn, fd, buffer, len); -} - -int Curl_sec_read_msg(struct connectdata *conn, char *buffer, - enum protection_level level) -{ - /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an - int */ - int decoded_len; - char *buf; - int ret_code = 0; - size_t decoded_sz = 0; - CURLcode error; - - if(!conn->mech) - /* not inititalized, return error */ - return -1; - - DEBUGASSERT(level > PROT_NONE && level < PROT_LAST); - - error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz); - if(error || decoded_sz == 0) - return -1; - - if(decoded_sz > (size_t)INT_MAX) { - free(buf); - return -1; - } - decoded_len = curlx_uztosi(decoded_sz); - - decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len, - level, conn); - if(decoded_len <= 0) { - free(buf); - return -1; - } - - if(conn->data->set.verbose) { - buf[decoded_len] = '\n'; - Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1); - } - - buf[decoded_len] = '\0'; - if(decoded_len <= 3) - /* suspiciously short */ - return 0; - - if(buf[3] != '-') - /* safe to ignore return code */ - (void)sscanf(buf, "%d", &ret_code); - - if(buf[decoded_len - 1] == '\n') - buf[decoded_len - 1] = '\0'; - strcpy(buffer, buf); - free(buf); - return ret_code; -} - -static int sec_set_protection_level(struct connectdata *conn) -{ - int code; - enum protection_level level = conn->request_data_prot; - - DEBUGASSERT(level > PROT_NONE && level < PROT_LAST); - - if(!conn->sec_complete) { - infof(conn->data, "Trying to change the protection level after the" - " completion of the data exchange.\n"); - return -1; - } - - /* Bail out if we try to set up the same level */ - if(conn->data_prot == level) - return 0; - - if(level) { - char *pbsz; - static unsigned int buffer_size = 1 << 20; /* 1048576 */ - - code = ftp_send_command(conn, "PBSZ %u", buffer_size); - if(code < 0) - return -1; - - if(code/100 != 2) { - failf(conn->data, "Failed to set the protection's buffer size."); - return -1; - } - conn->buffer_size = buffer_size; - - pbsz = strstr(conn->data->state.buffer, "PBSZ="); - if(pbsz) { - /* ignore return code, use default value if it fails */ - (void)sscanf(pbsz, "PBSZ=%u", &buffer_size); - if(buffer_size < conn->buffer_size) - conn->buffer_size = buffer_size; - } - } - - /* Now try to negiociate the protection level. */ - code = ftp_send_command(conn, "PROT %c", level_to_char(level)); - - if(code < 0) - return -1; - - if(code/100 != 2) { - failf(conn->data, "Failed to set the protection level."); - return -1; - } - - conn->data_prot = level; - if(level == PROT_PRIVATE) - conn->command_prot = level; - - return 0; -} - -int -Curl_sec_request_prot(struct connectdata *conn, const char *level) -{ - enum protection_level l = name_to_level(level); - if(l == PROT_NONE) - return -1; - DEBUGASSERT(l > PROT_NONE && l < PROT_LAST); - conn->request_data_prot = l; - return 0; -} - -static CURLcode choose_mech(struct connectdata *conn) -{ - int ret; - struct Curl_easy *data = conn->data; - void *tmp_allocation; - const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech; - - tmp_allocation = realloc(conn->app_data, mech->size); - if(tmp_allocation == NULL) { - failf(data, "Failed realloc of size %zu", mech->size); - mech = NULL; - return CURLE_OUT_OF_MEMORY; - } - conn->app_data = tmp_allocation; - - if(mech->init) { - ret = mech->init(conn->app_data); - if(ret) { - infof(data, "Failed initialization for %s. Skipping it.\n", - mech->name); - return CURLE_FAILED_INIT; - } - } - - infof(data, "Trying mechanism %s...\n", mech->name); - ret = ftp_send_command(conn, "AUTH %s", mech->name); - if(ret < 0) - return CURLE_COULDNT_CONNECT; - - if(ret/100 != 3) { - switch(ret) { - case 504: - infof(data, "Mechanism %s is not supported by the server (server " - "returned ftp code: 504).\n", mech->name); - break; - case 534: - infof(data, "Mechanism %s was rejected by the server (server returned " - "ftp code: 534).\n", mech->name); - break; - default: - if(ret/100 == 5) { - infof(data, "server does not support the security extensions\n"); - return CURLE_USE_SSL_FAILED; - } - break; - } - return CURLE_LOGIN_DENIED; - } - - /* Authenticate */ - ret = mech->auth(conn->app_data, conn); - - if(ret != AUTH_CONTINUE) { - if(ret != AUTH_OK) { - /* Mechanism has dumped the error to stderr, don't error here. */ - return -1; - } - DEBUGASSERT(ret == AUTH_OK); - - conn->mech = mech; - conn->sec_complete = 1; - conn->recv[FIRSTSOCKET] = sec_recv; - conn->send[FIRSTSOCKET] = sec_send; - conn->recv[SECONDARYSOCKET] = sec_recv; - conn->send[SECONDARYSOCKET] = sec_send; - conn->command_prot = PROT_SAFE; - /* Set the requested protection level */ - /* BLOCKING */ - (void)sec_set_protection_level(conn); - } - - return CURLE_OK; -} - -CURLcode -Curl_sec_login(struct connectdata *conn) -{ - return choose_mech(conn); -} - - -void -Curl_sec_end(struct connectdata *conn) -{ - if(conn->mech != NULL && conn->mech->end) - conn->mech->end(conn->app_data); - free(conn->app_data); - conn->app_data = NULL; - if(conn->in_buffer.data) { - free(conn->in_buffer.data); - conn->in_buffer.data = NULL; - conn->in_buffer.size = 0; - conn->in_buffer.index = 0; - conn->in_buffer.eof_flag = 0; - } - conn->sec_complete = 0; - conn->data_prot = PROT_CLEAR; - conn->mech = NULL; -} - -#endif /* HAVE_GSSAPI */ - -#endif /* CURL_DISABLE_FTP */ diff --git a/libs/libcurl/src/select.c b/libs/libcurl/src/select.c index abb124ae8f..917133b72b 100644 --- a/libs/libcurl/src/select.c +++ b/libs/libcurl/src/select.c @@ -149,15 +149,14 @@ int Curl_select(curl_socket_t maxfd, /* highest socket number */ { struct timeval pending_tv; struct timeval *ptimeout; - int r; #ifdef USE_WINSOCK /* WinSock select() can't handle zero events. See the comment below. */ if((!fds_read || fds_read->fd_count == 0) && (!fds_write || fds_write->fd_count == 0) && (!fds_err || fds_err->fd_count == 0)) { - r = Curl_wait_ms(timeout_ms); - return r; + /* no sockets, just wait */ + return Curl_wait_ms(timeout_ms); } #endif @@ -209,17 +208,16 @@ int Curl_select(curl_socket_t maxfd, /* highest socket number */ descriptor set must contain at least one handle to a socket. It is unclear why WinSock doesn't just handle this for us instead of - calling this an error. + calling this an error. Luckily, with WinSock, we can _also_ ask how + many bits are set on an fd_set. So, let's just check it beforehand. */ - r = select((int)maxfd + 1, - fds_read && fds_read->fd_count ? fds_read : NULL, - fds_write && fds_write->fd_count ? fds_write : NULL, - fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout); + return select((int)maxfd + 1, + fds_read && fds_read->fd_count ? fds_read : NULL, + fds_write && fds_write->fd_count ? fds_write : NULL, + fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout); #else - r = select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout); + return select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout); #endif - - return r; } /* @@ -247,23 +245,14 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */ curl_socket_t writefd, /* socket to write to */ timediff_t timeout_ms) /* milliseconds to wait */ { -#ifdef HAVE_POLL_FINE struct pollfd pfd[3]; int num; -#else - fd_set fds_read; - fd_set fds_write; - fd_set fds_err; - curl_socket_t maxfd; -#endif int r; - int ret; if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) { /* no sockets, just wait */ - r = Curl_wait_ms(timeout_ms); - return r; + return Curl_wait_ms(timeout_ms); } /* Avoid initial timestamp, avoid Curl_now() call, when elapsed @@ -271,8 +260,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */ when function is called with a zero timeout or a negative timeout value indicating a blocking call should be performed. */ -#ifdef HAVE_POLL_FINE - num = 0; if(readfd0 != CURL_SOCKET_BAD) { pfd[num].fd = readfd0; @@ -288,7 +275,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */ } if(writefd != CURL_SOCKET_BAD) { pfd[num].fd = writefd; - pfd[num].events = POLLWRNORM|POLLOUT; + pfd[num].events = POLLWRNORM|POLLOUT|POLLPRI; pfd[num].revents = 0; num++; } @@ -297,101 +284,30 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */ if(r <= 0) return r; - ret = 0; + r = 0; num = 0; if(readfd0 != CURL_SOCKET_BAD) { if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP)) - ret |= CURL_CSELECT_IN; + r |= CURL_CSELECT_IN; if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL)) - ret |= CURL_CSELECT_ERR; + r |= CURL_CSELECT_ERR; num++; } if(readfd1 != CURL_SOCKET_BAD) { if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP)) - ret |= CURL_CSELECT_IN2; + r |= CURL_CSELECT_IN2; if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL)) - ret |= CURL_CSELECT_ERR; + r |= CURL_CSELECT_ERR; num++; } if(writefd != CURL_SOCKET_BAD) { if(pfd[num].revents & (POLLWRNORM|POLLOUT)) - ret |= CURL_CSELECT_OUT; - if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL)) - ret |= CURL_CSELECT_ERR; - } - - return ret; - -#else /* HAVE_POLL_FINE */ - - FD_ZERO(&fds_err); - maxfd = (curl_socket_t)-1; - - FD_ZERO(&fds_read); - if(readfd0 != CURL_SOCKET_BAD) { - VERIFY_SOCK(readfd0); - FD_SET(readfd0, &fds_read); - FD_SET(readfd0, &fds_err); - maxfd = readfd0; - } - if(readfd1 != CURL_SOCKET_BAD) { - VERIFY_SOCK(readfd1); - FD_SET(readfd1, &fds_read); - FD_SET(readfd1, &fds_err); - if(readfd1 > maxfd) - maxfd = readfd1; - } - - FD_ZERO(&fds_write); - if(writefd != CURL_SOCKET_BAD) { - VERIFY_SOCK(writefd); - FD_SET(writefd, &fds_write); - FD_SET(writefd, &fds_err); - if(writefd > maxfd) - maxfd = writefd; - } - - /* We know that we have at least one bit set in at least two fd_sets in - this case, but we may have no bits set in either fds_read or fd_write, - so check for that and handle it. Luckily, with WinSock, we can _also_ - ask how many bits are set on an fd_set. - - Note also that WinSock ignores the first argument, so we don't worry - about the fact that maxfd is computed incorrectly with WinSock (since - curl_socket_t is unsigned in such cases and thus -1 is the largest - value). - */ - r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms); - - if(r < 0) - return -1; - if(r == 0) - return 0; - - ret = 0; - if(readfd0 != CURL_SOCKET_BAD) { - if(FD_ISSET(readfd0, &fds_read)) - ret |= CURL_CSELECT_IN; - if(FD_ISSET(readfd0, &fds_err)) - ret |= CURL_CSELECT_ERR; - } - if(readfd1 != CURL_SOCKET_BAD) { - if(FD_ISSET(readfd1, &fds_read)) - ret |= CURL_CSELECT_IN2; - if(FD_ISSET(readfd1, &fds_err)) - ret |= CURL_CSELECT_ERR; - } - if(writefd != CURL_SOCKET_BAD) { - if(FD_ISSET(writefd, &fds_write)) - ret |= CURL_CSELECT_OUT; - if(FD_ISSET(writefd, &fds_err)) - ret |= CURL_CSELECT_ERR; + r |= CURL_CSELECT_OUT; + if(pfd[num].revents & (POLLERR|POLLHUP|POLLPRI|POLLNVAL)) + r |= CURL_CSELECT_ERR; } - return ret; - -#endif /* HAVE_POLL_FINE */ - + return r; } /* @@ -431,8 +347,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) } if(fds_none) { /* no sockets, just wait */ - r = Curl_wait_ms(timeout_ms); - return r; + return Curl_wait_ms(timeout_ms); } /* Avoid initial timestamp, avoid Curl_now() call, when elapsed @@ -454,11 +369,8 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) else pending_ms = 0; r = poll(ufds, nfds, pending_ms); - - if(r < 0) - return -1; - if(r == 0) - return 0; + if(r <= 0) + return r; for(i = 0; i < nfds; i++) { if(ufds[i].fd == CURL_SOCKET_BAD) @@ -466,7 +378,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) if(ufds[i].revents & POLLHUP) ufds[i].revents |= POLLIN; if(ufds[i].revents & POLLERR) - ufds[i].revents |= (POLLIN|POLLOUT); + ufds[i].revents |= POLLIN|POLLOUT; } #else /* HAVE_POLL_FINE */ @@ -482,7 +394,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) continue; VERIFY_SOCK(ufds[i].fd); if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI| - POLLRDNORM|POLLWRNORM|POLLRDBAND)) { + POLLRDNORM|POLLWRNORM|POLLRDBAND)) { if(ufds[i].fd > maxfd) maxfd = ufds[i].fd; if(ufds[i].events & (POLLRDNORM|POLLIN)) @@ -494,24 +406,39 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) } } + /* + Note also that WinSock ignores the first argument, so we don't worry + about the fact that maxfd is computed incorrectly with WinSock (since + curl_socket_t is unsigned in such cases and thus -1 is the largest + value). + */ r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms); - - if(r < 0) - return -1; - if(r == 0) - return 0; + if(r <= 0) + return r; r = 0; for(i = 0; i < nfds; i++) { ufds[i].revents = 0; if(ufds[i].fd == CURL_SOCKET_BAD) continue; - if(FD_ISSET(ufds[i].fd, &fds_read)) - ufds[i].revents |= POLLIN; - if(FD_ISSET(ufds[i].fd, &fds_write)) - ufds[i].revents |= POLLOUT; - if(FD_ISSET(ufds[i].fd, &fds_err)) - ufds[i].revents |= POLLPRI; + if(FD_ISSET(ufds[i].fd, &fds_read)) { + if(ufds[i].events & POLLRDNORM) + ufds[i].revents |= POLLRDNORM; + if(ufds[i].events & POLLIN) + ufds[i].revents |= POLLIN; + } + if(FD_ISSET(ufds[i].fd, &fds_write)) { + if(ufds[i].events & POLLWRNORM) + ufds[i].revents |= POLLWRNORM; + if(ufds[i].events & POLLOUT) + ufds[i].revents |= POLLOUT; + } + if(FD_ISSET(ufds[i].fd, &fds_err)) { + if(ufds[i].events & POLLRDBAND) + ufds[i].revents |= POLLRDBAND; + if(ufds[i].events & POLLPRI) + ufds[i].revents |= POLLPRI; + } if(ufds[i].revents != 0) r++; } diff --git a/libs/libcurl/src/select.h b/libs/libcurl/src/select.h index 95181f467e..c9cc5c2e81 100644 --- a/libs/libcurl/src/select.h +++ b/libs/libcurl/src/select.h @@ -94,12 +94,23 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, fd_set* excepts, struct timeval *tv); #endif -/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which +/* TPF sockets are not in range [0..FD_SETSIZE-1], which unfortunately makes it impossible for us to easily check if they're valid + + With Winsock the valid range is [0..INVALID_SOCKET-1] according to + https://docs.microsoft.com/en-us/windows/win32/winsock/socket-data-type-2 */ -#if defined(USE_WINSOCK) || defined(TPF) +#if defined(TPF) #define VALID_SOCK(x) 1 #define VERIFY_SOCK(x) Curl_nop_stmt +#elif defined(USE_WINSOCK) +#define VALID_SOCK(s) ((s) < INVALID_SOCKET) +#define VERIFY_SOCK(x) do { \ + if(!VALID_SOCK(x)) { \ + SET_SOCKERRNO(WSAEINVAL); \ + return -1; \ + } \ +} while(0) #else #define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE)) #define VERIFY_SOCK(x) do { \ diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index 6943fa84e0..6cfc89b694 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -140,7 +140,7 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex) psnd->recv_size > psnd->recv_processed; } -static void pre_receive_plain(struct connectdata *conn, int num) +static CURLcode pre_receive_plain(struct connectdata *conn, int num) { const curl_socket_t sockfd = conn->sock[num]; struct postponed_data * const psnd = &(conn->postponed[num]); @@ -161,6 +161,8 @@ static void pre_receive_plain(struct connectdata *conn, int num) /* Use buffer double default size for intermediate buffer */ psnd->allocated_size = 2 * conn->data->set.buffer_size; psnd->buffer = malloc(psnd->allocated_size); + if(!psnd->buffer) + return CURLE_OUT_OF_MEMORY; psnd->recv_size = 0; psnd->recv_processed = 0; #ifdef DEBUGBUILD @@ -180,6 +182,7 @@ static void pre_receive_plain(struct connectdata *conn, int num) psnd->allocated_size = 0; } } + return CURLE_OK; } static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf, @@ -225,7 +228,7 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex) (void)sockindex; return false; } -#define pre_receive_plain(c,n) do {} while(0) +#define pre_receive_plain(c,n) CURLE_OK #define get_pre_recved(c,n,b,l) 0 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ @@ -283,52 +286,6 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...) } } -/* Curl_sendf() sends formatted data to the server */ -CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn, - const char *fmt, ...) -{ - struct Curl_easy *data = conn->data; - ssize_t bytes_written; - size_t write_len; - CURLcode result = CURLE_OK; - char *s; - char *sptr; - va_list ap; - va_start(ap, fmt); - s = vaprintf(fmt, ap); /* returns an allocated string */ - va_end(ap); - if(!s) - return CURLE_OUT_OF_MEMORY; /* failure */ - - bytes_written = 0; - write_len = strlen(s); - sptr = s; - - for(;;) { - /* Write the buffer to the socket */ - result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written); - - if(result) - break; - - if(data->set.verbose) - Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written); - - if((size_t)bytes_written != write_len) { - /* if not all was written at once, we must advance the pointer, decrease - the size left and try again! */ - write_len -= bytes_written; - sptr += bytes_written; - } - else - break; - } - - free(s); /* free the output string */ - - return result; -} - /* * Curl_write() is an internal write function that sends data to the * server. Works with plain sockets, SCP, SSL or kerberos. @@ -379,7 +336,10 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num, To avoid lossage of received data, recv() must be performed before every send() if any incoming data is available. */ - pre_receive_plain(conn, num); + if(pre_receive_plain(conn, num)) { + *code = CURLE_OUT_OF_MEMORY; + return -1; + } #if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */ if(conn->bits.tcp_fastopen) { diff --git a/libs/libcurl/src/sendf.h b/libs/libcurl/src/sendf.h index c68b017daa..2e270c598b 100644 --- a/libs/libcurl/src/sendf.h +++ b/libs/libcurl/src/sendf.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -24,8 +24,6 @@ #include "curl_setup.h" -CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *, - const char *fmt, ...); void Curl_infof(struct Curl_easy *, const char *fmt, ...); void Curl_failf(struct Curl_easy *, const char *fmt, ...); diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index d6213357cc..fa53982158 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -430,104 +430,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) primary->version_max = version_max; } #else - result = CURLE_UNKNOWN_OPTION; + result = CURLE_NOT_BUILT_IN; #endif break; -#ifndef CURL_DISABLE_HTTP - case CURLOPT_AUTOREFERER: - /* - * Switch on automatic referer that gets set if curl follows locations. - */ - data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_ACCEPT_ENCODING: - /* - * String to use at the value of Accept-Encoding header. - * - * If the encoding is set to "" we use an Accept-Encoding header that - * encompasses all the encodings we support. - * If the encoding is set to NULL we don't send an Accept-Encoding header - * and ignore an received Content-Encoding header. - * - */ - argptr = va_arg(param, char *); - if(argptr && !*argptr) { - argptr = Curl_all_content_encodings(); - if(!argptr) - result = CURLE_OUT_OF_MEMORY; - else { - result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); - free(argptr); - } - } - else - result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); - break; - - case CURLOPT_TRANSFER_ENCODING: - data->set.http_transfer_encoding = (0 != va_arg(param, long)) ? - TRUE : FALSE; - break; - - case CURLOPT_FOLLOWLOCATION: - /* - * Follow Location: header hints on a HTTP-server. - */ - data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_UNRESTRICTED_AUTH: - /* - * Send authentication (user+password) when following locations, even when - * hostname changed. - */ - data->set.allow_auth_to_other_hosts = - (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_MAXREDIRS: - /* - * The maximum amount of hops you allow curl to follow Location: - * headers. This should mostly be used to detect never-ending loops. - */ - arg = va_arg(param, long); - if(arg < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.maxredirs = arg; - break; - - case CURLOPT_POSTREDIR: - /* - * Set the behaviour of POST when redirecting - * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302 - * CURL_REDIR_POST_301 - POST is kept as POST after 301 - * CURL_REDIR_POST_302 - POST is kept as POST after 302 - * CURL_REDIR_POST_303 - POST is kept as POST after 303 - * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303 - * other - POST is kept as POST after 301 and 302 - */ - arg = va_arg(param, long); - if(arg < CURL_REDIR_GET_ALL) - /* no return error on too high numbers since the bitmask could be - extended in a future */ - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.keep_post = arg & CURL_REDIR_POST_ALL; - break; - - case CURLOPT_POST: - /* Does this option serve a purpose anymore? Yes it does, when - CURLOPT_POSTFIELDS isn't used and the POST data is read off the - callback! */ - if(va_arg(param, long)) { - data->set.method = HTTPREQ_POST; - data->set.opt_no_body = FALSE; /* this is implied */ - } - else - data->set.method = HTTPREQ_GET; - break; - + /* MQTT "borrows" some of the HTTP options */ +#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT) case CURLOPT_COPYPOSTFIELDS: /* * A string with POST data. Makes curl HTTP POST. Even if it is NULL. @@ -622,6 +530,100 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.postfieldsize = bigsize; break; +#endif +#ifndef CURL_DISABLE_HTTP + case CURLOPT_AUTOREFERER: + /* + * Switch on automatic referer that gets set if curl follows locations. + */ + data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_ACCEPT_ENCODING: + /* + * String to use at the value of Accept-Encoding header. + * + * If the encoding is set to "" we use an Accept-Encoding header that + * encompasses all the encodings we support. + * If the encoding is set to NULL we don't send an Accept-Encoding header + * and ignore an received Content-Encoding header. + * + */ + argptr = va_arg(param, char *); + if(argptr && !*argptr) { + argptr = Curl_all_content_encodings(); + if(!argptr) + result = CURLE_OUT_OF_MEMORY; + else { + result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); + free(argptr); + } + } + else + result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); + break; + + case CURLOPT_TRANSFER_ENCODING: + data->set.http_transfer_encoding = (0 != va_arg(param, long)) ? + TRUE : FALSE; + break; + + case CURLOPT_FOLLOWLOCATION: + /* + * Follow Location: header hints on a HTTP-server. + */ + data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_UNRESTRICTED_AUTH: + /* + * Send authentication (user+password) when following locations, even when + * hostname changed. + */ + data->set.allow_auth_to_other_hosts = + (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_MAXREDIRS: + /* + * The maximum amount of hops you allow curl to follow Location: + * headers. This should mostly be used to detect never-ending loops. + */ + arg = va_arg(param, long); + if(arg < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.maxredirs = arg; + break; + + case CURLOPT_POSTREDIR: + /* + * Set the behaviour of POST when redirecting + * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302 + * CURL_REDIR_POST_301 - POST is kept as POST after 301 + * CURL_REDIR_POST_302 - POST is kept as POST after 302 + * CURL_REDIR_POST_303 - POST is kept as POST after 303 + * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303 + * other - POST is kept as POST after 301 and 302 + */ + arg = va_arg(param, long); + if(arg < CURL_REDIR_GET_ALL) + /* no return error on too high numbers since the bitmask could be + extended in a future */ + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.keep_post = arg & CURL_REDIR_POST_ALL; + break; + + case CURLOPT_POST: + /* Does this option serve a purpose anymore? Yes it does, when + CURLOPT_POSTFIELDS isn't used and the POST data is read off the + callback! */ + if(va_arg(param, long)) { + data->set.method = HTTPREQ_POST; + data->set.opt_no_body = FALSE; /* this is implied */ + } + else + data->set.method = HTTPREQ_GET; + break; case CURLOPT_HTTPPOST: /* @@ -720,6 +722,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) argptr = (char *)va_arg(param, void *); if(argptr) { struct curl_slist *cl; + /* general protection against mistakes and abuse */ + if(strlen(argptr) > CURL_MAX_INPUT_LENGTH) + return CURLE_BAD_FUNCTION_ARGUMENT; /* append the cookie file name to the list of file names, and deal with them later */ cl = curl_slist_append(data->change.cookielist, argptr); @@ -804,6 +809,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* if cookie engine was not running, activate it */ data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); + /* general protection against mistakes and abuse */ + if(strlen(argptr) > CURL_MAX_INPUT_LENGTH) + return CURLE_BAD_FUNCTION_ARGUMENT; argptr = strdup(argptr); if(!argptr || !data->cookies) { result = CURLE_OUT_OF_MEMORY; @@ -1069,7 +1077,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; default: /* reserve other values for future use */ - result = CURLE_UNKNOWN_OPTION; + result = CURLE_BAD_FUNCTION_ARGUMENT; break; } break; @@ -1222,21 +1230,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * An FTP/SFTP option that modifies an upload to create missing * directories on the server. */ - switch(va_arg(param, long)) { - case 0: - data->set.ftp_create_missing_dirs = 0; - break; - case 1: - data->set.ftp_create_missing_dirs = 1; - break; - case 2: - data->set.ftp_create_missing_dirs = 2; - break; - default: - /* reserve other values for future use */ - result = CURLE_UNKNOWN_OPTION; - break; - } + arg = va_arg(param, long); + /* reserve other values for future use */ + if((arg < CURLFTP_CREATE_DIR_NONE) || + (arg > CURLFTP_CREATE_DIR_RETRY)) + result = CURLE_BAD_FUNCTION_ARGUMENT; + else + data->set.ftp_create_missing_dirs = (int)arg; break; case CURLOPT_READDATA: /* @@ -2075,6 +2075,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * The application kindly asks for a differently sized receive buffer. * If it seems reasonable, we'll use it. */ + if(data->state.buffer) + return CURLE_BAD_FUNCTION_ARGUMENT; + arg = va_arg(param, long); if(arg > READBUFFER_MAX) @@ -2084,18 +2087,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) else if(arg < READBUFFER_MIN) arg = READBUFFER_MIN; - /* Resize if new size */ - if((arg != data->set.buffer_size) && data->state.buffer) { - char *newbuff = realloc(data->state.buffer, arg + 1); - if(!newbuff) { - DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n")); - result = CURLE_OUT_OF_MEMORY; - } - else - data->state.buffer = newbuff; - } data->set.buffer_size = arg; - break; case CURLOPT_UPLOAD_BUFFERSIZE: @@ -2243,6 +2235,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #endif + case CURLOPT_SSL_EC_CURVES: + /* + * Set accepted curves in SSL connection setup. + * Specify colon-delimited list of curve algorithm names. + */ + result = Curl_setstropt(&data->set.str[STRING_SSL_EC_CURVES], + va_arg(param, char *)); + break; #endif case CURLOPT_IPRESOLVE: arg = va_arg(param, long); @@ -2513,9 +2513,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...) * Would this be better if the RTSPREQ_* were just moved into here? */ - long curl_rtspreq = va_arg(param, long); + long in_rtspreq = va_arg(param, long); Curl_RtspReq rtspreq = RTSPREQ_NONE; - switch(curl_rtspreq) { + switch(in_rtspreq) { case CURL_RTSPREQ_OPTIONS: rtspreq = RTSPREQ_OPTIONS; break; diff --git a/libs/libcurl/src/setup-win32.h b/libs/libcurl/src/setup-win32.h index 45b5847666..d20662aa19 100644 --- a/libs/libcurl/src/setup-win32.h +++ b/libs/libcurl/src/setup-win32.h @@ -60,7 +60,6 @@ /* * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else - * define USE_WINSOCK to 1 if we have and use WINSOCK API, else * undefine USE_WINSOCK. */ @@ -70,7 +69,7 @@ # define USE_WINSOCK 2 #else # ifdef HAVE_WINSOCK_H -# define USE_WINSOCK 1 +# error "WinSock version 1 is no longer supported, version 2 is required!" # endif #endif diff --git a/libs/libcurl/src/share.c b/libs/libcurl/src/share.c index a2d896042a..407ac34536 100644 --- a/libs/libcurl/src/share.c +++ b/libs/libcurl/src/share.c @@ -92,7 +92,7 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...) if(!share->sslsession) { share->max_ssl_sessions = 8; share->sslsession = calloc(share->max_ssl_sessions, - sizeof(struct curl_ssl_session)); + sizeof(struct Curl_ssl_session)); share->sessionage = 0; if(!share->sslsession) res = CURLSHE_NOMEM; diff --git a/libs/libcurl/src/share.h b/libs/libcurl/src/share.h index a7dea41adb..aa964b6ccd 100644 --- a/libs/libcurl/src/share.h +++ b/libs/libcurl/src/share.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -46,7 +46,7 @@ struct Curl_share { curl_unlock_function unlockfunc; void *clientdata; struct conncache conn_cache; - struct curl_hash hostcache; + struct Curl_hash hostcache; #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) struct CookieInfo *cookies; #endif @@ -54,7 +54,7 @@ struct Curl_share { struct PslCache psl; #endif - struct curl_ssl_session *sslsession; + struct Curl_ssl_session *sslsession; size_t max_ssl_sessions; long sessionage; }; diff --git a/libs/libcurl/src/smb.c b/libs/libcurl/src/smb.c index d493adcc03..41d97b84cc 100644 --- a/libs/libcurl/src/smb.c +++ b/libs/libcurl/src/smb.c @@ -23,11 +23,9 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ +#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ (CURL_SIZEOF_CURL_OFF_T > 4) -#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) - #define BUILDING_CURL_SMB_C #ifdef HAVE_PROCESS_H @@ -88,6 +86,7 @@ const struct Curl_handler Curl_handler_smb = { ZERO_NULL, /* connection_check */ PORT_SMB, /* defport */ CURLPROTO_SMB, /* protocol */ + CURLPROTO_SMB, /* family */ PROTOPT_NONE /* flags */ }; @@ -113,6 +112,7 @@ const struct Curl_handler Curl_handler_smbs = { ZERO_NULL, /* connection_check */ PORT_SMBS, /* defport */ CURLPROTO_SMBS, /* protocol */ + CURLPROTO_SMB, /* family */ PROTOPT_SSL /* flags */ }; #endif @@ -996,6 +996,5 @@ static CURLcode smb_parse_url_path(struct connectdata *conn) return CURLE_OK; } -#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ - -#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */ +#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && + CURL_SIZEOF_CURL_OFF_T > 4 */ diff --git a/libs/libcurl/src/smb.h b/libs/libcurl/src/smb.h index 136a89ce9e..ff0a354b7b 100644 --- a/libs/libcurl/src/smb.h +++ b/libs/libcurl/src/smb.h @@ -243,16 +243,13 @@ struct smb_tree_disconnect { #endif /* BUILDING_CURL_SMB_C */ -#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ +#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ (CURL_SIZEOF_CURL_OFF_T > 4) -#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) - extern const struct Curl_handler Curl_handler_smb; extern const struct Curl_handler Curl_handler_smbs; -#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ - -#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */ +#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && + CURL_SIZEOF_CURL_OFF_T > 4 */ #endif /* HEADER_CURL_SMB_H */ diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c index aea41bb4e3..49743c0369 100644 --- a/libs/libcurl/src/smtp.c +++ b/libs/libcurl/src/smtp.c @@ -133,6 +133,7 @@ const struct Curl_handler Curl_handler_smtp = { ZERO_NULL, /* connection_check */ PORT_SMTP, /* defport */ CURLPROTO_SMTP, /* protocol */ + CURLPROTO_SMTP, /* family */ PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ PROTOPT_URLOPTIONS }; @@ -160,6 +161,7 @@ const struct Curl_handler Curl_handler_smtps = { ZERO_NULL, /* connection_check */ PORT_SMTPS, /* defport */ CURLPROTO_SMTPS, /* protocol */ + CURLPROTO_SMTP, /* family */ PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */ }; @@ -1322,6 +1324,7 @@ static CURLcode smtp_connect(struct connectdata *conn, bool *done) Curl_sasl_init(&smtpc->sasl, &saslsmtp); /* Initialise the pingpong layer */ + Curl_pp_setup(pp); Curl_pp_init(pp); /* Parse the URL options */ diff --git a/libs/libcurl/src/socketpair.c b/libs/libcurl/src/socketpair.c index 1ec0d75a46..9e1f9ef4c1 100644 --- a/libs/libcurl/src/socketpair.c +++ b/libs/libcurl/src/socketpair.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -23,7 +23,7 @@ #include "curl_setup.h" #include "socketpair.h" -#ifndef HAVE_SOCKETPAIR +#if !defined(HAVE_SOCKETPAIR) && !defined(CURL_DISABLE_SOCKETPAIR) #ifdef WIN32 /* * This is a socketpair() implementation for Windows. diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c index 44783d015c..a41b67d5a9 100644 --- a/libs/libcurl/src/socks.c +++ b/libs/libcurl/src/socks.c @@ -184,12 +184,12 @@ int Curl_SOCKS_getsock(struct connectdata *conn, curl_socket_t *sock, * Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" * Nonsupport "Identification Protocol (RFC1413)" */ -CURLcode Curl_SOCKS4(const char *proxy_user, - const char *hostname, - int remote_port, - int sockindex, - struct connectdata *conn, - bool *done) +CURLproxycode Curl_SOCKS4(const char *proxy_user, + const char *hostname, + int remote_port, + int sockindex, + struct connectdata *conn, + bool *done) { const bool protocol4a = (conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE; @@ -237,11 +237,11 @@ CURLcode Curl_SOCKS4(const char *proxy_user, Curl_resolv(conn, hostname, remote_port, FALSE, &dns); if(rc == CURLRESOLV_ERROR) - return CURLE_COULDNT_RESOLVE_PROXY; + return CURLPX_RESOLVE_HOST; else if(rc == CURLRESOLV_PENDING) { sxstate(conn, CONNECT_RESOLVING); infof(data, "SOCKS4 non-blocking resolve of %s\n", hostname); - return CURLE_OK; + return CURLPX_OK; } sxstate(conn, CONNECT_RESOLVED); goto CONNECT_RESOLVED; @@ -265,8 +265,11 @@ CURLcode Curl_SOCKS4(const char *proxy_user, } else { result = Curl_resolv_check(data->conn, &dns); - if(!dns) - return result; + if(!dns) { + if(result) + return CURLPX_RESOLVE_HOST; + return CURLPX_OK; + } } /* FALLTHROUGH */ CONNECT_RESOLVED: @@ -303,7 +306,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user, if(!hp) { failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.", hostname); - return CURLE_COULDNT_RESOLVE_HOST; + return CURLPX_RESOLVE_HOST; } } /* FALLTHROUGH */ @@ -316,8 +319,8 @@ CURLcode Curl_SOCKS4(const char *proxy_user, if(proxy_user) { size_t plen = strlen(proxy_user); if(plen >= sizeof(sx->socksreq) - 8) { - failf(data, "Too long SOCKS proxy name, can't use!\n"); - return CURLE_COULDNT_CONNECT; + failf(data, "Too long SOCKS proxy user name, can't use!\n"); + return CURLPX_LONG_USER; } /* copy the proxy name WITH trailing zero */ memcpy(socksreq + 8, proxy_user, plen + 1); @@ -343,7 +346,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user, strcpy((char *)socksreq + packetsize, hostname); else { failf(data, "SOCKS4: too long host name"); - return CURLE_COULDNT_CONNECT; + return CURLPX_LONG_HOSTNAME; } packetsize += hostnamelen; } @@ -358,13 +361,13 @@ CURLcode Curl_SOCKS4(const char *proxy_user, sx->outstanding, &written); if(result && (CURLE_AGAIN != result)) { failf(data, "Failed to send SOCKS4 connect request."); - return CURLE_COULDNT_CONNECT; + return CURLPX_SEND_CONNECT; } if(written != sx->outstanding) { /* not done, remain in state */ sx->outstanding -= written; sx->outp += written; - return CURLE_OK; + return CURLPX_OK; } /* done sending! */ @@ -380,18 +383,18 @@ CURLcode Curl_SOCKS4(const char *proxy_user, if(result && (CURLE_AGAIN != result)) { failf(data, "SOCKS4: Failed receiving connect request ack: %s", curl_easy_strerror(result)); - return CURLE_COULDNT_CONNECT; + return CURLPX_RECV_CONNECT; } else if(!result && !actualread) { /* connection closed */ failf(data, "connection to proxy closed"); - return CURLE_COULDNT_CONNECT; + return CURLPX_CLOSED; } else if(actualread != sx->outstanding) { /* remain in reading state */ sx->outstanding -= actualread; sx->outp += actualread; - return CURLE_OK; + return CURLPX_OK; } sxstate(conn, CONNECT_DONE); break; @@ -422,7 +425,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user, if(socksreq[0] != 0) { failf(data, "SOCKS4 reply has wrong version, version should be 0."); - return CURLE_COULDNT_CONNECT; + return CURLPX_BAD_VERSION; } /* Result */ @@ -438,7 +441,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user, (unsigned char)socksreq[6], (unsigned char)socksreq[7], (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), (unsigned char)socksreq[1]); - return CURLE_COULDNT_CONNECT; + return CURLPX_REQUEST_FAILED; case 92: failf(data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" @@ -448,7 +451,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user, (unsigned char)socksreq[6], (unsigned char)socksreq[7], (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), (unsigned char)socksreq[1]); - return CURLE_COULDNT_CONNECT; + return CURLPX_IDENTD; case 93: failf(data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" @@ -458,7 +461,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user, (unsigned char)socksreq[6], (unsigned char)socksreq[7], (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), (unsigned char)socksreq[1]); - return CURLE_COULDNT_CONNECT; + return CURLPX_IDENTD_DIFFER; default: failf(data, "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" @@ -467,24 +470,24 @@ CURLcode Curl_SOCKS4(const char *proxy_user, (unsigned char)socksreq[6], (unsigned char)socksreq[7], (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), (unsigned char)socksreq[1]); - return CURLE_COULDNT_CONNECT; + return CURLPX_UNKNOWN_FAIL; } *done = TRUE; - return CURLE_OK; /* Proxy was successful! */ + return CURLPX_OK; /* Proxy was successful! */ } /* * This function logs in to a SOCKS5 proxy and sends the specifics to the final * destination server. */ -CURLcode Curl_SOCKS5(const char *proxy_user, - const char *proxy_password, - const char *hostname, - int remote_port, - int sockindex, - struct connectdata *conn, - bool *done) +CURLproxycode Curl_SOCKS5(const char *proxy_user, + const char *proxy_password, + const char *hostname, + int remote_port, + int sockindex, + struct connectdata *conn, + bool *done) { /* According to the RFC1928, section "6. Replies". This is what a SOCK5 @@ -561,13 +564,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user, result = Curl_write_plain(conn, sockfd, (char *)socksreq, idx, &written); if(result && (CURLE_AGAIN != result)) { failf(data, "Unable to send initial SOCKS5 request."); - return CURLE_COULDNT_CONNECT; + return CURLPX_SEND_CONNECT; } if(written != idx) { sxstate(conn, CONNECT_SOCKS_SEND); sx->outstanding = idx - written; sx->outp = &socksreq[written]; - return CURLE_OK; + return CURLPX_OK; } sxstate(conn, CONNECT_SOCKS_READ); goto CONNECT_SOCKS_READ_INIT; @@ -576,13 +579,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user, sx->outstanding, &written); if(result && (CURLE_AGAIN != result)) { failf(data, "Unable to send initial SOCKS5 request."); - return CURLE_COULDNT_CONNECT; + return CURLPX_SEND_CONNECT; } if(written != sx->outstanding) { /* not done, remain in state */ sx->outstanding -= written; sx->outp += written; - return CURLE_OK; + return CURLPX_OK; } /* FALLTHROUGH */ CONNECT_SOCKS_READ_INIT: @@ -595,22 +598,22 @@ CURLcode Curl_SOCKS5(const char *proxy_user, sx->outstanding, &actualread); if(result && (CURLE_AGAIN != result)) { failf(data, "Unable to receive initial SOCKS5 response."); - return CURLE_COULDNT_CONNECT; + return CURLPX_RECV_CONNECT; } else if(!result && !actualread) { /* connection closed */ failf(data, "Connection to proxy closed"); - return CURLE_COULDNT_CONNECT; + return CURLPX_CLOSED; } else if(actualread != sx->outstanding) { /* remain in reading state */ sx->outstanding -= actualread; sx->outp += actualread; - return CURLE_OK; + return CURLPX_OK; } else if(socksreq[0] != 5) { failf(data, "Received invalid version in initial SOCKS5 response."); - return CURLE_COULDNT_CONNECT; + return CURLPX_BAD_VERSION; } else if(socksreq[1] == 0) { /* DONE! No authentication needed. Send request. */ @@ -628,7 +631,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user, result = Curl_SOCKS5_gssapi_negotiate(sockindex, conn); if(result) { failf(data, "Unable to negotiate SOCKS5 GSS-API context."); - return CURLE_COULDNT_CONNECT; + return CURLPX_GSSAPI; } } #endif @@ -637,16 +640,16 @@ CURLcode Curl_SOCKS5(const char *proxy_user, if(!allow_gssapi && (socksreq[1] == 1)) { failf(data, "SOCKS5 GSSAPI per-message authentication is not supported."); - return CURLE_COULDNT_CONNECT; + return CURLPX_GSSAPI_PERMSG; } else if(socksreq[1] == 255) { failf(data, "No authentication method was acceptable."); - return CURLE_COULDNT_CONNECT; + return CURLPX_NO_AUTH; } } failf(data, "Undocumented SOCKS5 mode attempted to be used by server."); - return CURLE_COULDNT_CONNECT; + return CURLPX_UNKNOWN_MODE; #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) case CONNECT_GSSAPI_INIT: /* GSSAPI stuff done non-blocking */ @@ -683,7 +686,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user, /* the length must fit in a single byte */ if(proxy_user_len >= 255) { failf(data, "Excessive user name length for proxy auth"); - return CURLE_BAD_FUNCTION_ARGUMENT; + return CURLPX_LONG_USER; } memcpy(socksreq + len, proxy_user, proxy_user_len); } @@ -693,7 +696,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user, /* the length must fit in a single byte */ if(proxy_password_len > 255) { failf(data, "Excessive password length for proxy auth"); - return CURLE_BAD_FUNCTION_ARGUMENT; + return CURLPX_LONG_PASSWD; } memcpy(socksreq + len, proxy_password, proxy_password_len); } @@ -708,13 +711,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user, sx->outstanding, &written); if(result && (CURLE_AGAIN != result)) { failf(data, "Failed to send SOCKS5 sub-negotiation request."); - return CURLE_COULDNT_CONNECT; + return CURLPX_SEND_AUTH; } if(sx->outstanding != written) { /* remain in state */ sx->outstanding -= written; sx->outp += written; - return CURLE_OK; + return CURLPX_OK; } sx->outp = socksreq; sx->outstanding = 2; @@ -725,24 +728,24 @@ CURLcode Curl_SOCKS5(const char *proxy_user, sx->outstanding, &actualread); if(result && (CURLE_AGAIN != result)) { failf(data, "Unable to receive SOCKS5 sub-negotiation response."); - return CURLE_COULDNT_CONNECT; + return CURLPX_RECV_AUTH; } else if(!result && !actualread) { /* connection closed */ failf(data, "connection to proxy closed"); - return CURLE_COULDNT_CONNECT; + return CURLPX_CLOSED; } else if(actualread != sx->outstanding) { /* remain in state */ sx->outstanding -= actualread; sx->outp += actualread; - return CURLE_OK; + return CURLPX_OK; } /* ignore the first (VER) byte */ else if(socksreq[1] != 0) { /* status */ failf(data, "User was rejected by the SOCKS5 server (%d %d).", socksreq[0], socksreq[1]); - return CURLE_COULDNT_CONNECT; + return CURLPX_USER_REJECTED; } /* Everything is good so far, user was authenticated! */ @@ -755,11 +758,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user, FALSE, &dns); if(rc == CURLRESOLV_ERROR) - return CURLE_COULDNT_RESOLVE_HOST; + return CURLPX_RESOLVE_HOST; if(rc == CURLRESOLV_PENDING) { sxstate(conn, CONNECT_RESOLVING); - return CURLE_OK; + return CURLPX_OK; } sxstate(conn, CONNECT_RESOLVED); goto CONNECT_RESOLVED; @@ -780,8 +783,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user, if(!dns) { result = Curl_resolv_check(data->conn, &dns); - if(!dns) - return result; + if(!dns) { + if(result) + return CURLPX_RESOLVE_HOST; + return CURLPX_OK; + } } /* FALLTHROUGH */ CONNECT_RESOLVED: @@ -793,7 +799,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user, if(!hp) { failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.", hostname); - return CURLE_COULDNT_RESOLVE_HOST; + return CURLPX_RESOLVE_HOST; } Curl_printable_address(hp, dest, sizeof(dest)); @@ -867,7 +873,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user, #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) if(conn->socks5_gssapi_enctype) { failf(data, "SOCKS5 GSS-API protection not yet implemented."); - return CURLE_COULDNT_CONNECT; + return CURLPX_GSSAPI_PROTECTION; } #endif sx->outp = socksreq; @@ -879,18 +885,18 @@ CURLcode Curl_SOCKS5(const char *proxy_user, sx->outstanding, &written); if(result && (CURLE_AGAIN != result)) { failf(data, "Failed to send SOCKS5 connect request."); - return CURLE_COULDNT_CONNECT; + return CURLPX_SEND_REQUEST; } if(sx->outstanding != written) { /* remain in state */ sx->outstanding -= written; sx->outp += written; - return CURLE_OK; + return CURLPX_OK; } #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) if(conn->socks5_gssapi_enctype) { failf(data, "SOCKS5 GSS-API protection not yet implemented."); - return CURLE_COULDNT_CONNECT; + return CURLPX_GSSAPI_PROTECTION; } #endif sx->outstanding = 10; /* minimum packet size is 10 */ @@ -902,29 +908,46 @@ CURLcode Curl_SOCKS5(const char *proxy_user, sx->outstanding, &actualread); if(result && (CURLE_AGAIN != result)) { failf(data, "Failed to receive SOCKS5 connect request ack."); - return CURLE_COULDNT_CONNECT; + return CURLPX_RECV_REQACK; } else if(!result && !actualread) { /* connection closed */ failf(data, "connection to proxy closed"); - return CURLE_COULDNT_CONNECT; + return CURLPX_CLOSED; } else if(actualread != sx->outstanding) { /* remain in state */ sx->outstanding -= actualread; sx->outp += actualread; - return CURLE_OK; + return CURLPX_OK; } if(socksreq[0] != 5) { /* version */ failf(data, "SOCKS5 reply has wrong version, version should be 5."); - return CURLE_COULDNT_CONNECT; + return CURLPX_BAD_VERSION; } else if(socksreq[1] != 0) { /* Anything besides 0 is an error */ + CURLproxycode rc = CURLPX_REPLY_UNASSIGNED; + int code = socksreq[1]; failf(data, "Can't complete SOCKS5 connection to %s. (%d)", hostname, (unsigned char)socksreq[1]); - return CURLE_COULDNT_CONNECT; + if(code < 9) { + /* RFC 1928 section 6 lists: */ + static const CURLproxycode lookup[] = { + CURLPX_OK, + CURLPX_REPLY_GENERAL_SERVER_FAILURE, + CURLPX_REPLY_NOT_ALLOWED, + CURLPX_REPLY_NETWORK_UNREACHABLE, + CURLPX_REPLY_HOST_UNREACHABLE, + CURLPX_REPLY_CONNECTION_REFUSED, + CURLPX_REPLY_TTL_EXPIRED, + CURLPX_REPLY_COMMAND_NOT_SUPPORTED, + CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED, + }; + rc = lookup[code]; + } + return rc; } /* Fix: in general, returned BND.ADDR is variable length parameter by RFC @@ -958,7 +981,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user, } else { failf(data, "SOCKS5 reply has wrong address type."); - return CURLE_COULDNT_CONNECT; + return CURLPX_BAD_ADDRESS_TYPE; } /* At this point we already read first 10 bytes */ @@ -984,25 +1007,25 @@ CURLcode Curl_SOCKS5(const char *proxy_user, sx->outstanding, &actualread); if(result && (CURLE_AGAIN != result)) { failf(data, "Failed to receive SOCKS5 connect request ack."); - return CURLE_COULDNT_CONNECT; + return CURLPX_RECV_ADDRESS; } else if(!result && !actualread) { /* connection closed */ failf(data, "connection to proxy closed"); - return CURLE_COULDNT_CONNECT; + return CURLPX_CLOSED; } else if(actualread != sx->outstanding) { /* remain in state */ sx->outstanding -= actualread; sx->outp += actualread; - return CURLE_OK; + return CURLPX_OK; } sxstate(conn, CONNECT_DONE); } infof(data, "SOCKS5 request granted.\n"); *done = TRUE; - return CURLE_OK; /* Proxy was successful! */ + return CURLPX_OK; /* Proxy was successful! */ } #endif /* CURL_DISABLE_PROXY */ diff --git a/libs/libcurl/src/socks.h b/libs/libcurl/src/socks.h index 64a7563373..17e6f46101 100644 --- a/libs/libcurl/src/socks.h +++ b/libs/libcurl/src/socks.h @@ -48,24 +48,24 @@ int Curl_SOCKS_getsock(struct connectdata *conn, * This function logs in to a SOCKS4(a) proxy and sends the specifics to the * final destination server. */ -CURLcode Curl_SOCKS4(const char *proxy_name, - const char *hostname, - int remote_port, - int sockindex, - struct connectdata *conn, - bool *done); +CURLproxycode Curl_SOCKS4(const char *proxy_name, + const char *hostname, + int remote_port, + int sockindex, + struct connectdata *conn, + bool *done); /* * This function logs in to a SOCKS5 proxy and sends the specifics to the * final destination server. */ -CURLcode Curl_SOCKS5(const char *proxy_name, - const char *proxy_password, - const char *hostname, - int remote_port, - int sockindex, - struct connectdata *conn, - bool *done); +CURLproxycode Curl_SOCKS5(const char *proxy_name, + const char *proxy_password, + const char *hostname, + int remote_port, + int sockindex, + struct connectdata *conn, + bool *done); #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) /* diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c index 015e588cf7..b5808df2d1 100644 --- a/libs/libcurl/src/strerror.c +++ b/libs/libcurl/src/strerror.c @@ -320,6 +320,9 @@ curl_easy_strerror(CURLcode error) case CURLE_QUIC_CONNECT_ERROR: return "QUIC connection error"; + case CURLE_PROXY: + return "proxy handshake error"; + /* error codes not used by current libcurl */ case CURLE_OBSOLETE20: case CURLE_OBSOLETE24: @@ -652,34 +655,27 @@ static const char * get_winapi_error(int err, char *buf, size_t buflen) { char *p; + wchar_t wbuf[256]; if(!buflen) return NULL; *buf = '\0'; - -#ifdef _WIN32_WCE - { - wchar_t wbuf[256]; - wbuf[0] = L'\0'; - - if(FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, - LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { - size_t written = wcstombs(buf, wbuf, buflen - 1); - if(written != (size_t)-1) - buf[written] = '\0'; - else - *buf = '\0'; - } - } -#else - if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, - LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) { - *buf = '\0'; + *wbuf = L'\0'; + + /* We return the local codepage version of the error string because if it is + output to the user's terminal it will likely be with functions which + expect the local codepage (eg fprintf, failf, infof). + FormatMessageW -> wcstombs is used for Windows CE compatibility. */ + if(FormatMessageW((FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, + LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { + size_t written = wcstombs(buf, wbuf, buflen - 1); + if(written != (size_t)-1) + buf[written] = '\0'; + else + *buf = '\0'; } -#endif /* Truncate multiple lines */ p = strchr(buf, '\n'); diff --git a/libs/libcurl/src/system_win32.c b/libs/libcurl/src/system_win32.c index 2e59e032e2..9b0797bf9f 100644 --- a/libs/libcurl/src/system_win32.c +++ b/libs/libcurl/src/system_win32.c @@ -55,12 +55,7 @@ CURLcode Curl_win32_init(long flags) WSADATA wsaData; int res; -#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2) -#error IPV6_requires_winsock2 -#endif - - wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); - + wVersionRequested = MAKEWORD(2, 2); res = WSAStartup(wVersionRequested, &wsaData); if(res != 0) @@ -83,9 +78,9 @@ CURLcode Curl_win32_init(long flags) return CURLE_FAILED_INIT; } /* The Windows Sockets DLL is acceptable. Proceed. */ - #elif defined(USE_LWIPSOCK) +#elif defined(USE_LWIPSOCK) lwip_init(); - #endif +#endif } /* CURL_GLOBAL_WIN32 */ #ifdef USE_WINDOWS_SSPI diff --git a/libs/libcurl/src/telnet.c b/libs/libcurl/src/telnet.c index c3b58e54c5..754febe27b 100644 --- a/libs/libcurl/src/telnet.c +++ b/libs/libcurl/src/telnet.c @@ -87,12 +87,6 @@ #define printoption(a,b,c,d) Curl_nop_stmt #endif -#ifdef USE_WINSOCK -typedef WSAEVENT (WINAPI *WSOCK2_EVENT)(void); -typedef FARPROC WSOCK2_FUNC; -static CURLcode check_wsock2(struct Curl_easy *data); -#endif - static CURLcode telrcv(struct connectdata *, const unsigned char *inbuf, /* Data received from socket */ @@ -194,50 +188,11 @@ const struct Curl_handler Curl_handler_telnet = { ZERO_NULL, /* connection_check */ PORT_TELNET, /* defport */ CURLPROTO_TELNET, /* protocol */ + CURLPROTO_TELNET, /* family */ PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ }; -#ifdef USE_WINSOCK -static CURLcode -check_wsock2(struct Curl_easy *data) -{ - int err; - WORD wVersionRequested; - WSADATA wsaData; - - DEBUGASSERT(data); - - /* telnet requires at least WinSock 2.0 so ask for it. */ - wVersionRequested = MAKEWORD(2, 0); - - err = WSAStartup(wVersionRequested, &wsaData); - - /* We must've called this once already, so this call */ - /* should always succeed. But, just in case... */ - if(err != 0) { - failf(data,"WSAStartup failed (%d)",err); - return CURLE_FAILED_INIT; - } - - /* We have to have a WSACleanup call for every successful */ - /* WSAStartup call. */ - WSACleanup(); - - /* Check that our version is supported */ - if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || - HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) { - /* Our version isn't supported */ - failf(data, "insufficient winsock version to support " - "telnet"); - return CURLE_FAILED_INIT; - } - - /* Our version is supported */ - return CURLE_OK; -} -#endif - static CURLcode init_telnet(struct connectdata *conn) { @@ -1301,11 +1256,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) struct Curl_easy *data = conn->data; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; #ifdef USE_WINSOCK - HMODULE wsock2; - WSOCK2_FUNC close_event_func; - WSOCK2_EVENT create_event_func; - WSOCK2_FUNC event_select_func; - WSOCK2_FUNC enum_netevents_func; WSAEVENT event_handle; WSANETWORKEVENTS events; HANDLE stdin_handle; @@ -1340,75 +1290,21 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) return result; #ifdef USE_WINSOCK - /* - ** This functionality only works with WinSock >= 2.0. So, - ** make sure we have it. - */ - result = check_wsock2(data); - if(result) - return result; - - /* OK, so we have WinSock 2.0. We need to dynamically */ - /* load ws2_32.dll and get the function pointers we need. */ - wsock2 = Curl_load_library(TEXT("WS2_32.DLL")); - if(wsock2 == NULL) { - failf(data, "failed to load WS2_32.DLL (%u)", GetLastError()); - return CURLE_FAILED_INIT; - } - - /* Grab a pointer to WSACreateEvent */ - create_event_func = - CURLX_FUNCTION_CAST(WSOCK2_EVENT, - (GetProcAddress(wsock2, "WSACreateEvent"))); - if(create_event_func == NULL) { - failf(data, "failed to find WSACreateEvent function (%u)", GetLastError()); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* And WSACloseEvent */ - close_event_func = GetProcAddress(wsock2, "WSACloseEvent"); - if(close_event_func == NULL) { - failf(data, "failed to find WSACloseEvent function (%u)", GetLastError()); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* And WSAEventSelect */ - event_select_func = GetProcAddress(wsock2, "WSAEventSelect"); - if(event_select_func == NULL) { - failf(data, "failed to find WSAEventSelect function (%u)", GetLastError()); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* And WSAEnumNetworkEvents */ - enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents"); - if(enum_netevents_func == NULL) { - failf(data, "failed to find WSAEnumNetworkEvents function (%u)", - GetLastError()); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - /* We want to wait for both stdin and the socket. Since ** the select() function in winsock only works on sockets ** we have to use the WaitForMultipleObjects() call. */ /* First, create a sockets event object */ - event_handle = (WSAEVENT)create_event_func(); + event_handle = WSACreateEvent(); if(event_handle == WSA_INVALID_EVENT) { failf(data, "WSACreateEvent failed (%d)", SOCKERRNO); - FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* Tell winsock what events we want to listen to */ - if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == - SOCKET_ERROR) { - close_event_func(event_handle); - FreeLibrary(wsock2); + if(WSAEventSelect(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { + WSACloseEvent(event_handle); return CURLE_OK; } @@ -1439,6 +1335,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) DWORD waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout); switch(waitret) { + case WAIT_TIMEOUT: { for(;;) { @@ -1508,9 +1405,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) break; case WAIT_OBJECT_0: - + { events.lNetworkEvents = 0; - if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) { + if(WSAEnumNetworkEvents(sockfd, event_handle, &events) == SOCKET_ERROR) { err = SOCKERRNO; if(err != EINPROGRESS) { infof(data, "WSAEnumNetworkEvents failed (%d)", err); @@ -1554,7 +1451,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) if(events.lNetworkEvents & FD_CLOSE) { keepon = FALSE; } - break; + } + break; } @@ -1569,19 +1467,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) } /* We called WSACreateEvent, so call WSACloseEvent */ - if(!close_event_func(event_handle)) { + if(!WSACloseEvent(event_handle)) { infof(data, "WSACloseEvent failed (%d)", SOCKERRNO); } - - /* "Forget" pointers into the library we're about to free */ - create_event_func = NULL; - close_event_func = NULL; - event_select_func = NULL; - enum_netevents_func = NULL; - - /* We called LoadLibrary, so call FreeLibrary */ - if(!FreeLibrary(wsock2)) - infof(data, "FreeLibrary(wsock2) failed (%u)", GetLastError()); #else pfd[0].fd = sockfd; pfd[0].events = POLLIN; diff --git a/libs/libcurl/src/tftp.c b/libs/libcurl/src/tftp.c index 378d956081..1d3b8e8255 100644 --- a/libs/libcurl/src/tftp.c +++ b/libs/libcurl/src/tftp.c @@ -183,6 +183,7 @@ const struct Curl_handler Curl_handler_tftp = { ZERO_NULL, /* connection_check */ PORT_TFTP, /* defport */ CURLPROTO_TFTP, /* protocol */ + CURLPROTO_TFTP, /* family */ PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ }; diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index 150667aa97..8af33c0403 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -130,7 +130,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "memdebug.h" static void conn_free(struct connectdata *conn); -static unsigned int get_protocol_family(unsigned int protocol); /* Some parts of the code (e.g. chunked encoding) assume this buffer has at * more than just a few bytes to play with. Don't let it become too small or @@ -140,6 +139,24 @@ static unsigned int get_protocol_family(unsigned int protocol); # error READBUFFER_SIZE is too small #endif +/* +* get_protocol_family() +* +* This is used to return the protocol family for a given protocol. +* +* Parameters: +* +* 'h' [in] - struct Curl_handler pointer. +* +* Returns the family as a single bit protocol identifier. +*/ +static unsigned int get_protocol_family(const struct Curl_handler *h) +{ + DEBUGASSERT(h); + DEBUGASSERT(h->family); + return h->family; +} + /* * Protocol table. Schemes (roughly) in 2019 popularity order: @@ -215,9 +232,8 @@ static const struct Curl_handler * const protocols[] = { #endif #endif -#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) && \ - (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)) +#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ + (CURL_SIZEOF_CURL_OFF_T > 4) &Curl_handler_smb, #ifdef USE_SSL &Curl_handler_smbs, @@ -228,7 +244,7 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_rtsp, #endif -#ifdef CURL_ENABLE_MQTT +#ifndef CURL_DISABLE_MQTT &Curl_handler_mqtt, #endif @@ -274,6 +290,7 @@ static const struct Curl_handler Curl_handler_dummy = { ZERO_NULL, /* connection_check */ 0, /* defport */ 0, /* protocol */ + 0, /* family */ PROTOPT_NONE /* flags */ }; @@ -392,11 +409,8 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_dyn_free(&data->state.headerb); Curl_safefree(data->state.ulbuf); Curl_flush_cookies(data, TRUE); -#ifdef USE_ALTSVC Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]); - Curl_altsvc_cleanup(data->asi); - data->asi = NULL; -#endif + Curl_altsvc_cleanup(&data->asi); #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) Curl_http_auth_cleanup_digest(data); #endif @@ -1019,7 +1033,7 @@ static void prune_dead_connections(struct Curl_easy *data) Curl_conncache_remove_conn(data, prune.extracted, TRUE); /* disconnect it */ - (void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE); + (void)Curl_disconnect(data, prune.extracted, TRUE); } CONNCACHE_LOCK(data); data->state.conn_cache->last_cleanup = now; @@ -1075,7 +1089,7 @@ ConnectionExists(struct Curl_easy *data, &hostbundle); if(bundle) { /* Max pipe length is zero (unlimited) for multiplexed connections */ - struct curl_llist_element *curr; + struct Curl_llist_element *curr; infof(data, "Found bundle for host %s: %p [%s]\n", hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ? @@ -1121,6 +1135,12 @@ ConnectionExists(struct Curl_easy *data, /* connect-only or to-be-closed connections will not be reused */ continue; + if(extract_if_dead(check, data)) { + /* disconnect it */ + (void)Curl_disconnect(data, check, TRUE); + continue; + } + if(bundle->multiuse == BUNDLE_MULTIPLEX) multiplexed = CONN_INUSE(check); @@ -1171,7 +1191,7 @@ ConnectionExists(struct Curl_easy *data, if((needle->handler->flags&PROTOPT_SSL) != (check->handler->flags&PROTOPT_SSL)) /* don't do mixed SSL and non-SSL connections */ - if(get_protocol_family(check->handler->protocol) != + if(get_protocol_family(check->handler) != needle->handler->protocol || !check->bits.tls_upgraded) /* except protocols that have been upgraded via TLS */ continue; @@ -1276,7 +1296,7 @@ ConnectionExists(struct Curl_easy *data, is allowed to be upgraded via TLS */ if((strcasecompare(needle->handler->scheme, check->handler->scheme) || - (get_protocol_family(check->handler->protocol) == + (get_protocol_family(check->handler) == needle->handler->protocol && check->bits.tls_upgraded)) && (!needle->bits.conn_to_host || strcasecompare( needle->conn_to_host.name, check->conn_to_host.name)) && @@ -2377,8 +2397,10 @@ static CURLcode parse_proxy(struct Curl_easy *data, static CURLcode parse_proxy_auth(struct Curl_easy *data, struct connectdata *conn) { - char *proxyuser = data->set.str[STRING_PROXYUSERNAME]; - char *proxypasswd = data->set.str[STRING_PROXYPASSWORD]; + const char *proxyuser = data->set.str[STRING_PROXYUSERNAME] ? + data->set.str[STRING_PROXYUSERNAME] : ""; + const char *proxypasswd = data->set.str[STRING_PROXYPASSWORD] ? + data->set.str[STRING_PROXYPASSWORD] : ""; CURLcode result = CURLE_OK; if(proxyuser) @@ -2551,6 +2573,9 @@ static CURLcode create_conn_helper_init_proxy(struct connectdata *conn) conn->bits.socksproxy = FALSE; conn->bits.proxy_user_passwd = FALSE; conn->bits.tunnel_proxy = FALSE; + /* CURLPROXY_HTTPS does not have its own flag in conn->bits, yet we need + to signal that CURLPROXY_HTTPS is not used for this connection */ + conn->http_proxy.proxytype = CURLPROXY_HTTP; } out: @@ -3611,6 +3636,7 @@ static CURLcode create_conn(struct Curl_easy *data, data->set.ssl.primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_ORIG]; + data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES]; #ifndef CURL_DISABLE_PROXY data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; @@ -3627,18 +3653,15 @@ static CURLcode create_conn(struct Curl_easy *data, data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; - data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY]; data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY]; - data->set.proxy_ssl.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY]; #endif data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG]; data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG]; - data->set.ssl.cert = data->set.str[STRING_CERT_ORIG]; data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG]; data->set.ssl.key = data->set.str[STRING_KEY_ORIG]; data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG]; @@ -3653,7 +3676,6 @@ static CURLcode create_conn(struct Curl_easy *data, #endif #endif - data->set.ssl.cert_blob = data->set.blobs[BLOB_CERT_ORIG]; data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG]; data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG]; @@ -3752,8 +3774,7 @@ static CURLcode create_conn(struct Curl_easy *data, CONNCACHE_UNLOCK(data); if(conn_candidate) - (void)Curl_disconnect(data, conn_candidate, - /* dead_connection */ FALSE); + (void)Curl_disconnect(data, conn_candidate, FALSE); else { infof(data, "No more connections allowed to host %s: %zu\n", bundlehost, max_host_connections); @@ -3773,8 +3794,7 @@ static CURLcode create_conn(struct Curl_easy *data, /* The cache is full. Let's see if we can kill a connection. */ conn_candidate = Curl_conncache_extract_oldest(data); if(conn_candidate) - (void)Curl_disconnect(data, conn_candidate, - /* dead_connection */ FALSE); + (void)Curl_disconnect(data, conn_candidate, FALSE); else { infof(data, "No connections available in cache\n"); connections_available = FALSE; @@ -4026,113 +4046,3 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) return CURLE_OK; } - -/* -* get_protocol_family() -* -* This is used to return the protocol family for a given protocol. -* -* Parameters: -* -* protocol [in] - A single bit protocol identifier such as HTTP or HTTPS. -* -* Returns the family as a single bit protocol identifier. -*/ - -static unsigned int get_protocol_family(unsigned int protocol) -{ - unsigned int family; - - switch(protocol) { - case CURLPROTO_HTTP: - case CURLPROTO_HTTPS: - family = CURLPROTO_HTTP; - break; - - case CURLPROTO_FTP: - case CURLPROTO_FTPS: - family = CURLPROTO_FTP; - break; - - case CURLPROTO_SCP: - family = CURLPROTO_SCP; - break; - - case CURLPROTO_SFTP: - family = CURLPROTO_SFTP; - break; - - case CURLPROTO_TELNET: - family = CURLPROTO_TELNET; - break; - - case CURLPROTO_LDAP: - case CURLPROTO_LDAPS: - family = CURLPROTO_LDAP; - break; - - case CURLPROTO_DICT: - family = CURLPROTO_DICT; - break; - - case CURLPROTO_FILE: - family = CURLPROTO_FILE; - break; - - case CURLPROTO_TFTP: - family = CURLPROTO_TFTP; - break; - - case CURLPROTO_IMAP: - case CURLPROTO_IMAPS: - family = CURLPROTO_IMAP; - break; - - case CURLPROTO_POP3: - case CURLPROTO_POP3S: - family = CURLPROTO_POP3; - break; - - case CURLPROTO_SMTP: - case CURLPROTO_SMTPS: - family = CURLPROTO_SMTP; - break; - - case CURLPROTO_RTSP: - family = CURLPROTO_RTSP; - break; - - case CURLPROTO_RTMP: - case CURLPROTO_RTMPS: - family = CURLPROTO_RTMP; - break; - - case CURLPROTO_RTMPT: - case CURLPROTO_RTMPTS: - family = CURLPROTO_RTMPT; - break; - - case CURLPROTO_RTMPE: - family = CURLPROTO_RTMPE; - break; - - case CURLPROTO_RTMPTE: - family = CURLPROTO_RTMPTE; - break; - - case CURLPROTO_GOPHER: - family = CURLPROTO_GOPHER; - break; - - case CURLPROTO_SMB: - case CURLPROTO_SMBS: - family = CURLPROTO_SMB; - break; - - default: - family = 0; - break; - } - - return family; -} diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c index acbfb82875..88b7f042f4 100644 --- a/libs/libcurl/src/urlapi.c +++ b/libs/libcurl/src/urlapi.c @@ -1255,8 +1255,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, return CURLUE_UNKNOWN_PART; } if(storep && *storep) { - free(*storep); - *storep = NULL; + Curl_safefree(*storep); } return CURLUE_OK; } @@ -1284,8 +1283,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, break; case CURLUPART_HOST: storep = &u->host; - free(u->zoneid); - u->zoneid = NULL; + Curl_safefree(u->zoneid); break; case CURLUPART_ZONEID: storep = &u->zoneid; diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index 0ae9269275..5ee81770ea 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -76,9 +76,7 @@ /* length of longest IPv6 address string including the trailing null */ #define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") -/* Default FTP/IMAP etc response timeout in milliseconds. - Symbian OS panics when given a timeout much greater than 1/2 hour. -*/ +/* Default FTP/IMAP etc response timeout in milliseconds */ #define RESP_TIMEOUT (120*1000) /* Max string input length is a precaution against abuse and to detect junk @@ -230,6 +228,7 @@ struct ssl_primary_config { char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ char *pinned_key; struct curl_blob *cert_blob; + char *curves; /* list of curves to use */ BIT(verifypeer); /* set TRUE if this is desired */ BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */ BIT(verifystatus); /* set TRUE if certificate status must be checked */ @@ -244,8 +243,6 @@ struct ssl_config_data { struct curl_blob *issuercert_blob; curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ void *fsslctxp; /* parameter for call back */ - char *cert; /* client certificate file name */ - struct curl_blob *cert_blob; char *cert_type; /* format for certificate (default: PEM)*/ char *key; /* private key file name */ struct curl_blob *key_blob; @@ -271,7 +268,7 @@ struct ssl_general_config { }; /* information stored about one single SSL session */ -struct curl_ssl_session { +struct Curl_ssl_session { char *name; /* host name for which this ID was used */ char *conn_to_host; /* host name for the connection (may be NULL) */ const char *scheme; /* protocol scheme used */ @@ -472,6 +469,7 @@ struct ConnectBits { EPRT doesn't work we disable it for the forthcoming requests */ BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */ + BIT(ftp_use_control_ssl); /* Enabled SSL for the control connection */ #endif BIT(netrc); /* name+password provided by netrc */ BIT(bound); /* set true if bind() has already been done on this socket/ @@ -740,6 +738,8 @@ struct Curl_handler { long defport; /* Default port. */ unsigned int protocol; /* See CURLPROTO_* - this needs to be the single specific protocol bit */ + unsigned int family; /* single bit for protocol family; basically the + non-TLS name of the protocol this is */ unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */ }; @@ -860,7 +860,7 @@ struct connectdata { connection is used! */ struct Curl_easy *data; struct connstate cnnct; - struct curl_llist_element bundle_node; /* conncache */ + struct Curl_llist_element bundle_node; /* conncache */ /* chunk is for HTTP chunked encoding, but is in the general connectdata struct only because we can do just about any protocol through a HTTP proxy @@ -1024,7 +1024,7 @@ struct connectdata { struct kerberos5data krb5; /* variables into the structure definition, */ #endif /* however, some of them are ftp specific. */ - struct curl_llist easyq; /* List of easy handles using this connection */ + struct Curl_llist easyq; /* List of easy handles using this connection */ curl_seek_callback seek_func; /* function that seeks the input */ void *seek_client; /* pointer to pass to the seek() above */ @@ -1134,6 +1134,7 @@ struct PureInfo { OpenSSL, GnuTLS, Schannel, NSS and GSKit builds. Asked for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ + CURLproxycode pxcode; BIT(timecond); /* set to TRUE if the time condition didn't match, which thus made the document NOT get fetched */ }; @@ -1274,7 +1275,7 @@ typedef enum { * One instance for each timeout an easy handle can set. */ struct time_node { - struct curl_llist_element list; + struct Curl_llist_element list; struct curltime time; expire_id eid; }; @@ -1314,7 +1315,7 @@ struct UrlState { strdup() data. */ int first_remote_port; /* remote port of the first (not followed) request */ - struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */ + struct Curl_ssl_session *session; /* array of 'max_ssl_sessions' size */ long sessionage; /* number of the most recent session */ unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */ struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */ @@ -1338,7 +1339,7 @@ struct UrlState { #endif /* USE_OPENSSL */ struct curltime expiretime; /* set this with Curl_expire() only */ struct Curl_tree timenode; /* for the splay stuff */ - struct curl_llist timeoutlist; /* list of pending timeouts */ + struct Curl_llist timeoutlist; /* list of pending timeouts */ struct time_node expires[EXPIRE_LAST]; /* nodes for each expire type */ /* a place to store the most recently set FTP entrypath */ @@ -1347,8 +1348,7 @@ struct UrlState { int httpversion; /* the lowest HTTP version*10 reported by any server involved in this request */ -#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \ - !defined(__SYMBIAN32__) +#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) /* do FTP line-end conversions on most platforms */ #define CURL_DO_LINEEND_CONV /* for FTP downloads: track CRLF sequences that span blocks */ @@ -1564,6 +1564,7 @@ enum dupstring { STRING_DNS_INTERFACE, STRING_DNS_LOCAL_IP4, STRING_DNS_LOCAL_IP6, + STRING_SSL_EC_CURVES, /* -- end of null-terminated strings -- */ @@ -1839,7 +1840,7 @@ struct UserDefined { }; struct Names { - struct curl_hash *hostcache; + struct Curl_hash *hostcache; enum { HCACHE_NONE, /* not pointing to anything */ HCACHE_MULTI, /* points to a shared one in the multi handle */ @@ -1863,8 +1864,8 @@ struct Curl_easy { struct Curl_easy *prev; struct connectdata *conn; - struct curl_llist_element connect_queue; - struct curl_llist_element conn_queue; /* list per connectdata */ + struct Curl_llist_element connect_queue; + struct Curl_llist_element conn_queue; /* list per connectdata */ CURLMstate mstate; /* the handle's state */ CURLcode result; /* previous result */ diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c index 4f6dda24fe..bdeba88357 100644 --- a/libs/libcurl/src/version.c +++ b/libs/libcurl/src/version.c @@ -31,8 +31,8 @@ #include "curl_printf.h" #ifdef USE_ARES -# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ - (defined(WIN32) || defined(__SYMBIAN32__)) +# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ + defined(WIN32) # define CARES_STATICLIB # endif # include <ares.h> @@ -56,10 +56,6 @@ #ifdef HAVE_ZLIB_H #include <zlib.h> -#ifdef __SYMBIAN32__ -/* zlib pollutes the namespace with this definition */ -#undef WIN32 -#endif #endif #ifdef HAVE_BROTLI @@ -298,7 +294,7 @@ static const char * const protocols[] = { "ldaps", #endif #endif -#ifdef CURL_ENABLE_MQTT +#ifndef CURL_DISABLE_MQTT "mqtt", #endif #ifndef CURL_DISABLE_POP3 @@ -319,9 +315,8 @@ static const char * const protocols[] = { #ifdef USE_SSH "sftp", #endif -#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) && \ - (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)) +#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ + (CURL_SIZEOF_CURL_OFF_T > 4) "smb", # ifdef USE_SSL "smbs", @@ -475,11 +470,13 @@ curl_version_info_data *curl_version_info(CURLversion stamp) #ifdef USE_SSL Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer)); version_info.ssl_version = ssl_buffer; +#ifndef CURL_DISABLE_PROXY if(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY) version_info.features |= CURL_VERSION_HTTPS_PROXY; else version_info.features &= ~CURL_VERSION_HTTPS_PROXY; #endif +#endif #ifdef HAVE_LIBZ version_info.libz_version = zlibVersion(); diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c index 20ee08dd65..c076b7c3e7 100644 --- a/libs/libcurl/src/vquic/ngtcp2.c +++ b/libs/libcurl/src/vquic/ngtcp2.c @@ -798,7 +798,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn, infof(data, "Connect socket %d over QUIC to %s:%ld\n", sockfd, ipbuf, port); - qs->version = NGTCP2_PROTO_VER; + qs->version = NGTCP2_PROTO_VER_MAX; #ifdef USE_OPENSSL qs->sslctx = quic_ssl_ctx(data); if(!qs->sslctx) @@ -831,13 +831,9 @@ CURLcode Curl_quic_connect(struct connectdata *conn, ngtcp2_addr_init(&path.local, &qs->local_addr, qs->local_addrlen, NULL); ngtcp2_addr_init(&path.remote, addr, addrlen, NULL); -#ifdef NGTCP2_PROTO_VER -#define QUICVER NGTCP2_PROTO_VER -#else -#error "unsupported ngtcp2 version" -#endif - rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path, QUICVER, - &ng_callbacks, &qs->settings, NULL, qs); + rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path, + NGTCP2_PROTO_VER_MAX, &ng_callbacks, + &qs->settings, NULL, qs); if(rc) return CURLE_QUIC_CONNECT_ERROR; @@ -954,6 +950,7 @@ static const struct Curl_handler Curl_handler_http3 = { ng_conncheck, /* connection_check */ PORT_HTTP, /* defport */ CURLPROTO_HTTPS, /* protocol */ + CURLPROTO_HTTP, /* family */ PROTOPT_SSL | PROTOPT_STREAM /* flags */ }; @@ -1729,6 +1726,7 @@ static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd, socklen_t remote_addrlen; ngtcp2_path path; ngtcp2_tstamp ts = timestamp(); + ngtcp2_pkt_info pi = { 0 }; for(;;) { remote_addrlen = sizeof(remote_addr); @@ -1750,7 +1748,7 @@ static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd, ngtcp2_addr_init(&path.remote, (struct sockaddr *)&remote_addr, remote_addrlen, NULL); - rv = ngtcp2_conn_read_pkt(qs->qconn, &path, buf, recvd, ts); + rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts); if(rv != 0) { /* TODO Send CONNECTION_CLOSE if possible */ return CURLE_RECV_ERROR; @@ -1815,7 +1813,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd, uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_MORE | (fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0); outlen = - ngtcp2_conn_writev_stream(qs->qconn, &ps.path, + ngtcp2_conn_writev_stream(qs->qconn, &ps.path, NULL, out, pktlen, &ndatalen, flags, stream_id, (const ngtcp2_vec *)vec, veccnt, ts); @@ -1860,7 +1858,8 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd, } } if(outlen < 0) { - outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, out, pktlen, ts); + outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, NULL, + out, pktlen, ts); if(outlen < 0) { failf(conn->data, "ngtcp2_conn_write_pkt returned error: %s\n", ngtcp2_strerror((int)outlen)); diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c index fd9cb8bd34..f52e9da325 100644 --- a/libs/libcurl/src/vquic/quiche.c +++ b/libs/libcurl/src/vquic/quiche.c @@ -154,6 +154,7 @@ static const struct Curl_handler Curl_handler_http3 = { quiche_conncheck, /* connection_check */ PORT_HTTP, /* defport */ CURLPROTO_HTTPS, /* protocol */ + CURLPROTO_HTTP, /* family */ PROTOPT_SSL | PROTOPT_STREAM /* flags */ }; diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c index 8988e2392d..acdb4e7534 100644 --- a/libs/libcurl/src/vssh/libssh.c +++ b/libs/libcurl/src/vssh/libssh.c @@ -158,6 +158,7 @@ const struct Curl_handler Curl_handler_scp = { ZERO_NULL, /* connection_check */ PORT_SSH, /* defport */ CURLPROTO_SCP, /* protocol */ + CURLPROTO_SCP, /* family */ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ }; @@ -183,6 +184,7 @@ const struct Curl_handler Curl_handler_sftp = { ZERO_NULL, /* connection_check */ PORT_SSH, /* defport */ CURLPROTO_SFTP, /* protocol */ + CURLPROTO_SFTP, /* family */ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ }; @@ -2692,7 +2694,9 @@ static void sftp_quote(struct connectdata *conn) */ if(strncasecompare(cmd, "chgrp ", 6) || strncasecompare(cmd, "chmod ", 6) || - strncasecompare(cmd, "chown ", 6)) { + strncasecompare(cmd, "chown ", 6) || + strncasecompare(cmd, "atime ", 6) || + strncasecompare(cmd, "mtime ", 6)) { /* attribute change */ /* sshc->quote_path1 contains the mode to set */ @@ -2702,7 +2706,7 @@ static void sftp_quote(struct connectdata *conn) if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); else - failf(data, "Syntax error in chgrp/chmod/chown: " + failf(data, "Syntax error in chgrp/chmod/chown/atime/mtime: " "Bad second parameter"); Curl_safefree(sshc->quote_path1); state(conn, SSH_SFTP_CLOSE); @@ -2863,6 +2867,34 @@ static void sftp_quote_stat(struct connectdata *conn) } sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; } + else if(strncasecompare(cmd, "atime", 5)) { + time_t date = Curl_getdate_capped(sshc->quote_path1); + if(date == -1) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: incorrect access date format"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->atime = (uint32_t)date; + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME; + } + else if(strncasecompare(cmd, "mtime", 5)) { + time_t date = Curl_getdate_capped(sshc->quote_path1); + if(date == -1) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: incorrect modification date format"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->mtime = (uint32_t)date; + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME; + } /* Now send the completed structure... */ state(conn, SSH_SFTP_QUOTE_SETSTAT); diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c index 4f56bb44ce..d983cc9a9c 100644 --- a/libs/libcurl/src/vssh/libssh2.c +++ b/libs/libcurl/src/vssh/libssh2.c @@ -150,6 +150,7 @@ const struct Curl_handler Curl_handler_scp = { ZERO_NULL, /* connection_check */ PORT_SSH, /* defport */ CURLPROTO_SCP, /* protocol */ + CURLPROTO_SCP, /* family */ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ }; @@ -177,6 +178,7 @@ const struct Curl_handler Curl_handler_sftp = { ZERO_NULL, /* connection_check */ PORT_SSH, /* defport */ CURLPROTO_SFTP, /* protocol */ + CURLPROTO_SFTP, /* family */ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ }; @@ -442,6 +444,7 @@ static CURLcode ssh_knownhost(struct connectdata *conn) if(data->set.str[STRING_SSH_KNOWNHOSTS]) { /* we're asked to verify the host against a file */ struct ssh_conn *sshc = &conn->proto.sshc; + struct libssh2_knownhost *host = NULL; int rc; int keytype; size_t keylen; @@ -456,7 +459,6 @@ static CURLcode ssh_knownhost(struct connectdata *conn) * What host name does OpenSSH store in its file if an IDN name is * used? */ - struct libssh2_knownhost *host; enum curl_khmatch keymatch; curl_sshkeycallback func = data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback; @@ -568,7 +570,13 @@ static CURLcode ssh_knownhost(struct connectdata *conn) /* DEFER means bail out but keep the SSH_HOSTKEY state */ result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; break; + case CURLKHSTAT_FINE_REPLACE: + /* remove old host+key that doesn't match */ + if(host) + libssh2_knownhost_del(sshc->kh, host); + /*FALLTHROUGH*/ case CURLKHSTAT_FINE: + /*FALLTHROUGH*/ case CURLKHSTAT_FINE_ADD_TO_FILE: /* proceed */ if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) { @@ -583,7 +591,8 @@ static CURLcode ssh_knownhost(struct connectdata *conn) if(addrc) infof(data, "Warning adding the known host %s failed!\n", conn->host.name); - else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) { + else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE || + rc == CURLKHSTAT_FINE_REPLACE) { /* now we write the entire in-memory list of known hosts to the known_hosts file */ int wrc = @@ -814,6 +823,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) result = ssh_force_knownhost_key_type(conn); if(result) { state(conn, SSH_SESSION_FREE); + sshc->actualcode = result; break; } @@ -1390,7 +1400,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) */ if(strncasecompare(cmd, "chgrp ", 6) || strncasecompare(cmd, "chmod ", 6) || - strncasecompare(cmd, "chown ", 6) ) { + strncasecompare(cmd, "chown ", 6) || + strncasecompare(cmd, "atime ", 6) || + strncasecompare(cmd, "mtime ", 6)) { /* attribute change */ /* sshc->quote_path1 contains the mode to set */ @@ -1587,6 +1599,34 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } } + else if(strncasecompare(cmd, "atime", 5)) { + time_t date = Curl_getdate_capped(sshc->quote_path1); + if(date == -1) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: incorrect access date format"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + sshc->quote_attrs.atime = (unsigned long)date; + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; + } + else if(strncasecompare(cmd, "mtime", 5)) { + time_t date = Curl_getdate_capped(sshc->quote_path1); + if(date == -1) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: incorrect modification date format"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + sshc->quote_attrs.mtime = (unsigned long)date; + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; + } /* Now send the completed structure... */ state(conn, SSH_SFTP_QUOTE_SETSTAT); @@ -2999,6 +3039,42 @@ static CURLcode ssh_setup_connection(struct connectdata *conn) static Curl_recv scp_recv, sftp_recv; static Curl_send scp_send, sftp_send; +static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer, + size_t length, int flags, void **abstract) +{ + struct connectdata *conn = (struct connectdata *)*abstract; + ssize_t nread; + CURLcode result; + (void)flags; + + result = Curl_read(conn, sock, buffer, length, &nread); + if(result == CURLE_AGAIN) + return -EAGAIN; /* magic return code for libssh2 */ + else if(result) + return -1; /* generic error */ + if(conn->data->set.verbose) + Curl_debug(conn->data, CURLINFO_DATA_IN, (char *)buffer, (size_t)nread); + return nread; +} + +static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer, + size_t length, int flags, void **abstract) +{ + struct connectdata *conn = (struct connectdata *)*abstract; + ssize_t nwrite; + CURLcode result; + (void)flags; + + result = Curl_write(conn, sock, buffer, length, &nwrite); + if(result == CURLE_AGAIN) + return -EAGAIN; /* magic return code for libssh2 */ + else if(result) + return -1; /* error */ + if(conn->data->set.verbose) + Curl_debug(conn->data, CURLINFO_DATA_OUT, (char *)buffer, (size_t)nwrite); + return nwrite; +} + /* * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to * do protocol-specific actions at connect-time. @@ -3020,14 +3096,6 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) function to make the re-use checks properly be able to check this bit. */ connkeep(conn, "SSH default"); - if(conn->handler->protocol & CURLPROTO_SCP) { - conn->recv[FIRSTSOCKET] = scp_recv; - conn->send[FIRSTSOCKET] = scp_send; - } - else { - conn->recv[FIRSTSOCKET] = sftp_recv; - conn->send[FIRSTSOCKET] = sftp_send; - } ssh = &conn->proto.sshc; #ifdef CURL_LIBSSH2_DEBUG @@ -3048,6 +3116,53 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) return CURLE_FAILED_INIT; } + if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) { + /* + * This crazy union dance is here to avoid assigning a void pointer a + * function pointer as it is invalid C. The problem is of course that + * libssh2 has such an API... + */ + union receive { + void *recvp; + ssize_t (*recvptr)(libssh2_socket_t, void *, size_t, int, void **); + }; + union transfer { + void *sendp; + ssize_t (*sendptr)(libssh2_socket_t, const void *, size_t, int, void **); + }; + union receive sshrecv; + union transfer sshsend; + + sshrecv.recvptr = ssh_tls_recv; + sshsend.sendptr = ssh_tls_send; + + infof(data, "Uses HTTPS proxy!\n"); + /* + Setup libssh2 callbacks to make it read/write TLS from the socket. + + ssize_t + recvcb(libssh2_socket_t sock, void *buffer, size_t length, + int flags, void **abstract); + + ssize_t + sendcb(libssh2_socket_t sock, const void *buffer, size_t length, + int flags, void **abstract); + + */ + libssh2_session_callback_set(ssh->ssh_session, + LIBSSH2_CALLBACK_RECV, sshrecv.recvp); + libssh2_session_callback_set(ssh->ssh_session, + LIBSSH2_CALLBACK_SEND, sshsend.sendp); + } + else if(conn->handler->protocol & CURLPROTO_SCP) { + conn->recv[FIRSTSOCKET] = scp_recv; + conn->send[FIRSTSOCKET] = scp_send; + } + else { + conn->recv[FIRSTSOCKET] = sftp_recv; + conn->send[FIRSTSOCKET] = sftp_send; + } + if(data->set.ssh_compression) { #if LIBSSH2_VERSION_NUM >= 0x010208 if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) diff --git a/libs/libcurl/src/vtls/gskit.c b/libs/libcurl/src/vtls/gskit.c index 0538e4a463..dc79f487c8 100644 --- a/libs/libcurl/src/vtls/gskit.c +++ b/libs/libcurl/src/vtls/gskit.c @@ -705,7 +705,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex) int rc; const char * const keyringfile = SSL_CONN_CONFIG(CAfile); const char * const keyringpwd = SSL_SET_OPTION(key_passwd); - const char * const keyringlabel = SSL_SET_OPTION(cert); + const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert); const long int ssl_version = SSL_CONN_CONFIG(version); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name: diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c index 16b0bd6cb5..ec3f8599b0 100644 --- a/libs/libcurl/src/vtls/gtls.c +++ b/libs/libcurl/src/vtls/gtls.c @@ -81,7 +81,7 @@ static bool gtls_inited = FALSE; struct ssl_backend_data { gnutls_session_t session; gnutls_certificate_credentials_t cred; -#ifdef USE_TLS_SRP +#ifdef HAVE_GNUTLS_SRP gnutls_srp_client_credentials_t srp_client_cred; #endif }; @@ -304,7 +304,7 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type) return GNUTLS_X509_FMT_PEM; if(strcasecompare(type, "DER")) return GNUTLS_X509_FMT_DER; - return -1; + return GNUTLS_X509_FMT_PEM; /* default to PEM */ } #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509" @@ -399,15 +399,8 @@ gtls_connect_step1(struct connectdata *conn, #endif const char *prioritylist; const char *err = NULL; -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - long * const certverifyresult = SSL_IS_PROXY() ? - &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; -#else - const char * const hostname = conn->host.name; - long * const certverifyresult = &data->set.ssl.certverifyresult; -#endif + const char * const hostname = SSL_HOST_NAME(); + long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult); if(connssl->state == ssl_connection_complete) /* to make us tolerant against being called more than once for the @@ -434,7 +427,7 @@ gtls_connect_step1(struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } -#ifdef USE_TLS_SRP +#ifdef HAVE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username)); @@ -588,7 +581,7 @@ gtls_connect_step1(struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } -#ifdef USE_TLS_SRP +#ifdef HAVE_GNUTLS_SRP /* Only add SRP to the cipher list if SRP is requested. Otherwise * GnuTLS will disable TLS 1.3 support. */ if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { @@ -610,7 +603,7 @@ gtls_connect_step1(struct connectdata *conn, else { #endif rc = gnutls_priority_set_direct(session, prioritylist, &err); -#ifdef USE_TLS_SRP +#ifdef HAVE_GNUTLS_SRP } #endif @@ -645,7 +638,7 @@ gtls_connect_step1(struct connectdata *conn, gnutls_alpn_set_protocols(session, protocols, cur, 0); } - if(SSL_SET_OPTION(cert)) { + if(SSL_SET_OPTION(primary.clientcert)) { if(SSL_SET_OPTION(key_passwd)) { const unsigned int supported_key_encryption_algorithms = GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR | @@ -654,9 +647,9 @@ gtls_connect_step1(struct connectdata *conn, GNUTLS_PKCS_USE_PBES2_AES_256; rc = gnutls_certificate_set_x509_key_file2( backend->cred, - SSL_SET_OPTION(cert), + SSL_SET_OPTION(primary.clientcert), SSL_SET_OPTION(key) ? - SSL_SET_OPTION(key) : SSL_SET_OPTION(cert), + SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert), do_file_type(SSL_SET_OPTION(cert_type)), SSL_SET_OPTION(key_passwd), supported_key_encryption_algorithms); @@ -670,9 +663,9 @@ gtls_connect_step1(struct connectdata *conn, else { if(gnutls_certificate_set_x509_key_file( backend->cred, - SSL_SET_OPTION(cert), + SSL_SET_OPTION(primary.clientcert), SSL_SET_OPTION(key) ? - SSL_SET_OPTION(key) : SSL_SET_OPTION(cert), + SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert), do_file_type(SSL_SET_OPTION(cert_type)) ) != GNUTLS_E_SUCCESS) { failf(data, "error reading X.509 key or certificate file"); @@ -681,7 +674,7 @@ gtls_connect_step1(struct connectdata *conn, } } -#ifdef USE_TLS_SRP +#ifdef HAVE_GNUTLS_SRP /* put the credentials to the current session */ if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP, @@ -839,15 +832,8 @@ gtls_connect_step3(struct connectdata *conn, unsigned int bits; gnutls_protocol_t version = gnutls_protocol_get_version(session); #endif -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - long * const certverifyresult = SSL_IS_PROXY() ? - &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; -#else - const char * const hostname = conn->host.name; - long * const certverifyresult = &data->set.ssl.certverifyresult; -#endif + const char * const hostname = SSL_HOST_NAME(); + long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult); /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session), @@ -868,7 +854,7 @@ gtls_connect_step3(struct connectdata *conn, if(SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost) || SSL_SET_OPTION(issuercert)) { -#ifdef USE_TLS_SRP +#ifdef HAVE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP && SSL_SET_OPTION(username) != NULL && !SSL_CONN_CONFIG(verifypeer) @@ -881,7 +867,7 @@ gtls_connect_step3(struct connectdata *conn, failf(data, "failed to get server cert"); *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND; return CURLE_PEER_FAILED_VERIFICATION; -#ifdef USE_TLS_SRP +#ifdef HAVE_GNUTLS_SRP } #endif } @@ -1128,22 +1114,15 @@ gtls_connect_step3(struct connectdata *conn, } #endif if(!rc) { -#ifndef CURL_DISABLE_PROXY - const char * const dispname = SSL_IS_PROXY() ? - conn->http_proxy.host.dispname : conn->host.dispname; -#else - const char * const dispname = conn->host.dispname; -#endif - if(SSL_CONN_CONFIG(verifyhost)) { failf(data, "SSL: certificate subject name (%s) does not match " - "target host name '%s'", certname, dispname); + "target host name '%s'", certname, SSL_HOST_DISPNAME()); gnutls_x509_crt_deinit(x509_cert); return CURLE_PEER_FAILED_VERIFICATION; } else infof(data, "\t common name: %s (does not match '%s')\n", - certname, dispname); + certname, SSL_HOST_DISPNAME()); } else infof(data, "\t common name: %s (matched)\n", certname); @@ -1448,7 +1427,7 @@ static void close_one(struct ssl_connect_data *connssl) gnutls_certificate_free_credentials(backend->cred); backend->cred = NULL; } -#ifdef USE_TLS_SRP +#ifdef HAVE_GNUTLS_SRP if(backend->srp_client_cred) { gnutls_srp_free_client_credentials(backend->srp_client_cred); backend->srp_client_cred = NULL; @@ -1530,7 +1509,7 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) } gnutls_certificate_free_credentials(backend->cred); -#ifdef USE_TLS_SRP +#ifdef HAVE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP && SSL_SET_OPTION(username) != NULL) gnutls_srp_free_client_credentials(backend->srp_client_cred); diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c index 545f824c62..4e5f6574f1 100644 --- a/libs/libcurl/src/vtls/mbedtls.c +++ b/libs/libcurl/src/vtls/mbedtls.c @@ -31,6 +31,9 @@ #ifdef USE_MBEDTLS +/* Define this to enable lots of debugging for mbedTLS */ +/* #define MBEDTLS_DEBUG */ + #include <mbedtls/version.h> #if MBEDTLS_VERSION_NUMBER >= 0x02040000 #include <mbedtls/net_sockets.h> @@ -46,6 +49,12 @@ #include <mbedtls/ctr_drbg.h> #include <mbedtls/sha256.h> +#if MBEDTLS_VERSION_MAJOR >= 2 +# ifdef MBEDTLS_DEBUG +# include <mbedtls/debug.h> +# endif +#endif + #include "urldata.h" #include "sendf.h" #include "inet_pton.h" @@ -113,9 +122,6 @@ static int entropy_func_mutex(void *data, unsigned char *output, size_t len) #endif /* THREADING_SUPPORT */ -/* Define this to enable lots of debugging for mbedTLS */ -#undef MBEDTLS_DEBUG - #ifdef MBEDTLS_DEBUG static void mbed_debug(void *context, int level, const char *f_name, int line_nb, const char *line) @@ -244,7 +250,7 @@ mbed_connect_step1(struct connectdata *conn, const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const ssl_capath = SSL_CONN_CONFIG(CApath); - char * const ssl_cert = SSL_SET_OPTION(cert); + char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); #ifndef CURL_DISABLE_PROXY const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : diff --git a/libs/libcurl/src/vtls/mesalink.c b/libs/libcurl/src/vtls/mesalink.c index 7132bdfd22..7346a75f95 100644 --- a/libs/libcurl/src/vtls/mesalink.c +++ b/libs/libcurl/src/vtls/mesalink.c @@ -158,8 +158,8 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex) SSL_CONN_CONFIG(CApath))) { if(SSL_CONN_CONFIG(verifypeer)) { failf(data, - "error setting certificate verify locations:\n" - " CAfile: %s\n CApath: %s", + "error setting certificate verify locations: " + " CAfile: %s CApath: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none", SSL_CONN_CONFIG(CApath) ? @@ -173,20 +173,18 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex) else { infof(data, "successfully set certificate verify locations:\n"); } - infof(data, - " CAfile: %s\n" - " CApath: %s\n", - SSL_CONN_CONFIG(CAfile)? - SSL_CONN_CONFIG(CAfile): "none", - SSL_CONN_CONFIG(CApath)? - SSL_CONN_CONFIG(CApath): "none"); + infof(data, " CAfile: %s\n", + SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): "none"); + infof(data, " CApath: %s\n", + SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath): "none"); } - if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) { + if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) { int file_type = do_file_type(SSL_SET_OPTION(cert_type)); - if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx, SSL_SET_OPTION(cert), - file_type) != 1) { + if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx, + SSL_SET_OPTION(primary.clientcert), + file_type) != 1) { failf(data, "unable to use client certificate (no key or wrong pass" " phrase?)"); return CURLE_SSL_CONNECT_ERROR; diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c index 0f0d1ee6c8..d0988549dd 100644 --- a/libs/libcurl/src/vtls/nss.c +++ b/libs/libcurl/src/vtls/nss.c @@ -83,7 +83,7 @@ struct ssl_backend_data { PRFileDesc *handle; char *client_nickname; struct Curl_easy *data; - struct curl_llist obj_list; + struct Curl_llist obj_list; PK11GenericObject *obj_clicert; }; @@ -91,14 +91,14 @@ static PRLock *nss_initlock = NULL; static PRLock *nss_crllock = NULL; static PRLock *nss_findslot_lock = NULL; static PRLock *nss_trustload_lock = NULL; -static struct curl_llist nss_crl_list; +static struct Curl_llist nss_crl_list; static NSSInitContext *nss_context = NULL; static volatile int initialized = 0; /* type used to wrap pointers as list nodes */ struct ptr_list_wrap { void *ptr; - struct curl_llist_element node; + struct Curl_llist_element node; }; struct cipher_s { @@ -430,7 +430,7 @@ static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name) } /* wrap 'ptr' as list node and tail-insert into 'list' */ -static CURLcode insert_wrapped_ptr(struct curl_llist *list, void *ptr) +static CURLcode insert_wrapped_ptr(struct Curl_llist *list, void *ptr) { struct ptr_list_wrap *wrap = malloc(sizeof(*wrap)); if(!wrap) @@ -1027,12 +1027,7 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) CERTCertificate *cert; /* remember the cert verification result */ -#ifndef CURL_DISABLE_PROXY - if(SSL_IS_PROXY()) - data->set.proxy_ssl.certverifyresult = err; - else -#endif - data->set.ssl.certverifyresult = err; + SSL_SET_OPTION_LVALUE(certverifyresult) = err; if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost)) /* we are asked not to verify the host name */ @@ -1631,9 +1626,8 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn, if(capath && !capath[0]) capath = NULL; - infof(data, " CAfile: %s\n CApath: %s\n", - cafile ? cafile : "none", - capath ? capath : "none"); + infof(data, " CAfile: %s\n", cafile ? cafile : "none"); + infof(data, " CApath: %s\n", capath ? capath : "none"); /* load libnssckbi.so if no other trust roots were specified */ use_trust_module = !cafile && !capath; @@ -1673,7 +1667,8 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn, if(!dir) return CURLE_SSL_CACERT_BADFILE; - while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) { + while((entry = + PR_ReadDir(dir, (PRDirFlags)(PR_SKIP_BOTH | PR_SKIP_HIDDEN)))) { char *fullpath = aprintf("%s/%s", capath, entry->name); if(!fullpath) { PR_CloseDir(dir); @@ -1838,12 +1833,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) CURLcode result; bool second_layer = FALSE; SSLVersionRange sslver_supported; -#ifndef CURL_DISABLE_PROXY - const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - const char *hostname = conn->host.name; -#endif SSLVersionRange sslver = { SSL_LIBRARY_VERSION_TLS_1_0, /* min */ @@ -1948,12 +1937,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) goto error; /* not checked yet */ -#ifndef CURL_DISABLE_PROXY - if(SSL_IS_PROXY()) - data->set.proxy_ssl.certverifyresult = 0; - else -#endif - data->set.ssl.certverifyresult = 0; + SSL_SET_OPTION_LVALUE(certverifyresult) = 0; if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess) goto error; @@ -1981,14 +1965,15 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) infof(data, " CRLfile: %s\n", SSL_SET_OPTION(CRLfile)); } - if(SSL_SET_OPTION(cert)) { - char *nickname = dup_nickname(data, SSL_SET_OPTION(cert)); + if(SSL_SET_OPTION(primary.clientcert)) { + char *nickname = dup_nickname(data, SSL_SET_OPTION(primary.clientcert)); if(nickname) { /* we are not going to use libnsspem.so to read the client cert */ backend->obj_clicert = NULL; } else { - CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert), + CURLcode rv = cert_stuff(conn, sockindex, + SSL_SET_OPTION(primary.clientcert), SSL_SET_OPTION(key)); if(rv) { /* failf() is already done in cert_stuff() */ @@ -2124,11 +2109,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) goto error; /* propagate hostname to the TLS layer */ - if(SSL_SetURL(backend->handle, hostname) != SECSuccess) + if(SSL_SetURL(backend->handle, SSL_HOST_NAME()) != SECSuccess) goto error; /* prevent NSS from re-using the session for a different hostname */ - if(SSL_SetSockPeerID(backend->handle, hostname) != SECSuccess) + if(SSL_SetSockPeerID(backend->handle, SSL_HOST_NAME()) != SECSuccess) goto error; return CURLE_OK; @@ -2147,18 +2132,6 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) struct Curl_easy *data = conn->data; CURLcode result = CURLE_SSL_CONNECT_ERROR; PRUint32 timeout; -#ifndef CURL_DISABLE_PROXY - long * const certverifyresult = SSL_IS_PROXY() ? - &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; - const char * const pinnedpubkey = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; -#else - long * const certverifyresult = &data->set.ssl.certverifyresult; - const char * const pinnedpubkey = - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; -#endif - /* check timeout situation */ const timediff_t time_left = Curl_timeleft(data, NULL, TRUE); @@ -2174,9 +2147,9 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) if(PR_GetError() == PR_WOULD_BLOCK_ERROR) /* blocking direction is updated by nss_update_connecting_state() */ return CURLE_AGAIN; - else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN) + else if(SSL_SET_OPTION(certverifyresult) == SSL_ERROR_BAD_CERT_DOMAIN) result = CURLE_PEER_FAILED_VERIFICATION; - else if(*certverifyresult != 0) + else if(SSL_SET_OPTION(certverifyresult) != 0) result = CURLE_PEER_FAILED_VERIFICATION; goto error; } @@ -2204,7 +2177,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) } } - result = cmp_peer_pubkey(connssl, pinnedpubkey); + result = cmp_peer_pubkey(connssl, SSL_PINNED_PUB_KEY()); if(result) /* status already printed */ goto error; diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c index 1685a4aa4c..28a1ae6dab 100644 --- a/libs/libcurl/src/vtls/openssl.c +++ b/libs/libcurl/src/vtls/openssl.c @@ -34,6 +34,13 @@ /* Wincrypt must be included before anything that could include OpenSSL. */ #if defined(USE_WIN32_CRYPTO) #include <wincrypt.h> +/* Undefine wincrypt conflicting symbols for BoringSSL. */ +#undef X509_NAME +#undef X509_EXTENSIONS +#undef PKCS7_ISSUER_AND_SERIAL +#undef PKCS7_SIGNER_INFO +#undef OCSP_REQUEST +#undef OCSP_RESPONSE #endif #include "urldata.h" @@ -193,6 +200,10 @@ !defined(OPENSSL_IS_BORINGSSL)) #define HAVE_SSL_CTX_SET_CIPHERSUITES #define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH +/* SET_EC_CURVES available under the same preconditions: see + * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html + */ +#define HAVE_SSL_CTX_SET_EC_CURVES #endif #if defined(LIBRESSL_VERSION_NUMBER) @@ -1571,16 +1582,8 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) CURLcode result = CURLE_OK; bool dNSName = FALSE; /* if a dNSName field exists in the cert */ bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */ -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? - conn->http_proxy.host.name : conn->host.name; - const char * const dispname = SSL_IS_PROXY() ? - conn->http_proxy.host.dispname : conn->host.dispname; -#else - /* disabled proxy support */ - const char * const hostname = conn->host.name; - const char * const dispname = conn->host.dispname; -#endif + const char * const hostname = SSL_HOST_NAME(); + const char * const dispname = SSL_HOST_DISPNAME(); #ifdef ENABLE_IPV6 if(conn->bits.ipv6_ip && @@ -2459,12 +2462,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME bool sni; -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - const char * const hostname = conn->host.name; -#endif + const char * const hostname = SSL_HOST_NAME(); #ifdef ENABLE_IPV6 struct in6_addr addr; @@ -2472,18 +2470,12 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) struct in_addr addr; #endif #endif -#ifndef CURL_DISABLE_PROXY - long * const certverifyresult = SSL_IS_PROXY() ? - &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; -#else - long * const certverifyresult = &data->set.ssl.certverifyresult; -#endif const long int ssl_version = SSL_CONN_CONFIG(version); -#ifdef USE_TLS_SRP +#ifdef HAVE_OPENSSL_SRP const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype); #endif - char * const ssl_cert = SSL_SET_OPTION(cert); - const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob); + char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); + const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); const char * const ssl_cert_type = SSL_SET_OPTION(cert_type); const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); const char * const ssl_capath = SSL_CONN_CONFIG(CApath); @@ -2500,7 +2492,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) if(result) return result; - *certverifyresult = !X509_V_OK; + SSL_SET_OPTION_LVALUE(certverifyresult) = !X509_V_OK; /* check to see if we've been told to use an explicit SSL/TLS version */ @@ -2524,7 +2516,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) failf(data, OSSL_PACKAGE " was built without SSLv2 support"); return CURLE_NOT_BUILT_IN; #else -#ifdef USE_TLS_SRP +#ifdef HAVE_OPENSSL_SRP if(ssl_authtype == CURL_TLSAUTH_SRP) return CURLE_SSL_CONNECT_ERROR; #endif @@ -2537,7 +2529,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) failf(data, OSSL_PACKAGE " was built without SSLv3 support"); return CURLE_NOT_BUILT_IN; #else -#ifdef USE_TLS_SRP +#ifdef HAVE_OPENSSL_SRP if(ssl_authtype == CURL_TLSAUTH_SRP) return CURLE_SSL_CONNECT_ERROR; #endif @@ -2793,7 +2785,19 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) SSL_CTX_set_post_handshake_auth(backend->ctx, 1); #endif -#ifdef USE_TLS_SRP +#ifdef HAVE_SSL_CTX_SET_EC_CURVES + { + char *curves = SSL_CONN_CONFIG(curves); + if(curves) { + if(!SSL_CTX_set1_curves_list(backend->ctx, curves)) { + failf(data, "failed setting curves list: '%s'", curves); + return CURLE_SSL_CIPHER; + } + } + } +#endif + +#ifdef HAVE_OPENSSL_SRP if(ssl_authtype == CURL_TLSAUTH_SRP) { char * const ssl_username = SSL_SET_OPTION(username); @@ -2910,7 +2914,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate is good for all uses. If it returns zero, the certificate has no valid uses." */ - if(GetLastError() != CRYPT_E_NOT_FOUND) + if((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND) continue; } else { @@ -2970,7 +2974,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) { if(ssl_cafile) { if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) { - if(verifypeer) { + if(verifypeer && !imported_native_ca) { /* Fail if we insist on successfully verifying the server. */ failf(data, "error setting certificate file: %s", ssl_cafile); return CURLE_SSL_CACERT_BADFILE; @@ -2978,11 +2982,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* Continue with a warning if no certificate verif is required. */ infof(data, "error setting certificate file, continuing anyway\n"); } - infof(data, " CAfile: %s\n", ssl_cafile); + infof(data, " CAfile: %s\n", ssl_cafile); } if(ssl_capath) { if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) { - if(verifypeer) { + if(verifypeer && !imported_native_ca) { /* Fail if we insist on successfully verifying the server. */ failf(data, "error setting certificate path: %s", ssl_capath); return CURLE_SSL_CACERT_BADFILE; @@ -2990,7 +2994,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* Continue with a warning if no certificate verif is required. */ infof(data, "error setting certificate path, continuing anyway\n"); } - infof(data, " CApath: %s\n", ssl_capath); + infof(data, " CApath: %s\n", ssl_capath); } } #else @@ -3000,8 +3004,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) { if(verifypeer && !imported_native_ca) { /* Fail if we insist on successfully verifying the server. */ - failf(data, "error setting certificate verify locations:\n" - " CAfile: %s\n CApath: %s", + failf(data, "error setting certificate verify locations:" + " CAfile: %s CApath: %s", ssl_cafile ? ssl_cafile : "none", ssl_capath ? ssl_capath : "none"); return CURLE_SSL_CACERT_BADFILE; @@ -3015,11 +3019,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* Everything is fine. */ infof(data, "successfully set certificate verify locations:\n"); } - infof(data, - " CAfile: %s\n" - " CApath: %s\n", - ssl_cafile ? ssl_cafile : "none", - ssl_capath ? ssl_capath : "none"); + infof(data, " CAfile: %s\n", ssl_cafile ? ssl_cafile : "none"); + infof(data, " CApath: %s\n", ssl_capath ? ssl_capath : "none"); } #endif @@ -3201,12 +3202,6 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) struct Curl_easy *data = conn->data; int err; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; -#ifndef CURL_DISABLE_PROXY - long * const certverifyresult = SSL_IS_PROXY() ? - &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; -#else - long * const certverifyresult = &data->set.ssl.certverifyresult; -#endif struct ssl_backend_data *backend = connssl->backend; DEBUGASSERT(ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state @@ -3265,12 +3260,13 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) reason = ERR_GET_REASON(errdetail); if((lib == ERR_LIB_SSL) && - (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) { + ((reason == SSL_R_CERTIFICATE_VERIFY_FAILED) || + (reason == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED))) { result = CURLE_PEER_FAILED_VERIFICATION; lerr = SSL_get_verify_result(backend->handle); if(lerr != X509_V_OK) { - *certverifyresult = lerr; + SSL_SET_OPTION_LVALUE(certverifyresult) = lerr; msnprintf(error_buffer, sizeof(error_buffer), "SSL certificate problem: %s", X509_verify_cert_error_string(lerr)); @@ -3292,12 +3288,10 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) * the SO_ERROR is also lost. */ if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) { + const char * const hostname = SSL_HOST_NAME(); #ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? - conn->http_proxy.host.name : conn->host.name; const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; #else - const char * const hostname = conn->host.name; const long int port = conn->remote_port; #endif char extramsg[80]=""; @@ -3752,12 +3746,6 @@ static CURLcode servercert(struct connectdata *conn, char error_buffer[256]=""; char buffer[2048]; const char *ptr; -#ifndef CURL_DISABLE_PROXY - long * const certverifyresult = SSL_IS_PROXY() ? - &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; -#else - long * const certverifyresult = &data->set.ssl.certverifyresult; -#endif BIO *mem = BIO_new(BIO_s_mem()); struct ssl_backend_data *backend = connssl->backend; @@ -3878,9 +3866,9 @@ static CURLcode servercert(struct connectdata *conn, X509_free(issuer); } - lerr = *certverifyresult = SSL_get_verify_result(backend->handle); - - if(*certverifyresult != X509_V_OK) { + lerr = SSL_get_verify_result(backend->handle); + SSL_SET_OPTION_LVALUE(certverifyresult) = lerr; + if(lerr != X509_V_OK) { if(SSL_CONN_CONFIG(verifypeer)) { /* We probably never reach this, because SSL_connect() will fail and we return earlier if verifypeer is set? */ diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index 1c1432d757..c7e4e793cc 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.c @@ -346,6 +346,8 @@ set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers) } #ifdef HAS_CLIENT_CERT_PATH + +/* Function allocates memory for store_path only if CURLE_OK is returned */ static CURLcode get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, TCHAR **thumbprint) @@ -388,16 +390,16 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, if(sep == NULL) return CURLE_SSL_CERTPROBLEM; + *thumbprint = sep + 1; + if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) + return CURLE_SSL_CERTPROBLEM; + *sep = TEXT('\0'); *store_path = _tcsdup(store_path_start); *sep = TEXT('\\'); if(*store_path == NULL) return CURLE_OUT_OF_MEMORY; - *thumbprint = sep + 1; - if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) - return CURLE_SSL_CERTPROBLEM; - return CURLE_OK; } #endif @@ -418,7 +420,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) SCHANNEL_CRED schannel_cred; PCCERT_CONTEXT client_certs[1] = { NULL }; SECURITY_STATUS sspi_status = SEC_E_OK; - struct curl_schannel_cred *old_cred = NULL; + struct Curl_schannel_cred *old_cred = NULL; struct in_addr addr; #ifdef ENABLE_IPV6 struct in6_addr addr6; @@ -588,7 +590,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) #ifdef HAS_CLIENT_CERT_PATH /* client certificate */ - if(data->set.ssl.cert || data->set.ssl.cert_blob) { + if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { DWORD cert_store_name = 0; TCHAR *cert_store_path = NULL; TCHAR *cert_thumbprint_str = NULL; @@ -598,27 +600,28 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) FILE *fInCert = NULL; void *certdata = NULL; size_t certsize = 0; - bool blob = data->set.ssl.cert_blob != NULL; + bool blob = data->set.ssl.primary.cert_blob != NULL; TCHAR *cert_path = NULL; if(blob) { - certdata = data->set.ssl.cert_blob->data; - certsize = data->set.ssl.cert_blob->len; + certdata = data->set.ssl.primary.cert_blob->data; + certsize = data->set.ssl.primary.cert_blob->len; } else { - cert_path = curlx_convert_UTF8_to_tchar(data->set.ssl.cert); + cert_path = curlx_convert_UTF8_to_tchar( + data->set.ssl.primary.clientcert); if(!cert_path) return CURLE_OUT_OF_MEMORY; result = get_cert_location(cert_path, &cert_store_name, &cert_store_path, &cert_thumbprint_str); - if(result && (data->set.ssl.cert[0]!='\0')) - fInCert = fopen(data->set.ssl.cert, "rb"); + if(result && (data->set.ssl.primary.clientcert[0]!='\0')) + fInCert = fopen(data->set.ssl.primary.clientcert, "rb"); if(result && !fInCert) { failf(data, "schannel: Failed to get certificate location" " or file for %s", - data->set.ssl.cert); + data->set.ssl.primary.clientcert); curlx_unicodefree(cert_path); return result; } @@ -628,7 +631,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) (!strcasecompare(data->set.ssl.cert_type, "P12"))) { failf(data, "schannel: certificate format compatibility error " " for %s", - blob ? "(memory blob)" : data->set.ssl.cert); + blob ? "(memory blob)" : data->set.ssl.primary.clientcert); curlx_unicodefree(cert_path); return CURLE_SSL_CERTPROBLEM; } @@ -643,7 +646,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) size_t pwd_len = 0; int str_w_len = 0; const char *cert_showfilename_error = blob ? - "(memory blob)" : data->set.ssl.cert; + "(memory blob)" : data->set.ssl.primary.clientcert; curlx_unicodefree(cert_path); if(fInCert) { long cert_tell = 0; @@ -664,7 +667,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) fclose(fInCert); if(!continue_reading) { failf(data, "schannel: Failed to read cert file %s", - data->set.ssl.cert); + data->set.ssl.primary.clientcert); free(certdata); return CURLE_SSL_CERTPROBLEM; } @@ -771,15 +774,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) CertCloseStore(cert_store, 0); } #else - if(data->set.ssl.cert) { + if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { failf(data, "schannel: client cert support not built in"); return CURLE_NOT_BUILT_IN; } #endif /* allocate memory for the re-usable credential handle */ - BACKEND->cred = (struct curl_schannel_cred *) - calloc(1, sizeof(struct curl_schannel_cred)); + BACKEND->cred = (struct Curl_schannel_cred *) + calloc(1, sizeof(struct Curl_schannel_cred)); if(!BACKEND->cred) { failf(data, "schannel: unable to allocate memory"); @@ -893,8 +896,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) ISC_REQ_STREAM; /* allocate memory for the security context handle */ - BACKEND->ctxt = (struct curl_schannel_ctxt *) - calloc(1, sizeof(struct curl_schannel_ctxt)); + BACKEND->ctxt = (struct Curl_schannel_ctxt *) + calloc(1, sizeof(struct Curl_schannel_ctxt)); if(!BACKEND->ctxt) { failf(data, "schannel: unable to allocate memory"); return CURLE_OUT_OF_MEMORY; @@ -1178,6 +1181,10 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) failf(data, "schannel: SNI or certificate check failed: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); return CURLE_PEER_FAILED_VERIFICATION; + case SEC_E_UNTRUSTED_ROOT: + failf(data, "schannel: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_PEER_FAILED_VERIFICATION; /* case SEC_E_INVALID_HANDLE: case SEC_E_INVALID_TOKEN: @@ -1401,7 +1408,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) /* save the current session data for possible re-use */ if(SSL_SET_OPTION(primary.sessionid)) { bool incache; - struct curl_schannel_cred *old_cred = NULL; + struct Curl_schannel_cred *old_cred = NULL; Curl_ssl_sessionid_lock(conn); incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, @@ -1417,7 +1424,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) } if(!incache) { result = Curl_ssl_addsessionid(conn, (void *)BACKEND->cred, - sizeof(struct curl_schannel_cred), + sizeof(struct Curl_schannel_cred), sockindex); if(result) { Curl_ssl_sessionid_unlock(conn); @@ -2099,7 +2106,7 @@ static void Curl_schannel_close(struct connectdata *conn, int sockindex) static void Curl_schannel_session_free(void *ptr) { /* this is expected to be called under sessionid lock */ - struct curl_schannel_cred *cred = ptr; + struct Curl_schannel_cred *cred = ptr; cred->refcount--; if(cred->refcount == 0) { diff --git a/libs/libcurl/src/vtls/schannel.h b/libs/libcurl/src/vtls/schannel.h index ee8d7d47ac..f87bae8ff0 100644 --- a/libs/libcurl/src/vtls/schannel.h +++ b/libs/libcurl/src/vtls/schannel.h @@ -8,7 +8,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al. - * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -70,20 +70,20 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex); #endif #endif -struct curl_schannel_cred { +struct Curl_schannel_cred { CredHandle cred_handle; TimeStamp time_stamp; int refcount; }; -struct curl_schannel_ctxt { +struct Curl_schannel_ctxt { CtxtHandle ctxt_handle; TimeStamp time_stamp; }; struct ssl_backend_data { - struct curl_schannel_cred *cred; - struct curl_schannel_ctxt *ctxt; + struct Curl_schannel_cred *cred; + struct Curl_schannel_ctxt *ctxt; SecPkgContext_StreamSizes stream_sizes; size_t encdata_length, decdata_length; size_t encdata_offset, decdata_offset; diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c index 2627aff16a..af63df46ae 100644 --- a/libs/libcurl/src/vtls/sectransp.c +++ b/libs/libcurl/src/vtls/sectransp.c @@ -1397,11 +1397,16 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); const struct curl_blob *ssl_cablob = NULL; const bool verifypeer = SSL_CONN_CONFIG(verifypeer); - char * const ssl_cert = SSL_SET_OPTION(cert); - const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob); + char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); + const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); +#ifndef CURL_DISABLE_PROXY const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; +#else + const char * const hostname = conn->host.name; + const long int port = conn->remote_port; +#endif #ifdef ENABLE_IPV6 struct in6_addr addr; #else @@ -1606,8 +1611,11 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, &kCFTypeArrayCallBacks); #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 && - (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) { + if(data->set.httpversion >= CURL_HTTP_VERSION_2 +#ifndef CURL_DISABLE_PROXY + && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) +#endif + ) { CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID)); infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); } @@ -2379,8 +2387,12 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex) OSStatus err; SSLCipherSuite cipher; SSLProtocol protocol = 0; +#ifndef CURL_DISABLE_PROXY const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; +#else + const char * const hostname = conn->host.name; +#endif DEBUGASSERT(ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c index 281043aa63..e65fb4f787 100644 --- a/libs/libcurl/src/vtls/vtls.c +++ b/libs/libcurl/src/vtls/vtls.c @@ -138,6 +138,7 @@ Curl_ssl_config_matches(struct ssl_primary_config *data, Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) && Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) && + Curl_safe_strcasecompare(data->curves, needle->curves) && Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key)) return TRUE; @@ -164,6 +165,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, CLONE_STRING(cipher_list); CLONE_STRING(cipher_list13); CLONE_STRING(pinned_key); + CLONE_STRING(curves); return TRUE; } @@ -179,6 +181,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) Curl_safefree(sslc->cipher_list13); Curl_safefree(sslc->pinned_key); Curl_safefree(sslc->cert_blob); + Curl_safefree(sslc->curves); } #ifdef USE_SSL @@ -362,7 +365,7 @@ bool Curl_ssl_getsessionid(struct connectdata *conn, size_t *idsize, /* set 0 if unknown */ int sockindex) { - struct curl_ssl_session *check; + struct Curl_ssl_session *check; struct Curl_easy *data = conn->data; size_t i; long *general_age; @@ -429,7 +432,7 @@ bool Curl_ssl_getsessionid(struct connectdata *conn, /* * Kill a single session ID entry in the cache. */ -void Curl_ssl_kill_session(struct curl_ssl_session *session) +void Curl_ssl_kill_session(struct Curl_ssl_session *session) { if(session->sessionid) { /* defensive check */ @@ -456,7 +459,7 @@ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid) struct Curl_easy *data = conn->data; for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) { - struct curl_ssl_session *check = &data->state.session[i]; + struct Curl_ssl_session *check = &data->state.session[i]; if(check->sessionid == ssl_sessionid) { Curl_ssl_kill_session(check); @@ -478,7 +481,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, { size_t i; struct Curl_easy *data = conn->data; /* the mother of all structs */ - struct curl_ssl_session *store = &data->state.session[0]; + struct Curl_ssl_session *store = &data->state.session[0]; long oldest_age = data->state.session[0].age; /* zero if unused */ char *clone_host; char *clone_conn_to_host; @@ -664,13 +667,13 @@ struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data) */ CURLcode Curl_ssl_initsessions(struct Curl_easy *data, size_t amount) { - struct curl_ssl_session *session; + struct Curl_ssl_session *session; if(data->state.session) /* this is just a precaution to prevent multiple inits */ return CURLE_OK; - session = calloc(amount, sizeof(struct curl_ssl_session)); + session = calloc(amount, sizeof(struct Curl_ssl_session)); if(!session) return CURLE_OUT_OF_MEMORY; diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index bcc8444161..b86bdbc1df 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -131,12 +131,26 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state) #define SSL_SET_OPTION(var) \ (SSL_IS_PROXY() ? data->set.proxy_ssl.var : data->set.ssl.var) +#define SSL_SET_OPTION_LVALUE(var) \ + (*(SSL_IS_PROXY() ? &data->set.proxy_ssl.var : &data->set.ssl.var)) #define SSL_CONN_CONFIG(var) \ (SSL_IS_PROXY() ? conn->proxy_ssl_config.var : conn->ssl_config.var) +#define SSL_HOST_NAME() \ + (SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name) +#define SSL_HOST_DISPNAME() \ + (SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname) +#define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \ + ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \ + : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) #else #define SSL_IS_PROXY() FALSE #define SSL_SET_OPTION(var) data->set.ssl.var +#define SSL_SET_OPTION_LVALUE(var) data->set.ssl.var #define SSL_CONN_CONFIG(var) conn->ssl_config.var +#define SSL_HOST_NAME() conn->host.name +#define SSL_HOST_DISPNAME() conn->host.dispname +#define SSL_PINNED_PUB_KEY() \ + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG] #endif bool Curl_ssl_config_matches(struct ssl_primary_config *data, @@ -221,7 +235,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, * take sessionid object ownership from sessionid cache * (e.g. decrement refcount). */ -void Curl_ssl_kill_session(struct curl_ssl_session *session); +void Curl_ssl_kill_session(struct Curl_ssl_session *session); /* delete a session from the cache * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock). * This will call engine-specific curlssl_session_free function, which must diff --git a/libs/libcurl/src/vtls/wolfssl.c b/libs/libcurl/src/vtls/wolfssl.c index 7b2a124e4f..a299b99d1f 100644 --- a/libs/libcurl/src/vtls/wolfssl.c +++ b/libs/libcurl/src/vtls/wolfssl.c @@ -353,8 +353,8 @@ wolfssl_connect_step1(struct connectdata *conn, SSL_CONN_CONFIG(CApath))) { if(SSL_CONN_CONFIG(verifypeer)) { /* Fail if we insist on successfully verifying the server. */ - failf(data, "error setting certificate verify locations:\n" - " CAfile: %s\n CApath: %s", + failf(data, "error setting certificate verify locations:" + " CAfile: %s CApath: %s", SSL_CONN_CONFIG(CAfile)? SSL_CONN_CONFIG(CAfile): "none", SSL_CONN_CONFIG(CApath)? @@ -372,21 +372,19 @@ wolfssl_connect_step1(struct connectdata *conn, /* Everything is fine. */ infof(data, "successfully set certificate verify locations:\n"); } - infof(data, - " CAfile: %s\n" - " CApath: %s\n", - SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): - "none", - SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath): - "none"); + infof(data, " CAfile: %s\n", + SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none"); + infof(data, " CApath: %s\n", + SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath) : "none"); } /* Load the client certificate, and private key */ - if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) { + if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) { int file_type = do_file_type(SSL_SET_OPTION(cert_type)); - if(SSL_CTX_use_certificate_file(backend->ctx, SSL_SET_OPTION(cert), - file_type) != 1) { + if(SSL_CTX_use_certificate_file(backend->ctx, + SSL_SET_OPTION(primary.clientcert), + file_type) != 1) { failf(data, "unable to use client certificate (no key or wrong pass" " phrase?)"); return CURLE_SSL_CONNECT_ERROR; diff --git a/libs/libcurl/src/wildcard.h b/libs/libcurl/src/wildcard.h index 306c8c99ff..f090826fb2 100644 --- a/libs/libcurl/src/wildcard.h +++ b/libs/libcurl/src/wildcard.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2010 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -39,18 +39,18 @@ typedef enum { CURLWC_ERROR, /* error cases */ CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop will end */ -} curl_wildcard_states; +} wildcard_states; -typedef void (*curl_wildcard_dtor)(void *ptr); +typedef void (*wildcard_dtor)(void *ptr); /* struct keeping information about wildcard download process */ struct WildcardData { - curl_wildcard_states state; + wildcard_states state; char *path; /* path to the directory, where we trying wildcard-match */ char *pattern; /* wildcard pattern */ - struct curl_llist filelist; /* llist with struct Curl_fileinfo */ + struct Curl_llist filelist; /* llist with struct Curl_fileinfo */ void *protdata; /* pointer to protocol specific temporary data */ - curl_wildcard_dtor dtor; + wildcard_dtor dtor; void *customptr; /* for CURLOPT_CHUNK_DATA pointer */ }; |