diff options
Diffstat (limited to 'libs/libcurl/src')
130 files changed, 2266 insertions, 877 deletions
diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt index eca9a8af93..a9c90b6650 100644 --- a/libs/libcurl/src/CMakeLists.txt +++ b/libs/libcurl/src/CMakeLists.txt @@ -20,7 +20,6 @@ list(APPEND HHEADERS if(MSVC) list(APPEND CSOURCES libcurl.rc) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127") endif() # SET(CSOURCES diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in index 27101a8eea..9259841744 100644 --- a/libs/libcurl/src/Makefile.in +++ b/libs/libcurl/src/Makefile.in @@ -245,14 +245,15 @@ am__objects_3 = vtls/libcurl_la-openssl.lo vtls/libcurl_la-gtls.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-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_6 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) am__objects_7 = am__objects_8 = $(am__objects_7) $(am__objects_7) $(am__objects_7) \ - $(am__objects_7) + $(am__objects_7) $(am__objects_7) am_libcurl_la_OBJECTS = $(am__objects_6) $(am__objects_8) libcurl_la_OBJECTS = $(am_libcurl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -332,7 +333,8 @@ am__objects_11 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.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 \ - vtls/libcurlu_la-mbedtls.lo vtls/libcurlu_la-mesalink.lo + vtls/libcurlu_la-mbedtls.lo vtls/libcurlu_la-mesalink.lo \ + vtls/libcurlu_la-bearssl.lo am__objects_12 = vquic/libcurlu_la-ngtcp2.lo \ vquic/libcurlu_la-quiche.lo am__objects_13 = vssh/libcurlu_la-libssh2.lo \ @@ -610,6 +612,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ vssh/$(DEPDIR)/libcurl_la-libssh2.Plo \ vssh/$(DEPDIR)/libcurlu_la-libssh.Plo \ vssh/$(DEPDIR)/libcurlu_la-libssh2.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 \ @@ -623,6 +626,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ vtls/$(DEPDIR)/libcurl_la-sectransp.Plo \ vtls/$(DEPDIR)/libcurl_la-vtls.Plo \ vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo \ + vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo \ vtls/$(DEPDIR)/libcurlu_la-gskit.Plo \ vtls/$(DEPDIR)/libcurlu_la-gtls.Plo \ vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo \ @@ -815,6 +819,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ USE_ARES = @USE_ARES@ +USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@ USE_LIBRTMP = @USE_LIBRTMP@ @@ -975,16 +980,18 @@ 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/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/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_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 \ ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \ @@ -1014,7 +1021,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \ inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \ easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \ - socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \ + socks.h curl_base64.h curl_addrinfo.h curl_sspi.h \ slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \ rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \ curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \ @@ -1031,7 +1038,7 @@ CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \ $(LIB_VQUIC_CFILES) $(LIB_VSSH_CFILES) HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) \ - $(LIB_VQUIC_HFILES) + $(LIB_VQUIC_HFILES) $(LIB_VSSH_HFILES) # Makefile.inc provides the CSOURCES and HHEADERS defines @@ -1205,6 +1212,8 @@ vtls/libcurl_la-mbedtls.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-mesalink.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-bearssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) vquic/$(am__dirstamp): @$(MKDIR_P) vquic @: > vquic/$(am__dirstamp) @@ -1278,6 +1287,8 @@ vtls/libcurlu_la-mbedtls.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-mesalink.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-bearssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) vquic/libcurlu_la-ngtcp2.lo: vquic/$(am__dirstamp) \ vquic/$(DEPDIR)/$(am__dirstamp) vquic/libcurlu_la-quiche.lo: vquic/$(am__dirstamp) \ @@ -1558,6 +1569,7 @@ distclean-compile: @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)/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@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 @@ -1571,6 +1583,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-sectransp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-vtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo@am__quote@ # am--include-marker @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 @@ -2567,6 +2580,13 @@ vtls/libcurl_la-mesalink.lo: vtls/mesalink.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-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c +vtls/libcurl_la-bearssl.lo: vtls/bearssl.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-bearssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-bearssl.Tpo -c -o vtls/libcurl_la-bearssl.lo `test -f 'vtls/bearssl.c' || echo '$(srcdir)/'`vtls/bearssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-bearssl.Tpo vtls/$(DEPDIR)/libcurl_la-bearssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/bearssl.c' object='vtls/libcurl_la-bearssl.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-bearssl.lo `test -f 'vtls/bearssl.c' || echo '$(srcdir)/'`vtls/bearssl.c + vquic/libcurl_la-ngtcp2.lo: vquic/ngtcp2.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 vquic/libcurl_la-ngtcp2.lo -MD -MP -MF vquic/$(DEPDIR)/libcurl_la-ngtcp2.Tpo -c -o vquic/libcurl_la-ngtcp2.lo `test -f 'vquic/ngtcp2.c' || echo '$(srcdir)/'`vquic/ngtcp2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurl_la-ngtcp2.Tpo vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo @@ -3547,6 +3567,13 @@ vtls/libcurlu_la-mesalink.lo: vtls/mesalink.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-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c +vtls/libcurlu_la-bearssl.lo: vtls/bearssl.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-bearssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-bearssl.Tpo -c -o vtls/libcurlu_la-bearssl.lo `test -f 'vtls/bearssl.c' || echo '$(srcdir)/'`vtls/bearssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-bearssl.Tpo vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/bearssl.c' object='vtls/libcurlu_la-bearssl.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-bearssl.lo `test -f 'vtls/bearssl.c' || echo '$(srcdir)/'`vtls/bearssl.c + vquic/libcurlu_la-ngtcp2.lo: vquic/ngtcp2.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 vquic/libcurlu_la-ngtcp2.lo -MD -MP -MF vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Tpo -c -o vquic/libcurlu_la-ngtcp2.lo `test -f 'vquic/ngtcp2.c' || echo '$(srcdir)/'`vquic/ngtcp2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Tpo vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo @@ -3976,6 +4003,7 @@ distclean: distclean-am -rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo -rm -f vssh/$(DEPDIR)/libcurlu_la-libssh.Plo -rm -f vssh/$(DEPDIR)/libcurlu_la-libssh2.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 @@ -3989,6 +4017,7 @@ distclean: distclean-am -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-vtls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo @@ -4301,6 +4330,7 @@ maintainer-clean: maintainer-clean-am -rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo -rm -f vssh/$(DEPDIR)/libcurlu_la-libssh.Plo -rm -f vssh/$(DEPDIR)/libcurlu_la-libssh2.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 @@ -4314,6 +4344,7 @@ maintainer-clean: maintainer-clean-am -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-vtls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc index 72ef428ee6..6c90c26752 100644 --- a/libs/libcurl/src/Makefile.inc +++ b/libs/libcurl/src/Makefile.inc @@ -30,12 +30,13 @@ 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/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/mbedtls.h vtls/mesalink.h vtls/bearssl.h LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c @@ -43,6 +44,8 @@ LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.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 \ ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \ @@ -72,7 +75,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \ inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \ easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \ - socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \ + socks.h curl_base64.h curl_addrinfo.h curl_sspi.h \ slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \ rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \ curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \ @@ -89,4 +92,4 @@ LIB_RCFILES = libcurl.rc CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \ $(LIB_VQUIC_CFILES) $(LIB_VSSH_CFILES) HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) \ - $(LIB_VQUIC_HFILES) + $(LIB_VQUIC_HFILES) $(LIB_VSSH_HFILES) diff --git a/libs/libcurl/src/Makefile.m32 b/libs/libcurl/src/Makefile.m32 index ae88f4dced..b6ef0a5cbd 100644 --- a/libs/libcurl/src/Makefile.m32 +++ b/libs/libcurl/src/Makefile.m32 @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1999 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 1999 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -271,7 +271,7 @@ ifdef SSL endif INCLUDES += -I"$(OPENSSL_INCLUDE)" CFLAGS += -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \ - -DHAVE_ENGINE_LOAD_BUILTIN_ENGINES -DOPENSSL_NO_KRB5 + -DOPENSSL_NO_KRB5 DLL_LIBS += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS) ifdef SRP ifeq "$(wildcard $(OPENSSL_INCLUDE)/openssl/srp.h)" "$(OPENSSL_INCLUDE)/openssl/srp.h" diff --git a/libs/libcurl/src/altsvc.c b/libs/libcurl/src/altsvc.c index 64971a9f0f..bf869c37a5 100644 --- a/libs/libcurl/src/altsvc.c +++ b/libs/libcurl/src/altsvc.c @@ -55,7 +55,7 @@ static enum alpnid alpn2alpnid(char *name) if(strcasecompare(name, "h2")) return ALPN_h2; #if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS) - if(strcasecompare(name, "h3-23")) + if(strcasecompare(name, "h3-24")) return ALPN_h3; #else if(strcasecompare(name, "h3")) @@ -74,7 +74,7 @@ const char *Curl_alpnid2str(enum alpnid id) return "h2"; case ALPN_h3: #if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS) - return "h3-23"; + return "h3-24"; #else return "h3"; #endif @@ -161,7 +161,7 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char *line) date, &persist, &prio); if(9 == rc) { struct altsvc *as; - time_t expires = curl_getdate(date, NULL); + time_t expires = Curl_getdate_capped(date); as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport); if(as) { as->expires = expires; @@ -320,8 +320,8 @@ CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file) /* no cache activated */ return CURLE_OK; - if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file[0]) - /* marked as read-only or zero length file name */ + 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(!out) diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c index 8c552baa9a..b08497aaa0 100644 --- a/libs/libcurl/src/asyn-thread.c +++ b/libs/libcurl/src/asyn-thread.c @@ -698,6 +698,16 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, *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); @@ -741,7 +751,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, /* This is a dotted IP address 123.123.123.123-style */ return Curl_ip2addr(AF_INET, &in, hostname, port); } -#ifdef CURLRES_IPV6 +#ifdef ENABLE_IPV6 { struct in6_addr in6; /* check if this is an IPv6 address string */ @@ -749,7 +759,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, /* This is an IPv6 address literal */ return Curl_ip2addr(AF_INET6, &in6, hostname, port); } -#endif /* CURLRES_IPV6 */ +#endif /* ENABLE_IPV6 */ #endif /* !USE_RESOLVE_ON_IPS */ #ifdef CURLRES_IPV6 diff --git a/libs/libcurl/src/checksrc.pl b/libs/libcurl/src/checksrc.pl index b2cfa83559..8343645610 100644 --- a/libs/libcurl/src/checksrc.pl +++ b/libs/libcurl/src/checksrc.pl @@ -6,7 +6,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 2011 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -717,12 +717,17 @@ sub scanfile { my $commityear = undef; @copyright = sort {$$b{year} cmp $$a{year}} @copyright; + # if the file is modified, assume commit year this year if(`git status -s -- $file` =~ /^ [MARCU]/) { $commityear = (localtime(time))[5] + 1900; } - elsif (`git rev-list --count origin/master..HEAD -- $file` !~ /^0/) { - my $grl = `git rev-list --max-count=1 --timestamp HEAD -- $file`; - $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900; + else { + # min-parents=1 to ignore wrong initial commit in truncated repos + my $grl = `git rev-list --max-count=1 --min-parents=1 --timestamp HEAD -- $file`; + if($grl) { + chomp $grl; + $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900; + } } if(defined($commityear) && scalar(@copyright) && diff --git a/libs/libcurl/src/config-dos.h b/libs/libcurl/src/config-dos.h index 3e973de0b4..25f751eb56 100644 --- a/libs/libcurl/src/config-dos.h +++ b/libs/libcurl/src/config-dos.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/config-mac.h b/libs/libcurl/src/config-mac.h index 3c12bdfacc..14b98fe572 100644 --- a/libs/libcurl/src/config-mac.h +++ b/libs/libcurl/src/config-mac.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/config-plan9.h b/libs/libcurl/src/config-plan9.h index 64bfbdea05..4063d4bbd6 100644 --- a/libs/libcurl/src/config-plan9.h +++ b/libs/libcurl/src/config-plan9.h @@ -102,7 +102,6 @@ #define HAVE_BASENAME 1 #define HAVE_BOOL_T 1 #define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 #define HAVE_ERRNO_H 1 #define HAVE_FCNTL 1 #define HAVE_FCNTL_H 1 diff --git a/libs/libcurl/src/config-symbian.h b/libs/libcurl/src/config-symbian.h index cb2e96d5d1..c01e1bfab8 100644 --- a/libs/libcurl/src/config-symbian.h +++ b/libs/libcurl/src/config-symbian.h @@ -128,9 +128,6 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #define HAVE_DLFCN_H 1 -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -/*#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1*/ - /* Define to 1 if you have the <errno.h> header file. */ #define HAVE_ERRNO_H 1 diff --git a/libs/libcurl/src/config-tpf.h b/libs/libcurl/src/config-tpf.h index f0c095bb04..85b634f9d4 100644 --- a/libs/libcurl/src/config-tpf.h +++ b/libs/libcurl/src/config-tpf.h @@ -119,10 +119,6 @@ /* #undef HAVE_DES_H */ #define HAVE_DES_H 1 -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */ -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - /* Define to 1 if you have the <errno.h> header file. */ #define HAVE_ERRNO_H 1 diff --git a/libs/libcurl/src/config-vxworks.h b/libs/libcurl/src/config-vxworks.h index d352578e33..004fd4e800 100644 --- a/libs/libcurl/src/config-vxworks.h +++ b/libs/libcurl/src/config-vxworks.h @@ -143,9 +143,6 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #define HAVE_DLFCN_H 1 -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - /* Define to 1 if you have the <errno.h> header file. */ #define HAVE_ERRNO_H 1 diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index 5b028f193f..1dcce0db41 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -246,10 +246,6 @@ /* Define if you have the socket function. */ #define HAVE_SOCKET 1 -/* Define if libSSH2 is in use */ -#define USE_LIBSSH2 1 -#define HAVE_LIBSSH2_H 1 - /* Define if you have the strcasecmp function. */ /* #define HAVE_STRCASECMP 1 */ @@ -739,8 +735,12 @@ Vista #define OS "i386-pc-win32" #elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */ #define OS "x86_64-pc-win32" -#elif defined(_M_IA64) /* Itanium */ +#elif defined(_M_IA64) || defined(__ia64__) /* Itanium */ #define OS "ia64-pc-win32" +#elif defined(_M_ARM_NT) || defined(__arm__) /* ARMv7-Thumb2 (Windows RT) */ +#define OS "thumbv7a-pc-win32" +#elif defined(_M_ARM64) || defined(__aarch64__) /* ARM64 (Windows 10) */ +#define OS "aarch64-pc-win32" #else #define OS "unknown-pc-win32" #endif diff --git a/libs/libcurl/src/config-win32ce.h b/libs/libcurl/src/config-win32ce.h index 182052290e..5eb1c18f6f 100644 --- a/libs/libcurl/src/config-win32ce.h +++ b/libs/libcurl/src/config-win32ce.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/conncache.c b/libs/libcurl/src/conncache.c index 57d6061fda..28044644bf 100644 --- a/libs/libcurl/src/conncache.c +++ b/libs/libcurl/src/conncache.c @@ -40,27 +40,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifdef CURLDEBUG -/* the debug versions of these macros make extra certain that the lock is - never doubly locked or unlocked */ -#define CONN_LOCK(x) if((x)->share) { \ - Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \ - DEBUGASSERT(!(x)->state.conncache_lock); \ - (x)->state.conncache_lock = TRUE; \ - } - -#define CONN_UNLOCK(x) if((x)->share) { \ - DEBUGASSERT((x)->state.conncache_lock); \ - (x)->state.conncache_lock = FALSE; \ - Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \ - } -#else -#define CONN_LOCK(x) if((x)->share) \ - Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE) -#define CONN_UNLOCK(x) if((x)->share) \ - Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT) -#endif - #define HASHKEY_SIZE 128 static void conn_llist_dtor(void *user, void *element) @@ -122,6 +101,7 @@ static int bundle_remove_conn(struct connectbundle *cb_ptr, } curr = curr->next; } + DEBUGASSERT(0); return 0; } @@ -428,17 +408,15 @@ conncache_find_first_connection(struct conncache *connc) * * Return TRUE if stored, FALSE if closed. */ -bool Curl_conncache_return_conn(struct connectdata *conn) +bool Curl_conncache_return_conn(struct Curl_easy *data, + struct connectdata *conn) { - struct Curl_easy *data = conn->data; - /* data->multi->maxconnects can be negative, deal with it. */ size_t maxconnects = (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: data->multi->maxconnects; struct connectdata *conn_candidate = NULL; - conn->data = NULL; /* no owner anymore */ conn->lastused = Curl_now(); /* it was used up until now */ if(maxconnects > 0 && Curl_conncache_size(data) > maxconnects) { @@ -541,7 +519,8 @@ Curl_conncache_extract_oldest(struct Curl_easy *data) while(curr) { conn = curr->ptr; - if(!CONN_INUSE(conn) && !conn->data) { + if(!CONN_INUSE(conn) && !conn->data && !conn->bits.close && + !conn->bits.connect_only) { /* Set higher score for the age passed since the connection was used */ score = Curl_timediff(now, conn->lastused); diff --git a/libs/libcurl/src/conncache.h b/libs/libcurl/src/conncache.h index 58f9024093..5fe80b4c8d 100644 --- a/libs/libcurl/src/conncache.h +++ b/libs/libcurl/src/conncache.h @@ -42,6 +42,27 @@ struct conncache { #define BUNDLE_UNKNOWN 0 /* initial value */ #define BUNDLE_MULTIPLEX 2 +#ifdef CURLDEBUG +/* the debug versions of these macros make extra certain that the lock is + never doubly locked or unlocked */ +#define CONN_LOCK(x) if((x)->share) { \ + Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \ + DEBUGASSERT(!(x)->state.conncache_lock); \ + (x)->state.conncache_lock = TRUE; \ + } + +#define CONN_UNLOCK(x) if((x)->share) { \ + DEBUGASSERT((x)->state.conncache_lock); \ + (x)->state.conncache_lock = FALSE; \ + Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \ + } +#else +#define CONN_LOCK(x) if((x)->share) \ + Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE) +#define CONN_UNLOCK(x) if((x)->share) \ + Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT) +#endif + struct connectbundle { int multiuse; /* supports multi-use */ size_t num_connections; /* Number of connections in the bundle */ @@ -61,7 +82,8 @@ void Curl_conncache_unlock(struct Curl_easy *data); size_t Curl_conncache_size(struct Curl_easy *data); size_t Curl_conncache_bundle_size(struct connectdata *conn); -bool Curl_conncache_return_conn(struct connectdata *conn); +bool Curl_conncache_return_conn(struct Curl_easy *data, + struct connectdata *conn); CURLcode Curl_conncache_add_conn(struct conncache *connc, struct connectdata *conn) WARN_UNUSED_RESULT; void Curl_conncache_remove_conn(struct Curl_easy *data, diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index 3b88a59623..611d6d2f02 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.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 @@ -932,9 +932,11 @@ CURLcode Curl_is_connected(struct connectdata *conn, SET_SOCKERRNO(error); if(conn->tempaddr[i]) { CURLcode status; +#ifndef CURL_DISABLE_VERBOSE_STRINGS char ipaddress[MAX_IPADR_LEN]; char buffer[STRERROR_LEN]; Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN); +#endif infof(data, "connect to %s port %ld failed: %s\n", ipaddress, conn->port, Curl_strerror(error, buffer, sizeof(buffer))); @@ -992,14 +994,12 @@ CURLcode Curl_is_connected(struct connectdata *conn, static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) { #if defined(TCP_NODELAY) -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) - struct Curl_easy *data = conn->data; -#endif curl_socklen_t onoff = (curl_socklen_t) 1; int level = IPPROTO_TCP; +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) + struct Curl_easy *data = conn->data; char buffer[STRERROR_LEN]; - -#if defined(CURL_DISABLE_VERBOSE_STRINGS) +#else (void) conn; #endif diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c index f56bd85a93..0091132aa3 100644 --- a/libs/libcurl/src/cookie.c +++ b/libs/libcurl/src/cookie.c @@ -96,6 +96,7 @@ Example set of cookies: #include "curl_get_line.h" #include "curl_memrchr.h" #include "inet_pton.h" +#include "parsedate.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -715,7 +716,7 @@ Curl_cookie_add(struct Curl_easy *data, else if(co->expirestr) { /* Note that if the date couldn't get parsed for whatever reason, the cookie will be treated as a session cookie */ - co->expires = curl_getdate(co->expirestr, NULL); + co->expires = Curl_getdate_capped(co->expirestr); /* Session cookies have expires set to 0 so if we get that back from the date parser let's add a second to make it a diff --git a/libs/libcurl/src/curl_base64.h b/libs/libcurl/src/curl_base64.h index 7e9fc26062..cfb6ee75b2 100644 --- a/libs/libcurl/src/curl_base64.h +++ b/libs/libcurl/src/curl_base64.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake index e0793a7ee4..2c3b6562d4 100644 --- a/libs/libcurl/src/curl_config.h.cmake +++ b/libs/libcurl/src/curl_config.h.cmake @@ -148,9 +148,6 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #cmakedefine HAVE_DLFCN_H 1 -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - /* Define to 1 if you have the <errno.h> header file. */ #cmakedefine HAVE_ERRNO_H 1 @@ -948,6 +945,9 @@ ${SIZEOF_TIME_T_CODE} /* if mbedTLS is enabled */ #cmakedefine USE_MBEDTLS 1 +/* if BearSSL is enabled */ +#cmakedefine USE_BEARSSL 1 + /* if libSSH2 is in use */ #cmakedefine USE_LIBSSH2 1 @@ -957,6 +957,9 @@ ${SIZEOF_TIME_T_CODE} /* if NSS is enabled */ #cmakedefine USE_NSS 1 +/* if you have the PK11_CreateManagedGenericObject function */ +#cmakedefine HAVE_PK11_CREATEMANAGEDGENERICOBJECT 1 + /* if you want to use OpenLDAP code instead of legacy ldap implementation */ #cmakedefine USE_OPENLDAP 1 diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in index 32a87bd293..bb7f4e3402 100644 --- a/libs/libcurl/src/curl_config.h.in +++ b/libs/libcurl/src/curl_config.h.in @@ -955,6 +955,9 @@ /* Define to enable c-ares support */ #undef USE_ARES +/* if BearSSL is enabled */ +#undef USE_BEARSSL + /* if ESNI support is available */ #undef USE_ESNI diff --git a/libs/libcurl/src/curl_des.c b/libs/libcurl/src/curl_des.c index b123a00f01..39c0f35ee6 100644 --- a/libs/libcurl/src/curl_des.c +++ b/libs/libcurl/src/curl_des.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>. + * Copyright (C) 2015 - 2019, 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 diff --git a/libs/libcurl/src/curl_des.h b/libs/libcurl/src/curl_des.h index 129060ff7d..a42eeb53f3 100644 --- a/libs/libcurl/src/curl_des.h +++ b/libs/libcurl/src/curl_des.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>. + * Copyright (C) 2015 - 2019, 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 diff --git a/libs/libcurl/src/curl_endian.c b/libs/libcurl/src/curl_endian.c index b7563b3ded..a774d136e4 100644 --- a/libs/libcurl/src/curl_endian.c +++ b/libs/libcurl/src/curl_endian.c @@ -81,6 +81,7 @@ unsigned short Curl_read16_be(const unsigned char *buf) ((unsigned short)buf[1])); } +#if (CURL_SIZEOF_CURL_OFF_T > 4) /* * write32_le() * @@ -100,7 +101,6 @@ static void write32_le(const int value, unsigned char *buffer) buffer[3] = (char)((value & 0xFF000000) >> 24); } -#if (CURL_SIZEOF_CURL_OFF_T > 4) /* * Curl_write64_le() * diff --git a/libs/libcurl/src/curl_fnmatch.h b/libs/libcurl/src/curl_fnmatch.h index 69ffe392fd..34fccae488 100644 --- a/libs/libcurl/src/curl_fnmatch.h +++ b/libs/libcurl/src/curl_fnmatch.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_gethostname.h b/libs/libcurl/src/curl_gethostname.h index 07517c5359..8ae15e6c19 100644 --- a/libs/libcurl/src/curl_gethostname.h +++ b/libs/libcurl/src/curl_gethostname.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_ldap.h b/libs/libcurl/src/curl_ldap.h index 94c002948c..912e13107c 100644 --- a/libs/libcurl/src/curl_ldap.h +++ b/libs/libcurl/src/curl_ldap.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_memrchr.h b/libs/libcurl/src/curl_memrchr.h index 747509c45a..90a8a07cce 100644 --- a/libs/libcurl/src/curl_memrchr.h +++ b/libs/libcurl/src/curl_memrchr.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_multibyte.c b/libs/libcurl/src/curl_multibyte.c index e48334faff..e3843449bb 100644 --- a/libs/libcurl/src/curl_multibyte.c +++ b/libs/libcurl/src/curl_multibyte.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_multibyte.h b/libs/libcurl/src/curl_multibyte.h index 615f5c086c..3becf41cfa 100644 --- a/libs/libcurl/src/curl_multibyte.h +++ b/libs/libcurl/src/curl_multibyte.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -61,8 +61,13 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w); #define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr)) #define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr)) -#define Curl_unicodefree(ptr) \ - do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE +#define Curl_unicodefree(ptr) \ + do { \ + if(ptr) { \ + free(ptr); \ + (ptr) = NULL; \ + } \ + } while(0) typedef union { unsigned short *tchar_ptr; @@ -76,7 +81,7 @@ typedef union { #define Curl_convert_UTF8_to_tchar(ptr) (ptr) #define Curl_convert_tchar_to_UTF8(ptr) (ptr) #define Curl_unicodefree(ptr) \ - do {(ptr) = NULL;} WHILE_FALSE + do {(ptr) = NULL;} while(0) typedef union { char *tchar_ptr; diff --git a/libs/libcurl/src/curl_ntlm_core.h b/libs/libcurl/src/curl_ntlm_core.h index 3b4b8053c3..392a1b81de 100644 --- a/libs/libcurl/src/curl_ntlm_core.h +++ b/libs/libcurl/src/curl_ntlm_core.h @@ -48,7 +48,9 @@ /* 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) +#if defined(USE_NTRESPONSES) && \ + (!defined(USE_WIN32_CRYPTO) || \ + (defined(USE_SSL) && !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 80266e2a45..30b54de444 100644 --- a/libs/libcurl/src/curl_ntlm_wb.c +++ b/libs/libcurl/src/curl_ntlm_wb.c @@ -108,10 +108,8 @@ void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn) conn->ntlm_auth_hlpr_pid = 0; } - free(conn->challenge_header); - conn->challenge_header = NULL; - free(conn->response_header); - conn->response_header = NULL; + Curl_safefree(conn->challenge_header); + Curl_safefree(conn->response_header); } static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) @@ -393,7 +391,6 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, struct auth *authp; CURLcode res = CURLE_OK; - char *input; DEBUGASSERT(conn); DEBUGASSERT(conn->data); @@ -444,19 +441,17 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, proxy ? "Proxy-" : "", conn->response_header); DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); - free(conn->response_header); + Curl_safefree(conn->response_header); if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; - conn->response_header = NULL; break; - case NTLMSTATE_TYPE2: - input = aprintf("TT %s\n", conn->challenge_header); + case NTLMSTATE_TYPE2: { + char *input = aprintf("TT %s\n", conn->challenge_header); if(!input) return CURLE_OUT_OF_MEMORY; res = ntlm_wb_response(conn, input, *state); free(input); - input = NULL; if(res) return res; @@ -471,7 +466,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; break; - + } case NTLMSTATE_TYPE3: /* connection is already authenticated, * don't send a header in future requests */ diff --git a/libs/libcurl/src/curl_rtmp.h b/libs/libcurl/src/curl_rtmp.h index 3306e22005..86a01382da 100644 --- a/libs/libcurl/src/curl_rtmp.h +++ b/libs/libcurl/src/curl_rtmp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com> + * Copyright (C) 2010 - 2019, Howard Chu, <hyc@highlandsun.com> * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index 13af8cdec9..4ecda6a9b4 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -27,6 +27,14 @@ #endif /* + * Disable Visual Studio warnings: + * 4127 "conditional expression is constant" + */ +#ifdef _MSC_VER +#pragma warning(disable:4127) +#endif + +/* * Define WIN32 when build target is Win32 API */ @@ -563,6 +571,12 @@ * Mutually exclusive CURLRES_* definitions. */ +#if defined(ENABLE_IPV6) && defined(HAVE_GETADDRINFO) +# define CURLRES_IPV6 +#else +# define CURLRES_IPV4 +#endif + #ifdef USE_ARES # define CURLRES_ASYNCH # define CURLRES_ARES @@ -577,12 +591,6 @@ # define CURLRES_SYNCH #endif -#ifdef ENABLE_IPV6 -# define CURLRES_IPV6 -#else -# define CURLRES_IPV4 -#endif - /* ---------------------------------------------------------------- */ /* @@ -644,7 +652,8 @@ int netware_init(void); #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ defined(USE_MBEDTLS) || \ defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ - defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) + defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) || \ + defined(USE_BEARSSL) #define USE_SSL /* SSL support has been enabled */ #endif @@ -713,7 +722,7 @@ int netware_init(void); */ #ifndef Curl_nop_stmt -# define Curl_nop_stmt do { } WHILE_FALSE +# define Curl_nop_stmt do { } while(0) #endif /* diff --git a/libs/libcurl/src/curl_setup_once.h b/libs/libcurl/src/curl_setup_once.h index 413ccea917..8890f3890d 100644 --- a/libs/libcurl/src/curl_setup_once.h +++ b/libs/libcurl/src/curl_setup_once.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -330,27 +330,6 @@ struct timeval { #include "curl_ctype.h" /* - * Macro WHILE_FALSE may be used to build single-iteration do-while loops, - * avoiding compiler warnings. Mostly intended for other macro definitions. - */ - -#define WHILE_FALSE while(0) - -#if defined(_MSC_VER) && !defined(__POCC__) -# undef WHILE_FALSE -# if (_MSC_VER < 1500) -# define WHILE_FALSE while(1, 0) -# else -# define WHILE_FALSE \ -__pragma(warning(push)) \ -__pragma(warning(disable:4127)) \ -while(0) \ -__pragma(warning(pop)) -# endif -#endif - - -/* * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type. */ @@ -387,7 +366,7 @@ typedef int sig_atomic_t; #ifdef DEBUGBUILD #define DEBUGF(x) x #else -#define DEBUGF(x) do { } WHILE_FALSE +#define DEBUGF(x) do { } while(0) #endif @@ -395,10 +374,11 @@ typedef int sig_atomic_t; * Macro used to include assertion code only in debug builds. */ +#undef DEBUGASSERT #if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H) #define DEBUGASSERT(x) assert(x) #else -#define DEBUGASSERT(x) do { } WHILE_FALSE +#define DEBUGASSERT(x) do { } while(0) #endif diff --git a/libs/libcurl/src/curl_sha256.h b/libs/libcurl/src/curl_sha256.h index 6db4b04dbb..14b6414ea0 100644 --- a/libs/libcurl/src/curl_sha256.h +++ b/libs/libcurl/src/curl_sha256.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Florin Petriuc, <petriuc.florin@gmail.com> + * Copyright (C) 1998 - 2019, Florin Petriuc, <petriuc.florin@gmail.com> * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_sspi.c b/libs/libcurl/src/curl_sspi.c index 1d0de4ed33..f7cc10f804 100644 --- a/libs/libcurl/src/curl_sspi.c +++ b/libs/libcurl/src/curl_sspi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_sspi.h b/libs/libcurl/src/curl_sspi.h index 2bbf9477bb..c09026ebbb 100644 --- a/libs/libcurl/src/curl_sspi.h +++ b/libs/libcurl/src/curl_sspi.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_threads.c b/libs/libcurl/src/curl_threads.c index 8e5937aa0b..064c075d0e 100644 --- a/libs/libcurl/src/curl_threads.c +++ b/libs/libcurl/src/curl_threads.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_threads.h b/libs/libcurl/src/curl_threads.h index 2a93644c56..65d1a790c1 100644 --- a/libs/libcurl/src/curl_threads.h +++ b/libs/libcurl/src/curl_threads.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/dict.h b/libs/libcurl/src/dict.h index 12c0f3394d..38a55ac0de 100644 --- a/libs/libcurl/src/dict.h +++ b/libs/libcurl/src/dict.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/doh.c b/libs/libcurl/src/doh.c index d1795789e5..7f4eee5d81 100644 --- a/libs/libcurl/src/doh.c +++ b/libs/libcurl/src/doh.c @@ -86,12 +86,36 @@ UNITTEST DOHcode doh_encode(const char *host, unsigned char *orig = dnsp; const char *hostp = host; - /* The expected output length does not depend on the number of dots within - * the host name. It will always be two more than the length of the host - * name, one for the size and one trailing null. In case there are dots, - * each dot adds one size but removes the need to store the dot, net zero. + /* The expected output length is 16 bytes more than the length of + * the QNAME-encoding of the host name. + * + * A valid DNS name may not contain a zero-length label, except at + * the end. For this reason, a name beginning with a dot, or + * containing a sequence of two or more consecutive dots, is invalid + * and cannot be encoded as a QNAME. + * + * If the host name ends with a trailing dot, the corresponding + * QNAME-encoding is one byte longer than the host name. If (as is + * also valid) the hostname is shortened by the omission of the + * trailing dot, then its QNAME-encoding will be two bytes longer + * than the host name. + * + * Each [ label, dot ] pair is encoded as [ length, label ], + * preserving overall length. A final [ label ] without a dot is + * also encoded as [ length, label ], increasing overall length + * by one. The encoding is completed by appending a zero byte, + * representing the zero-length root label, again increasing + * the overall length by one. */ - const size_t expected_len = 12 + ( 1 + hostlen + 1) + 4; + + size_t expected_len; + DEBUGASSERT(hostlen); + expected_len = 12 + 1 + hostlen + 4; + if(host[hostlen-1]!='.') + expected_len++; + + if(expected_len > (256 + 16)) /* RFCs 1034, 1035 */ + return DOH_DNS_NAME_TOO_LONG; if(len < expected_len) return DOH_TOO_SMALL_BUFFER; @@ -109,31 +133,30 @@ UNITTEST DOHcode doh_encode(const char *host, *dnsp++ = '\0'; *dnsp++ = '\0'; /* ARCOUNT */ - /* store a QNAME */ - do { - char *dot = strchr(hostp, '.'); + /* encode each label and store it in the QNAME */ + while(*hostp) { size_t labellen; - bool found = false; - if(dot) { - found = true; + char *dot = strchr(hostp, '.'); + if(dot) labellen = dot - hostp; - } else labellen = strlen(hostp); - if(labellen > 63) { - /* too long label, error out */ + if((labellen > 63) || (!labellen)) { + /* label is too long or too short, error out */ *olen = 0; return DOH_DNS_BAD_LABEL; } + /* label is non-empty, process it */ *dnsp++ = (unsigned char)labellen; memcpy(dnsp, hostp, labellen); dnsp += labellen; - hostp += labellen + 1; - if(!found) { - *dnsp++ = 0; /* terminating zero */ - break; - } - } while(1); + hostp += labellen; + /* advance past dot, but only if there is one */ + if(dot) + hostp++; + } /* next label */ + + *dnsp++ = 0; /* append zero-length label for root */ /* There are assigned TYPE codes beyond 255: use range [1..65535] */ *dnsp++ = (unsigned char)(255 & (dnstype>>8)); /* upper 8 bit TYPE */ @@ -144,8 +167,8 @@ UNITTEST DOHcode doh_encode(const char *host, *olen = dnsp - orig; - /* verify that our assumption of length is valid, since - * this has lead to buffer overflows in this function */ + /* verify that our estimation of length is valid, since + * this has led to buffer overflows in this function */ DEBUGASSERT(*olen == expected_len); return DOH_OK; } @@ -195,7 +218,7 @@ do { \ result = curl_easy_setopt(doh, x, y); \ if(result) \ goto error; \ -} WHILE_FALSE +} while(0) static CURLcode dohprobe(struct Curl_easy *data, struct dnsprobe *p, DNStype dnstype, @@ -280,38 +303,42 @@ static CURLcode dohprobe(struct Curl_easy *data, ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L); if(data->set.ssl.primary.verifyhost) ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L); +#ifndef CURL_DISABLE_PROXY if(data->set.proxy_ssl.primary.verifyhost) ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L); - if(data->set.ssl.primary.verifypeer) - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L); if(data->set.proxy_ssl.primary.verifypeer) ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYPEER, 1L); + if(data->set.str[STRING_SSL_CAFILE_PROXY]) { + ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO, + data->set.str[STRING_SSL_CAFILE_PROXY]); + } + if(data->set.str[STRING_SSL_CRLFILE_PROXY]) { + ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE, + data->set.str[STRING_SSL_CRLFILE_PROXY]); + } + if(data->set.proxy_ssl.no_revoke) + ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); + if(data->set.str[STRING_SSL_CAPATH_PROXY]) { + ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH, + data->set.str[STRING_SSL_CAPATH_PROXY]); + } +#endif + if(data->set.ssl.primary.verifypeer) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L); if(data->set.ssl.primary.verifystatus) ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L); if(data->set.str[STRING_SSL_CAFILE_ORIG]) { ERROR_CHECK_SETOPT(CURLOPT_CAINFO, data->set.str[STRING_SSL_CAFILE_ORIG]); } - if(data->set.str[STRING_SSL_CAFILE_PROXY]) { - ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO, - data->set.str[STRING_SSL_CAFILE_PROXY]); - } if(data->set.str[STRING_SSL_CAPATH_ORIG]) { ERROR_CHECK_SETOPT(CURLOPT_CAPATH, data->set.str[STRING_SSL_CAPATH_ORIG]); } - if(data->set.str[STRING_SSL_CAPATH_PROXY]) { - ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH, - data->set.str[STRING_SSL_CAPATH_PROXY]); - } if(data->set.str[STRING_SSL_CRLFILE_ORIG]) { ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, data->set.str[STRING_SSL_CRLFILE_ORIG]); } - if(data->set.str[STRING_SSL_CRLFILE_PROXY]) { - ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE, - data->set.str[STRING_SSL_CRLFILE_PROXY]); - } if(data->set.ssl.certinfo) ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); if(data->set.str[STRING_SSL_RANDOM_FILE]) { @@ -324,8 +351,6 @@ static CURLcode dohprobe(struct Curl_easy *data, } if(data->set.ssl.no_revoke) ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); - if(data->set.proxy_ssl.no_revoke) - ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); if(data->set.ssl.fsslctx) ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); if(data->set.ssl.fsslctxp) @@ -362,6 +387,7 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn, { struct Curl_easy *data = conn->data; CURLcode result = CURLE_OK; + int slot; *waitp = TRUE; /* this never returns synchronously */ (void)conn; (void)hostname; @@ -380,8 +406,8 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn, if(conn->ip_version != CURL_IPRESOLVE_V6) { /* create IPv4 DOH request */ - result = dohprobe(data, &data->req.doh.probe[0], DNS_TYPE_A, - hostname, data->set.str[STRING_DOH], + result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4], + DNS_TYPE_A, hostname, data->set.str[STRING_DOH], data->multi, data->req.doh.headers); if(result) goto error; @@ -390,8 +416,8 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn, if(conn->ip_version != CURL_IPRESOLVE_V4) { /* create IPv6 DOH request */ - result = dohprobe(data, &data->req.doh.probe[1], DNS_TYPE_AAAA, - hostname, data->set.str[STRING_DOH], + result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6], + DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH], data->multi, data->req.doh.headers); if(result) goto error; @@ -402,8 +428,9 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn, error: curl_slist_free_all(data->req.doh.headers); data->req.doh.headers = NULL; - Curl_close(&data->req.doh.probe[0].easy); - Curl_close(&data->req.doh.probe[1].easy); + for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { + Curl_close(&data->req.doh.probe[slot].easy); + } return NULL; } @@ -586,6 +613,9 @@ static DOHcode rdata(unsigned char *doh, if(rc) return rc; break; + case DNS_TYPE_DNAME: + /* explicit for clarity; just skip; rely on synthesized CNAME */ + break; default: /* unsupported type, just skip it */ break; @@ -647,8 +677,10 @@ UNITTEST DOHcode doh_decode(unsigned char *doh, return DOH_DNS_OUT_OF_RANGE; type = get16bit(doh, index); - if((type != DNS_TYPE_CNAME) && (type != dnstype)) - /* Not the same type as was asked for nor CNAME */ + if((type != DNS_TYPE_CNAME) /* may be synthesized from DNAME */ + && (type != DNS_TYPE_DNAME) /* if present, accept and ignore */ + && (type != dnstype)) + /* Not the same type as was asked for nor CNAME nor DNAME */ return DOH_DNS_UNEXPECTED_TYPE; index += 2; @@ -909,46 +941,43 @@ UNITTEST void de_cleanup(struct dohentry *d) CURLcode Curl_doh_is_resolved(struct connectdata *conn, struct Curl_dns_entry **dnsp) { + CURLcode result; struct Curl_easy *data = conn->data; *dnsp = NULL; /* defaults to no response */ - if(!data->req.doh.probe[0].easy && !data->req.doh.probe[1].easy) { + if(!data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4].easy && + !data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6].easy) { failf(data, "Could not DOH-resolve: %s", conn->async.hostname); return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY: CURLE_COULDNT_RESOLVE_HOST; } else if(!data->req.doh.pending) { - DOHcode rc; - DOHcode rc2; + DOHcode rc[DOH_PROBE_SLOTS]; struct dohentry de; + int slot; /* remove DOH handles from multi handle and close them */ - curl_multi_remove_handle(data->multi, data->req.doh.probe[0].easy); - Curl_close(&data->req.doh.probe[0].easy); - curl_multi_remove_handle(data->multi, data->req.doh.probe[1].easy); - Curl_close(&data->req.doh.probe[1].easy); + for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { + curl_multi_remove_handle(data->multi, data->req.doh.probe[slot].easy); + Curl_close(&data->req.doh.probe[slot].easy); + } /* parse the responses, create the struct and return it! */ init_dohentry(&de); - rc = doh_decode(data->req.doh.probe[0].serverdoh.memory, - data->req.doh.probe[0].serverdoh.size, - data->req.doh.probe[0].dnstype, - &de); - Curl_safefree(data->req.doh.probe[0].serverdoh.memory); - if(rc) { - infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc), - type2name(data->req.doh.probe[0].dnstype), - data->req.doh.host); - } - rc2 = doh_decode(data->req.doh.probe[1].serverdoh.memory, - data->req.doh.probe[1].serverdoh.size, - data->req.doh.probe[1].dnstype, - &de); - Curl_safefree(data->req.doh.probe[1].serverdoh.memory); - if(rc2) { - infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc2), - type2name(data->req.doh.probe[1].dnstype), - data->req.doh.host); - } - if(!rc || !rc2) { + for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { + rc[slot] = doh_decode(data->req.doh.probe[slot].serverdoh.memory, + data->req.doh.probe[slot].serverdoh.size, + data->req.doh.probe[slot].dnstype, + &de); + Curl_safefree(data->req.doh.probe[slot].serverdoh.memory); + if(rc[slot]) { + infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc[slot]), + type2name(data->req.doh.probe[slot].dnstype), + data->req.doh.host); + } + } /* next slot */ + + result = CURLE_COULDNT_RESOLVE_HOST; /* until we know better */ + if(!rc[DOH_PROBE_SLOT_IPADDR_V4] || !rc[DOH_PROBE_SLOT_IPADDR_V6]) { + /* we have an address, of one kind or other */ struct Curl_dns_entry *dns; struct Curl_addrinfo *ai; @@ -970,21 +999,26 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn, if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - de_cleanup(&de); - if(!dns) + if(!dns) { /* returned failure, bail out nicely */ Curl_freeaddrinfo(ai); + } else { conn->async.dns = dns; *dnsp = dns; - return CURLE_OK; + result = CURLE_OK; /* address resolution OK */ } - } + } /* address processing done */ + + /* Now process any build-specific attributes retrieved from DNS */ + + /* All done */ de_cleanup(&de); + return result; - return CURLE_COULDNT_RESOLVE_HOST; - } + } /* !data->req.doh.pending */ + /* else wait for pending DOH transactions to complete */ return CURLE_OK; } diff --git a/libs/libcurl/src/doh.h b/libs/libcurl/src/doh.h index f522d33085..fc053eddf9 100644 --- a/libs/libcurl/src/doh.h +++ b/libs/libcurl/src/doh.h @@ -55,14 +55,16 @@ typedef enum { DOH_DNS_UNEXPECTED_TYPE, /* 9 */ DOH_DNS_UNEXPECTED_CLASS, /* 10 */ DOH_NO_CONTENT, /* 11 */ - DOH_DNS_BAD_ID /* 12 */ + DOH_DNS_BAD_ID, /* 12 */ + DOH_DNS_NAME_TOO_LONG /* 13 */ } DOHcode; typedef enum { DNS_TYPE_A = 1, DNS_TYPE_NS = 2, DNS_TYPE_CNAME = 5, - DNS_TYPE_AAAA = 28 + DNS_TYPE_AAAA = 28, + DNS_TYPE_DNAME = 39 /* RFC6672 */ } DNStype; #define DOH_MAX_ADDR 24 diff --git a/libs/libcurl/src/dotdot.c b/libs/libcurl/src/dotdot.c index 2c6177aead..fe4f4971f1 100644 --- a/libs/libcurl/src/dotdot.c +++ b/libs/libcurl/src/dotdot.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/dotdot.h b/libs/libcurl/src/dotdot.h index 125af43671..f70b1db3fe 100644 --- a/libs/libcurl/src/dotdot.h +++ b/libs/libcurl/src/dotdot.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/easy.c b/libs/libcurl/src/easy.c index 001648d49b..6382cee3d5 100644 --- a/libs/libcurl/src/easy.c +++ b/libs/libcurl/src/easy.c @@ -72,7 +72,7 @@ #include "warnless.h" #include "multiif.h" #include "sigpipe.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "setopt.h" #include "http_digest.h" #include "system_win32.h" @@ -157,20 +157,20 @@ static CURLcode global_init(long flags, bool memoryfuncs) if(!Curl_ssl_init()) { DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n")); - return CURLE_FAILED_INIT; + goto fail; } #ifdef WIN32 if(Curl_win32_init(flags)) { DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); - return CURLE_FAILED_INIT; + goto fail; } #endif #ifdef __AMIGA__ if(!Curl_amiga_init()) { DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n")); - return CURLE_FAILED_INIT; + goto fail; } #endif @@ -182,14 +182,14 @@ static CURLcode global_init(long flags, bool memoryfuncs) if(Curl_resolver_global_init()) { DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n")); - return CURLE_FAILED_INIT; + goto fail; } (void)Curl_ipv6works(); #if defined(USE_SSH) if(Curl_ssh_init()) { - return CURLE_FAILED_INIT; + goto fail; } #endif @@ -201,6 +201,10 @@ static CURLcode global_init(long flags, bool memoryfuncs) Curl_version_init(); return CURLE_OK; + + fail: + initialized--; /* undo the increase */ + return CURLE_FAILED_INIT; } @@ -1027,9 +1031,10 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) Curl_update_timer(data->multi); } - /* This transfer may have been moved in or out of the bundle, update - the corresponding socket callback, if used */ - Curl_updatesocket(data); + if(!data->state.done) + /* This transfer may have been moved in or out of the bundle, update the + corresponding socket callback, if used */ + Curl_updatesocket(data); return result; } diff --git a/libs/libcurl/src/easyif.h b/libs/libcurl/src/easyif.h index 6ba7e549d7..8a309c55b6 100644 --- a/libs/libcurl/src/easyif.h +++ b/libs/libcurl/src/easyif.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/file.c b/libs/libcurl/src/file.c index d349cd9241..249237073f 100644 --- a/libs/libcurl/src/file.c +++ b/libs/libcurl/src/file.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 @@ -136,7 +136,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) struct Curl_easy *data = conn->data; char *real_path; struct FILEPROTO *file = data->req.protop; - int fd; + int fd = -1; #ifdef DOS_FILESYSTEM size_t i; char *actual_path; @@ -181,7 +181,9 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) return CURLE_URL_MALFORMAT; } - fd = open_readonly(actual_path, O_RDONLY|O_BINARY); + if(strncmp("\\\\", actual_path, 2)) + /* refuse to open path that starts with two backslashes */ + fd = open_readonly(actual_path, O_RDONLY|O_BINARY); file->path = actual_path; #else if(memchr(real_path, 0, real_path_len)) { diff --git a/libs/libcurl/src/file.h b/libs/libcurl/src/file.h index 20828ad4a9..f6b74a7f72 100644 --- a/libs/libcurl/src/file.h +++ b/libs/libcurl/src/file.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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 8072a33d5d..469096f0f6 100644 --- a/libs/libcurl/src/ftp.c +++ b/libs/libcurl/src/ftp.c @@ -2039,13 +2039,11 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn, &year, &month, &day, &hour, &minute, &second)) { /* we have a time, reformat it */ char timebuf[24]; - time_t secs = time(NULL); - msnprintf(timebuf, sizeof(timebuf), "%04d%02d%02d %02d:%02d:%02d GMT", year, month, day, hour, minute, second); /* now, convert this into a time() value: */ - data->info.filetime = curl_getdate(timebuf, &secs); + data->info.filetime = Curl_getdate_capped(timebuf); } #ifdef CURL_FTP_HTTPSTYLE_HEAD diff --git a/libs/libcurl/src/ftplistparser.h b/libs/libcurl/src/ftplistparser.h index 8128887c0b..b34ae9b63a 100644 --- a/libs/libcurl/src/ftplistparser.h +++ b/libs/libcurl/src/ftplistparser.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/getinfo.h b/libs/libcurl/src/getinfo.h index aecf717f75..8d2af4266d 100644 --- a/libs/libcurl/src/getinfo.h +++ b/libs/libcurl/src/getinfo.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/gopher.h b/libs/libcurl/src/gopher.h index 501c990a85..dec2557fc6 100644 --- a/libs/libcurl/src/gopher.h +++ b/libs/libcurl/src/gopher.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/hostcheck.h b/libs/libcurl/src/hostcheck.h index f562df9ae7..9c180856ad 100644 --- a/libs/libcurl/src/hostcheck.h +++ b/libs/libcurl/src/hostcheck.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/hostip.c b/libs/libcurl/src/hostip.c index d4e8f9366a..b434b390a2 100644 --- a/libs/libcurl/src/hostip.c +++ b/libs/libcurl/src/hostip.c @@ -1021,6 +1021,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) CURLcode Curl_resolv_check(struct connectdata *conn, struct Curl_dns_entry **dns) { +#if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH) + (void)dns; +#endif + if(conn->data->set.doh) return Curl_doh_is_resolved(conn, dns); return Curl_resolver_is_resolved(conn, dns); diff --git a/libs/libcurl/src/hostip4.c b/libs/libcurl/src/hostip4.c index e6ba710d83..2636851e68 100644 --- a/libs/libcurl/src/hostip4.c +++ b/libs/libcurl/src/hostip4.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -131,6 +131,16 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, 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); diff --git a/libs/libcurl/src/hostsyn.c b/libs/libcurl/src/hostsyn.c index 3de6746f52..9e31008d2c 100644 --- a/libs/libcurl/src/hostsyn.c +++ b/libs/libcurl/src/hostsyn.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/http.c b/libs/libcurl/src/http.c index 4631a7f36b..837f53c415 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.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 @@ -641,7 +641,7 @@ output_auth_headers(struct connectdata *conn, { const char *auth = NULL; CURLcode result = CURLE_OK; -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO) +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) struct Curl_easy *data = conn->data; #endif @@ -1617,7 +1617,8 @@ CURLcode Curl_http_done(struct connectdata *conn, Curl_add_buffer_free(&http->send_buffer); } - Curl_http2_done(conn, premature); + Curl_http2_done(data, premature); + Curl_quic_done(data, premature); Curl_mime_cleanpart(&http->form); @@ -3973,7 +3974,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, else if(checkprefix("Retry-After:", k->p)) { /* Retry-After = HTTP-date / delay-seconds */ curl_off_t retry_after = 0; /* zero for unknown or "now" */ - time_t date = curl_getdate(&k->p[12], NULL); + time_t date = Curl_getdate_capped(&k->p[12]); if(-1 == date) { /* not a date, try it as a decimal number */ (void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after); @@ -4031,9 +4032,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, #endif else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) && (data->set.timecondition || data->set.get_filetime) ) { - time_t secs = time(NULL); - k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"), - &secs); + k->timeofdoc = Curl_getdate_capped(k->p + strlen("Last-Modified:")); if(data->set.get_filetime) data->info.filetime = k->timeofdoc; } diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h index a3a2757025..70d5dccec6 100644 --- a/libs/libcurl/src/http.h +++ b/libs/libcurl/src/http.h @@ -193,12 +193,17 @@ struct HTTP { #ifdef ENABLE_QUIC /*********** for HTTP/3 we store stream-local data here *************/ int64_t stream3_id; /* stream we are interested in */ + bool firstheader; /* FALSE until headers arrive */ bool firstbody; /* FALSE until body arrives */ bool h3req; /* FALSE until request is issued */ bool upload_done; #endif #ifdef USE_NGHTTP3 + size_t unacked_window; struct h3out *h3out; /* per-stream buffers for upload */ + char *overflow_buf; /* excess data received during a single Curl_read */ + size_t overflow_buflen; /* amount of data currently in overflow_buf */ + size_t overflow_bufsize; /* size of the overflow_buf allocation */ #endif }; diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index 6315fc4014..65f3513ee5 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -68,7 +68,7 @@ #ifdef DEBUG_HTTP2 #define H2BUGF(x) x #else -#define H2BUGF(x) do { } WHILE_FALSE +#define H2BUGF(x) do { } while(0) #endif @@ -1169,11 +1169,10 @@ static void populate_settings(struct connectdata *conn, httpc->local_settings_num = 3; } -void Curl_http2_done(struct connectdata *conn, bool premature) +void Curl_http2_done(struct Curl_easy *data, bool premature) { - struct Curl_easy *data = conn->data; struct HTTP *http = data->req.protop; - struct http_conn *httpc = &conn->proto.httpc; + struct http_conn *httpc = &data->conn->proto.httpc; /* there might be allocated resources done before this got the 'h2' pointer setup */ diff --git a/libs/libcurl/src/http2.h b/libs/libcurl/src/http2.h index 93058ccb31..12d36eef9b 100644 --- a/libs/libcurl/src/http2.h +++ b/libs/libcurl/src/http2.h @@ -50,7 +50,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn, /* called from http_setup_conn */ void Curl_http2_setup_conn(struct connectdata *conn); void Curl_http2_setup_req(struct Curl_easy *data); -void Curl_http2_done(struct connectdata *conn, bool premature); +void Curl_http2_done(struct Curl_easy *data, bool premature); CURLcode Curl_http2_done_sending(struct connectdata *conn); CURLcode Curl_http2_add_child(struct Curl_easy *parent, struct Curl_easy *child, diff --git a/libs/libcurl/src/http_ntlm.c b/libs/libcurl/src/http_ntlm.c index e4a4fe05d0..342b2424f3 100644 --- a/libs/libcurl/src/http_ntlm.c +++ b/libs/libcurl/src/http_ntlm.c @@ -44,9 +44,7 @@ /* SSL backend-specific #if branches in this file must be kept in the order documented in curl_ntlm_core. */ -#if defined(NTLM_NEEDS_NSS_INIT) -#include "vtls/nssg.h" -#elif defined(USE_WINDOWS_SSPI) +#if defined(USE_WINDOWS_SSPI) #include "curl_sspi.h" #endif @@ -137,11 +135,6 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) DEBUGASSERT(conn); DEBUGASSERT(conn->data); -#if defined(NTLM_NEEDS_NSS_INIT) - if(CURLE_OK != Curl_nss_force_init(conn->data)) - return CURLE_OUT_OF_MEMORY; -#endif - if(proxy) { allocuserpwd = &conn->allocptr.proxyuserpwd; userp = conn->http_proxy.user; diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c index f095455a51..75c7a60c35 100644 --- a/libs/libcurl/src/http_proxy.c +++ b/libs/libcurl/src/http_proxy.c @@ -58,8 +58,9 @@ static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex) Curl_ssl_connect_nonblocking(conn, sockindex, &conn->bits.proxy_ssl_connected[sockindex]); if(result) - conn->bits.close = TRUE; /* a failed connection is marked for closure to - prevent (bad) re-use or similar */ + /* a failed connection is marked for closure to prevent (bad) re-use or + similar */ + connclose(conn, "TLS handshake failed"); } return result; #else diff --git a/libs/libcurl/src/imap.h b/libs/libcurl/src/imap.h index 0efcfd293c..4786f56241 100644 --- a/libs/libcurl/src/imap.h +++ b/libs/libcurl/src/imap.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2009 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/inet_ntop.c b/libs/libcurl/src/inet_ntop.c index 855981c666..9a5af7f421 100644 --- a/libs/libcurl/src/inet_ntop.c +++ b/libs/libcurl/src/inet_ntop.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1996-2001 Internet Software Consortium. + * Copyright (C) 1996-2019 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/libcurl/src/inet_ntop.h b/libs/libcurl/src/inet_ntop.h index d150bb6937..9d3f237f37 100644 --- a/libs/libcurl/src/inet_ntop.h +++ b/libs/libcurl/src/inet_ntop.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/inet_pton.c b/libs/libcurl/src/inet_pton.c index 0d65ae0ec7..9c87a05620 100644 --- a/libs/libcurl/src/inet_pton.c +++ b/libs/libcurl/src/inet_pton.c @@ -1,6 +1,6 @@ /* This is from the BIND 4.9.4 release, modified to compile by itself */ -/* Copyright (c) 1996 by Internet Software Consortium. +/* Copyright (c) 1996 - 2019 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/libcurl/src/inet_pton.h b/libs/libcurl/src/inet_pton.h index 0209b9b7b7..e695af9c66 100644 --- a/libs/libcurl/src/inet_pton.h +++ b/libs/libcurl/src/inet_pton.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/krb5.c b/libs/libcurl/src/krb5.c index 5a47d481b4..f50287aec6 100644 --- a/libs/libcurl/src/krb5.c +++ b/libs/libcurl/src/krb5.c @@ -2,7 +2,7 @@ * * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). - * Copyright (c) 2004 - 2017 Daniel Stenberg + * Copyright (c) 2004 - 2019 Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c index af3d61c57e..771edb4e98 100644 --- a/libs/libcurl/src/ldap.c +++ b/libs/libcurl/src/ldap.c @@ -112,7 +112,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp); #define LDAP_TRACE(x) do { \ _ldap_trace("%u: ", __LINE__); \ _ldap_trace x; \ - } WHILE_FALSE + } while(0) static void _ldap_trace(const char *fmt, ...); #else diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index 55c2ed494d..236ec4279b 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.67.0</string> + <string>7.68.0</string> <key>CFBundleName</key> <string>libcurl</string> @@ -27,9 +27,9 @@ <string>????</string> <key>CFBundleShortVersionString</key> - <string>libcurl 7.67.0</string> + <string>libcurl 7.68.0</string> <key>CFBundleGetInfoString</key> - <string>libcurl.plist 7.67.0</string> + <string>libcurl.plist 7.68.0</string> </dict> </plist> diff --git a/libs/libcurl/src/llist.h b/libs/libcurl/src/llist.h index b9d4c89a98..a5e2ecbfb4 100644 --- a/libs/libcurl/src/llist.h +++ b/libs/libcurl/src/llist.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/memdebug.h b/libs/libcurl/src/memdebug.h index 5236f60fa5..7ca4426269 100644 --- a/libs/libcurl/src/memdebug.h +++ b/libs/libcurl/src/memdebug.h @@ -169,6 +169,6 @@ CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); */ #define Curl_safefree(ptr) \ - do { free((ptr)); (ptr) = NULL;} WHILE_FALSE + do { free((ptr)); (ptr) = NULL;} while(0) #endif /* HEADER_CURL_MEMDEBUG_H */ diff --git a/libs/libcurl/src/mprintf.c b/libs/libcurl/src/mprintf.c index e190936782..bc0091351d 100644 --- a/libs/libcurl/src/mprintf.c +++ b/libs/libcurl/src/mprintf.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1999 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1999 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -104,7 +104,7 @@ static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; done++; \ else \ return done; /* return immediately on failure */ \ - } WHILE_FALSE + } while(0) /* Data type to read from the arglist */ typedef enum { diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index 6dfe8842e7..6d819b4aaa 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -46,6 +46,7 @@ #include "connect.h" #include "http_proxy.h" #include "http2.h" +#include "socketpair.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -259,6 +260,7 @@ static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh, /* make/add new hash entry */ if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) { + Curl_hash_destroy(&check->transfers); free(check); return NULL; /* major failure */ } @@ -367,6 +369,21 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ /* -1 means it not set by user, use the default value */ multi->maxconnects = -1; + +#ifdef ENABLE_WAKEUP + if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) { + multi->wakeup_pair[0] = CURL_SOCKET_BAD; + multi->wakeup_pair[1] = CURL_SOCKET_BAD; + } + else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 || + curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) { + sclose(multi->wakeup_pair[0]); + sclose(multi->wakeup_pair[1]); + multi->wakeup_pair[0] = CURL_SOCKET_BAD; + multi->wakeup_pair[1] = CURL_SOCKET_BAD; + } +#endif + return multi; error: @@ -531,6 +548,8 @@ static CURLcode multi_done(struct Curl_easy *data, /* Stop if multi_done() has already been called */ return CURLE_OK; + conn->data = data; /* ensure the connection uses this transfer now */ + /* Stop the resolver and free its own resources (but not dns_entry yet). */ Curl_resolver_kill(conn); @@ -567,15 +586,17 @@ static CURLcode multi_done(struct Curl_easy *data, process_pending_handles(data->multi); /* connection / multiplex */ + CONN_LOCK(data); detach_connnection(data); if(CONN_INUSE(conn)) { /* Stop if still used. */ + CONN_UNLOCK(data); DEBUGF(infof(data, "Connection still in use %zu, " "no more multi_done now!\n", conn->easyq.size)); return CURLE_OK; } - + conn->data = NULL; /* the connection now has no owner */ data->state.done = TRUE; /* called just now! */ if(conn->dns_entry) { @@ -618,7 +639,10 @@ static CURLcode multi_done(struct Curl_easy *data, #endif ) || conn->bits.close || (premature && !(conn->handler->flags & PROTOPT_STREAM))) { - CURLcode res2 = Curl_disconnect(data, conn, premature); + CURLcode res2; + connclose(conn, "disconnecting"); + CONN_UNLOCK(data); + res2 = Curl_disconnect(data, conn, premature); /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ @@ -635,9 +659,9 @@ static CURLcode multi_done(struct Curl_easy *data, conn->bits.httpproxy ? conn->http_proxy.host.dispname : conn->bits.conn_to_host ? conn->conn_to_host.dispname : conn->host.dispname); - /* the connection is no longer in use by this transfer */ - if(Curl_conncache_return_conn(conn)) { + CONN_UNLOCK(data); + if(Curl_conncache_return_conn(data, conn)) { /* remember the most recently used connection */ data->state.lastconnect = conn; infof(data, "%s\n", buffer); @@ -695,11 +719,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, easy_owns_conn = TRUE; } - /* The timer must be shut down before data->multi is set to NULL, - else the timenode will remain in the splay tree after - curl_easy_cleanup is called. */ - Curl_expire_clear(data); - if(data->conn) { /* we must call multi_done() here (if we still own the connection) so that @@ -715,6 +734,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, } } + /* The timer must be shut down before data->multi is set to NULL, else the + timenode will remain in the splay tree after curl_easy_cleanup is + called. Do it after multi_done() in case that sets another time! */ + Curl_expire_clear(data); + if(data->connect_queue.ptr) /* the handle was in the pending list waiting for an available connection, so go ahead and remove it */ @@ -744,10 +768,8 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, vanish with this handle */ /* Remove the association between the connection and the handle */ - if(data->conn) { - data->conn->data = NULL; + if(data->conn) detach_connnection(data); - } #ifdef USE_LIBPSL /* Remove the PSL association. */ @@ -1005,7 +1027,8 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, unsigned int extra_nfds, int timeout_ms, int *ret, - bool extrawait) /* when no socket, wait */ + bool extrawait, /* when no socket, wait */ + bool use_wakeup) { struct Curl_easy *data; curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; @@ -1059,6 +1082,12 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, curlfds = nfds; /* number of internal file descriptors */ nfds += extra_nfds; /* add the externally provided ones */ +#ifdef ENABLE_WAKEUP + if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { + ++nfds; + } +#endif + if(nfds > NUM_POLLS_ON_STACK) { /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes big, so at 2^29 sockets this value might wrap. When a process gets @@ -1117,6 +1146,14 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, ++nfds; } +#ifdef ENABLE_WAKEUP + if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { + ufds[nfds].fd = multi->wakeup_pair[0]; + ufds[nfds].events = POLLIN; + ++nfds; + } +#endif + if(nfds) { int pollrc; /* wait... */ @@ -1140,6 +1177,29 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, extra_fds[i].revents = mask; } + +#ifdef ENABLE_WAKEUP + if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { + if(ufds[curlfds + extra_nfds].revents & POLLIN) { + char buf[64]; + while(1) { + /* the reading socket is non-blocking, try to read + 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) { +#ifndef USE_WINSOCK + if(EINTR == SOCKERRNO) + continue; +#endif + break; + } + } + /* do not count the wakeup socket into the returned value */ + retcode--; + } + } +#endif } } @@ -1147,7 +1207,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, free(ufds); if(ret) *ret = retcode; - if(!extrawait || extra_fds || curlfds) + if(!extrawait || nfds) /* if any socket was checked */ ; else { @@ -1157,6 +1217,10 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) { if(sleep_ms > timeout_ms) sleep_ms = timeout_ms; + /* when there are no easy handles in the multi, this holds a -1 + timeout */ + else if((sleep_ms < 0) && extrawait) + sleep_ms = timeout_ms; Curl_wait_ms((int)sleep_ms); } } @@ -1170,7 +1234,8 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi, int timeout_ms, int *ret) { - return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE); + return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE, + FALSE); } CURLMcode curl_multi_poll(struct Curl_multi *multi, @@ -1179,7 +1244,55 @@ CURLMcode curl_multi_poll(struct Curl_multi *multi, int timeout_ms, int *ret) { - return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE); + return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE, + TRUE); +} + +CURLMcode curl_multi_wakeup(struct Curl_multi *multi) +{ + /* this function is usually called from another thread, + it has to be careful only to access parts of the + Curl_multi struct that are constant */ + + /* GOOD_MULTI_HANDLE can be safely called */ + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + +#ifdef ENABLE_WAKEUP + /* the wakeup_pair variable is only written during init and cleanup, + making it safe to access from another thread after the init part + and before cleanup */ + if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) { + char buf[1]; + buf[0] = 1; + while(1) { + /* swrite() is not thread-safe in general, because concurrent calls + can have their messages interleaved, but in this case the content + of the messages does not matter, which makes it ok to call. + + The write socket is set to non-blocking, this way this function + cannot block, making it safe to call even from the same thread + that will call Curl_multi_wait(). If swrite() returns that it + would block, it's considered successful because it means that + previous calls to this function will wake up the poll(). */ + if(swrite(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) { + int err = SOCKERRNO; + int return_success; +#ifdef USE_WINSOCK + return_success = WSAEWOULDBLOCK == err; +#else + if(EINTR == err) + continue; + return_success = EWOULDBLOCK == err || EAGAIN == err; +#endif + if(!return_success) + return CURLM_WAKEUP_FAILURE; + } + return CURLM_OK; + } + } +#endif + return CURLM_WAKEUP_FAILURE; } /* @@ -1242,6 +1355,7 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done) DEBUGASSERT(conn); DEBUGASSERT(conn->handler); + DEBUGASSERT(conn->data == data); if(conn->handler->do_it) { /* generic protocol-specific function pointer set in curl_connect() */ @@ -2305,6 +2419,11 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) Curl_hash_destroy(&multi->hostcache); Curl_psl_destroy(&multi->psl); + +#ifdef ENABLE_WAKEUP + sclose(multi->wakeup_pair[0]); + sclose(multi->wakeup_pair[1]); +#endif free(multi); return CURLM_OK; diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h index b65bd96386..0bf09e6bb5 100644 --- a/libs/libcurl/src/multihandle.h +++ b/libs/libcurl/src/multihandle.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,6 +24,7 @@ #include "conncache.h" #include "psl.h" +#include "socketpair.h" struct Curl_message { struct curl_llist_element list; @@ -66,6 +67,14 @@ typedef enum { #define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) +#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS) +#define ENABLE_WAKEUP +#endif + + +/* value for MAXIMUM CONCURRENT STREAMS upper limit */ +#define INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1) + /* This is the struct known as CURLM on the outside */ struct Curl_multi { /* First a simple identifier to easier detect if a user mix up @@ -134,6 +143,11 @@ struct Curl_multi { previous callback */ bool in_callback; /* true while executing a callback */ long max_concurrent_streams; /* max concurrent streams client to support */ + +#ifdef ENABLE_WAKEUP + curl_socket_t wakeup_pair[2]; /* socketpair() used for wakeup + 0 is used for read, 1 is used for write */ +#endif }; #endif /* HEADER_CURL_MULTIHANDLE_H */ diff --git a/libs/libcurl/src/nonblock.c b/libs/libcurl/src/nonblock.c index 4d105c1fea..abeb6598c2 100644 --- a/libs/libcurl/src/nonblock.c +++ b/libs/libcurl/src/nonblock.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/nonblock.h b/libs/libcurl/src/nonblock.h index eb18ea1c34..d50d315944 100644 --- a/libs/libcurl/src/nonblock.h +++ b/libs/libcurl/src/nonblock.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/parsedate.c b/libs/libcurl/src/parsedate.c index f4b18d091a..585d7ea404 100644 --- a/libs/libcurl/src/parsedate.c +++ b/libs/libcurl/src/parsedate.c @@ -587,6 +587,30 @@ time_t curl_getdate(const char *p, const time_t *now) return -1; } +/* Curl_getdate_capped() differs from curl_getdate() in that this will return + TIME_T_MAX in case the parsed time value was too big, instead of an + error. */ + +time_t Curl_getdate_capped(const char *p) +{ + time_t parsed = -1; + int rc = parsedate(p, &parsed); + + switch(rc) { + case PARSEDATE_OK: + if(parsed == -1) + /* avoid returning -1 for a working scenario */ + parsed++; + return parsed; + case PARSEDATE_LATER: + /* this returns the maximum time value */ + return parsed; + default: + return -1; /* everything else is fail */ + } + /* UNREACHABLE */ +} + /* * Curl_gmtime() is a gmtime() replacement for portability. Do not use the * gmtime_r() or gmtime() functions anywhere else but here. diff --git a/libs/libcurl/src/parsedate.h b/libs/libcurl/src/parsedate.h index 8dc3b90ec7..8c7ae94e43 100644 --- a/libs/libcurl/src/parsedate.h +++ b/libs/libcurl/src/parsedate.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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,4 +27,10 @@ extern const char * const Curl_month[12]; CURLcode Curl_gmtime(time_t intime, struct tm *store); +/* Curl_getdate_capped() differs from curl_getdate() in that this will return + TIME_T_MAX in case the parsed time value was too big, instead of an + error. */ + +time_t Curl_getdate_capped(const char *p); + #endif /* HEADER_CURL_PARSEDATE_H */ diff --git a/libs/libcurl/src/pop3.h b/libs/libcurl/src/pop3.h index a8e697cde2..3ba7999771 100644 --- a/libs/libcurl/src/pop3.h +++ b/libs/libcurl/src/pop3.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/progress.c b/libs/libcurl/src/progress.c index 2aa9295993..60a941ab2d 100644 --- a/libs/libcurl/src/progress.c +++ b/libs/libcurl/src/progress.c @@ -594,11 +594,13 @@ int Curl_pgrsUpdate(struct connectdata *conn) data->progress.size_ul, data->progress.uploaded); Curl_set_in_callback(data, false); - if(result) - failf(data, "Callback aborted"); - return result; + if(result != CURL_PROGRESSFUNC_CONTINUE) { + if(result) + failf(data, "Callback aborted"); + return result; + } } - if(data->set.fprogress) { + else if(data->set.fprogress) { int result; /* The older deprecated callback is set, call that */ Curl_set_in_callback(data, true); @@ -608,9 +610,11 @@ int Curl_pgrsUpdate(struct connectdata *conn) (double)data->progress.size_ul, (double)data->progress.uploaded); Curl_set_in_callback(data, false); - if(result) - failf(data, "Callback aborted"); - return result; + if(result != CURL_PROGRESSFUNC_CONTINUE) { + if(result) + failf(data, "Callback aborted"); + return result; + } } if(showprogress) diff --git a/libs/libcurl/src/quic.h b/libs/libcurl/src/quic.h index 6c132a3247..1eb23e9766 100644 --- a/libs/libcurl/src/quic.h +++ b/libs/libcurl/src/quic.h @@ -45,9 +45,13 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn, bool *connected); int Curl_quic_ver(char *p, size_t len); CURLcode Curl_quic_done_sending(struct connectdata *conn); +void Curl_quic_done(struct Curl_easy *data, bool premature); +bool Curl_quic_data_pending(const struct Curl_easy *data); #else /* ENABLE_QUIC */ #define Curl_quic_done_sending(x) +#define Curl_quic_done(x,y) +#define Curl_quic_data_pending(x) #endif /* !ENABLE_QUIC */ #endif /* HEADER_CURL_QUIC_H */ diff --git a/libs/libcurl/src/rtsp.h b/libs/libcurl/src/rtsp.h index 2f9cc32c8e..1aae86456d 100644 --- a/libs/libcurl/src/rtsp.h +++ b/libs/libcurl/src/rtsp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/select.c b/libs/libcurl/src/select.c index 8cd9eb2add..2de503d370 100644 --- a/libs/libcurl/src/select.c +++ b/libs/libcurl/src/select.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/select.h b/libs/libcurl/src/select.h index f5652a74f7..687ab164c4 100644 --- a/libs/libcurl/src/select.h +++ b/libs/libcurl/src/select.h @@ -109,7 +109,7 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, SET_SOCKERRNO(EINVAL); \ return -1; \ } \ -} WHILE_FALSE +} while(0) #endif #endif /* HEADER_CURL_SELECT_H */ diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index 5913ea4060..6c38b04b23 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -36,7 +36,7 @@ #include "sendf.h" #include "connect.h" #include "vtls/vtls.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "easyif.h" #include "multiif.h" #include "non-ascii.h" @@ -224,7 +224,7 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex) (void)sockindex; return false; } -#define pre_receive_plain(c,n) do {} WHILE_FALSE +#define pre_receive_plain(c,n) do {} while(0) #define get_pre_recved(c,n,b,l) 0 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index 64c29e3336..5f88ad3afd 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -2133,6 +2133,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.ssl.enable_beast = (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); + data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); break; #ifndef CURL_DISABLE_PROXY @@ -2141,6 +2142,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.proxy_ssl.enable_beast = (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); + data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); break; #endif @@ -2612,14 +2614,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = CURLE_NOT_BUILT_IN; #endif break; -#ifdef USE_NGHTTP2 case CURLOPT_SSL_ENABLE_NPN: data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE; break; case CURLOPT_SSL_ENABLE_ALPN: data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE; break; -#endif #ifdef USE_UNIX_SOCKETS case CURLOPT_UNIX_SOCKET_PATH: data->set.abstract_unix_socket = FALSE; diff --git a/libs/libcurl/src/sha256.c b/libs/libcurl/src/sha256.c index f9287af232..bcaaeae308 100644 --- a/libs/libcurl/src/sha256.c +++ b/libs/libcurl/src/sha256.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Florin Petriuc, <petriuc.florin@gmail.com> + * Copyright (C) 1998 - 2019, Florin Petriuc, <petriuc.florin@gmail.com> * * 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/slist.c b/libs/libcurl/src/slist.c index 392b84d13a..d27fbe19bc 100644 --- a/libs/libcurl/src/slist.c +++ b/libs/libcurl/src/slist.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/slist.h b/libs/libcurl/src/slist.h index d73dbf672d..799b3c060f 100644 --- a/libs/libcurl/src/slist.h +++ b/libs/libcurl/src/slist.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/smtp.h b/libs/libcurl/src/smtp.h index b67340a40c..20fc081190 100644 --- a/libs/libcurl/src/smtp.h +++ b/libs/libcurl/src/smtp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/sockaddr.h b/libs/libcurl/src/sockaddr.h index db146803ab..b037ee06c2 100644 --- a/libs/libcurl/src/sockaddr.h +++ b/libs/libcurl/src/sockaddr.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/socketpair.c b/libs/libcurl/src/socketpair.c index 1f0e2e4a4f..1ec0d75a46 100644 --- a/libs/libcurl/src/socketpair.c +++ b/libs/libcurl/src/socketpair.c @@ -40,6 +40,9 @@ #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> /* IPPROTO_TCP */ #endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 #endif /* !INADDR_LOOPBACK */ diff --git a/libs/libcurl/src/socks.h b/libs/libcurl/src/socks.h index daa07c1275..3b319a6ef1 100644 --- a/libs/libcurl/src/socks.h +++ b/libs/libcurl/src/socks.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/strdup.c b/libs/libcurl/src/strdup.c index 51e7978b7f..1ab10fd644 100644 --- a/libs/libcurl/src/strdup.c +++ b/libs/libcurl/src/strdup.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/strerror.c b/libs/libcurl/src/strerror.c index d0650d80c5..29df5aa55a 100644 --- a/libs/libcurl/src/strerror.c +++ b/libs/libcurl/src/strerror.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2004 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2004 - 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 @@ -314,6 +314,9 @@ curl_easy_strerror(CURLcode error) case CURLE_AUTH_ERROR: return "An authentication function returned an error"; + case CURLE_HTTP3: + return "HTTP/3 error"; + /* error codes not used by current libcurl */ case CURLE_OBSOLETE20: case CURLE_OBSOLETE24: @@ -386,6 +389,9 @@ curl_multi_strerror(CURLMcode error) case CURLM_RECURSIVE_API_CALL: return "API function called from within callback"; + case CURLM_WAKEUP_FAILURE: + return "Wakeup is unavailable or failed"; + case CURLM_LAST: break; } @@ -436,19 +442,26 @@ curl_share_strerror(CURLSHcode error) } #ifdef USE_WINSOCK - -/* This function handles most / all (?) Winsock errors curl is able to produce. +/* This is a helper function for Curl_strerror that converts Winsock error + * codes (WSAGetLastError) to error messages. + * Returns NULL if no error message was found for error code. */ static const char * get_winsock_error (int err, char *buf, size_t len) { -#ifdef PRESERVE_WINDOWS_ERROR_CODE - DWORD old_win_err = GetLastError(); -#endif - int old_errno = errno; +#ifndef CURL_DISABLE_VERBOSE_STRINGS const char *p; +#endif -#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(!len) + return NULL; + + *buf = '\0'; + +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)err; + return NULL; +#else switch(err) { case WSAEINTR: p = "Call interrupted"; @@ -617,26 +630,63 @@ get_winsock_error (int err, char *buf, size_t len) default: return NULL; } -#else - if(!err) - return NULL; - else - p = "error"; -#endif strncpy(buf, p, len); buf [len-1] = '\0'; + return buf; +#endif +} +#endif /* USE_WINSOCK */ - if(errno != old_errno) - errno = old_errno; +#if defined(WIN32) || defined(_WIN32_WCE) +/* This is a helper function for Curl_strerror that converts Windows API error + * codes (GetLastError) to error messages. + * Returns NULL if no error message was found for error code. + */ +static const char * +get_winapi_error(int err, char *buf, size_t buflen) +{ + char *p; -#ifdef PRESERVE_WINDOWS_ERROR_CODE - if(old_win_err != GetLastError()) - SetLastError(old_win_err); + if(!buflen) + return NULL; + + *buf = '\0'; + +#ifdef _WIN32_WCE + { + wchar_t wbuf[256]; + wbuf[0] = L'\0'; + + if(FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, + LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { + size_t written = wcstombs(buf, wbuf, buflen - 1); + if(written != (size_t)-1) + buf[written] = '\0'; + else + *buf = '\0'; + } + } +#else + if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, + LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) { + *buf = '\0'; + } #endif - return buf; + /* Truncate multiple lines */ + p = strchr(buf, '\n'); + if(p) { + if(p > buf && *(p-1) == '\r') + *(p-1) = '\0'; + else + *p = '\0'; + } + + return (*buf ? buf : NULL); } -#endif /* USE_WINSOCK */ +#endif /* WIN32 || _WIN32_WCE */ /* * Our thread-safe and smart strerror() replacement. @@ -648,6 +698,14 @@ get_winsock_error (int err, char *buf, size_t len) * * We don't do range checking (on systems other than Windows) since there is * no good reliable and portable way to do it. + * + * On Windows different types of error codes overlap. This function has an + * order of preference when trying to match error codes: + * CRT (errno), Winsock (WSAGetLastError), Windows API (GetLastError). + * + * It may be more correct to call one of the variant functions instead: + * Call Curl_sspi_strerror if the error code is definitely Windows SSPI. + * Call Curl_winapi_strerror if the error code is definitely Windows API. */ const char *Curl_strerror(int err, char *buf, size_t buflen) { @@ -658,35 +716,30 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) char *p; size_t max; + if(!buflen) + return NULL; + DEBUGASSERT(err >= 0); max = buflen - 1; *buf = '\0'; -#ifdef USE_WINSOCK - -#ifdef _WIN32_WCE - { - wchar_t wbuf[256]; - wbuf[0] = L'\0'; - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL); - wcstombs(buf, wbuf, max); - } -#else +#if defined(WIN32) || defined(_WIN32_WCE) +#if defined(WIN32) /* 'sys_nerr' is the maximum errno number, it is not widely portable */ if(err >= 0 && err < sys_nerr) strncpy(buf, strerror(err), max); - else { - if(!get_winsock_error(err, buf, max) && - !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - LANG_NEUTRAL, buf, (DWORD)max, NULL)) + else +#endif + { + if( +#ifdef USE_WINSOCK + !get_winsock_error(err, buf, max) && +#endif + !get_winapi_error((DWORD)err, buf, max)) msnprintf(buf, max, "Unknown error %d (%#x)", err, err); } -#endif - -#else /* not USE_WINSOCK coming up */ +#else /* not Windows coming up */ #if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R) /* @@ -734,7 +787,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) } #endif -#endif /* end of ! USE_WINSOCK */ +#endif /* end of not Windows */ buf[max] = '\0'; /* make sure the string is zero terminated */ @@ -757,7 +810,52 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) return buf; } +/* + * Curl_winapi_strerror: + * Variant of Curl_strerror if the error code is definitely Windows API. + */ +#if defined(WIN32) || defined(_WIN32_WCE) +const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen) +{ +#ifdef PRESERVE_WINDOWS_ERROR_CODE + DWORD old_win_err = GetLastError(); +#endif + int old_errno = errno; + + if(!buflen) + return NULL; + + *buf = '\0'; + +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(!get_winapi_error(err, buf, buflen)) { + msnprintf(buf, buflen, "Unknown error %u (0x%08X)", err, err); + } +#else + { + const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error"; + strncpy(buf, txt, buflen); + buf[buflen - 1] = '\0'; + } +#endif + + if(errno != old_errno) + errno = old_errno; + +#ifdef PRESERVE_WINDOWS_ERROR_CODE + if(old_win_err != GetLastError()) + SetLastError(old_win_err); +#endif + + return buf; +} +#endif /* WIN32 || _WIN32_WCE */ + #ifdef USE_WINDOWS_SSPI +/* + * Curl_sspi_strerror: + * Variant of Curl_strerror if the error code is definitely Windows SSPI. + */ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) { #ifdef PRESERVE_WINDOWS_ERROR_CODE @@ -765,18 +863,11 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) #endif int old_errno = errno; const char *txt; - char *outbuf; - size_t outmax; -#ifndef CURL_DISABLE_VERBOSE_STRINGS - char txtbuf[80]; - char msgbuf[256]; - char *p, *str, *msg = NULL; - bool msg_formatted = FALSE; -#endif - outbuf = buf; - outmax = buflen - 1; - *outbuf = '\0'; + if(!buflen) + return NULL; + + *buf = '\0'; #ifndef CURL_DISABLE_VERBOSE_STRINGS @@ -784,314 +875,121 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) case SEC_E_OK: txt = "No error"; break; - case CRYPT_E_REVOKED: - txt = "CRYPT_E_REVOKED"; - break; - case SEC_E_ALGORITHM_MISMATCH: - txt = "SEC_E_ALGORITHM_MISMATCH"; - break; - case SEC_E_BAD_BINDINGS: - txt = "SEC_E_BAD_BINDINGS"; - break; - case SEC_E_BAD_PKGID: - txt = "SEC_E_BAD_PKGID"; - break; - case SEC_E_BUFFER_TOO_SMALL: - txt = "SEC_E_BUFFER_TOO_SMALL"; - break; - case SEC_E_CANNOT_INSTALL: - txt = "SEC_E_CANNOT_INSTALL"; - break; - case SEC_E_CANNOT_PACK: - txt = "SEC_E_CANNOT_PACK"; - break; - case SEC_E_CERT_EXPIRED: - txt = "SEC_E_CERT_EXPIRED"; - break; - case SEC_E_CERT_UNKNOWN: - txt = "SEC_E_CERT_UNKNOWN"; - break; - case SEC_E_CERT_WRONG_USAGE: - txt = "SEC_E_CERT_WRONG_USAGE"; - break; - case SEC_E_CONTEXT_EXPIRED: - txt = "SEC_E_CONTEXT_EXPIRED"; - break; - case SEC_E_CROSSREALM_DELEGATION_FAILURE: - txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE"; - break; - case SEC_E_CRYPTO_SYSTEM_INVALID: - txt = "SEC_E_CRYPTO_SYSTEM_INVALID"; - break; - case SEC_E_DECRYPT_FAILURE: - txt = "SEC_E_DECRYPT_FAILURE"; - break; - case SEC_E_DELEGATION_POLICY: - txt = "SEC_E_DELEGATION_POLICY"; - break; - case SEC_E_DELEGATION_REQUIRED: - txt = "SEC_E_DELEGATION_REQUIRED"; - break; - case SEC_E_DOWNGRADE_DETECTED: - txt = "SEC_E_DOWNGRADE_DETECTED"; - break; - case SEC_E_ENCRYPT_FAILURE: - txt = "SEC_E_ENCRYPT_FAILURE"; - break; - case SEC_E_ILLEGAL_MESSAGE: - txt = "SEC_E_ILLEGAL_MESSAGE"; - break; - case SEC_E_INCOMPLETE_CREDENTIALS: - txt = "SEC_E_INCOMPLETE_CREDENTIALS"; - break; - case SEC_E_INCOMPLETE_MESSAGE: - txt = "SEC_E_INCOMPLETE_MESSAGE"; - break; - case SEC_E_INSUFFICIENT_MEMORY: - txt = "SEC_E_INSUFFICIENT_MEMORY"; - break; - case SEC_E_INTERNAL_ERROR: - txt = "SEC_E_INTERNAL_ERROR"; - break; - case SEC_E_INVALID_HANDLE: - txt = "SEC_E_INVALID_HANDLE"; - break; - case SEC_E_INVALID_PARAMETER: - txt = "SEC_E_INVALID_PARAMETER"; - break; - case SEC_E_INVALID_TOKEN: - txt = "SEC_E_INVALID_TOKEN"; - break; - case SEC_E_ISSUING_CA_UNTRUSTED: - txt = "SEC_E_ISSUING_CA_UNTRUSTED"; - break; - case SEC_E_ISSUING_CA_UNTRUSTED_KDC: - txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC"; - break; - case SEC_E_KDC_CERT_EXPIRED: - txt = "SEC_E_KDC_CERT_EXPIRED"; - break; - case SEC_E_KDC_CERT_REVOKED: - txt = "SEC_E_KDC_CERT_REVOKED"; - break; - case SEC_E_KDC_INVALID_REQUEST: - txt = "SEC_E_KDC_INVALID_REQUEST"; - break; - case SEC_E_KDC_UNABLE_TO_REFER: - txt = "SEC_E_KDC_UNABLE_TO_REFER"; - break; - case SEC_E_KDC_UNKNOWN_ETYPE: - txt = "SEC_E_KDC_UNKNOWN_ETYPE"; - break; - case SEC_E_LOGON_DENIED: - txt = "SEC_E_LOGON_DENIED"; - break; - case SEC_E_MAX_REFERRALS_EXCEEDED: - txt = "SEC_E_MAX_REFERRALS_EXCEEDED"; - break; - case SEC_E_MESSAGE_ALTERED: - txt = "SEC_E_MESSAGE_ALTERED"; - break; - case SEC_E_MULTIPLE_ACCOUNTS: - txt = "SEC_E_MULTIPLE_ACCOUNTS"; - break; - case SEC_E_MUST_BE_KDC: - txt = "SEC_E_MUST_BE_KDC"; - break; - case SEC_E_NOT_OWNER: - txt = "SEC_E_NOT_OWNER"; - break; - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY"; - break; - case SEC_E_NO_CREDENTIALS: - txt = "SEC_E_NO_CREDENTIALS"; - break; - case SEC_E_NO_IMPERSONATION: - txt = "SEC_E_NO_IMPERSONATION"; - break; - case SEC_E_NO_IP_ADDRESSES: - txt = "SEC_E_NO_IP_ADDRESSES"; - break; - case SEC_E_NO_KERB_KEY: - txt = "SEC_E_NO_KERB_KEY"; - break; - case SEC_E_NO_PA_DATA: - txt = "SEC_E_NO_PA_DATA"; - break; - case SEC_E_NO_S4U_PROT_SUPPORT: - txt = "SEC_E_NO_S4U_PROT_SUPPORT"; - break; - case SEC_E_NO_TGT_REPLY: - txt = "SEC_E_NO_TGT_REPLY"; - break; - case SEC_E_OUT_OF_SEQUENCE: - txt = "SEC_E_OUT_OF_SEQUENCE"; - break; - case SEC_E_PKINIT_CLIENT_FAILURE: - txt = "SEC_E_PKINIT_CLIENT_FAILURE"; - break; - case SEC_E_PKINIT_NAME_MISMATCH: - txt = "SEC_E_PKINIT_NAME_MISMATCH"; - break; - case SEC_E_POLICY_NLTM_ONLY: - txt = "SEC_E_POLICY_NLTM_ONLY"; - break; - case SEC_E_QOP_NOT_SUPPORTED: - txt = "SEC_E_QOP_NOT_SUPPORTED"; - break; - case SEC_E_REVOCATION_OFFLINE_C: - txt = "SEC_E_REVOCATION_OFFLINE_C"; - break; - case SEC_E_REVOCATION_OFFLINE_KDC: - txt = "SEC_E_REVOCATION_OFFLINE_KDC"; - break; - case SEC_E_SECPKG_NOT_FOUND: - txt = "SEC_E_SECPKG_NOT_FOUND"; - break; - case SEC_E_SECURITY_QOS_FAILED: - txt = "SEC_E_SECURITY_QOS_FAILED"; - break; - case SEC_E_SHUTDOWN_IN_PROGRESS: - txt = "SEC_E_SHUTDOWN_IN_PROGRESS"; - break; - case SEC_E_SMARTCARD_CERT_EXPIRED: - txt = "SEC_E_SMARTCARD_CERT_EXPIRED"; - break; - case SEC_E_SMARTCARD_CERT_REVOKED: - txt = "SEC_E_SMARTCARD_CERT_REVOKED"; - break; - case SEC_E_SMARTCARD_LOGON_REQUIRED: - txt = "SEC_E_SMARTCARD_LOGON_REQUIRED"; - break; - case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED: - txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED"; - break; - case SEC_E_TARGET_UNKNOWN: - txt = "SEC_E_TARGET_UNKNOWN"; - break; - case SEC_E_TIME_SKEW: - txt = "SEC_E_TIME_SKEW"; - break; - case SEC_E_TOO_MANY_PRINCIPALS: - txt = "SEC_E_TOO_MANY_PRINCIPALS"; - break; - case SEC_E_UNFINISHED_CONTEXT_DELETED: - txt = "SEC_E_UNFINISHED_CONTEXT_DELETED"; - break; - case SEC_E_UNKNOWN_CREDENTIALS: - txt = "SEC_E_UNKNOWN_CREDENTIALS"; - break; - case SEC_E_UNSUPPORTED_FUNCTION: - txt = "SEC_E_UNSUPPORTED_FUNCTION"; - break; - case SEC_E_UNSUPPORTED_PREAUTH: - txt = "SEC_E_UNSUPPORTED_PREAUTH"; - break; - case SEC_E_UNTRUSTED_ROOT: - txt = "SEC_E_UNTRUSTED_ROOT"; - break; - case SEC_E_WRONG_CREDENTIAL_HANDLE: - txt = "SEC_E_WRONG_CREDENTIAL_HANDLE"; - break; - case SEC_E_WRONG_PRINCIPAL: - txt = "SEC_E_WRONG_PRINCIPAL"; - break; - case SEC_I_COMPLETE_AND_CONTINUE: - txt = "SEC_I_COMPLETE_AND_CONTINUE"; - break; - case SEC_I_COMPLETE_NEEDED: - txt = "SEC_I_COMPLETE_NEEDED"; - break; - case SEC_I_CONTEXT_EXPIRED: - txt = "SEC_I_CONTEXT_EXPIRED"; - break; - case SEC_I_CONTINUE_NEEDED: - txt = "SEC_I_CONTINUE_NEEDED"; - break; - case SEC_I_INCOMPLETE_CREDENTIALS: - txt = "SEC_I_INCOMPLETE_CREDENTIALS"; - break; - case SEC_I_LOCAL_LOGON: - txt = "SEC_I_LOCAL_LOGON"; - break; - case SEC_I_NO_LSA_CONTEXT: - txt = "SEC_I_NO_LSA_CONTEXT"; - break; - case SEC_I_RENEGOTIATE: - txt = "SEC_I_RENEGOTIATE"; - break; - case SEC_I_SIGNATURE_NEEDED: - txt = "SEC_I_SIGNATURE_NEEDED"; - break; +#define SEC2TXT(sec) case sec: txt = #sec; break + SEC2TXT(CRYPT_E_REVOKED); + SEC2TXT(SEC_E_ALGORITHM_MISMATCH); + SEC2TXT(SEC_E_BAD_BINDINGS); + SEC2TXT(SEC_E_BAD_PKGID); + SEC2TXT(SEC_E_BUFFER_TOO_SMALL); + SEC2TXT(SEC_E_CANNOT_INSTALL); + SEC2TXT(SEC_E_CANNOT_PACK); + SEC2TXT(SEC_E_CERT_EXPIRED); + SEC2TXT(SEC_E_CERT_UNKNOWN); + SEC2TXT(SEC_E_CERT_WRONG_USAGE); + SEC2TXT(SEC_E_CONTEXT_EXPIRED); + SEC2TXT(SEC_E_CROSSREALM_DELEGATION_FAILURE); + SEC2TXT(SEC_E_CRYPTO_SYSTEM_INVALID); + SEC2TXT(SEC_E_DECRYPT_FAILURE); + SEC2TXT(SEC_E_DELEGATION_POLICY); + SEC2TXT(SEC_E_DELEGATION_REQUIRED); + SEC2TXT(SEC_E_DOWNGRADE_DETECTED); + SEC2TXT(SEC_E_ENCRYPT_FAILURE); + SEC2TXT(SEC_E_ILLEGAL_MESSAGE); + SEC2TXT(SEC_E_INCOMPLETE_CREDENTIALS); + SEC2TXT(SEC_E_INCOMPLETE_MESSAGE); + SEC2TXT(SEC_E_INSUFFICIENT_MEMORY); + SEC2TXT(SEC_E_INTERNAL_ERROR); + SEC2TXT(SEC_E_INVALID_HANDLE); + SEC2TXT(SEC_E_INVALID_PARAMETER); + SEC2TXT(SEC_E_INVALID_TOKEN); + SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED); + SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED_KDC); + SEC2TXT(SEC_E_KDC_CERT_EXPIRED); + SEC2TXT(SEC_E_KDC_CERT_REVOKED); + SEC2TXT(SEC_E_KDC_INVALID_REQUEST); + SEC2TXT(SEC_E_KDC_UNABLE_TO_REFER); + SEC2TXT(SEC_E_KDC_UNKNOWN_ETYPE); + SEC2TXT(SEC_E_LOGON_DENIED); + SEC2TXT(SEC_E_MAX_REFERRALS_EXCEEDED); + SEC2TXT(SEC_E_MESSAGE_ALTERED); + SEC2TXT(SEC_E_MULTIPLE_ACCOUNTS); + SEC2TXT(SEC_E_MUST_BE_KDC); + SEC2TXT(SEC_E_NOT_OWNER); + SEC2TXT(SEC_E_NO_AUTHENTICATING_AUTHORITY); + SEC2TXT(SEC_E_NO_CREDENTIALS); + SEC2TXT(SEC_E_NO_IMPERSONATION); + SEC2TXT(SEC_E_NO_IP_ADDRESSES); + SEC2TXT(SEC_E_NO_KERB_KEY); + SEC2TXT(SEC_E_NO_PA_DATA); + SEC2TXT(SEC_E_NO_S4U_PROT_SUPPORT); + SEC2TXT(SEC_E_NO_TGT_REPLY); + SEC2TXT(SEC_E_OUT_OF_SEQUENCE); + SEC2TXT(SEC_E_PKINIT_CLIENT_FAILURE); + SEC2TXT(SEC_E_PKINIT_NAME_MISMATCH); + SEC2TXT(SEC_E_POLICY_NLTM_ONLY); + SEC2TXT(SEC_E_QOP_NOT_SUPPORTED); + SEC2TXT(SEC_E_REVOCATION_OFFLINE_C); + SEC2TXT(SEC_E_REVOCATION_OFFLINE_KDC); + SEC2TXT(SEC_E_SECPKG_NOT_FOUND); + SEC2TXT(SEC_E_SECURITY_QOS_FAILED); + SEC2TXT(SEC_E_SHUTDOWN_IN_PROGRESS); + SEC2TXT(SEC_E_SMARTCARD_CERT_EXPIRED); + SEC2TXT(SEC_E_SMARTCARD_CERT_REVOKED); + SEC2TXT(SEC_E_SMARTCARD_LOGON_REQUIRED); + SEC2TXT(SEC_E_STRONG_CRYPTO_NOT_SUPPORTED); + SEC2TXT(SEC_E_TARGET_UNKNOWN); + SEC2TXT(SEC_E_TIME_SKEW); + SEC2TXT(SEC_E_TOO_MANY_PRINCIPALS); + SEC2TXT(SEC_E_UNFINISHED_CONTEXT_DELETED); + SEC2TXT(SEC_E_UNKNOWN_CREDENTIALS); + SEC2TXT(SEC_E_UNSUPPORTED_FUNCTION); + SEC2TXT(SEC_E_UNSUPPORTED_PREAUTH); + SEC2TXT(SEC_E_UNTRUSTED_ROOT); + SEC2TXT(SEC_E_WRONG_CREDENTIAL_HANDLE); + SEC2TXT(SEC_E_WRONG_PRINCIPAL); + SEC2TXT(SEC_I_COMPLETE_AND_CONTINUE); + SEC2TXT(SEC_I_COMPLETE_NEEDED); + SEC2TXT(SEC_I_CONTEXT_EXPIRED); + SEC2TXT(SEC_I_CONTINUE_NEEDED); + SEC2TXT(SEC_I_INCOMPLETE_CREDENTIALS); + SEC2TXT(SEC_I_LOCAL_LOGON); + SEC2TXT(SEC_I_NO_LSA_CONTEXT); + SEC2TXT(SEC_I_RENEGOTIATE); + SEC2TXT(SEC_I_SIGNATURE_NEEDED); default: txt = "Unknown error"; } - if(err == SEC_E_OK) - strncpy(outbuf, txt, outmax); - else if(err == SEC_E_ILLEGAL_MESSAGE) - msnprintf(outbuf, outmax, + if(err == SEC_E_ILLEGAL_MESSAGE) { + msnprintf(buf, buflen, "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs " "when a fatal SSL/TLS alert is received (e.g. handshake failed)." " More detail may be available in the Windows System event log.", err); + } else { - str = txtbuf; + char txtbuf[80]; + char msgbuf[256]; + msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err); - txtbuf[sizeof(txtbuf)-1] = '\0'; -#ifdef _WIN32_WCE - { - wchar_t wbuf[256]; - wbuf[0] = L'\0'; - - if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, LANG_NEUTRAL, - wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { - wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1); - msg_formatted = TRUE; - } - } -#else - if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, LANG_NEUTRAL, - msgbuf, sizeof(msgbuf)-1, NULL)) { - msg_formatted = TRUE; + if(get_winapi_error(err, msgbuf, sizeof(msgbuf))) + msnprintf(buf, buflen, "%s - %s", txtbuf, msgbuf); + else { + strncpy(buf, txtbuf, buflen); + buf[buflen - 1] = '\0'; } -#endif - if(msg_formatted) { - msgbuf[sizeof(msgbuf)-1] = '\0'; - /* strip trailing '\r\n' or '\n' */ - p = strrchr(msgbuf, '\n'); - if(p && (p - msgbuf) >= 2) - *p = '\0'; - p = strrchr(msgbuf, '\r'); - if(p && (p - msgbuf) >= 1) - *p = '\0'; - msg = msgbuf; - } - if(msg) - msnprintf(outbuf, outmax, "%s - %s", str, msg); - else - strncpy(outbuf, str, outmax); } #else - if(err == SEC_E_OK) txt = "No error"; else txt = "Error"; - - strncpy(outbuf, txt, outmax); - + strncpy(buf, txt, buflen); + buf[buflen - 1] = '\0'; #endif - outbuf[outmax] = '\0'; - if(errno != old_errno) errno = old_errno; @@ -1100,6 +998,6 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) SetLastError(old_win_err); #endif - return outbuf; + return buf; } #endif /* USE_WINDOWS_SSPI */ diff --git a/libs/libcurl/src/strerror.h b/libs/libcurl/src/strerror.h index 683b5b4a3a..278c1082f0 100644 --- a/libs/libcurl/src/strerror.h +++ b/libs/libcurl/src/strerror.h @@ -27,6 +27,9 @@ #define STRERROR_LEN 128 /* a suitable length */ const char *Curl_strerror(int err, char *buf, size_t buflen); +#if defined(WIN32) || defined(_WIN32_WCE) +const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen); +#endif #ifdef USE_WINDOWS_SSPI const char *Curl_sspi_strerror(int err, char *buf, size_t buflen); #endif diff --git a/libs/libcurl/src/strtok.c b/libs/libcurl/src/strtok.c index 460eb87e51..be8f481282 100644 --- a/libs/libcurl/src/strtok.c +++ b/libs/libcurl/src/strtok.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/strtok.h b/libs/libcurl/src/strtok.h index 90b831eb67..e221fa680f 100644 --- a/libs/libcurl/src/strtok.h +++ b/libs/libcurl/src/strtok.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/strtoofft.c b/libs/libcurl/src/strtoofft.c index 546a3ff75d..96e3820600 100644 --- a/libs/libcurl/src/strtoofft.c +++ b/libs/libcurl/src/strtoofft.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/telnet.c b/libs/libcurl/src/telnet.c index 955255c36c..4bf4c652c2 100644 --- a/libs/libcurl/src/telnet.c +++ b/libs/libcurl/src/telnet.c @@ -69,12 +69,12 @@ do { \ x->subend = x->subpointer; \ CURL_SB_CLEAR(x); \ - } WHILE_FALSE + } while(0) #define CURL_SB_ACCUM(x,c) \ do { \ if(x->subpointer < (x->subbuffer + sizeof(x->subbuffer))) \ *x->subpointer++ = (c); \ - } WHILE_FALSE + } while(0) #define CURL_SB_GET(x) ((*x->subpointer++)&0xff) #define CURL_SB_LEN(x) (x->subend - x->subpointer) diff --git a/libs/libcurl/src/telnet.h b/libs/libcurl/src/telnet.h index 668a78a133..431427f395 100644 --- a/libs/libcurl/src/telnet.h +++ b/libs/libcurl/src/telnet.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/tftp.h b/libs/libcurl/src/tftp.h index 1335f64bd1..33348300fe 100644 --- a/libs/libcurl/src/tftp.h +++ b/libs/libcurl/src/tftp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/transfer.c b/libs/libcurl/src/transfer.c index d0d4aeb500..ead8b36db9 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -484,8 +484,9 @@ CURLcode Curl_readrewind(struct connectdata *conn) return CURLE_OK; } -static int data_pending(const struct connectdata *conn) +static int data_pending(const struct Curl_easy *data) { + struct connectdata *conn = data->conn; /* in the case of libssh2, we can never be really sure that we have emptied its internal buffers so we MUST always try until we get EAGAIN back */ return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) || @@ -499,6 +500,8 @@ static int data_pending(const struct connectdata *conn) be called and we cannot signal the HTTP/2 stream has closed. As a workaround, we return nonzero here to call http2_recv. */ ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20); +#elif defined(ENABLE_QUIC) + Curl_ssl_data_pending(conn, FIRSTSOCKET) || Curl_quic_data_pending(data); #else Curl_ssl_data_pending(conn, FIRSTSOCKET); #endif @@ -918,7 +921,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, break; } - } while(data_pending(conn) && maxloops--); + } while(data_pending(data) && maxloops--); if(maxloops <= 0) { /* we mark it as read-again-please */ @@ -1174,7 +1177,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, } - } WHILE_FALSE; /* just to break out from! */ + } while(0); /* just to break out from! */ return CURLE_OK; } diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index 8285474fd7..56fb736368 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -106,7 +106,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "http2.h" #include "file.h" #include "curl_ldap.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "imap.h" #include "url.h" #include "connect.h" @@ -403,9 +403,11 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } +#ifndef CURL_DISABLE_DOH free(data->req.doh.probe[0].serverdoh.memory); free(data->req.doh.probe[1].serverdoh.memory); curl_slist_free_all(data->req.doh.headers); +#endif /* destruct wildcard structures if it is needed */ Curl_wildcard_dtor(&data->wildcard); @@ -672,7 +674,7 @@ static void conn_reset_all_postponed_data(struct connectdata *conn) } #else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ /* Use "do-nothing" macro instead of function when workaround not used */ -#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE +#define conn_reset_all_postponed_data(c) do {} while(0) #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ @@ -1080,16 +1082,15 @@ ConnectionExists(struct Curl_easy *data, check = curr->ptr; curr = curr->next; - if(check->bits.connect_only) - /* connect-only connections will not be reused */ + if(check->bits.connect_only || check->bits.close) + /* connect-only or to-be-closed connections will not be reused */ continue; multiplexed = CONN_INUSE(check) && (bundle->multiuse == BUNDLE_MULTIPLEX); if(canmultiplex) { - if(check->bits.protoconnstart && check->bits.close) - continue; + ; } else { if(multiplexed) { @@ -1109,12 +1110,9 @@ ConnectionExists(struct Curl_easy *data, } } - if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || - check->bits.close) { - if(!check->bits.close) - foundPendingCandidate = TRUE; - /* Don't pick a connection that hasn't connected yet or that is going - to get closed. */ + if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) { + foundPendingCandidate = TRUE; + /* Don't pick a connection that hasn't connected yet */ infof(data, "Connection #%ld isn't open enough, can't reuse\n", check->connection_id); continue; @@ -1192,8 +1190,7 @@ ConnectionExists(struct Curl_easy *data, already in use so we skip it */ continue; - if(CONN_INUSE(check) && check->data && - (check->data->multi != needle->data->multi)) + if(check->data && (check->data->multi != needle->data->multi)) /* this could be subject for multiplex use, but only if they belong to * the same multi handle */ continue; @@ -1641,6 +1638,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) it may live on without (this specific) Curl_easy */ conn->fclosesocket = data->set.fclosesocket; conn->closesocket_client = data->set.closesocket_client; + conn->lastused = Curl_now(); /* used now */ return conn; error: @@ -1987,8 +1985,11 @@ void Curl_free_request_state(struct Curl_easy *data) { Curl_safefree(data->req.protop); Curl_safefree(data->req.newurl); + +#ifndef CURL_DISABLE_DOH Curl_close(&data->req.doh.probe[0].easy); Curl_close(&data->req.doh.probe[1].easy); +#endif } @@ -3593,25 +3594,6 @@ static CURLcode create_conn(struct Curl_easy *data, else reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe); - /* If we found a reusable connection that is now marked as in use, we may - still want to open a new connection if we are multiplexing. */ - if(reuse && !force_reuse && IsMultiplexingPossible(data, conn_temp)) { - size_t multiplexed = CONN_INUSE(conn_temp); - if(multiplexed > 0) { - infof(data, "Found connection %ld, with %zu requests on it\n", - conn_temp->connection_id, multiplexed); - - if(Curl_conncache_bundle_size(conn_temp) < max_host_connections && - Curl_conncache_size(data) < max_total_connections) { - /* We want a new connection anyway */ - reuse = FALSE; - - infof(data, "We can reuse, but we want a new connection anyway\n"); - Curl_conncache_return_conn(conn_temp); - } - } - } - if(reuse) { /* * We already have a connection for this, we got the former connection diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index f9365b2e68..3effb1626f 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -124,7 +124,7 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ #include "smtp.h" #include "ftp.h" #include "file.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "http.h" #include "rtsp.h" #include "smb.h" @@ -257,6 +257,7 @@ struct ssl_config_data { BIT(falsestart); BIT(enable_beast); /* allow this flaw for interoperability's sake*/ BIT(no_revoke); /* disable SSL certificate revocation checks */ + BIT(no_partialchain); /* don't accept partial certificate chains */ }; struct ssl_general_config { @@ -528,6 +529,24 @@ enum upgrade101 { UPGR101_WORKING /* talking upgraded protocol */ }; +enum doh_slots { + /* Explicit values for first two symbols so as to match hard-coded + * constants in existing code + */ + DOH_PROBE_SLOT_IPADDR_V4 = 0, /* make 'V4' stand out for readability */ + DOH_PROBE_SLOT_IPADDR_V6 = 1, /* 'V6' likewise */ + + /* Space here for (possibly build-specific) additional slot definitions */ + + /* for example */ + /* #ifdef WANT_DOH_FOOBAR_TXT */ + /* DOH_PROBE_SLOT_FOOBAR_TXT, */ + /* #endif */ + + /* AFTER all slot definitions, establish how many we have */ + DOH_PROBE_SLOTS +}; + struct dohresponse { unsigned char *memory; size_t size; @@ -544,7 +563,7 @@ struct dnsprobe { struct dohdata { struct curl_slist *headers; - struct dnsprobe probe[2]; + struct dnsprobe probe[DOH_PROBE_SLOTS]; unsigned int pending; /* still outstanding requests */ const char *host; int port; diff --git a/libs/libcurl/src/vauth/cram.c b/libs/libcurl/src/vauth/cram.c index d148618b0d..04438fa740 100644 --- a/libs/libcurl/src/vauth/cram.c +++ b/libs/libcurl/src/vauth/cram.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/vauth/digest.h b/libs/libcurl/src/vauth/digest.h index 8686c44a42..cc05fdb769 100644 --- a/libs/libcurl/src/vauth/digest.h +++ b/libs/libcurl/src/vauth/digest.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/version.c b/libs/libcurl/src/version.c index cfd09e36d7..6405d369d7 100644 --- a/libs/libcurl/src/version.c +++ b/libs/libcurl/src/version.c @@ -26,7 +26,7 @@ #include "urldata.h" #include "vtls/vtls.h" #include "http2.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "quic.h" #include "curl_printf.h" diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c index c0f9b16e38..e97e9e871b 100644 --- a/libs/libcurl/src/vquic/ngtcp2.c +++ b/libs/libcurl/src/vquic/ngtcp2.c @@ -49,7 +49,7 @@ #ifdef DEBUG_HTTP3 #define H3BUGF(x) x #else -#define H3BUGF(x) do { } WHILE_FALSE +#define H3BUGF(x) do { } while(0) #endif /* @@ -174,8 +174,10 @@ static int quic_set_encryption_secrets(SSL *ssl, tx_secret, secretlen, NGTCP2_CRYPTO_SIDE_CLIENT) != 0) return 0; - if(level == NGTCP2_CRYPTO_LEVEL_APP && init_ngh3_conn(qs) != CURLE_OK) - return 0; + if(level == NGTCP2_CRYPTO_LEVEL_APP) { + if(init_ngh3_conn(qs) != CURLE_OK) + return 0; + } return 1; } @@ -188,11 +190,12 @@ static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level, ngtcp2_crypto_level level = quic_from_ossl_level(ossl_level); int rv; - crypto_data = &qs->client_crypto_data[level]; + crypto_data = &qs->crypto_data[level]; if(crypto_data->buf == NULL) { crypto_data->buf = malloc(4096); + if(!crypto_data->buf) + return 0; crypto_data->alloclen = 4096; - /* TODO Explode if malloc failed */ } /* TODO Just pretend that handshake does not grow more than 4KiB for @@ -203,8 +206,8 @@ static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level, crypto_data->len += len; rv = ngtcp2_conn_submit_crypto_data( - qs->qconn, level, (uint8_t *)(&crypto_data->buf[crypto_data->len] - len), - len); + qs->qconn, level, (uint8_t *)(&crypto_data->buf[crypto_data->len] - len), + len); if(rv) { H3BUGF(fprintf(stderr, "write_client_handshake failed\n")); } @@ -244,8 +247,9 @@ static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data) SSL_CTX_set_default_verify_paths(ssl_ctx); if(SSL_CTX_set_ciphersuites(ssl_ctx, QUIC_CIPHERS) != 1) { - failf(data, "SSL_CTX_set_ciphersuites: %s", - ERR_error_string(ERR_get_error(), NULL)); + char error_buffer[256]; + ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer)); + failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer); return NULL; } @@ -305,7 +309,7 @@ static int cb_initial(ngtcp2_conn *quic, void *user_data) struct quicsocket *qs = (struct quicsocket *)user_data; if(ngtcp2_crypto_read_write_crypto_data( - quic, qs->ssl, NGTCP2_CRYPTO_LEVEL_INITIAL, NULL, 0) != 0) + quic, qs->ssl, NGTCP2_CRYPTO_LEVEL_INITIAL, NULL, 0) != 0) return NGTCP2_ERR_CALLBACK_FAILURE; return 0; @@ -336,6 +340,16 @@ static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data) return 0; } +static void extend_stream_window(ngtcp2_conn *tconn, + struct HTTP *stream) +{ + size_t thismuch = stream->unacked_window; + ngtcp2_conn_extend_max_stream_offset(tconn, stream->stream3_id, thismuch); + ngtcp2_conn_extend_max_offset(tconn, thismuch); + stream->unacked_window = 0; +} + + static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t stream_id, int fin, uint64_t offset, const uint8_t *buf, size_t buflen, @@ -346,9 +360,6 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t stream_id, (void)offset; (void)stream_user_data; - infof(qs->conn->data, "Received %ld bytes data on stream %u\n", - buflen, stream_id); - nconsumed = nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin); if(nconsumed < 0) { @@ -357,6 +368,9 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t stream_id, return NGTCP2_ERR_CALLBACK_FAILURE; } + /* number of bytes inside buflen which consists of framing overhead + * including QPACK HEADERS. In other words, it does not consume payload of + * DATA frame. */ ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed); ngtcp2_conn_extend_max_offset(tconn, nconsumed); @@ -514,7 +528,7 @@ static ngtcp2_conn_callbacks ng_callbacks = { NULL, /* rand */ cb_get_new_connection_id, NULL, /* remove_connection_id */ - NULL, /* update_key */ + ngtcp2_crypto_update_key_cb, /* update_key */ NULL, /* path_validation */ NULL, /* select_preferred_addr */ cb_stream_reset, @@ -656,8 +670,16 @@ static int ng_perform_getsock(const struct connectdata *conn, static CURLcode ng_disconnect(struct connectdata *conn, bool dead_connection) { - (void)conn; + int i; + struct quicsocket *qs = &conn->hequic[0]; (void)dead_connection; + if(qs->ssl) + SSL_free(qs->ssl); + for(i = 0; i < 3; i++) + free(qs->crypto_data[i].buf); + nghttp3_conn_del(qs->h3conn); + ngtcp2_conn_del(qs->qconn); + SSL_CTX_free(qs->sslctx); return CURLE_OK; } @@ -704,42 +726,121 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, stream->closed = TRUE; Curl_expire(data, 0, EXPIRE_QUIC); + /* make sure that ngh3_stream_recv is called again to complete the transfer + even if there are no more packets to be received from the server. */ + data->state.drain = 1; return 0; } -static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id, - const uint8_t *buf, size_t buflen, - void *user_data, void *stream_user_data) -{ - struct quicsocket *qs = user_data; - size_t ncopy; - struct Curl_easy *data = stream_user_data; - struct HTTP *stream = data->req.protop; - (void)conn; - H3BUGF(infof(data, "cb_h3_recv_data CALLED with %d bytes\n", buflen)); +/* Minimum size of the overflow buffer */ +#define OVERFLOWSIZE 1024 - /* TODO: this needs to be handled properly */ - DEBUGASSERT(buflen <= stream->len); +/* + * allocate_overflow() ensures that there is room for incoming data in the + * overflow buffer, growing it to accommodate the new data if necessary. We + * may need to use the overflow buffer because we can't precisely limit the + * amount of HTTP/3 header data we receive using QUIC flow control mechanisms. + */ +static CURLcode allocate_overflow(struct Curl_easy *data, + struct HTTP *stream, + size_t length) +{ + size_t maxleft; + size_t newsize; + /* length can be arbitrarily large, so take care not to overflow newsize */ + maxleft = CURL_MAX_READ_SIZE - stream->overflow_buflen; + if(length > maxleft) { + /* The reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a highly compressed list of headers that + will cause our overflow buffer to grow too large */ + failf(data, "Rejected %zu bytes of overflow data (max is %d)!", + stream->overflow_buflen + length, CURL_MAX_READ_SIZE); + return CURLE_OUT_OF_MEMORY; + } + newsize = stream->overflow_buflen + length; + if(newsize > stream->overflow_bufsize) { + /* We enlarge the overflow buffer as it is too small */ + char *newbuff; + newsize = CURLMAX(newsize * 3 / 2, stream->overflow_bufsize*2); + newsize = CURLMIN(CURLMAX(OVERFLOWSIZE, newsize), CURL_MAX_READ_SIZE); + newbuff = realloc(stream->overflow_buf, newsize); + if(!newbuff) { + failf(data, "Failed to alloc memory for overflow buffer!"); + return CURLE_OUT_OF_MEMORY; + } + stream->overflow_buf = newbuff; + stream->overflow_bufsize = newsize; + infof(data, "Grew HTTP/3 overflow buffer to %zu bytes\n", newsize); + } + return CURLE_OK; +} - ncopy = CURLMIN(stream->len, buflen); - memcpy(stream->mem, buf, ncopy); - stream->len -= ncopy; - stream->memlen += ncopy; +/* + * write_data() copies data to the stream's receive buffer. If not enough + * space is available in the receive buffer, it copies the rest to the + * stream's overflow buffer. + */ +static CURLcode write_data(struct Curl_easy *data, + struct HTTP *stream, + const void *mem, size_t memlen) +{ + CURLcode result = CURLE_OK; + const char *buf = mem; + size_t ncopy = memlen; + /* copy as much as possible to the receive buffer */ + if(stream->len) { + size_t len = CURLMIN(ncopy, stream->len); +#if 0 /* extra debugging of incoming h3 data */ + fprintf(stderr, "!! Copies %zd bytes to %p (total %zd)\n", + len, stream->mem, stream->memlen); +#endif + memcpy(stream->mem, buf, len); + stream->len -= len; + stream->memlen += len; + stream->mem += len; + buf += len; + ncopy -= len; + } + /* copy the rest to the overflow buffer */ + if(ncopy) { + result = allocate_overflow(data, stream, ncopy); + if(result) { + return result; + } +#if 0 /* extra debugging of incoming h3 data */ + fprintf(stderr, "!! Copies %zd overflow bytes to %p (total %zd)\n", + ncopy, stream->overflow_buf, stream->overflow_buflen); +#endif + memcpy(stream->overflow_buf + stream->overflow_buflen, buf, ncopy); + stream->overflow_buflen += ncopy; + } #if 0 /* extra debugging of incoming h3 data */ - fprintf(stderr, "!! Copies %zd bytes to %p (total %zd)\n", - ncopy, stream->mem, stream->memlen); { size_t i; - for(i = 0; i < ncopy; i++) { + for(i = 0; i < memlen; i++) { fprintf(stderr, "!! data[%d]: %02x '%c'\n", i, buf[i], buf[i]); } } #endif - stream->mem += ncopy; + return result; +} - ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, buflen); - ngtcp2_conn_extend_max_offset(qs->qconn, buflen); +static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id, + const uint8_t *buf, size_t buflen, + void *user_data, void *stream_user_data) +{ + struct Curl_easy *data = stream_user_data; + struct HTTP *stream = data->req.protop; + CURLcode result = CURLE_OK; + (void)conn; + result = write_data(data, stream, buf, buflen); + if(result) { + return -1; + } + stream->unacked_window += buflen; + (void)stream_id; + (void)user_data; return 0; } @@ -750,10 +851,10 @@ static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream_id, struct quicsocket *qs = user_data; (void)conn; (void)stream_user_data; + (void)stream_id; ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, consumed); ngtcp2_conn_extend_max_offset(qs->qconn, consumed); - return 0; } @@ -789,15 +890,17 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id, { struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.protop; + CURLcode result = CURLE_OK; (void)conn; (void)stream_id; (void)user_data; - if(stream->memlen >= 2) { - memcpy(stream->mem, "\r\n", 2); - stream->len -= 2; - stream->memlen += 2; - stream->mem += 2; + /* add a CRLF only if we've received some headers */ + if(stream->firstheader) { + result = write_data(data, stream, "\r\n", 2); + if(result) { + return -1; + } } return 0; } @@ -811,7 +914,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value); struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.protop; - size_t ncopy; + CURLcode result = CURLE_OK; (void)conn; (void)stream_id; (void)token; @@ -820,20 +923,37 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, if(h3name.len == sizeof(":status") - 1 && !memcmp(":status", h3name.base, h3name.len)) { + char line[14]; /* status line is always 13 characters long */ + size_t ncopy; int status = decode_status_code(h3val.base, h3val.len); DEBUGASSERT(status != -1); - msnprintf(stream->mem, stream->len, "HTTP/3 %03d \r\n", status); + ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", status); + result = write_data(data, stream, line, ncopy); + if(result) { + return -1; + } } else { /* store as a HTTP1-style header */ - msnprintf(stream->mem, stream->len, "%.*s: %.*s\n", - h3name.len, h3name.base, h3val.len, h3val.base); + result = write_data(data, stream, h3name.base, h3name.len); + if(result) { + return -1; + } + result = write_data(data, stream, ": ", 2); + if(result) { + return -1; + } + result = write_data(data, stream, h3val.base, h3val.len); + if(result) { + return -1; + } + result = write_data(data, stream, "\r\n", 2); + if(result) { + return -1; + } } - ncopy = strlen(stream->mem); - stream->len -= ncopy; - stream->memlen += ncopy; - stream->mem += ncopy; + stream->firstheader = TRUE; return 0; } @@ -933,6 +1053,21 @@ static int init_ngh3_conn(struct quicsocket *qs) static Curl_recv ngh3_stream_recv; static Curl_send ngh3_stream_send; +static size_t drain_overflow_buffer(struct HTTP *stream) +{ + size_t ncopy = CURLMIN(stream->overflow_buflen, stream->len); + if(ncopy > 0) { + memcpy(stream->mem, stream->overflow_buf, ncopy); + stream->len -= ncopy; + stream->mem += ncopy; + stream->memlen += ncopy; + stream->overflow_buflen -= ncopy; + memmove(stream->overflow_buf, stream->overflow_buf + ncopy, + stream->overflow_buflen); + } + return ncopy; +} + /* incoming data frames on the h3 stream */ static ssize_t ngh3_stream_recv(struct connectdata *conn, int sockindex, @@ -952,6 +1087,10 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn, } /* else, there's data in the buffer already */ + /* if there's data in the overflow buffer from a previous call, copy as much + as possible to the receive buffer before receiving more */ + drain_overflow_buffer(stream); + if(ng_process_ingress(conn, sockfd, qs)) { *curlcode = CURLE_RECV_ERROR; return -1; @@ -969,8 +1108,13 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn, stream->memlen = 0; stream->mem = buf; stream->len = buffersize; - H3BUGF(infof(conn->data, "!! ngh3_stream_recv returns %zd bytes at %p\n", - memlen, buf)); + /* extend the stream window with the data we're consuming and send out + any additional packets to tell the server that we can receive more */ + extend_stream_window(qs->qconn, stream); + if(ng_flush_egress(conn, sockfd, qs)) { + *curlcode = CURLE_SEND_ERROR; + return -1; + } return memlen; } @@ -1590,4 +1734,32 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn) return CURLE_OK; } + +/* + * Called from http.c:Curl_http_done when a request completes. + */ +void Curl_quic_done(struct Curl_easy *data, bool premature) +{ + (void)premature; + if(data->conn->handler == &Curl_handler_http3) { + /* only for HTTP/3 transfers */ + struct HTTP *stream = data->req.protop; + Curl_safefree(stream->overflow_buf); + } +} + +/* + * Called from transfer.c:data_pending to know if we should keep looping + * to receive more data from the connection. + */ +bool Curl_quic_data_pending(const struct Curl_easy *data) +{ + /* We may have received more data than we're able to hold in the receive + buffer and allocated an overflow buffer. Since it's possible that + there's no more data coming on the socket, we need to keep reading + until the overflow buffer is empty. */ + const struct HTTP *stream = data->req.protop; + return stream->overflow_buflen > 0; +} + #endif diff --git a/libs/libcurl/src/vquic/ngtcp2.h b/libs/libcurl/src/vquic/ngtcp2.h index 5570fc7e78..30d442fdde 100644 --- a/libs/libcurl/src/vquic/ngtcp2.h +++ b/libs/libcurl/src/vquic/ngtcp2.h @@ -46,7 +46,7 @@ struct quicsocket { ngtcp2_settings settings; SSL_CTX *sslctx; SSL *ssl; - struct quic_handshake client_crypto_data[3]; + struct quic_handshake crypto_data[3]; /* the last TLS alert description generated by the local endpoint */ uint8_t tls_alert; struct sockaddr_storage local_addr; diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c index 0ee360d07f..e2f43237fa 100644 --- a/libs/libcurl/src/vquic/quiche.c +++ b/libs/libcurl/src/vquic/quiche.c @@ -45,7 +45,7 @@ #ifdef DEBUG_HTTP3 #define H3BUGF(x) x #else -#define H3BUGF(x) do { } WHILE_FALSE +#define H3BUGF(x) do { } while(0) #endif #define QUIC_MAX_STREAMS (256*1024) @@ -379,6 +379,9 @@ static int cb_each_header(uint8_t *name, size_t name_len, headers->destlen, "HTTP/3 %.*s\n", (int) value_len, value); } + else if(!headers->nlen) { + return CURLE_HTTP3; + } else { msnprintf(headers->dest, headers->destlen, "%.*s: %.*s\n", @@ -433,7 +436,9 @@ static ssize_t h3_stream_recv(struct connectdata *conn, case QUICHE_H3_EVENT_HEADERS: rc = quiche_h3_event_for_each_header(ev, cb_each_header, &headers); if(rc) { - /* what do we do about this? */ + *curlcode = rc; + failf(data, "Error in HTTP/3 response header"); + break; } recvd = headers.nlen; break; @@ -780,4 +785,23 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn) return CURLE_OK; } +/* + * Called from http.c:Curl_http_done when a request completes. + */ +void Curl_quic_done(struct Curl_easy *data, bool premature) +{ + (void)data; + (void)premature; +} + +/* + * Called from transfer.c:data_pending to know if we should keep looping + * to receive more data from the connection. + */ +bool Curl_quic_data_pending(const struct Curl_easy *data) +{ + (void)data; + return FALSE; +} + #endif diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c index cad8b37864..62a7f1960c 100644 --- a/libs/libcurl/src/vssh/libssh.c +++ b/libs/libcurl/src/vssh/libssh.c @@ -97,9 +97,13 @@ /* A recent macro provided by libssh. Or make our own. */ #ifndef SSH_STRING_FREE_CHAR -/* !checksrc! disable ASSIGNWITHINCONDITION 1 */ -#define SSH_STRING_FREE_CHAR(x) \ - do { if((x) != NULL) { ssh_string_free_char(x); x = NULL; } } while(0) +#define SSH_STRING_FREE_CHAR(x) \ + do { \ + if(x) { \ + ssh_string_free_char(x); \ + x = NULL; \ + } \ + } while(0) #endif /* Local functions: */ diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c index c71cfbc9fd..063f3d2ae6 100644 --- a/libs/libcurl/src/vssh/libssh2.c +++ b/libs/libcurl/src/vssh/libssh2.c @@ -466,61 +466,95 @@ static CURLcode ssh_knownhost(struct connectdata *conn) struct curl_khkey *knownkeyp = NULL; struct curl_khkey foundkey; - keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? - LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS; - + switch(keytype) { + case LIBSSH2_HOSTKEY_TYPE_RSA: + keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA; + break; + case LIBSSH2_HOSTKEY_TYPE_DSS: + keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS; + break; +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256 + case LIBSSH2_HOSTKEY_TYPE_ECDSA_256: + keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256; + break; +#endif +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384 + case LIBSSH2_HOSTKEY_TYPE_ECDSA_384: + keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384; + break; +#endif +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521 + case LIBSSH2_HOSTKEY_TYPE_ECDSA_521: + keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521; + break; +#endif +#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519 + case LIBSSH2_HOSTKEY_TYPE_ED25519: + keybit = LIBSSH2_KNOWNHOST_KEY_ED25519; + break; +#endif + default: + infof(data, "unsupported key type, can't check knownhosts!\n"); + keybit = 0; + break; + } + if(!keybit) + /* no check means failure! */ + rc = CURLKHSTAT_REJECT; + else { #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP - keycheck = libssh2_knownhost_checkp(sshc->kh, - conn->host.name, - (conn->remote_port != PORT_SSH)? - conn->remote_port:-1, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, - &host); + keycheck = libssh2_knownhost_checkp(sshc->kh, + conn->host.name, + (conn->remote_port != PORT_SSH)? + conn->remote_port:-1, + remotekey, keylen, + LIBSSH2_KNOWNHOST_TYPE_PLAIN| + LIBSSH2_KNOWNHOST_KEYENC_RAW| + keybit, + &host); #else - keycheck = libssh2_knownhost_check(sshc->kh, - conn->host.name, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, - &host); + keycheck = libssh2_knownhost_check(sshc->kh, + conn->host.name, + remotekey, keylen, + LIBSSH2_KNOWNHOST_TYPE_PLAIN| + LIBSSH2_KNOWNHOST_KEYENC_RAW| + keybit, + &host); #endif - infof(data, "SSH host check: %d, key: %s\n", keycheck, - (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? - host->key:"<none>"); + infof(data, "SSH host check: %d, key: %s\n", keycheck, + (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? + host->key:"<none>"); + + /* setup 'knownkey' */ + if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { + knownkey.key = host->key; + knownkey.len = 0; + knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? + CURLKHTYPE_RSA : CURLKHTYPE_DSS; + knownkeyp = &knownkey; + } - /* setup 'knownkey' */ - if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { - knownkey.key = host->key; - knownkey.len = 0; - knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? + /* setup 'foundkey' */ + foundkey.key = remotekey; + foundkey.len = keylen; + foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? CURLKHTYPE_RSA : CURLKHTYPE_DSS; - knownkeyp = &knownkey; - } - /* setup 'foundkey' */ - foundkey.key = remotekey; - foundkey.len = keylen; - foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? - CURLKHTYPE_RSA : CURLKHTYPE_DSS; + /* + * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the + * curl_khmatch enum are ever modified, we need to introduce a + * translation table here! + */ + keymatch = (enum curl_khmatch)keycheck; - /* - * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the - * curl_khmatch enum are ever modified, we need to introduce a - * translation table here! - */ - keymatch = (enum curl_khmatch)keycheck; - - /* Ask the callback how to behave */ - Curl_set_in_callback(data, true); - 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); + /* Ask the callback how to behave */ + Curl_set_in_callback(data, true); + 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); + } } else /* no remotekey means failure! */ diff --git a/libs/libcurl/src/ssh.h b/libs/libcurl/src/vssh/ssh.h index 3213c5a52e..3213c5a52e 100644 --- a/libs/libcurl/src/ssh.h +++ b/libs/libcurl/src/vssh/ssh.h diff --git a/libs/libcurl/src/vtls/bearssl.c b/libs/libcurl/src/vtls/bearssl.c new file mode 100644 index 0000000000..67f945831c --- /dev/null +++ b/libs/libcurl/src/vtls/bearssl.c @@ -0,0 +1,866 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019, Michael Forney, <mforney@mforney.org> + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * 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_BEARSSL + +#include <bearssl.h> + +#include "bearssl.h" +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "connect.h" +#include "select.h" +#include "multiif.h" +#include "curl_printf.h" +#include "curl_memory.h" + +struct x509_context { + const br_x509_class *vtable; + br_x509_minimal_context minimal; + bool verifyhost; + bool verifypeer; +}; + +struct ssl_backend_data { + br_ssl_client_context ctx; + struct x509_context x509; + unsigned char buf[BR_SSL_BUFSIZE_BIDI]; + br_x509_trust_anchor *anchors; + size_t anchors_len; + const char *protocols[2]; + /* SSL client context is active */ + bool active; + /* size of pending write, yet to be flushed */ + size_t pending_write; +}; + +#define BACKEND connssl->backend + +struct cafile_parser { + CURLcode err; + bool in_cert; + br_x509_decoder_context xc; + /* array of trust anchors loaded from CAfile */ + br_x509_trust_anchor *anchors; + size_t anchors_len; + /* buffer for DN data */ + unsigned char dn[1024]; + size_t dn_len; +}; + +static void append_dn(void *ctx, const void *buf, size_t len) +{ + struct cafile_parser *ca = ctx; + + if(ca->err != CURLE_OK || !ca->in_cert) + return; + if(sizeof(ca->dn) - ca->dn_len < len) { + ca->err = CURLE_FAILED_INIT; + return; + } + memcpy(ca->dn + ca->dn_len, buf, len); + ca->dn_len += len; +} + +static void x509_push(void *ctx, const void *buf, size_t len) +{ + struct cafile_parser *ca = ctx; + + if(ca->in_cert) + br_x509_decoder_push(&ca->xc, buf, len); +} + +static CURLcode load_cafile(const char *path, br_x509_trust_anchor **anchors, + size_t *anchors_len) +{ + struct cafile_parser ca; + br_pem_decoder_context pc; + br_x509_trust_anchor *ta; + size_t ta_size; + br_x509_trust_anchor *new_anchors; + size_t new_anchors_len; + br_x509_pkey *pkey; + FILE *fp; + unsigned char buf[BUFSIZ], *p; + const char *name; + size_t n, i, pushed; + + fp = fopen(path, "rb"); + if(!fp) + return CURLE_SSL_CACERT_BADFILE; + + ca.err = CURLE_OK; + ca.in_cert = FALSE; + ca.anchors = NULL; + ca.anchors_len = 0; + br_pem_decoder_init(&pc); + br_pem_decoder_setdest(&pc, x509_push, &ca); + for(;;) { + n = fread(buf, 1, sizeof(buf), fp); + if(n == 0) + break; + p = buf; + while(n) { + pushed = br_pem_decoder_push(&pc, p, n); + if(ca.err) + goto fail; + p += pushed; + n -= pushed; + + switch(br_pem_decoder_event(&pc)) { + case 0: + break; + case BR_PEM_BEGIN_OBJ: + name = br_pem_decoder_name(&pc); + if(strcmp(name, "CERTIFICATE") && strcmp(name, "X509 CERTIFICATE")) + break; + br_x509_decoder_init(&ca.xc, append_dn, &ca); + if(ca.anchors_len == SIZE_MAX / sizeof(ca.anchors[0])) { + ca.err = CURLE_OUT_OF_MEMORY; + goto fail; + } + new_anchors_len = ca.anchors_len + 1; + new_anchors = realloc(ca.anchors, + new_anchors_len * sizeof(ca.anchors[0])); + if(!new_anchors) { + ca.err = CURLE_OUT_OF_MEMORY; + goto fail; + } + ca.anchors = new_anchors; + ca.anchors_len = new_anchors_len; + ca.in_cert = TRUE; + ca.dn_len = 0; + ta = &ca.anchors[ca.anchors_len - 1]; + ta->dn.data = NULL; + break; + case BR_PEM_END_OBJ: + if(!ca.in_cert) + break; + ca.in_cert = FALSE; + if(br_x509_decoder_last_error(&ca.xc)) { + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + ta->flags = 0; + if(br_x509_decoder_isCA(&ca.xc)) + ta->flags |= BR_X509_TA_CA; + pkey = br_x509_decoder_get_pkey(&ca.xc); + if(!pkey) { + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + ta->pkey = *pkey; + + /* calculate space needed for trust anchor data */ + ta_size = ca.dn_len; + switch(pkey->key_type) { + case BR_KEYTYPE_RSA: + ta_size += pkey->key.rsa.nlen + pkey->key.rsa.elen; + break; + case BR_KEYTYPE_EC: + ta_size += pkey->key.ec.qlen; + break; + default: + ca.err = CURLE_FAILED_INIT; + goto fail; + } + + /* fill in trust anchor DN and public key data */ + ta->dn.data = malloc(ta_size); + if(!ta->dn.data) { + ca.err = CURLE_OUT_OF_MEMORY; + goto fail; + } + memcpy(ta->dn.data, ca.dn, ca.dn_len); + ta->dn.len = ca.dn_len; + switch(pkey->key_type) { + case BR_KEYTYPE_RSA: + ta->pkey.key.rsa.n = ta->dn.data + ta->dn.len; + memcpy(ta->pkey.key.rsa.n, pkey->key.rsa.n, pkey->key.rsa.nlen); + ta->pkey.key.rsa.e = ta->pkey.key.rsa.n + ta->pkey.key.rsa.nlen; + memcpy(ta->pkey.key.rsa.e, pkey->key.rsa.e, pkey->key.rsa.elen); + break; + case BR_KEYTYPE_EC: + ta->pkey.key.ec.q = ta->dn.data + ta->dn.len; + memcpy(ta->pkey.key.ec.q, pkey->key.ec.q, pkey->key.ec.qlen); + break; + } + break; + default: + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + } + } + if(ferror(fp)) + ca.err = CURLE_READ_ERROR; + +fail: + fclose(fp); + if(ca.err == CURLE_OK) { + *anchors = ca.anchors; + *anchors_len = ca.anchors_len; + } + else { + for(i = 0; i < ca.anchors_len; ++i) + free(ca.anchors[i].dn.data); + free(ca.anchors); + } + + return ca.err; +} + +static void x509_start_chain(const br_x509_class **ctx, + const char *server_name) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + if(!x509->verifyhost) + server_name = NULL; + x509->minimal.vtable->start_chain(&x509->minimal.vtable, server_name); +} + +static void x509_start_cert(const br_x509_class **ctx, uint32_t length) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + x509->minimal.vtable->start_cert(&x509->minimal.vtable, length); +} + +static void x509_append(const br_x509_class **ctx, const unsigned char *buf, + size_t len) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + x509->minimal.vtable->append(&x509->minimal.vtable, buf, len); +} + +static void x509_end_cert(const br_x509_class **ctx) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + x509->minimal.vtable->end_cert(&x509->minimal.vtable); +} + +static unsigned x509_end_chain(const br_x509_class **ctx) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + unsigned err; + + err = x509->minimal.vtable->end_chain(&x509->minimal.vtable); + if(err && !x509->verifypeer) { + /* ignore any X.509 errors */ + err = BR_ERR_OK; + } + + return err; +} + +static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx, + unsigned *usages) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + return x509->minimal.vtable->get_pkey(&x509->minimal.vtable, usages); +} + +static const br_x509_class x509_vtable = { + sizeof(struct x509_context), + x509_start_chain, + x509_start_cert, + x509_append, + x509_end_cert, + x509_end_chain, + x509_get_pkey +}; + +static CURLcode bearssl_connect_step1(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const bool verifyhost = SSL_CONN_CONFIG(verifyhost); + CURLcode ret; + unsigned version_min, version_max; +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_SSLv2: + failf(data, "BearSSL does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv3: + failf(data, "BearSSL does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_0: + version_min = BR_TLS10; + version_max = BR_TLS10; + break; + case CURL_SSLVERSION_TLSv1_1: + version_min = BR_TLS11; + version_max = BR_TLS11; + break; + case CURL_SSLVERSION_TLSv1_2: + version_min = BR_TLS12; + version_max = BR_TLS12; + break; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + version_min = BR_TLS10; + version_max = BR_TLS12; + break; + default: + failf(data, "BearSSL: unknown CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(ssl_cafile) { + ret = load_cafile(ssl_cafile, &BACKEND->anchors, &BACKEND->anchors_len); + if(ret != CURLE_OK) { + if(verifypeer) { + failf(data, "error setting certificate verify locations:\n" + " CAfile: %s\n", ssl_cafile); + return ret; + } + infof(data, "error setting certificate verify locations," + " continuing anyway:\n"); + } + } + + /* initialize SSL context */ + br_ssl_client_init_full(&BACKEND->ctx, &BACKEND->x509.minimal, + BACKEND->anchors, BACKEND->anchors_len); + br_ssl_engine_set_versions(&BACKEND->ctx.eng, version_min, version_max); + br_ssl_engine_set_buffer(&BACKEND->ctx.eng, BACKEND->buf, + sizeof(BACKEND->buf), 1); + + /* initialize X.509 context */ + BACKEND->x509.vtable = &x509_vtable; + BACKEND->x509.verifypeer = verifypeer; + BACKEND->x509.verifyhost = verifyhost; + br_ssl_engine_set_x509(&BACKEND->ctx.eng, &BACKEND->x509.vtable); + + if(SSL_SET_OPTION(primary.sessionid)) { + void *session; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &session, NULL, sockindex)) { + br_ssl_engine_set_session_parameters(&BACKEND->ctx.eng, session); + infof(data, "BearSSL: re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + if(conn->bits.tls_enable_alpn) { + int cur = 0; + + /* NOTE: when adding more protocols here, increase the size of the + * protocols array in `struct ssl_backend_data`. + */ + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) { + BACKEND->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + BACKEND->protocols[cur++] = ALPN_HTTP_1_1; + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + br_ssl_engine_set_protocol_names(&BACKEND->ctx.eng, + BACKEND->protocols, cur); + } + + if((1 == Curl_inet_pton(AF_INET, hostname, &addr)) +#ifdef ENABLE_IPV6 + || (1 == Curl_inet_pton(AF_INET6, hostname, &addr)) +#endif + ) { + if(verifyhost) { + failf(data, "BearSSL: " + "host verification of IP address is not supported"); + return CURLE_PEER_FAILED_VERIFICATION; + } + hostname = NULL; + } + + if(!br_ssl_client_reset(&BACKEND->ctx, hostname, 0)) + return CURLE_FAILED_INIT; + BACKEND->active = TRUE; + + connssl->connecting_state = ssl_connect_2; + + return CURLE_OK; +} + +static CURLcode bearssl_run_until(struct connectdata *conn, int sockindex, + unsigned target) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + unsigned state; + unsigned char *buf; + size_t len; + ssize_t ret; + int err; + + for(;;) { + state = br_ssl_engine_current_state(&BACKEND->ctx.eng); + if(state & BR_SSL_CLOSED) { + err = br_ssl_engine_last_error(&BACKEND->ctx.eng); + switch(err) { + case BR_ERR_OK: + /* TLS close notify */ + if(connssl->state != ssl_connection_complete) { + failf(data, "SSL: connection closed during handshake"); + return CURLE_SSL_CONNECT_ERROR; + } + return CURLE_OK; + case BR_ERR_X509_EXPIRED: + failf(data, "SSL: X.509 verification: " + "certificate is expired or not yet valid"); + return CURLE_PEER_FAILED_VERIFICATION; + case BR_ERR_X509_BAD_SERVER_NAME: + failf(data, "SSL: X.509 verification: " + "expected server name was not found in the chain"); + return CURLE_PEER_FAILED_VERIFICATION; + case BR_ERR_X509_NOT_TRUSTED: + failf(data, "SSL: X.509 verification: " + "chain could not be linked to a trust anchor"); + return CURLE_PEER_FAILED_VERIFICATION; + } + /* X.509 errors are documented to have the range 32..63 */ + if(err >= 32 && err < 64) + return CURLE_PEER_FAILED_VERIFICATION; + return CURLE_SSL_CONNECT_ERROR; + } + if(state & target) + return CURLE_OK; + if(state & BR_SSL_SENDREC) { + buf = br_ssl_engine_sendrec_buf(&BACKEND->ctx.eng, &len); + ret = swrite(sockfd, buf, len); + if(ret == -1) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(connssl->state != ssl_connection_complete) + connssl->connecting_state = ssl_connect_2_writing; + return CURLE_AGAIN; + } + return CURLE_WRITE_ERROR; + } + br_ssl_engine_sendrec_ack(&BACKEND->ctx.eng, ret); + } + else if(state & BR_SSL_RECVREC) { + buf = br_ssl_engine_recvrec_buf(&BACKEND->ctx.eng, &len); + ret = sread(sockfd, buf, len); + if(ret == 0) { + failf(data, "SSL: EOF without close notify"); + return CURLE_READ_ERROR; + } + if(ret == -1) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(connssl->state != ssl_connection_complete) + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_AGAIN; + } + return CURLE_READ_ERROR; + } + br_ssl_engine_recvrec_ack(&BACKEND->ctx.eng, ret); + } + } +} + +static CURLcode bearssl_connect_step2(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CURLcode ret; + + ret = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP | BR_SSL_RECVAPP); + if(ret == CURLE_AGAIN) + return CURLE_OK; + if(ret == CURLE_OK) { + if(br_ssl_engine_current_state(&BACKEND->ctx.eng) == BR_SSL_CLOSED) { + failf(data, "SSL: connection closed during handshake"); + return CURLE_SSL_CONNECT_ERROR; + } + connssl->connecting_state = ssl_connect_3; + } + return ret; +} + +static CURLcode bearssl_connect_step3(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CURLcode ret; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + if(conn->bits.tls_enable_alpn) { + const char *protocol; + + protocol = br_ssl_engine_get_selected_protocol(&BACKEND->ctx.eng); + if(protocol) { + infof(data, "ALPN, server accepted to use %s\n", protocol); + +#ifdef USE_NGHTTP2 + if(!strcmp(protocol, NGHTTP2_PROTO_VERSION_ID)) + conn->negnpn = CURL_HTTP_VERSION_2; + else +#endif + if(!strcmp(protocol, ALPN_HTTP_1_1)) + conn->negnpn = CURL_HTTP_VERSION_1_1; + else + infof(data, "ALPN, unrecognized protocol %s\n", protocol); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + } + + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + void *oldsession; + br_ssl_session_parameters *session; + + session = malloc(sizeof(*session)); + if(!session) + return CURLE_OUT_OF_MEMORY; + br_ssl_engine_get_session_parameters(&BACKEND->ctx.eng, session); + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, &oldsession, NULL, sockindex)); + if(incache) + Curl_ssl_delsessionid(conn, oldsession); + ret = Curl_ssl_addsessionid(conn, session, 0, sockindex); + Curl_ssl_sessionid_unlock(conn); + if(ret) { + free(session); + return CURLE_OUT_OF_MEMORY; + } + } + + connssl->connecting_state = ssl_connect_done; + + return CURLE_OK; +} + +static ssize_t bearssl_send(struct connectdata *conn, int sockindex, + const void *buf, size_t len, CURLcode *err) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned char *app; + size_t applen; + + for(;;) { + *err = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP); + if (*err != CURLE_OK) + return -1; + app = br_ssl_engine_sendapp_buf(&BACKEND->ctx.eng, &applen); + if(!app) { + failf(data, "SSL: connection closed during write"); + *err = CURLE_SEND_ERROR; + return -1; + } + if(BACKEND->pending_write) { + applen = BACKEND->pending_write; + BACKEND->pending_write = 0; + return applen; + } + if(applen > len) + applen = len; + memcpy(app, buf, applen); + br_ssl_engine_sendapp_ack(&BACKEND->ctx.eng, applen); + br_ssl_engine_flush(&BACKEND->ctx.eng, 0); + BACKEND->pending_write = applen; + } +} + +static ssize_t bearssl_recv(struct connectdata *conn, int sockindex, + char *buf, size_t len, CURLcode *err) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned char *app; + size_t applen; + + *err = bearssl_run_until(conn, sockindex, BR_SSL_RECVAPP); + if(*err != CURLE_OK) + return -1; + app = br_ssl_engine_recvapp_buf(&BACKEND->ctx.eng, &applen); + if(!app) + return 0; + if(applen > len) + applen = len; + memcpy(buf, app, applen); + br_ssl_engine_recvapp_ack(&BACKEND->ctx.eng, applen); + + return applen; +} + +static CURLcode bearssl_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode ret; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + time_t timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + ret = bearssl_connect_step1(conn, sockindex); + if(ret) + return ret; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if this + * connection is done nonblocking and this loop would execute again. This + * permits the owner of a multi handle to abort a connection attempt + * before step2 has completed while ensuring that a client using select() + * or epoll() will always have a valid fdset to wait on. + */ + ret = bearssl_connect_step2(conn, sockindex); + if(ret || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return ret; + } + + if(ssl_connect_3 == connssl->connecting_state) { + ret = bearssl_connect_step3(conn, sockindex); + if(ret) + return ret; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = bearssl_recv; + conn->send[sockindex] = bearssl_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static size_t Curl_bearssl_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "BearSSL"); +} + +static bool Curl_bearssl_data_pending(const struct connectdata *conn, + int connindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; + + return br_ssl_engine_current_state(&BACKEND->ctx.eng) & BR_SSL_RECVAPP; +} + +static CURLcode Curl_bearssl_random(struct Curl_easy *data UNUSED_PARAM, + unsigned char *entropy, size_t length) +{ + static br_hmac_drbg_context ctx; + static bool seeded = FALSE; + + if(!seeded) { + br_prng_seeder seeder; + + br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0); + seeder = br_prng_seeder_system(NULL); + if(!seeder || !seeder(&ctx.vtable)) + return CURLE_FAILED_INIT; + seeded = TRUE; + } + br_hmac_drbg_generate(&ctx, entropy, length); + + return CURLE_OK; +} + +static CURLcode Curl_bearssl_connect(struct connectdata *conn, int sockindex) +{ + CURLcode ret; + bool done = FALSE; + + ret = bearssl_connect_common(conn, sockindex, FALSE, &done); + if(ret) + return ret; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static CURLcode Curl_bearssl_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return bearssl_connect_common(conn, sockindex, TRUE, done); +} + +static void *Curl_bearssl_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + return &BACKEND->ctx; +} + +static void Curl_bearssl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + size_t i; + + if(BACKEND->active) { + br_ssl_engine_close(&BACKEND->ctx.eng); + (void)bearssl_run_until(conn, sockindex, BR_SSL_CLOSED); + } + for(i = 0; i < BACKEND->anchors_len; ++i) + free(BACKEND->anchors[i].dn.data); + free(BACKEND->anchors); +} + +static void Curl_bearssl_session_free(void *ptr) +{ + free(ptr); +} + +static CURLcode Curl_bearssl_md5sum(unsigned char *input, + size_t inputlen, + unsigned char *md5sum, + size_t md5len UNUSED_PARAM) +{ + br_md5_context ctx; + + br_md5_init(&ctx); + br_md5_update(&ctx, input, inputlen); + br_md5_out(&ctx, md5sum); + return CURLE_OK; +} + +static CURLcode Curl_bearssl_sha256sum(const unsigned char *input, + size_t inputlen, + unsigned char *sha256sum, + size_t sha256len UNUSED_PARAM) +{ + br_sha256_context ctx; + + br_sha256_init(&ctx); + br_sha256_update(&ctx, input, inputlen); + br_sha256_out(&ctx, sha256sum); + return CURLE_OK; +} + +const struct Curl_ssl Curl_ssl_bearssl = { + { CURLSSLBACKEND_BEARSSL, "bearssl" }, + + 0, + + sizeof(struct ssl_backend_data), + + Curl_none_init, + Curl_none_cleanup, + Curl_bearssl_version, + Curl_none_check_cxn, + Curl_none_shutdown, + Curl_bearssl_data_pending, + Curl_bearssl_random, + Curl_none_cert_status_request, + Curl_bearssl_connect, + Curl_bearssl_connect_nonblocking, + Curl_bearssl_get_internals, + Curl_bearssl_close, + Curl_none_close_all, + Curl_bearssl_session_free, + Curl_none_set_engine, + Curl_none_set_engine_default, + Curl_none_engines_list, + Curl_none_false_start, + Curl_bearssl_md5sum, + Curl_bearssl_sha256sum +}; + +#endif /* USE_BEARSSL */ diff --git a/libs/libcurl/src/vtls/bearssl.h b/libs/libcurl/src/vtls/bearssl.h new file mode 100644 index 0000000000..5f94922b92 --- /dev/null +++ b/libs/libcurl/src/vtls/bearssl.h @@ -0,0 +1,32 @@ +#ifndef HEADER_CURL_BEARSSL_H +#define HEADER_CURL_BEARSSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019, Michael Forney, <mforney@mforney.org> + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * 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_BEARSSL + +extern const struct Curl_ssl Curl_ssl_bearssl; + +#endif /* USE_BEARSSL */ +#endif /* HEADER_CURL_BEARSSL_H */ diff --git a/libs/libcurl/src/vtls/gskit.h b/libs/libcurl/src/vtls/gskit.h index 466ee4d9de..b06b5e17d3 100644 --- a/libs/libcurl/src/vtls/gskit.h +++ b/libs/libcurl/src/vtls/gskit.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, 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/vtls/mbedtls.h b/libs/libcurl/src/vtls/mbedtls.h index 4a938605bd..0cc64b3991 100644 --- a/libs/libcurl/src/vtls/mbedtls.h +++ b/libs/libcurl/src/vtls/mbedtls.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2019, 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 diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c index a375f00da2..ef51b0d912 100644 --- a/libs/libcurl/src/vtls/nss.c +++ b/libs/libcurl/src/vtls/nss.c @@ -113,7 +113,7 @@ typedef struct { ptr->type = (_type); \ ptr->pValue = (_val); \ ptr->ulValueLen = (_len); \ -} WHILE_FALSE +} while(0) #define CERT_NewTempCertificate __CERT_NewTempCertificate diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c index 760758d234..726ff6e7ca 100644 --- a/libs/libcurl/src/vtls/openssl.c +++ b/libs/libcurl/src/vtls/openssl.c @@ -142,10 +142,6 @@ #endif #endif -#ifdef LIBRESSL_VERSION_NUMBER -#define OpenSSL_version_num() LIBRESSL_VERSION_NUMBER -#endif - #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \ !(defined(LIBRESSL_VERSION_NUMBER) && \ LIBRESSL_VERSION_NUMBER < 0x20700000L) @@ -392,11 +388,20 @@ static const char *SSL_ERROR_to_str(int err) */ static char *ossl_strerror(unsigned long error, char *buf, size_t size) { + if(size) + *buf = '\0'; + #ifdef OPENSSL_IS_BORINGSSL ERR_error_string_n((uint32_t)error, buf, size); #else ERR_error_string_n(error, buf, size); #endif + + if(size > 1 && !*buf) { + strncpy(buf, (error ? "Unknown error" : "No error"), size); + buf[size - 1] = '\0'; + } + return buf; } @@ -2768,19 +2773,29 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) infof(data, " CRLfile: %s\n", ssl_crlfile); } - /* Try building a chain using issuers in the trusted store first to avoid - problems with server-sent legacy intermediates. Newer versions of - OpenSSL do alternate chain checking by default which gives us the same - fix without as much of a performance hit (slight), so we prefer that if - available. - https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest - */ -#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) if(verifypeer) { + /* Try building a chain using issuers in the trusted store first to avoid + problems with server-sent legacy intermediates. Newer versions of + OpenSSL do alternate chain checking by default which gives us the same + fix without as much of a performance hit (slight), so we prefer that if + available. + https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest + */ +#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), X509_V_FLAG_TRUSTED_FIRST); - } #endif +#ifdef X509_V_FLAG_PARTIAL_CHAIN + if(!SSL_SET_OPTION(no_partialchain)) { + /* Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert + only, instead of needing the whole chain. */ + X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_V_FLAG_PARTIAL_CHAIN); + } +#endif + } /* SSL always tries to verify the peer, this only says whether it should * fail to connect if the verification fails, or if it should continue @@ -2806,8 +2821,10 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* give application a chance to interfere with SSL set up. */ if(data->set.ssl.fsslctx) { + Curl_set_in_callback(data, true); result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx, data->set.ssl.fsslctxp); + Curl_set_in_callback(data, false); if(result) { failf(data, "error signaled by ssl ctx callback"); return result; @@ -2988,8 +3005,13 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; + char extramsg[80]=""; + int sockerr = SOCKERRNO; + if(sockerr && detail == SSL_ERROR_SYSCALL) + Curl_strerror(sockerr, extramsg, sizeof(extramsg)); failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ", - SSL_ERROR_to_str(detail), hostname, port); + extramsg[0] ? extramsg : SSL_ERROR_to_str(detail), + hostname, port); return result; } @@ -3065,7 +3087,7 @@ do { \ Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \ if(1 != BIO_reset(mem)) \ break; \ -} WHILE_FALSE +} while(0) static void pubkey_show(struct Curl_easy *data, BIO *mem, @@ -3097,7 +3119,7 @@ do { \ if(_type->_name) { \ pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \ } \ -} WHILE_FALSE +} while(0) #endif static int X509V3_ext(struct Curl_easy *data, @@ -3826,10 +3848,22 @@ static ssize_t ossl_send(struct connectdata *conn, *curlcode = CURLE_AGAIN; return -1; case SSL_ERROR_SYSCALL: - Curl_strerror(SOCKERRNO, error_buffer, sizeof(error_buffer)); - failf(conn->data, OSSL_PACKAGE " SSL_write: %s", error_buffer); - *curlcode = CURLE_SEND_ERROR; - return -1; + { + int sockerr = SOCKERRNO; + sslerror = ERR_get_error(); + if(sslerror) + ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); + else if(sockerr) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); + error_buffer[sizeof(error_buffer) - 1] = '\0'; + } + failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d", + error_buffer, sockerr); + *curlcode = CURLE_SEND_ERROR; + return -1; + } case SSL_ERROR_SSL: /* A failure in the SSL library occurred, usually a protocol error. The OpenSSL error queue contains more information on the error. */ @@ -3894,11 +3928,6 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ /* there's data pending, re-invoke SSL_read() */ *curlcode = CURLE_AGAIN; return -1; - case SSL_ERROR_SYSCALL: - Curl_strerror(SOCKERRNO, error_buffer, sizeof(error_buffer)); - failf(conn->data, OSSL_PACKAGE " SSL_read: %s", error_buffer); - *curlcode = CURLE_RECV_ERROR; - return -1; default: /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return value/errno" */ @@ -3907,14 +3936,44 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ if((nread < 0) || sslerror) { /* If the return code was negative or there actually is an error in the queue */ + int sockerr = SOCKERRNO; + if(sslerror) + ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); + else if(sockerr && err == SSL_ERROR_SYSCALL) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); + error_buffer[sizeof(error_buffer) - 1] = '\0'; + } failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d", - (sslerror ? - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)) : - SSL_ERROR_to_str(err)), - SOCKERRNO); + error_buffer, sockerr); *curlcode = CURLE_RECV_ERROR; return -1; } + /* For debug builds be a little stricter and error on any + SSL_ERROR_SYSCALL. For example a server may have closed the connection + abruptly without a close_notify alert. For compatibility with older + peers we don't do this by default. #4624 + + We can use this to gauge how many users may be affected, and + if it goes ok eventually transition to allow in dev and release with + the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ +#ifdef DEBUGBUILD + if(err == SSL_ERROR_SYSCALL) { + int sockerr = SOCKERRNO; + if(sockerr) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + msnprintf(error_buffer, sizeof(error_buffer), + "Connection closed abruptly"); + } + failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d" + " (Fatal because this is a curl debug build)", + error_buffer, sockerr); + *curlcode = CURLE_RECV_ERROR; + return -1; + } +#endif } } return nread; @@ -3922,13 +3981,35 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ static size_t Curl_ossl_version(char *buffer, size_t size) { -#ifdef OPENSSL_IS_BORINGSSL +#ifdef LIBRESSL_VERSION_NUMBER +#if LIBRESSL_VERSION_NUMBER < 0x2070100fL + return msnprintf(buffer, size, "%s/%lx.%lx.%lx", + OSSL_PACKAGE, + (LIBRESSL_VERSION_NUMBER>>28)&0xf, + (LIBRESSL_VERSION_NUMBER>>20)&0xff, + (LIBRESSL_VERSION_NUMBER>>12)&0xff); +#else /* OpenSSL_version() first appeared in LibreSSL 2.7.1 */ + char *p; + int count; + const char *ver = OpenSSL_version(OPENSSL_VERSION); + const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ + if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) { + ver += sizeof(expected) - 1; + } + count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); + for(p = buffer; *p; ++p) { + if(ISSPACE(*p)) + *p = '_'; + } + return count; +#endif +#elif defined(OPENSSL_IS_BORINGSSL) return msnprintf(buffer, size, OSSL_PACKAGE); #elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING) return msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); #else - /* not BoringSSL and not using OpenSSL_version */ + /* not LibreSSL, BoringSSL and not using OpenSSL_version */ char sub[3]; unsigned long ssleay_value; diff --git a/libs/libcurl/src/vtls/polarssl.h b/libs/libcurl/src/vtls/polarssl.h index 23c3636ee6..f36f24f8df 100644 --- a/libs/libcurl/src/vtls/polarssl.h +++ b/libs/libcurl/src/vtls/polarssl.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2019, 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 diff --git a/libs/libcurl/src/vtls/polarssl_threadlock.c b/libs/libcurl/src/vtls/polarssl_threadlock.c index 27c94b11e2..4e269c8e6a 100644 --- a/libs/libcurl/src/vtls/polarssl_threadlock.c +++ b/libs/libcurl/src/vtls/polarssl_threadlock.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2013-2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2013 - 2019, 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 diff --git a/libs/libcurl/src/vtls/polarssl_threadlock.h b/libs/libcurl/src/vtls/polarssl_threadlock.h index 122647528d..c1900bfe81 100644 --- a/libs/libcurl/src/vtls/polarssl_threadlock.h +++ b/libs/libcurl/src/vtls/polarssl_threadlock.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2013 - 2019, 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 diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index bbd2fe921c..dc58ed0d3b 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.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 @@ -554,10 +554,6 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) switch(conn->ssl_config.version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT | - SP_PROT_TLS1_1_CLIENT | - SP_PROT_TLS1_2_CLIENT; - break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: case CURL_SSLVERSION_TLSv1_2: @@ -1859,7 +1855,9 @@ schannel_recv(struct connectdata *conn, int sockindex, goto cleanup; } else { +#ifndef CURL_DISABLE_VERBOSE_STRINGS char buffer[STRERROR_LEN]; +#endif *err = CURLE_RECV_ERROR; infof(data, "schannel: failed to read data from server: %s\n", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c index 1bdf50a55c..3a668adc76 100644 --- a/libs/libcurl/src/vtls/schannel_verify.c +++ b/libs/libcurl/src/vtls/schannel_verify.c @@ -99,7 +99,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: invalid path name for CA file '%s': %s", - ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -120,7 +121,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: failed to open CA file '%s': %s", - ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -129,7 +131,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: failed to determine size of CA file '%s': %s", - ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -159,7 +162,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: failed to read from CA file '%s': %s", - ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -223,7 +227,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, "schannel: failed to extract certificate from CA file " "'%s': %s", ca_file, - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -252,7 +256,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, "schannel: failed to add certificate from CA file '%s' " "to certificate store: %s", ca_file, - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, + sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -460,7 +465,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) if(!trust_store) { char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate store: %s", - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } else { @@ -489,7 +494,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate chain engine: %s", - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } } @@ -512,7 +517,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) &pChainContext)) { char buffer[STRERROR_LEN]; failf(data, "schannel: CertGetCertificateChain failed: %s", - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); pChainContext = NULL; result = CURLE_PEER_FAILED_VERIFICATION; } diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c index e6d7562254..c493b15169 100644 --- a/libs/libcurl/src/vtls/vtls.c +++ b/libs/libcurl/src/vtls/vtls.c @@ -517,7 +517,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_MBEDTLS) || defined(USE_WOLFSSL) + defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_BEARSSL) int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks) { struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; @@ -1189,6 +1189,8 @@ const struct Curl_ssl *Curl_ssl = &Curl_ssl_schannel; #elif defined(USE_MESALINK) &Curl_ssl_mesalink; +#elif defined(USE_BEARSSL) + &Curl_ssl_bearssl; #else #error "Missing struct Curl_ssl for selected SSL backend" #endif @@ -1224,6 +1226,9 @@ static const struct Curl_ssl *available_backends[] = { #if defined(USE_MESALINK) &Curl_ssl_mesalink, #endif +#if defined(USE_BEARSSL) + &Curl_ssl_bearssl, +#endif NULL }; diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index 61d8416c29..976cc43601 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -108,6 +108,7 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, #include "sectransp.h" /* SecureTransport (Darwin) version */ #include "mbedtls.h" /* mbedTLS versions */ #include "mesalink.h" /* MesaLink versions */ +#include "bearssl.h" /* BearSSL versions */ #ifndef MAX_PINNED_PUBKEY_SIZE #define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */ |