summaryrefslogtreecommitdiff
path: root/libs/libcurl/src
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src')
-rw-r--r--libs/libcurl/src/CMakeLists.txt6
-rw-r--r--libs/libcurl/src/Makefile.in154
-rw-r--r--libs/libcurl/src/Makefile.inc23
-rw-r--r--libs/libcurl/src/Makefile.m324
-rw-r--r--libs/libcurl/src/Makefile.netware3
-rw-r--r--libs/libcurl/src/altsvc.c254
-rw-r--r--libs/libcurl/src/altsvc.h9
-rw-r--r--libs/libcurl/src/asyn-ares.c19
-rw-r--r--libs/libcurl/src/asyn-thread.c42
-rw-r--r--libs/libcurl/src/config-dos.h3
-rw-r--r--libs/libcurl/src/config-plan9.h3
-rw-r--r--libs/libcurl/src/config-symbian.h5
-rw-r--r--libs/libcurl/src/config-tpf.h6
-rw-r--r--libs/libcurl/src/config-vxworks.h5
-rw-r--r--libs/libcurl/src/config-win32.h11
-rw-r--r--libs/libcurl/src/conncache.c14
-rw-r--r--libs/libcurl/src/conncache.h3
-rw-r--r--libs/libcurl/src/connect.c87
-rw-r--r--libs/libcurl/src/cookie.c63
-rw-r--r--libs/libcurl/src/curl_config.h.cmake9
-rw-r--r--libs/libcurl/src/curl_config.h.in9
-rw-r--r--libs/libcurl/src/curl_hmac.h9
-rw-r--r--libs/libcurl/src/curl_md4.h5
-rw-r--r--libs/libcurl/src/curl_md5.h6
-rw-r--r--libs/libcurl/src/curl_ntlm_core.c39
-rw-r--r--libs/libcurl/src/curl_ntlm_core.h10
-rw-r--r--libs/libcurl/src/curl_ntlm_wb.c103
-rw-r--r--libs/libcurl/src/curl_sasl.c16
-rw-r--r--libs/libcurl/src/curl_sha256.h9
-rw-r--r--libs/libcurl/src/doh.c4
-rw-r--r--libs/libcurl/src/easy.c92
-rw-r--r--libs/libcurl/src/formdata.c2
-rw-r--r--libs/libcurl/src/ftp.c52
-rw-r--r--libs/libcurl/src/ftp.h4
-rw-r--r--libs/libcurl/src/getenv.c47
-rw-r--r--libs/libcurl/src/hmac.c39
-rw-r--r--libs/libcurl/src/hostip.c82
-rw-r--r--libs/libcurl/src/hostip.h33
-rw-r--r--libs/libcurl/src/hostip4.c294
-rw-r--r--libs/libcurl/src/hostip6.c26
-rw-r--r--libs/libcurl/src/http.c29
-rw-r--r--libs/libcurl/src/http.h4
-rw-r--r--libs/libcurl/src/http2.c113
-rw-r--r--libs/libcurl/src/http2.h4
-rw-r--r--libs/libcurl/src/libcurl.plist6
-rw-r--r--libs/libcurl/src/llist.c53
-rw-r--r--libs/libcurl/src/llist.h5
-rw-r--r--libs/libcurl/src/md4.c60
-rw-r--r--libs/libcurl/src/md5.c69
-rw-r--r--libs/libcurl/src/mime.c2
-rw-r--r--libs/libcurl/src/mime.h2
-rw-r--r--libs/libcurl/src/mk-ca-bundle.pl62
-rw-r--r--libs/libcurl/src/multi.c39
-rw-r--r--libs/libcurl/src/multihandle.h13
-rw-r--r--libs/libcurl/src/multiif.h8
-rw-r--r--libs/libcurl/src/rename.c62
-rw-r--r--libs/libcurl/src/rename.h27
-rw-r--r--libs/libcurl/src/select.c215
-rw-r--r--libs/libcurl/src/select.h10
-rw-r--r--libs/libcurl/src/sendf.c19
-rw-r--r--libs/libcurl/src/setopt.c8
-rw-r--r--libs/libcurl/src/sha256.c193
-rw-r--r--libs/libcurl/src/smtp.c324
-rw-r--r--libs/libcurl/src/smtp.h7
-rw-r--r--libs/libcurl/src/socks.c1132
-rw-r--r--libs/libcurl/src/socks.h15
-rw-r--r--libs/libcurl/src/socks_gssapi.c6
-rw-r--r--libs/libcurl/src/socks_sspi.c5
-rw-r--r--libs/libcurl/src/strcase.c8
-rw-r--r--libs/libcurl/src/strcase.h3
-rw-r--r--libs/libcurl/src/strerror.c6
-rw-r--r--libs/libcurl/src/strerror.h4
-rw-r--r--libs/libcurl/src/system_win32.c4
-rw-r--r--libs/libcurl/src/timeval.c3
-rw-r--r--libs/libcurl/src/transfer.c5
-rw-r--r--libs/libcurl/src/url.c111
-rw-r--r--libs/libcurl/src/url.h7
-rw-r--r--libs/libcurl/src/urlapi.c68
-rw-r--r--libs/libcurl/src/urldata.h92
-rw-r--r--libs/libcurl/src/vauth/digest.c74
-rw-r--r--libs/libcurl/src/vauth/ntlm.c13
-rw-r--r--libs/libcurl/src/version.c6
-rw-r--r--libs/libcurl/src/vquic/ngtcp2.c34
-rw-r--r--libs/libcurl/src/vquic/quiche.c4
-rw-r--r--libs/libcurl/src/vssh/libssh.c101
-rw-r--r--libs/libcurl/src/vssh/libssh2.c133
-rw-r--r--libs/libcurl/src/vssh/ssh.h22
-rw-r--r--libs/libcurl/src/vssh/wolfssh.c1156
-rw-r--r--libs/libcurl/src/vtls/gtls.c6
-rw-r--r--libs/libcurl/src/vtls/mbedtls.c16
-rw-r--r--libs/libcurl/src/vtls/mbedtls_threadlock.c144
-rw-r--r--libs/libcurl/src/vtls/mbedtls_threadlock.h48
-rw-r--r--libs/libcurl/src/vtls/openssl.c32
-rw-r--r--libs/libcurl/src/vtls/schannel.c2
-rw-r--r--libs/libcurl/src/vtls/schannel_verify.c152
-rw-r--r--libs/libcurl/src/vtls/sectransp.c4
-rw-r--r--libs/libcurl/src/vtls/vtls.c46
-rw-r--r--libs/libcurl/src/vtls/vtls.h3
-rw-r--r--libs/libcurl/src/vtls/wolfssl.c12
99 files changed, 4495 insertions, 1920 deletions
diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt
index a9c90b6650..e73efb90af 100644
--- a/libs/libcurl/src/CMakeLists.txt
+++ b/libs/libcurl/src/CMakeLists.txt
@@ -96,6 +96,12 @@ endif()
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
+if(CURL_HAS_LTO)
+ set_target_properties(${LIB_NAME} PROPERTIES
+ INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
+ INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
+endif()
+
if(WIN32)
if(BUILD_SHARED_LIBS)
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in
index 9259841744..3fc95847d4 100644
--- a/libs/libcurl/src/Makefile.in
+++ b/libs/libcurl/src/Makefile.in
@@ -21,7 +21,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
@@ -229,7 +229,8 @@ am__objects_1 = libcurl_la-file.lo libcurl_la-timeval.lo \
libcurl_la-curl_path.lo libcurl_la-curl_ctype.lo \
libcurl_la-curl_range.lo libcurl_la-psl.lo libcurl_la-doh.lo \
libcurl_la-urlapi.lo libcurl_la-curl_get_line.lo \
- libcurl_la-altsvc.lo libcurl_la-socketpair.lo
+ libcurl_la-altsvc.lo libcurl_la-socketpair.lo \
+ libcurl_la-rename.lo
am__dirstamp = $(am__leading_dot)dirstamp
am__objects_2 = vauth/libcurl_la-vauth.lo \
vauth/libcurl_la-cleartext.lo vauth/libcurl_la-cram.lo \
@@ -240,15 +241,15 @@ am__objects_2 = vauth/libcurl_la-vauth.lo \
vauth/libcurl_la-spnego_sspi.lo
am__objects_3 = vtls/libcurl_la-openssl.lo vtls/libcurl_la-gtls.lo \
vtls/libcurl_la-vtls.lo vtls/libcurl_la-nss.lo \
- vtls/libcurl_la-polarssl.lo \
- vtls/libcurl_la-polarssl_threadlock.lo \
+ vtls/libcurl_la-mbedtls_threadlock.lo \
vtls/libcurl_la-wolfssl.lo vtls/libcurl_la-schannel.lo \
vtls/libcurl_la-schannel_verify.lo \
vtls/libcurl_la-sectransp.lo vtls/libcurl_la-gskit.lo \
vtls/libcurl_la-mbedtls.lo vtls/libcurl_la-mesalink.lo \
vtls/libcurl_la-bearssl.lo
am__objects_4 = vquic/libcurl_la-ngtcp2.lo vquic/libcurl_la-quiche.lo
-am__objects_5 = vssh/libcurl_la-libssh2.lo vssh/libcurl_la-libssh.lo
+am__objects_5 = vssh/libcurl_la-libssh2.lo vssh/libcurl_la-libssh.lo \
+ vssh/libcurl_la-wolfssh.lo
am__objects_6 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5)
am__objects_7 =
@@ -317,7 +318,7 @@ am__objects_9 = libcurlu_la-file.lo libcurlu_la-timeval.lo \
libcurlu_la-curl_ctype.lo libcurlu_la-curl_range.lo \
libcurlu_la-psl.lo libcurlu_la-doh.lo libcurlu_la-urlapi.lo \
libcurlu_la-curl_get_line.lo libcurlu_la-altsvc.lo \
- libcurlu_la-socketpair.lo
+ libcurlu_la-socketpair.lo libcurlu_la-rename.lo
am__objects_10 = vauth/libcurlu_la-vauth.lo \
vauth/libcurlu_la-cleartext.lo vauth/libcurlu_la-cram.lo \
vauth/libcurlu_la-digest.lo vauth/libcurlu_la-digest_sspi.lo \
@@ -328,8 +329,7 @@ am__objects_10 = vauth/libcurlu_la-vauth.lo \
vauth/libcurlu_la-spnego_sspi.lo
am__objects_11 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.lo \
vtls/libcurlu_la-vtls.lo vtls/libcurlu_la-nss.lo \
- vtls/libcurlu_la-polarssl.lo \
- vtls/libcurlu_la-polarssl_threadlock.lo \
+ vtls/libcurlu_la-mbedtls_threadlock.lo \
vtls/libcurlu_la-wolfssl.lo vtls/libcurlu_la-schannel.lo \
vtls/libcurlu_la-schannel_verify.lo \
vtls/libcurlu_la-sectransp.lo vtls/libcurlu_la-gskit.lo \
@@ -338,7 +338,7 @@ am__objects_11 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.lo \
am__objects_12 = vquic/libcurlu_la-ngtcp2.lo \
vquic/libcurlu_la-quiche.lo
am__objects_13 = vssh/libcurlu_la-libssh2.lo \
- vssh/libcurlu_la-libssh.lo
+ vssh/libcurlu_la-libssh.lo vssh/libcurlu_la-wolfssh.lo
am__objects_14 = $(am__objects_9) $(am__objects_10) $(am__objects_11) \
$(am__objects_12) $(am__objects_13)
am_libcurlu_la_OBJECTS = $(am__objects_14) $(am__objects_8)
@@ -438,6 +438,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
./$(DEPDIR)/libcurl_la-pop3.Plo \
./$(DEPDIR)/libcurl_la-progress.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 \
@@ -548,6 +549,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
./$(DEPDIR)/libcurlu_la-progress.Plo \
./$(DEPDIR)/libcurlu_la-psl.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 \
@@ -610,17 +612,18 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
vquic/$(DEPDIR)/libcurlu_la-quiche.Plo \
vssh/$(DEPDIR)/libcurl_la-libssh.Plo \
vssh/$(DEPDIR)/libcurl_la-libssh2.Plo \
+ vssh/$(DEPDIR)/libcurl_la-wolfssh.Plo \
vssh/$(DEPDIR)/libcurlu_la-libssh.Plo \
vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo \
+ vssh/$(DEPDIR)/libcurlu_la-wolfssh.Plo \
vtls/$(DEPDIR)/libcurl_la-bearssl.Plo \
vtls/$(DEPDIR)/libcurl_la-gskit.Plo \
vtls/$(DEPDIR)/libcurl_la-gtls.Plo \
vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo \
+ vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Plo \
vtls/$(DEPDIR)/libcurl_la-mesalink.Plo \
vtls/$(DEPDIR)/libcurl_la-nss.Plo \
vtls/$(DEPDIR)/libcurl_la-openssl.Plo \
- vtls/$(DEPDIR)/libcurl_la-polarssl.Plo \
- vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo \
vtls/$(DEPDIR)/libcurl_la-schannel.Plo \
vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo \
vtls/$(DEPDIR)/libcurl_la-sectransp.Plo \
@@ -630,11 +633,10 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \
vtls/$(DEPDIR)/libcurlu_la-gskit.Plo \
vtls/$(DEPDIR)/libcurlu_la-gtls.Plo \
vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo \
+ vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Plo \
vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo \
vtls/$(DEPDIR)/libcurlu_la-nss.Plo \
vtls/$(DEPDIR)/libcurlu_la-openssl.Plo \
- vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo \
- vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo \
vtls/$(DEPDIR)/libcurlu_la-schannel.Plo \
vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo \
vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo \
@@ -838,6 +840,7 @@ USE_SCHANNEL = @USE_SCHANNEL@
USE_SECTRANSP = @USE_SECTRANSP@
USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@
USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@
+USE_WOLFSSH = @USE_WOLFSSH@
USE_WOLFSSL = @USE_WOLFSSL@
VERSION = @VERSION@
VERSIONNUM = @VERSIONNUM@
@@ -978,19 +981,18 @@ LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \
LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
- vtls/polarssl.c vtls/polarssl_threadlock.c \
- vtls/wolfssl.c vtls/schannel.c vtls/schannel_verify.c \
- vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c \
- vtls/bearssl.c
+ vtls/mbedtls_threadlock.c vtls/wolfssl.c vtls/schannel.c \
+ vtls/schannel_verify.c vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c \
+ vtls/mesalink.c vtls/bearssl.c
-LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
- vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \
- vtls/wolfssl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \
- vtls/mbedtls.h vtls/mesalink.h vtls/bearssl.h
+LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h vtls/nssg.h \
+ vtls/mbedtls_threadlock.h vtls/wolfssl.h vtls/schannel.h \
+ vtls/sectransp.h vtls/gskit.h vtls/mbedtls.h vtls/mesalink.h \
+ vtls/bearssl.h
LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
-LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c
+LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c vssh/wolfssh.c
LIB_VSSH_HFILES = vssh/ssh.h
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
@@ -1010,7 +1012,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
curl_multibyte.c hostcheck.c conncache.c dotdot.c \
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \
- doh.c urlapi.c curl_get_line.c altsvc.c socketpair.c
+ doh.c urlapi.c curl_get_line.c altsvc.c socketpair.c rename.c
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
@@ -1031,7 +1033,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \
curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \
- curl_get_line.h altsvc.h quic.h socketpair.h
+ curl_get_line.h altsvc.h quic.h socketpair.h rename.h
LIB_RCFILES = libcurl.rc
CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \
@@ -1194,9 +1196,7 @@ vtls/libcurl_la-vtls.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurl_la-nss.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
-vtls/libcurl_la-polarssl.lo: vtls/$(am__dirstamp) \
- vtls/$(DEPDIR)/$(am__dirstamp)
-vtls/libcurl_la-polarssl_threadlock.lo: vtls/$(am__dirstamp) \
+vtls/libcurl_la-mbedtls_threadlock.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurl_la-wolfssl.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
@@ -1234,6 +1234,8 @@ vssh/libcurl_la-libssh2.lo: vssh/$(am__dirstamp) \
vssh/$(DEPDIR)/$(am__dirstamp)
vssh/libcurl_la-libssh.lo: vssh/$(am__dirstamp) \
vssh/$(DEPDIR)/$(am__dirstamp)
+vssh/libcurl_la-wolfssh.lo: vssh/$(am__dirstamp) \
+ vssh/$(DEPDIR)/$(am__dirstamp)
libcurl.la: $(libcurl_la_OBJECTS) $(libcurl_la_DEPENDENCIES) $(EXTRA_libcurl_la_DEPENDENCIES)
$(AM_V_CCLD)$(libcurl_la_LINK) -rpath $(libdir) $(libcurl_la_OBJECTS) $(libcurl_la_LIBADD) $(LIBS)
@@ -1269,9 +1271,7 @@ vtls/libcurlu_la-vtls.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurlu_la-nss.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
-vtls/libcurlu_la-polarssl.lo: vtls/$(am__dirstamp) \
- vtls/$(DEPDIR)/$(am__dirstamp)
-vtls/libcurlu_la-polarssl_threadlock.lo: vtls/$(am__dirstamp) \
+vtls/libcurlu_la-mbedtls_threadlock.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
vtls/libcurlu_la-wolfssl.lo: vtls/$(am__dirstamp) \
vtls/$(DEPDIR)/$(am__dirstamp)
@@ -1297,6 +1297,8 @@ vssh/libcurlu_la-libssh2.lo: vssh/$(am__dirstamp) \
vssh/$(DEPDIR)/$(am__dirstamp)
vssh/libcurlu_la-libssh.lo: vssh/$(am__dirstamp) \
vssh/$(DEPDIR)/$(am__dirstamp)
+vssh/libcurlu_la-wolfssh.lo: vssh/$(am__dirstamp) \
+ vssh/$(DEPDIR)/$(am__dirstamp)
libcurlu.la: $(libcurlu_la_OBJECTS) $(libcurlu_la_DEPENDENCIES) $(EXTRA_libcurlu_la_DEPENDENCIES)
$(AM_V_CCLD)$(libcurlu_la_LINK) $(am_libcurlu_la_rpath) $(libcurlu_la_OBJECTS) $(libcurlu_la_LIBADD) $(LIBS)
@@ -1394,6 +1396,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-progress.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-psl.Plo@am__quote@ # am--include-marker
@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
@@ -1505,6 +1508,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-progress.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-psl.Plo@am__quote@ # am--include-marker
@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
@@ -1567,17 +1571,18 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@vquic/$(DEPDIR)/libcurlu_la-quiche.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurl_la-libssh.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurl_la-libssh2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurl_la-wolfssh.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurlu_la-libssh.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurlu_la-wolfssh.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-bearssl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gskit.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gtls.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mesalink.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-nss.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-openssl.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-polarssl.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-sectransp.Plo@am__quote@ # am--include-marker
@@ -1587,11 +1592,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gskit.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gtls.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-nss.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-openssl.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo@am__quote@ # am--include-marker
@@ -2405,6 +2409,13 @@ libcurl_la-socketpair.lo: socketpair.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-socketpair.lo `test -f 'socketpair.c' || echo '$(srcdir)/'`socketpair.c
+libcurl_la-rename.lo: rename.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-rename.lo -MD -MP -MF $(DEPDIR)/libcurl_la-rename.Tpo -c -o libcurl_la-rename.lo `test -f 'rename.c' || echo '$(srcdir)/'`rename.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-rename.Tpo $(DEPDIR)/libcurl_la-rename.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rename.c' object='libcurl_la-rename.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-rename.lo `test -f 'rename.c' || echo '$(srcdir)/'`rename.c
+
vauth/libcurl_la-vauth.lo: vauth/vauth.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-vauth.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-vauth.Tpo -c -o vauth/libcurl_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-vauth.Tpo vauth/$(DEPDIR)/libcurl_la-vauth.Plo
@@ -2517,19 +2528,12 @@ vtls/libcurl_la-nss.lo: vtls/nss.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-nss.lo `test -f 'vtls/nss.c' || echo '$(srcdir)/'`vtls/nss.c
-vtls/libcurl_la-polarssl.lo: vtls/polarssl.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-polarssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-polarssl.Tpo -c -o vtls/libcurl_la-polarssl.lo `test -f 'vtls/polarssl.c' || echo '$(srcdir)/'`vtls/polarssl.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-polarssl.Tpo vtls/$(DEPDIR)/libcurl_la-polarssl.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/polarssl.c' object='vtls/libcurl_la-polarssl.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-polarssl.lo `test -f 'vtls/polarssl.c' || echo '$(srcdir)/'`vtls/polarssl.c
-
-vtls/libcurl_la-polarssl_threadlock.lo: vtls/polarssl_threadlock.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-polarssl_threadlock.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Tpo -c -o vtls/libcurl_la-polarssl_threadlock.lo `test -f 'vtls/polarssl_threadlock.c' || echo '$(srcdir)/'`vtls/polarssl_threadlock.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Tpo vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/polarssl_threadlock.c' object='vtls/libcurl_la-polarssl_threadlock.lo' libtool=yes @AMDEPBACKSLASH@
+vtls/libcurl_la-mbedtls_threadlock.lo: vtls/mbedtls_threadlock.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-mbedtls_threadlock.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Tpo -c -o vtls/libcurl_la-mbedtls_threadlock.lo `test -f 'vtls/mbedtls_threadlock.c' || echo '$(srcdir)/'`vtls/mbedtls_threadlock.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Tpo vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/mbedtls_threadlock.c' object='vtls/libcurl_la-mbedtls_threadlock.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-polarssl_threadlock.lo `test -f 'vtls/polarssl_threadlock.c' || echo '$(srcdir)/'`vtls/polarssl_threadlock.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-mbedtls_threadlock.lo `test -f 'vtls/mbedtls_threadlock.c' || echo '$(srcdir)/'`vtls/mbedtls_threadlock.c
vtls/libcurl_la-wolfssl.lo: vtls/wolfssl.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-wolfssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-wolfssl.Tpo -c -o vtls/libcurl_la-wolfssl.lo `test -f 'vtls/wolfssl.c' || echo '$(srcdir)/'`vtls/wolfssl.c
@@ -2615,6 +2619,13 @@ vssh/libcurl_la-libssh.lo: vssh/libssh.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 vssh/libcurl_la-libssh.lo `test -f 'vssh/libssh.c' || echo '$(srcdir)/'`vssh/libssh.c
+vssh/libcurl_la-wolfssh.lo: vssh/wolfssh.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 vssh/libcurl_la-wolfssh.lo -MD -MP -MF vssh/$(DEPDIR)/libcurl_la-wolfssh.Tpo -c -o vssh/libcurl_la-wolfssh.lo `test -f 'vssh/wolfssh.c' || echo '$(srcdir)/'`vssh/wolfssh.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vssh/$(DEPDIR)/libcurl_la-wolfssh.Tpo vssh/$(DEPDIR)/libcurl_la-wolfssh.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vssh/wolfssh.c' object='vssh/libcurl_la-wolfssh.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 vssh/libcurl_la-wolfssh.lo `test -f 'vssh/wolfssh.c' || echo '$(srcdir)/'`vssh/wolfssh.c
+
libcurlu_la-file.lo: file.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-file.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-file.Tpo -c -o libcurlu_la-file.lo `test -f 'file.c' || echo '$(srcdir)/'`file.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-file.Tpo $(DEPDIR)/libcurlu_la-file.Plo
@@ -3392,6 +3403,13 @@ libcurlu_la-socketpair.lo: socketpair.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-socketpair.lo `test -f 'socketpair.c' || echo '$(srcdir)/'`socketpair.c
+libcurlu_la-rename.lo: rename.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-rename.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-rename.Tpo -c -o libcurlu_la-rename.lo `test -f 'rename.c' || echo '$(srcdir)/'`rename.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-rename.Tpo $(DEPDIR)/libcurlu_la-rename.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rename.c' object='libcurlu_la-rename.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-rename.lo `test -f 'rename.c' || echo '$(srcdir)/'`rename.c
+
vauth/libcurlu_la-vauth.lo: vauth/vauth.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-vauth.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-vauth.Tpo -c -o vauth/libcurlu_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-vauth.Tpo vauth/$(DEPDIR)/libcurlu_la-vauth.Plo
@@ -3504,19 +3522,12 @@ vtls/libcurlu_la-nss.lo: vtls/nss.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-nss.lo `test -f 'vtls/nss.c' || echo '$(srcdir)/'`vtls/nss.c
-vtls/libcurlu_la-polarssl.lo: vtls/polarssl.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-polarssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-polarssl.Tpo -c -o vtls/libcurlu_la-polarssl.lo `test -f 'vtls/polarssl.c' || echo '$(srcdir)/'`vtls/polarssl.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-polarssl.Tpo vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/polarssl.c' object='vtls/libcurlu_la-polarssl.lo' libtool=yes @AMDEPBACKSLASH@
+vtls/libcurlu_la-mbedtls_threadlock.lo: vtls/mbedtls_threadlock.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-mbedtls_threadlock.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Tpo -c -o vtls/libcurlu_la-mbedtls_threadlock.lo `test -f 'vtls/mbedtls_threadlock.c' || echo '$(srcdir)/'`vtls/mbedtls_threadlock.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Tpo vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/mbedtls_threadlock.c' object='vtls/libcurlu_la-mbedtls_threadlock.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-polarssl.lo `test -f 'vtls/polarssl.c' || echo '$(srcdir)/'`vtls/polarssl.c
-
-vtls/libcurlu_la-polarssl_threadlock.lo: vtls/polarssl_threadlock.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-polarssl_threadlock.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Tpo -c -o vtls/libcurlu_la-polarssl_threadlock.lo `test -f 'vtls/polarssl_threadlock.c' || echo '$(srcdir)/'`vtls/polarssl_threadlock.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Tpo vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/polarssl_threadlock.c' object='vtls/libcurlu_la-polarssl_threadlock.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-polarssl_threadlock.lo `test -f 'vtls/polarssl_threadlock.c' || echo '$(srcdir)/'`vtls/polarssl_threadlock.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-mbedtls_threadlock.lo `test -f 'vtls/mbedtls_threadlock.c' || echo '$(srcdir)/'`vtls/mbedtls_threadlock.c
vtls/libcurlu_la-wolfssl.lo: vtls/wolfssl.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-wolfssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-wolfssl.Tpo -c -o vtls/libcurlu_la-wolfssl.lo `test -f 'vtls/wolfssl.c' || echo '$(srcdir)/'`vtls/wolfssl.c
@@ -3602,6 +3613,13 @@ vssh/libcurlu_la-libssh.lo: vssh/libssh.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 vssh/libcurlu_la-libssh.lo `test -f 'vssh/libssh.c' || echo '$(srcdir)/'`vssh/libssh.c
+vssh/libcurlu_la-wolfssh.lo: vssh/wolfssh.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 vssh/libcurlu_la-wolfssh.lo -MD -MP -MF vssh/$(DEPDIR)/libcurlu_la-wolfssh.Tpo -c -o vssh/libcurlu_la-wolfssh.lo `test -f 'vssh/wolfssh.c' || echo '$(srcdir)/'`vssh/wolfssh.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vssh/$(DEPDIR)/libcurlu_la-wolfssh.Tpo vssh/$(DEPDIR)/libcurlu_la-wolfssh.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vssh/wolfssh.c' object='vssh/libcurlu_la-wolfssh.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 vssh/libcurlu_la-wolfssh.lo `test -f 'vssh/wolfssh.c' || echo '$(srcdir)/'`vssh/wolfssh.c
+
mostlyclean-libtool:
-rm -f *.lo
@@ -3828,6 +3846,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libcurl_la-progress.Plo
-rm -f ./$(DEPDIR)/libcurl_la-psl.Plo
-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
@@ -3939,6 +3958,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libcurlu_la-progress.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-psl.Plo
-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
@@ -4001,17 +4021,18 @@ distclean: distclean-am
-rm -f vquic/$(DEPDIR)/libcurlu_la-quiche.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-libssh.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo
+ -rm -f vssh/$(DEPDIR)/libcurl_la-wolfssh.Plo
-rm -f vssh/$(DEPDIR)/libcurlu_la-libssh.Plo
-rm -f vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo
+ -rm -f vssh/$(DEPDIR)/libcurlu_la-wolfssh.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-bearssl.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo
+ -rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mesalink.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-nss.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-openssl.Plo
- -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl.Plo
- -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-schannel.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo
@@ -4021,11 +4042,10 @@ distclean: distclean-am
-rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo
+ -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-nss.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-openssl.Plo
- -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo
- -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-schannel.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo
@@ -4155,6 +4175,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libcurl_la-progress.Plo
-rm -f ./$(DEPDIR)/libcurl_la-psl.Plo
-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
@@ -4266,6 +4287,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libcurlu_la-progress.Plo
-rm -f ./$(DEPDIR)/libcurlu_la-psl.Plo
-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
@@ -4328,17 +4350,18 @@ maintainer-clean: maintainer-clean-am
-rm -f vquic/$(DEPDIR)/libcurlu_la-quiche.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-libssh.Plo
-rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo
+ -rm -f vssh/$(DEPDIR)/libcurl_la-wolfssh.Plo
-rm -f vssh/$(DEPDIR)/libcurlu_la-libssh.Plo
-rm -f vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo
+ -rm -f vssh/$(DEPDIR)/libcurlu_la-wolfssh.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-bearssl.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo
+ -rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-mesalink.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-nss.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-openssl.Plo
- -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl.Plo
- -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-schannel.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo
-rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo
@@ -4348,11 +4371,10 @@ maintainer-clean: maintainer-clean-am
-rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo
+ -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-nss.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-openssl.Plo
- -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo
- -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-schannel.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo
-rm -f vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo
diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc
index 6c90c26752..46ded90bb6 100644
--- a/libs/libcurl/src/Makefile.inc
+++ b/libs/libcurl/src/Makefile.inc
@@ -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
@@ -28,21 +28,20 @@ LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \
LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
- vtls/polarssl.c vtls/polarssl_threadlock.c \
- vtls/wolfssl.c vtls/schannel.c vtls/schannel_verify.c \
- vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c \
- vtls/bearssl.c
+ vtls/mbedtls_threadlock.c vtls/wolfssl.c vtls/schannel.c \
+ vtls/schannel_verify.c vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c \
+ vtls/mesalink.c vtls/bearssl.c
-LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
- vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \
- vtls/wolfssl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \
- vtls/mbedtls.h vtls/mesalink.h vtls/bearssl.h
+LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h vtls/nssg.h \
+ vtls/mbedtls_threadlock.h vtls/wolfssl.h vtls/schannel.h \
+ vtls/sectransp.h vtls/gskit.h vtls/mbedtls.h vtls/mesalink.h \
+ vtls/bearssl.h
LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
-LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c
+LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c vssh/wolfssh.c
LIB_VSSH_HFILES = vssh/ssh.h
@@ -64,7 +63,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
curl_multibyte.c hostcheck.c conncache.c dotdot.c \
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \
- doh.c urlapi.c curl_get_line.c altsvc.c socketpair.c
+ doh.c urlapi.c curl_get_line.c altsvc.c socketpair.c rename.c
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
@@ -85,7 +84,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \
curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \
- curl_get_line.h altsvc.h quic.h socketpair.h
+ curl_get_line.h altsvc.h quic.h socketpair.h rename.h
LIB_RCFILES = libcurl.rc
diff --git a/libs/libcurl/src/Makefile.m32 b/libs/libcurl/src/Makefile.m32
index b6ef0a5cbd..ac6b3de631 100644
--- a/libs/libcurl/src/Makefile.m32
+++ b/libs/libcurl/src/Makefile.m32
@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1999 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1999 - 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
@@ -270,7 +270,7 @@ ifdef SSL
OPENSSL_LIBS += -lgdi32 -lcrypt32
endif
INCLUDES += -I"$(OPENSSL_INCLUDE)"
- CFLAGS += -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \
+ CFLAGS += -DUSE_OPENSSL -DHAVE_OPENSSL_PKCS12_H \
-DOPENSSL_NO_KRB5
DLL_LIBS += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS)
ifdef SRP
diff --git a/libs/libcurl/src/Makefile.netware b/libs/libcurl/src/Makefile.netware
index a40534684d..752d3d6fba 100644
--- a/libs/libcurl/src/Makefile.netware
+++ b/libs/libcurl/src/Makefile.netware
@@ -6,7 +6,7 @@
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2004 - 2015, Guenter Knauf
-# Copyright (C) 2001 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 2001 - 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
@@ -639,7 +639,6 @@ ifdef WITH_SSL
@echo $(DL)#define HAVE_OPENSSL_PEM_H 1$(DL) >> $@
@echo $(DL)#define HAVE_OPENSSL_ERR_H 1$(DL) >> $@
@echo $(DL)#define HAVE_OPENSSL_CRYPTO_H 1$(DL) >> $@
- @echo $(DL)#define HAVE_OPENSSL_ENGINE_H 1$(DL) >> $@
@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@
ifdef WITH_SRP
@echo $(DL)#define USE_TLS_SRP 1$(DL) >> $@
diff --git a/libs/libcurl/src/altsvc.c b/libs/libcurl/src/altsvc.c
index bf869c37a5..c39d86eaff 100644
--- a/libs/libcurl/src/altsvc.c
+++ b/libs/libcurl/src/altsvc.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
@@ -34,6 +34,8 @@
#include "parsedate.h"
#include "sendf.h"
#include "warnless.h"
+#include "rand.h"
+#include "rename.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -48,19 +50,20 @@
#define MAX_ALTSVC_ALPNLENSTR "10"
#define MAX_ALTSVC_ALPNLEN 10
+#if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS)
+#define H3VERSION "h3-27"
+#else
+#define H3VERSION "h3"
+#endif
+
static enum alpnid alpn2alpnid(char *name)
{
if(strcasecompare(name, "h1"))
return ALPN_h1;
if(strcasecompare(name, "h2"))
return ALPN_h2;
-#if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS)
- if(strcasecompare(name, "h3-24"))
- return ALPN_h3;
-#else
- if(strcasecompare(name, "h3"))
+ if(strcasecompare(name, H3VERSION))
return ALPN_h3;
-#endif
return ALPN_none; /* unknown, probably rubbish input */
}
@@ -73,11 +76,7 @@ const char *Curl_alpnid2str(enum alpnid id)
case ALPN_h2:
return "h2";
case ALPN_h3:
-#if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS)
- return "h3-24";
-#else
- return "h3";
-#endif
+ return H3VERSION;
default:
return ""; /* bad */
}
@@ -188,7 +187,16 @@ static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
{
CURLcode result = CURLE_OK;
char *line = NULL;
- FILE *fp = fopen(file, FOPEN_READTEXT);
+ FILE *fp;
+
+ /* we need a private copy of the file name so that the altsvc cache file
+ name survives an easy handle reset */
+ free(asi->filename);
+ asi->filename = strdup(file);
+ if(!asi->filename)
+ return CURLE_OUT_OF_MEMORY;
+
+ fp = fopen(file, FOPEN_READTEXT);
if(fp) {
line = malloc(MAX_ALTSVC_LINE);
if(!line)
@@ -209,6 +217,7 @@ static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
return result;
fail:
+ Curl_safefree(asi->filename);
free(line);
fclose(fp);
return CURLE_OUT_OF_MEMORY;
@@ -302,6 +311,7 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
n = e->next;
altsvc_free(as);
}
+ free(altsvc->filename);
free(altsvc);
}
}
@@ -309,34 +319,57 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
/*
* Curl_altsvc_save() writes the altsvc cache to a file.
*/
-CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file)
+CURLcode Curl_altsvc_save(struct Curl_easy *data,
+ struct altsvcinfo *altsvc, const char *file)
{
struct curl_llist_element *e;
struct curl_llist_element *n;
CURLcode result = CURLE_OK;
FILE *out;
+ char *tempstore;
+ unsigned char randsuffix[9];
if(!altsvc)
/* no cache activated */
return CURLE_OK;
+ /* if not new name is given, use the one we stored from the load */
+ if(!file && altsvc->filename)
+ file = altsvc->filename;
+
if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0])
/* marked as read-only, no file or zero length file name */
return CURLE_OK;
- out = fopen(file, FOPEN_WRITETEXT);
+
+ if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
+ return CURLE_FAILED_INIT;
+
+ tempstore = aprintf("%s.%s.tmp", file, randsuffix);
+ if(!tempstore)
+ return CURLE_OUT_OF_MEMORY;
+
+ out = fopen(tempstore, FOPEN_WRITETEXT);
if(!out)
- return CURLE_WRITE_ERROR;
- fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
- "# This file was generated by libcurl! Edit at your own risk.\n",
- out);
- for(e = altsvc->list.head; e; e = n) {
- struct altsvc *as = e->ptr;
- n = e->next;
- result = altsvc_out(as, out);
+ result = CURLE_WRITE_ERROR;
+ else {
+ fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
+ "# This file was generated by libcurl! Edit at your own risk.\n",
+ out);
+ for(e = altsvc->list.head; e; e = n) {
+ struct altsvc *as = e->ptr;
+ n = e->next;
+ result = altsvc_out(as, out);
+ if(result)
+ break;
+ }
+ fclose(out);
+ if(!result && Curl_rename(tempstore, file))
+ result = CURLE_WRITE_ERROR;
+
if(result)
- break;
+ unlink(tempstore);
}
- fclose(out);
+ free(tempstore);
return result;
}
@@ -351,12 +384,12 @@ static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
while(*p && !ISBLANK(*p) && (*p != ';') && (*p != '='))
p++;
len = p - protop;
+ *ptr = p;
if(!len || (len >= buflen))
return CURLE_BAD_FUNCTION_ARGUMENT;
memcpy(alpnbuf, protop, len);
alpnbuf[len] = 0;
- *ptr = p;
return CURLE_OK;
}
@@ -402,6 +435,10 @@ static time_t debugtime(void *unused)
*
* 'value' points to the header *value*. That's contents to the right of the
* header name.
+ *
+ * Currently this function rejects invalid data without returning an error.
+ * Invalid host name, port number will result in the specific alternative
+ * being rejected. Unknown protocols are skipped.
*/
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
struct altsvcinfo *asi, const char *value,
@@ -415,12 +452,11 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
struct altsvc *as;
unsigned short dstport = srcport; /* the same by default */
- const char *semip;
- time_t maxage = 24 * 3600; /* default is 24 hours */
- bool persist = FALSE;
CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
- if(result)
- return result;
+ if(result) {
+ infof(data, "Excessive alt-svc header, ignoring...\n");
+ return CURLE_OK;
+ }
DEBUGASSERT(asi);
@@ -432,57 +468,20 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
return CURLE_OK;
}
- /* The 'ma' and 'persist' flags are annoyingly meant for all alternatives
- but are set after the list on the line. Scan for the semicolons and get
- those fields first! */
- semip = p;
- do {
- semip = strchr(semip, ';');
- if(semip) {
- char option[32];
- unsigned long num;
- char *end_ptr;
- bool quoted = FALSE;
- semip++; /* pass the semicolon */
- result = getalnum(&semip, option, sizeof(option));
- if(result)
- break;
- while(*semip && ISBLANK(*semip))
- semip++;
- if(*semip != '=')
- continue;
- semip++;
- while(*semip && ISBLANK(*semip))
- semip++;
- if(*semip == '\"') {
- /* quoted value */
- semip++;
- quoted = TRUE;
- }
- num = strtoul(semip, &end_ptr, 10);
- if((end_ptr != semip) && num && (num < ULONG_MAX)) {
- if(strcasecompare("ma", option))
- maxage = num;
- else if(strcasecompare("persist", option) && (num == 1))
- persist = TRUE;
- if(quoted && (*end_ptr == '\"'))
- end_ptr++;
- }
- semip = end_ptr;
- }
- } while(semip);
-
do {
if(*p == '=') {
/* [protocol]="[host][:port]" */
dstalpnid = alpn2alpnid(alpnbuf);
- if(!dstalpnid) {
- infof(data, "Unknown alt-svc protocol \"%s\", ignoring...\n", alpnbuf);
- return CURLE_OK;
- }
p++;
if(*p == '\"') {
const char *dsthost;
+ const char *value_ptr;
+ char option[32];
+ unsigned long num;
+ char *end_ptr;
+ bool quoted = FALSE;
+ time_t maxage = 24 * 3600; /* default is 24 hours */
+ bool persist = FALSE;
p++;
if(*p != ':') {
/* host name starts here */
@@ -490,11 +489,15 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
p++;
len = p - hostp;
- if(!len || (len >= MAX_ALTSVC_HOSTLEN))
- return CURLE_BAD_FUNCTION_ARGUMENT;
- memcpy(namebuf, hostp, len);
- namebuf[len] = 0;
- dsthost = namebuf;
+ if(!len || (len >= MAX_ALTSVC_HOSTLEN)) {
+ infof(data, "Excessive alt-svc host name, ignoring...\n");
+ dstalpnid = ALPN_none;
+ }
+ else {
+ memcpy(namebuf, hostp, len);
+ namebuf[len] = 0;
+ dsthost = namebuf;
+ }
}
else {
/* no destination name, use source host */
@@ -502,31 +505,86 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
}
if(*p == ':') {
/* a port number */
- char *end_ptr;
unsigned long port = strtoul(++p, &end_ptr, 10);
if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
infof(data, "Unknown alt-svc port number, ignoring...\n");
- return CURLE_OK;
+ dstalpnid = ALPN_none;
}
p = end_ptr;
dstport = curlx_ultous(port);
}
if(*p++ != '\"')
- return CURLE_BAD_FUNCTION_ARGUMENT;
- as = altsvc_createid(srchost, dsthost,
- srcalpnid, dstalpnid,
- srcport, dstport);
- if(as) {
- /* The expires time also needs to take the Age: value (if any) into
- account. [See RFC 7838 section 3.1] */
- as->expires = maxage + time(NULL);
- as->persist = persist;
- Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
- asi->num++; /* one more entry */
- infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
- Curl_alpnid2str(dstalpnid));
+ break;
+ /* Handle the optional 'ma' and 'persist' flags. Unknown flags
+ are skipped. */
+ for(;;) {
+ while(*p && ISBLANK(*p) && *p != ';' && *p != ',')
+ p++;
+ if(!*p || *p == ',')
+ break;
+ p++; /* pass the semicolon */
+ if(!*p)
+ break;
+ result = getalnum(&p, option, sizeof(option));
+ if(result) {
+ /* skip option if name is too long */
+ option[0] = '\0';
+ }
+ while(*p && ISBLANK(*p))
+ p++;
+ if(*p != '=')
+ return CURLE_OK;
+ p++;
+ while(*p && ISBLANK(*p))
+ p++;
+ if(!*p)
+ return CURLE_OK;
+ if(*p == '\"') {
+ /* quoted value */
+ p++;
+ quoted = TRUE;
+ }
+ value_ptr = p;
+ if(quoted) {
+ while(*p && *p != '\"')
+ p++;
+ if(!*p++)
+ return CURLE_OK;
+ }
+ else {
+ while(*p && !ISBLANK(*p) && *p!= ';' && *p != ',')
+ p++;
+ }
+ num = strtoul(value_ptr, &end_ptr, 10);
+ if((end_ptr != value_ptr) && (num < ULONG_MAX)) {
+ if(strcasecompare("ma", option))
+ maxage = num;
+ else if(strcasecompare("persist", option) && (num == 1))
+ persist = TRUE;
+ }
+ }
+ if(dstalpnid) {
+ as = altsvc_createid(srchost, dsthost,
+ srcalpnid, dstalpnid,
+ srcport, dstport);
+ if(as) {
+ /* The expires time also needs to take the Age: value (if any) into
+ account. [See RFC 7838 section 3.1] */
+ as->expires = maxage + time(NULL);
+ as->persist = persist;
+ Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
+ asi->num++; /* one more entry */
+ infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
+ Curl_alpnid2str(dstalpnid));
+ }
+ }
+ else {
+ infof(data, "Unknown alt-svc protocol \"%s\", skipping...\n",
+ alpnbuf);
}
}
+ else
+ break;
/* after the double quote there can be a comma if there's another
string or a semicolon if no more */
if(*p == ',') {
@@ -534,11 +592,11 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
p++;
result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
if(result)
- /* failed to parse, but since we already did at least one host we
- return OK */
- return CURLE_OK;
+ break;
}
}
+ else
+ break;
} while(*p && (*p != ';') && (*p != '\n') && (*p != '\r'));
return CURLE_OK;
diff --git a/libs/libcurl/src/altsvc.h b/libs/libcurl/src/altsvc.h
index 99d0499af7..248e71eef8 100644
--- a/libs/libcurl/src/altsvc.h
+++ b/libs/libcurl/src/altsvc.h
@@ -7,7 +7,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
@@ -59,7 +59,8 @@ struct altsvcinfo {
const char *Curl_alpnid2str(enum alpnid id);
struct altsvcinfo *Curl_altsvc_init(void);
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
-CURLcode Curl_altsvc_save(struct altsvcinfo *asi, const char *file);
+CURLcode Curl_altsvc_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);
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
@@ -70,9 +71,9 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
enum alpnid srcalpnid, const char *srchost,
int srcport,
struct altsvc **dstentry,
- int versions); /* one or more CURLALTSVC_H* bits */
+ const int versions); /* CURLALTSVC_H* bits */
#else
/* disabled */
-#define Curl_altsvc_save(a,b)
+#define Curl_altsvc_save(a,b,c)
#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 835cfa48fa..b76e66548e 100644
--- a/libs/libcurl/src/asyn-ares.c
+++ b/libs/libcurl/src/asyn-ares.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
@@ -626,26 +626,11 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
{
char *bufp;
struct Curl_easy *data = conn->data;
- struct in_addr in;
int family = PF_INET;
-#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
- struct in6_addr in6;
-#endif /* CURLRES_IPV6 */
*waitp = 0; /* default to synchronous response */
- /* First check if this is an IPv4 address string */
- if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
- /* This is a dotted IP address 123.123.123.123-style */
- return Curl_ip2addr(AF_INET, &in, hostname, port);
- }
-
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
- /* Otherwise, check if this is an IPv6 address string */
- if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
- /* This must be an IPv6 address literal. */
- return Curl_ip2addr(AF_INET6, &in6, hostname, port);
-
switch(conn->ip_version) {
default:
#if ARES_VERSION >= 0x010601
@@ -684,7 +669,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
res->last_status = ARES_ENOTFOUND;
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
if(family == PF_UNSPEC) {
- if(Curl_ipv6works()) {
+ if(Curl_ipv6works(conn)) {
res->num_pending = 2;
/* areschannel is already setup in the Curl_open() function */
diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c
index b08497aaa0..68dcbb3ecd 100644
--- a/libs/libcurl/src/asyn-thread.c
+++ b/libs/libcurl/src/asyn-thread.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
@@ -71,7 +71,6 @@
#include "strerror.h"
#include "url.h"
#include "multiif.h"
-#include "inet_pton.h"
#include "inet_ntop.h"
#include "curl_threads.h"
#include "connect.h"
@@ -692,26 +691,11 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
int port,
int *waitp)
{
- struct in_addr in;
struct Curl_easy *data = conn->data;
struct resdata *reslv = (struct resdata *)data->state.resolver;
*waitp = 0; /* default to synchronous response */
-#ifdef ENABLE_IPV6
- {
- struct in6_addr in6;
- /* check if this is an IPv6 address string */
- if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
- /* This is an IPv6 address literal */
- return Curl_ip2addr(AF_INET6, &in6, hostname, port);
- }
-#endif /* ENABLE_IPV6 */
-
- if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
- /* This is a dotted IP address 123.123.123.123-style */
- return Curl_ip2addr(AF_INET, &in, hostname, port);
-
reslv->start = Curl_now();
/* fire up a new resolver thread! */
@@ -736,32 +720,12 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
int *waitp)
{
struct addrinfo hints;
- char sbuf[12];
int pf = PF_INET;
struct Curl_easy *data = conn->data;
struct resdata *reslv = (struct resdata *)data->state.resolver;
*waitp = 0; /* default to synchronous response */
-#ifndef USE_RESOLVE_ON_IPS
- {
- struct in_addr in;
- /* First check if this is an IPv4 address string */
- if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
- /* This is a dotted IP address 123.123.123.123-style */
- return Curl_ip2addr(AF_INET, &in, hostname, port);
- }
-#ifdef ENABLE_IPV6
- {
- struct in6_addr in6;
- /* check if this is an IPv6 address string */
- if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
- /* This is an IPv6 address literal */
- return Curl_ip2addr(AF_INET6, &in6, hostname, port);
- }
-#endif /* ENABLE_IPV6 */
-#endif /* !USE_RESOLVE_ON_IPS */
-
#ifdef CURLRES_IPV6
/*
* Check if a limited name resolve has been requested.
@@ -778,7 +742,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
break;
}
- if((pf != PF_INET) && !Curl_ipv6works())
+ if((pf != PF_INET) && !Curl_ipv6works(conn))
/* The stack seems to be a non-IPv6 one */
pf = PF_INET;
#endif /* CURLRES_IPV6 */
@@ -788,8 +752,6 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
hints.ai_socktype = (conn->transport == TRNSPRT_TCP)?
SOCK_STREAM : SOCK_DGRAM;
- msnprintf(sbuf, sizeof(sbuf), "%d", port);
-
reslv->start = Curl_now();
/* fire up a new resolver thread! */
if(init_resolve_thread(conn, hostname, port, &hints)) {
diff --git a/libs/libcurl/src/config-dos.h b/libs/libcurl/src/config-dos.h
index 25f751eb56..aa83c4be55 100644
--- a/libs/libcurl/src/config-dos.h
+++ b/libs/libcurl/src/config-dos.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
@@ -138,7 +138,6 @@
/* USE_OPENSSL on cmd-line */
#ifdef USE_OPENSSL
#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
- #define HAVE_OPENSSL_ENGINE_H 1
#define OPENSSL_NO_KRB5 1
#endif
diff --git a/libs/libcurl/src/config-plan9.h b/libs/libcurl/src/config-plan9.h
index 4063d4bbd6..41440a14ec 100644
--- a/libs/libcurl/src/config-plan9.h
+++ b/libs/libcurl/src/config-plan9.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
@@ -138,7 +138,6 @@
#define USE_OPENSSL 1
#define HAVE_OPENSSL_CRYPTO_H 1
-#define HAVE_OPENSSL_ENGINE_H 1
#define HAVE_OPENSSL_ERR_H 1
#define HAVE_OPENSSL_PEM_H 1
#define HAVE_OPENSSL_PKCS12_H 1
diff --git a/libs/libcurl/src/config-symbian.h b/libs/libcurl/src/config-symbian.h
index c01e1bfab8..82a27bfefa 100644
--- a/libs/libcurl/src/config-symbian.h
+++ b/libs/libcurl/src/config-symbian.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
@@ -358,9 +358,6 @@
/* 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/engine.h> header file. */
-/*#define HAVE_OPENSSL_ENGINE_H 1*/
-
/* Define to 1 if you have the <openssl/err.h> header file. */
/*#define HAVE_OPENSSL_ERR_H 1*/
diff --git a/libs/libcurl/src/config-tpf.h b/libs/libcurl/src/config-tpf.h
index 85b634f9d4..a79afae6d3 100644
--- a/libs/libcurl/src/config-tpf.h
+++ b/libs/libcurl/src/config-tpf.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
@@ -316,10 +316,6 @@
/* #undef HAVE_OPENSSL_CRYPTO_H */
#define HAVE_OPENSSL_CRYPTO_H 1
-/* Define to 1 if you have the <openssl/engine.h> header file. */
-/* #undef HAVE_OPENSSL_ENGINE_H */
-#define HAVE_OPENSSL_ENGINE_H 1
-
/* Define to 1 if you have the <openssl/err.h> header file. */
/* #undef HAVE_OPENSSL_ERR_H */
#define HAVE_OPENSSL_ERR_H 1
diff --git a/libs/libcurl/src/config-vxworks.h b/libs/libcurl/src/config-vxworks.h
index 004fd4e800..2769cdfd94 100644
--- a/libs/libcurl/src/config-vxworks.h
+++ b/libs/libcurl/src/config-vxworks.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
@@ -418,9 +418,6 @@
/* 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/engine.h> header file. */
-#define HAVE_OPENSSL_ENGINE_H 1
-
/* Define to 1 if you have the <openssl/err.h> header file. */
#define HAVE_OPENSSL_ERR_H 1
diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h
index 9abdb9fe6c..8b488c1c1c 100644
--- a/libs/libcurl/src/config-win32.h
+++ b/libs/libcurl/src/config-win32.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
@@ -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,11 +713,10 @@ 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
+#endif
/* Define to use Unix sockets. */
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
diff --git a/libs/libcurl/src/conncache.c b/libs/libcurl/src/conncache.c
index 28044644bf..cbd3bb1bb3 100644
--- a/libs/libcurl/src/conncache.c
+++ b/libs/libcurl/src/conncache.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
- * Copyright (C) 2012 - 2019, 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
@@ -179,18 +179,6 @@ size_t Curl_conncache_size(struct Curl_easy *data)
return num;
}
-/* Returns number of connections currently held in the connections's bundle
- Locks/unlocks the cache itself!
-*/
-size_t Curl_conncache_bundle_size(struct connectdata *conn)
-{
- size_t num;
- CONN_LOCK(conn->data);
- num = conn->bundle->num_connections;
- CONN_UNLOCK(conn->data);
- return num;
-}
-
/* Look up the bundle with all the connections to the same host this
connectdata struct is setup to use.
diff --git a/libs/libcurl/src/conncache.h b/libs/libcurl/src/conncache.h
index 5fe80b4c8d..e3e4c9c282 100644
--- a/libs/libcurl/src/conncache.h
+++ b/libs/libcurl/src/conncache.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2015 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
@@ -80,7 +80,6 @@ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
void Curl_conncache_unlock(struct Curl_easy *data);
/* returns number of connections currently held in the connection cache */
size_t Curl_conncache_size(struct Curl_easy *data);
-size_t Curl_conncache_bundle_size(struct connectdata *conn);
bool Curl_conncache_return_conn(struct Curl_easy *data,
struct connectdata *conn);
diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c
index 611d6d2f02..0a7475cb6a 100644
--- a/libs/libcurl/src/connect.c
+++ b/libs/libcurl/src/connect.c
@@ -745,13 +745,15 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
Curl_persistconninfo(conn);
}
-/* after a TCP connection to the proxy has been verified, this function does
- the next magic step.
+/* After a TCP connection to the proxy has been verified, this function does
+ the next magic steps. If 'done' isn't set TRUE, it is not done yet and
+ must be called again.
Note: this function's sub-functions call failf()
*/
-static CURLcode connected_proxy(struct connectdata *conn, int sockindex)
+static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
+ bool *done)
{
CURLcode result = CURLE_OK;
@@ -760,44 +762,63 @@ static CURLcode connected_proxy(struct connectdata *conn, int sockindex)
/* for the secondary socket (FTP), use the "connect to host"
* but ignore the "connect to port" (use the secondary port)
*/
- const char * const host = conn->bits.httpproxy ?
- conn->http_proxy.host.name :
- conn->bits.conn_to_host ?
- conn->conn_to_host.name :
- sockindex == SECONDARYSOCKET ?
- conn->secondaryhostname : conn->host.name;
- const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
- sockindex == SECONDARYSOCKET ? conn->secondary_port :
- conn->bits.conn_to_port ? conn->conn_to_port :
- conn->remote_port;
- conn->bits.socksproxy_connecting = TRUE;
+ const char * const host =
+ conn->bits.httpproxy ?
+ conn->http_proxy.host.name :
+ conn->bits.conn_to_host ?
+ conn->conn_to_host.name :
+ sockindex == SECONDARYSOCKET ?
+ conn->secondaryhostname : conn->host.name;
+ const int port =
+ conn->bits.httpproxy ? (int)conn->http_proxy.port :
+ sockindex == SECONDARYSOCKET ? conn->secondary_port :
+ conn->bits.conn_to_port ? conn->conn_to_port :
+ conn->remote_port;
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);
+ host, port, sockindex, conn, done);
break;
case CURLPROXY_SOCKS4:
case CURLPROXY_SOCKS4A:
result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
- conn);
+ conn, done);
break;
default:
failf(conn->data, "unknown proxytype option given");
result = CURLE_COULDNT_CONNECT;
} /* switch proxytype */
- conn->bits.socksproxy_connecting = FALSE;
#else
(void)sockindex;
#endif /* CURL_DISABLE_PROXY */
}
+ else
+ *done = TRUE; /* no SOCKS proxy, so consider us connected */
return result;
}
/*
+ * post_SOCKS() is called after a successful connect to the peer, which
+ * *could* be a SOCKS proxy
+ */
+static void post_SOCKS(struct connectdata *conn,
+ int sockindex,
+ bool *connected)
+{
+ conn->bits.tcpconnect[sockindex] = TRUE;
+
+ *connected = TRUE;
+ if(sockindex == FIRSTSOCKET)
+ Curl_pgrsTime(conn->data, TIMER_CONNECT); /* connect done */
+ Curl_updateconninfo(conn, conn->sock[sockindex]);
+ Curl_verboseconnect(conn);
+}
+
+/*
* Curl_is_connected() checks if the socket has connected.
*/
@@ -834,6 +855,14 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return CURLE_OPERATION_TIMEDOUT;
}
+ if(SOCKS_STATE(conn->cnnct.state)) {
+ /* still doing SOCKS */
+ result = connect_SOCKS(conn, sockindex, connected);
+ if(!result && *connected)
+ post_SOCKS(conn, sockindex, connected);
+ return result;
+ }
+
for(i = 0; i<2; i++) {
const int other = i ^ 1;
if(conn->tempsock[i] == CURL_SOCKET_BAD)
@@ -900,18 +929,13 @@ CURLcode Curl_is_connected(struct connectdata *conn,
conn->tempsock[other] = CURL_SOCKET_BAD;
}
- /* see if we need to do any proxy magic first once we connected */
- result = connected_proxy(conn, sockindex);
- if(result)
+ /* see if we need to kick off any SOCKS proxy magic once we
+ connected */
+ result = connect_SOCKS(conn, sockindex, connected);
+ if(result || !*connected)
return result;
- conn->bits.tcpconnect[sockindex] = TRUE;
-
- *connected = TRUE;
- if(sockindex == FIRSTSOCKET)
- Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
- Curl_updateconninfo(conn, conn->sock[sockindex]);
- Curl_verboseconnect(conn);
+ post_SOCKS(conn, sockindex, connected);
return CURLE_OK;
}
@@ -1007,8 +1031,6 @@ static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
sizeof(onoff)) < 0)
infof(data, "Could not set TCP_NODELAY: %s\n",
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
- else
- infof(data, "TCP_NODELAY set\n");
#else
(void)conn;
(void)sockfd;
@@ -1216,8 +1238,6 @@ static CURLcode singleipconnect(struct connectdata *conn,
if(setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
(void *)&optval, sizeof(optval)) < 0)
infof(data, "Failed to enable TCP Fast Open on fd %d\n", sockfd);
- else
- infof(data, "TCP_FASTOPEN_CONNECT set\n");
rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
#elif defined(MSG_FASTOPEN) /* old Linux */
@@ -1428,12 +1448,11 @@ int Curl_closesocket(struct connectdata *conn,
curl_socket_t sock)
{
if(conn && conn->fclosesocket) {
- if((sock == conn->sock[SECONDARYSOCKET]) &&
- conn->sock_accepted[SECONDARYSOCKET])
+ if((sock == conn->sock[SECONDARYSOCKET]) && conn->sock_accepted)
/* if this socket matches the second socket, and that was created with
accept, then we MUST NOT call the callback but clear the accepted
status */
- conn->sock_accepted[SECONDARYSOCKET] = FALSE;
+ conn->sock_accepted = FALSE;
else {
int rc;
Curl_multi_closed(conn->data, sock);
diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c
index 0091132aa3..69bc04260a 100644
--- a/libs/libcurl/src/cookie.c
+++ b/libs/libcurl/src/cookie.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
@@ -97,6 +97,8 @@ Example set of cookies:
#include "curl_memrchr.h"
#include "inet_pton.h"
#include "parsedate.h"
+#include "rand.h"
+#include "rename.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -537,9 +539,9 @@ Curl_cookie_add(struct Curl_easy *data,
* only test for names where that can possibly be true.
*/
if(nlen > 3 && name[0] == '_' && name[1] == '_') {
- if(strncasecompare("__Secure-", name, 9))
+ if(!strncmp("__Secure-", name, 9))
co->prefix |= COOKIE_PREFIX__SECURE;
- else if(strncasecompare("__Host-", name, 7))
+ else if(!strncmp("__Host-", name, 7))
co->prefix |= COOKIE_PREFIX__HOST;
}
@@ -1046,7 +1048,7 @@ Curl_cookie_add(struct Curl_easy *data,
*clist = *co; /* then store all the new data */
- free(co); /* free the newly alloced memory */
+ free(co); /* free the newly allocated memory */
co = clist; /* point to the previous struct instead */
/* We have replaced a cookie, now skip the rest of the list but
@@ -1501,11 +1503,14 @@ static char *get_netscape_format(const struct Cookie *co)
*
* The function returns non-zero on write failure.
*/
-static int cookie_output(struct CookieInfo *c, const char *dumphere)
+static int cookie_output(struct Curl_easy *data,
+ struct CookieInfo *c, const char *filename)
{
struct Cookie *co;
- FILE *out;
+ FILE *out = NULL;
bool use_stdout = FALSE;
+ char *tempstore = NULL;
+ bool error = false;
if(!c)
/* no cookie engine alive */
@@ -1514,16 +1519,24 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
/* at first, remove expired cookies */
remove_expired(c);
- if(!strcmp("-", dumphere)) {
+ if(!strcmp("-", filename)) {
/* use stdout */
out = stdout;
use_stdout = TRUE;
}
else {
- out = fopen(dumphere, FOPEN_WRITETEXT);
- if(!out) {
- return 1; /* failure */
- }
+ unsigned char randsuffix[9];
+
+ if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
+ return 2;
+
+ tempstore = aprintf("%s.%s.tmp", filename, randsuffix);
+ if(!tempstore)
+ return 1;
+
+ out = fopen(tempstore, FOPEN_WRITETEXT);
+ if(!out)
+ goto error;
}
fputs("# Netscape HTTP Cookie File\n"
@@ -1538,9 +1551,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
array = calloc(1, sizeof(struct Cookie *) * c->numcookies);
if(!array) {
- if(!use_stdout)
- fclose(out);
- return 1;
+ goto error;
}
/* only sort the cookies with a domain property */
@@ -1559,9 +1570,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
if(format_ptr == NULL) {
fprintf(out, "#\n# Fatal libcurl error\n");
free(array);
- if(!use_stdout)
- fclose(out);
- return 1;
+ goto error;
}
fprintf(out, "%s\n", format_ptr);
free(format_ptr);
@@ -1569,10 +1578,24 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
free(array);
}
- if(!use_stdout)
+
+ if(!use_stdout) {
fclose(out);
+ out = NULL;
+ if(Curl_rename(tempstore, filename)) {
+ unlink(tempstore);
+ goto error;
+ }
+ }
- return 0;
+ goto cleanup;
+error:
+ error = true;
+cleanup:
+ if(out && !use_stdout)
+ fclose(out);
+ free(tempstore);
+ return error ? 1 : 0;
}
static struct curl_slist *cookie_list(struct Curl_easy *data)
@@ -1631,7 +1654,7 @@ void Curl_flush_cookies(struct Curl_easy *data, bool cleanup)
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
/* if we have a destination file for all the cookies to get dumped to */
- if(cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR]))
+ if(cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR]))
infof(data, "WARNING: failed to save cookies in %s\n",
data->set.str[STRING_COOKIEJAR]);
}
diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake
index 2c3b6562d4..98cdf51454 100644
--- a/libs/libcurl/src/curl_config.h.cmake
+++ b/libs/libcurl/src/curl_config.h.cmake
@@ -73,6 +73,9 @@
#define CURL_EXTERN_SYMBOL
#endif
+/* Allow SMB to work on Windows */
+#cmakedefine USE_WIN32_CRYPTO
+
/* Use Windows LDAP implementation */
#cmakedefine USE_WIN32_LDAP 1
@@ -452,9 +455,6 @@
/* Define to 1 if you have the <openssl/crypto.h> header file. */
#cmakedefine HAVE_OPENSSL_CRYPTO_H 1
-/* Define to 1 if you have the <openssl/engine.h> header file. */
-#cmakedefine HAVE_OPENSSL_ENGINE_H 1
-
/* Define to 1 if you have the <openssl/err.h> header file. */
#cmakedefine HAVE_OPENSSL_ERR_H 1
@@ -936,9 +936,6 @@ ${SIZEOF_TIME_T_CODE}
/* if GnuTLS is enabled */
#cmakedefine USE_GNUTLS 1
-/* if PolarSSL is enabled */
-#cmakedefine USE_POLARSSL 1
-
/* if Secure Transport is enabled */
#cmakedefine USE_SECTRANSP 1
diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in
index bb7f4e3402..8f29f51c11 100644
--- a/libs/libcurl/src/curl_config.h.in
+++ b/libs/libcurl/src/curl_config.h.in
@@ -435,6 +435,9 @@
/* Define to 1 if you have the `ssl' library (-lssl). */
#undef HAVE_LIBSSL
+/* Define to 1 if you have the `wolfssh' library (-lwolfssh). */
+#undef HAVE_LIBWOLFSSH
+
/* if zlib is available */
#undef HAVE_LIBZ
@@ -787,6 +790,9 @@
/* Define to 1 if you have the winsock.h header file. */
#undef HAVE_WINSOCK_H
+/* Define to 1 if you have the <wolfssh/ssh.h> header file. */
+#undef HAVE_WOLFSSH_SSH_H
+
/* Define to 1 if you have the `wolfSSLv3_client_method' function. */
#undef HAVE_WOLFSSLV3_CLIENT_METHOD
@@ -1050,6 +1056,9 @@
/* to enable SSPI support */
#undef USE_WINDOWS_SSPI
+/* if wolfSSH is in use */
+#undef USE_WOLFSSH
+
/* if wolfSSL is enabled */
#undef USE_WOLFSSL
diff --git a/libs/libcurl/src/curl_hmac.h b/libs/libcurl/src/curl_hmac.h
index 756dc9e4cd..3ff799bbda 100644
--- a/libs/libcurl/src/curl_hmac.h
+++ b/libs/libcurl/src/curl_hmac.h
@@ -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
@@ -24,6 +24,8 @@
#ifndef CURL_DISABLE_CRYPTO_AUTH
+#define HMAC_MD5_LENGTH 16
+
typedef void (* HMAC_hinit_func)(void *context);
typedef void (* HMAC_hupdate_func)(void *context,
const unsigned char *data,
@@ -62,6 +64,11 @@ int Curl_HMAC_update(HMAC_context *context,
unsigned int len);
int Curl_HMAC_final(HMAC_context *context, unsigned char *result);
+CURLcode Curl_hmacit(const HMAC_params *hashparams,
+ const unsigned char *key, const size_t keylen,
+ const unsigned char *data, const size_t datalen,
+ unsigned char *output);
+
#endif
#endif /* HEADER_CURL_HMAC_H */
diff --git a/libs/libcurl/src/curl_md4.h b/libs/libcurl/src/curl_md4.h
index 82df708cee..c7bb209815 100644
--- a/libs/libcurl/src/curl_md4.h
+++ b/libs/libcurl/src/curl_md4.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
@@ -28,7 +28,8 @@
#define MD4_DIGEST_LENGTH 16
-void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
+void Curl_md4it(unsigned char *output, const unsigned char *input,
+ const size_t len);
#endif /* !defined(CURL_DISABLE_CRYPTO_AUTH) */
diff --git a/libs/libcurl/src/curl_md5.h b/libs/libcurl/src/curl_md5.h
index aaf25f61bb..dd464416a2 100644
--- a/libs/libcurl/src/curl_md5.h
+++ b/libs/libcurl/src/curl_md5.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
@@ -49,8 +49,8 @@ typedef struct {
extern const MD5_params Curl_DIGEST_MD5[1];
extern const HMAC_params Curl_HMAC_MD5[1];
-void Curl_md5it(unsigned char *output,
- const unsigned char *input);
+void Curl_md5it(unsigned char *output, const unsigned char *input,
+ const size_t len);
MD5_context * Curl_MD5_init(const MD5_params *md5params);
CURLcode Curl_MD5_update(MD5_context *context,
diff --git a/libs/libcurl/src/curl_ntlm_core.c b/libs/libcurl/src/curl_ntlm_core.c
index 19f9b61d87..f9b823b4f6 100644
--- a/libs/libcurl/src/curl_ntlm_core.c
+++ b/libs/libcurl/src/curl_ntlm_core.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
@@ -120,7 +120,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#define NTLM_HMAC_MD5_LEN (16)
#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4)
@@ -567,25 +566,6 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
-/* This returns the HMAC MD5 digest */
-static CURLcode hmac_md5(const unsigned char *key, unsigned int keylen,
- const unsigned char *data, unsigned int datalen,
- unsigned char *output)
-{
- HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen);
-
- if(!ctxt)
- return CURLE_OUT_OF_MEMORY;
-
- /* Update the digest with the given challenge */
- Curl_HMAC_update(ctxt, data, datalen);
-
- /* Finalise the digest */
- Curl_HMAC_final(ctxt, output);
-
- return CURLE_OK;
-}
-
/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
* (uppercase UserName + Domain) as the data
*/
@@ -615,8 +595,8 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
ascii_uppercase_to_unicode_le(identity, user, userlen);
ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
- result = hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
- ntlmv2hash);
+ result = Curl_hmacit(Curl_HMAC_MD5, ntlmhash, 16, identity, identity_len,
+ ntlmv2hash);
free(identity);
return result;
@@ -662,7 +642,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
unsigned int len = 0;
unsigned char *ptr = NULL;
- unsigned char hmac_output[NTLM_HMAC_MD5_LEN];
+ unsigned char hmac_output[HMAC_MD5_LENGTH];
curl_off_t tw;
CURLcode result = CURLE_OK;
@@ -681,7 +661,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000;
/* Calculate the response len */
- len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN;
+ len = HMAC_MD5_LENGTH + NTLMv2_BLOB_LEN;
/* Allocate the response */
ptr = calloc(1, len);
@@ -689,7 +669,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
return CURLE_OUT_OF_MEMORY;
/* Create the BLOB structure */
- msnprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
+ msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN,
"%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
"%c%c%c%c", /* Reserved = 0 */
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
@@ -702,7 +682,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
/* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
memcpy(ptr + 8, &ntlm->nonce[0], 8);
- result = hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
+ result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8,
NTLMv2_BLOB_LEN + 8, hmac_output);
if(result) {
free(ptr);
@@ -710,7 +690,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
}
/* Concatenate the HMAC MD5 output with the BLOB */
- memcpy(ptr, hmac_output, NTLM_HMAC_MD5_LEN);
+ memcpy(ptr, hmac_output, HMAC_MD5_LENGTH);
/* Return the response */
*ntresp = ptr;
@@ -745,7 +725,8 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
memcpy(&data[0], challenge_server, 8);
memcpy(&data[8], challenge_client, 8);
- result = hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
+ result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, 16, &data[0], 16,
+ hmac_output);
if(result)
return result;
diff --git a/libs/libcurl/src/curl_ntlm_core.h b/libs/libcurl/src/curl_ntlm_core.h
index 392a1b81de..e1643d6277 100644
--- a/libs/libcurl/src/curl_ntlm_core.h
+++ b/libs/libcurl/src/curl_ntlm_core.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
@@ -46,11 +46,9 @@
#define USE_NTRESPONSES
/* Define USE_NTLM2SESSION in order to make the type-3 message include the
- NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
- Crypto engine that we have curl_ssl_md5sum() for. */
-#if defined(USE_NTRESPONSES) && \
- (!defined(USE_WIN32_CRYPTO) || \
- (defined(USE_SSL) && !defined(CURL_DISABLE_CRYPTO_AUTH)))
+ NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and
+ MD5 support */
+#if defined(USE_NTRESPONSES) && !defined(CURL_DISABLE_CRYPTO_AUTH)
#define USE_NTLM2SESSION
#endif
diff --git a/libs/libcurl/src/curl_ntlm_wb.c b/libs/libcurl/src/curl_ntlm_wb.c
index 30b54de444..f820b842e8 100644
--- a/libs/libcurl/src/curl_ntlm_wb.c
+++ b/libs/libcurl/src/curl_ntlm_wb.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
@@ -76,22 +76,22 @@
# define sclose_nolog(x) close((x))
#endif
-void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn)
+static void ntlm_wb_cleanup(struct ntlmdata *ntlm)
{
- if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
- sclose(conn->ntlm_auth_hlpr_socket);
- conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+ if(ntlm->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
+ sclose(ntlm->ntlm_auth_hlpr_socket);
+ ntlm->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
}
- if(conn->ntlm_auth_hlpr_pid) {
+ if(ntlm->ntlm_auth_hlpr_pid) {
int i;
for(i = 0; i < 4; i++) {
- pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
- if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
+ pid_t ret = waitpid(ntlm->ntlm_auth_hlpr_pid, NULL, WNOHANG);
+ if(ret == ntlm->ntlm_auth_hlpr_pid || errno == ECHILD)
break;
switch(i) {
case 0:
- kill(conn->ntlm_auth_hlpr_pid, SIGTERM);
+ kill(ntlm->ntlm_auth_hlpr_pid, SIGTERM);
break;
case 1:
/* Give the process another moment to shut down cleanly before
@@ -99,20 +99,21 @@ void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn)
Curl_wait_ms(1);
break;
case 2:
- kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
+ kill(ntlm->ntlm_auth_hlpr_pid, SIGKILL);
break;
case 3:
break;
}
}
- conn->ntlm_auth_hlpr_pid = 0;
+ ntlm->ntlm_auth_hlpr_pid = 0;
}
- Curl_safefree(conn->challenge_header);
- Curl_safefree(conn->response_header);
+ Curl_safefree(ntlm->challenge);
+ Curl_safefree(ntlm->response);
}
-static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
+static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm,
+ const char *userp)
{
curl_socket_t sockfds[2];
pid_t child_pid;
@@ -126,9 +127,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
#endif
char buffer[STRERROR_LEN];
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void) data;
+#endif
+
/* Return if communication with ntlm_auth already set up */
- if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
- conn->ntlm_auth_hlpr_pid)
+ if(ntlm->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
+ ntlm->ntlm_auth_hlpr_pid)
return CURLE_OK;
username = userp;
@@ -179,13 +184,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
ntlm_auth = NTLM_WB_FILE;
if(access(ntlm_auth, X_OK) != 0) {
- failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
+ failf(data, "Could not access ntlm_auth: %s errno %d: %s",
ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer)));
goto done;
}
- if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
- failf(conn->data, "Could not open socket pair. errno %d: %s",
+ if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
+ failf(data, "Could not open socket pair. errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
goto done;
}
@@ -194,7 +199,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
if(child_pid == -1) {
sclose(sockfds[0]);
sclose(sockfds[1]);
- failf(conn->data, "Could not fork. errno %d: %s",
+ failf(data, "Could not fork. errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
goto done;
}
@@ -206,13 +211,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
/* Don't use sclose in the child since it fools the socket leak detector */
sclose_nolog(sockfds[0]);
if(dup2(sockfds[1], STDIN_FILENO) == -1) {
- failf(conn->data, "Could not redirect child stdin. errno %d: %s",
+ failf(data, "Could not redirect child stdin. errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
exit(1);
}
if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
- failf(conn->data, "Could not redirect child stdout. errno %d: %s",
+ failf(data, "Could not redirect child stdout. errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
exit(1);
}
@@ -232,14 +237,14 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
NULL);
sclose_nolog(sockfds[1]);
- failf(conn->data, "Could not execl(). errno %d: %s",
+ failf(data, "Could not execl(). errno %d: %s",
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
exit(1);
}
sclose(sockfds[1]);
- conn->ntlm_auth_hlpr_socket = sockfds[0];
- conn->ntlm_auth_hlpr_pid = child_pid;
+ ntlm->ntlm_auth_hlpr_socket = sockfds[0];
+ ntlm->ntlm_auth_hlpr_pid = child_pid;
free(domain);
free(ntlm_auth_alloc);
return CURLE_OK;
@@ -253,17 +258,21 @@ done:
/* if larger than this, something is seriously wrong */
#define MAX_NTLM_WB_RESPONSE 100000
-static CURLcode ntlm_wb_response(struct connectdata *conn,
+static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm,
const char *input, curlntlm state)
{
char *buf = malloc(NTLM_BUFSIZE);
size_t len_in = strlen(input), len_out = 0;
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void) data;
+#endif
+
if(!buf)
return CURLE_OUT_OF_MEMORY;
while(len_in > 0) {
- ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
+ ssize_t written = swrite(ntlm->ntlm_auth_hlpr_socket, input, len_in);
if(written == -1) {
/* Interrupted by a signal, retry it */
if(errno == EINTR)
@@ -279,7 +288,7 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
ssize_t size;
char *newbuf;
- size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
+ size = sread(ntlm->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
if(size == -1) {
if(errno == EINTR)
continue;
@@ -295,7 +304,7 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
}
if(len_out > MAX_NTLM_WB_RESPONSE) {
- failf(conn->data, "too large ntlm_wb response!");
+ failf(data, "too large ntlm_wb response!");
free(buf);
return CURLE_OUT_OF_MEMORY;
}
@@ -323,9 +332,9 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
(buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
goto done;
- conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3);
+ ntlm->response = aprintf("%.*s", len_out - 4, buf + 3);
free(buf);
- if(!conn->response_header)
+ if(!ntlm->response)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
done:
@@ -337,6 +346,7 @@ CURLcode Curl_input_ntlm_wb(struct connectdata *conn,
bool proxy,
const char *header)
{
+ struct ntlmdata *ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
curlntlm *state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state;
if(!checkprefix("NTLM", header))
@@ -347,8 +357,8 @@ CURLcode Curl_input_ntlm_wb(struct connectdata *conn,
header++;
if(*header) {
- conn->challenge_header = strdup(header);
- if(!conn->challenge_header)
+ ntlm->challenge = strdup(header);
+ if(!ntlm->challenge)
return CURLE_OUT_OF_MEMORY;
*state = NTLMSTATE_TYPE2; /* We got a type-2 message */
@@ -387,6 +397,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
char **allocuserpwd;
/* point to the name and password for this */
const char *userp;
+ struct ntlmdata *ntlm;
curlntlm *state;
struct auth *authp;
@@ -398,12 +409,14 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
if(proxy) {
allocuserpwd = &conn->allocptr.proxyuserpwd;
userp = conn->http_proxy.user;
+ ntlm = &conn->proxyntlm;
state = &conn->proxy_ntlm_state;
authp = &conn->data->state.authproxy;
}
else {
allocuserpwd = &conn->allocptr.userpwd;
userp = conn->user;
+ ntlm = &conn->ntlm;
state = &conn->http_ntlm_state;
authp = &conn->data->state.authhost;
}
@@ -429,36 +442,36 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
* request handling process.
*/
/* Create communication with ntlm_auth */
- res = ntlm_wb_init(conn, userp);
+ res = ntlm_wb_init(conn->data, ntlm, userp);
if(res)
return res;
- res = ntlm_wb_response(conn, "YR\n", *state);
+ res = ntlm_wb_response(conn->data, ntlm, "YR\n", *state);
if(res)
return res;
free(*allocuserpwd);
- *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+ *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
proxy ? "Proxy-" : "",
- conn->response_header);
+ ntlm->response);
DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
- Curl_safefree(conn->response_header);
+ Curl_safefree(ntlm->response);
if(!*allocuserpwd)
return CURLE_OUT_OF_MEMORY;
break;
case NTLMSTATE_TYPE2: {
- char *input = aprintf("TT %s\n", conn->challenge_header);
+ char *input = aprintf("TT %s\n", ntlm->challenge);
if(!input)
return CURLE_OUT_OF_MEMORY;
- res = ntlm_wb_response(conn, input, *state);
+ res = ntlm_wb_response(conn->data, ntlm, input, *state);
free(input);
if(res)
return res;
free(*allocuserpwd);
- *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+ *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
proxy ? "Proxy-" : "",
- conn->response_header);
+ ntlm->response);
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
*state = NTLMSTATE_TYPE3; /* we sent a type-3 */
authp->done = TRUE;
@@ -481,4 +494,10 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
return CURLE_OK;
}
+void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn)
+{
+ ntlm_wb_cleanup(&conn->ntlm);
+ ntlm_wb_cleanup(&conn->proxyntlm);
+}
+
#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
diff --git a/libs/libcurl/src/curl_sasl.c b/libs/libcurl/src/curl_sasl.c
index 0aa1f5bb7a..8c1c86623d 100644
--- a/libs/libcurl/src/curl_sasl.c
+++ b/libs/libcurl/src/curl_sasl.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.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -272,6 +272,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
data->set.str[STRING_SERVICE_NAME] :
sasl->params->service;
#endif
+ const char *oauth_bearer = data->set.str[STRING_BEARER];
sasl->force_ir = force_ir; /* Latch for future use */
sasl->authused = 0; /* No mechanism used yet */
@@ -341,7 +342,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
}
else
#endif
- if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) {
+ if((enabledmechs & SASL_MECH_OAUTHBEARER) && oauth_bearer) {
mech = SASL_MECH_STRING_OAUTHBEARER;
state1 = SASL_OAUTH2;
state2 = SASL_OAUTH2_RESP;
@@ -351,17 +352,17 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
hostname,
port,
- conn->oauth_bearer,
+ oauth_bearer,
&resp, &len);
}
- else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) {
+ else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) {
mech = SASL_MECH_STRING_XOAUTH2;
state1 = SASL_OAUTH2;
sasl->authused = SASL_MECH_XOAUTH2;
if(force_ir || data->set.sasl_ir)
result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
- conn->oauth_bearer,
+ oauth_bearer,
&resp, &len);
}
else if(enabledmechs & SASL_MECH_PLAIN) {
@@ -431,6 +432,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
char *serverdata;
#endif
size_t len = 0;
+ const char *oauth_bearer = data->set.str[STRING_BEARER];
*progress = SASL_INPROGRESS;
@@ -558,7 +560,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
hostname,
port,
- conn->oauth_bearer,
+ oauth_bearer,
&resp, &len);
/* Failures maybe sent by the server as continuations for OAUTHBEARER */
@@ -566,7 +568,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
}
else
result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
- conn->oauth_bearer,
+ oauth_bearer,
&resp, &len);
break;
diff --git a/libs/libcurl/src/curl_sha256.h b/libs/libcurl/src/curl_sha256.h
index 14b6414ea0..35d286cebd 100644
--- a/libs/libcurl/src/curl_sha256.h
+++ b/libs/libcurl/src/curl_sha256.h
@@ -7,7 +7,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Florin Petriuc, <petriuc.florin@gmail.com>
+ * Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com>
+ * Copyright (C) 2018 - 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 +25,10 @@
#ifndef CURL_DISABLE_CRYPTO_AUTH
-void Curl_sha256it(unsigned char *outbuffer,
- const unsigned char *input);
+#define SHA256_DIGEST_LENGTH 32
+
+void Curl_sha256it(unsigned char *outbuffer, const unsigned char *input,
+ const size_t len);
#endif
diff --git a/libs/libcurl/src/doh.c b/libs/libcurl/src/doh.c
index 7f4eee5d81..aaa8f15ca6 100644
--- a/libs/libcurl/src/doh.c
+++ b/libs/libcurl/src/doh.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2018 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 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
@@ -548,7 +548,7 @@ static DOHcode store_cname(unsigned char *doh,
if((index + 1) >= dohlen)
return DOH_DNS_OUT_OF_RANGE;
- /* move to the the new index */
+ /* move to the new index */
newpos = (length & 0x3f) << 8 | doh[index + 1];
index = newpos;
continue;
diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c
index 6382cee3d5..1a6912748e 100644
--- a/libs/libcurl/src/easy.c
+++ b/libs/libcurl/src/easy.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
@@ -76,6 +76,7 @@
#include "setopt.h"
#include "http_digest.h"
#include "system_win32.h"
+#include "http2.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -185,16 +186,18 @@ static CURLcode global_init(long flags, bool memoryfuncs)
goto fail;
}
- (void)Curl_ipv6works();
-
#if defined(USE_SSH)
if(Curl_ssh_init()) {
goto fail;
}
#endif
- if(flags & CURL_GLOBAL_ACK_EINTR)
- Curl_ack_eintr = 1;
+#ifdef USE_WOLFSSH
+ if(WS_SUCCESS != wolfSSH_Init()) {
+ DEBUGF(fprintf(stderr, "Error: wolfSSH_Init failed\n"));
+ return CURLE_FAILED_INIT;
+ }
+#endif
init_flags = flags;
@@ -272,6 +275,10 @@ void curl_global_cleanup(void)
Curl_ssh_cleanup();
+#ifdef USE_WOLFSSH
+ (void)wolfSSH_Cleanup();
+#endif
+
init_flags = 0;
}
@@ -684,10 +691,6 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
sigpipe_ignore(data, &pipe_st);
- /* assign this after curl_multi_add_handle() since that function checks for
- it and rejects this handle otherwise */
- data->multi = multi;
-
/* run the transfer */
result = events ? easy_events(multi) : easy_transfer(multi);
@@ -983,49 +986,54 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
/* put it back in the keepon */
k->keepon = newstate;
- if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempcount) {
- /* there are buffers for sending that can be delivered as the receive
- pausing is lifted! */
- unsigned int i;
- unsigned int count = data->state.tempcount;
- struct tempbuf writebuf[3]; /* there can only be three */
- struct connectdata *conn = data->conn;
- struct Curl_easy *saved_data = NULL;
-
- /* copy the structs to allow for immediate re-pausing */
- for(i = 0; i < data->state.tempcount; i++) {
- writebuf[i] = data->state.tempwrite[i];
- data->state.tempwrite[i].buf = NULL;
- }
- data->state.tempcount = 0;
+ if(!(newstate & KEEP_RECV_PAUSE)) {
+ Curl_http2_stream_pause(data, FALSE);
+
+ if(data->state.tempcount) {
+ /* there are buffers for sending that can be delivered as the receive
+ pausing is lifted! */
+ unsigned int i;
+ unsigned int count = data->state.tempcount;
+ struct tempbuf writebuf[3]; /* there can only be three */
+ struct connectdata *conn = data->conn;
+ struct Curl_easy *saved_data = NULL;
+
+ /* copy the structs to allow for immediate re-pausing */
+ for(i = 0; i < data->state.tempcount; i++) {
+ writebuf[i] = data->state.tempwrite[i];
+ data->state.tempwrite[i].buf = NULL;
+ }
+ data->state.tempcount = 0;
- /* set the connection's current owner */
- if(conn->data != data) {
- saved_data = conn->data;
- conn->data = data;
- }
+ /* set the connection's current owner */
+ if(conn->data != data) {
+ saved_data = conn->data;
+ conn->data = data;
+ }
- for(i = 0; i < count; i++) {
- /* even if one function returns error, this loops through and frees all
- buffers */
- if(!result)
- result = Curl_client_write(conn, writebuf[i].type, writebuf[i].buf,
- writebuf[i].len);
- free(writebuf[i].buf);
- }
+ for(i = 0; i < count; i++) {
+ /* even if one function returns error, this loops through and frees
+ all buffers */
+ if(!result)
+ result = Curl_client_write(conn, writebuf[i].type, writebuf[i].buf,
+ writebuf[i].len);
+ free(writebuf[i].buf);
+ }
- /* recover previous owner of the connection */
- if(saved_data)
- conn->data = saved_data;
+ /* recover previous owner of the connection */
+ if(saved_data)
+ conn->data = saved_data;
- if(result)
- return result;
+ if(result)
+ return result;
+ }
}
/* if there's no error and we're not pausing both directions, we want
to have this handle checked soon */
if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) {
+ data->state.drain++;
Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
if(data->multi)
Curl_update_timer(data->multi);
diff --git a/libs/libcurl/src/formdata.c b/libs/libcurl/src/formdata.c
index 429d479da5..50a37e0e74 100644
--- a/libs/libcurl/src/formdata.c
+++ b/libs/libcurl/src/formdata.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
diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c
index 469096f0f6..57b22ade97 100644
--- a/libs/libcurl/src/ftp.c
+++ b/libs/libcurl/src/ftp.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
@@ -55,7 +55,6 @@
#include "transfer.h"
#include "escape.h"
#include "http.h" /* for HTTP proxy tunnel stuff */
-#include "socks.h"
#include "ftp.h"
#include "fileinfo.h"
#include "ftplistparser.h"
@@ -78,6 +77,7 @@
#include "warnless.h"
#include "http_proxy.h"
#include "non-ascii.h"
+#include "socks.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -253,18 +253,6 @@ static void freedirs(struct ftp_conn *ftpc)
Curl_safefree(ftpc->newhost);
}
-/* Returns non-zero if the given string contains CR (\r) or LF (\n),
- which are not allowed within RFC 959 <string>.
- Note: The input string is in the client's encoding which might
- not be ASCII, so escape sequences \r & \n must be used instead
- of hex values 0x0d & 0x0a.
-*/
-static bool isBadFtpString(const char *string)
-{
- return ((NULL != strchr(string, '\r')) ||
- (NULL != strchr(string, '\n'))) ? TRUE : FALSE;
-}
-
/***********************************************************************
*
* AcceptServerConnect()
@@ -303,7 +291,7 @@ static CURLcode AcceptServerConnect(struct connectdata *conn)
conn->sock[SECONDARYSOCKET] = s;
(void)curlx_nonblock(s, TRUE); /* enable non-blocking */
- conn->sock_accepted[SECONDARYSOCKET] = TRUE;
+ conn->sock_accepted = TRUE;
if(data->set.fsockopt) {
int error = 0;
@@ -785,9 +773,8 @@ static void _state(struct connectdata *conn,
static CURLcode ftp_state_user(struct connectdata *conn)
{
CURLcode result;
- struct FTP *ftp = conn->data->req.protop;
/* send USER */
- PPSENDF(&conn->proto.ftpc.pp, "USER %s", ftp->user?ftp->user:"");
+ PPSENDF(&conn->proto.ftpc.pp, "USER %s", conn->user?conn->user:"");
state(conn, FTP_USER);
conn->data->state.ftp_trying_alternative = FALSE;
@@ -823,6 +810,9 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks)
* handle ordinary commands.
*/
+ if(SOCKS_STATE(conn->cnnct.state))
+ return Curl_SOCKS_getsock(conn, socks, SECONDARYSOCKET);
+
if(FTP_STOP == ftpc->state) {
int bits = GETSOCK_READSOCK(0);
@@ -920,7 +910,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct Curl_easy *data = conn->data;
curl_socket_t portsock = CURL_SOCKET_BAD;
- char myhost[256] = "";
+ char myhost[MAX_IPADR_LEN + 1] = "";
struct Curl_sockaddr_storage ss;
Curl_addrinfo *res, *ai;
@@ -931,9 +921,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
#ifdef ENABLE_IPV6
struct sockaddr_in6 * const sa6 = (void *)sa;
#endif
- char tmp[1024];
static const char mode[][5] = { "EPRT", "PORT" };
- int rc;
+ enum resolve_t rc;
int error;
char *host = NULL;
char *string_ftpport = data->set.str[STRING_FTPPORT];
@@ -1246,8 +1235,10 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
break;
}
if(PORT == fcmd) {
+ /* large enough for [IP address],[num],[num] */
+ char target[sizeof(myhost) + 20];
char *source = myhost;
- char *dest = tmp;
+ char *dest = target;
/* translate x.x.x.x to x,x,x,x */
while(source && *source) {
@@ -1261,7 +1252,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
*dest = 0;
msnprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
- result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
+ result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], target);
if(result) {
failf(data, "Failure sending PORT command: %s",
curl_easy_strerror(result));
@@ -1806,7 +1797,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
CURLcode result;
struct Curl_easy *data = conn->data;
struct Curl_dns_entry *addr = NULL;
- int rc;
+ enum resolve_t rc;
unsigned short connectport; /* the local port connect() should use! */
char *str = &data->state.buffer[4]; /* start on the first letter */
@@ -2528,7 +2519,6 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct FTP *ftp = data->req.protop;
struct ftp_conn *ftpc = &conn->proto.ftpc;
(void)instate; /* no use for this yet */
@@ -2536,7 +2526,7 @@ 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", ftp->passwd?ftp->passwd:"");
+ PPSENDF(&ftpc->pp, "PASS %s", conn->passwd?conn->passwd:"");
state(conn, FTP_PASS);
}
else if(ftpcode/100 == 2) {
@@ -4369,18 +4359,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
/* get some initial data into the ftp struct */
ftp->transfer = FTPTRANSFER_BODY;
ftp->downloadsize = 0;
-
- /* No need to duplicate user+password, the connectdata struct won't change
- during a session, but we re-init them here since on subsequent inits
- since the conn struct may have changed or been replaced.
- */
- ftp->user = conn->user;
- ftp->passwd = conn->passwd;
- if(isBadFtpString(ftp->user))
- return CURLE_URL_MALFORMAT;
- if(isBadFtpString(ftp->passwd))
- return CURLE_URL_MALFORMAT;
-
conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
return CURLE_OK;
diff --git a/libs/libcurl/src/ftp.h b/libs/libcurl/src/ftp.h
index 2c88d568c1..984347f2a3 100644
--- a/libs/libcurl/src/ftp.h
+++ b/libs/libcurl/src/ftp.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
@@ -102,8 +102,6 @@ typedef enum {
perhaps the Curl_easy is changed between the times the connection is
used. */
struct FTP {
- char *user; /* user name string */
- char *passwd; /* password string */
char *path; /* points to the urlpieces struct field */
char *pathalloc; /* if non-NULL a pointer to an allocated path */
diff --git a/libs/libcurl/src/getenv.c b/libs/libcurl/src/getenv.c
index e444a6a3ad..9385b8f677 100644
--- a/libs/libcurl/src/getenv.c
+++ b/libs/libcurl/src/getenv.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
@@ -27,25 +27,48 @@
#include "memdebug.h"
-static
-char *GetEnv(const char *variable)
+static char *GetEnv(const char *variable)
{
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
(void)variable;
return NULL;
-#else
-#ifdef WIN32
- char env[4096];
- char *temp = getenv(variable);
- env[0] = '\0';
- if(temp != NULL)
- ExpandEnvironmentStringsA(temp, env, sizeof(env));
- return (env[0] != '\0')?strdup(env):NULL;
+#elif defined(WIN32)
+ /* This uses Windows API instead of C runtime getenv() to get the environment
+ variable since some changes aren't always visible to the latter. #4774 */
+ char *buf = NULL;
+ char *tmp;
+ DWORD bufsize;
+ DWORD rc = 1;
+ const DWORD max = 32768; /* max env var size from MSCRT source */
+
+ for(;;) {
+ tmp = realloc(buf, rc);
+ if(!tmp) {
+ free(buf);
+ return NULL;
+ }
+
+ buf = tmp;
+ bufsize = rc;
+
+ /* It's possible for rc to be 0 if the variable was found but empty.
+ Since getenv doesn't make that distinction we ignore it as well. */
+ rc = GetEnvironmentVariableA(variable, buf, bufsize);
+ if(!rc || rc == bufsize || rc > max) {
+ free(buf);
+ return NULL;
+ }
+
+ /* if rc < bufsize then rc is bytes written not including null */
+ if(rc < bufsize)
+ return buf;
+
+ /* else rc is bytes needed, try again */
+ }
#else
char *env = getenv(variable);
return (env && env[0])?strdup(env):NULL;
#endif
-#endif
}
char *curl_getenv(const char *v)
diff --git a/libs/libcurl/src/hmac.c b/libs/libcurl/src/hmac.c
index bf49ebec54..ae68827bea 100644
--- a/libs/libcurl/src/hmac.c
+++ b/libs/libcurl/src/hmac.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
@@ -30,6 +30,7 @@
#include "curl_hmac.h"
#include "curl_memory.h"
+#include "warnless.h"
/* The last #include file should be: */
#include "memdebug.h"
@@ -129,4 +130,40 @@ int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
return 0;
}
+/*
+ * Curl_hmacit()
+ *
+ * This is used to generate a HMAC hash, for the specified input data, given
+ * the specified hash function and key.
+ *
+ * Parameters:
+ *
+ * hashparams [in] - The hash function (Curl_HMAC_MD5).
+ * key [in] - The key to use.
+ * keylen [in] - The length of the key.
+ * data [in] - The data to encrypt.
+ * datalen [in] - The length of the data.
+ * output [in/out] - The output buffer.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_hmacit(const HMAC_params *hashparams,
+ const unsigned char *key, const size_t keylen,
+ const unsigned char *data, const size_t datalen,
+ unsigned char *output)
+{
+ HMAC_context *ctxt = Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen));
+
+ if(!ctxt)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Update the digest with the given challenge */
+ Curl_HMAC_update(ctxt, data, curlx_uztoui(datalen));
+
+ /* Finalise the digest */
+ Curl_HMAC_final(ctxt, output);
+
+ return CURLE_OK;
+}
+
#endif /* CURL_DISABLE_CRYPTO_AUTH */
diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c
index b434b390a2..c0feb79fb3 100644
--- a/libs/libcurl/src/hostip.c
+++ b/libs/libcurl/src/hostip.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
@@ -59,6 +59,7 @@
#include "strerror.h"
#include "url.h"
#include "inet_ntop.h"
+#include "inet_pton.h"
#include "multiif.h"
#include "doh.h"
#include "warnless.h"
@@ -482,16 +483,16 @@ Curl_cache_addr(struct Curl_easy *data,
* CURLRESOLV_PENDING (1) = waiting for response, no pointer
*/
-int Curl_resolv(struct connectdata *conn,
- const char *hostname,
- int port,
- bool allowDOH,
- struct Curl_dns_entry **entry)
+enum resolve_t Curl_resolv(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ bool allowDOH,
+ struct Curl_dns_entry **entry)
{
struct Curl_dns_entry *dns = NULL;
struct Curl_easy *data = conn->data;
CURLcode result;
- int rc = CURLRESOLV_ERROR; /* default to failure */
+ enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
*entry = NULL;
@@ -512,13 +513,11 @@ int Curl_resolv(struct connectdata *conn,
if(!dns) {
/* The entry was not in the cache. Resolve it to IP address */
- Curl_addrinfo *addr;
+ Curl_addrinfo *addr = NULL;
int respwait = 0;
-
- /* Check what IP specifics the app has requested and if we can provide it.
- * If not, bail out. */
- if(!Curl_ipvalid(conn))
- return CURLRESOLV_ERROR;
+#ifndef USE_RESOLVE_ON_IPS
+ struct in_addr in;
+#endif
/* notify the resolver start callback */
if(data->set.resolver_start) {
@@ -531,20 +530,43 @@ int Curl_resolv(struct connectdata *conn,
return CURLRESOLV_ERROR;
}
- if(allowDOH && data->set.doh) {
- addr = Curl_doh(conn, hostname, port, &respwait);
+#ifndef USE_RESOLVE_ON_IPS
+ /* First check if this is an IPv4 address string */
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+ /* This is a dotted IP address 123.123.123.123-style */
+ addr = Curl_ip2addr(AF_INET, &in, hostname, port);
+#ifdef ENABLE_IPV6
+ if(!addr) {
+ struct in6_addr in6;
+ /* check if this is an IPv6 address string */
+ if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
+ /* This is an IPv6 address literal */
+ addr = Curl_ip2addr(AF_INET6, &in6, hostname, port);
}
- else {
- /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
- non-zero value indicating that we need to wait for the response to the
- resolve call */
- addr = Curl_getaddrinfo(conn,
+#endif /* ENABLE_IPV6 */
+#endif /* !USE_RESOLVE_ON_IPS */
+
+ if(!addr) {
+ /* Check what IP specifics the app has requested and if we can provide
+ * it. If not, bail out. */
+ if(!Curl_ipvalid(conn))
+ return CURLRESOLV_ERROR;
+
+ if(allowDOH && data->set.doh) {
+ addr = Curl_doh(conn, hostname, port, &respwait);
+ }
+ else {
+ /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
+ non-zero value indicating that we need to wait for the response to
+ the resolve call */
+ addr = Curl_getaddrinfo(conn,
#ifdef DEBUGBUILD
- (data->set.str[STRING_DEVICE]
- && !strcmp(data->set.str[STRING_DEVICE],
- "LocalHost"))?"localhost":
+ (data->set.str[STRING_DEVICE]
+ && !strcmp(data->set.str[STRING_DEVICE],
+ "LocalHost"))?"localhost":
#endif
- hostname, port, &respwait);
+ hostname, port, &respwait);
+ }
}
if(!addr) {
if(respwait) {
@@ -620,11 +642,11 @@ RETSIGTYPE alarmfunc(int sig)
* CURLRESOLV_PENDING (1) = waiting for response, no pointer
*/
-int Curl_resolv_timeout(struct connectdata *conn,
- const char *hostname,
- int port,
- struct Curl_dns_entry **entry,
- timediff_t timeoutms)
+enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ struct Curl_dns_entry **entry,
+ timediff_t timeoutms)
{
#ifdef USE_ALARM_TIMEOUT
#ifdef HAVE_SIGACTION
@@ -640,7 +662,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
volatile unsigned int prev_alarm = 0;
struct Curl_easy *data = conn->data;
#endif /* USE_ALARM_TIMEOUT */
- int rc;
+ enum resolve_t rc;
*entry = NULL;
diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h
index e0597ea96a..baf1e5860a 100644
--- a/libs/libcurl/src/hostip.h
+++ b/libs/libcurl/src/hostip.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
@@ -79,26 +79,29 @@ struct Curl_dns_entry {
* use, or we'll leak memory!
*/
/* return codes */
-#define CURLRESOLV_TIMEDOUT -2
-#define CURLRESOLV_ERROR -1
-#define CURLRESOLV_RESOLVED 0
-#define CURLRESOLV_PENDING 1
-int Curl_resolv(struct connectdata *conn,
- const char *hostname,
- int port,
- bool allowDOH,
- struct Curl_dns_entry **dnsentry);
-int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
- int port, struct Curl_dns_entry **dnsentry,
- timediff_t timeoutms);
+enum resolve_t {
+ CURLRESOLV_TIMEDOUT = -2,
+ CURLRESOLV_ERROR = -1,
+ CURLRESOLV_RESOLVED = 0,
+ CURLRESOLV_PENDING = 1
+};
+enum resolve_t Curl_resolv(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ bool allowDOH,
+ struct Curl_dns_entry **dnsentry);
+enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
+ const char *hostname, int port,
+ struct Curl_dns_entry **dnsentry,
+ timediff_t timeoutms);
#ifdef CURLRES_IPV6
/*
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
*/
-bool Curl_ipv6works(void);
+bool Curl_ipv6works(struct connectdata *conn);
#else
-#define Curl_ipv6works() FALSE
+#define Curl_ipv6works(x) FALSE
#endif
/*
diff --git a/libs/libcurl/src/hostip4.c b/libs/libcurl/src/hostip4.c
index 2636851e68..d5009a3efb 100644
--- a/libs/libcurl/src/hostip4.c
+++ b/libs/libcurl/src/hostip4.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
@@ -52,7 +52,6 @@
#include "share.h"
#include "strerror.h"
#include "url.h"
-#include "inet_pton.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -128,38 +127,22 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
#endif
Curl_addrinfo *ai = NULL;
struct hostent *h = NULL;
- struct in_addr in;
struct hostent *buf = NULL;
-#ifdef ENABLE_IPV6
- {
- struct in6_addr in6;
- /* check if this is an IPv6 address string */
- if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
- /* This is an IPv6 address literal */
- return Curl_ip2addr(AF_INET6, &in6, hostname, port);
- }
-#endif /* ENABLE_IPV6 */
-
- if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
- /* This is a dotted IP address 123.123.123.123-style */
- return Curl_ip2addr(AF_INET, &in, hostname, port);
-
#if defined(HAVE_GETADDRINFO_THREADSAFE)
- else {
- struct addrinfo hints;
- char sbuf[12];
- char *sbufptr = NULL;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_INET;
- hints.ai_socktype = SOCK_STREAM;
- if(port) {
- msnprintf(sbuf, sizeof(sbuf), "%d", port);
- sbufptr = sbuf;
- }
+ struct addrinfo hints;
+ char sbuf[12];
+ char *sbufptr = NULL;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ if(port) {
+ msnprintf(sbuf, sizeof(sbuf), "%d", port);
+ sbufptr = sbuf;
+ }
- (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai);
+ (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai);
#elif defined(HAVE_GETHOSTBYNAME_R)
/*
@@ -167,144 +150,141 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
* Since there are three different versions of it, the following code is
* somewhat #ifdef-ridden.
*/
- else {
- int h_errnop;
-
- buf = calloc(1, CURL_HOSTENT_SIZE);
- if(!buf)
- return NULL; /* major failure */
- /*
- * The clearing of the buffer is a workaround for a gethostbyname_r bug in
- * qnx nto and it is also _required_ for some of these functions on some
- * platforms.
- */
+ int h_errnop;
+
+ buf = calloc(1, CURL_HOSTENT_SIZE);
+ if(!buf)
+ return NULL; /* major failure */
+ /*
+ * The clearing of the buffer is a workaround for a gethostbyname_r bug in
+ * qnx nto and it is also _required_ for some of these functions on some
+ * platforms.
+ */
#if defined(HAVE_GETHOSTBYNAME_R_5)
- /* Solaris, IRIX and more */
- h = gethostbyname_r(hostname,
- (struct hostent *)buf,
- (char *)buf + sizeof(struct hostent),
- CURL_HOSTENT_SIZE - sizeof(struct hostent),
- &h_errnop);
-
- /* If the buffer is too small, it returns NULL and sets errno to
- * ERANGE. The errno is thread safe if this is compiled with
- * -D_REENTRANT as then the 'errno' variable is a macro defined to get
- * used properly for threads.
- */
+ /* Solaris, IRIX and more */
+ h = gethostbyname_r(hostname,
+ (struct hostent *)buf,
+ (char *)buf + sizeof(struct hostent),
+ CURL_HOSTENT_SIZE - sizeof(struct hostent),
+ &h_errnop);
+
+ /* If the buffer is too small, it returns NULL and sets errno to
+ * ERANGE. The errno is thread safe if this is compiled with
+ * -D_REENTRANT as then the 'errno' variable is a macro defined to get
+ * used properly for threads.
+ */
- if(h) {
- ;
- }
- else
+ if(h) {
+ ;
+ }
+ else
#elif defined(HAVE_GETHOSTBYNAME_R_6)
- /* Linux */
-
- (void)gethostbyname_r(hostname,
- (struct hostent *)buf,
- (char *)buf + sizeof(struct hostent),
- CURL_HOSTENT_SIZE - sizeof(struct hostent),
- &h, /* DIFFERENCE */
- &h_errnop);
- /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
- * sudden this function returns EAGAIN if the given buffer size is too
- * small. Previous versions are known to return ERANGE for the same
- * problem.
- *
- * This wouldn't be such a big problem if older versions wouldn't
- * sometimes return EAGAIN on a common failure case. Alas, we can't
- * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
- * glibc.
- *
- * For now, we do that and thus we may call the function repeatedly and
- * fail for older glibc versions that return EAGAIN, until we run out of
- * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
- *
- * If anyone has a better fix, please tell us!
- *
- * -------------------------------------------------------------------
- *
- * On October 23rd 2003, Dan C dug up more details on the mysteries of
- * gethostbyname_r() in glibc:
- *
- * In glibc 2.2.5 the interface is different (this has also been
- * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
- * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
- * (shipped/upgraded by Redhat 7.2) don't show this behavior!
- *
- * In this "buggy" version, the return code is -1 on error and 'errno'
- * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
- * thread-safe variable.
- */
+ /* Linux */
+
+ (void)gethostbyname_r(hostname,
+ (struct hostent *)buf,
+ (char *)buf + sizeof(struct hostent),
+ CURL_HOSTENT_SIZE - sizeof(struct hostent),
+ &h, /* DIFFERENCE */
+ &h_errnop);
+ /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
+ * sudden this function returns EAGAIN if the given buffer size is too
+ * small. Previous versions are known to return ERANGE for the same
+ * problem.
+ *
+ * This wouldn't be such a big problem if older versions wouldn't
+ * sometimes return EAGAIN on a common failure case. Alas, we can't
+ * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
+ * glibc.
+ *
+ * For now, we do that and thus we may call the function repeatedly and
+ * fail for older glibc versions that return EAGAIN, until we run out of
+ * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
+ *
+ * If anyone has a better fix, please tell us!
+ *
+ * -------------------------------------------------------------------
+ *
+ * On October 23rd 2003, Dan C dug up more details on the mysteries of
+ * gethostbyname_r() in glibc:
+ *
+ * In glibc 2.2.5 the interface is different (this has also been
+ * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
+ * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
+ * (shipped/upgraded by Redhat 7.2) don't show this behavior!
+ *
+ * In this "buggy" version, the return code is -1 on error and 'errno'
+ * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
+ * thread-safe variable.
+ */
- if(!h) /* failure */
+ if(!h) /* failure */
#elif defined(HAVE_GETHOSTBYNAME_R_3)
- /* AIX, Digital Unix/Tru64, HPUX 10, more? */
-
- /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
- * the plain fact that it does not return unique full buffers on each
- * call, but instead several of the pointers in the hostent structs will
- * point to the same actual data! This have the unfortunate down-side that
- * our caching system breaks down horribly. Luckily for us though, AIX 4.3
- * and more recent versions have a "completely thread-safe"[*] libc where
- * all the data is stored in thread-specific memory areas making calls to
- * the plain old gethostbyname() work fine even for multi-threaded
- * programs.
- *
- * This AIX 4.3 or later detection is all made in the configure script.
- *
- * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
- *
- * [*] = much later we've found out that it isn't at all "completely
- * thread-safe", but at least the gethostbyname() function is.
+ /* AIX, Digital Unix/Tru64, HPUX 10, more? */
+
+ /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
+ * the plain fact that it does not return unique full buffers on each
+ * call, but instead several of the pointers in the hostent structs will
+ * point to the same actual data! This have the unfortunate down-side that
+ * our caching system breaks down horribly. Luckily for us though, AIX 4.3
+ * and more recent versions have a "completely thread-safe"[*] libc where
+ * all the data is stored in thread-specific memory areas making calls to
+ * the plain old gethostbyname() work fine even for multi-threaded
+ * programs.
+ *
+ * This AIX 4.3 or later detection is all made in the configure script.
+ *
+ * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
+ *
+ * [*] = much later we've found out that it isn't at all "completely
+ * thread-safe", but at least the gethostbyname() function is.
+ */
+
+ if(CURL_HOSTENT_SIZE >=
+ (sizeof(struct hostent) + sizeof(struct hostent_data))) {
+
+ /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
+ * that should work! September 20: Richard Prescott worked on the buffer
+ * size dilemma.
*/
- if(CURL_HOSTENT_SIZE >=
- (sizeof(struct hostent) + sizeof(struct hostent_data))) {
-
- /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
- * that should work! September 20: Richard Prescott worked on the buffer
- * size dilemma.
- */
-
- res = gethostbyname_r(hostname,
- (struct hostent *)buf,
- (struct hostent_data *)((char *)buf +
- sizeof(struct hostent)));
- h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */
- }
- else
- res = -1; /* failure, too smallish buffer size */
-
- if(!res) { /* success */
-
- h = buf; /* result expected in h */
-
- /* This is the worst kind of the different gethostbyname_r() interfaces.
- * Since we don't know how big buffer this particular lookup required,
- * we can't realloc down the huge alloc without doing closer analysis of
- * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
- * name lookup. Fixing this would require an extra malloc() and then
- * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
- * memory area to the actually used amount.
- */
- }
- else
+ res = gethostbyname_r(hostname,
+ (struct hostent *)buf,
+ (struct hostent_data *)((char *)buf +
+ sizeof(struct hostent)));
+ h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */
+ }
+ else
+ res = -1; /* failure, too smallish buffer size */
+
+ if(!res) { /* success */
+
+ h = buf; /* result expected in h */
+
+ /* This is the worst kind of the different gethostbyname_r() interfaces.
+ * Since we don't know how big buffer this particular lookup required,
+ * we can't realloc down the huge alloc without doing closer analysis of
+ * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
+ * name lookup. Fixing this would require an extra malloc() and then
+ * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
+ * memory area to the actually used amount.
+ */
+ }
+ else
#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */
- {
- h = NULL; /* set return code to NULL */
- free(buf);
- }
+ {
+ h = NULL; /* set return code to NULL */
+ free(buf);
+ }
#else /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
- /*
- * Here is code for platforms that don't have a thread safe
- * getaddrinfo() nor gethostbyname_r() function or for which
- * gethostbyname() is the preferred one.
- */
- else {
- h = gethostbyname((void *)hostname);
+ /*
+ * Here is code for platforms that don't have a thread safe
+ * getaddrinfo() nor gethostbyname_r() function or for which
+ * gethostbyname() is the preferred one.
+ */
+ h = gethostbyname((void *)hostname);
#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
- }
if(h) {
ai = Curl_he2ai(h, port);
diff --git a/libs/libcurl/src/hostip6.c b/libs/libcurl/src/hostip6.c
index e0e0c58dfa..41ff986964 100644
--- a/libs/libcurl/src/hostip6.c
+++ b/libs/libcurl/src/hostip6.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
@@ -62,13 +62,19 @@
/*
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
*/
-bool Curl_ipv6works(void)
+bool Curl_ipv6works(struct connectdata *conn)
{
- /* the nature of most system is that IPv6 status doesn't come and go
- during a program's lifetime so we only probe the first time and then we
- have the info kept for fast re-use */
- static int ipv6_works = -1;
- if(-1 == ipv6_works) {
+ if(conn) {
+ /* the nature of most system is that IPv6 status doesn't come and go
+ during a program's lifetime so we only probe the first time and then we
+ have the info kept for fast re-use */
+ DEBUGASSERT(conn);
+ DEBUGASSERT(conn->data);
+ DEBUGASSERT(conn->data->multi);
+ return conn->data->multi->ipv6_works;
+ }
+ else {
+ int ipv6_works = -1;
/* probe to see if we have a working IPv6 stack */
curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
if(s == CURL_SOCKET_BAD)
@@ -78,8 +84,8 @@ bool Curl_ipv6works(void)
ipv6_works = 1;
Curl_closesocket(NULL, s);
}
+ return (ipv6_works>0)?TRUE:FALSE;
}
- return (ipv6_works>0)?TRUE:FALSE;
}
/*
@@ -89,7 +95,7 @@ bool Curl_ipv6works(void)
bool Curl_ipvalid(struct connectdata *conn)
{
if(conn->ip_version == CURL_IPRESOLVE_V6)
- return Curl_ipv6works();
+ return Curl_ipv6works(conn);
return TRUE;
}
@@ -159,7 +165,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
break;
}
- if((pf != PF_INET) && !Curl_ipv6works())
+ if((pf != PF_INET) && !Curl_ipv6works(conn))
/* The stack seems to be a non-IPv6 one */
pf = PF_INET;
diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c
index 837f53c415..bff3adc170 100644
--- a/libs/libcurl/src/http.c
+++ b/libs/libcurl/src/http.c
@@ -344,7 +344,7 @@ static CURLcode http_output_bearer(struct connectdata *conn)
userp = &conn->allocptr.userpwd;
free(*userp);
*userp = aprintf("Authorization: Bearer %s\r\n",
- conn->oauth_bearer);
+ conn->data->set.str[STRING_BEARER]);
if(!*userp) {
result = CURLE_OUT_OF_MEMORY;
@@ -555,7 +555,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
CURLcode result = CURLE_OK;
unsigned long authmask = ~0ul;
- if(!conn->oauth_bearer)
+ if(!data->set.str[STRING_BEARER])
authmask &= (unsigned long)~CURLAUTH_BEARER;
if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
@@ -565,7 +565,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
if(data->state.authproblem)
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
- if((conn->bits.user_passwd || conn->oauth_bearer) &&
+ if((conn->bits.user_passwd || data->set.str[STRING_BEARER]) &&
((data->req.httpcode == 401) ||
(conn->bits.authneg && data->req.httpcode < 300))) {
pickhost = pickoneauth(&data->state.authhost, authmask);
@@ -641,9 +641,7 @@ output_auth_headers(struct connectdata *conn,
{
const char *auth = NULL;
CURLcode result = CURLE_OK;
-#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
struct Curl_easy *data = conn->data;
-#endif
#ifdef CURL_DISABLE_CRYPTO_AUTH
(void)request;
@@ -707,7 +705,7 @@ output_auth_headers(struct connectdata *conn,
}
if(authstatus->picked == CURLAUTH_BEARER) {
/* Bearer */
- if((!proxy && conn->oauth_bearer &&
+ if((!proxy && data->set.str[STRING_BEARER] &&
!Curl_checkheaders(conn, "Authorization:"))) {
auth = "Bearer";
result = http_output_bearer(conn);
@@ -765,7 +763,7 @@ Curl_http_output_auth(struct connectdata *conn,
authproxy = &data->state.authproxy;
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
- conn->bits.user_passwd || conn->oauth_bearer)
+ conn->bits.user_passwd || data->set.str[STRING_BEARER])
/* continue please */;
else {
authhost->done = TRUE;
@@ -1691,7 +1689,7 @@ static CURLcode expect100(struct Curl_easy *data,
CURLcode result = CURLE_OK;
data->state.expect100header = FALSE; /* default to false unless it is set
to TRUE below */
- if(use_http_1_1plus(data, conn) &&
+ if(!data->state.disableexpect && use_http_1_1plus(data, conn) &&
(conn->httpversion < 20)) {
/* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
Expect: 100-continue to the headers which actually speeds up post
@@ -2390,7 +2388,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return CURLE_OUT_OF_MEMORY;
}
}
- /* Extract the the URL to use in the request. Store in STRING_TEMP_URL for
+ /* Extract the URL to use in the request. Store in STRING_TEMP_URL for
clean-up reasons if the function returns before the free() further
down. */
uc = curl_url_get(h, CURLUPART_URL, &data->set.str[STRING_TEMP_URL], 0);
@@ -3046,6 +3044,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
if(result)
return result;
+ if(!postsize)
+ data->req.upload_done = TRUE;
if(data->req.writebytecount) {
/* if a request-body has been sent off, we make sure this progress is noted
@@ -3545,7 +3545,16 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
*/
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
if(!k->upload_done) {
- if(data->set.http_keep_sending_on_error) {
+ if((k->httpcode == 417) && data->state.expect100header) {
+ /* 417 Expectation Failed - try again without the Expect
+ header */
+ infof(data, "Got 417 while waiting for a 100\n");
+ data->state.disableexpect = TRUE;
+ DEBUGASSERT(!data->req.newurl);
+ data->req.newurl = strdup(conn->data->change.url);
+ Curl_done_sending(conn, k);
+ }
+ else if(data->set.http_keep_sending_on_error) {
infof(data, "HTTP error before end of send, keep sending\n");
if(k->exp100 > EXP100_SEND_DATA) {
k->exp100 = EXP100_SEND_DATA;
diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h
index 70d5dccec6..4c1825f60f 100644
--- a/libs/libcurl/src/http.h
+++ b/libs/libcurl/src/http.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
@@ -116,7 +116,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn);
*
*/
#ifndef EXPECT_100_THRESHOLD
-#define EXPECT_100_THRESHOLD 1024
+#define EXPECT_100_THRESHOLD (1024*1024)
#endif
#endif /* CURL_DISABLE_HTTP */
diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c
index 65f3513ee5..72b38a3f66 100644
--- a/libs/libcurl/src/http2.c
+++ b/libs/libcurl/src/http2.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
@@ -43,19 +43,11 @@
#define H2_BUFSIZE 32768
-#if (NGHTTP2_VERSION_NUM < 0x010000)
+#if (NGHTTP2_VERSION_NUM < 0x010c00)
#error too old nghttp2 version, upgrade!
#endif
-#if (NGHTTP2_VERSION_NUM > 0x010800)
-#define NGHTTP2_HAS_HTTP2_STRERROR 1
-#endif
-
-#if (NGHTTP2_VERSION_NUM >= 0x010900)
-/* nghttp2_session_callbacks_set_error_callback is present in nghttp2 1.9.0 or
- later */
-#define NGHTTP2_HAS_ERROR_CALLBACK 1
-#else
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
#define nghttp2_session_callbacks_set_error_callback(x,y)
#endif
@@ -63,7 +55,7 @@
#define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1
#endif
-#define HTTP2_HUGE_WINDOW_SIZE (1 << 30)
+#define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */
#ifdef DEBUG_HTTP2
#define H2BUGF(x) x
@@ -344,35 +336,6 @@ int Curl_http2_ver(char *p, size_t len)
return msnprintf(p, len, " nghttp2/%s", h2->version_str);
}
-/* HTTP/2 error code to name based on the Error Code Registry.
-https://tools.ietf.org/html/rfc7540#page-77
-nghttp2_error_code enums are identical.
-*/
-static const char *http2_strerror(uint32_t err)
-{
-#ifndef NGHTTP2_HAS_HTTP2_STRERROR
- const char *str[] = {
- "NO_ERROR", /* 0x0 */
- "PROTOCOL_ERROR", /* 0x1 */
- "INTERNAL_ERROR", /* 0x2 */
- "FLOW_CONTROL_ERROR", /* 0x3 */
- "SETTINGS_TIMEOUT", /* 0x4 */
- "STREAM_CLOSED", /* 0x5 */
- "FRAME_SIZE_ERROR", /* 0x6 */
- "REFUSED_STREAM", /* 0x7 */
- "CANCEL", /* 0x8 */
- "COMPRESSION_ERROR", /* 0x9 */
- "CONNECT_ERROR", /* 0xA */
- "ENHANCE_YOUR_CALM", /* 0xB */
- "INADEQUATE_SECURITY", /* 0xC */
- "HTTP_1_1_REQUIRED" /* 0xD */
- };
- return (err < sizeof(str) / sizeof(str[0])) ? str[err] : "unknown";
-#else
- return nghttp2_http2_strerror(err);
-#endif
-}
-
/*
* The implementation of nghttp2_send_callback type. Here we write |data| with
* size |length| to the network and return the number of bytes actually
@@ -838,7 +801,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
return 0;
}
H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
- http2_strerror(error_code), error_code, stream_id));
+ nghttp2_strerror(error_code), error_code, stream_id));
stream = data_s->req.protop;
if(!stream)
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -1138,8 +1101,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
return nread;
}
-#if defined(NGHTTP2_HAS_ERROR_CALLBACK) && \
- !defined(CURL_DISABLE_VERBOSE_STRINGS)
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
static int error_callback(nghttp2_session *session,
const char *msg,
size_t len,
@@ -1156,9 +1118,10 @@ static void populate_settings(struct connectdata *conn,
struct http_conn *httpc)
{
nghttp2_settings_entry *iv = httpc->local_settings;
+ DEBUGASSERT(conn->data);
iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
- iv[0].value = (uint32_t)Curl_multi_max_concurrent_streams(conn->data->multi);
+ iv[0].value = Curl_multi_max_concurrent_streams(conn->data->multi);
iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
iv[1].value = HTTP2_HUGE_WINDOW_SIZE;
@@ -1257,9 +1220,7 @@ static CURLcode http2_init(struct connectdata *conn)
/* nghttp2_on_header_callback */
nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header);
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
nghttp2_session_callbacks_set_error_callback(callbacks, error_callback);
-#endif
/* The nghttp2 session is not yet setup, do it */
rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn);
@@ -1457,7 +1418,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
}
else if(httpc->error_code != NGHTTP2_NO_ERROR) {
failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
- stream->stream_id, http2_strerror(httpc->error_code),
+ stream->stream_id, nghttp2_strerror(httpc->error_code),
httpc->error_code);
*err = CURLE_HTTP2_STREAM;
return -1;
@@ -1594,8 +1555,12 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
return ncopy;
}
- H2BUGF(infof(data, "http2_recv: easy %p (stream %u)\n",
- data, stream->stream_id));
+ H2BUGF(infof(data, "http2_recv: easy %p (stream %u) win %u/%u\n",
+ data, stream->stream_id,
+ nghttp2_session_get_local_window_size(httpc->h2),
+ nghttp2_session_get_stream_local_window_size(httpc->h2,
+ stream->stream_id)
+ ));
if((data->state.drain) && stream->memlen) {
H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
@@ -1626,7 +1591,6 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
stream->pausedata += nread;
stream->pauselen -= nread;
- infof(data, "%zd data bytes written\n", nread);
if(stream->pauselen == 0) {
H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
@@ -2264,7 +2228,6 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
}
}
-#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
rv = nghttp2_session_set_local_window_size(httpc->h2, NGHTTP2_FLAG_NONE, 0,
HTTP2_HUGE_WINDOW_SIZE);
if(rv != 0) {
@@ -2272,7 +2235,6 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
nghttp2_strerror(rv), rv);
return CURLE_HTTP2;
}
-#endif
/* we are going to copy mem to httpc->inbuf. This is required since
mem is part of buffer pointed by stream->mem, and callbacks
@@ -2330,6 +2292,51 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
return CURLE_OK;
}
+CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
+{
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->conn);
+ /* if it isn't HTTP/2, we're done */
+ if(!data->conn->proto.httpc.h2)
+ return CURLE_OK;
+#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
+ else {
+ struct HTTP *stream = data->req.protop;
+ struct http_conn *httpc = &data->conn->proto.httpc;
+ uint32_t window = !pause * HTTP2_HUGE_WINDOW_SIZE;
+ int rv = nghttp2_session_set_local_window_size(httpc->h2,
+ NGHTTP2_FLAG_NONE,
+ stream->stream_id,
+ window);
+ if(rv) {
+ failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
+ nghttp2_strerror(rv), rv);
+ return CURLE_HTTP2;
+ }
+
+ /* make sure the window update gets sent */
+ rv = h2_session_send(data, httpc->h2);
+ if(rv)
+ return CURLE_SEND_ERROR;
+
+ DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u\n",
+ window, stream->stream_id));
+
+#ifdef DEBUGBUILD
+ {
+ /* read out the stream local window again */
+ uint32_t window2 =
+ nghttp2_session_get_stream_local_window_size(httpc->h2,
+ stream->stream_id);
+ DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u\n",
+ window2, stream->stream_id));
+ }
+#endif
+ }
+#endif
+ return CURLE_OK;
+}
+
CURLcode Curl_http2_add_child(struct Curl_easy *parent,
struct Curl_easy *child,
bool exclusive)
diff --git a/libs/libcurl/src/http2.h b/libs/libcurl/src/http2.h
index 12d36eef9b..1989aff826 100644
--- a/libs/libcurl/src/http2.h
+++ b/libs/libcurl/src/http2.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
@@ -58,6 +58,7 @@ CURLcode Curl_http2_add_child(struct Curl_easy *parent,
void Curl_http2_remove_child(struct Curl_easy *parent,
struct Curl_easy *child);
void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
+CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause);
/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */
bool Curl_h2_http_1_1_error(struct connectdata *conn);
@@ -74,6 +75,7 @@ bool Curl_h2_http_1_1_error(struct connectdata *conn);
#define Curl_http2_add_child(x, y, z)
#define Curl_http2_remove_child(x, y)
#define Curl_http2_cleanup_dependencies(x)
+#define Curl_http2_stream_pause(x, y)
#define Curl_h2_http_1_1_error(x) 0
#endif
diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist
index 236ec4279b..f0001fee06 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.68.0</string>
+ <string>7.69.0</string>
<key>CFBundleName</key>
<string>libcurl</string>
@@ -27,9 +27,9 @@
<string>????</string>
<key>CFBundleShortVersionString</key>
- <string>libcurl 7.68.0</string>
+ <string>libcurl 7.69.0</string>
<key>CFBundleGetInfoString</key>
- <string>libcurl.plist 7.68.0</string>
+ <string>libcurl.plist 7.69.0</string>
</dict>
</plist>
diff --git a/libs/libcurl/src/llist.c b/libs/libcurl/src/llist.c
index f8769c2af8..e7c6f51dc7 100644
--- a/libs/libcurl/src/llist.c
+++ b/libs/libcurl/src/llist.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, 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
@@ -144,54 +144,3 @@ Curl_llist_count(struct curl_llist *list)
{
return list->size;
}
-
-/*
- * @unittest: 1300
- */
-void Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
- struct curl_llist *to_list,
- struct curl_llist_element *to_e)
-{
- /* Remove element from list */
- if(e == NULL || list->size == 0)
- return;
-
- if(e == list->head) {
- list->head = e->next;
-
- if(list->head == NULL)
- list->tail = NULL;
- else
- e->next->prev = NULL;
- }
- else {
- e->prev->next = e->next;
- if(!e->next)
- list->tail = e->prev;
- else
- e->next->prev = e->prev;
- }
-
- --list->size;
-
- /* Add element to to_list after to_e */
- if(to_list->size == 0) {
- to_list->head = e;
- to_list->head->prev = NULL;
- to_list->head->next = NULL;
- to_list->tail = e;
- }
- else {
- e->next = to_e->next;
- e->prev = to_e;
- if(to_e->next) {
- to_e->next->prev = e;
- }
- else {
- to_list->tail = e;
- }
- to_e->next = e;
- }
-
- ++to_list->size;
-}
diff --git a/libs/libcurl/src/llist.h b/libs/libcurl/src/llist.h
index a5e2ecbfb4..0178c42598 100644
--- a/libs/libcurl/src/llist.h
+++ b/libs/libcurl/src/llist.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
@@ -47,7 +47,4 @@ 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 *);
-void Curl_llist_move(struct curl_llist *, struct curl_llist_element *,
- struct curl_llist *, struct curl_llist_element *);
-
#endif /* HEADER_CURL_LLIST_H */
diff --git a/libs/libcurl/src/md4.c b/libs/libcurl/src/md4.c
index bbf8975081..38f1b2bc96 100644
--- a/libs/libcurl/src/md4.c
+++ b/libs/libcurl/src/md4.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
@@ -29,10 +29,16 @@
#ifdef USE_OPENSSL
#include <openssl/opensslconf.h>
-#endif
+#endif /* USE_OPENSSL */
+
#ifdef USE_MBEDTLS
#include <mbedtls/config.h>
+#include <mbedtls/version.h>
+
+#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
+ #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
#endif
+#endif /* USE_MBEDTLS */
#if defined(USE_GNUTLS_NETTLE)
@@ -65,10 +71,11 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
#include <gcrypt.h>
#include "curl_memory.h"
+
/* The last #include file should be: */
#include "memdebug.h"
-typedef struct gcry_md_hd_t MD4_CTX;
+typedef gcry_md_hd_t MD4_CTX;
static void MD4_Init(MD4_CTX *ctx)
{
@@ -82,52 +89,41 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
{
- memcpy(result, gcry_md_read(ctx, 0), MD4_DIGEST_LENGTH);
- gcry_md_close(ctx);
+ memcpy(result, gcry_md_read(*ctx, 0), MD4_DIGEST_LENGTH);
+ gcry_md_close(*ctx);
}
#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
/* When OpenSSL is available we use the MD4-functions from OpenSSL */
#include <openssl/md4.h>
-#elif defined(USE_SECTRANSP)
+#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
+ (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
+ (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
#include <CommonCrypto/CommonDigest.h>
#include "curl_memory.h"
+
/* The last #include file should be: */
#include "memdebug.h"
-typedef struct {
- void *data;
- unsigned long size;
-} MD4_CTX;
+typedef CC_MD4_CTX MD4_CTX;
static void MD4_Init(MD4_CTX *ctx)
{
- ctx->data = NULL;
- ctx->size = 0;
+ (void)CC_MD4_Init(ctx);
}
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
{
- if(ctx->data == NULL) {
- ctx->data = malloc(size);
- if(ctx->data != NULL) {
- memcpy(ctx->data, data, size);
- ctx->size = size;
- }
- }
+ (void)CC_MD4_Update(ctx, data, (CC_LONG)size);
}
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
{
- if(ctx->data != NULL) {
- (void)CC_MD4(ctx->data, (CC_LONG) ctx->size, result);
-
- Curl_safefree(ctx->data);
- ctx->size = 0;
- }
+ (void)CC_MD4_Final(result, ctx);
}
#elif defined(USE_WIN32_CRYPTO)
@@ -135,7 +131,8 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
#include <wincrypt.h>
#include "curl_memory.h"
- /* The last #include file should be: */
+
+/* The last #include file should be: */
#include "memdebug.h"
typedef struct {
@@ -156,7 +153,7 @@ static void MD4_Init(MD4_CTX *ctx)
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
{
- CryptHashData(ctx->hHash, data, (unsigned int) size, 0);
+ CryptHashData(ctx->hHash, (BYTE *)data, (unsigned int) size, 0);
}
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
@@ -179,6 +176,7 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
#include <mbedtls/md4.h>
#include "curl_memory.h"
+
/* The last #include file should be: */
#include "memdebug.h"
@@ -207,7 +205,11 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
{
if(ctx->data != NULL) {
+#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
mbedtls_md4(ctx->data, ctx->size, result);
+#else
+ (void) mbedtls_md4_ret(ctx->data, ctx->size, result);
+#endif
Curl_safefree(ctx->data);
ctx->size = 0;
@@ -505,9 +507,11 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
#endif /* CRYPTO LIBS */
-void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
+void Curl_md4it(unsigned char *output, const unsigned char *input,
+ const size_t len)
{
MD4_CTX ctx;
+
MD4_Init(&ctx);
MD4_Update(&ctx, input, curlx_uztoui(len));
MD4_Final(output, &ctx);
diff --git a/libs/libcurl/src/md5.c b/libs/libcurl/src/md5.c
index 2b81ca455a..3f601b3a42 100644
--- a/libs/libcurl/src/md5.c
+++ b/libs/libcurl/src/md5.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
@@ -30,6 +30,14 @@
#include "curl_hmac.h"
#include "warnless.h"
+#ifdef USE_MBEDTLS
+#include <mbedtls/version.h>
+
+#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
+ #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
+#endif
+#endif /* USE_MBEDTLS */
+
#if defined(USE_GNUTLS_NETTLE)
#include <nettle/md5.h>
@@ -51,7 +59,7 @@ static void MD5_Update(MD5_CTX *ctx,
md5_update(ctx, inputLen, input);
}
-static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
{
md5_digest(ctx, 16, digest);
}
@@ -77,7 +85,7 @@ static void MD5_Update(MD5_CTX *ctx,
gcry_md_write(*ctx, input, inputLen);
}
-static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
{
memcpy(digest, gcry_md_read(*ctx, 0), 16);
gcry_md_close(*ctx);
@@ -90,6 +98,46 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
/* The last #include file should be: */
#include "memdebug.h"
+#elif defined(USE_MBEDTLS)
+
+#include <mbedtls/md5.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef mbedtls_md5_context MD5_CTX;
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
+ mbedtls_md5_starts(ctx);
+#else
+ (void) mbedtls_md5_starts_ret(ctx);
+#endif
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+ const unsigned char *data,
+ unsigned int length)
+{
+#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
+ mbedtls_md5_update(ctx, data, length);
+#else
+ (void) mbedtls_md5_update_ret(ctx, data, length);
+#endif
+}
+
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
+{
+#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
+ mbedtls_md5_finish(ctx, digest);
+#else
+ (void) mbedtls_md5_finish_ret(ctx, digest);
+#endif
+}
+
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
@@ -119,12 +167,12 @@ static void MD5_Update(MD5_CTX *ctx,
CC_MD5_Update(ctx, input, inputLen);
}
-static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
{
CC_MD5_Final(digest, ctx);
}
-#elif defined(WIN32) && !defined(CURL_WINDOWS_APP)
+#elif defined(USE_WIN32_CRYPTO)
#include <wincrypt.h>
#include "curl_memory.h"
@@ -151,7 +199,7 @@ static void MD5_Update(MD5_CTX *ctx,
CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
}
-static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
{
unsigned long length = 0;
CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
@@ -164,7 +212,9 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
}
#else
+
/* When no other crypto library is available we use this code segment */
+
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD5 Message-Digest Algorithm (RFC 1321).
@@ -513,12 +563,13 @@ const MD5_params Curl_DIGEST_MD5[] = {
/*
* @unittest: 1601
*/
-void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
- const unsigned char *input)
+void Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
+ const size_t len)
{
MD5_CTX ctx;
+
MD5_Init(&ctx);
- MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
+ MD5_Update(&ctx, input, curlx_uztoui(len));
MD5_Final(outbuffer, &ctx);
}
diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c
index 081e51e508..2571287c6a 100644
--- a/libs/libcurl/src/mime.c
+++ b/libs/libcurl/src/mime.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
diff --git a/libs/libcurl/src/mime.h b/libs/libcurl/src/mime.h
index 3241fdc1f7..4312125796 100644
--- a/libs/libcurl/src/mime.h
+++ b/libs/libcurl/src/mime.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
diff --git a/libs/libcurl/src/mk-ca-bundle.pl b/libs/libcurl/src/mk-ca-bundle.pl
index 33977f3226..09e8e5b9bb 100644
--- a/libs/libcurl/src/mk-ca-bundle.pl
+++ b/libs/libcurl/src/mk-ca-bundle.pl
@@ -6,7 +6,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
@@ -38,6 +38,7 @@ use warnings;
use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_k $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
use List::Util;
use Text::Wrap;
+use Time::Local;
my $MOD_SHA = "Digest::SHA";
eval "require $MOD_SHA";
if ($@) {
@@ -421,6 +422,8 @@ my $certnum = 0;
my $skipnum = 0;
my $start_of_cert = 0;
my @precert;
+my $cka_value;
+my $valid = 1;
open(TXT,"$txt") or die "Couldn't open $txt: $!\n";
while (<TXT>) {
@@ -435,6 +438,7 @@ while (<TXT>) {
}
elsif(/^# (Issuer|Serial Number|Subject|Not Valid Before|Not Valid After |Fingerprint \(MD5\)|Fingerprint \(SHA1\)):/) {
push @precert, $_;
+ $valid = 1;
next;
}
elsif(/^#|^\s*$/) {
@@ -443,6 +447,49 @@ while (<TXT>) {
}
chomp;
+ # Example:
+ # CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
+ # \062\060\060\066\061\067\060\060\060\060\060\060\132
+ # END
+
+ if (/^CKA_NSS_SERVER_DISTRUST_AFTER (CK_BBOOL CK_FALSE|MULTILINE_OCTAL)/) {
+ if($1 eq "MULTILINE_OCTAL") {
+ my @timestamp;
+ while (<TXT>) {
+ last if (/^END/);
+ chomp;
+ my @octets = split(/\\/);
+ shift @octets;
+ for (@octets) {
+ push @timestamp, chr(oct);
+ }
+ }
+ # A trailing Z in the timestamp signifies UTC
+ if($timestamp[12] ne "Z") {
+ report "distrust date stamp is not using UTC";
+ }
+ # Example date: 200617000000Z
+ # Means 2020-06-17 00:00:00 UTC
+ my $distrustat =
+ timegm($timestamp[10] . $timestamp[11], # second
+ $timestamp[8] . $timestamp[9], # minute
+ $timestamp[6] . $timestamp[7], # hour
+ $timestamp[4] . $timestamp[5], # day
+ ($timestamp[2] . $timestamp[3]) - 1, # month
+ "20" . $timestamp[0] . $timestamp[1]); # year
+ if(time >= $distrustat) {
+ # not trusted anymore
+ $skipnum++;
+ report "Skipping: $caname is not trusted anymore" if ($opt_v);
+ $valid = 0;
+ }
+ else {
+ # still trusted
+ }
+ }
+ next;
+ }
+
# this is a match for the start of a certificate
if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) {
$start_of_cert = 1
@@ -452,21 +499,18 @@ while (<TXT>) {
}
my %trust_purposes_by_level;
if ($start_of_cert && /^CKA_VALUE MULTILINE_OCTAL/) {
- my $data;
+ $cka_value="";
while (<TXT>) {
last if (/^END/);
chomp;
my @octets = split(/\\/);
shift @octets;
for (@octets) {
- $data .= chr(oct);
+ $cka_value .= chr(oct);
}
}
- # scan forwards until the trust part
- while (<TXT>) {
- last if (/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/);
- chomp;
- }
+ }
+ if(/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/ && $valid) {
# now scan the trust part to determine how we should trust this cert
while (<TXT>) {
last if (/^#/);
@@ -485,6 +529,8 @@ while (<TXT>) {
$skipnum ++;
report "Skipping: $caname" if ($opt_v);
} else {
+ my $data = $cka_value;
+ $cka_value = "";
my $encoded = MIME::Base64::encode_base64($data, '');
$encoded =~ s/(.{1,${opt_w}})/$1\n/g;
my $pem = "-----BEGIN CERTIFICATE-----\n"
diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c
index 6d819b4aaa..cef2805c8e 100644
--- a/libs/libcurl/src/multi.c
+++ b/libs/libcurl/src/multi.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
@@ -47,6 +47,7 @@
#include "http_proxy.h"
#include "http2.h"
#include "socketpair.h"
+#include "socks.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -369,6 +370,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
/* -1 means it not set by user, use the default value */
multi->maxconnects = -1;
+ multi->max_concurrent_streams = 100;
+ multi->ipv6_works = Curl_ipv6works(NULL);
#ifdef ENABLE_WAKEUP
if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) {
@@ -590,6 +593,9 @@ static CURLcode multi_done(struct Curl_easy *data,
detach_connnection(data);
if(CONN_INUSE(conn)) {
/* Stop if still used. */
+ /* conn->data must not remain pointing to this transfer since it is going
+ away! Find another to own it! */
+ conn->data = conn->easyq.head->ptr;
CONN_UNLOCK(data);
DEBUGF(infof(data, "Connection still in use %zu, "
"no more multi_done now!\n",
@@ -725,8 +731,8 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
we don't leave a half-baked one around */
if(easy_owns_conn) {
- /* multi_done() clears the conn->data field to lose the association
- between the easy handle and the connection
+ /* multi_done() clears the association between the easy handle and the
+ connection.
Note that this ignores the return code simply because there's
nothing really useful to do with it anyway! */
@@ -851,6 +857,9 @@ static int waitconnect_getsock(struct connectdata *conn,
return Curl_ssl_getsock(conn, sock);
#endif
+ if(SOCKS_STATE(conn->cnnct.state))
+ return Curl_SOCKS_getsock(conn, sock, FIRSTSOCKET);
+
for(i = 0; i<2; i++) {
if(conn->tempsock[i] != CURL_SOCKET_BAD) {
sock[s] = conn->tempsock[i];
@@ -1048,6 +1057,9 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
if(multi->in_callback)
return CURLM_RECURSIVE_API_CALL;
+ if(timeout_ms < 0)
+ return CURLM_BAD_FUNCTION_ARGUMENT;
+
/* Count up how many fds we have from the multi handle */
data = multi->easyp;
while(data) {
@@ -1187,7 +1199,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
data from it until it receives an error (except EINTR).
In normal cases it will get EAGAIN or EWOULDBLOCK
when there is no more data, breaking the loop. */
- if(sread(multi->wakeup_pair[0], buf, sizeof(buf)) < 0) {
+ if(sread(multi->wakeup_pair[0], buf, sizeof(buf)) <= 0) {
#ifndef USE_WINSOCK
if(EINTR == SOCKERRNO)
continue;
@@ -2183,8 +2195,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
}
}
- else if(comeback)
- rc = CURLM_CALL_MULTI_PERFORM;
+ else if(comeback) {
+ /* This avoids CURLM_CALL_MULTI_PERFORM so that a very fast transfer
+ won't get stuck on this transfer at the expense of other concurrent
+ transfers */
+ Curl_expire(data, 0, EXPIRE_RUN_NOW);
+ rc = CURLM_OK;
+ }
break;
}
@@ -2897,8 +2914,8 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi,
if(streams < 1)
streams = 100;
multi->max_concurrent_streams =
- (streams > (long)INITIAL_MAX_CONCURRENT_STREAMS)?
- (long)INITIAL_MAX_CONCURRENT_STREAMS : streams;
+ (streams > (long)INITIAL_MAX_CONCURRENT_STREAMS)?
+ INITIAL_MAX_CONCURRENT_STREAMS : (unsigned int)streams;
}
break;
default:
@@ -3340,8 +3357,8 @@ void Curl_multi_dump(struct Curl_multi *multi)
}
#endif
-size_t Curl_multi_max_concurrent_streams(struct Curl_multi *multi)
+unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi)
{
- return multi ? ((size_t)multi->max_concurrent_streams ?
- (size_t)multi->max_concurrent_streams : 100) : 0;
+ DEBUGASSERT(multi);
+ return multi->max_concurrent_streams;
}
diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h
index 0bf09e6bb5..91eca16c4a 100644
--- a/libs/libcurl/src/multihandle.h
+++ b/libs/libcurl/src/multihandle.h
@@ -119,11 +119,6 @@ struct Curl_multi {
same actual socket) */
struct curl_hash sockhash;
- /* multiplexing wanted */
- bool multiplexing;
-
- bool recheckstate; /* see Curl_multi_connchanged */
-
/* Shared connection cache (bundles)*/
struct conncache conn_cache;
@@ -141,13 +136,17 @@ struct Curl_multi {
void *timer_userp;
struct curltime timer_lastcall; /* the fixed time for the timeout for the
previous callback */
- bool in_callback; /* true while executing a callback */
- long max_concurrent_streams; /* max concurrent streams client to support */
+ unsigned int max_concurrent_streams;
#ifdef ENABLE_WAKEUP
curl_socket_t wakeup_pair[2]; /* socketpair() used for wakeup
0 is used for read, 1 is used for write */
#endif
+ /* multiplexing wanted */
+ bool multiplexing;
+ bool recheckstate; /* see Curl_multi_connchanged */
+ bool in_callback; /* true while executing a callback */
+ bool ipv6_works;
};
#endif /* HEADER_CURL_MULTIHANDLE_H */
diff --git a/libs/libcurl/src/multiif.h b/libs/libcurl/src/multiif.h
index 75025232c4..bde755ee0f 100644
--- a/libs/libcurl/src/multiif.h
+++ b/libs/libcurl/src/multiif.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
@@ -90,9 +90,7 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
struct connectdata *conn);
-/* Return the value of the CURLMOPT_MAX_CONCURRENT_STREAMS option
- * If not specified or 0, default would be 100
- */
-size_t Curl_multi_max_concurrent_streams(struct Curl_multi *multi);
+/* Return the value of the CURLMOPT_MAX_CONCURRENT_STREAMS option */
+unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi);
#endif /* HEADER_CURL_MULTIIF_H */
diff --git a/libs/libcurl/src/rename.c b/libs/libcurl/src/rename.c
new file mode 100644
index 0000000000..bb170d3cc7
--- /dev/null
+++ b/libs/libcurl/src/rename.c
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.
+ *
+ ***************************************************************************/
+
+#include "rename.h"
+
+#include "curl_setup.h"
+
+#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)) || \
+ defined(USE_ALTSVC)
+
+#include "timeval.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* return 0 on success, 1 on error */
+int Curl_rename(const char *oldpath, const char *newpath)
+{
+#ifdef WIN32
+ /* rename() on Windows doesn't overwrite, so we can't use it here.
+ MoveFileExA() will overwrite and is usually atomic, however it fails
+ when there are open handles to the file. */
+ const int max_wait_ms = 1000;
+ struct curltime start = Curl_now();
+ for(;;) {
+ timediff_t diff;
+ if(MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
+ break;
+ diff = Curl_timediff(Curl_now(), start);
+ if(diff < 0 || diff > max_wait_ms)
+ return 1;
+ Sleep(1);
+ }
+#else
+ if(rename(oldpath, newpath))
+ return 1;
+#endif
+ return 0;
+}
+
+#endif
diff --git a/libs/libcurl/src/rename.h b/libs/libcurl/src/rename.h
new file mode 100644
index 0000000000..d7442c8447
--- /dev/null
+++ b/libs/libcurl/src/rename.h
@@ -0,0 +1,27 @@
+#ifndef HEADER_CURL_RENAME_H
+#define HEADER_CURL_RENAME_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.
+ *
+ ***************************************************************************/
+
+int Curl_rename(const char *oldpath, const char *newpath);
+
+#endif /* HEADER_CURL_RENAME_H */
diff --git a/libs/libcurl/src/select.c b/libs/libcurl/src/select.c
index 2de503d370..b372efff10 100644
--- a/libs/libcurl/src/select.c
+++ b/libs/libcurl/src/select.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
@@ -53,9 +53,6 @@
/* Convenience local macros */
#define ELAPSED_MS() (int)Curl_timediff(Curl_now(), initial_tv)
-int Curl_ack_eintr = 0;
-#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
-
/*
* Internal function used for waiting a specific amount of ms
* in Curl_socket_check() and Curl_poll() when no file descriptor
@@ -74,13 +71,6 @@ int Curl_ack_eintr = 0;
*/
int Curl_wait_ms(int timeout_ms)
{
-#if !defined(MSDOS) && !defined(USE_WINSOCK)
-#ifndef HAVE_POLL_FINE
- struct timeval pending_tv;
-#endif
- struct curltime initial_tv;
- int pending_ms;
-#endif
int r = 0;
if(!timeout_ms)
@@ -94,28 +84,16 @@ int Curl_wait_ms(int timeout_ms)
#elif defined(USE_WINSOCK)
Sleep(timeout_ms);
#else
- pending_ms = timeout_ms;
- initial_tv = Curl_now();
- do {
- int error;
#if defined(HAVE_POLL_FINE)
- r = poll(NULL, 0, pending_ms);
+ r = poll(NULL, 0, timeout_ms);
#else
- pending_tv.tv_sec = pending_ms / 1000;
- pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+ {
+ struct timeval pending_tv;
+ pending_tv.tv_sec = timeout_ms / 1000;
+ pending_tv.tv_usec = (timeout_ms % 1000) * 1000;
r = select(0, NULL, NULL, NULL, &pending_tv);
+ }
#endif /* HAVE_POLL_FINE */
- if(r != -1)
- break;
- error = SOCKERRNO;
- if(error && ERROR_NOT_EINTR(error))
- break;
- pending_ms = timeout_ms - ELAPSED_MS();
- if(pending_ms <= 0) {
- r = 0; /* Simulate a "call timed out" case */
- break;
- }
- } while(r == -1);
#endif /* USE_WINSOCK */
if(r)
r = -1;
@@ -158,7 +136,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
fd_set fds_err;
curl_socket_t maxfd;
#endif
- struct curltime initial_tv = {0, 0};
int pending_ms = 0;
int r;
int ret;
@@ -183,7 +160,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
if(timeout_ms > 0) {
pending_ms = (int)timeout_ms;
- initial_tv = Curl_now();
}
#ifdef HAVE_POLL_FINE
@@ -208,26 +184,11 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
num++;
}
- do {
- int error;
- if(timeout_ms < 0)
- pending_ms = -1;
- else if(!timeout_ms)
- pending_ms = 0;
- r = poll(pfd, num, pending_ms);
- if(r != -1)
- break;
- error = SOCKERRNO;
- if(error && ERROR_NOT_EINTR(error))
- break;
- if(timeout_ms > 0) {
- pending_ms = (int)(timeout_ms - ELAPSED_MS());
- if(pending_ms <= 0) {
- r = 0; /* Simulate a "call timed out" case */
- break;
- }
- }
- } while(r == -1);
+ if(timeout_ms < 0)
+ pending_ms = -1;
+ else if(!timeout_ms)
+ pending_ms = 0;
+ r = poll(pfd, num, pending_ms);
if(r < 0)
return -1;
@@ -290,61 +251,45 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
- do {
- int error;
- if(timeout_ms > 0) {
- pending_tv.tv_sec = pending_ms / 1000;
- pending_tv.tv_usec = (pending_ms % 1000) * 1000;
- }
- else if(!timeout_ms) {
- pending_tv.tv_sec = 0;
- pending_tv.tv_usec = 0;
- }
+ if(timeout_ms > 0) {
+ pending_tv.tv_sec = pending_ms / 1000;
+ pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+ }
+ else if(!timeout_ms) {
+ pending_tv.tv_sec = 0;
+ pending_tv.tv_usec = 0;
+ }
- /* WinSock select() must not be called with an fd_set that contains zero
- fd flags, or it will return WSAEINVAL. But, it also can't be called
- with no fd_sets at all! From the documentation:
+ /* WinSock select() must not be called with an fd_set that contains zero
+ fd flags, or it will return WSAEINVAL. But, it also can't be called
+ with no fd_sets at all! From the documentation:
- Any two of the parameters, readfds, writefds, or exceptfds, can be
- given as null. At least one must be non-null, and any non-null
- descriptor set must contain at least one handle to a socket.
+ Any two of the parameters, readfds, writefds, or exceptfds, can be
+ given as null. At least one must be non-null, and any non-null
+ descriptor set must contain at least one handle to a socket.
- 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.
+ 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.
- It is unclear why WinSock doesn't just handle this for us instead of
- calling this an error.
+ It is unclear why WinSock doesn't just handle this for us instead of
+ calling this an error.
- 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).
- */
+ 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).
+ */
#ifdef USE_WINSOCK
- r = select((int)maxfd + 1,
- fds_read.fd_count ? &fds_read : NULL,
- fds_write.fd_count ? &fds_write : NULL,
- &fds_err, ptimeout);
+ r = select((int)maxfd + 1,
+ fds_read.fd_count ? &fds_read : NULL,
+ fds_write.fd_count ? &fds_write : NULL,
+ &fds_err, ptimeout);
#else
- r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
+ r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
#endif
- if(r != -1)
- break;
- error = SOCKERRNO;
- if(error && ERROR_NOT_EINTR(error))
- break;
- if(timeout_ms > 0) {
- pending_ms = (int)(timeout_ms - ELAPSED_MS());
- if(pending_ms <= 0) {
- r = 0; /* Simulate a "call timed out" case */
- break;
- }
- }
- } while(r == -1);
-
if(r < 0)
return -1;
if(r == 0)
@@ -399,7 +344,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
fd_set fds_err;
curl_socket_t maxfd;
#endif
- struct curltime initial_tv = {0, 0};
bool fds_none = TRUE;
unsigned int i;
int pending_ms = 0;
@@ -425,31 +369,15 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
if(timeout_ms > 0) {
pending_ms = timeout_ms;
- initial_tv = Curl_now();
}
#ifdef HAVE_POLL_FINE
- do {
- int error;
- if(timeout_ms < 0)
- pending_ms = -1;
- else if(!timeout_ms)
- pending_ms = 0;
- r = poll(ufds, nfds, pending_ms);
- if(r != -1)
- break;
- error = SOCKERRNO;
- if(error && ERROR_NOT_EINTR(error))
- break;
- if(timeout_ms > 0) {
- pending_ms = (int)(timeout_ms - ELAPSED_MS());
- if(pending_ms <= 0) {
- r = 0; /* Simulate a "call timed out" case */
- break;
- }
- }
- } while(r == -1);
+ if(timeout_ms < 0)
+ pending_ms = -1;
+ else if(!timeout_ms)
+ pending_ms = 0;
+ r = poll(ufds, nfds, pending_ms);
if(r < 0)
return -1;
@@ -502,42 +430,27 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
- do {
- int error;
- if(timeout_ms > 0) {
- pending_tv.tv_sec = pending_ms / 1000;
- pending_tv.tv_usec = (pending_ms % 1000) * 1000;
- }
- else if(!timeout_ms) {
- pending_tv.tv_sec = 0;
- pending_tv.tv_usec = 0;
- }
+ if(timeout_ms > 0) {
+ pending_tv.tv_sec = pending_ms / 1000;
+ pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+ }
+ else if(!timeout_ms) {
+ pending_tv.tv_sec = 0;
+ pending_tv.tv_usec = 0;
+ }
#ifdef USE_WINSOCK
- r = select((int)maxfd + 1,
- /* WinSock select() can't handle fd_sets with zero bits set, so
- don't give it such arguments. See the comment about this in
- Curl_check_socket().
- */
- fds_read.fd_count ? &fds_read : NULL,
- fds_write.fd_count ? &fds_write : NULL,
- fds_err.fd_count ? &fds_err : NULL, ptimeout);
+ r = select((int)maxfd + 1,
+ /* WinSock select() can't handle fd_sets with zero bits set, so
+ don't give it such arguments. See the comment about this in
+ Curl_check_socket().
+ */
+ fds_read.fd_count ? &fds_read : NULL,
+ fds_write.fd_count ? &fds_write : NULL,
+ fds_err.fd_count ? &fds_err : NULL, ptimeout);
#else
- r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
+ r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
#endif
- if(r != -1)
- break;
- error = SOCKERRNO;
- if(error && ERROR_NOT_EINTR(error))
- break;
- if(timeout_ms > 0) {
- pending_ms = timeout_ms - ELAPSED_MS();
- if(pending_ms <= 0) {
- r = 0; /* Simulate a "call timed out" case */
- break;
- }
- }
- } while(r == -1);
if(r < 0)
return -1;
diff --git a/libs/libcurl/src/select.h b/libs/libcurl/src/select.h
index 687ab164c4..ec3021aac2 100644
--- a/libs/libcurl/src/select.h
+++ b/libs/libcurl/src/select.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
@@ -75,20 +75,12 @@ struct pollfd
int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
curl_socket_t writefd,
time_t timeout_ms);
-
#define SOCKET_READABLE(x,z) \
Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, (time_t)z)
#define SOCKET_WRITABLE(x,z) \
Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, (time_t)z)
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
-
-/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set,
- * EINTR condition is honored and function might exit early without
- * awaiting full timeout. Otherwise EINTR will be ignored and full
- * timeout will elapse. */
-extern int Curl_ack_eintr;
-
int Curl_wait_ms(int timeout_ms);
#ifdef TPF
diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c
index 6c38b04b23..6ef47aa801 100644
--- a/libs/libcurl/src/sendf.c
+++ b/libs/libcurl/src/sendf.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
@@ -43,6 +43,7 @@
#include "strerror.h"
#include "select.h"
#include "strdup.h"
+#include "http2.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -501,6 +502,9 @@ static CURLcode pausewrite(struct Curl_easy *data,
unsigned int i;
bool newtype = TRUE;
+ /* If this transfers over HTTP/2, pause the stream! */
+ Curl_http2_stream_pause(data, TRUE);
+
if(s->tempcount) {
for(i = 0; i< s->tempcount; i++) {
if(s->tempwrite[i].type == type) {
@@ -529,6 +533,8 @@ static CURLcode pausewrite(struct Curl_easy *data,
/* update the pointer and the size */
s->tempwrite[i].buf = newptr;
s->tempwrite[i].len = newlen;
+
+ len = newlen; /* for the debug output below */
}
else {
dupl = Curl_memdup(ptr, len);
@@ -692,19 +698,20 @@ CURLcode Curl_read_plain(curl_socket_t sockfd,
ssize_t nread = sread(sockfd, buf, bytesfromsocket);
if(-1 == nread) {
- int err = SOCKERRNO;
- int return_error;
+ const int err = SOCKERRNO;
+ const bool return_error =
#ifdef USE_WINSOCK
- return_error = WSAEWOULDBLOCK == err;
+ WSAEWOULDBLOCK == err
#else
- return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err;
+ EWOULDBLOCK == err || EAGAIN == err || EINTR == err
#endif
+ ;
+ *n = 0; /* no data returned */
if(return_error)
return CURLE_AGAIN;
return CURLE_RECV_ERROR;
}
- /* we only return number of bytes read when we return OK */
*n = nread;
return CURLE_OK;
}
diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c
index 5f88ad3afd..2e494a6df9 100644
--- a/libs/libcurl/src/setopt.c
+++ b/libs/libcurl/src/setopt.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
@@ -2288,7 +2288,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_SSH_KEYFUNCTION:
/* setting to NULL is fine since the ssh.c functions themselves will
- then rever to use the internal default */
+ then revert to use the internal default */
data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
break;
@@ -2391,6 +2391,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
/* Set the list of mail recipients */
data->set.mail_rcpt = va_arg(param, struct curl_slist *);
break;
+ case CURLOPT_MAIL_RCPT_ALLLOWFAILS:
+ /* allow RCPT TO command to fail for some recipients */
+ data->set.mail_rcpt_allowfails = (0 != va_arg(param, long)) ? TRUE : FALSE;
+ break;
#endif
case CURLOPT_SASL_AUTHZID:
diff --git a/libs/libcurl/src/sha256.c b/libs/libcurl/src/sha256.c
index bcaaeae308..97214182be 100644
--- a/libs/libcurl/src/sha256.c
+++ b/libs/libcurl/src/sha256.c
@@ -5,7 +5,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Florin Petriuc, <petriuc.florin@gmail.com>
+ * Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com>
+ * Copyright (C) 2018 - 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
@@ -35,16 +36,135 @@
#define USE_OPENSSL_SHA256
#endif
+#endif /* USE_OPENSSL */
+
+#ifdef USE_MBEDTLS
+#include <mbedtls/version.h>
+
+#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
+ #define HAS_RESULT_CODE_BASED_FUNCTIONS
#endif
+#endif /* USE_MBEDTLS */
+
+/* Please keep the SSL backend-specific #if branches in this order:
+ *
+ * 1. USE_OPENSSL
+ * 2. USE_GNUTLS_NETTLE
+ * 3. USE_GNUTLS
+ * 4. USE_MBEDTLS
+ * 5. USE_COMMON_CRYPTO
+ * 6. USE_WIN32_CRYPTO
+ *
+ * This ensures that the same SSL branch gets activated throughout this source
+ * file even if multiple backends are enabled at the same time.
+ */
+
+#if defined(USE_OPENSSL_SHA256)
-#ifdef USE_OPENSSL_SHA256
/* When OpenSSL is available we use the SHA256-function from OpenSSL */
#include <openssl/sha.h>
+
+#elif defined(USE_GNUTLS_NETTLE)
+
+#include <nettle/sha.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct sha256_ctx SHA256_CTX;
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+ sha256_init(ctx);
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+ const unsigned char *data,
+ unsigned int length)
+{
+ sha256_update(ctx, length, data);
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+ sha256_digest(ctx, SHA256_DIGEST_SIZE, digest);
+}
+
+#elif defined(USE_GNUTLS)
+
+#include <gcrypt.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef gcry_md_hd_t SHA256_CTX;
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_SHA256, 0);
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+ const unsigned char *data,
+ unsigned int length)
+{
+ gcry_md_write(*ctx, data, length);
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+ memcpy(digest, gcry_md_read(*ctx, 0), SHA256_DIGEST_LENGTH);
+ gcry_md_close(*ctx);
+}
+
+#elif defined(USE_MBEDTLS)
+
+#include <mbedtls/sha256.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef mbedtls_sha256_context SHA256_CTX;
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+#if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
+ mbedtls_sha256_starts(ctx, 0);
+#else
+ (void) mbedtls_sha256_starts_ret(ctx, 0);
+#endif
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+ const unsigned char *data,
+ unsigned int length)
+{
+#if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
+ mbedtls_sha256_update(ctx, data, length);
+#else
+ (void) mbedtls_sha256_update_ret(ctx, data, length);
+#endif
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+#if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
+ mbedtls_sha256_finish(ctx, digest);
+#else
+ (void) mbedtls_sha256_finish_ret(ctx, digest);
+#endif
+}
+
#else
/* When no other crypto library is available we use this code segment */
-/* ===== start - public domain SHA256 implementation ===== */
/* This is based on SHA256 implementation in LibTomCrypt that was released into
* public domain by Tom St Denis. */
@@ -95,7 +215,8 @@ typedef struct sha256_state {
unsigned long state[8], curlen;
unsigned char buf[64];
} SHA256_CTX;
-/* the K array */
+
+/* The K array */
static const unsigned long K[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
@@ -111,6 +232,7 @@ static const unsigned long K[64] = {
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
+
/* Various logical functions */
#define RORc(x, y) \
(((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
@@ -123,13 +245,15 @@ static const unsigned long K[64] = {
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
-/* compress 512-bits */
+
+/* Compress 512-bits */
static int sha256_compress(struct sha256_state *md,
unsigned char *buf)
{
unsigned long S[8], W[64];
int i;
- /* copy state into S */
+
+ /* Copy state into S */
for(i = 0; i < 8; i++) {
S[i] = md->state[i];
}
@@ -141,6 +265,7 @@ static int sha256_compress(struct sha256_state *md,
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
W[i - 16];
}
+
/* Compress */
#define RND(a,b,c,d,e,f,g,h,i) \
unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
@@ -153,12 +278,15 @@ static int sha256_compress(struct sha256_state *md,
t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
}
- /* feedback */
+
+ /* Feedback */
for(i = 0; i < 8; i++) {
md->state[i] = md->state[i] + S[i];
}
+
return 0;
}
+
/* Initialize the hash state */
static void SHA256_Init(struct sha256_state *md)
{
@@ -173,7 +301,8 @@ static void SHA256_Init(struct sha256_state *md)
md->state[6] = 0x1F83D9ABUL;
md->state[7] = 0x5BE0CD19UL;
}
-/**
+
+/*
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@@ -185,6 +314,7 @@ static int SHA256_Update(struct sha256_state *md,
unsigned long inlen)
{
unsigned long n;
+
#define block_size 64
if(md->curlen > sizeof(md->buf))
return -1;
@@ -210,9 +340,11 @@ static int SHA256_Update(struct sha256_state *md,
}
}
}
+
return 0;
}
-/**
+
+/*
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (32 bytes)
@@ -222,13 +354,17 @@ static int SHA256_Final(unsigned char *out,
struct sha256_state *md)
{
int i;
+
if(md->curlen >= sizeof(md->buf))
return -1;
- /* increase the length of the message */
+
+ /* Increase the length of the message */
md->length += md->curlen * 8;
- /* append the '1' bit */
+
+ /* Append the '1' bit */
md->buf[md->curlen++] = (unsigned char)0x80;
- /* if the length is currently above 56 bytes we append zeros
+
+ /* If the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
@@ -239,29 +375,44 @@ static int SHA256_Final(unsigned char *out,
sha256_compress(md, md->buf);
md->curlen = 0;
}
- /* pad up to 56 bytes of zeroes */
+
+ /* Pad up to 56 bytes of zeroes */
while(md->curlen < 56) {
md->buf[md->curlen++] = (unsigned char)0;
}
- /* store length */
+
+ /* Store length */
WPA_PUT_BE64(md->buf + 56, md->length);
sha256_compress(md, md->buf);
- /* copy output */
+
+ /* Copy output */
for(i = 0; i < 8; i++)
WPA_PUT_BE32(out + (4 * i), md->state[i]);
+
return 0;
}
-/* ===== end - public domain SHA256 implementation ===== */
-#endif
+#endif /* CRYPTO LIBS */
-void Curl_sha256it(unsigned char *outbuffer, /* 32 unsigned chars */
- const unsigned char *input)
+/*
+ * Curl_sha256it()
+ *
+ * Generates a SHA256 hash for the given input data.
+ *
+ * Parameters:
+ *
+ * output [in/out] - The output buffer.
+ * input [in] - The input data.
+ * length [in] - The input length.
+ */
+void Curl_sha256it(unsigned char *output, const unsigned char *input,
+ const size_t length)
{
SHA256_CTX ctx;
+
SHA256_Init(&ctx);
- SHA256_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
- SHA256_Final(outbuffer, &ctx);
+ SHA256_Update(&ctx, input, curlx_uztoui(length));
+ SHA256_Final(output, &ctx);
}
#endif /* CURL_DISABLE_CRYPTO_AUTH */
diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c
index 65220b0f68..e1872871dc 100644
--- a/libs/libcurl/src/smtp.c
+++ b/libs/libcurl/src/smtp.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
@@ -27,6 +27,9 @@
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
* RFC4954 SMTP Authentication
* RFC5321 SMTP protocol
+ * RFC5890 Internationalized Domain Names for Applications (IDNA)
+ * RFC6531 SMTP Extension for Internationalized Email
+ * RFC6532 Internationalized Email Headers
* RFC6749 OAuth 2.0 Authorization Framework
* RFC8314 Use of TLS for Email Submission and Access
* Draft SMTP URL Interface <draft-earhart-url-smtp-00.txt>
@@ -101,6 +104,8 @@ static CURLcode smtp_setup_connection(struct connectdata *conn);
static CURLcode smtp_parse_url_options(struct connectdata *conn);
static CURLcode smtp_parse_url_path(struct connectdata *conn);
static CURLcode smtp_parse_custom_request(struct connectdata *conn);
+static CURLcode smtp_parse_address(struct connectdata *conn, const char *fqma,
+ char **address, struct hostname *host);
static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech,
const char *initresp);
static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp);
@@ -481,13 +486,55 @@ static CURLcode smtp_perform_command(struct connectdata *conn)
struct Curl_easy *data = conn->data;
struct SMTP *smtp = data->req.protop;
- /* Send the command */
- if(smtp->rcpt)
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s",
- smtp->custom && smtp->custom[0] != '\0' ?
- smtp->custom : "VRFY",
- smtp->rcpt->data);
+ if(smtp->rcpt) {
+ /* We notify the server we are sending UTF-8 data if a) it supports the
+ SMTPUTF8 extension and b) The mailbox contains UTF-8 charaacters, in
+ either the local address or host name parts. This is regardless of
+ whether the host name is encoded using IDN ACE */
+ bool utf8 = FALSE;
+
+ if((!smtp->custom) || (!smtp->custom[0])) {
+ char *address = NULL;
+ struct hostname host = { NULL, NULL, NULL, NULL };
+
+ /* Parse the mailbox to verify into the local address and host name
+ parts, converting the host name to an IDN A-label if necessary */
+ result = smtp_parse_address(conn, smtp->rcpt->data,
+ &address, &host);
+ if(result)
+ return result;
+
+ /* Establish whether we should report SMTPUTF8 to the server for this
+ mailbox as per RFC-6531 sect. 3.1 point 6 */
+ utf8 = (conn->proto.smtpc.utf8_supported) &&
+ ((host.encalloc) || (!Curl_is_ASCII_name(address)) ||
+ (!Curl_is_ASCII_name(host.name)));
+
+ /* Send the VRFY command (Note: The host name part may be absent when the
+ host is a local system) */
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "VRFY %s%s%s%s",
+ address,
+ host.name ? "@" : "",
+ host.name ? host.name : "",
+ utf8 ? " SMTPUTF8" : "");
+
+ Curl_free_idnconverted_hostname(&host);
+ free(address);
+ }
+ else {
+ /* Establish whether we should report that we support SMTPUTF8 for EXPN
+ commands to the server as per RFC-6531 sect. 3.1 point 6 */
+ utf8 = (conn->proto.smtpc.utf8_supported) &&
+ (!strcmp(smtp->custom, "EXPN"));
+
+ /* Send the custom recipient based command such as the EXPN command */
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s%s", smtp->custom,
+ smtp->rcpt->data,
+ utf8 ? " SMTPUTF8" : "");
+ }
+ }
else
+ /* Send the non-recipient based command such as HELP */
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s",
smtp->custom && smtp->custom[0] != '\0' ?
smtp->custom : "HELP");
@@ -512,22 +559,86 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
+ /* We notify the server we are sending UTF-8 data if a) it supports the
+ SMTPUTF8 extension and b) The mailbox contains UTF-8 charaacters, in
+ either the local address or host name parts. This is regardless of
+ whether the host name is encoded using IDN ACE */
+ bool utf8 = FALSE;
+
/* Calculate the FROM parameter */
- if(!data->set.str[STRING_MAIL_FROM])
+ if(data->set.str[STRING_MAIL_FROM]) {
+ char *address = NULL;
+ struct hostname host = { NULL, NULL, NULL, NULL };
+
+ /* Parse the FROM mailbox into the local address and host name parts,
+ converting the host name to an IDN A-label if necessary */
+ result = smtp_parse_address(conn, data->set.str[STRING_MAIL_FROM],
+ &address, &host);
+ if(result)
+ return result;
+
+ /* Establish whether we should report SMTPUTF8 to the server for this
+ mailbox as per RFC-6531 sect. 3.1 point 4 and sect. 3.4 */
+ utf8 = (conn->proto.smtpc.utf8_supported) &&
+ ((host.encalloc) || (!Curl_is_ASCII_name(address)) ||
+ (!Curl_is_ASCII_name(host.name)));
+
+ if(host.name) {
+ from = aprintf("<%s@%s>", address, host.name);
+
+ Curl_free_idnconverted_hostname(&host);
+ }
+ else
+ /* An invalid mailbox was provided but we'll simply let the server worry
+ about that and reply with a 501 error */
+ from = aprintf("<%s>", address);
+
+ free(address);
+ }
+ else
/* Null reverse-path, RFC-5321, sect. 3.6.3 */
from = strdup("<>");
- else if(data->set.str[STRING_MAIL_FROM][0] == '<')
- from = aprintf("%s", data->set.str[STRING_MAIL_FROM]);
- else
- from = aprintf("<%s>", data->set.str[STRING_MAIL_FROM]);
if(!from)
return CURLE_OUT_OF_MEMORY;
/* Calculate the optional AUTH parameter */
if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.sasl.authused) {
- if(data->set.str[STRING_MAIL_AUTH][0] != '\0')
- auth = aprintf("%s", data->set.str[STRING_MAIL_AUTH]);
+ if(data->set.str[STRING_MAIL_AUTH][0] != '\0') {
+ char *address = NULL;
+ struct hostname host = { NULL, NULL, NULL, NULL };
+
+ /* Parse the AUTH mailbox into the local address and host name parts,
+ converting the host name to an IDN A-label if necessary */
+ result = smtp_parse_address(conn, data->set.str[STRING_MAIL_AUTH],
+ &address, &host);
+ if(result) {
+ free(from);
+ return result;
+ }
+
+ /* Establish whether we should report SMTPUTF8 to the server for this
+ mailbox as per RFC-6531 sect. 3.1 point 4 and sect. 3.4 */
+ if((!utf8) && (conn->proto.smtpc.utf8_supported) &&
+ ((host.encalloc) || (!Curl_is_ASCII_name(address)) ||
+ (!Curl_is_ASCII_name(host.name))))
+ utf8 = TRUE;
+
+ if(host.name) {
+ free(from);
+ from = aprintf("<%s@%s>", address, host.name);
+
+ Curl_free_idnconverted_hostname(&host);
+ }
+ else
+ /* An invalid mailbox was provided but we'll simply let the server
+ worry about it */
+ auth = aprintf("<%s>", address);
+
+ free(address);
+ if(!from)
+ return CURLE_OUT_OF_MEMORY;
+ }
else
/* Empty AUTH, RFC-2554, sect. 5 */
auth = strdup("<>");
@@ -561,6 +672,7 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
if(result) {
free(from);
free(auth);
+
return result;
}
@@ -583,19 +695,33 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
}
}
+ /* If the mailboxes in the FROM and AUTH parameters don't include a UTF-8
+ based address then quickly scan through the recipient list and check if
+ any there do, as we need to correctly identify our support for SMTPUTF8
+ in the envelope, as per RFC-6531 sect. 3.4 */
+ if(conn->proto.smtpc.utf8_supported && !utf8) {
+ struct SMTP *smtp = data->req.protop;
+ struct curl_slist *rcpt = smtp->rcpt;
+
+ while(rcpt && !utf8) {
+ /* Does the host name contain non-ASCII characters? */
+ if(!Curl_is_ASCII_name(rcpt->data))
+ utf8 = TRUE;
+
+ rcpt = rcpt->next;
+ }
+ }
+
/* Send the MAIL command */
- if(!auth && !size)
- result = Curl_pp_sendf(&conn->proto.smtpc.pp,
- "MAIL FROM:%s", from);
- else if(auth && !size)
- result = Curl_pp_sendf(&conn->proto.smtpc.pp,
- "MAIL FROM:%s AUTH=%s", from, auth);
- else if(auth && size)
- result = Curl_pp_sendf(&conn->proto.smtpc.pp,
- "MAIL FROM:%s AUTH=%s SIZE=%s", from, auth, size);
- else
- result = Curl_pp_sendf(&conn->proto.smtpc.pp,
- "MAIL FROM:%s SIZE=%s", from, size);
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+ "MAIL FROM:%s%s%s%s%s%s",
+ from, /* Mandatory */
+ auth ? " AUTH=" : "", /* Optional on AUTH support */
+ auth ? auth : "", /* */
+ size ? " SIZE=" : "", /* Optional on SIZE support */
+ size ? size : "", /* */
+ utf8 ? " SMTPUTF8" /* Internationalised mailbox */
+ : ""); /* included in our envelope */
free(from);
free(auth);
@@ -619,14 +745,28 @@ static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
struct SMTP *smtp = data->req.protop;
+ char *address = NULL;
+ struct hostname host = { NULL, NULL, NULL, NULL };
+
+ /* Parse the recipient mailbox into the local address and host name parts,
+ converting the host name to an IDN A-label if necessary */
+ result = smtp_parse_address(conn, smtp->rcpt->data,
+ &address, &host);
+ if(result)
+ return result;
/* Send the RCPT TO command */
- if(smtp->rcpt->data[0] == '<')
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s",
- smtp->rcpt->data);
+ if(host.name)
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s@%s>", address,
+ host.name);
else
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>",
- smtp->rcpt->data);
+ /* An invalid mailbox was provided but we'll simply let the server worry
+ about that and reply with a 501 error */
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>", address);
+
+ Curl_free_idnconverted_hostname(&host);
+ free(address);
+
if(!result)
state(conn, SMTP_RCPT);
@@ -726,6 +866,10 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
else if(len >= 4 && !memcmp(line, "SIZE", 4))
smtpc->size_supported = TRUE;
+ /* Does the server support the UTF-8 capability? */
+ else if(len >= 8 && !memcmp(line, "SMTPUTF8", 8))
+ smtpc->utf8_supported = TRUE;
+
/* Does the server support authentication? */
else if(len >= 5 && !memcmp(line, "AUTH ", 5)) {
smtpc->auth_supported = TRUE;
@@ -915,25 +1059,53 @@ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
struct SMTP *smtp = data->req.protop;
+ bool is_smtp_err = FALSE;
+ bool is_smtp_blocking_err = FALSE;
(void)instate; /* no use for this yet */
- if(smtpcode/100 != 2) {
- failf(data, "RCPT failed: %d", smtpcode);
- result = CURLE_SEND_ERROR;
+ is_smtp_err = (smtpcode/100 != 2) ? TRUE : FALSE;
+
+ /* If there's multiple RCPT TO to be issued, it's possible to ignore errors
+ and proceed with only the valid addresses. */
+ is_smtp_blocking_err =
+ (is_smtp_err && !data->set.mail_rcpt_allowfails) ? TRUE : FALSE;
+
+ if(is_smtp_err) {
+ /* Remembering the last failure which we can report if all "RCPT TO" have
+ failed and we cannot proceed. */
+ smtp->rcpt_last_error = smtpcode;
+
+ if(is_smtp_blocking_err) {
+ failf(data, "RCPT failed: %d", smtpcode);
+ result = CURLE_SEND_ERROR;
+ }
}
else {
+ /* Some RCPT TO commands have succeeded. */
+ smtp->rcpt_had_ok = TRUE;
+ }
+
+ if(!is_smtp_blocking_err) {
smtp->rcpt = smtp->rcpt->next;
if(smtp->rcpt)
/* Send the next RCPT TO command */
result = smtp_perform_rcpt_to(conn);
else {
- /* Send the DATA command */
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
+ /* We weren't able to issue a successful RCPT TO command while going
+ over recipients (potentially multiple). Sending back last error. */
+ if(!smtp->rcpt_had_ok) {
+ failf(data, "RCPT failed: %d (last error)", smtp->rcpt_last_error);
+ result = CURLE_SEND_ERROR;
+ }
+ else {
+ /* Send the DATA command */
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
- if(!result)
- state(conn, SMTP_DATA);
+ if(!result)
+ state(conn, SMTP_DATA);
+ }
}
}
@@ -1287,6 +1459,12 @@ static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
/* Store the first recipient (or NULL if not specified) */
smtp->rcpt = data->set.mail_rcpt;
+ /* Track of whether we've successfully sent at least one RCPT TO command */
+ smtp->rcpt_had_ok = FALSE;
+
+ /* Track of the last error we've received by sending RCPT TO command */
+ smtp->rcpt_last_error = 0;
+
/* Initial data character is the first character in line: it is implicitly
preceded by a virtual CRLF. */
smtp->trailing_crlf = TRUE;
@@ -1537,6 +1715,76 @@ static CURLcode smtp_parse_custom_request(struct connectdata *conn)
return result;
}
+/***********************************************************************
+ *
+ * smtp_parse_address()
+ *
+ * Parse the fully qualified mailbox address into a local address part and the
+ * host name, converting the host name to an IDN A-label, as per RFC-5890, if
+ * necessary.
+ *
+ * Parameters:
+ *
+ * conn [in] - The connection handle.
+ * fqma [in] - The fully qualified mailbox address (which may or
+ * may not contain UTF-8 characters).
+ * address [in/out] - A new allocated buffer which holds the local
+ * address part of the mailbox. This buffer must be
+ * free'ed by the caller.
+ * host [in/out] - The host name structure that holds the original,
+ * and optionally encoded, host name.
+ * Curl_free_idnconverted_hostname() must be called
+ * once the caller has finished with the structure.
+ *
+ * Returns CURLE_OK on success.
+ *
+ * Notes:
+ *
+ * Should a UTF-8 host name require conversion to IDN ACE and we cannot honor
+ * that convertion then we shall return success. This allow the caller to send
+ * the data to the server as a U-label (as per RFC-6531 sect. 3.2).
+ *
+ * If an mailbox '@' seperator cannot be located then the mailbox is considered
+ * to be either a local mailbox or an invalid mailbox (depending on what the
+ * calling function deems it to be) then the input will simply be returned in
+ * the address part with the host name being NULL.
+ */
+static CURLcode smtp_parse_address(struct connectdata *conn, const char *fqma,
+ char **address, struct hostname *host)
+{
+ CURLcode result = CURLE_OK;
+ size_t length;
+
+ /* Duplicate the fully qualified email address so we can manipulate it,
+ ensuring it doesn't contain the delimiters if specified */
+ char *dup = strdup(fqma[0] == '<' ? fqma + 1 : fqma);
+ if(!dup)
+ return CURLE_OUT_OF_MEMORY;
+
+ length = strlen(dup);
+ if(dup[length - 1] == '>')
+ dup[length - 1] = '\0';
+
+ /* Extract the host name from the addresss (if we can) */
+ host->name = strpbrk(dup, "@");
+ if(host->name) {
+ *host->name = '\0';
+ host->name = host->name + 1;
+
+ /* Attempt to convert the host name to IDN ACE */
+ (void) Curl_idnconvert_hostname(conn, host);
+
+ /* If Curl_idnconvert_hostname() fails then we shall attempt to continue
+ and send the host name using UTF-8 rather than as 7-bit ACE (which is
+ our preference) */
+ }
+
+ /* Extract the local address from the mailbox */
+ *address = dup;
+
+ return result;
+}
+
CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
{
/* When sending a SMTP payload we must detect CRLF. sequences making sure
diff --git a/libs/libcurl/src/smtp.h b/libs/libcurl/src/smtp.h
index 20fc081190..164a175d75 100644
--- a/libs/libcurl/src/smtp.h
+++ b/libs/libcurl/src/smtp.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
@@ -55,6 +55,9 @@ struct SMTP {
curl_pp_transfer transfer;
char *custom; /* Custom Request */
struct curl_slist *rcpt; /* Recipient list */
+ bool rcpt_had_ok; /* Whether any of RCPT TO commands (depends on
+ total number of recipients) succeeded so far */
+ int rcpt_last_error; /* The last error received for RCPT TO command */
size_t eob; /* Number of bytes of the EOB (End Of Body) that
have been received so far */
bool trailing_crlf; /* Specifies if the tailing CRLF is present */
@@ -71,6 +74,8 @@ struct smtp_conn {
bool tls_supported; /* StartTLS capability supported by server */
bool size_supported; /* If server supports SIZE extension according to
RFC 1870 */
+ bool utf8_supported; /* If server supports SMTPUTF8 extension according
+ to RFC 6531 */
bool auth_supported; /* AUTH capability supported by server */
};
diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c
index 6ae98184d1..0fb97e1e5d 100644
--- a/libs/libcurl/src/socks.c
+++ b/libs/libcurl/src/socks.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
@@ -37,18 +37,19 @@
#include "connect.h"
#include "timeval.h"
#include "socks.h"
+#include "multiif.h" /* for getsock macros */
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
/*
* Helper read-from-socket functions. Does the same as Curl_read() but it
* blocks until all bytes amount of buffersize will be read. No more, no less.
*
- * This is STUPID BLOCKING behaviour which we frown upon, but right now this
- * is what we have...
+ * This is STUPID BLOCKING behavior. Only used by the SOCKS GSSAPI functions.
*/
int Curl_blockread_all(struct connectdata *conn, /* connection data */
curl_socket_t sockfd, /* read from this socket */
@@ -94,6 +95,81 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
}
return result;
}
+#endif
+
+#ifndef DEBUGBUILD
+#define sxstate(x,y) socksstate(x,y)
+#else
+#define sxstate(x,y) socksstate(x,y, __LINE__)
+#endif
+
+
+/* always use this function to change state, to make debugging easier */
+static void socksstate(struct connectdata *conn,
+ enum connect_t state
+#ifdef DEBUGBUILD
+ , int lineno
+#endif
+)
+{
+ enum connect_t oldstate = conn->cnnct.state;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* synced with the state list in urldata.h */
+ static const char * const statename[] = {
+ "INIT",
+ "SOCKS_INIT",
+ "SOCKS_SEND",
+ "SOCKS_READ_INIT",
+ "SOCKS_READ",
+ "GSSAPI_INIT",
+ "AUTH_INIT",
+ "AUTH_SEND",
+ "AUTH_READ",
+ "REQ_INIT",
+ "RESOLVING",
+ "RESOLVED",
+ "RESOLVE_REMOTE",
+ "REQ_SEND",
+ "REQ_SENDING",
+ "REQ_READ",
+ "REQ_READ_MORE",
+ "DONE"
+ };
+#endif
+
+ if(oldstate == state)
+ /* don't bother when the new state is the same as the old state */
+ return;
+
+ conn->cnnct.state = state;
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ infof(conn->data,
+ "SXSTATE: %s => %s conn %p; line %d\n",
+ statename[oldstate], statename[conn->cnnct.state], conn,
+ lineno);
+#endif
+}
+
+int Curl_SOCKS_getsock(struct connectdata *conn, curl_socket_t *sock,
+ int sockindex)
+{
+ int rc = 0;
+ sock[0] = conn->sock[sockindex];
+ switch(conn->cnnct.state) {
+ case CONNECT_RESOLVING:
+ case CONNECT_SOCKS_READ:
+ case CONNECT_AUTH_READ:
+ case CONNECT_REQ_READ:
+ case CONNECT_REQ_READ_MORE:
+ rc = GETSOCK_READSOCK(0);
+ break;
+ default:
+ rc = GETSOCK_WRITESOCK(0);
+ break;
+ }
+ return rc;
+}
/*
* This function logs in to a SOCKS4 proxy and sends the specifics to the final
@@ -110,62 +186,89 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
const char *hostname,
int remote_port,
int sockindex,
- struct connectdata *conn)
+ struct connectdata *conn,
+ bool *done)
{
const bool protocol4a =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
-#define SOCKS4REQLEN 262
- unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
- id */
- CURLcode code;
- curl_socket_t sock = conn->sock[sockindex];
+ unsigned char *socksreq = &conn->cnnct.socksreq[0];
+ CURLcode result;
+ curl_socket_t sockfd = conn->sock[sockindex];
struct Curl_easy *data = conn->data;
+ struct connstate *sx = &conn->cnnct;
+ struct Curl_dns_entry *dns = NULL;
+ ssize_t actualread;
+ ssize_t written;
- if(Curl_timeleft(data, NULL, TRUE) < 0) {
- /* time-out, bail out, go home */
- failf(data, "Connection time-out");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- if(conn->bits.httpproxy)
- infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
- protocol4a ? "a" : "", hostname, remote_port);
-
- (void)curlx_nonblock(sock, FALSE);
+ if(!SOCKS_STATE(sx->state) && !*done)
+ sxstate(conn, CONNECT_SOCKS_INIT);
- infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
+ switch(sx->state) {
+ case CONNECT_SOCKS_INIT:
+ if(conn->bits.httpproxy)
+ infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
+ protocol4a ? "a" : "", hostname, remote_port);
- /*
- * Compose socks4 request
- *
- * Request format
- *
- * +----+----+----+----+----+----+----+----+----+----+....+----+
- * | VN | CD | DSTPORT | DSTIP | USERID |NULL|
- * +----+----+----+----+----+----+----+----+----+----+....+----+
- * # of bytes: 1 1 2 4 variable 1
- */
+ infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
- socksreq[0] = 4; /* version (SOCKS4) */
- socksreq[1] = 1; /* connect */
- socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
- socksreq[3] = (unsigned char)(remote_port & 0xff); /* PORT LSB */
-
- /* DNS resolve only for SOCKS4, not SOCKS4a */
- if(!protocol4a) {
- struct Curl_dns_entry *dns;
- Curl_addrinfo *hp = NULL;
- int rc;
+ /*
+ * Compose socks4 request
+ *
+ * Request format
+ *
+ * +----+----+----+----+----+----+----+----+----+----+....+----+
+ * | VN | CD | DSTPORT | DSTIP | USERID |NULL|
+ * +----+----+----+----+----+----+----+----+----+----+....+----+
+ * # of bytes: 1 1 2 4 variable 1
+ */
- rc = Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
+ socksreq[0] = 4; /* version (SOCKS4) */
+ socksreq[1] = 1; /* connect */
+ socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
+ socksreq[3] = (unsigned char)(remote_port & 0xff); /* PORT LSB */
+
+ /* DNS resolve only for SOCKS4, not SOCKS4a */
+ if(!protocol4a) {
+ enum resolve_t rc =
+ Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
+
+ if(rc == CURLRESOLV_ERROR)
+ return CURLE_COULDNT_RESOLVE_PROXY;
+ else if(rc == CURLRESOLV_PENDING) {
+ sxstate(conn, CONNECT_RESOLVING);
+ infof(data, "SOCKS4 non-blocking resolve of %s\n", hostname);
+ return CURLE_OK;
+ }
+ sxstate(conn, CONNECT_RESOLVED);
+ goto CONNECT_RESOLVED;
+ }
- if(rc == CURLRESOLV_ERROR)
- return CURLE_COULDNT_RESOLVE_PROXY;
+ /* socks4a doesn't resolve anything locally */
+ sxstate(conn, CONNECT_REQ_INIT);
+ goto CONNECT_REQ_INIT;
- if(rc == CURLRESOLV_PENDING)
- /* ignores the return code, but 'dns' remains NULL on failure */
- (void)Curl_resolver_wait_resolv(conn, &dns);
+ case CONNECT_RESOLVING:
+ /* check if we have the name resolved by now */
+ dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
+ if(dns) {
+#ifdef CURLRES_ASYNCH
+ conn->async.dns = dns;
+ conn->async.done = TRUE;
+#endif
+ infof(data, "Hostname '%s' was found\n", hostname);
+ sxstate(conn, CONNECT_RESOLVED);
+ }
+ else {
+ result = Curl_resolv_check(data->conn, &dns);
+ /* stay in the state or error out */
+ return result;
+ }
+ /* FALLTHROUGH */
+ CONNECT_RESOLVED:
+ case CONNECT_RESOLVED: {
+ Curl_addrinfo *hp = NULL;
+ char buf[64];
/*
* We cannot use 'hostent' as a struct that Curl_resolv() returns. It
* returns a Curl_addrinfo pointer that may not always look the same.
@@ -173,7 +276,6 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
if(dns)
hp = dns->addr;
if(hp) {
- char buf[64];
Curl_printable_address(hp, buf, sizeof(buf));
if(hp->ai_family == AF_INET) {
@@ -189,7 +291,6 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
}
else {
hp = NULL; /* fail! */
-
failf(data, "SOCKS4 connection to %s not supported\n", buf);
}
@@ -201,149 +302,166 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
return CURLE_COULDNT_RESOLVE_HOST;
}
}
-
- /*
- * This is currently not supporting "Identification Protocol (RFC1413)".
- */
- socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
- if(proxy_user) {
- size_t plen = strlen(proxy_user);
- if(plen >= sizeof(socksreq) - 8) {
- failf(data, "Too long SOCKS proxy name, can't use!\n");
- return CURLE_COULDNT_CONNECT;
+ /* FALLTHROUGH */
+ CONNECT_REQ_INIT:
+ case CONNECT_REQ_INIT:
+ /*
+ * This is currently not supporting "Identification Protocol (RFC1413)".
+ */
+ socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
+ 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;
+ }
+ /* copy the proxy name WITH trailing zero */
+ memcpy(socksreq + 8, proxy_user, plen + 1);
}
- /* copy the proxy name WITH trailing zero */
- memcpy(socksreq + 8, proxy_user, plen + 1);
- }
- /*
- * Make connection
- */
- {
- int result;
- ssize_t actualread;
- ssize_t written;
- ssize_t hostnamelen = 0;
- ssize_t packetsize = 9 +
- strlen((char *)socksreq + 8); /* size including NUL */
-
- /* If SOCKS4a, set special invalid IP address 0.0.0.x */
- if(protocol4a) {
- socksreq[4] = 0;
- socksreq[5] = 0;
- socksreq[6] = 0;
- socksreq[7] = 1;
- /* If still enough room in buffer, also append hostname */
- hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
- if(packetsize + hostnamelen <= SOCKS4REQLEN)
- strcpy((char *)socksreq + packetsize, hostname);
- else
- hostnamelen = 0; /* Flag: hostname did not fit in buffer */
+ /*
+ * Make connection
+ */
+ {
+ ssize_t packetsize = 9 +
+ strlen((char *)socksreq + 8); /* size including NUL */
+
+ /* If SOCKS4a, set special invalid IP address 0.0.0.x */
+ if(protocol4a) {
+ ssize_t hostnamelen = 0;
+ socksreq[4] = 0;
+ socksreq[5] = 0;
+ socksreq[6] = 0;
+ socksreq[7] = 1;
+ /* append hostname */
+ hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
+ if(hostnamelen <= 255)
+ strcpy((char *)socksreq + packetsize, hostname);
+ else {
+ failf(data, "SOCKS4: too long host name");
+ return CURLE_COULDNT_CONNECT;
+ }
+ packetsize += hostnamelen;
+ }
+ sx->outp = socksreq;
+ sx->outstanding = packetsize;
+ sxstate(conn, CONNECT_REQ_SENDING);
}
-
+ /* FALLTHROUGH */
+ case CONNECT_REQ_SENDING:
/* Send request */
- code = Curl_write_plain(conn, sock, (char *)socksreq,
- packetsize + hostnamelen,
- &written);
- if(code || (written != packetsize + hostnamelen)) {
+ result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ sx->outstanding, &written);
+ if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS4 connect request.");
return CURLE_COULDNT_CONNECT;
}
- if(protocol4a && hostnamelen == 0) {
- /* SOCKS4a with very long hostname - send that name separately */
- hostnamelen = (ssize_t)strlen(hostname) + 1;
- code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
- &written);
- if(code || (written != hostnamelen)) {
- failf(data, "Failed to send SOCKS4 connect request.");
- return CURLE_COULDNT_CONNECT;
- }
+ if(written != sx->outstanding) {
+ /* not done, remain in state */
+ sx->outstanding -= written;
+ sx->outp += written;
+ return CURLE_OK;
}
- packetsize = 8; /* receive data size */
+ /* done sending! */
+ sx->outstanding = 8; /* receive data size */
+ sx->outp = socksreq;
+ sxstate(conn, CONNECT_SOCKS_READ);
+ /* FALLTHROUGH */
+ case CONNECT_SOCKS_READ:
/* Receive response */
- result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
- &actualread);
- if(result || (actualread != packetsize)) {
- failf(data, "Failed to receive SOCKS4 connect request ack.");
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
+ sx->outstanding, &actualread);
+ if(result && (CURLE_AGAIN != result)) {
+ failf(data, "SOCKS4: Failed receiving connect request ack: %s",
+ curl_easy_strerror(result));
return CURLE_COULDNT_CONNECT;
}
-
- /*
- * Response format
- *
- * +----+----+----+----+----+----+----+----+
- * | VN | CD | DSTPORT | DSTIP |
- * +----+----+----+----+----+----+----+----+
- * # of bytes: 1 1 2 4
- *
- * VN is the version of the reply code and should be 0. CD is the result
- * code with one of the following values:
- *
- * 90: request granted
- * 91: request rejected or failed
- * 92: request rejected because SOCKS server cannot connect to
- * identd on the client
- * 93: request rejected because the client program and identd
- * report different user-ids
- */
-
- /* wrong version ? */
- if(socksreq[0] != 0) {
- failf(data,
- "SOCKS4 reply has wrong version, version should be 0.");
- return CURLE_COULDNT_CONNECT;
+ else if(actualread != sx->outstanding) {
+ /* remain in reading state */
+ sx->outstanding -= actualread;
+ sx->outp += actualread;
+ return CURLE_OK;
}
+ sxstate(conn, CONNECT_DONE);
+ break;
+ default: /* lots of unused states in SOCKS4 */
+ break;
+ }
- /* Result */
- switch(socksreq[1]) {
- case 90:
- infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
- break;
- case 91:
- failf(data,
- "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
- ", request rejected or failed.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (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;
- case 92:
- failf(data,
- "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
- ", request rejected because SOCKS server cannot connect to "
- "identd on the client.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (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;
- case 93:
- failf(data,
- "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
- ", request rejected because the client program and identd "
- "report different user-ids.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (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;
- default:
- failf(data,
- "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
- ", Unknown.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (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;
- }
+ /*
+ * Response format
+ *
+ * +----+----+----+----+----+----+----+----+
+ * | VN | CD | DSTPORT | DSTIP |
+ * +----+----+----+----+----+----+----+----+
+ * # of bytes: 1 1 2 4
+ *
+ * VN is the version of the reply code and should be 0. CD is the result
+ * code with one of the following values:
+ *
+ * 90: request granted
+ * 91: request rejected or failed
+ * 92: request rejected because SOCKS server cannot connect to
+ * identd on the client
+ * 93: request rejected because the client program and identd
+ * report different user-ids
+ */
+
+ /* wrong version ? */
+ if(socksreq[0] != 0) {
+ failf(data,
+ "SOCKS4 reply has wrong version, version should be 0.");
+ return CURLE_COULDNT_CONNECT;
}
- (void)curlx_nonblock(sock, TRUE);
+ /* Result */
+ switch(socksreq[1]) {
+ case 90:
+ infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
+ break;
+ case 91:
+ failf(data,
+ "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+ ", request rejected or failed.",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (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;
+ case 92:
+ failf(data,
+ "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+ ", request rejected because SOCKS server cannot connect to "
+ "identd on the client.",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (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;
+ case 93:
+ failf(data,
+ "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+ ", request rejected because the client program and identd "
+ "report different user-ids.",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (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;
+ default:
+ failf(data,
+ "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+ ", Unknown.",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (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;
+ }
+ *done = TRUE;
return CURLE_OK; /* Proxy was successful! */
}
@@ -356,7 +474,8 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
const char *hostname,
int remote_port,
int sockindex,
- struct connectdata *conn)
+ struct connectdata *conn,
+ bool *done)
{
/*
According to the RFC1928, section "6. Replies". This is what a SOCK5
@@ -374,141 +493,158 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
o REP Reply field:
o X'00' succeeded
*/
-#define REQUEST_BUFSIZE 600 /* room for large user/pw (255 max each) */
- unsigned char socksreq[REQUEST_BUFSIZE];
- char dest[REQUEST_BUFSIZE] = "unknown"; /* printable hostname:port */
+ unsigned char *socksreq = &conn->cnnct.socksreq[0];
+ char dest[256] = "unknown"; /* printable hostname:port */
int idx;
ssize_t actualread;
ssize_t written;
- int result;
- CURLcode code;
- curl_socket_t sock = conn->sock[sockindex];
+ CURLcode result;
+ curl_socket_t sockfd = conn->sock[sockindex];
struct Curl_easy *data = conn->data;
- timediff_t timeout;
bool socks5_resolve_local =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
const size_t hostname_len = strlen(hostname);
ssize_t len = 0;
const unsigned long auth = data->set.socks5auth;
bool allow_gssapi = FALSE;
+ struct connstate *sx = &conn->cnnct;
+ struct Curl_dns_entry *dns = NULL;
+
+ if(!SOCKS_STATE(sx->state) && !*done)
+ sxstate(conn, CONNECT_SOCKS_INIT);
+
+ switch(sx->state) {
+ case CONNECT_SOCKS_INIT:
+ if(conn->bits.httpproxy)
+ infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
+ hostname, remote_port);
+
+ /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
+ if(!socks5_resolve_local && hostname_len > 255) {
+ infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
+ "length > 255 [actual len=%zu]\n", hostname_len);
+ socks5_resolve_local = TRUE;
+ }
- if(conn->bits.httpproxy)
- infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
- hostname, remote_port);
-
- /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
- if(!socks5_resolve_local && hostname_len > 255) {
- infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
- "length > 255 [actual len=%zu]\n", hostname_len);
- socks5_resolve_local = TRUE;
- }
-
- /* get timeout */
- timeout = Curl_timeleft(data, NULL, TRUE);
-
- if(timeout < 0) {
- /* time-out, bail out, go home */
- failf(data, "Connection time-out");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- (void)curlx_nonblock(sock, TRUE);
-
- /* wait until socket gets connected */
- result = SOCKET_WRITABLE(sock, timeout);
-
- if(-1 == result) {
- failf(conn->data, "SOCKS5: no connection here");
- return CURLE_COULDNT_CONNECT;
- }
- if(0 == result) {
- failf(conn->data, "SOCKS5: connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- if(result & CURL_CSELECT_ERR) {
- failf(conn->data, "SOCKS5: error occurred during connection");
- return CURLE_COULDNT_CONNECT;
- }
-
- if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
- infof(conn->data,
- "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n",
- auth);
- if(!(auth & CURLAUTH_BASIC))
- /* disable username/password auth */
- proxy_user = NULL;
+ if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
+ infof(conn->data,
+ "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n",
+ auth);
+ if(!(auth & CURLAUTH_BASIC))
+ /* disable username/password auth */
+ proxy_user = NULL;
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- if(auth & CURLAUTH_GSSAPI)
- allow_gssapi = TRUE;
+ if(auth & CURLAUTH_GSSAPI)
+ allow_gssapi = TRUE;
#endif
- idx = 0;
- socksreq[idx++] = 5; /* version */
- idx++; /* reserve for the number of authentication methods */
- socksreq[idx++] = 0; /* no authentication */
- if(allow_gssapi)
- socksreq[idx++] = 1; /* GSS-API */
- if(proxy_user)
- socksreq[idx++] = 2; /* username/password */
- /* write the number of authentication methods */
- socksreq[1] = (unsigned char) (idx - 2);
-
- (void)curlx_nonblock(sock, FALSE);
-
- infof(data, "SOCKS5 communication to %s:%d\n", hostname, remote_port);
-
- code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
- &written);
- if(code || (written != (2 + (int)socksreq[1]))) {
- failf(data, "Unable to send initial SOCKS5 request.");
- return CURLE_COULDNT_CONNECT;
- }
-
- (void)curlx_nonblock(sock, TRUE);
-
- result = SOCKET_READABLE(sock, timeout);
-
- if(-1 == result) {
- failf(conn->data, "SOCKS5 nothing to read");
- return CURLE_COULDNT_CONNECT;
- }
- if(0 == result) {
- failf(conn->data, "SOCKS5 read timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- if(result & CURL_CSELECT_ERR) {
- failf(conn->data, "SOCKS5 read error occurred");
- return CURLE_RECV_ERROR;
- }
-
- (void)curlx_nonblock(sock, FALSE);
-
- result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
- if(result || (actualread != 2)) {
- failf(data, "Unable to receive initial SOCKS5 response.");
- return CURLE_COULDNT_CONNECT;
- }
-
- if(socksreq[0] != 5) {
- failf(data, "Received invalid version in initial SOCKS5 response.");
- return CURLE_COULDNT_CONNECT;
- }
- if(socksreq[1] == 0) {
- /* Nothing to do, no authentication needed */
- ;
- }
+ idx = 0;
+ socksreq[idx++] = 5; /* version */
+ idx++; /* number of authentication methods */
+ socksreq[idx++] = 0; /* no authentication */
+ if(allow_gssapi)
+ socksreq[idx++] = 1; /* GSS-API */
+ if(proxy_user)
+ socksreq[idx++] = 2; /* username/password */
+ /* write the number of authentication methods */
+ socksreq[1] = (unsigned char) (idx - 2);
+
+ 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;
+ }
+ if(written != idx) {
+ sxstate(conn, CONNECT_SOCKS_SEND);
+ sx->outstanding = idx - written;
+ sx->outp = &socksreq[written];
+ return CURLE_OK;
+ }
+ sxstate(conn, CONNECT_SOCKS_READ);
+ goto CONNECT_SOCKS_READ_INIT;
+ case CONNECT_SOCKS_SEND:
+ result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ sx->outstanding, &written);
+ if(result && (CURLE_AGAIN != result)) {
+ failf(data, "Unable to send initial SOCKS5 request.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ if(written != sx->outstanding) {
+ /* not done, remain in state */
+ sx->outstanding -= written;
+ sx->outp += written;
+ return CURLE_OK;
+ }
+ /* FALLTHROUGH */
+ CONNECT_SOCKS_READ_INIT:
+ case CONNECT_SOCKS_READ_INIT:
+ sx->outstanding = 2; /* expect two bytes */
+ sx->outp = socksreq; /* store it here */
+ /* FALLTHROUGH */
+ case CONNECT_SOCKS_READ:
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
+ sx->outstanding, &actualread);
+ if(result && (CURLE_AGAIN != result)) {
+ failf(data, "Unable to receive initial SOCKS5 response.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(actualread != sx->outstanding) {
+ /* remain in reading state */
+ sx->outstanding -= actualread;
+ sx->outp += actualread;
+ return CURLE_OK;
+ }
+ else if(socksreq[0] != 5) {
+ failf(data, "Received invalid version in initial SOCKS5 response.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(socksreq[1] == 0) {
+ /* DONE! No authentication needed. Send request. */
+ sxstate(conn, CONNECT_REQ_INIT);
+ goto CONNECT_REQ_INIT;
+ }
+ else if(socksreq[1] == 2) {
+ /* regular name + password authentication */
+ sxstate(conn, CONNECT_AUTH_INIT);
+ goto CONNECT_AUTH_INIT;
+ }
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- else if(allow_gssapi && (socksreq[1] == 1)) {
- code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
- if(code) {
- failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
+ else if(allow_gssapi && (socksreq[1] == 1)) {
+ sxstate(conn, CONNECT_GSSAPI_INIT);
+ result = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
+ if(result) {
+ failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ }
+#endif
+ else {
+ /* error */
+ if(!allow_gssapi && (socksreq[1] == 1)) {
+ failf(data,
+ "SOCKS5 GSSAPI per-message authentication is not supported.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(socksreq[1] == 255) {
+ failf(data, "No authentication method was acceptable.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ failf(data,
+ "Undocumented SOCKS5 mode attempted to be used by server.");
return CURLE_COULDNT_CONNECT;
}
- }
+ break;
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ case CONNECT_GSSAPI_INIT:
+ /* GSSAPI stuff done non-blocking */
+ break;
#endif
- else if(socksreq[1] == 2) {
+
+ default: /* do nothing! */
+ break;
+
+ CONNECT_AUTH_INIT:
+ case CONNECT_AUTH_INIT: {
/* Needs user name and password */
size_t proxy_user_len, proxy_password_len;
if(proxy_user && proxy_password) {
@@ -549,18 +685,41 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
memcpy(socksreq + len, proxy_password, proxy_password_len);
}
len += proxy_password_len;
-
- code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
- if(code || (len != written)) {
+ sxstate(conn, CONNECT_AUTH_SEND);
+ sx->outstanding = len;
+ sx->outp = socksreq;
+ }
+ /* FALLTHROUGH */
+ case CONNECT_AUTH_SEND:
+ result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ sx->outstanding, &written);
+ if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS5 sub-negotiation request.");
return CURLE_COULDNT_CONNECT;
}
-
- result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
- if(result || (actualread != 2)) {
+ if(sx->outstanding != written) {
+ /* remain in state */
+ sx->outstanding -= written;
+ sx->outp += written;
+ return CURLE_OK;
+ }
+ sx->outp = socksreq;
+ sx->outstanding = 2;
+ sxstate(conn, CONNECT_AUTH_READ);
+ /* FALLTHROUGH */
+ case CONNECT_AUTH_READ:
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
+ sx->outstanding, &actualread);
+ if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
return CURLE_COULDNT_CONNECT;
}
+ if(actualread != sx->outstanding) {
+ /* remain in state */
+ sx->outstanding -= actualread;
+ sx->outp += actualread;
+ return CURLE_OK;
+ }
/* ignore the first (VER) byte */
if(socksreq[1] != 0) { /* status */
@@ -570,209 +729,248 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
}
/* Everything is good so far, user was authenticated! */
- }
- else {
- /* error */
- if(!allow_gssapi && (socksreq[1] == 1)) {
- failf(data,
- "SOCKS5 GSSAPI per-message authentication is not supported.");
- return CURLE_COULDNT_CONNECT;
- }
- if(socksreq[1] == 255) {
- if(!proxy_user || !*proxy_user) {
- failf(data,
- "No authentication method was acceptable. (It is quite likely"
- " that the SOCKS5 server wanted a username/password, since none"
- " was supplied to the server on this connection.)");
+ sxstate(conn, CONNECT_REQ_INIT);
+ /* FALLTHROUGH */
+ CONNECT_REQ_INIT:
+ case CONNECT_REQ_INIT:
+ if(socks5_resolve_local) {
+ enum resolve_t rc = Curl_resolv(conn, hostname, remote_port,
+ FALSE, &dns);
+
+ if(rc == CURLRESOLV_ERROR)
+ return CURLE_COULDNT_RESOLVE_HOST;
+
+ if(rc == CURLRESOLV_PENDING) {
+ sxstate(conn, CONNECT_RESOLVING);
+ return CURLE_OK;
}
- else {
- failf(data, "No authentication method was acceptable.");
- }
- return CURLE_COULDNT_CONNECT;
+ sxstate(conn, CONNECT_RESOLVED);
+ goto CONNECT_RESOLVED;
}
- else {
- failf(data,
- "Undocumented SOCKS5 mode attempted to be used by server.");
- return CURLE_COULDNT_CONNECT;
- }
- }
+ goto CONNECT_RESOLVE_REMOTE;
- /* Authentication is complete, now specify destination to the proxy */
- len = 0;
- socksreq[len++] = 5; /* version (SOCKS5) */
- socksreq[len++] = 1; /* connect */
- socksreq[len++] = 0; /* must be zero */
-
- if(!socks5_resolve_local) {
- socksreq[len++] = 3; /* ATYP: domain name = 3 */
- socksreq[len++] = (char) hostname_len; /* address length */
- memcpy(&socksreq[len], hostname, hostname_len); /* address str w/o NULL */
- len += hostname_len;
- msnprintf(dest, sizeof(dest), "%s:%d", hostname, remote_port);
- infof(data, "SOCKS5 connect to %s (remotely resolved)\n", dest);
- }
- else {
- struct Curl_dns_entry *dns;
- Curl_addrinfo *hp = NULL;
- int rc = Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
-
- if(rc == CURLRESOLV_ERROR)
- return CURLE_COULDNT_RESOLVE_HOST;
+ case CONNECT_RESOLVING:
+ /* check if we have the name resolved by now */
+ dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
- if(rc == CURLRESOLV_PENDING) {
- /* this requires that we're in "wait for resolve" state */
- code = Curl_resolver_wait_resolv(conn, &dns);
- if(code)
- return code;
+ if(dns) {
+#ifdef CURLRES_ASYNCH
+ conn->async.dns = dns;
+ conn->async.done = TRUE;
+#endif
+ infof(data, "SOCKS5: hostname '%s' found\n", hostname);
}
- /*
- * We cannot use 'hostent' as a struct that Curl_resolv() returns. It
- * returns a Curl_addrinfo pointer that may not always look the same.
- */
+ if(!dns) {
+ result = Curl_resolv_check(data->conn, &dns);
+ /* stay in the state or error out */
+ return result;
+ }
+ /* FALLTHROUGH */
+ CONNECT_RESOLVED:
+ case CONNECT_RESOLVED: {
+ Curl_addrinfo *hp = NULL;
if(dns)
hp = dns->addr;
- if(hp) {
- if(Curl_printable_address(hp, dest, sizeof(dest))) {
- size_t destlen = strlen(dest);
- msnprintf(dest + destlen, sizeof(dest) - destlen, ":%d", remote_port);
- }
- else {
- strcpy(dest, "unknown");
- }
-
- if(hp->ai_family == AF_INET) {
- int i;
- struct sockaddr_in *saddr_in;
- socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
-
- saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
- for(i = 0; i < 4; i++) {
- socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
- }
+ if(!hp) {
+ failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
+ hostname);
+ return CURLE_COULDNT_RESOLVE_HOST;
+ }
- infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", dest);
- }
-#ifdef ENABLE_IPV6
- else if(hp->ai_family == AF_INET6) {
- int i;
- struct sockaddr_in6 *saddr_in6;
- socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
-
- saddr_in6 = (struct sockaddr_in6 *)(void *)hp->ai_addr;
- for(i = 0; i < 16; i++) {
- socksreq[len++] =
- ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
- }
+ if(Curl_printable_address(hp, dest, sizeof(dest))) {
+ size_t destlen = strlen(dest);
+ msnprintf(dest + destlen, sizeof(dest) - destlen, ":%d", remote_port);
+ }
+ else {
+ strcpy(dest, "unknown");
+ }
- infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", dest);
+ len = 0;
+ socksreq[len++] = 5; /* version (SOCKS5) */
+ socksreq[len++] = 1; /* connect */
+ socksreq[len++] = 0; /* must be zero */
+ if(hp->ai_family == AF_INET) {
+ int i;
+ struct sockaddr_in *saddr_in;
+ socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
+
+ saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
+ for(i = 0; i < 4; i++) {
+ socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
}
-#endif
- else {
- hp = NULL; /* fail! */
- failf(data, "SOCKS5 connection to %s not supported\n", dest);
+ infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", dest);
+ }
+#ifdef ENABLE_IPV6
+ else if(hp->ai_family == AF_INET6) {
+ int i;
+ struct sockaddr_in6 *saddr_in6;
+ socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
+
+ saddr_in6 = (struct sockaddr_in6 *)(void *)hp->ai_addr;
+ for(i = 0; i < 16; i++) {
+ socksreq[len++] =
+ ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
}
- Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+ infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", dest);
}
- if(!hp) {
- failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
- hostname);
- return CURLE_COULDNT_RESOLVE_HOST;
+#endif
+ else {
+ hp = NULL; /* fail! */
+ failf(data, "SOCKS5 connection to %s not supported\n", dest);
}
+
+ Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+ goto CONNECT_REQ_SEND;
}
+ CONNECT_RESOLVE_REMOTE:
+ case CONNECT_RESOLVE_REMOTE:
+ /* Authentication is complete, now specify destination to the proxy */
+ len = 0;
+ socksreq[len++] = 5; /* version (SOCKS5) */
+ socksreq[len++] = 1; /* connect */
+ socksreq[len++] = 0; /* must be zero */
+
+ if(!socks5_resolve_local) {
+ socksreq[len++] = 3; /* ATYP: domain name = 3 */
+ socksreq[len++] = (char) hostname_len; /* one byte address length */
+ memcpy(&socksreq[len], hostname, hostname_len); /* address w/o NULL */
+ len += hostname_len;
+ infof(data, "SOCKS5 connect to %s:%d (remotely resolved)\n",
+ hostname, remote_port);
+ }
+ /* FALLTHROUGH */
- socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
- socksreq[len++] = (unsigned char)(remote_port & 0xff); /* PORT LSB */
+ CONNECT_REQ_SEND:
+ case CONNECT_REQ_SEND:
+ /* PORT MSB */
+ socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff);
+ /* PORT LSB */
+ socksreq[len++] = (unsigned char)(remote_port & 0xff);
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- if(conn->socks5_gssapi_enctype) {
- failf(data, "SOCKS5 GSS-API protection not yet implemented.");
- }
- else
+ if(conn->socks5_gssapi_enctype) {
+ failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+ return CURLE_COULDNT_CONNECT;
+ }
#endif
- code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
-
- if(code || (len != written)) {
- failf(data, "Failed to send SOCKS5 connect request.");
- return CURLE_COULDNT_CONNECT;
- }
-
- len = 10; /* minimum packet size is 10 */
-
+ sx->outp = socksreq;
+ sx->outstanding = len;
+ sxstate(conn, CONNECT_REQ_SENDING);
+ /* FALLTHROUGH */
+ case CONNECT_REQ_SENDING:
+ result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ sx->outstanding, &written);
+ if(result && (CURLE_AGAIN != result)) {
+ failf(data, "Failed to send SOCKS5 connect request.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ if(sx->outstanding != written) {
+ /* remain in state */
+ sx->outstanding -= written;
+ sx->outp += written;
+ return CURLE_OK;
+ }
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- if(conn->socks5_gssapi_enctype) {
- failf(data, "SOCKS5 GSS-API protection not yet implemented.");
- }
- else
+ if(conn->socks5_gssapi_enctype) {
+ failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+ return CURLE_COULDNT_CONNECT;
+ }
#endif
- result = Curl_blockread_all(conn, sock, (char *)socksreq,
- len, &actualread);
-
- if(result || (len != actualread)) {
- failf(data, "Failed to receive SOCKS5 connect request ack.");
- return CURLE_COULDNT_CONNECT;
- }
-
- if(socksreq[0] != 5) { /* version */
- failf(data,
- "SOCKS5 reply has wrong version, version should be 5.");
- return CURLE_COULDNT_CONNECT;
- }
-
- /* Fix: in general, returned BND.ADDR is variable length parameter by RFC
- 1928, so the reply packet should be read until the end to avoid errors at
- subsequent protocol level.
-
- +----+-----+-------+------+----------+----------+
- |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
- +----+-----+-------+------+----------+----------+
- | 1 | 1 | X'00' | 1 | Variable | 2 |
- +----+-----+-------+------+----------+----------+
+ sx->outstanding = 10; /* minimum packet size is 10 */
+ sx->outp = socksreq;
+ sxstate(conn, CONNECT_REQ_READ);
+ /* FALLTHROUGH */
+ case CONNECT_REQ_READ:
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
+ sx->outstanding, &actualread);
+ if(result && (CURLE_AGAIN != result)) {
+ failf(data, "Failed to receive SOCKS5 connect request ack.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(actualread != sx->outstanding) {
+ /* remain in state */
+ sx->outstanding -= actualread;
+ sx->outp += actualread;
+ return CURLE_OK;
+ }
- ATYP:
- o IP v4 address: X'01', BND.ADDR = 4 byte
- o domain name: X'03', BND.ADDR = [ 1 byte length, string ]
- o IP v6 address: X'04', BND.ADDR = 16 byte
- */
+ if(socksreq[0] != 5) { /* version */
+ failf(data,
+ "SOCKS5 reply has wrong version, version should be 5.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(socksreq[1] != 0) { /* Anything besides 0 is an error */
+ failf(data, "Can't complete SOCKS5 connection to %s. (%d)",
+ hostname, (unsigned char)socksreq[1]);
+ return CURLE_COULDNT_CONNECT;
+ }
- /* Calculate real packet size */
- if(socksreq[3] == 3) {
- /* domain name */
- int addrlen = (int) socksreq[4];
- len = 5 + addrlen + 2;
- }
- else if(socksreq[3] == 4) {
- /* IPv6 */
- len = 4 + 16 + 2;
- }
+ /* Fix: in general, returned BND.ADDR is variable length parameter by RFC
+ 1928, so the reply packet should be read until the end to avoid errors
+ at subsequent protocol level.
+
+ +----+-----+-------+------+----------+----------+
+ |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+ +----+-----+-------+------+----------+----------+
+ | 1 | 1 | X'00' | 1 | Variable | 2 |
+ +----+-----+-------+------+----------+----------+
+
+ ATYP:
+ o IP v4 address: X'01', BND.ADDR = 4 byte
+ o domain name: X'03', BND.ADDR = [ 1 byte length, string ]
+ o IP v6 address: X'04', BND.ADDR = 16 byte
+ */
+
+ /* Calculate real packet size */
+ if(socksreq[3] == 3) {
+ /* domain name */
+ int addrlen = (int) socksreq[4];
+ len = 5 + addrlen + 2;
+ }
+ else if(socksreq[3] == 4) {
+ /* IPv6 */
+ len = 4 + 16 + 2;
+ }
- /* At this point we already read first 10 bytes */
+ /* At this point we already read first 10 bytes */
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- if(!conn->socks5_gssapi_enctype) {
- /* decrypt_gssapi_blockread already read the whole packet */
+ if(!conn->socks5_gssapi_enctype) {
+ /* decrypt_gssapi_blockread already read the whole packet */
#endif
- if(len > 10) {
- result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
- len - 10, &actualread);
- if(result || ((len - 10) != actualread)) {
- failf(data, "Failed to receive SOCKS5 connect request ack.");
- return CURLE_COULDNT_CONNECT;
+ if(len > 10) {
+ sx->outstanding = len - 10; /* get the rest */
+ sx->outp = &socksreq[10];
+ sxstate(conn, CONNECT_REQ_READ_MORE);
+ }
+ else {
+ sxstate(conn, CONNECT_DONE);
+ break;
}
- }
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- }
+ }
#endif
-
- if(socksreq[1] != 0) { /* Anything besides 0 is an error */
- failf(data, "Can't complete SOCKS5 connection to %s. (%d)",
- dest, (unsigned char)socksreq[1]);
- return CURLE_COULDNT_CONNECT;
+ /* FALLTHROUGH */
+ case CONNECT_REQ_READ_MORE:
+ result = Curl_read_plain(sockfd, (char *)sx->outp,
+ sx->outstanding, &actualread);
+ if(result && (CURLE_AGAIN != result)) {
+ failf(data, "Failed to receive SOCKS5 connect request ack.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ if(actualread != sx->outstanding) {
+ /* remain in state */
+ sx->outstanding -= actualread;
+ sx->outp += actualread;
+ return CURLE_OK;
+ }
+ sxstate(conn, CONNECT_DONE);
}
infof(data, "SOCKS5 request granted.\n");
- (void)curlx_nonblock(sock, TRUE);
+ *done = TRUE;
return CURLE_OK; /* Proxy was successful! */
}
diff --git a/libs/libcurl/src/socks.h b/libs/libcurl/src/socks.h
index 3b319a6ef1..64a7563373 100644
--- a/libs/libcurl/src/socks.h
+++ b/libs/libcurl/src/socks.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
@@ -27,13 +27,13 @@
#ifdef CURL_DISABLE_PROXY
#define Curl_SOCKS4(a,b,c,d,e) CURLE_NOT_BUILT_IN
#define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
+#define Curl_SOCKS_getsock(x,y,z) 0
#else
/*
* Helper read-from-socket functions. Does the same as Curl_read() but it
* blocks until all bytes amount of buffersize will be read. No more, no less.
*
- * This is STUPID BLOCKING behaviour which we frown upon, but right now this
- * is what we have...
+ * This is STUPID BLOCKING behavior
*/
int Curl_blockread_all(struct connectdata *conn,
curl_socket_t sockfd,
@@ -41,6 +41,9 @@ int Curl_blockread_all(struct connectdata *conn,
ssize_t buffersize,
ssize_t *n);
+int Curl_SOCKS_getsock(struct connectdata *conn,
+ curl_socket_t *sock,
+ int sockindex);
/*
* This function logs in to a SOCKS4(a) proxy and sends the specifics to the
* final destination server.
@@ -49,7 +52,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
const char *hostname,
int remote_port,
int sockindex,
- struct connectdata *conn);
+ struct connectdata *conn,
+ bool *done);
/*
* This function logs in to a SOCKS5 proxy and sends the specifics to the
@@ -60,7 +64,8 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
const char *hostname,
int remote_port,
int sockindex,
- struct connectdata *conn);
+ struct connectdata *conn,
+ bool *done);
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
/*
diff --git a/libs/libcurl/src/socks_gssapi.c b/libs/libcurl/src/socks_gssapi.c
index 65294bbebd..97ee7183e0 100644
--- a/libs/libcurl/src/socks_gssapi.c
+++ b/libs/libcurl/src/socks_gssapi.c
@@ -5,8 +5,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
- * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -167,6 +167,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
return CURLE_COULDNT_CONNECT;
}
+ (void)curlx_nonblock(sock, FALSE);
+
/* As long as we need to keep sending some context info, and there's no */
/* errors, keep sending it... */
for(;;) {
@@ -513,6 +515,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
gss_release_buffer(&gss_status, &gss_recv_token);
}
+ (void)curlx_nonblock(sock, TRUE);
+
infof(data, "SOCKS5 access with%s protection granted.\n",
(socksreq[0] == 0)?"out GSS-API data":
((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality"));
diff --git a/libs/libcurl/src/socks_sspi.c b/libs/libcurl/src/socks_sspi.c
index 57027ef686..d5be64a3c0 100644
--- a/libs/libcurl/src/socks_sspi.c
+++ b/libs/libcurl/src/socks_sspi.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) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
*
* This software is licensed as described in the file COPYING, which
@@ -153,6 +153,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
return CURLE_COULDNT_CONNECT;
}
+ (void)curlx_nonblock(sock, FALSE);
+
/* As long as we need to keep sending some context info, and there's no */
/* errors, keep sending it... */
for(;;) {
@@ -587,6 +589,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
}
+ (void)curlx_nonblock(sock, TRUE);
infof(data, "SOCKS5 access with%s protection granted.\n",
(socksreq[0] == 0)?"out GSS-API data":
diff --git a/libs/libcurl/src/strcase.c b/libs/libcurl/src/strcase.c
index a894712254..a309e35291 100644
--- a/libs/libcurl/src/strcase.c
+++ b/libs/libcurl/src/strcase.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,8 @@
#include "strcase.h"
+static char raw_tolower(char in);
+
/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
its behavior is altered by the current locale. */
char Curl_raw_toupper(char in)
@@ -96,7 +98,7 @@ char Curl_raw_toupper(char in)
/* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because
its behavior is altered by the current locale. */
-char Curl_raw_tolower(char in)
+static char raw_tolower(char in)
{
#if !defined(CURL_DOES_CONVERSIONS)
if(in >= 'A' && in <= 'Z')
@@ -245,7 +247,7 @@ void Curl_strntolower(char *dest, const char *src, size_t n)
return;
do {
- *dest++ = Curl_raw_tolower(*src);
+ *dest++ = raw_tolower(*src);
} while(*src++ && --n);
}
diff --git a/libs/libcurl/src/strcase.h b/libs/libcurl/src/strcase.h
index baa768b2b2..cd4c4191a9 100644
--- a/libs/libcurl/src/strcase.h
+++ b/libs/libcurl/src/strcase.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
@@ -40,7 +40,6 @@ int Curl_safe_strcasecompare(const char *first, const char *second);
int Curl_strncasecompare(const char *first, const char *second, size_t max);
char Curl_raw_toupper(char in);
-char Curl_raw_tolower(char in);
/* checkprefix() is a shorter version of the above, used when the first
argument is zero-byte terminated */
diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c
index 29df5aa55a..1a166bf019 100644
--- a/libs/libcurl/src/strerror.c
+++ b/libs/libcurl/src/strerror.c
@@ -317,6 +317,9 @@ curl_easy_strerror(CURLcode error)
case CURLE_HTTP3:
return "HTTP/3 error";
+ case CURLE_QUIC_CONNECT_ERROR:
+ return "QUIC connection error";
+
/* error codes not used by current libcurl */
case CURLE_OBSOLETE20:
case CURLE_OBSOLETE24:
@@ -392,6 +395,9 @@ curl_multi_strerror(CURLMcode error)
case CURLM_WAKEUP_FAILURE:
return "Wakeup is unavailable or failed";
+ case CURLM_BAD_FUNCTION_ARGUMENT:
+ return "A libcurl function was given a bad argument";
+
case CURLM_LAST:
break;
}
diff --git a/libs/libcurl/src/strerror.h b/libs/libcurl/src/strerror.h
index 278c1082f0..bae8f89745 100644
--- a/libs/libcurl/src/strerror.h
+++ b/libs/libcurl/src/strerror.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
@@ -24,7 +24,7 @@
#include "urldata.h"
-#define STRERROR_LEN 128 /* a suitable length */
+#define STRERROR_LEN 256 /* a suitable length */
const char *Curl_strerror(int err, char *buf, size_t buflen);
#if defined(WIN32) || defined(_WIN32_WCE)
diff --git a/libs/libcurl/src/system_win32.c b/libs/libcurl/src/system_win32.c
index 52a5fd9519..b9587b5f3a 100644
--- a/libs/libcurl/src/system_win32.c
+++ b/libs/libcurl/src/system_win32.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2016 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2016 - 2020, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -109,11 +109,11 @@ CURLcode Curl_win32_init(long flags)
if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
Curl_isVistaOrGreater = TRUE;
- QueryPerformanceFrequency(&Curl_freq);
}
else
Curl_isVistaOrGreater = FALSE;
+ QueryPerformanceFrequency(&Curl_freq);
return CURLE_OK;
}
diff --git a/libs/libcurl/src/timeval.c b/libs/libcurl/src/timeval.c
index 9b05cf0512..e761966a1b 100644
--- a/libs/libcurl/src/timeval.c
+++ b/libs/libcurl/src/timeval.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
@@ -28,6 +28,7 @@
extern LARGE_INTEGER Curl_freq;
extern bool Curl_isVistaOrGreater;
+/* In case of bug fix this function has a counterpart in tool_util.c */
struct curltime Curl_now(void)
{
struct curltime now;
diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c
index ead8b36db9..827076183f 100644
--- a/libs/libcurl/src/transfer.c
+++ b/libs/libcurl/src/transfer.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
@@ -1217,7 +1217,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
else
fd_write = CURL_SOCKET_BAD;
- if(conn->data->state.drain) {
+ if(data->state.drain) {
+ data->state.drain--;
select_res |= CURL_CSELECT_IN;
DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n"));
}
diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c
index 56fb736368..47fc66aedd 100644
--- a/libs/libcurl/src/url.c
+++ b/libs/libcurl/src/url.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
@@ -128,7 +128,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "memdebug.h"
static void conn_free(struct connectdata *conn);
-static void free_idnconverted_hostname(struct hostname *host);
static unsigned int get_protocol_family(unsigned int protocol);
/* Some parts of the code (e.g. chunked encoding) assume this buffer has at
@@ -187,7 +186,7 @@ static const struct Curl_handler * const protocols[] = {
&Curl_handler_tftp,
#endif
-#if defined(USE_SSH)
+#if defined(USE_SSH) && !defined(USE_WOLFSSH)
&Curl_handler_scp,
#endif
@@ -380,7 +379,7 @@ CURLcode Curl_close(struct Curl_easy **datap)
Curl_safefree(data->state.ulbuf);
Curl_flush_cookies(data, TRUE);
#ifdef USE_ALTSVC
- Curl_altsvc_save(data->asi, data->set.str[STRING_ALTSVC]);
+ Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]);
Curl_altsvc_cleanup(data->asi);
data->asi = NULL;
#endif
@@ -714,14 +713,13 @@ static void conn_free(struct connectdata *conn)
if(!conn)
return;
- free_idnconverted_hostname(&conn->host);
- free_idnconverted_hostname(&conn->conn_to_host);
- free_idnconverted_hostname(&conn->http_proxy.host);
- free_idnconverted_hostname(&conn->socks_proxy.host);
+ Curl_free_idnconverted_hostname(&conn->host);
+ Curl_free_idnconverted_hostname(&conn->conn_to_host);
+ Curl_free_idnconverted_hostname(&conn->http_proxy.host);
+ Curl_free_idnconverted_hostname(&conn->socks_proxy.host);
Curl_safefree(conn->user);
Curl_safefree(conn->passwd);
- Curl_safefree(conn->oauth_bearer);
Curl_safefree(conn->sasl_authzid);
Curl_safefree(conn->options);
Curl_safefree(conn->http_proxy.user);
@@ -883,9 +881,37 @@ proxy_info_matches(const struct proxy_info* data,
return FALSE;
}
+
+static bool
+socks_proxy_info_matches(const struct proxy_info* data,
+ const struct proxy_info* needle)
+{
+ if(!proxy_info_matches(data, needle))
+ return FALSE;
+
+ /* the user information is case-sensitive
+ or at least it is not defined as case-insensitive
+ see https://tools.ietf.org/html/rfc3986#section-3.2.1 */
+ if((data->user == NULL) != (needle->user == NULL))
+ return FALSE;
+ /* curl_strequal does a case insentive comparison, so do not use it here! */
+ if(data->user &&
+ needle->user &&
+ strcmp(data->user, needle->user) != 0)
+ return FALSE;
+ if((data->passwd == NULL) != (needle->passwd == NULL))
+ return FALSE;
+ /* curl_strequal does a case insentive comparison, so do not use it here! */
+ if(data->passwd &&
+ needle->passwd &&
+ strcmp(data->passwd, needle->passwd) != 0)
+ return FALSE;
+ return TRUE;
+}
#else
/* disabled, won't get called */
#define proxy_info_matches(x,y) FALSE
+#define socks_proxy_info_matches(x,y) FALSE
#endif
/* A connection has to have been idle for a shorter time than 'maxage_conn' to
@@ -1073,7 +1099,7 @@ ConnectionExists(struct Curl_easy *data,
curr = bundle->conn_list.head;
while(curr) {
bool match = FALSE;
- size_t multiplexed;
+ size_t multiplexed = 0;
/*
* Note that if we use a HTTP proxy in normal mode (no tunneling), we
@@ -1086,8 +1112,8 @@ ConnectionExists(struct Curl_easy *data,
/* connect-only or to-be-closed connections will not be reused */
continue;
- multiplexed = CONN_INUSE(check) &&
- (bundle->multiuse == BUNDLE_MULTIPLEX);
+ if(bundle->multiuse == BUNDLE_MULTIPLEX)
+ multiplexed = CONN_INUSE(check);
if(canmultiplex) {
;
@@ -1144,8 +1170,9 @@ ConnectionExists(struct Curl_easy *data,
needle->bits.socksproxy != check->bits.socksproxy)
continue;
- if(needle->bits.socksproxy && !proxy_info_matches(&needle->socks_proxy,
- &check->socks_proxy))
+ if(needle->bits.socksproxy &&
+ !socks_proxy_info_matches(&needle->socks_proxy,
+ &check->socks_proxy))
continue;
if(needle->bits.conn_to_host != check->bits.conn_to_host)
@@ -1185,6 +1212,8 @@ ConnectionExists(struct Curl_easy *data,
}
}
+ DEBUGASSERT(!check->data || GOOD_EASY_HANDLE(check->data));
+
if(!canmultiplex && check->data)
/* this request can't be multiplexed but the checked connection is
already in use so we skip it */
@@ -1239,7 +1268,7 @@ ConnectionExists(struct Curl_easy *data,
needle->conn_to_port == check->conn_to_port) &&
strcasecompare(needle->host.name, check->host.name) &&
needle->remote_port == check->remote_port) {
- /* The schemes match or the the protocol family is the same and the
+ /* The schemes match or the protocol family is the same and the
previous connection was TLS upgraded, and the hostname and host
port match */
if(needle->handler->flags & PROTOPT_SSL) {
@@ -1347,6 +1376,13 @@ ConnectionExists(struct Curl_easy *data,
multiplexed);
continue;
}
+ else if(multiplexed >=
+ Curl_multi_max_concurrent_streams(needle->data->multi)) {
+ infof(data, "client side MAX_CONCURRENT_STREAMS reached"
+ ", skip (%zu)\n",
+ multiplexed);
+ continue;
+ }
}
#endif
/* When not multiplexed, we have a match here! */
@@ -1400,10 +1436,14 @@ void Curl_verboseconnect(struct connectdata *conn)
/*
* Helpers for IDNA conversions.
*/
-static bool is_ASCII_name(const char *hostname)
+bool Curl_is_ASCII_name(const char *hostname)
{
+ /* get an UNSIGNED local version of the pointer */
const unsigned char *ch = (const unsigned char *)hostname;
+ if(!hostname) /* bad input, consider it ASCII! */
+ return TRUE;
+
while(*ch) {
if(*ch++ & 0x80)
return FALSE;
@@ -1428,8 +1468,8 @@ static void strip_trailing_dot(struct hostname *host)
/*
* Perform any necessary IDN conversion of hostname
*/
-static CURLcode idnconvert_hostname(struct connectdata *conn,
- struct hostname *host)
+CURLcode Curl_idnconvert_hostname(struct connectdata *conn,
+ struct hostname *host)
{
struct Curl_easy *data = conn->data;
@@ -1444,7 +1484,7 @@ static CURLcode idnconvert_hostname(struct connectdata *conn,
host->dispname = host->name;
/* Check name for non-ASCII and convert hostname to ACE form if we can */
- if(!is_ASCII_name(host->name)) {
+ if(!Curl_is_ASCII_name(host->name)) {
#ifdef USE_LIBIDN2
if(idn2_check_version(IDN2_VERSION)) {
char *ace_hostname = NULL;
@@ -1477,7 +1517,9 @@ static CURLcode idnconvert_hostname(struct connectdata *conn,
host->name = host->encalloc;
}
else {
- failf(data, "Failed to convert %s to ACE;\n", host->name);
+ char buffer[STRERROR_LEN];
+ failf(data, "Failed to convert %s to ACE; %s\n", host->name,
+ Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
return CURLE_URL_MALFORMAT;
}
#else
@@ -1490,7 +1532,7 @@ static CURLcode idnconvert_hostname(struct connectdata *conn,
/*
* Frees data allocated by idnconvert_hostname()
*/
-static void free_idnconverted_hostname(struct hostname *host)
+void Curl_free_idnconverted_hostname(struct hostname *host)
{
#if defined(USE_LIBIDN2)
if(host->encalloc) {
@@ -1615,7 +1657,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
defined(NTLM_WB_ENABLED)
- conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+ conn->ntlm.ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+ conn->proxyntlm.ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
#endif
/* Initialize the easy handle list */
@@ -3194,8 +3237,8 @@ static CURLcode resolve_server(struct Curl_easy *data,
static void reuse_conn(struct connectdata *old_conn,
struct connectdata *conn)
{
- free_idnconverted_hostname(&old_conn->http_proxy.host);
- free_idnconverted_hostname(&old_conn->socks_proxy.host);
+ Curl_free_idnconverted_hostname(&old_conn->http_proxy.host);
+ Curl_free_idnconverted_hostname(&old_conn->socks_proxy.host);
free(old_conn->http_proxy.host.rawalloc);
free(old_conn->socks_proxy.host.rawalloc);
@@ -3239,8 +3282,8 @@ static void reuse_conn(struct connectdata *old_conn,
/* host can change, when doing keepalive with a proxy or if the case is
different this time etc */
- free_idnconverted_hostname(&conn->host);
- free_idnconverted_hostname(&conn->conn_to_host);
+ Curl_free_idnconverted_hostname(&conn->host);
+ Curl_free_idnconverted_hostname(&conn->conn_to_host);
Curl_safefree(conn->host.rawalloc);
Curl_safefree(conn->conn_to_host.rawalloc);
conn->host = old_conn->host;
@@ -3336,14 +3379,6 @@ static CURLcode create_conn(struct Curl_easy *data,
if(result)
goto out;
- if(data->set.str[STRING_BEARER]) {
- conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
- if(!conn->oauth_bearer) {
- result = CURLE_OUT_OF_MEMORY;
- goto out;
- }
- }
-
if(data->set.str[STRING_SASL_AUTHZID]) {
conn->sasl_authzid = strdup(data->set.str[STRING_SASL_AUTHZID]);
if(!conn->sasl_authzid) {
@@ -3407,21 +3442,21 @@ static CURLcode create_conn(struct Curl_easy *data,
/*************************************************************
* IDN-convert the hostnames
*************************************************************/
- result = idnconvert_hostname(conn, &conn->host);
+ result = Curl_idnconvert_hostname(conn, &conn->host);
if(result)
goto out;
if(conn->bits.conn_to_host) {
- result = idnconvert_hostname(conn, &conn->conn_to_host);
+ result = Curl_idnconvert_hostname(conn, &conn->conn_to_host);
if(result)
goto out;
}
if(conn->bits.httpproxy) {
- result = idnconvert_hostname(conn, &conn->http_proxy.host);
+ result = Curl_idnconvert_hostname(conn, &conn->http_proxy.host);
if(result)
goto out;
}
if(conn->bits.socksproxy) {
- result = idnconvert_hostname(conn, &conn->socks_proxy.host);
+ result = Curl_idnconvert_hostname(conn, &conn->socks_proxy.host);
if(result)
goto out;
}
diff --git a/libs/libcurl/src/url.h b/libs/libcurl/src/url.h
index 053fbdffc2..5000c512a8 100644
--- a/libs/libcurl/src/url.h
+++ b/libs/libcurl/src/url.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
@@ -62,6 +62,11 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len,
const struct Curl_handler *Curl_builtin_scheme(const char *scheme);
+bool Curl_is_ASCII_name(const char *hostname);
+CURLcode Curl_idnconvert_hostname(struct connectdata *conn,
+ struct hostname *host);
+void Curl_free_idnconverted_hostname(struct hostname *host);
+
#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
#define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless
specified */
diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c
index fa514bce53..506e244dc4 100644
--- a/libs/libcurl/src/urlapi.c
+++ b/libs/libcurl/src/urlapi.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
@@ -428,7 +428,6 @@ static char *concat_url(const char *base, const char *relurl)
*
*/
static CURLUcode parse_hostname_login(struct Curl_URL *u,
- const struct Curl_handler *h,
char **hostname,
unsigned int flags)
{
@@ -437,6 +436,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
char *userp = NULL;
char *passwdp = NULL;
char *optionsp = NULL;
+ const struct Curl_handler *h = NULL;
/* At this point, we're hoping all the other special cases have
* been taken care of, so conn->host.name is at most
@@ -456,6 +456,10 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
* ftp://user:password@ftp.my.site:8021/README */
*hostname = ++ptr;
+ /* if this is a known scheme, get some details */
+ if(u->scheme)
+ h = Curl_builtin_scheme(u->scheme);
+
/* We could use the login information in the URL so extract it. Only parse
options if the handler says we should. Note that 'h' might be NULL! */
ccode = Curl_parse_login_details(login, ptr - login - 1,
@@ -571,7 +575,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
}
/* scan for byte values < 31 or 127 */
-static CURLUcode junkscan(char *part)
+static CURLUcode junkscan(const char *part)
{
if(part) {
static const char badbytes[]={
@@ -668,10 +672,9 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
CURLUcode result;
bool url_has_scheme = FALSE;
char schemebuf[MAX_SCHEME_LEN + 1];
- char *schemep = NULL;
+ const char *schemep = NULL;
size_t schemelen = 0;
size_t urllen;
- const struct Curl_handler *h = NULL;
if(!url)
return CURLUE_MALFORMED_INPUT;
@@ -798,7 +801,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME)))
return CURLUE_MALFORMED_INPUT;
if(flags & CURLU_DEFAULT_SCHEME)
- schemep = (char *) DEFAULT_SCHEME;
+ schemep = DEFAULT_SCHEME;
/*
* The URL was badly formatted, let's try without scheme specified.
@@ -820,36 +823,17 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
return CURLUE_MALFORMED_INPUT;
}
- if((flags & CURLU_GUESS_SCHEME) && !schemep) {
- /* legacy curl-style guess based on host name */
- if(checkprefix("ftp.", hostname))
- schemep = (char *)"ftp";
- else if(checkprefix("dict.", hostname))
- schemep = (char *)"dict";
- else if(checkprefix("ldap.", hostname))
- schemep = (char *)"ldap";
- else if(checkprefix("imap.", hostname))
- schemep = (char *)"imap";
- else if(checkprefix("smtp.", hostname))
- schemep = (char *)"smtp";
- else if(checkprefix("pop3.", hostname))
- schemep = (char *)"pop3";
- else
- schemep = (char *)"http";
- }
-
len = strlen(p);
memcpy(path, p, len);
path[len] = 0;
- u->scheme = strdup(schemep);
- if(!u->scheme)
- return CURLUE_OUT_OF_MEMORY;
+ if(schemep) {
+ u->scheme = strdup(schemep);
+ if(!u->scheme)
+ return CURLUE_OUT_OF_MEMORY;
+ }
}
- /* if this is a known scheme, get some details */
- h = Curl_builtin_scheme(u->scheme);
-
if(junkscan(path))
return CURLUE_MALFORMED_INPUT;
@@ -916,7 +900,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(junkscan(hostname))
return CURLUE_MALFORMED_INPUT;
- result = parse_hostname_login(u, h, &hostname, flags);
+ result = parse_hostname_login(u, &hostname, flags);
if(result)
return result;
@@ -936,6 +920,28 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
u->host = strdup(hostname);
if(!u->host)
return CURLUE_OUT_OF_MEMORY;
+
+ if((flags & CURLU_GUESS_SCHEME) && !schemep) {
+ /* legacy curl-style guess based on host name */
+ if(checkprefix("ftp.", hostname))
+ schemep = "ftp";
+ else if(checkprefix("dict.", hostname))
+ schemep = "dict";
+ else if(checkprefix("ldap.", hostname))
+ schemep = "ldap";
+ else if(checkprefix("imap.", hostname))
+ schemep = "imap";
+ else if(checkprefix("smtp.", hostname))
+ schemep = "smtp";
+ else if(checkprefix("pop3.", hostname))
+ schemep = "pop3";
+ else
+ schemep = "http";
+
+ u->scheme = strdup(schemep);
+ if(!u->scheme)
+ return CURLUE_OUT_OF_MEMORY;
+ }
}
Curl_safefree(u->scratch);
diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h
index 3effb1626f..e1348cf29b 100644
--- a/libs/libcurl/src/urldata.h
+++ b/libs/libcurl/src/urldata.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
@@ -367,6 +367,14 @@ struct ntlmdata {
unsigned char nonce[8];
void *target_info; /* TargetInfo received in the ntlm type-2 message */
unsigned int target_info_len;
+
+#if defined(NTLM_WB_ENABLED)
+ /* used for communication with Samba's winbind daemon helper ntlm_auth */
+ curl_socket_t ntlm_auth_hlpr_socket;
+ pid_t ntlm_auth_hlpr_pid;
+ char *challenge; /* The received base64 encoded ntlm type-2 message */
+ char *response; /* The generated base64 ntlm type-1/type-3 message */
+#endif
#endif
};
#endif
@@ -468,7 +476,6 @@ struct ConnectBits {
BIT(tcp_fastopen); /* use TCP Fast Open */
BIT(tls_enable_npn); /* TLS NPN extension? */
BIT(tls_enable_alpn); /* TLS ALPN extension? */
- BIT(socksproxy_connecting); /* connecting through a socks proxy */
BIT(connect_only);
};
@@ -809,6 +816,41 @@ struct http_connect_state {
struct ldapconninfo;
+/* for the (SOCKS) connect state machine */
+enum connect_t {
+ CONNECT_INIT,
+ CONNECT_SOCKS_INIT, /* 1 */
+ CONNECT_SOCKS_SEND, /* 2 waiting to send more first data */
+ CONNECT_SOCKS_READ_INIT, /* 3 set up read */
+ CONNECT_SOCKS_READ, /* 4 read server response */
+ CONNECT_GSSAPI_INIT, /* 5 */
+ CONNECT_AUTH_INIT, /* 6 setup outgoing auth buffer */
+ CONNECT_AUTH_SEND, /* 7 send auth */
+ CONNECT_AUTH_READ, /* 8 read auth response */
+ CONNECT_REQ_INIT, /* 9 init SOCKS "request" */
+ CONNECT_RESOLVING, /* 10 */
+ CONNECT_RESOLVED, /* 11 */
+ CONNECT_RESOLVE_REMOTE, /* 12 */
+ CONNECT_REQ_SEND, /* 13 */
+ CONNECT_REQ_SENDING, /* 14 */
+ CONNECT_REQ_READ, /* 15 */
+ CONNECT_REQ_READ_MORE, /* 16 */
+ CONNECT_DONE /* 17 connected fine to the remote or the SOCKS proxy */
+};
+
+#define SOCKS_STATE(x) (((x) >= CONNECT_SOCKS_INIT) && \
+ ((x) < CONNECT_DONE))
+#define SOCKS_REQUEST_BUFSIZE 600 /* room for large user/pw (255 max each) */
+
+struct connstate {
+ enum connect_t state;
+ unsigned char socksreq[SOCKS_REQUEST_BUFSIZE];
+
+ /* CONNECT_SOCKS_SEND */
+ ssize_t outstanding; /* send this many bytes more */
+ unsigned char *outp; /* send from this pointer */
+};
+
/*
* The connectdata struct contains all fields and variables that should be
* unique for an entire connection.
@@ -818,7 +860,7 @@ struct connectdata {
caution that this might very well vary between different times this
connection is used! */
struct Curl_easy *data;
-
+ struct connstate cnnct;
struct curl_llist_element bundle_node; /* conncache */
/* chunk is for HTTP chunked encoding, but is in the general connectdata
@@ -906,7 +948,6 @@ struct connectdata {
char *passwd; /* password string, allocated */
char *options; /* options string, allocated */
- char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
char *sasl_authzid; /* authorisation identity string, allocated */
int httpversion; /* the HTTP version*10 reported by the server */
@@ -918,8 +959,6 @@ struct connectdata {
curl_socket_t sock[2]; /* two sockets, the second is used for the data
transfer when doing FTP */
curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */
- bool sock_accepted[2]; /* TRUE if the socket on this index was created with
- accept() */
Curl_recv *recv[2];
Curl_send *send[2];
@@ -1011,14 +1050,6 @@ struct connectdata {
because it authenticates connections, not
single requests! */
struct ntlmdata proxyntlm; /* NTLM data for proxy */
-
-#if defined(NTLM_WB_ENABLED)
- /* used for communication with Samba's winbind daemon helper ntlm_auth */
- curl_socket_t ntlm_auth_hlpr_socket;
- pid_t ntlm_auth_hlpr_pid;
- char *challenge_header;
- char *response_header;
-#endif
#endif
#ifdef USE_SPNEGO
@@ -1082,6 +1113,8 @@ struct connectdata {
handle */
BIT(writechannel_inuse); /* whether the write channel is in use by an easy
handle */
+ BIT(sock_accepted); /* TRUE if the SECONDARYSOCKET was created with
+ accept() */
};
/* The end of connectdata. */
@@ -1409,6 +1442,8 @@ struct UrlState {
BIT(ftp_trying_alternative);
BIT(wildcardmatch); /* enable wildcard matching */
BIT(expect100header); /* TRUE if we added Expect: 100-continue */
+ BIT(disableexpect); /* TRUE if Expect: is disabled due to a previous
+ 417 response */
BIT(use_range);
BIT(rangestringalloc); /* the range string is malloc()'ed */
BIT(done); /* set to FALSE when Curl_init_do() is called and set to TRUE
@@ -1451,6 +1486,14 @@ struct DynamicStatic {
struct Curl_multi; /* declared and used only in multi.c */
+/*
+ * This enumeration MUST not use conditional directives (#ifdefs), new
+ * null terminated strings MUST be added to the enumeration immediately
+ * before STRING_LASTZEROTERMINATED, binary fields immediately before
+ * STRING_LAST. When doing so, ensure that the packages/OS400/chkstring.c
+ * test is updated and applicable changes for EBCDIC to ASCII conversion
+ * are catered for in curl_easy_setopt_ccsid()
+ */
enum dupstring {
STRING_CERT_ORIG, /* client certificate file name */
STRING_CERT_PROXY, /* client certificate file name */
@@ -1507,36 +1550,35 @@ enum dupstring {
STRING_RTSP_SESSION_ID, /* Session ID to use */
STRING_RTSP_STREAM_URI, /* Stream URI for this request */
STRING_RTSP_TRANSPORT, /* Transport for this session */
-#ifdef USE_SSH
+
STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */
STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */
STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
STRING_SSH_KNOWNHOSTS, /* file name of knownhosts file */
-#endif
+
STRING_PROXY_SERVICE_NAME, /* Proxy service name */
STRING_SERVICE_NAME, /* Service name */
STRING_MAIL_FROM,
STRING_MAIL_AUTH,
-#ifdef USE_TLS_SRP
STRING_TLSAUTH_USERNAME_ORIG, /* TLS auth <username> */
STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth <username> */
STRING_TLSAUTH_PASSWORD_ORIG, /* TLS auth <password> */
STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth <password> */
-#endif
+
STRING_BEARER, /* <bearer>, if used */
-#ifdef USE_UNIX_SOCKETS
+
STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */
-#endif
+
STRING_TARGET, /* CURLOPT_REQUEST_TARGET */
STRING_DOH, /* CURLOPT_DOH_URL */
-#ifdef USE_ALTSVC
+
STRING_ALTSVC, /* CURLOPT_ALTSVC */
-#endif
+
STRING_SASL_AUTHZID, /* CURLOPT_SASL_AUTHZID */
-#ifndef CURL_DISABLE_PROXY
+
STRING_TEMP_URL, /* temp URL storage for proxy use */
-#endif
+
/* -- end of zero-terminated strings -- */
STRING_LASTZEROTERMINATED,
@@ -1792,6 +1834,8 @@ struct UserDefined {
BIT(doh); /* DNS-over-HTTPS enabled */
BIT(doh_get); /* use GET for DoH requests, instead of POST */
BIT(http09_allowed); /* allow HTTP/0.9 responses */
+ BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some
+ recipients */
};
struct Names {
diff --git a/libs/libcurl/src/vauth/digest.c b/libs/libcurl/src/vauth/digest.c
index 8cd4d83ed3..a8835705f3 100644
--- a/libs/libcurl/src/vauth/digest.c
+++ b/libs/libcurl/src/vauth/digest.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
@@ -62,7 +62,7 @@
what ultimately goes over the network.
*/
#define CURL_OUTPUT_DIGEST_CONV(a, b) \
- result = Curl_convert_to_network(a, (char *)b, strlen((const char *)b)); \
+ result = Curl_convert_to_network(a, b, strlen(b)); \
if(result) { \
free(b); \
return result; \
@@ -660,7 +660,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
}
/*
- * _Curl_auth_create_digest_http_message()
+ * auth_create_digest_http_message()
*
* This is used to generate a HTTP DIGEST response message ready for sending
* to the recipient.
@@ -679,7 +679,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
*
* Returns CURLE_OK on success.
*/
-static CURLcode _Curl_auth_create_digest_http_message(
+static CURLcode auth_create_digest_http_message(
struct Curl_easy *data,
const char *userp,
const char *passwdp,
@@ -688,12 +688,12 @@ static CURLcode _Curl_auth_create_digest_http_message(
struct digestdata *digest,
char **outptr, size_t *outlen,
void (*convert_to_ascii)(unsigned char *, unsigned char *),
- void (*hash)(unsigned char *, const unsigned char *))
+ void (*hash)(unsigned char *, const unsigned char *,
+ const size_t))
{
CURLcode result;
unsigned char hashbuf[32]; /* 32 bytes/256 bits */
unsigned char request_digest[65];
- unsigned char *hashthis;
unsigned char ha1[65]; /* 64 digits and 1 zero byte */
unsigned char ha2[65]; /* 64 digits and 1 zero byte */
char userh[65];
@@ -701,6 +701,7 @@ static CURLcode _Curl_auth_create_digest_http_message(
size_t cnonce_sz = 0;
char *userp_quoted;
char *response = NULL;
+ char *hashthis = NULL;
char *tmp = NULL;
if(!digest->nc)
@@ -722,12 +723,12 @@ static CURLcode _Curl_auth_create_digest_http_message(
}
if(digest->userhash) {
- hashthis = (unsigned char *) aprintf("%s:%s", userp, digest->realm);
+ hashthis = aprintf("%s:%s", userp, digest->realm);
if(!hashthis)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, hashthis);
- hash(hashbuf, hashthis);
+ hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
free(hashthis);
convert_to_ascii(hashbuf, (unsigned char *)userh);
}
@@ -743,14 +744,13 @@ static CURLcode _Curl_auth_create_digest_http_message(
unq(nonce-value) ":" unq(cnonce-value)
*/
- hashthis = (unsigned char *)
- aprintf("%s:%s:%s", digest->userhash ? userh : userp,
- digest->realm, passwdp);
+ hashthis = aprintf("%s:%s:%s", digest->userhash ? userh : userp,
+ digest->realm, passwdp);
if(!hashthis)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
- hash(hashbuf, hashthis);
+ hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
free(hashthis);
convert_to_ascii(hashbuf, ha1);
@@ -763,7 +763,7 @@ static CURLcode _Curl_auth_create_digest_http_message(
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, tmp); /* Convert on non-ASCII machines */
- hash(hashbuf, (unsigned char *) tmp);
+ hash(hashbuf, (unsigned char *) tmp, strlen(tmp));
free(tmp);
convert_to_ascii(hashbuf, ha1);
}
@@ -781,19 +781,19 @@ static CURLcode _Curl_auth_create_digest_http_message(
5.1.1 of RFC 2616)
*/
- hashthis = (unsigned char *) aprintf("%s:%s", request, uripath);
+ hashthis = aprintf("%s:%s", request, uripath);
if(!hashthis)
return CURLE_OUT_OF_MEMORY;
if(digest->qop && strcasecompare(digest->qop, "auth-int")) {
/* We don't support auth-int for PUT or POST */
char hashed[65];
- unsigned char *hashthis2;
+ char *hashthis2;
- hash(hashbuf, (const unsigned char *)"");
+ hash(hashbuf, (const unsigned char *)"", 0);
convert_to_ascii(hashbuf, (unsigned char *)hashed);
- hashthis2 = (unsigned char *)aprintf("%s:%s", hashthis, hashed);
+ hashthis2 = aprintf("%s:%s", hashthis, hashed);
free(hashthis);
hashthis = hashthis2;
}
@@ -802,31 +802,23 @@ static CURLcode _Curl_auth_create_digest_http_message(
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
- hash(hashbuf, hashthis);
+ hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
free(hashthis);
convert_to_ascii(hashbuf, ha2);
if(digest->qop) {
- hashthis = (unsigned char *) aprintf("%s:%s:%08x:%s:%s:%s",
- ha1,
- digest->nonce,
- digest->nc,
- digest->cnonce,
- digest->qop,
- ha2);
+ hashthis = aprintf("%s:%s:%08x:%s:%s:%s", ha1, digest->nonce, digest->nc,
+ digest->cnonce, digest->qop, ha2);
}
else {
- hashthis = (unsigned char *) aprintf("%s:%s:%s",
- ha1,
- digest->nonce,
- ha2);
+ hashthis = aprintf("%s:%s:%s", ha1, digest->nonce, ha2);
}
if(!hashthis)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
- hash(hashbuf, hashthis);
+ hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
free(hashthis);
convert_to_ascii(hashbuf, request_digest);
@@ -899,7 +891,7 @@ static CURLcode _Curl_auth_create_digest_http_message(
if(digest->algorithm) {
/* Append the algorithm */
- tmp = aprintf("%s, algorithm=\"%s\"", response, digest->algorithm);
+ tmp = aprintf("%s, algorithm=%s", response, digest->algorithm);
free(response);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
@@ -955,21 +947,21 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
switch(digest->algo) {
case CURLDIGESTALGO_MD5:
case CURLDIGESTALGO_MD5SESS:
- return _Curl_auth_create_digest_http_message(data, userp, passwdp,
- request, uripath, digest,
- outptr, outlen,
- auth_digest_md5_to_ascii,
- Curl_md5it);
+ return auth_create_digest_http_message(data, userp, passwdp,
+ request, uripath, digest,
+ outptr, outlen,
+ auth_digest_md5_to_ascii,
+ Curl_md5it);
case CURLDIGESTALGO_SHA256:
case CURLDIGESTALGO_SHA256SESS:
case CURLDIGESTALGO_SHA512_256:
case CURLDIGESTALGO_SHA512_256SESS:
- return _Curl_auth_create_digest_http_message(data, userp, passwdp,
- request, uripath, digest,
- outptr, outlen,
- auth_digest_sha256_to_ascii,
- Curl_sha256it);
+ return auth_create_digest_http_message(data, userp, passwdp,
+ request, uripath, digest,
+ outptr, outlen,
+ auth_digest_sha256_to_ascii,
+ Curl_sha256it);
default:
return CURLE_UNSUPPORTED_PROTOCOL;
diff --git a/libs/libcurl/src/vauth/ntlm.c b/libs/libcurl/src/vauth/ntlm.c
index 047c2b5a3f..8f91038064 100644
--- a/libs/libcurl/src/vauth/ntlm.c
+++ b/libs/libcurl/src/vauth/ntlm.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
@@ -40,6 +40,7 @@
#include "curl_ntlm_core.h"
#include "curl_gethostname.h"
#include "curl_multibyte.h"
+#include "curl_md5.h"
#include "warnless.h"
#include "rand.h"
#include "vtls/vtls.h"
@@ -621,11 +622,11 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
memcpy(tmp, &ntlm->nonce[0], 8);
memcpy(tmp + 8, entropy, 8);
- result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
- if(!result)
- /* We shall only use the first 8 bytes of md5sum, but the des code in
- Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
- result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+ Curl_md5it(md5sum, tmp, 16);
+
+ /* We shall only use the first 8 bytes of md5sum, but the des code in
+ Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
+ result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
if(result)
return result;
diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c
index 6405d369d7..77aca7cbe8 100644
--- a/libs/libcurl/src/version.c
+++ b/libs/libcurl/src/version.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
@@ -265,8 +265,10 @@ static const char * const protocols[] = {
#ifndef CURL_DISABLE_RTSP
"rtsp",
#endif
-#if defined(USE_SSH)
+#if defined(USE_SSH) && !defined(USE_WOLFSSH)
"scp",
+#endif
+#ifdef USE_SSH
"sftp",
#endif
#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c
index e97e9e871b..0788404c02 100644
--- a/libs/libcurl/src/vquic/ngtcp2.c
+++ b/libs/libcurl/src/vquic/ngtcp2.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
@@ -146,7 +146,7 @@ static void quic_settings(ngtcp2_settings *s,
s->transport_params.initial_max_data = QUIC_MAX_DATA;
s->transport_params.initial_max_streams_bidi = 1;
s->transport_params.initial_max_streams_uni = 3;
- s->transport_params.idle_timeout = QUIC_IDLE_TIMEOUT;
+ s->transport_params.max_idle_timeout = QUIC_IDLE_TIMEOUT;
}
static FILE *keylog_file; /* not thread-safe */
@@ -535,6 +535,8 @@ static ngtcp2_conn_callbacks ng_callbacks = {
NULL, /* extend_max_remote_streams_bidi */
NULL, /* extend_max_remote_streams_uni */
cb_extend_max_stream_data,
+ NULL, /* dcid_status */
+ NULL /* handshake_confirmed */
};
/*
@@ -574,10 +576,10 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
qs->version = NGTCP2_PROTO_VER;
qs->sslctx = quic_ssl_ctx(data);
if(!qs->sslctx)
- return CURLE_FAILED_INIT; /* TODO: better return code */
+ return CURLE_QUIC_CONNECT_ERROR;
if(quic_init_ssl(qs))
- return CURLE_FAILED_INIT; /* TODO: better return code */
+ return CURLE_QUIC_CONNECT_ERROR;
qs->dcid.datalen = NGTCP2_MAX_CIDLEN;
result = Curl_rand(data, qs->dcid.data, NGTCP2_MAX_CIDLEN);
@@ -595,7 +597,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr,
&qs->local_addrlen);
if(rv == -1)
- return CURLE_FAILED_INIT;
+ return CURLE_QUIC_CONNECT_ERROR;
ngtcp2_addr_init(&path.local, (uint8_t *)&qs->local_addr, qs->local_addrlen,
NULL);
@@ -609,7 +611,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path, QUICVER,
&ng_callbacks, &qs->settings, NULL, qs);
if(rc)
- return CURLE_FAILED_INIT; /* TODO: create a QUIC error code */
+ return CURLE_QUIC_CONNECT_ERROR;
ngtcp2_conn_get_local_transport_params(qs->qconn, &params);
nwrite = ngtcp2_encode_transport_params(
@@ -618,15 +620,15 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
if(nwrite < 0) {
failf(data, "ngtcp2_encode_transport_params: %s\n",
ngtcp2_strerror((int)nwrite));
- return CURLE_FAILED_INIT;
+ return CURLE_QUIC_CONNECT_ERROR;
}
if(!SSL_set_quic_transport_params(qs->ssl, paramsbuf, nwrite))
- return CURLE_FAILED_INIT;
+ return CURLE_QUIC_CONNECT_ERROR;
rc = setup_initial_crypto_context(qs);
if(rc)
- return CURLE_FAILED_INIT; /* TODO: better return code */
+ return CURLE_QUIC_CONNECT_ERROR;
return CURLE_OK;
}
@@ -998,7 +1000,7 @@ static int init_ngh3_conn(struct quicsocket *qs)
if(ngtcp2_conn_get_max_local_streams_uni(qs->qconn) < 3) {
failf(qs->conn->data, "too few available QUIC streams");
- return CURLE_FAILED_INIT;
+ return CURLE_QUIC_CONNECT_ERROR;
}
nghttp3_conn_settings_default(&qs->h3settings);
@@ -1015,32 +1017,32 @@ static int init_ngh3_conn(struct quicsocket *qs)
rc = ngtcp2_conn_open_uni_stream(qs->qconn, &ctrl_stream_id, NULL);
if(rc) {
- result = CURLE_FAILED_INIT;
+ result = CURLE_QUIC_CONNECT_ERROR;
goto fail;
}
rc = nghttp3_conn_bind_control_stream(qs->h3conn, ctrl_stream_id);
if(rc) {
- result = CURLE_FAILED_INIT;
+ result = CURLE_QUIC_CONNECT_ERROR;
goto fail;
}
rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_enc_stream_id, NULL);
if(rc) {
- result = CURLE_FAILED_INIT;
+ result = CURLE_QUIC_CONNECT_ERROR;
goto fail;
}
rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_dec_stream_id, NULL);
if(rc) {
- result = CURLE_FAILED_INIT;
+ result = CURLE_QUIC_CONNECT_ERROR;
goto fail;
}
rc = nghttp3_conn_bind_qpack_streams(qs->h3conn, qpack_enc_stream_id,
qpack_dec_stream_id);
if(rc) {
- result = CURLE_FAILED_INIT;
+ result = CURLE_QUIC_CONNECT_ERROR;
goto fail;
}
@@ -1599,9 +1601,11 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
case AF_INET:
pktlen = NGTCP2_MAX_PKTLEN_IPV4;
break;
+#ifdef ENABLE_IPV6
case AF_INET6:
pktlen = NGTCP2_MAX_PKTLEN_IPV6;
break;
+#endif
default:
assert(0);
}
diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c
index e2f43237fa..d09ba7038a 100644
--- a/libs/libcurl/src/vquic/quiche.c
+++ b/libs/libcurl/src/vquic/quiche.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
@@ -171,7 +171,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
return CURLE_FAILED_INIT;
}
- quiche_config_set_idle_timeout(qs->cfg, QUIC_IDLE_TIMEOUT);
+ quiche_config_set_max_idle_timeout(qs->cfg, QUIC_IDLE_TIMEOUT);
quiche_config_set_initial_max_data(qs->cfg, QUIC_MAX_DATA);
quiche_config_set_initial_max_stream_data_bidi_local(qs->cfg, QUIC_MAX_DATA);
quiche_config_set_initial_max_stream_data_bidi_remote(qs->cfg,
diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c
index 62a7f1960c..647b4d4913 100644
--- a/libs/libcurl/src/vssh/libssh.c
+++ b/libs/libcurl/src/vssh/libssh.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2017 - 2019 Red Hat, Inc.
+ * Copyright (C) 2017 - 2020 Red Hat, Inc.
*
* Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek,
* Robert Kolcun, Andreas Schneider
@@ -322,14 +322,25 @@ static int myssh_is_known(struct connectdata *conn)
ssh_key pubkey;
size_t hlen;
unsigned char *hash = NULL;
- char *base64 = NULL;
+ char *found_base64 = NULL;
+ char *known_base64 = NULL;
int vstate;
enum curl_khmatch keymatch;
struct curl_khkey foundkey;
+ struct curl_khkey *knownkeyp = NULL;
curl_sshkeycallback func =
data->set.ssh_keyfunc;
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+ struct ssh_knownhosts_entry *knownhostsentry = NULL;
+ struct curl_khkey knownkey;
+#endif
+
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0)
+ rc = ssh_get_server_publickey(sshc->ssh_session, &pubkey);
+#else
rc = ssh_get_publickey(sshc->ssh_session, &pubkey);
+#endif
if(rc != SSH_OK)
return rc;
@@ -354,6 +365,65 @@ static int myssh_is_known(struct connectdata *conn)
goto cleanup;
}
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+ /* Get the known_key from the known hosts file */
+ vstate = ssh_session_get_known_hosts_entry(sshc->ssh_session,
+ &knownhostsentry);
+
+ /* Case an entry was found in a known hosts file */
+ if(knownhostsentry) {
+ if(knownhostsentry->publickey) {
+ rc = ssh_pki_export_pubkey_base64(knownhostsentry->publickey,
+ &known_base64);
+ if(rc != SSH_OK) {
+ goto cleanup;
+ }
+ knownkey.key = known_base64;
+ knownkey.len = strlen(known_base64);
+
+ switch(ssh_key_type(knownhostsentry->publickey)) {
+ case SSH_KEYTYPE_RSA:
+ knownkey.keytype = CURLKHTYPE_RSA;
+ break;
+ case SSH_KEYTYPE_RSA1:
+ knownkey.keytype = CURLKHTYPE_RSA1;
+ break;
+ case SSH_KEYTYPE_ECDSA:
+ knownkey.keytype = CURLKHTYPE_ECDSA;
+ break;
+ case SSH_KEYTYPE_ED25519:
+ knownkey.keytype = CURLKHTYPE_ED25519;
+ break;
+ case SSH_KEYTYPE_DSS:
+ knownkey.keytype = CURLKHTYPE_DSS;
+ break;
+ default:
+ rc = SSH_ERROR;
+ goto cleanup;
+ }
+ knownkeyp = &knownkey;
+ }
+ }
+
+ switch(vstate) {
+ case SSH_KNOWN_HOSTS_OK:
+ keymatch = CURLKHMATCH_OK;
+ break;
+ case SSH_KNOWN_HOSTS_OTHER:
+ /* fallthrough */
+ case SSH_KNOWN_HOSTS_NOT_FOUND:
+ /* fallthrough */
+ case SSH_KNOWN_HOSTS_UNKNOWN:
+ /* fallthrough */
+ case SSH_KNOWN_HOSTS_ERROR:
+ keymatch = CURLKHMATCH_MISSING;
+ break;
+ default:
+ keymatch = CURLKHMATCH_MISMATCH;
+ break;
+ }
+
+#else
vstate = ssh_is_server_known(sshc->ssh_session);
switch(vstate) {
case SSH_SERVER_KNOWN_OK:
@@ -368,14 +438,15 @@ static int myssh_is_known(struct connectdata *conn)
keymatch = CURLKHMATCH_MISMATCH;
break;
}
+#endif
if(func) { /* use callback to determine action */
- rc = ssh_pki_export_pubkey_base64(pubkey, &base64);
+ rc = ssh_pki_export_pubkey_base64(pubkey, &found_base64);
if(rc != SSH_OK)
goto cleanup;
- foundkey.key = base64;
- foundkey.len = strlen(base64);
+ foundkey.key = found_base64;
+ foundkey.len = strlen(found_base64);
switch(ssh_key_type(pubkey)) {
case SSH_KEYTYPE_RSA:
@@ -400,15 +471,19 @@ static int myssh_is_known(struct connectdata *conn)
goto cleanup;
}
- /* we don't have anything equivalent to knownkey. Always NULL */
Curl_set_in_callback(data, true);
- rc = func(data, NULL, &foundkey, /* from the remote host */
+ rc = func(data, knownkeyp, /* from the knownhosts file */
+ &foundkey, /* from the remote host */
keymatch, data->set.ssh_keyfunc_userp);
Curl_set_in_callback(data, false);
switch(rc) {
case CURLKHSTAT_FINE_ADD_TO_FILE:
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0)
+ rc = ssh_session_update_known_hosts(sshc->ssh_session);
+#else
rc = ssh_write_knownhost(sshc->ssh_session);
+#endif
if(rc != SSH_OK) {
goto cleanup;
}
@@ -429,9 +504,20 @@ static int myssh_is_known(struct connectdata *conn)
rc = SSH_OK;
cleanup:
+ if(found_base64) {
+ free(found_base64);
+ }
+ if(known_base64) {
+ free(known_base64);
+ }
if(hash)
ssh_clean_pubkey_hash(&hash);
ssh_key_free(pubkey);
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+ if(knownhostsentry) {
+ ssh_knownhosts_entry_free(knownhostsentry);
+ }
+#endif
return rc;
}
@@ -1586,7 +1672,6 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
return CURLE_BAD_DOWNLOAD_RESUME;
}
}
- /* Does a completed file need to be seeked and started or closed ? */
/* Now store the number of bytes we are expected to download */
data->req.size = size - data->state.resume_from;
data->req.maxdownload = size - data->state.resume_from;
diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c
index 063f3d2ae6..8e043747e7 100644
--- a/libs/libcurl/src/vssh/libssh2.c
+++ b/libs/libcurl/src/vssh/libssh2.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
@@ -106,6 +106,7 @@ static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
static LIBSSH2_FREE_FUNC(my_libssh2_free);
+static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn);
static CURLcode ssh_connect(struct connectdata *conn, bool *done);
static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
static CURLcode ssh_do(struct connectdata *conn, bool *done);
@@ -649,6 +650,129 @@ static CURLcode ssh_check_fingerprint(struct connectdata *conn)
}
/*
+ * ssh_force_knownhost_key_type() will check the known hosts file and try to
+ * force a specific public key type from the server if an entry is found.
+ */
+static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+
+#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
+ static const char * const hostkey_method_ssh_ed25519
+ = "ssh-ed25519";
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
+ static const char * const hostkey_method_ssh_ecdsa_521
+ = "ecdsa-sha2-nistp521";
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
+ static const char * const hostkey_method_ssh_ecdsa_384
+ = "ecdsa-sha2-nistp384";
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
+ static const char * const hostkey_method_ssh_ecdsa_256
+ = "ecdsa-sha2-nistp256";
+#endif
+ static const char * const hostkey_method_ssh_rsa
+ = "ssh-rsa";
+ static const char * const hostkey_method_ssh_dss
+ = "ssh-dss";
+
+ const char *hostkey_method = NULL;
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ struct Curl_easy *data = conn->data;
+ struct libssh2_knownhost* store = NULL;
+ const char *kh_name_end = NULL;
+ size_t kh_name_size = 0;
+ int port = 0;
+ bool found = false;
+
+ if(sshc->kh && !data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
+ /* lets try to find our host in the known hosts file */
+ while(!libssh2_knownhost_get(sshc->kh, &store, store)) {
+ /* For non-standard ports, the name will be enclosed in */
+ /* square brackets, followed by a colon and the port */
+ if(store->name[0] == '[') {
+ kh_name_end = strstr(store->name, "]:");
+ if(!kh_name_end) {
+ infof(data, "Invalid host pattern %s in %s\n",
+ store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+ continue;
+ }
+ port = atoi(kh_name_end + 2);
+ if(kh_name_end && (port == conn->remote_port)) {
+ kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end);
+ if(strncmp(store->name + 1, conn->host.name, kh_name_size) == 0) {
+ found = true;
+ break;
+ }
+ }
+ }
+ else if(strcmp(store->name, conn->host.name) == 0) {
+ found = true;
+ break;
+ }
+ }
+
+ if(found) {
+ infof(data, "Found host %s in %s\n",
+ store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+
+ switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
+#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
+ case LIBSSH2_KNOWNHOST_KEY_ED25519:
+ hostkey_method = hostkey_method_ssh_ed25519;
+ break;
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
+ hostkey_method = hostkey_method_ssh_ecdsa_521;
+ break;
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
+ hostkey_method = hostkey_method_ssh_ecdsa_384;
+ break;
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
+ hostkey_method = hostkey_method_ssh_ecdsa_256;
+ break;
+#endif
+ case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
+ hostkey_method = hostkey_method_ssh_rsa;
+ break;
+ case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
+ hostkey_method = hostkey_method_ssh_dss;
+ break;
+ case LIBSSH2_KNOWNHOST_KEY_RSA1:
+ failf(data, "Found host key type RSA1 which is not supported\n");
+ return CURLE_SSH;
+ default:
+ failf(data, "Unknown host key type: %i\n",
+ (store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK));
+ return CURLE_SSH;
+ }
+
+ infof(data, "Set \"%s\" as SSH hostkey type\n", hostkey_method);
+ result = libssh2_session_error_to_CURLE(
+ libssh2_session_method_pref(
+ sshc->ssh_session, LIBSSH2_METHOD_HOSTKEY, hostkey_method));
+ }
+ else {
+ infof(data, "Did not find host %s in %s\n",
+ conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+ }
+ }
+
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+ return result;
+}
+
+/*
* ssh_statemach_act() runs the SSH state machine as far as it can without
* blocking and without reaching the end. The data the pointer 'block' points
* to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
@@ -680,6 +804,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
non-blocking */
libssh2_session_set_blocking(sshc->ssh_session, 0);
+ result = ssh_force_knownhost_key_type(conn);
+ if(result) {
+ state(conn, SSH_SESSION_FREE);
+ break;
+ }
+
state(conn, SSH_S_STARTUP);
/* FALLTHROUGH */
@@ -2251,7 +2381,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
return CURLE_BAD_DOWNLOAD_RESUME;
}
}
- /* Does a completed file need to be seeked and started or closed ? */
/* Now store the number of bytes we are expected to download */
data->req.size = attrs.filesize - data->state.resume_from;
data->req.maxdownload = attrs.filesize - data->state.resume_from;
diff --git a/libs/libcurl/src/vssh/ssh.h b/libs/libcurl/src/vssh/ssh.h
index 3213c5a52e..0d4ee521d1 100644
--- a/libs/libcurl/src/vssh/ssh.h
+++ b/libs/libcurl/src/vssh/ssh.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
@@ -30,7 +30,10 @@
#elif defined(HAVE_LIBSSH_LIBSSH_H)
#include <libssh/libssh.h>
#include <libssh/sftp.h>
-#endif /* HAVE_LIBSSH2_H */
+#elif defined(USE_WOLFSSH)
+#include <wolfssh/ssh.h>
+#include <wolfssh/wolfsftp.h>
+#endif
/****************************************************************************
* SSH unique setup
@@ -188,6 +191,12 @@ struct ssh_conn {
#ifdef HAVE_LIBSSH2_KNOWNHOST_API
LIBSSH2_KNOWNHOSTS *kh;
#endif
+#elif defined(USE_WOLFSSH)
+ WOLFSSH *ssh_session;
+ WOLFSSH_CTX *ctx;
+ word32 handleSz;
+ byte handle[WOLFSSH_MAX_HANDLE];
+ curl_off_t offset;
#endif /* USE_LIBSSH */
};
@@ -195,9 +204,6 @@ struct ssh_conn {
#define CURL_LIBSSH_VERSION ssh_version(0)
-extern const struct Curl_handler Curl_handler_scp;
-extern const struct Curl_handler Curl_handler_sftp;
-
#elif defined(USE_LIBSSH2)
/* Feature detection based on version numbers to better work with
@@ -237,11 +243,13 @@ extern const struct Curl_handler Curl_handler_sftp;
#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
#endif
-extern const struct Curl_handler Curl_handler_scp;
-extern const struct Curl_handler Curl_handler_sftp;
#endif /* USE_LIBSSH2 */
#ifdef USE_SSH
+
+extern const struct Curl_handler Curl_handler_scp;
+extern const struct Curl_handler Curl_handler_sftp;
+
/* generic SSH backend functions */
CURLcode Curl_ssh_init(void);
void Curl_ssh_cleanup(void);
diff --git a/libs/libcurl/src/vssh/wolfssh.c b/libs/libcurl/src/vssh/wolfssh.c
new file mode 100644
index 0000000000..363a52c772
--- /dev/null
+++ b/libs/libcurl/src/vssh/wolfssh.c
@@ -0,0 +1,1156 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * 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
+ * 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"
+
+#ifdef USE_WOLFSSH
+
+#include <limits.h>
+
+#include <wolfssh/ssh.h>
+#include <wolfssh/wolfsftp.h>
+#include "urldata.h"
+#include "connect.h"
+#include "sendf.h"
+#include "progress.h"
+#include "curl_path.h"
+#include "strtoofft.h"
+#include "transfer.h"
+#include "speedcheck.h"
+#include "select.h"
+#include "multiif.h"
+#include "warnless.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static CURLcode wssh_connect(struct connectdata *conn, bool *done);
+static CURLcode wssh_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode wssh_do(struct connectdata *conn, bool *done);
+#if 0
+static CURLcode wscp_done(struct connectdata *conn,
+ CURLcode, bool premature);
+static CURLcode wscp_doing(struct connectdata *conn,
+ bool *dophase_done);
+static CURLcode wscp_disconnect(struct connectdata *conn,
+ bool dead_connection);
+#endif
+static CURLcode wsftp_done(struct connectdata *conn,
+ CURLcode, bool premature);
+static CURLcode wsftp_doing(struct connectdata *conn,
+ bool *dophase_done);
+static CURLcode wsftp_disconnect(struct connectdata *conn, bool dead);
+static int wssh_getsock(struct connectdata *conn,
+ curl_socket_t *sock);
+static int wssh_perform_getsock(const struct connectdata *conn,
+ curl_socket_t *sock);
+static CURLcode wssh_setup_connection(struct connectdata *conn);
+
+#if 0
+/*
+ * SCP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_scp = {
+ "SCP", /* scheme */
+ wssh_setup_connection, /* setup_connection */
+ wssh_do, /* do_it */
+ wscp_done, /* done */
+ ZERO_NULL, /* do_more */
+ wssh_connect, /* connect_it */
+ wssh_multi_statemach, /* connecting */
+ wscp_doing, /* doing */
+ wssh_getsock, /* proto_getsock */
+ wssh_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ wssh_perform_getsock, /* perform_getsock */
+ wscp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ ZERO_NULL, /* connection_check */
+ PORT_SSH, /* defport */
+ CURLPROTO_SCP, /* protocol */
+ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+ | PROTOPT_NOURLQUERY /* flags */
+};
+
+#endif
+
+/*
+ * SFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_sftp = {
+ "SFTP", /* scheme */
+ wssh_setup_connection, /* setup_connection */
+ wssh_do, /* do_it */
+ wsftp_done, /* done */
+ ZERO_NULL, /* do_more */
+ wssh_connect, /* connect_it */
+ wssh_multi_statemach, /* connecting */
+ wsftp_doing, /* doing */
+ wssh_getsock, /* proto_getsock */
+ wssh_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ wssh_perform_getsock, /* perform_getsock */
+ wsftp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ ZERO_NULL, /* connection_check */
+ PORT_SSH, /* defport */
+ CURLPROTO_SFTP, /* protocol */
+ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+ | PROTOPT_NOURLQUERY /* flags */
+};
+
+/*
+ * SSH State machine related code
+ */
+/* This is the ONLY way to change SSH state! */
+static void state(struct connectdata *conn, sshstate nowstate)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* for debug purposes */
+ static const char * const names[] = {
+ "SSH_STOP",
+ "SSH_INIT",
+ "SSH_S_STARTUP",
+ "SSH_HOSTKEY",
+ "SSH_AUTHLIST",
+ "SSH_AUTH_PKEY_INIT",
+ "SSH_AUTH_PKEY",
+ "SSH_AUTH_PASS_INIT",
+ "SSH_AUTH_PASS",
+ "SSH_AUTH_AGENT_INIT",
+ "SSH_AUTH_AGENT_LIST",
+ "SSH_AUTH_AGENT",
+ "SSH_AUTH_HOST_INIT",
+ "SSH_AUTH_HOST",
+ "SSH_AUTH_KEY_INIT",
+ "SSH_AUTH_KEY",
+ "SSH_AUTH_GSSAPI",
+ "SSH_AUTH_DONE",
+ "SSH_SFTP_INIT",
+ "SSH_SFTP_REALPATH",
+ "SSH_SFTP_QUOTE_INIT",
+ "SSH_SFTP_POSTQUOTE_INIT",
+ "SSH_SFTP_QUOTE",
+ "SSH_SFTP_NEXT_QUOTE",
+ "SSH_SFTP_QUOTE_STAT",
+ "SSH_SFTP_QUOTE_SETSTAT",
+ "SSH_SFTP_QUOTE_SYMLINK",
+ "SSH_SFTP_QUOTE_MKDIR",
+ "SSH_SFTP_QUOTE_RENAME",
+ "SSH_SFTP_QUOTE_RMDIR",
+ "SSH_SFTP_QUOTE_UNLINK",
+ "SSH_SFTP_QUOTE_STATVFS",
+ "SSH_SFTP_GETINFO",
+ "SSH_SFTP_FILETIME",
+ "SSH_SFTP_TRANS_INIT",
+ "SSH_SFTP_UPLOAD_INIT",
+ "SSH_SFTP_CREATE_DIRS_INIT",
+ "SSH_SFTP_CREATE_DIRS",
+ "SSH_SFTP_CREATE_DIRS_MKDIR",
+ "SSH_SFTP_READDIR_INIT",
+ "SSH_SFTP_READDIR",
+ "SSH_SFTP_READDIR_LINK",
+ "SSH_SFTP_READDIR_BOTTOM",
+ "SSH_SFTP_READDIR_DONE",
+ "SSH_SFTP_DOWNLOAD_INIT",
+ "SSH_SFTP_DOWNLOAD_STAT",
+ "SSH_SFTP_CLOSE",
+ "SSH_SFTP_SHUTDOWN",
+ "SSH_SCP_TRANS_INIT",
+ "SSH_SCP_UPLOAD_INIT",
+ "SSH_SCP_DOWNLOAD_INIT",
+ "SSH_SCP_DOWNLOAD",
+ "SSH_SCP_DONE",
+ "SSH_SCP_SEND_EOF",
+ "SSH_SCP_WAIT_EOF",
+ "SSH_SCP_WAIT_CLOSE",
+ "SSH_SCP_CHANNEL_FREE",
+ "SSH_SESSION_DISCONNECT",
+ "SSH_SESSION_FREE",
+ "QUIT"
+ };
+
+ /* a precaution to make sure the lists are in sync */
+ DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST);
+
+ if(sshc->state != nowstate) {
+ infof(conn->data, "wolfssh %p state change from %s to %s\n",
+ (void *)sshc, names[sshc->state], names[nowstate]);
+ }
+#endif
+
+ sshc->state = nowstate;
+}
+
+static ssize_t wscp_send(struct connectdata *conn, int sockindex,
+ const void *mem, size_t len, CURLcode *err)
+{
+ ssize_t nwrite = 0;
+ (void)conn;
+ (void)sockindex; /* we only support SCP on the fixed known primary socket */
+ (void)mem;
+ (void)len;
+ (void)err;
+
+ return nwrite;
+}
+
+static ssize_t wscp_recv(struct connectdata *conn, int sockindex,
+ char *mem, size_t len, CURLcode *err)
+{
+ ssize_t nread = 0;
+ (void)conn;
+ (void)sockindex; /* we only support SCP on the fixed known primary socket */
+ (void)mem;
+ (void)len;
+ (void)err;
+
+ return nread;
+}
+
+/* return number of sent bytes */
+static ssize_t wsftp_send(struct connectdata *conn, int sockindex,
+ const void *mem, size_t len, CURLcode *err)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ word32 offset[2];
+ int rc;
+ (void)sockindex;
+
+ offset[0] = (word32)sshc->offset&0xFFFFFFFF;
+ offset[1] = (word32)(sshc->offset>>32)&0xFFFFFFFF;
+
+ rc = wolfSSH_SFTP_SendWritePacket(sshc->ssh_session, sshc->handle,
+ sshc->handleSz,
+ &offset[0],
+ (byte *)mem, (word32)len);
+
+ if(rc == WS_FATAL_ERROR)
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ if(rc == WS_WANT_READ) {
+ conn->waitfor = KEEP_RECV;
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ conn->waitfor = KEEP_SEND;
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ if(rc < 0) {
+ failf(conn->data, "wolfSSH_SFTP_SendWritePacket returned %d\n", rc);
+ return -1;
+ }
+ DEBUGASSERT(rc == (int)len);
+ infof(conn->data, "sent %zd bytes SFTP from offset %zd\n",
+ len, sshc->offset);
+ sshc->offset += len;
+ return (ssize_t)rc;
+}
+
+/*
+ * Return number of received (decrypted) bytes
+ * or <0 on error
+ */
+static ssize_t wsftp_recv(struct connectdata *conn, int sockindex,
+ char *mem, size_t len, CURLcode *err)
+{
+ int rc;
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ word32 offset[2];
+ (void)sockindex;
+
+ offset[0] = (word32)sshc->offset&0xFFFFFFFF;
+ offset[1] = (word32)(sshc->offset>>32)&0xFFFFFFFF;
+
+ rc = wolfSSH_SFTP_SendReadPacket(sshc->ssh_session, sshc->handle,
+ sshc->handleSz,
+ &offset[0],
+ (byte *)mem, (word32)len);
+ if(rc == WS_FATAL_ERROR)
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ if(rc == WS_WANT_READ) {
+ conn->waitfor = KEEP_RECV;
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ conn->waitfor = KEEP_SEND;
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+
+ DEBUGASSERT(rc <= (int)len);
+
+ if(rc < 0) {
+ failf(conn->data, "wolfSSH_SFTP_SendReadPacket returned %d\n", rc);
+ return -1;
+ }
+ sshc->offset += len;
+
+ return (ssize_t)rc;
+}
+
+/*
+ * SSH setup and connection
+ */
+static CURLcode wssh_setup_connection(struct connectdata *conn)
+{
+ struct SSHPROTO *ssh;
+
+ conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+ if(!ssh)
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
+}
+
+static Curl_recv wscp_recv, wsftp_recv;
+static Curl_send wscp_send, wsftp_send;
+
+static int userauth(byte authtype,
+ WS_UserAuthData* authdata,
+ void *ctx)
+{
+ struct connectdata *conn = ctx;
+ DEBUGF(infof(conn->data, "wolfssh callback: type %s\n",
+ authtype == WOLFSSH_USERAUTH_PASSWORD ? "PASSWORD" :
+ "PUBLICCKEY"));
+ if(authtype == WOLFSSH_USERAUTH_PASSWORD) {
+ authdata->sf.password.password = (byte *)conn->passwd;
+ authdata->sf.password.passwordSz = (word32) strlen(conn->passwd);
+ }
+
+ return 0;
+}
+
+static CURLcode wssh_connect(struct connectdata *conn, bool *done)
+{
+ struct Curl_easy *data = conn->data;
+ struct ssh_conn *sshc;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ int rc;
+
+ /* initialize per-handle data if not already */
+ if(!data->req.protop)
+ wssh_setup_connection(conn);
+
+ /* We default to persistent connections. We set this already in this connect
+ 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] = wscp_recv;
+ conn->send[FIRSTSOCKET] = wscp_send;
+ }
+ else {
+ conn->recv[FIRSTSOCKET] = wsftp_recv;
+ conn->send[FIRSTSOCKET] = wsftp_send;
+ }
+ sshc = &conn->proto.sshc;
+ sshc->ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
+ if(!sshc->ctx) {
+ failf(data, "No wolfSSH context");
+ goto error;
+ }
+
+ sshc->ssh_session = wolfSSH_new(sshc->ctx);
+ if(sshc->ssh_session == NULL) {
+ failf(data, "No wolfSSH session");
+ goto error;
+ }
+
+ rc = wolfSSH_SetUsername(sshc->ssh_session, conn->user);
+ if(rc != WS_SUCCESS) {
+ failf(data, "wolfSSH failed to set user name");
+ goto error;
+ }
+
+ /* set callback for authentication */
+ wolfSSH_SetUserAuth(sshc->ctx, userauth);
+ wolfSSH_SetUserAuthCtx(sshc->ssh_session, conn);
+
+ rc = wolfSSH_set_fd(sshc->ssh_session, (int)sock);
+ if(rc) {
+ failf(data, "wolfSSH failed to set socket");
+ goto error;
+ }
+
+#if 0
+ wolfSSH_Debugging_ON();
+#endif
+
+ *done = TRUE;
+ if(conn->handler->protocol & CURLPROTO_SCP)
+ state(conn, SSH_INIT);
+ else
+ state(conn, SSH_SFTP_INIT);
+
+ return wssh_multi_statemach(conn, done);
+ error:
+ wolfSSH_free(sshc->ssh_session);
+ wolfSSH_CTX_free(sshc->ctx);
+ return CURLE_FAILED_INIT;
+}
+
+/*
+ * wssh_statemach_act() runs the SSH state machine as far as it can without
+ * blocking and without reaching the end. The data the pointer 'block' points
+ * to will be set to TRUE if the wolfssh function returns EAGAIN meaning it
+ * wants to be called again when the socket is ready
+ */
+
+static CURLcode wssh_statemach_act(struct connectdata *conn, bool *block)
+{
+ CURLcode result = CURLE_OK;
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ struct Curl_easy *data = conn->data;
+ struct SSHPROTO *sftp_scp = data->req.protop;
+ WS_SFTPNAME *name;
+ int rc = 0;
+ *block = FALSE; /* we're not blocking by default */
+
+ do {
+ switch(sshc->state) {
+ case SSH_INIT:
+ state(conn, SSH_S_STARTUP);
+ /* FALLTHROUGH */
+ case SSH_S_STARTUP:
+ rc = wolfSSH_connect(sshc->ssh_session);
+ if(rc != WS_SUCCESS)
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ if(rc == WS_WANT_READ) {
+ *block = TRUE;
+ conn->waitfor = KEEP_RECV;
+ return CURLE_OK;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ *block = TRUE;
+ conn->waitfor = KEEP_SEND;
+ return CURLE_OK;
+ }
+ else if(rc != WS_SUCCESS) {
+ state(conn, SSH_STOP);
+ return CURLE_SSH;
+ }
+ infof(data, "wolfssh connected!\n");
+ state(conn, SSH_STOP);
+ break;
+ case SSH_STOP:
+ break;
+
+ case SSH_SFTP_INIT:
+ rc = wolfSSH_SFTP_connect(sshc->ssh_session);
+ if(rc != WS_SUCCESS)
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ if(rc == WS_WANT_READ) {
+ *block = TRUE;
+ conn->waitfor = KEEP_RECV;
+ return CURLE_OK;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ *block = TRUE;
+ conn->waitfor = KEEP_SEND;
+ return CURLE_OK;
+ }
+ else if(rc == WS_SUCCESS) {
+ infof(data, "wolfssh SFTP connected!\n");
+ state(conn, SSH_SFTP_REALPATH);
+ }
+ else {
+ failf(data, "wolfssh SFTP connect error %d", rc);
+ return CURLE_SSH;
+ }
+ break;
+ case SSH_SFTP_REALPATH:
+ name = wolfSSH_SFTP_RealPath(sshc->ssh_session, (char *)".");
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ if(rc == WS_WANT_READ) {
+ *block = TRUE;
+ conn->waitfor = KEEP_RECV;
+ return CURLE_OK;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ *block = TRUE;
+ conn->waitfor = KEEP_SEND;
+ return CURLE_OK;
+ }
+ else if(name && (rc == WS_SUCCESS)) {
+ sshc->homedir = malloc(name->fSz + 1);
+ if(!sshc->homedir) {
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ }
+ else {
+ memcpy(sshc->homedir, name->fName, name->fSz);
+ sshc->homedir[name->fSz] = 0;
+ infof(data, "wolfssh SFTP realpath succeeded!\n");
+ }
+ wolfSSH_SFTPNAME_list_free(name);
+ state(conn, SSH_STOP);
+ return CURLE_OK;
+ }
+ failf(data, "wolfssh SFTP realpath %d", rc);
+ return CURLE_SSH;
+
+ case SSH_SFTP_QUOTE_INIT:
+ result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+ if(result) {
+ sshc->actualcode = result;
+ state(conn, SSH_STOP);
+ break;
+ }
+
+ if(data->set.quote) {
+ infof(data, "Sending quote commands\n");
+ sshc->quote_item = data->set.quote;
+ state(conn, SSH_SFTP_QUOTE);
+ }
+ else {
+ state(conn, SSH_SFTP_GETINFO);
+ }
+ break;
+ case SSH_SFTP_GETINFO:
+ if(data->set.get_filetime) {
+ state(conn, SSH_SFTP_FILETIME);
+ }
+ else {
+ state(conn, SSH_SFTP_TRANS_INIT);
+ }
+ break;
+ case SSH_SFTP_TRANS_INIT:
+ if(data->set.upload)
+ state(conn, SSH_SFTP_UPLOAD_INIT);
+ else {
+ if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
+ state(conn, SSH_SFTP_READDIR_INIT);
+ else
+ state(conn, SSH_SFTP_DOWNLOAD_INIT);
+ }
+ break;
+ case SSH_SFTP_UPLOAD_INIT: {
+ word32 flags;
+ WS_SFTP_FILEATRB createattrs;
+ if(data->state.resume_from) {
+ WS_SFTP_FILEATRB attrs;
+ if(data->state.resume_from < 0) {
+ rc = wolfSSH_SFTP_STAT(sshc->ssh_session, sftp_scp->path,
+ &attrs);
+ if(rc != WS_SUCCESS)
+ break;
+
+ if(rc) {
+ data->state.resume_from = 0;
+ }
+ else {
+ curl_off_t size = ((curl_off_t)attrs.sz[1] << 32) | attrs.sz[0];
+ if(size < 0) {
+ failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ data->state.resume_from = size;
+ }
+ }
+ }
+
+ if(data->set.ftp_append)
+ /* Try to open for append, but create if nonexisting */
+ flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_APPEND;
+ else if(data->state.resume_from > 0)
+ /* If we have restart position then open for append */
+ flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_APPEND;
+ else
+ /* Clear file before writing (normal behaviour) */
+ flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_TRUNC;
+
+ memset(&createattrs, 0, sizeof(createattrs));
+ createattrs.per = (word32)data->set.new_file_perms;
+ sshc->handleSz = sizeof(sshc->handle);
+ rc = wolfSSH_SFTP_Open(sshc->ssh_session, sftp_scp->path,
+ flags, &createattrs,
+ sshc->handle, &sshc->handleSz);
+ if(rc == WS_FATAL_ERROR)
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ if(rc == WS_WANT_READ) {
+ *block = TRUE;
+ conn->waitfor = KEEP_RECV;
+ return CURLE_OK;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ *block = TRUE;
+ conn->waitfor = KEEP_SEND;
+ return CURLE_OK;
+ }
+ else if(rc == WS_SUCCESS) {
+ infof(data, "wolfssh SFTP open succeeded!\n");
+ }
+ else {
+ failf(data, "wolfssh SFTP upload open failed: %d", rc);
+ return CURLE_SSH;
+ }
+ state(conn, SSH_SFTP_DOWNLOAD_STAT);
+
+ /* If we have a restart point then we need to seek to the correct
+ position. */
+ if(data->state.resume_from > 0) {
+ /* Let's read off the proper amount of bytes from the input. */
+ int seekerr = CURL_SEEKFUNC_OK;
+ if(conn->seek_func) {
+ Curl_set_in_callback(data, true);
+ seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+ SEEK_SET);
+ Curl_set_in_callback(data, false);
+ }
+
+ if(seekerr != CURL_SEEKFUNC_OK) {
+ curl_off_t passed = 0;
+
+ if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+ failf(data, "Could not seek stream");
+ return CURLE_FTP_COULDNT_USE_REST;
+ }
+ /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+ do {
+ size_t readthisamountnow =
+ (data->state.resume_from - passed > data->set.buffer_size) ?
+ (size_t)data->set.buffer_size :
+ curlx_sotouz(data->state.resume_from - passed);
+
+ size_t actuallyread;
+ Curl_set_in_callback(data, true);
+ actuallyread = data->state.fread_func(data->state.buffer, 1,
+ readthisamountnow,
+ data->state.in);
+ Curl_set_in_callback(data, false);
+
+ passed += actuallyread;
+ if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+ /* this checks for greater-than only to make sure that the
+ CURL_READFUNC_ABORT return code still aborts */
+ failf(data, "Failed to read data");
+ return CURLE_FTP_COULDNT_USE_REST;
+ }
+ } while(passed < data->state.resume_from);
+ }
+
+ /* now, decrease the size of the read */
+ if(data->state.infilesize > 0) {
+ data->state.infilesize -= data->state.resume_from;
+ data->req.size = data->state.infilesize;
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+ }
+
+ sshc->offset += data->state.resume_from;
+ }
+ if(data->state.infilesize > 0) {
+ data->req.size = data->state.infilesize;
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+ }
+ /* upload data */
+ Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
+
+ /* not set by Curl_setup_transfer to preserve keepon bits */
+ conn->sockfd = conn->writesockfd;
+
+ if(result) {
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = result;
+ }
+ else {
+ /* store this original bitmask setup to use later on if we can't
+ figure out a "real" bitmask */
+ sshc->orig_waitfor = data->req.keepon;
+
+ /* we want to use the _sending_ function even when the socket turns
+ out readable as the underlying libssh2 sftp send function will deal
+ with both accordingly */
+ conn->cselect_bits = CURL_CSELECT_OUT;
+
+ /* since we don't really wait for anything at this point, we want the
+ state machine to move on as soon as possible so we set a very short
+ timeout here */
+ Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+ state(conn, SSH_STOP);
+ }
+ break;
+ }
+ case SSH_SFTP_DOWNLOAD_INIT:
+ sshc->handleSz = sizeof(sshc->handle);
+ rc = wolfSSH_SFTP_Open(sshc->ssh_session, sftp_scp->path,
+ WOLFSSH_FXF_READ, NULL,
+ sshc->handle, &sshc->handleSz);
+ if(rc == WS_FATAL_ERROR)
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ if(rc == WS_WANT_READ) {
+ *block = TRUE;
+ conn->waitfor = KEEP_RECV;
+ return CURLE_OK;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ *block = TRUE;
+ conn->waitfor = KEEP_SEND;
+ return CURLE_OK;
+ }
+ else if(rc == WS_SUCCESS) {
+ infof(data, "wolfssh SFTP open succeeded!\n");
+ state(conn, SSH_SFTP_DOWNLOAD_STAT);
+ return CURLE_OK;
+ }
+
+ failf(data, "wolfssh SFTP open failed: %d", rc);
+ return CURLE_SSH;
+
+ case SSH_SFTP_DOWNLOAD_STAT: {
+ WS_SFTP_FILEATRB attrs;
+ curl_off_t size;
+
+ rc = wolfSSH_SFTP_STAT(sshc->ssh_session, sftp_scp->path, &attrs);
+ if(rc == WS_FATAL_ERROR)
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ if(rc == WS_WANT_READ) {
+ *block = TRUE;
+ conn->waitfor = KEEP_RECV;
+ return CURLE_OK;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ *block = TRUE;
+ conn->waitfor = KEEP_SEND;
+ return CURLE_OK;
+ }
+ else if(rc == WS_SUCCESS) {
+ infof(data, "wolfssh STAT succeeded!\n");
+ }
+ else {
+ failf(data, "wolfssh SFTP open failed: %d", rc);
+ data->req.size = -1;
+ data->req.maxdownload = -1;
+ Curl_pgrsSetDownloadSize(data, -1);
+ return CURLE_SSH;
+ }
+
+ size = ((curl_off_t)attrs.sz[1] <<32) | attrs.sz[0];
+
+ data->req.size = size;
+ data->req.maxdownload = size;
+ Curl_pgrsSetDownloadSize(data, size);
+
+ infof(data, "SFTP download %" CURL_FORMAT_CURL_OFF_T " bytes\n", size);
+
+ /* We cannot seek with wolfSSH so resuming and range requests are not
+ possible */
+ if(conn->data->state.use_range || data->state.resume_from) {
+ infof(data, "wolfSSH cannot do range/seek on SFTP\n");
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+
+ /* Setup the actual download */
+ if(data->req.size == 0) {
+ /* no data to transfer */
+ Curl_setup_transfer(data, -1, -1, FALSE, -1);
+ infof(data, "File already completely downloaded\n");
+ state(conn, SSH_STOP);
+ break;
+ }
+ Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
+
+ /* not set by Curl_setup_transfer to preserve keepon bits */
+ conn->writesockfd = conn->sockfd;
+
+ /* we want to use the _receiving_ function even when the socket turns
+ out writableable as the underlying libssh2 recv function will deal
+ with both accordingly */
+ conn->cselect_bits = CURL_CSELECT_IN;
+
+ if(result) {
+ /* this should never occur; the close state should be entered
+ at the time the error occurs */
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = result;
+ }
+ else {
+ state(conn, SSH_STOP);
+ }
+ break;
+ }
+ case SSH_SFTP_CLOSE:
+ if(sshc->handleSz)
+ rc = wolfSSH_SFTP_Close(sshc->ssh_session, sshc->handle,
+ sshc->handleSz);
+ else
+ rc = WS_SUCCESS; /* directory listing */
+ if(rc == WS_WANT_READ) {
+ *block = TRUE;
+ conn->waitfor = KEEP_RECV;
+ return CURLE_OK;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ *block = TRUE;
+ conn->waitfor = KEEP_SEND;
+ return CURLE_OK;
+ }
+ else if(rc == WS_SUCCESS) {
+ state(conn, SSH_STOP);
+ return CURLE_OK;
+ }
+
+ failf(data, "wolfssh SFTP CLOSE failed: %d", rc);
+ return CURLE_SSH;
+
+ case SSH_SFTP_READDIR_INIT:
+ Curl_pgrsSetDownloadSize(data, -1);
+ if(data->set.opt_no_body) {
+ state(conn, SSH_STOP);
+ break;
+ }
+ state(conn, SSH_SFTP_READDIR);
+ /* FALLTHROUGH */
+ case SSH_SFTP_READDIR:
+ name = wolfSSH_SFTP_LS(sshc->ssh_session, sftp_scp->path);
+ if(!name)
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ else
+ rc = WS_SUCCESS;
+
+ if(rc == WS_WANT_READ) {
+ *block = TRUE;
+ conn->waitfor = KEEP_RECV;
+ return CURLE_OK;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ *block = TRUE;
+ conn->waitfor = KEEP_SEND;
+ return CURLE_OK;
+ }
+ else if(name && (rc == WS_SUCCESS)) {
+ WS_SFTPNAME *origname = name;
+ result = CURLE_OK;
+ while(name) {
+ char *line = aprintf("%s\n",
+ data->set.ftp_list_only ?
+ name->fName : name->lName);
+ if(line == NULL) {
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ line, strlen(line));
+ free(line);
+ if(result) {
+ sshc->actualcode = result;
+ break;
+ }
+ name = name->next;
+ }
+ wolfSSH_SFTPNAME_list_free(origname);
+ state(conn, SSH_STOP);
+ return result;
+ }
+ failf(data, "wolfssh SFTP ls failed: %d", rc);
+ return CURLE_SSH;
+
+ case SSH_SFTP_SHUTDOWN:
+ Curl_safefree(sshc->homedir);
+ wolfSSH_free(sshc->ssh_session);
+ wolfSSH_CTX_free(sshc->ctx);
+ state(conn, SSH_STOP);
+ return CURLE_OK;
+ default:
+ break;
+ }
+ } while(!rc && (sshc->state != SSH_STOP));
+ return result;
+}
+
+/* called repeatedly until done from multi.c */
+static CURLcode wssh_multi_statemach(struct connectdata *conn, bool *done)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ CURLcode result = CURLE_OK;
+ bool block; /* we store the status and use that to provide a ssh_getsock()
+ implementation */
+ do {
+ result = wssh_statemach_act(conn, &block);
+ *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+ /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
+ try again */
+ if(*done) {
+ DEBUGF(infof(conn->data, "wssh_statemach_act says DONE\n"));
+ }
+ } while(!result && !*done && !block);
+
+ return result;
+}
+
+static
+CURLcode wscp_perform(struct connectdata *conn,
+ bool *connected,
+ bool *dophase_done)
+{
+ (void)conn;
+ (void)connected;
+ (void)dophase_done;
+ return CURLE_OK;
+}
+
+static
+CURLcode wsftp_perform(struct connectdata *conn,
+ bool *connected,
+ bool *dophase_done)
+{
+ CURLcode result = CURLE_OK;
+
+ DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+ *dophase_done = FALSE; /* not done yet */
+
+ /* start the first command in the DO phase */
+ state(conn, SSH_SFTP_QUOTE_INIT);
+
+ /* run the state-machine */
+ result = wssh_multi_statemach(conn, dophase_done);
+
+ *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+ if(*dophase_done) {
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+
+ return result;
+}
+
+/*
+ * The DO function is generic for both protocols.
+ */
+static CURLcode wssh_do(struct connectdata *conn, bool *done)
+{
+ CURLcode result;
+ bool connected = 0;
+ struct Curl_easy *data = conn->data;
+ struct ssh_conn *sshc = &conn->proto.sshc;
+
+ *done = FALSE; /* default to false */
+ data->req.size = -1; /* make sure this is unknown at this point */
+ sshc->actualcode = CURLE_OK; /* reset error code */
+ sshc->secondCreateDirs = 0; /* reset the create dir attempt state
+ variable */
+
+ Curl_pgrsSetUploadCounter(data, 0);
+ Curl_pgrsSetDownloadCounter(data, 0);
+ Curl_pgrsSetUploadSize(data, -1);
+ Curl_pgrsSetDownloadSize(data, -1);
+
+ if(conn->handler->protocol & CURLPROTO_SCP)
+ result = wscp_perform(conn, &connected, done);
+ else
+ result = wsftp_perform(conn, &connected, done);
+
+ return result;
+}
+
+static CURLcode wssh_block_statemach(struct connectdata *conn,
+ bool disconnect)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ CURLcode result = CURLE_OK;
+ struct Curl_easy *data = conn->data;
+
+ while((sshc->state != SSH_STOP) && !result) {
+ bool block;
+ timediff_t left = 1000;
+ struct curltime now = Curl_now();
+
+ result = wssh_statemach_act(conn, &block);
+ if(result)
+ break;
+
+ if(!disconnect) {
+ if(Curl_pgrsUpdate(conn))
+ return CURLE_ABORTED_BY_CALLBACK;
+
+ result = Curl_speedcheck(data, now);
+ if(result)
+ break;
+
+ left = Curl_timeleft(data, NULL, FALSE);
+ if(left < 0) {
+ failf(data, "Operation timed out");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ }
+
+ if(!result) {
+ int dir = conn->waitfor;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ curl_socket_t fd_read = CURL_SOCKET_BAD;
+ curl_socket_t fd_write = CURL_SOCKET_BAD;
+ if(dir == KEEP_RECV)
+ fd_read = sock;
+ else if(dir == KEEP_SEND)
+ fd_write = sock;
+
+ /* wait for the socket to become ready */
+ (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
+ left>1000?1000:left); /* ignore result */
+ }
+ }
+
+ return result;
+}
+
+/* generic done function for both SCP and SFTP called from their specific
+ done functions */
+static CURLcode wssh_done(struct connectdata *conn, CURLcode status)
+{
+ CURLcode result = CURLE_OK;
+ struct SSHPROTO *sftp_scp = conn->data->req.protop;
+
+ if(!status) {
+ /* run the state-machine */
+ result = wssh_block_statemach(conn, FALSE);
+ }
+ else
+ result = status;
+
+ if(sftp_scp)
+ Curl_safefree(sftp_scp->path);
+ if(Curl_pgrsDone(conn))
+ return CURLE_ABORTED_BY_CALLBACK;
+
+ conn->data->req.keepon = 0; /* clear all bits */
+ return result;
+}
+
+#if 0
+static CURLcode wscp_done(struct connectdata *conn,
+ CURLcode code, bool premature)
+{
+ CURLcode result = CURLE_OK;
+ (void)conn;
+ (void)code;
+ (void)premature;
+
+ return result;
+}
+
+static CURLcode wscp_doing(struct connectdata *conn,
+ bool *dophase_done)
+{
+ CURLcode result = CURLE_OK;
+ (void)conn;
+ (void)dophase_done;
+
+ return result;
+}
+
+static CURLcode wscp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ CURLcode result = CURLE_OK;
+ (void)conn;
+ (void)dead_connection;
+
+ return result;
+}
+#endif
+
+static CURLcode wsftp_done(struct connectdata *conn,
+ CURLcode code, bool premature)
+{
+ (void)premature;
+ state(conn, SSH_SFTP_CLOSE);
+
+ return wssh_done(conn, code);
+}
+
+static CURLcode wsftp_doing(struct connectdata *conn,
+ bool *dophase_done)
+{
+ CURLcode result = wssh_multi_statemach(conn, dophase_done);
+
+ if(*dophase_done) {
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+ return result;
+}
+
+static CURLcode wsftp_disconnect(struct connectdata *conn, bool dead)
+{
+ CURLcode result = CURLE_OK;
+ (void)dead;
+
+ DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+
+ if(conn->proto.sshc.ssh_session) {
+ /* only if there's a session still around to use! */
+ state(conn, SSH_SFTP_SHUTDOWN);
+ result = wssh_block_statemach(conn, TRUE);
+ }
+
+ DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+ return result;
+}
+
+static int wssh_getsock(struct connectdata *conn,
+ curl_socket_t *sock)
+{
+ return wssh_perform_getsock(conn, sock);
+}
+
+static int wssh_perform_getsock(const struct connectdata *conn,
+ curl_socket_t *sock)
+{
+ int bitmap = GETSOCK_BLANK;
+ int dir = conn->waitfor;
+ sock[0] = conn->sock[FIRSTSOCKET];
+
+ if(dir == KEEP_RECV)
+ bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+ else if(dir == KEEP_SEND)
+ bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+ return bitmap;
+}
+
+size_t Curl_ssh_version(char *buffer, size_t buflen)
+{
+ return msnprintf(buffer, buflen, "wolfssh/%s", LIBWOLFSSH_VERSION_STRING);
+}
+
+CURLcode Curl_ssh_init(void)
+{
+ if(WS_SUCCESS != wolfSSH_Init()) {
+ DEBUGF(fprintf(stderr, "Error: wolfSSH_Init failed\n"));
+ return CURLE_FAILED_INIT;
+ }
+
+ return CURLE_OK;
+}
+void Curl_ssh_cleanup(void)
+{
+}
+
+#endif /* USE_WOLFSSH */
diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c
index 3737d7c685..5f740eeba1 100644
--- a/libs/libcurl/src/vtls/gtls.c
+++ b/libs/libcurl/src/vtls/gtls.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
@@ -666,6 +666,10 @@ gtls_connect_step1(struct connectdata *conn,
/* Initialize TLS session as a client */
init_flags = GNUTLS_CLIENT;
+#if defined(GNUTLS_FORCE_CLIENT_CERT)
+ init_flags |= GNUTLS_FORCE_CLIENT_CERT;
+#endif
+
#if defined(GNUTLS_NO_TICKETS)
/* Disable TLS session tickets */
init_flags |= GNUTLS_NO_TICKETS;
diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c
index e34ec9d13f..f057315f30 100644
--- a/libs/libcurl/src/vtls/mbedtls.c
+++ b/libs/libcurl/src/vtls/mbedtls.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- * Copyright (C) 2012 - 2019, 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
@@ -55,7 +55,7 @@
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "multiif.h"
-#include "polarssl_threadlock.h"
+#include "mbedtls_threadlock.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -91,12 +91,12 @@ static int entropy_init_initialized = 0;
static void entropy_init_mutex(mbedtls_entropy_context *ctx)
{
/* lock 0 = entropy_init_mutex() */
- Curl_polarsslthreadlock_lock_function(0);
+ Curl_mbedtlsthreadlock_lock_function(0);
if(entropy_init_initialized == 0) {
mbedtls_entropy_init(ctx);
entropy_init_initialized = 1;
}
- Curl_polarsslthreadlock_unlock_function(0);
+ Curl_mbedtlsthreadlock_unlock_function(0);
}
/* end of entropy_init_mutex() */
@@ -105,9 +105,9 @@ static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
{
int ret;
/* lock 1 = entropy_func_mutex() */
- Curl_polarsslthreadlock_lock_function(1);
+ Curl_mbedtlsthreadlock_lock_function(1);
ret = mbedtls_entropy_func(data, output, len);
- Curl_polarsslthreadlock_unlock_function(1);
+ Curl_mbedtlsthreadlock_unlock_function(1);
return ret;
}
@@ -1017,12 +1017,12 @@ static CURLcode Curl_mbedtls_connect(struct connectdata *conn, int sockindex)
*/
static int Curl_mbedtls_init(void)
{
- return Curl_polarsslthreadlock_thread_setup();
+ return Curl_mbedtlsthreadlock_thread_setup();
}
static void Curl_mbedtls_cleanup(void)
{
- (void)Curl_polarsslthreadlock_thread_cleanup();
+ (void)Curl_mbedtlsthreadlock_thread_cleanup();
}
static bool Curl_mbedtls_data_pending(const struct connectdata *conn,
diff --git a/libs/libcurl/src/vtls/mbedtls_threadlock.c b/libs/libcurl/src/vtls/mbedtls_threadlock.c
new file mode 100644
index 0000000000..4d672f106e
--- /dev/null
+++ b/libs/libcurl/src/vtls/mbedtls_threadlock.c
@@ -0,0 +1,144 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(USE_MBEDTLS) && \
+ ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
+ (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)))
+
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+# include <pthread.h>
+# define MBEDTLS_MUTEX_T pthread_mutex_t
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+# include <process.h>
+# define MBEDTLS_MUTEX_T HANDLE
+#endif
+
+#include "mbedtls_threadlock.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* number of thread locks */
+#define NUMT 2
+
+/* This array will store all of the mutexes available to Mbedtls. */
+static MBEDTLS_MUTEX_T *mutex_buf = NULL;
+
+int Curl_mbedtlsthreadlock_thread_setup(void)
+{
+ int i;
+
+ mutex_buf = calloc(NUMT * sizeof(MBEDTLS_MUTEX_T), 1);
+ if(!mutex_buf)
+ return 0; /* error, no number of threads defined */
+
+ for(i = 0; i < NUMT; i++) {
+ int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+ ret = pthread_mutex_init(&mutex_buf[i], NULL);
+ if(ret)
+ return 0; /* pthread_mutex_init failed */
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+ mutex_buf[i] = CreateMutex(0, FALSE, 0);
+ if(mutex_buf[i] == 0)
+ return 0; /* CreateMutex failed */
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
+ }
+
+ return 1; /* OK */
+}
+
+int Curl_mbedtlsthreadlock_thread_cleanup(void)
+{
+ int i;
+
+ if(!mutex_buf)
+ return 0; /* error, no threads locks defined */
+
+ for(i = 0; i < NUMT; i++) {
+ int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+ ret = pthread_mutex_destroy(&mutex_buf[i]);
+ if(ret)
+ return 0; /* pthread_mutex_destroy failed */
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+ ret = CloseHandle(mutex_buf[i]);
+ if(!ret)
+ return 0; /* CloseHandle failed */
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
+ }
+ free(mutex_buf);
+ mutex_buf = NULL;
+
+ return 1; /* OK */
+}
+
+int Curl_mbedtlsthreadlock_lock_function(int n)
+{
+ if(n < NUMT) {
+ int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+ ret = pthread_mutex_lock(&mutex_buf[n]);
+ if(ret) {
+ DEBUGF(fprintf(stderr,
+ "Error: mbedtlsthreadlock_lock_function failed\n"));
+ return 0; /* pthread_mutex_lock failed */
+ }
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+ ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0);
+ if(ret) {
+ DEBUGF(fprintf(stderr,
+ "Error: mbedtlsthreadlock_lock_function failed\n"));
+ return 0; /* pthread_mutex_lock failed */
+ }
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
+ }
+ return 1; /* OK */
+}
+
+int Curl_mbedtlsthreadlock_unlock_function(int n)
+{
+ if(n < NUMT) {
+ int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+ ret = pthread_mutex_unlock(&mutex_buf[n]);
+ if(ret) {
+ DEBUGF(fprintf(stderr,
+ "Error: mbedtlsthreadlock_unlock_function failed\n"));
+ return 0; /* pthread_mutex_unlock failed */
+ }
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+ ret = ReleaseMutex(mutex_buf[n]);
+ if(!ret) {
+ DEBUGF(fprintf(stderr,
+ "Error: mbedtlsthreadlock_unlock_function failed\n"));
+ return 0; /* pthread_mutex_lock failed */
+ }
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
+ }
+ return 1; /* OK */
+}
+
+#endif /* USE_MBEDTLS */
diff --git a/libs/libcurl/src/vtls/mbedtls_threadlock.h b/libs/libcurl/src/vtls/mbedtls_threadlock.h
new file mode 100644
index 0000000000..96a787d1a2
--- /dev/null
+++ b/libs/libcurl/src/vtls/mbedtls_threadlock.h
@@ -0,0 +1,48 @@
+#ifndef HEADER_CURL_MBEDTLS_THREADLOCK_H
+#define HEADER_CURL_MBEDTLS_THREADLOCK_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * 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"
+
+#ifdef USE_MBEDTLS
+
+#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
+ (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H))
+
+int Curl_mbedtlsthreadlock_thread_setup(void);
+int Curl_mbedtlsthreadlock_thread_cleanup(void);
+int Curl_mbedtlsthreadlock_lock_function(int n);
+int Curl_mbedtlsthreadlock_unlock_function(int n);
+
+#else
+
+#define Curl_mbedtlsthreadlock_thread_setup() 1
+#define Curl_mbedtlsthreadlock_thread_cleanup() 1
+#define Curl_mbedtlsthreadlock_lock_function(x) 1
+#define Curl_mbedtlsthreadlock_unlock_function(x) 1
+
+#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
+
+#endif /* USE_MBEDTLS */
+
+#endif /* HEADER_CURL_MBEDTLS_THREADLOCK_H */
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index 726ff6e7ca..1d09cadca8 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.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
@@ -2212,7 +2212,6 @@ set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
curl_ssl_version_max = SSL_CONN_CONFIG(version_max);
/* convert cURL max SSL version option to OpenSSL constant */
- ossl_ssl_version_max = 0;
switch(curl_ssl_version_max) {
case CURL_SSLVERSION_MAX_TLSv1_0:
ossl_ssl_version_max = TLS1_VERSION;
@@ -3122,28 +3121,25 @@ do { \
} while(0)
#endif
-static int X509V3_ext(struct Curl_easy *data,
+static void X509V3_ext(struct Curl_easy *data,
int certnum,
CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
{
int i;
- size_t j;
if((int)sk_X509_EXTENSION_num(exts) <= 0)
/* no extensions, bail out */
- return 1;
+ return;
for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) {
ASN1_OBJECT *obj;
X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
BUF_MEM *biomem;
- char buf[512];
- char *ptr = buf;
char namebuf[128];
BIO *bio_out = BIO_new(BIO_s_mem());
if(!bio_out)
- return 1;
+ return;
obj = X509_EXTENSION_get_object(ext);
@@ -3153,26 +3149,10 @@ static int X509V3_ext(struct Curl_easy *data,
ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
BIO_get_mem_ptr(bio_out, &biomem);
-
- for(j = 0; j < (size_t)biomem->length; j++) {
- const char *sep = "";
- if(biomem->data[j] == '\n') {
- sep = ", ";
- j++; /* skip the newline */
- };
- while((j<(size_t)biomem->length) && (biomem->data[j] == ' '))
- j++;
- if(j<(size_t)biomem->length)
- ptr += msnprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
- biomem->data[j]);
- }
-
- Curl_ssl_push_certinfo(data, certnum, namebuf, buf);
-
+ Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data,
+ biomem->length);
BIO_free(bio_out);
-
}
- return 0; /* all is fine */
}
#ifdef OPENSSL_IS_BORINGSSL
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c
index dc58ed0d3b..0818d947a4 100644
--- a/libs/libcurl/src/vtls/schannel.c
+++ b/libs/libcurl/src/vtls/schannel.c
@@ -718,7 +718,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
unsigned short* list_len = NULL;
/* The first four bytes will be an unsigned int indicating number
- of bytes of data in the rest of the the buffer. */
+ of bytes of data in the rest of the buffer. */
extension_len = (unsigned int *)(&alpn_buffer[cur]);
cur += sizeof(unsigned int);
diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c
index 3a668adc76..e75132cadd 100644
--- a/libs/libcurl/src/vtls/schannel_verify.c
+++ b/libs/libcurl/src/vtls/schannel_verify.c
@@ -7,7 +7,7 @@
*
* Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de>
* Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
- * Copyright (C) 2012 - 2019, 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
@@ -293,6 +293,133 @@ cleanup:
return result;
}
+/*
+ * Returns the number of characters necessary to populate all the host_names.
+ * If host_names is not NULL, populate it with all the host names. Each string
+ * in the host_names is null-terminated and the last string is double
+ * null-terminated. If no DNS names are found, a single null-terminated empty
+ * string is returned.
+ */
+static DWORD cert_get_name_string(struct Curl_easy *data,
+ CERT_CONTEXT *cert_context,
+ LPTSTR host_names,
+ DWORD length)
+{
+ DWORD actual_length = 0;
+ BOOL compute_content = FALSE;
+ CERT_INFO *cert_info = NULL;
+ CERT_EXTENSION *extension = NULL;
+ CRYPT_DECODE_PARA decode_para = {0, 0, 0};
+ CERT_ALT_NAME_INFO *alt_name_info = NULL;
+ DWORD alt_name_info_size = 0;
+ BOOL ret_val = FALSE;
+ LPTSTR current_pos = NULL;
+ DWORD i;
+
+ /* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */
+ if(Curl_verify_windows_version(6, 2, PLATFORM_WINNT,
+ VERSION_GREATER_THAN_EQUAL)) {
+#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
+ /* CertGetNameString will provide the 8-bit character string without
+ * any decoding */
+ DWORD name_flags =
+ CERT_NAME_DISABLE_IE4_UTF8_FLAG | CERT_NAME_SEARCH_ALL_NAMES_FLAG;
+ actual_length = CertGetNameString(cert_context,
+ CERT_NAME_DNS_TYPE,
+ name_flags,
+ NULL,
+ host_names,
+ length);
+ return actual_length;
+#endif
+ }
+
+ compute_content = host_names != NULL && length != 0;
+
+ /* Initialize default return values. */
+ actual_length = 1;
+ if(compute_content) {
+ *host_names = '\0';
+ }
+
+ if(!cert_context) {
+ failf(data, "schannel: Null certificate context.");
+ return actual_length;
+ }
+
+ cert_info = cert_context->pCertInfo;
+ if(!cert_info) {
+ failf(data, "schannel: Null certificate info.");
+ return actual_length;
+ }
+
+ extension = CertFindExtension(szOID_SUBJECT_ALT_NAME2,
+ cert_info->cExtension,
+ cert_info->rgExtension);
+ if(!extension) {
+ failf(data, "schannel: CertFindExtension() returned no extension.");
+ return actual_length;
+ }
+
+ decode_para.cbSize = sizeof(CRYPT_DECODE_PARA);
+
+ ret_val =
+ CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ szOID_SUBJECT_ALT_NAME2,
+ extension->Value.pbData,
+ extension->Value.cbData,
+ CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG,
+ &decode_para,
+ &alt_name_info,
+ &alt_name_info_size);
+ if(!ret_val) {
+ failf(data,
+ "schannel: CryptDecodeObjectEx() returned no alternate name "
+ "information.");
+ return actual_length;
+ }
+
+ current_pos = host_names;
+
+ /* Iterate over the alternate names and populate host_names. */
+ for(i = 0; i < alt_name_info->cAltEntry; i++) {
+ const CERT_ALT_NAME_ENTRY *entry = &alt_name_info->rgAltEntry[i];
+ wchar_t *dns_w = NULL;
+ size_t current_length = 0;
+
+ if(entry->dwAltNameChoice != CERT_ALT_NAME_DNS_NAME) {
+ continue;
+ }
+ if(entry->pwszDNSName == NULL) {
+ infof(data, "schannel: Empty DNS name.");
+ continue;
+ }
+ current_length = wcslen(entry->pwszDNSName) + 1;
+ if(!compute_content) {
+ actual_length += (DWORD)current_length;
+ continue;
+ }
+ /* Sanity check to prevent buffer overrun. */
+ if((actual_length + current_length) > length) {
+ failf(data, "schannel: Not enough memory to list all host names.");
+ break;
+ }
+ dns_w = entry->pwszDNSName;
+ /* pwszDNSName is in ia5 string format and hence doesn't contain any
+ * non-ascii characters. */
+ while(*dns_w != '\0') {
+ *current_pos++ = (char)(*dns_w++);
+ }
+ *current_pos++ = '\0';
+ actual_length += (DWORD)current_length;
+ }
+ if(compute_content) {
+ /* Last string has double null-terminator. */
+ *current_pos = '\0';
+ }
+ return actual_length;
+}
+
static CURLcode verify_host(struct Curl_easy *data,
CERT_CONTEXT *pCertContextServer,
const char * const conn_hostname)
@@ -303,21 +430,8 @@ static CURLcode verify_host(struct Curl_easy *data,
DWORD len = 0;
DWORD actual_len = 0;
- /* CertGetNameString will provide the 8-bit character string without
- * any decoding */
- DWORD name_flags = CERT_NAME_DISABLE_IE4_UTF8_FLAG;
-
-#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
- name_flags |= CERT_NAME_SEARCH_ALL_NAMES_FLAG;
-#endif
-
/* Determine the size of the string needed for the cert hostname */
- len = CertGetNameString(pCertContextServer,
- CERT_NAME_DNS_TYPE,
- name_flags,
- NULL,
- NULL,
- 0);
+ len = cert_get_name_string(data, pCertContextServer, NULL, 0);
if(len == 0) {
failf(data,
"schannel: CertGetNameString() returned no "
@@ -334,12 +448,8 @@ static CURLcode verify_host(struct Curl_easy *data,
result = CURLE_OUT_OF_MEMORY;
goto cleanup;
}
- actual_len = CertGetNameString(pCertContextServer,
- CERT_NAME_DNS_TYPE,
- name_flags,
- NULL,
- (LPTSTR) cert_hostname_buff,
- len);
+ actual_len = cert_get_name_string(
+ data, pCertContextServer, (LPTSTR)cert_hostname_buff, len);
/* Sanity check */
if(actual_len != len) {
diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c
index 4eece89d55..7dd028fb7f 100644
--- a/libs/libcurl/src/vtls/sectransp.c
+++ b/libs/libcurl/src/vtls/sectransp.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
- * Copyright (C) 2012 - 2019, 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
@@ -1164,7 +1164,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
* the Keychain.
*
* As this doesn't match iOS, and apps may not want to see their client
- * certificate saved in the the user's keychain, we use SecItemImport
+ * certificate saved in the user's keychain, we use SecItemImport
* with a NULL keychain to avoid importing it.
*
* This returns a SecCertificateRef from which we can construct a
diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c
index c493b15169..dfefa1bd5e 100644
--- a/libs/libcurl/src/vtls/vtls.c
+++ b/libs/libcurl/src/vtls/vtls.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
@@ -516,7 +516,7 @@ void Curl_ssl_close_all(struct Curl_easy *data)
}
#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
- defined(USE_SECTRANSP) || defined(USE_POLARSSL) || defined(USE_NSS) || \
+ defined(USE_SECTRANSP) || defined(USE_NSS) || \
defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_BEARSSL)
int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks)
{
@@ -1183,8 +1183,6 @@ const struct Curl_ssl *Curl_ssl =
&Curl_ssl_nss;
#elif defined(USE_OPENSSL)
&Curl_ssl_openssl;
-#elif defined(USE_POLARSSL)
- &Curl_ssl_polarssl;
#elif defined(USE_SCHANNEL)
&Curl_ssl_schannel;
#elif defined(USE_MESALINK)
@@ -1217,9 +1215,6 @@ static const struct Curl_ssl *available_backends[] = {
#if defined(USE_OPENSSL)
&Curl_ssl_openssl,
#endif
-#if defined(USE_POLARSSL)
- &Curl_ssl_polarssl,
-#endif
#if defined(USE_SCHANNEL)
&Curl_ssl_schannel,
#endif
@@ -1236,7 +1231,7 @@ static size_t Curl_multissl_version(char *buffer, size_t size)
{
static const struct Curl_ssl *selected;
static char backends[200];
- static size_t total;
+ static size_t backends_len;
const struct Curl_ssl *current;
current = Curl_ssl == &Curl_ssl_multi ? available_backends[0] : Curl_ssl;
@@ -1248,27 +1243,32 @@ static size_t Curl_multissl_version(char *buffer, size_t size)
selected = current;
- for(i = 0; available_backends[i] && p < (end - 4); i++) {
- if(i)
- *(p++) = ' ';
- if(selected != available_backends[i])
- *(p++) = '(';
- p += available_backends[i]->version(p, end - p - 2);
- if(selected != available_backends[i])
- *(p++) = ')';
+ backends[0] = '\0';
+
+ for(i = 0; available_backends[i]; ++i) {
+ char vb[200];
+ bool paren = (selected != available_backends[i]);
+
+ if(available_backends[i]->version(vb, sizeof(vb))) {
+ p += msnprintf(p, end - p, "%s%s%s%s", (p != backends ? " " : ""),
+ (paren ? "(" : ""), vb, (paren ? ")" : ""));
+ }
}
- *p = '\0';
- total = p - backends;
+
+ backends_len = p - backends;
}
- if(size > total)
- memcpy(buffer, backends, total + 1);
- else {
- memcpy(buffer, backends, size - 1);
+ if(!size)
+ return 0;
+
+ if(size <= backends_len) {
+ strncpy(buffer, backends, size - 1);
buffer[size - 1] = '\0';
+ return size - 1;
}
- return CURLMIN(size - 1, total);
+ strcpy(buffer, backends);
+ return backends_len;
}
static int multissl_init(const struct Curl_ssl *backend)
diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h
index 976cc43601..f58adee6e8 100644
--- a/libs/libcurl/src/vtls/vtls.h
+++ b/libs/libcurl/src/vtls/vtls.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
@@ -102,7 +102,6 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
#include "gtls.h" /* GnuTLS versions */
#include "nssg.h" /* NSS versions */
#include "gskit.h" /* Global Secure ToolKit versions */
-#include "polarssl.h" /* PolarSSL versions */
#include "wolfssl.h" /* wolfSSL versions */
#include "schannel.h" /* Schannel SSPI version */
#include "sectransp.h" /* SecureTransport (Darwin) version */
diff --git a/libs/libcurl/src/vtls/wolfssl.c b/libs/libcurl/src/vtls/wolfssl.c
index 890bcbf797..8c2d3f4a28 100644
--- a/libs/libcurl/src/vtls/wolfssl.c
+++ b/libs/libcurl/src/vtls/wolfssl.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
@@ -923,7 +923,7 @@ static CURLcode Curl_wolfssl_connect(struct connectdata *conn, int sockindex)
static CURLcode Curl_wolfssl_random(struct Curl_easy *data,
unsigned char *entropy, size_t length)
{
- RNG rng;
+ WC_RNG rng;
(void)data;
if(wc_InitRng(&rng))
return CURLE_FAILED_INIT;
@@ -937,11 +937,11 @@ static CURLcode Curl_wolfssl_random(struct Curl_easy *data,
}
static CURLcode Curl_wolfssl_sha256sum(const unsigned char *tmp, /* input */
- size_t tmplen,
- unsigned char *sha256sum /* output */,
- size_t unused)
+ size_t tmplen,
+ unsigned char *sha256sum /* output */,
+ size_t unused)
{
- Sha256 SHA256pw;
+ wc_Sha256 SHA256pw;
(void)unused;
wc_InitSha256(&SHA256pw);
wc_Sha256Update(&SHA256pw, tmp, (word32)tmplen);