aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2019-01-08 14:27:10 -0800
committerHaibo Huang <hhb@google.com>2019-01-14 23:02:29 +0000
commit21926d584a5b118cbff81a9fb4329059011f87c6 (patch)
tree421b037a92a6d5209e8e4c30e8a830c262abe6d4 /lib
parent98caa6f514b401764e3ac76041ff7e006f109e8c (diff)
downloadexternal_curl-21926d584a5b118cbff81a9fb4329059011f87c6.tar.gz
external_curl-21926d584a5b118cbff81a9fb4329059011f87c6.tar.bz2
external_curl-21926d584a5b118cbff81a9fb4329059011f87c6.zip
Upgrade curl from 7.62.0 to 7.63.0
Test: build, boots, `vendor/google/tools/fake-ota on streaming` works Change-Id: Iecd6120501e7a6d2c8b83c2891de62163a30f08a
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.Watcom2
-rw-r--r--lib/Makefile.inc4
-rw-r--r--lib/Makefile.netware27
-rw-r--r--lib/asyn-ares.c33
-rw-r--r--lib/asyn-thread.c11
-rw-r--r--lib/asyn.h9
-rw-r--r--lib/base64.c26
-rwxr-xr-xlib/checksrc.pl118
-rw-r--r--lib/conncache.c2
-rw-r--r--lib/connect.c8
-rw-r--r--lib/cookie.c67
-rw-r--r--lib/curl_config.h6
-rw-r--r--lib/curl_config.h.in6
-rw-r--r--lib/curl_gssapi.c6
-rw-r--r--lib/curl_multibyte.c12
-rw-r--r--lib/curl_ntlm_core.c34
-rw-r--r--lib/curl_printf.h16
-rw-r--r--lib/curl_setup.h2
-rw-r--r--lib/curlx.h11
-rw-r--r--lib/doh.c43
-rw-r--r--lib/easy.c10
-rw-r--r--lib/escape.c2
-rw-r--r--lib/file.c25
-rw-r--r--lib/ftp.c30
-rw-r--r--lib/ftplistparser.c2
-rw-r--r--lib/hostcheck.c5
-rw-r--r--lib/hostip4.c4
-rw-r--r--lib/hostip6.c2
-rw-r--r--lib/http.c78
-rw-r--r--lib/http2.c10
-rw-r--r--lib/http2.h4
-rw-r--r--lib/http_negotiate.c8
-rw-r--r--lib/if2ip.c6
-rw-r--r--lib/imap.c4
-rw-r--r--lib/inet_ntop.c12
-rw-r--r--lib/ldap.c15
-rw-r--r--lib/libcurl.plist6
-rw-r--r--lib/libcurl.rc12
-rw-r--r--lib/md4.c1
-rw-r--r--lib/md5.c7
-rw-r--r--lib/memdebug.c4
-rw-r--r--lib/mprintf.c2
-rw-r--r--lib/multi.c66
-rw-r--r--lib/multiif.h10
-rw-r--r--lib/netrc.c11
-rw-r--r--lib/netrc.h2
-rw-r--r--lib/openldap.c4
-rw-r--r--lib/pop3.c14
-rw-r--r--lib/progress.c36
-rw-r--r--lib/security.c4
-rw-r--r--lib/sendf.c15
-rw-r--r--lib/setopt.c6
-rw-r--r--lib/socks_gssapi.c6
-rw-r--r--lib/socks_sspi.c8
-rw-r--r--lib/ssh-libssh.c24
-rw-r--r--lib/ssh.c26
-rw-r--r--lib/strerror.c26
-rw-r--r--lib/telnet.c30
-rw-r--r--lib/tftp.c14
-rw-r--r--lib/transfer.c47
-rw-r--r--lib/url.c160
-rw-r--r--lib/urlapi-int.h5
-rw-r--r--lib/urlapi.c61
-rw-r--r--lib/urldata.h2
-rw-r--r--lib/vauth/digest.c10
-rw-r--r--lib/vauth/ntlm.c222
-rw-r--r--lib/version.c36
-rw-r--r--lib/vtls/axtls.c741
-rw-r--r--lib/vtls/axtls.h33
-rw-r--r--lib/vtls/cyassl.c8
-rw-r--r--lib/vtls/darwinssl.c26
-rw-r--r--lib/vtls/gskit.c2
-rw-r--r--lib/vtls/gtls.c26
-rw-r--r--lib/vtls/mbedtls.c6
-rw-r--r--lib/vtls/mesalink.c6
-rw-r--r--lib/vtls/nss.c72
-rw-r--r--lib/vtls/openssl.c252
-rw-r--r--lib/vtls/polarssl.c8
-rw-r--r--lib/vtls/schannel.c83
-rw-r--r--lib/vtls/schannel.h4
-rw-r--r--lib/vtls/schannel_verify.c4
-rw-r--r--lib/vtls/vtls.c16
-rw-r--r--lib/vtls/vtls.h1
-rw-r--r--lib/x509asn1.c2
84 files changed, 1232 insertions, 1595 deletions
diff --git a/lib/Makefile.Watcom b/lib/Makefile.Watcom
index 5f335ced..942cd0c7 100644
--- a/lib/Makefile.Watcom
+++ b/lib/Makefile.Watcom
@@ -157,7 +157,7 @@ CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H -I"$(LIBSSH2_ROOT)/include" -I"$(LIBSSH
!endif
!ifdef %use_ssl
-CFLAGS += -wcd=138 -dUSE_OPENSSL -dUSE_SSLEAY -I"$(OPENSSL_ROOT)/inc32"
+CFLAGS += -wcd=138 -dUSE_OPENSSL -I"$(OPENSSL_ROOT)/inc32"
!endif
!ifdef %use_ares
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 4aa04225..54acd6ce 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -28,12 +28,12 @@ LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \
LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
- vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \
+ vtls/polarssl.c vtls/polarssl_threadlock.c \
vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \
vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c
LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
- vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \
+ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \
vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h \
vtls/mbedtls.h vtls/mesalink.h
diff --git a/lib/Makefile.netware b/lib/Makefile.netware
index fa6beec0..29885a19 100644
--- a/lib/Makefile.netware
+++ b/lib/Makefile.netware
@@ -6,7 +6,7 @@
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2004 - 2015, Guenter Knauf
-# Copyright (C) 2001 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 2001 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -49,11 +49,6 @@ ifndef LIBSSH2_PATH
LIBSSH2_PATH = ../../libssh2-1.5.0
endif
-# Edit the path below to point to the base of your axTLS package.
-ifndef AXTLS_PATH
-AXTLS_PATH = ../../axTLS-1.2.7
-endif
-
# Edit the path below to point to the base of your libidn package.
ifndef LIBIDN_PATH
LIBIDN_PATH = ../../libidn-1.18
@@ -230,10 +225,6 @@ WITH_SSH2 = 1
WITH_SSL = 1
WITH_ZLIB = 1
endif
-ifeq ($(findstring -axtls,$(CFG)),-axtls)
-WITH_AXTLS = 1
-WITH_SSL =
-else
ifeq ($(findstring -ssl,$(CFG)),-ssl)
WITH_SSL = 1
ifeq ($(findstring -srp,$(CFG)),-srp)
@@ -242,7 +233,6 @@ WITH_SRP = 1
endif
endif
endif
-endif
ifeq ($(findstring -zlib,$(CFG)),-zlib)
WITH_ZLIB = 1
endif
@@ -280,16 +270,6 @@ ifdef WITH_SSL
IMPORTS += GetProcessSwitchCount RunningProcess
INSTDEP += ca-bundle.crt
else
-ifdef WITH_AXTLS
- INCLUDES += -I$(AXTLS_PATH)/inc
- ifdef LINK_STATIC
- LDLIBS += $(AXTLS_PATH)/lib/libaxtls.$(LIBEXT)
- else
- MODULES += libaxtls.nlm
- IMPORTS += $(AXTLS_PATH)/lib/libaxtls.imp
- endif
- INSTDEP += ca-bundle.crt
-endif
endif
ifdef WITH_ZLIB
INCLUDES += -I$(ZLIB_PATH)
@@ -652,7 +632,6 @@ ifdef WITH_ZLIB
@echo $(DL)#define HAVE_LIBZ 1$(DL) >> $@
endif
ifdef WITH_SSL
- @echo $(DL)#define USE_SSLEAY 1$(DL) >> $@
@echo $(DL)#define USE_OPENSSL 1$(DL) >> $@
@echo $(DL)#define HAVE_OPENSSL_X509_H 1$(DL) >> $@
@echo $(DL)#define HAVE_OPENSSL_SSL_H 1$(DL) >> $@
@@ -665,16 +644,12 @@ ifdef WITH_SSL
@echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@
@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@
ifdef WITH_SRP
- @echo $(DL)#define HAVE_SSLEAY_SRP 1$(DL) >> $@
@echo $(DL)#define USE_TLS_SRP 1$(DL) >> $@
endif
ifdef WITH_SPNEGO
@echo $(DL)#define HAVE_SPNEGO 1$(DL) >> $@
endif
else
-ifdef WITH_AXTLS
- @echo $(DL)#define USE_AXTLS 1$(DL) >> $@
-endif
endif
ifdef WITH_SSH2
@echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@
diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c
index 5cfb2602..6a49566c 100644
--- a/lib/asyn-ares.c
+++ b/lib/asyn-ares.c
@@ -119,6 +119,17 @@ void Curl_resolver_global_cleanup(void)
#endif
}
+
+static void Curl_ares_sock_state_cb(void *data, ares_socket_t socket_fd,
+ int readable, int writable)
+{
+ struct Curl_easy *easy = data;
+ if(!readable && !writable) {
+ DEBUGASSERT(easy);
+ Curl_multi_closed(easy, socket_fd);
+ }
+}
+
/*
* Curl_resolver_init()
*
@@ -126,9 +137,14 @@ void Curl_resolver_global_cleanup(void)
* URL-state specific environment ('resolver' member of the UrlState
* structure). Fills the passed pointer by the initialized ares_channel.
*/
-CURLcode Curl_resolver_init(void **resolver)
+CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
{
- int status = ares_init((ares_channel*)resolver);
+ int status;
+ struct ares_options options;
+ int optmask = ARES_OPT_SOCK_STATE_CB;
+ options.sock_state_cb = Curl_ares_sock_state_cb;
+ options.sock_state_cb_data = easy;
+ status = ares_init_options((ares_channel*)resolver, &options, optmask);
if(status != ARES_SUCCESS) {
if(status == ARES_ENOMEM)
return CURLE_OUT_OF_MEMORY;
@@ -159,12 +175,15 @@ void Curl_resolver_cleanup(void *resolver)
* environment ('resolver' member of the UrlState structure). Duplicates the
* 'from' ares channel and passes the resulting channel to the 'to' pointer.
*/
-int Curl_resolver_duphandle(void **to, void *from)
+CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
{
- /* Clone the ares channel for the new handle */
- if(ARES_SUCCESS != ares_dup((ares_channel*)to, (ares_channel)from))
- return CURLE_FAILED_INIT;
- return CURLE_OK;
+ (void)from;
+ /*
+ * it would be better to call ares_dup instead, but right now
+ * it is not possible to set 'sock_state_cb_data' outside of
+ * ares_init_options
+ */
+ return Curl_resolver_init(easy, to);
}
static void destroy_async_data(struct Curl_async *async);
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index 2a59294e..74208d7e 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -108,8 +108,9 @@ void Curl_resolver_global_cleanup(void)
* URL-state specific environment ('resolver' member of the UrlState
* structure).
*/
-CURLcode Curl_resolver_init(void **resolver)
+CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
{
+ (void)easy;
*resolver = calloc(1, sizeof(struct resdata));
if(!*resolver)
return CURLE_OUT_OF_MEMORY;
@@ -132,10 +133,10 @@ void Curl_resolver_cleanup(void *resolver)
* Called from curl_easy_duphandle() to duplicate resolver URL state-specific
* environment ('resolver' member of the UrlState structure).
*/
-int Curl_resolver_duphandle(void **to, void *from)
+CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
{
(void)from;
- return Curl_resolver_init(to);
+ return Curl_resolver_init(easy, to);
}
static void destroy_async_data(struct Curl_async *);
@@ -276,7 +277,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
char service[12];
int rc;
- snprintf(service, sizeof(service), "%d", tsd->port);
+ msnprintf(service, sizeof(service), "%d", tsd->port);
rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
@@ -678,7 +679,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
hints.ai_family = pf;
hints.ai_socktype = conn->socktype;
- snprintf(sbuf, sizeof(sbuf), "%d", port);
+ msnprintf(sbuf, sizeof(sbuf), "%d", port);
reslv->start = Curl_now();
/* fire up a new resolver thread! */
diff --git a/lib/asyn.h b/lib/asyn.h
index 3adc3664..43625bc3 100644
--- a/lib/asyn.h
+++ b/lib/asyn.h
@@ -60,7 +60,7 @@ void Curl_resolver_global_cleanup(void);
* Returning anything else than CURLE_OK fails curl_easy_init() with the
* correspondent code.
*/
-CURLcode Curl_resolver_init(void **resolver);
+CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver);
/*
* Curl_resolver_cleanup()
@@ -79,7 +79,8 @@ void Curl_resolver_cleanup(void *resolver);
* pointer. Returning anything else than CURLE_OK causes failed
* curl_easy_duphandle() call.
*/
-int Curl_resolver_duphandle(void **to, void *from);
+CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to,
+ void *from);
/*
* Curl_resolver_cancel().
@@ -150,8 +151,8 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
#define Curl_resolver_getsock(x,y,z) 0
-#define Curl_resolver_duphandle(x,y) CURLE_OK
-#define Curl_resolver_init(x) CURLE_OK
+#define Curl_resolver_duphandle(x,y,z) CURLE_OK
+#define Curl_resolver_init(x,y) CURLE_OK
#define Curl_resolver_global_init() CURLE_OK
#define Curl_resolver_global_cleanup() Curl_nop_stmt
#define Curl_resolver_cleanup(x) Curl_nop_stmt
diff --git a/lib/base64.c b/lib/base64.c
index 6370e4cd..431b6435 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -233,24 +233,24 @@ static CURLcode base64_encode(const char *table64,
switch(inputparts) {
case 1: /* only one byte read */
- snprintf(output, 5, "%c%c==",
- table64[obuf[0]],
- table64[obuf[1]]);
+ msnprintf(output, 5, "%c%c==",
+ table64[obuf[0]],
+ table64[obuf[1]]);
break;
case 2: /* two bytes read */
- snprintf(output, 5, "%c%c%c=",
- table64[obuf[0]],
- table64[obuf[1]],
- table64[obuf[2]]);
+ msnprintf(output, 5, "%c%c%c=",
+ table64[obuf[0]],
+ table64[obuf[1]],
+ table64[obuf[2]]);
break;
default:
- snprintf(output, 5, "%c%c%c%c",
- table64[obuf[0]],
- table64[obuf[1]],
- table64[obuf[2]],
- table64[obuf[3]]);
+ msnprintf(output, 5, "%c%c%c%c",
+ table64[obuf[0]],
+ table64[obuf[1]],
+ table64[obuf[2]],
+ table64[obuf[3]]);
break;
}
output += 4;
diff --git a/lib/checksrc.pl b/lib/checksrc.pl
index 15e9aff8..965f0bab 100755
--- a/lib/checksrc.pl
+++ b/lib/checksrc.pl
@@ -35,6 +35,7 @@ my $suppressed; # whitelisted problems
my $file;
my $dir=".";
my $wlist="";
+my @alist;
my $windows_os = $^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'cygwin';
my $verbose;
my %whitelist;
@@ -44,6 +45,10 @@ my %ignore_set;
my %ignore_used;
my @ignore_line;
+my %warnings_extended = (
+ 'COPYRIGHTYEAR' => 'copyright year incorrect',
+ );
+
my %warnings = (
'LONGLINE' => "Line longer than $max_column",
'TABS' => 'TAB characters not allowed',
@@ -74,6 +79,7 @@ my %warnings = (
'SEMINOSPACE' => 'semicolon without following space',
'MULTISPACE' => 'multiple spaces used when not suitable',
'SIZEOFNOPAREN' => 'use of sizeof without parentheses',
+ 'SNPRINTF' => 'use of snprintf',
);
sub readwhitelist {
@@ -86,6 +92,35 @@ sub readwhitelist {
close(W);
}
+# Reads the .checksrc in $dir for any extended warnings to enable locally.
+# Currently there is no support for disabling warnings from the standard set,
+# and since that's already handled via !checksrc! commands there is probably
+# little use to add it.
+sub readlocalfile {
+ my $i = 0;
+
+ open(my $rcfile, "<", "$dir/.checksrc") or return;
+
+ while(<$rcfile>) {
+ $i++;
+
+ # Lines starting with '#' are considered comments
+ if (/^\s*(#.*)/) {
+ next;
+ }
+ elsif (/^\s*enable ([A-Z]+)$/) {
+ if(!defined($warnings_extended{$1})) {
+ print STDERR "invalid warning specified in .checksrc: \"$1\"\n";
+ next;
+ }
+ $warnings{$1} = $warnings_extended{$1};
+ }
+ else {
+ die "Invalid format in $dir/.checksrc on line $i\n";
+ }
+ }
+}
+
sub checkwarn {
my ($name, $num, $col, $file, $line, $msg, $error) = @_;
@@ -153,6 +188,11 @@ while(1) {
$file = shift @ARGV;
next;
}
+ elsif($file =~ /-A(.+)/) {
+ push @alist, $1;
+ $file = shift @ARGV;
+ next;
+ }
elsif($file =~ /-i([1-9])/) {
$indent = $1 + 0;
$file = shift @ARGV;
@@ -174,6 +214,7 @@ while(1) {
if(!$file) {
print "checksrc.pl [option] <file1> [file2] ...\n";
print " Options:\n";
+ print " -A[rule] Accept this violation, can be used multiple times\n";
print " -D[DIR] Directory to prepend file names\n";
print " -h Show help output\n";
print " -W[file] Whitelist the given file - ignore all its flaws\n";
@@ -187,6 +228,7 @@ if(!$file) {
}
readwhitelist();
+readlocalfile();
do {
if("$wlist" !~ / $file /) {
@@ -198,6 +240,17 @@ do {
} while($file);
+sub accept_violations {
+ for my $r (@alist) {
+ if(!$warnings{$r}) {
+ print "'$r' is not a warning to accept!\n";
+ exit;
+ }
+ $ignore{$r}=999999;
+ $ignore_used{$r}=0;
+ }
+}
+
sub checksrc_clear {
undef %ignore;
undef %ignore_set;
@@ -295,8 +348,9 @@ sub scanfile {
open(R, "<$file") || die "failed to open $file";
my $incomment=0;
- my $copyright=0;
+ my @copyright=();
checksrc_clear(); # for file based ignores
+ accept_violations();
while(<R>) {
$windows_os ? $_ =~ s/\r?\n$// : chomp;
@@ -310,9 +364,16 @@ sub scanfile {
checksrc($cmd, $line, $file, $l)
}
- # check for a copyright statement
- if(!$copyright && ($l =~ /copyright .* \d\d\d\d/i)) {
- $copyright=1;
+ # check for a copyright statement and save the years
+ if($l =~ /\* +copyright .* \d\d\d\d/i) {
+ while($l =~ /([\d]{4})/g) {
+ push @copyright, {
+ year => $1,
+ line => $line,
+ col => index($l, $1),
+ code => $l
+ };
+ }
}
# detect long lines
@@ -511,6 +572,13 @@ sub scanfile {
"use of $2 is banned");
}
+ # scan for use of snprintf for curl-internals reasons
+ if($l =~ /^(.*\W)(v?snprintf)\s*\(/x) {
+ checkwarn("SNPRINTF",
+ $line, length($1), $file, $ol,
+ "use of $2 is banned");
+ }
+
# scan for use of non-binary fopen without the macro
if($l =~ /^(.*\W)fopen\s*\([^,]*, *\"([^"]*)/) {
my $mode = $2;
@@ -623,9 +691,49 @@ sub scanfile {
$prevl = $ol;
}
- if(!$copyright) {
+ if(!scalar(@copyright)) {
checkwarn("COPYRIGHT", 1, 0, $file, "", "Missing copyright statement", 1);
}
+
+ # COPYRIGHTYEAR is a extended warning so we must first see if it has been
+ # enabled in .checksrc
+ if(defined($warnings{"COPYRIGHTYEAR"})) {
+ # The check for updated copyrightyear is overly complicated in order to
+ # not punish current hacking for past sins. The copyright years are
+ # right now a bit behind, so enforcing copyright year checking on all
+ # files would cause hundreds of errors. Instead we only look at files
+ # which are tracked in the Git repo and edited in the workdir, or
+ # committed locally on the branch without being in upstream master.
+ #
+ # The simple and naive test is to simply check for the current year,
+ # but updating the year even without an edit is against project policy
+ # (and it would fail every file on January 1st).
+ #
+ # A rather more interesting, and correct, check would be to not test
+ # only locally committed files but inspect all files wrt the year of
+ # their last commit. Removing the `git rev-list origin/master..HEAD`
+ # condition below will enfore copyright year checks against the year
+ # the file was last committed (and thus edited to some degree).
+ my $commityear = undef;
+ @copyright = sort {$$b{year} cmp $$a{year}} @copyright;
+
+ 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;
+ }
+
+ if(defined($commityear) && scalar(@copyright) &&
+ $copyright[0]{year} != $commityear) {
+ checkwarn("COPYRIGHTYEAR", $copyright[0]{line}, $copyright[0]{col},
+ $file, $copyright[0]{code},
+ "Copyright year out of date, should be $commityear, " .
+ "is $copyright[0]{year}", 1);
+ }
+ }
+
if($incomment) {
checkwarn("OPENCOMMENT", 1, 0, $file, "", "Missing closing comment", 1);
}
diff --git a/lib/conncache.c b/lib/conncache.c
index 6fbf3b1d..08e9042a 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -175,7 +175,7 @@ static void hashkey(struct connectdata *conn, char *buf,
DEBUGASSERT(len > 32);
/* put the number first so that the hostname gets cut off if too long */
- snprintf(buf, len, "%ld%s", conn->port, hostname);
+ msnprintf(buf, len, "%ld%s", conn->port, hostname);
}
void Curl_conncache_unlock(struct connectdata *conn)
diff --git a/lib/connect.c b/lib/connect.c
index 41f22026..ec3cd3a7 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -522,7 +522,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
err = 0;
}
#endif
-#ifdef __minix
+#if defined(EBADIOCTL) && defined(__minix)
/* Minix 3.1.x doesn't support getsockopt on UDP sockets */
if(EBADIOCTL == err) {
SET_SOCKERRNO(0);
@@ -655,7 +655,7 @@ bool Curl_getaddressinfo(struct sockaddr *sa, char *addr,
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
case AF_UNIX:
su = (struct sockaddr_un*)sa;
- snprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
+ msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
*port = 0;
return TRUE;
#endif
@@ -1314,7 +1314,7 @@ int Curl_closesocket(struct connectdata *conn,
conn->sock_accepted[SECONDARYSOCKET] = FALSE;
else {
int rc;
- Curl_multi_closed(conn, sock);
+ Curl_multi_closed(conn->data, sock);
Curl_set_in_callback(conn->data, true);
rc = conn->fclosesocket(conn->closesocket_client, sock);
Curl_set_in_callback(conn->data, false);
@@ -1324,7 +1324,7 @@ int Curl_closesocket(struct connectdata *conn,
if(conn)
/* tell the multi-socket code about this */
- Curl_multi_closed(conn, sock);
+ Curl_multi_closed(conn->data, sock);
sclose(sock);
diff --git a/lib/cookie.c b/lib/cookie.c
index 5b7ab663..3dc85ee5 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -675,7 +675,10 @@ Curl_cookie_add(struct Curl_easy *data,
/* overflow, used max value */
co->expires = CURL_OFF_T_MAX;
else if(!offt) {
- if(CURL_OFF_T_MAX - now < co->expires)
+ if(!co->expires)
+ /* already expired */
+ co->expires = 1;
+ else if(CURL_OFF_T_MAX - now < co->expires)
/* would overflow */
co->expires = CURL_OFF_T_MAX;
else
@@ -1456,22 +1459,9 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
unsigned int j;
struct Cookie **array;
- if((NULL == c) || (0 == c->numcookies))
- /* If there are no known cookies, we don't write or even create any
- destination file */
- return 0;
-
/* at first, remove expired cookies */
remove_expired(c);
- /* make sure we still have cookies after expiration */
- if(0 == c->numcookies)
- return 0;
-
- array = malloc(sizeof(struct Cookie *) * c->numcookies);
- if(!array)
- return 1;
-
if(!strcmp("-", dumphere)) {
/* use stdout */
out = stdout;
@@ -1480,7 +1470,6 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
else {
out = fopen(dumphere, FOPEN_WRITETEXT);
if(!out) {
- free(array);
return 1; /* failure */
}
}
@@ -1490,32 +1479,40 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
"# This file was generated by libcurl! Edit at your own risk.\n\n",
out);
- j = 0;
- for(i = 0; i < COOKIE_HASH_SIZE; i++) {
- for(co = c->cookies[i]; co; co = co->next) {
- if(!co->domain)
- continue;
- array[j++] = co;
- }
- }
-
- qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct);
-
- for(i = 0; i < j; i++) {
- format_ptr = get_netscape_format(array[i]);
- if(format_ptr == NULL) {
- fprintf(out, "#\n# Fatal libcurl error\n");
- free(array);
+ if(c->numcookies) {
+ array = malloc(sizeof(struct Cookie *) * c->numcookies);
+ if(!array) {
if(!use_stdout)
fclose(out);
return 1;
}
- fprintf(out, "%s\n", format_ptr);
- free(format_ptr);
- }
- free(array);
+ j = 0;
+ for(i = 0; i < COOKIE_HASH_SIZE; i++) {
+ for(co = c->cookies[i]; co; co = co->next) {
+ if(!co->domain)
+ continue;
+ array[j++] = co;
+ }
+ }
+ qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct);
+
+ for(i = 0; i < j; i++) {
+ format_ptr = get_netscape_format(array[i]);
+ if(format_ptr == NULL) {
+ fprintf(out, "#\n# Fatal libcurl error\n");
+ free(array);
+ if(!use_stdout)
+ fclose(out);
+ return 1;
+ }
+ fprintf(out, "%s\n", format_ptr);
+ free(format_ptr);
+ }
+
+ free(array);
+ }
if(!use_stdout)
fclose(out);
diff --git a/lib/curl_config.h b/lib/curl_config.h
index 853c6728..72d2a548 100644
--- a/lib/curl_config.h
+++ b/lib/curl_config.h
@@ -176,9 +176,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_cleanup' function. */
-/* #undef HAVE_ENGINE_CLEANUP */
-
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
@@ -911,9 +908,6 @@
/* Define to enable c-ares support */
/* #undef USE_ARES */
-/* if axTLS is enabled */
-/* #undef USE_AXTLS */
-
/* if CyaSSL/WolfSSL is enabled */
/* #undef USE_CYASSL */
diff --git a/lib/curl_config.h.in b/lib/curl_config.h.in
index 477d61eb..781006f2 100644
--- a/lib/curl_config.h.in
+++ b/lib/curl_config.h.in
@@ -175,9 +175,6 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
-/* Define to 1 if you have the `ENGINE_cleanup' function. */
-#undef HAVE_ENGINE_CLEANUP
-
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
@@ -928,9 +925,6 @@
/* Define to enable c-ares support */
#undef USE_ARES
-/* if axTLS is enabled */
-#undef USE_AXTLS
-
/* if CyaSSL/WolfSSL is enabled */
#undef USE_CYASSL
diff --git a/lib/curl_gssapi.c b/lib/curl_gssapi.c
index f007986c..d854ab0c 100644
--- a/lib/curl_gssapi.c
+++ b/lib/curl_gssapi.c
@@ -97,9 +97,9 @@ static size_t display_gss_error(OM_uint32 status, int type,
&msg_ctx,
&status_string);
if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) {
- len += snprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
- "%.*s. ", (int)status_string.length,
- (char *)status_string.value);
+ len += msnprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
+ "%.*s. ", (int)status_string.length,
+ (char *)status_string.value);
}
gss_release_buffer(&min_stat, &status_string);
} while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
diff --git a/lib/curl_multibyte.c b/lib/curl_multibyte.c
index e78bb500..e48334fa 100644
--- a/lib/curl_multibyte.c
+++ b/lib/curl_multibyte.c
@@ -64,13 +64,13 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
char *str_utf8 = NULL;
if(str_w) {
- int str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
- 0, NULL, NULL);
- if(str_utf8_len > 0) {
- str_utf8 = malloc(str_utf8_len * sizeof(wchar_t));
+ int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1,
+ NULL, 0, NULL, NULL);
+ if(bytes > 0) {
+ str_utf8 = malloc(bytes);
if(str_utf8) {
- if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
- NULL, FALSE) == 0) {
+ if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes,
+ NULL, NULL) == 0) {
free(str_utf8);
return NULL;
}
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 922e85a9..9eb6c43c 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -54,23 +54,13 @@
#ifdef USE_OPENSSL
-# ifdef USE_OPENSSL
-# include <openssl/des.h>
-# ifndef OPENSSL_NO_MD4
-# include <openssl/md4.h>
-# endif
-# include <openssl/md5.h>
-# include <openssl/ssl.h>
-# include <openssl/rand.h>
-# else
-# include <des.h>
-# ifndef OPENSSL_NO_MD4
-# include <md4.h>
-# endif
-# include <md5.h>
-# include <ssl.h>
-# include <rand.h>
+# include <openssl/des.h>
+# ifndef OPENSSL_NO_MD4
+# include <openssl/md4.h>
# endif
+# include <openssl/md5.h>
+# include <openssl/ssl.h>
+# include <openssl/rand.h>
# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
# define DES_key_schedule des_key_schedule
# define DES_cblock des_cblock
@@ -753,12 +743,12 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
return CURLE_OUT_OF_MEMORY;
/* Create the BLOB structure */
- snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
- "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
- "%c%c%c%c", /* Reserved = 0 */
- NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
- NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
- 0, 0, 0, 0);
+ msnprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
+ "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
+ "%c%c%c%c", /* Reserved = 0 */
+ NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
+ NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
+ 0, 0, 0, 0);
Curl_write64_le(tw, ptr + 24);
memcpy(ptr + 32, challenge_client, 8);
diff --git a/lib/curl_printf.h b/lib/curl_printf.h
index 49857cdb..0d37b8e5 100644
--- a/lib/curl_printf.h
+++ b/lib/curl_printf.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -31,7 +31,7 @@
# undef printf
# undef fprintf
-# undef snprintf
+# undef msnprintf
# undef vprintf
# undef vfprintf
# undef vsnprintf
@@ -39,18 +39,10 @@
# undef vaprintf
# define printf curl_mprintf
# define fprintf curl_mfprintf
-# define snprintf curl_msnprintf
+# define msnprintf curl_msnprintf
# define vprintf curl_mvprintf
# define vfprintf curl_mvfprintf
-# define vsnprintf curl_mvsnprintf
+# define mvsnprintf curl_mvsnprintf
# define aprintf curl_maprintf
# define vaprintf curl_mvaprintf
-
-/* We define away the sprintf functions unconditonally since we don't want
- internal code to be using them, intentionally or by mistake!*/
-# undef sprintf
-# undef vsprintf
-# define sprintf sprintf_was_used
-# define vsprintf vsprintf_was_used
-
#endif /* HEADER_CURL_PRINTF_H */
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index b8450155..f83e1ea4 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -646,7 +646,7 @@ int netware_init(void);
#define LIBIDN_REQUIRED_VERSION "0.4.1"
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
- defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_MBEDTLS) || \
+ defined(USE_POLARSSL) || defined(USE_MBEDTLS) || \
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
defined(USE_DARWINSSL) || defined(USE_GSKIT) || defined(USE_MESALINK)
#define USE_SSL /* SSL support has been enabled */
diff --git a/lib/curlx.h b/lib/curlx.h
index 4c77d4f2..3e9b516f 100644
--- a/lib/curlx.h
+++ b/lib/curlx.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -81,22 +81,21 @@
# undef printf
# undef fprintf
# undef sprintf
-# undef snprintf
+# undef msnprintf
# undef vprintf
# undef vfprintf
# undef vsprintf
-# undef vsnprintf
+# undef mvsnprintf
# undef aprintf
# undef vaprintf
# define printf curlx_mprintf
# define fprintf curlx_mfprintf
# define sprintf curlx_msprintf
-# define snprintf curlx_msnprintf
+# define msnprintf curlx_msnprintf
# define vprintf curlx_mvprintf
# define vfprintf curlx_mvfprintf
-# define vsprintf curlx_mvsprintf
-# define vsnprintf curlx_mvsnprintf
+# define mvsnprintf curlx_mvsnprintf
# define aprintf curlx_maprintf
# define vaprintf curlx_mvaprintf
#endif /* ENABLE_CURLX_PRINTF */
diff --git a/lib/doh.c b/lib/doh.c
index ef6013db..1e76c96f 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -26,13 +26,13 @@
#include "curl_addrinfo.h"
#include "doh.h"
-#ifdef USE_NGHTTP2
#include "sendf.h"
#include "multiif.h"
#include "url.h"
#include "share.h"
#include "curl_base64.h"
#include "connect.h"
+#include "strdup.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -143,8 +143,8 @@ doh_write_cb(void *contents, size_t size, size_t nmemb, void *userp)
/* suspiciously much for us */
return 0;
- mem->memory = realloc(mem->memory, mem->size + realsize);
- if(mem->memory == NULL)
+ mem->memory = Curl_saferealloc(mem->memory, mem->size + realsize);
+ if(!mem->memory)
/* out of memory! */
return 0;
@@ -234,7 +234,9 @@ static CURLcode dohprobe(struct Curl_easy *data,
ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDSIZE, (long)p->dohlen);
}
ERROR_CHECK_SETOPT(CURLOPT_HTTPHEADER, headers);
+#ifdef USE_NGHTTP2
ERROR_CHECK_SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
+#endif
#ifndef CURLDEBUG
/* enforce HTTPS if not debug */
ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
@@ -524,7 +526,7 @@ UNITTEST DOHcode doh_decode(unsigned char *doh,
if(dohlen < 12)
return DOH_TOO_SMALL_BUFFER; /* too small */
- if(doh[0] || doh[1])
+ if(!doh || doh[0] || doh[1])
return DOH_DNS_BAD_ID; /* bad ID */
rcode = doh[3] & 0x0f;
if(rcode)
@@ -660,13 +662,13 @@ static void showdoh(struct Curl_easy *data,
char buffer[128];
char *ptr;
size_t len;
- snprintf(buffer, 128, "DOH AAAA: ");
+ msnprintf(buffer, 128, "DOH AAAA: ");
ptr = &buffer[10];
len = 118;
for(j = 0; j < 16; j += 2) {
size_t l;
- snprintf(ptr, len, "%s%02x%02x", j?":":"", d->addr[i].ip.v6[j],
- d->addr[i].ip.v6[j + 1]);
+ msnprintf(ptr, len, "%s%02x%02x", j?":":"", d->addr[i].ip.v6[j],
+ d->addr[i].ip.v6[j + 1]);
l = strlen(ptr);
len -= l;
ptr += l;
@@ -853,7 +855,7 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
&de);
free(data->req.doh.probe[1].serverdoh.memory);
if(rc2) {
- infof(data, "DOG: %s type %s for %s\n", doh_strerror(rc2),
+ infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc2),
type2name(data->req.doh.probe[1].dnstype),
data->req.doh.host);
}
@@ -893,28 +895,3 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
return CURLE_OK;
}
-
-#else /* !USE_NGHTTP2 */
-/*
- */
-Curl_addrinfo *Curl_doh(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
-{
- (void)conn;
- (void)hostname;
- (void)port;
- (void)waitp;
- return NULL;
-}
-
-CURLcode Curl_doh_is_resolved(struct connectdata *conn,
- struct Curl_dns_entry **dnsp)
-{
- (void)conn;
- (void)dnsp;
- return CURLE_NOT_BUILT_IN;
-}
-
-#endif /* USE_NGHTTP2 */
diff --git a/lib/easy.c b/lib/easy.c
index 4de4e652..e592d7a7 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -664,12 +664,12 @@ static CURLcode easy_transfer(struct Curl_multi *multi)
while(!done && !mcode) {
int still_running = 0;
- int rc;
+ bool gotsocket = FALSE;
- mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
+ mcode = Curl_multi_wait(multi, NULL, 0, 1000, NULL, &gotsocket);
if(!mcode) {
- if(!rc) {
+ if(!gotsocket) {
long sleep_ms;
/* If it returns without any filedescriptor instantly, we need to
@@ -688,6 +688,7 @@ static CURLcode easy_transfer(struct Curl_multi *multi)
/* only read 'still_running' if curl_multi_perform() return OK */
if(!mcode && !still_running) {
+ int rc;
CURLMsg *msg = curl_multi_info_read(multi, &rc);
if(msg) {
result = msg->data.result;
@@ -966,7 +967,8 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
}
/* Clone the resolver handle, if present, for the new handle */
- if(Curl_resolver_duphandle(&outcurl->state.resolver,
+ if(Curl_resolver_duphandle(outcurl,
+ &outcurl->state.resolver,
data->state.resolver))
goto fail;
diff --git a/lib/escape.c b/lib/escape.c
index afd3899f..7121db31 100644
--- a/lib/escape.c
+++ b/lib/escape.c
@@ -122,7 +122,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
return NULL;
}
- snprintf(&ns[strindex], 4, "%%%02X", in);
+ msnprintf(&ns[strindex], 4, "%%%02X", in);
strindex += 3;
}
diff --git a/lib/file.c b/lib/file.c
index 722b55e9..8bba3b91 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -417,8 +417,9 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
struct tm buffer;
const struct tm *tm = &buffer;
char header[80];
- snprintf(header, sizeof(header),
- "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
+ msnprintf(header, sizeof(header),
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n",
+ expected_size);
result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
if(result)
return result;
@@ -434,16 +435,16 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
return result;
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
- snprintf(header, sizeof(header),
- "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s",
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec,
- data->set.opt_no_body ? "": "\r\n");
+ msnprintf(header, sizeof(header),
+ "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s",
+ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ data->set.opt_no_body ? "": "\r\n");
result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
if(result)
return result;
diff --git a/lib/ftp.c b/lib/ftp.c
index 793d991c..581df09d 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1272,7 +1272,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
source++;
}
*dest = 0;
- snprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
+ msnprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
if(result) {
@@ -2061,9 +2061,9 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
char timebuf[24];
time_t secs = time(NULL);
- snprintf(timebuf, sizeof(timebuf),
- "%04d%02d%02d %02d:%02d:%02d GMT",
- year, month, day, hour, minute, second);
+ 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);
}
@@ -2086,15 +2086,15 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
return result;
/* format: "Tue, 15 Nov 1994 12:45:26" */
- snprintf(headerbuf, sizeof(headerbuf),
- "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
+ msnprintf(headerbuf, sizeof(headerbuf),
+ "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
result = Curl_client_write(conn, CLIENTWRITE_BOTH, headerbuf, 0);
if(result)
return result;
@@ -2276,8 +2276,8 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
#ifdef CURL_FTP_HTTPSTYLE_HEAD
if(-1 != filesize) {
char clbuf[128];
- snprintf(clbuf, sizeof(clbuf),
- "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
+ msnprintf(clbuf, sizeof(clbuf),
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
result = Curl_client_write(conn, CLIENTWRITE_BOTH, clbuf, 0);
if(result)
return result;
diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c
index 249fe09c..1b1de5c3 100644
--- a/lib/ftplistparser.c
+++ b/lib/ftplistparser.c
@@ -405,7 +405,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
parser->state.UNIX.main = PL_UNIX_FILETYPE;
/* start FSM again not considering size of directory */
finfo->b_used = 0;
- i--;
+ continue;
}
break;
case PL_UNIX_TOTALSIZE_READING:
diff --git a/lib/hostcheck.c b/lib/hostcheck.c
index c9d8112d..6fcd0a90 100644
--- a/lib/hostcheck.c
+++ b/lib/hostcheck.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -23,7 +23,6 @@
#include "curl_setup.h"
#if defined(USE_OPENSSL) \
- || defined(USE_AXTLS) \
|| defined(USE_GSKIT) \
|| defined(USE_SCHANNEL)
/* these backends use functions from this file */
@@ -150,4 +149,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
return res;
}
-#endif /* OPENSSL, AXTLS, GSKIT or schannel+wince */
+#endif /* OPENSSL, GSKIT or schannel+wince */
diff --git a/lib/hostip4.c b/lib/hostip4.c
index 9d6f115a..e6ba710d 100644
--- a/lib/hostip4.c
+++ b/lib/hostip4.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -145,7 +145,7 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;
if(port) {
- snprintf(sbuf, sizeof(sbuf), "%d", port);
+ msnprintf(sbuf, sizeof(sbuf), "%d", port);
sbufptr = sbuf;
}
diff --git a/lib/hostip6.c b/lib/hostip6.c
index 3bf47b46..e06d0343 100644
--- a/lib/hostip6.c
+++ b/lib/hostip6.c
@@ -178,7 +178,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
#endif
if(port) {
- snprintf(sbuf, sizeof(sbuf), "%d", port);
+ msnprintf(sbuf, sizeof(sbuf), "%d", port);
sbufptr = sbuf;
}
diff --git a/lib/http.c b/lib/http.c
index 46ac15a6..345100f6 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -526,6 +526,12 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
pickhost = pickoneauth(&data->state.authhost, authmask);
if(!pickhost)
data->state.authproblem = TRUE;
+ if(data->state.authhost.picked == CURLAUTH_NTLM &&
+ conn->httpversion > 11) {
+ infof(data, "Forcing HTTP/1.1 for NTLM");
+ connclose(conn, "Force HTTP/1.1 connection");
+ conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
+ }
}
if(conn->bits.proxy_user_passwd &&
((data->req.httpcode == 407) ||
@@ -610,7 +616,6 @@ output_auth_headers(struct connectdata *conn,
result = Curl_output_negotiate(conn, proxy);
if(result)
return result;
- authstatus->done = TRUE;
negdata->state = GSS_AUTHSENT;
}
else
@@ -697,7 +702,7 @@ output_auth_headers(struct connectdata *conn,
*
* @param conn all information about the current connection
* @param request pointer to the request keyword
- * @param path pointer to the requested path
+ * @param path pointer to the requested path; should include query part
* @param proxytunnel boolean if this is the request setting up a "proxy
* tunnel"
*
@@ -1479,14 +1484,14 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
strcpy(tcp_version, "TCP4");
}
- snprintf(proxy_header,
- sizeof(proxy_header),
- "PROXY %s %s %s %li %li\r\n",
- tcp_version,
- conn->data->info.conn_local_ip,
- conn->data->info.conn_primary_ip,
- conn->data->info.conn_local_port,
- conn->data->info.conn_primary_port);
+ msnprintf(proxy_header,
+ sizeof(proxy_header),
+ "PROXY %s %s %s %li %li\r\n",
+ tcp_version,
+ conn->data->info.conn_local_ip,
+ conn->data->info.conn_primary_ip,
+ conn->data->info.conn_local_port,
+ conn->data->info.conn_primary_port);
req_buffer = Curl_add_buffer_init();
if(!req_buffer)
@@ -1850,16 +1855,16 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
*/
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
- snprintf(datestr, sizeof(datestr),
- "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
- condp,
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
+ msnprintf(datestr, sizeof(datestr),
+ "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+ condp,
+ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
result = Curl_add_buffer(&req_buffer, datestr, strlen(datestr));
@@ -1995,9 +2000,18 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
/* setup the authentication headers */
- result = Curl_http_output_auth(conn, request, path, FALSE);
- if(result)
- return result;
+ {
+ char *pq = NULL;
+ if(query && *query) {
+ pq = aprintf("%s?%s", path, query);
+ if(!pq)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ result = Curl_http_output_auth(conn, request, (pq ? pq : path), FALSE);
+ free(pq);
+ if(result)
+ return result;
+ }
if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
(httpreq != HTTPREQ_GET) &&
@@ -2293,8 +2307,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(!*data->state.up.path && path[strlen(path) - 1] != '/') {
*p++ = '/';
}
- snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
- data->set.prefer_ascii ? 'a' : 'i');
+ msnprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
+ data->set.prefer_ascii ? 'a' : 'i');
}
}
if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
@@ -3652,13 +3666,6 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
switch(k->httpcode) {
- case 204:
- /* (quote from RFC2616, section 10.2.5): The server has
- * fulfilled the request but does not need to return an
- * entity-body ... The 204 response MUST NOT include a
- * message-body, and thus is always terminated by the first
- * empty line after the header fields. */
- /* FALLTHROUGH */
case 304:
/* (quote from RFC2616, section 10.3.5): The 304 response
* MUST NOT contain a message-body, and thus is always
@@ -3666,6 +3673,13 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* fields. */
if(data->set.timecondition)
data->info.timecond = TRUE;
+ /* FALLTHROUGH */
+ case 204:
+ /* (quote from RFC2616, section 10.2.5): The server has
+ * fulfilled the request but does not need to return an
+ * entity-body ... The 204 response MUST NOT include a
+ * message-body, and thus is always terminated by the first
+ * empty line after the header fields. */
k->size = 0;
k->maxdownload = 0;
k->ignorecl = TRUE; /* ignore Content-Length headers */
diff --git a/lib/http2.c b/lib/http2.c
index 0c5f6db0..a61d8c24 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -350,7 +350,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
int Curl_http2_ver(char *p, size_t len)
{
nghttp2_info *h2 = nghttp2_version(0);
- return snprintf(p, len, " nghttp2/%s", h2->version_str);
+ return msnprintf(p, len, " nghttp2/%s", h2->version_str);
}
/* HTTP/2 error code to name based on the Error Code Registry.
@@ -2367,6 +2367,14 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data)
Curl_http2_remove_child(data->set.stream_depends_on, data);
}
+/* Only call this function for a transfer that already got a HTTP/2
+ CURLE_HTTP2_STREAM error! */
+bool Curl_h2_http_1_1_error(struct connectdata *conn)
+{
+ struct http_conn *httpc = &conn->proto.httpc;
+ return (httpc->error_code == NGHTTP2_HTTP_1_1_REQUIRED);
+}
+
#else /* !USE_NGHTTP2 */
/* Satisfy external references even if http2 is not compiled in. */
diff --git a/lib/http2.h b/lib/http2.h
index 4492ec21..67db3dff 100644
--- a/lib/http2.h
+++ b/lib/http2.h
@@ -59,6 +59,9 @@ CURLcode Curl_http2_add_child(struct Curl_easy *parent,
void Curl_http2_remove_child(struct Curl_easy *parent,
struct Curl_easy *child);
void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
+
+/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */
+bool Curl_h2_http_1_1_error(struct connectdata *conn);
#else /* USE_NGHTTP2 */
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
@@ -74,6 +77,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
#define Curl_http2_add_child(x, y, z)
#define Curl_http2_remove_child(x, y)
#define Curl_http2_cleanup_dependencies(x)
+#define Curl_h2_http_1_1_error(x) 0
#endif
#endif /* HEADER_CURL_HTTP2_H */
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index ddcd65b3..444265d1 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -49,6 +49,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
/* Point to the correct struct with this */
struct negotiatedata *neg_ctx;
+ struct auth *authp;
if(proxy) {
userp = conn->http_proxy.user;
@@ -57,6 +58,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
host = conn->http_proxy.host.name;
neg_ctx = &data->state.proxyneg;
+ authp = &conn->data->state.authproxy;
}
else {
userp = conn->user;
@@ -65,6 +67,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
data->set.str[STRING_SERVICE_NAME] : "HTTP";
host = conn->host.name;
neg_ctx = &data->state.negotiate;
+ authp = &conn->data->state.authhost;
}
/* Not set means empty */
@@ -95,6 +98,11 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
if(result)
Curl_auth_spnego_cleanup(neg_ctx);
+ else
+ /* If the status is different than 0 and we encountered no errors
+ it means we have to continue. 0 is the OK value for both GSSAPI
+ (GSS_S_COMPLETE) and SSPI (SEC_E_OK) */
+ authp->done = !neg_ctx->status;
return result;
}
diff --git a/lib/if2ip.c b/lib/if2ip.c
index ce38ea11..566061a5 100644
--- a/lib/if2ip.c
+++ b/lib/if2ip.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -169,7 +169,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
}
#endif
if(scopeid)
- snprintf(scope, sizeof(scope), "%%%u", scopeid);
+ msnprintf(scope, sizeof(scope), "%%%u", scopeid);
}
else
#endif
@@ -177,7 +177,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
&((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr;
res = IF2IP_FOUND;
ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr));
- snprintf(buf, buf_size, "%s%s", ip, scope);
+ msnprintf(buf, buf_size, "%s%s", ip, scope);
break;
}
}
diff --git a/lib/imap.c b/lib/imap.c
index 3ef89097..a8320e3f 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1749,8 +1749,8 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
imapc->cmdid = (imapc->cmdid + 1) % 1000;
/* Calculate the tag based on the connection ID and command ID */
- snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
- 'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
+ msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
+ 'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
/* Prefix the format with the tag */
taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
diff --git a/lib/inet_ntop.c b/lib/inet_ntop.c
index ac5d2d4d..855981c6 100644
--- a/lib/inet_ntop.c
+++ b/lib/inet_ntop.c
@@ -55,11 +55,11 @@ static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
DEBUGASSERT(size >= 16);
tmp[0] = '\0';
- (void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
- ((int)((unsigned char)src[0])) & 0xff,
- ((int)((unsigned char)src[1])) & 0xff,
- ((int)((unsigned char)src[2])) & 0xff,
- ((int)((unsigned char)src[3])) & 0xff);
+ (void)msnprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
+ ((int)((unsigned char)src[0])) & 0xff,
+ ((int)((unsigned char)src[1])) & 0xff,
+ ((int)((unsigned char)src[2])) & 0xff,
+ ((int)((unsigned char)src[3])) & 0xff);
len = strlen(tmp);
if(len == 0 || len >= size) {
@@ -148,7 +148,7 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
tp += strlen(tp);
break;
}
- tp += snprintf(tp, 5, "%lx", words[i]);
+ tp += msnprintf(tp, 5, "%lx", words[i]);
}
/* Was it a trailing run of 0x00's?
diff --git a/lib/ldap.c b/lib/ldap.c
index ceaa71d0..a149f8cb 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -839,6 +839,7 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
{
int rc = LDAP_SUCCESS;
char *path;
+ char *query;
char *p;
char *q;
size_t i;
@@ -846,7 +847,7 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
if(!conn->data ||
!conn->data->state.up.path ||
conn->data->state.up.path[0] != '/' ||
- !strcasecompare("LDAP", conn->data->state.up.scheme))
+ !strncasecompare("LDAP", conn->data->state.up.scheme, 4))
return LDAP_INVALID_SYNTAX;
ludp->lud_scope = LDAP_SCOPE_BASE;
@@ -858,11 +859,14 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
if(!path)
return LDAP_NO_MEMORY;
- /* Parse the DN (Distinguished Name) */
- q = strchr(p, '?');
- if(q)
- *q++ = '\0';
+ /* Duplicate the query */
+ q = query = strdup(conn->data->state.up.query);
+ if(!query) {
+ free(path);
+ return LDAP_NO_MEMORY;
+ }
+ /* Parse the DN (Distinguished Name) */
if(*p) {
char *dn = p;
char *unescaped;
@@ -1039,6 +1043,7 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
quit:
free(path);
+ free(query);
return rc;
}
diff --git a/lib/libcurl.plist b/lib/libcurl.plist
index 54d0480b..ca8d6420 100644
--- a/lib/libcurl.plist
+++ b/lib/libcurl.plist
@@ -15,7 +15,7 @@
<string>se.haxx.curl.libcurl</string>
<key>CFBundleVersion</key>
- <string>7.62.0</string>
+ <string>7.63.0</string>
<key>CFBundleName</key>
<string>libcurl</string>
@@ -27,9 +27,9 @@
<string>????</string>
<key>CFBundleShortVersionString</key>
- <string>libcurl 7.62.0</string>
+ <string>libcurl 7.63.0</string>
<key>CFBundleGetInfoString</key>
- <string>libcurl.plist 7.62.0</string>
+ <string>libcurl.plist 7.63.0</string>
</dict>
</plist>
diff --git a/lib/libcurl.rc b/lib/libcurl.rc
index 3316fba1..4839d0a6 100644
--- a/lib/libcurl.rc
+++ b/lib/libcurl.rc
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -22,22 +22,22 @@
#include <winver.h>
#include "../include/curl/curlver.h"
-LANGUAGE 0x09,0x01
+LANGUAGE 0, 0
#define RC_VERSION LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR, LIBCURL_VERSION_PATCH, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VERSION
PRODUCTVERSION RC_VERSION
- FILEFLAGSMASK 0x3fL
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#if defined(DEBUGBUILD) || defined(_DEBUG)
- FILEFLAGS 1
+ FILEFLAGS VS_FF_DEBUG
#else
- FILEFLAGS 0
+ FILEFLAGS 0L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
+ FILESUBTYPE 0L
BEGIN
BLOCK "StringFileInfo"
diff --git a/lib/md4.c b/lib/md4.c
index d3506021..4691904b 100644
--- a/lib/md4.c
+++ b/lib/md4.c
@@ -1,4 +1,5 @@
/*
+ * !checksrc! disable COPYRIGHT
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
* MD4 Message-Digest Algorithm (RFC 1320).
*
diff --git a/lib/md5.c b/lib/md5.c
index 45f45bbd..a17a58fa 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -163,13 +163,6 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
CryptReleaseContext(ctx->hCryptProv, 0);
}
-#elif defined(USE_AXTLS)
-#include <axTLS/config.h>
-#include <axTLS/os_int.h>
-#include <axTLS/crypto.h>
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
#else
/* When no other crypto library is available we use this code segment */
/*
diff --git a/lib/memdebug.c b/lib/memdebug.c
index 2b81c26a..05590a8f 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -504,7 +504,7 @@ void curl_memlog(const char *format, ...)
return;
va_start(ap, format);
- nchars = vsnprintf(buf, LOGLINE_BUFSIZE, format, ap);
+ nchars = mvsnprintf(buf, LOGLINE_BUFSIZE, format, ap);
va_end(ap);
if(nchars > LOGLINE_BUFSIZE - 1)
diff --git a/lib/mprintf.c b/lib/mprintf.c
index d2d91d74..e1909367 100644
--- a/lib/mprintf.c
+++ b/lib/mprintf.c
@@ -835,7 +835,7 @@ static int dprintf_formatf(
while(width-- > 0)
OUTCHAR(' ');
- while((len-- > 0) && *str)
+ for(; len && *str; len--)
OUTCHAR(*str++);
if(p->flags&FLAGS_LEFT)
while(width-- > 0)
diff --git a/lib/multi.c b/lib/multi.c
index 0db2a973..56b3faf2 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -46,6 +46,7 @@
#include "vtls/vtls.h"
#include "connect.h"
#include "http_proxy.h"
+#include "http2.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -634,13 +635,13 @@ static CURLcode multi_done(struct connectdata **connp,
else {
char buffer[256];
/* create string before returning the connection */
- snprintf(buffer, sizeof(buffer),
- "Connection #%ld to host %s left intact",
- conn->connection_id,
- conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
- conn->bits.httpproxy ? conn->http_proxy.host.dispname :
- conn->bits.conn_to_host ? conn->conn_to_host.dispname :
- conn->host.dispname);
+ msnprintf(buffer, sizeof(buffer),
+ "Connection #%ld to host %s left intact",
+ conn->connection_id,
+ conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
+ 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)) {
@@ -985,11 +986,12 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
#define NUM_POLLS_ON_STACK 10
-CURLMcode curl_multi_wait(struct Curl_multi *multi,
+CURLMcode Curl_multi_wait(struct Curl_multi *multi,
struct curl_waitfd extra_fds[],
unsigned int extra_nfds,
int timeout_ms,
- int *ret)
+ int *ret,
+ bool *gotsocket) /* if any socket was checked */
{
struct Curl_easy *data;
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
@@ -1003,6 +1005,9 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
int retcode = 0;
struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
+ if(gotsocket)
+ *gotsocket = FALSE;
+
if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE;
@@ -1135,9 +1140,21 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
free(ufds);
if(ret)
*ret = retcode;
+ if(gotsocket && (extra_fds || curlfds))
+ /* if any socket was checked */
+ *gotsocket = TRUE;
+
return CURLM_OK;
}
+CURLMcode curl_multi_wait(struct Curl_multi *multi,
+ struct curl_waitfd extra_fds[],
+ unsigned int extra_nfds,
+ int timeout_ms,
+ int *ret)
+{
+ return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, NULL);
+}
/*
* Curl_multi_connchanged() is called to tell that there is a connection in
* this multi handle that has changed state (pipelining become possible, the
@@ -1337,8 +1354,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
CURLMcode rc;
CURLcode result = CURLE_OK;
struct SingleRequest *k;
- time_t timeout_ms;
- time_t recv_timeout_ms;
+ timediff_t timeout_ms;
+ timediff_t recv_timeout_ms;
timediff_t send_timeout_ms;
int control;
@@ -1939,6 +1956,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
done = TRUE;
}
}
+ else if((CURLE_HTTP2_STREAM == result) &&
+ Curl_h2_http_1_1_error(data->easy_conn)) {
+ CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
+
+ infof(data, "Forcing HTTP/1.1 for NTLM");
+ data->set.httpversion = CURL_HTTP_VERSION_1_1;
+
+ if(!ret)
+ retry = (newurl)?TRUE:FALSE;
+ else
+ result = ret;
+
+ if(retry) {
+ /* if we are to retry, set the result to OK and consider the
+ request as done */
+ result = CURLE_OK;
+ done = TRUE;
+ }
+ }
if(result) {
/*
@@ -2466,11 +2502,11 @@ void Curl_updatesocket(struct Curl_easy *data)
* socket again and it gets the same file descriptor number.
*/
-void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
+void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s)
{
- if(conn->data) {
+ if(data) {
/* if there's still an easy handle associated with this connection */
- struct Curl_multi *multi = conn->data->multi;
+ struct Curl_multi *multi = data->multi;
if(multi) {
/* this is set if this connection is part of a handle that is added to
a multi handle, and only then this is necessary */
@@ -2478,7 +2514,7 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
if(entry) {
if(multi->socket_cb)
- multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
+ multi->socket_cb(data, s, CURL_POLL_REMOVE,
multi->socket_userp,
entry->socketp);
diff --git a/lib/multiif.h b/lib/multiif.h
index c8fb5ca0..e44646bf 100644
--- a/lib/multiif.h
+++ b/lib/multiif.h
@@ -89,7 +89,7 @@ void Curl_multi_connchanged(struct Curl_multi *multi);
* socket again and it gets the same file descriptor number.
*/
-void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
+void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s);
/*
* Add a handle and move it into PERFORM state at once. For pushed streams.
@@ -97,4 +97,12 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
struct Curl_easy *data,
struct connectdata *conn);
+
+CURLMcode Curl_multi_wait(struct Curl_multi *multi,
+ struct curl_waitfd extra_fds[],
+ unsigned int extra_nfds,
+ int timeout_ms,
+ int *ret,
+ bool *gotsocket); /* if any socket was checked */
+
#endif /* HEADER_CURL_MULTIIF_H */
diff --git a/lib/netrc.c b/lib/netrc.c
index 1724b35b..aba355b7 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -53,6 +53,8 @@ enum host_lookup_state {
int Curl_parsenetrc(const char *host,
char **loginp,
char **passwordp,
+ bool *login_changed,
+ bool *password_changed,
char *netrcfile)
{
FILE *file;
@@ -164,7 +166,7 @@ int Curl_parsenetrc(const char *host,
if(specific_login) {
state_our_login = strcasecompare(login, tok);
}
- else {
+ else if(!login || strcmp(login, tok)) {
if(login_alloc) {
free(login);
login_alloc = FALSE;
@@ -179,7 +181,8 @@ int Curl_parsenetrc(const char *host,
state_login = 0;
}
else if(state_password) {
- if(state_our_login || !specific_login) {
+ if((state_our_login || !specific_login)
+ && (!password || strcmp(password, tok))) {
if(password_alloc) {
free(password);
password_alloc = FALSE;
@@ -211,15 +214,19 @@ int Curl_parsenetrc(const char *host,
out:
if(!retcode) {
+ *login_changed = FALSE;
+ *password_changed = FALSE;
if(login_alloc) {
if(*loginp)
free(*loginp);
*loginp = login;
+ *login_changed = TRUE;
}
if(password_alloc) {
if(*passwordp)
free(*passwordp);
*passwordp = password;
+ *password_changed = TRUE;
}
}
else {
diff --git a/lib/netrc.h b/lib/netrc.h
index d980166e..fe3dc357 100644
--- a/lib/netrc.h
+++ b/lib/netrc.h
@@ -26,6 +26,8 @@
int Curl_parsenetrc(const char *host,
char **loginp,
char **passwordp,
+ bool *login_changed,
+ bool *password_changed,
char *filename);
/* Assume: (*passwordp)[0]=0, host[0] != 0.
* If (*loginp)[0] = 0, search for login and password within a machine
diff --git a/lib/openldap.c b/lib/openldap.c
index c6cb7943..bc007883 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -220,8 +220,8 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
ptr = hosturl + 4;
if(conn->handler->flags & PROTOPT_SSL)
*ptr++ = 's';
- snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
- conn->host.name, conn->remote_port);
+ msnprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
+ conn->host.name, conn->remote_port);
#ifdef CURL_OPENLDAP_DEBUG
static int do_trace = 0;
diff --git a/lib/pop3.c b/lib/pop3.c
index 5e0fd229..05853f00 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -443,7 +443,7 @@ static CURLcode pop3_perform_apop(struct connectdata *conn)
/* Convert the calculated 16 octet digest into a 32 byte hex string */
for(i = 0; i < MD5_DIGEST_LEN; i++)
- snprintf(&secret[2 * i], 3, "%02x", digest[i]);
+ msnprintf(&secret[2 * i], 3, "%02x", digest[i]);
result = Curl_pp_sendf(&pop3c->pp, "APOP %s %s", conn->user, secret);
@@ -629,6 +629,7 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
if(line[i] == '<') {
/* Calculate the length of the timestamp */
size_t timestamplen = len - 1 - i;
+ char *at;
if(!timestamplen)
break;
@@ -642,8 +643,15 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
memcpy(pop3c->apoptimestamp, line + i, timestamplen);
pop3c->apoptimestamp[timestamplen] = '\0';
- /* Store the APOP capability */
- pop3c->authtypes |= POP3_TYPE_APOP;
+ /* If the timestamp does not contain '@' it is not (as required by
+ RFC-1939) conformant to the RFC-822 message id syntax, and we
+ therefore do not use APOP authentication. */
+ at = strchr(pop3c->apoptimestamp, '@');
+ if(!at)
+ Curl_safefree(pop3c->apoptimestamp);
+ else
+ /* Store the APOP capability */
+ pop3c->authtypes |= POP3_TYPE_APOP;
break;
}
}
diff --git a/lib/progress.c b/lib/progress.c
index a94668dc..d37e1d5a 100644
--- a/lib/progress.c
+++ b/lib/progress.c
@@ -44,8 +44,8 @@ static void time2str(char *r, curl_off_t seconds)
if(h <= CURL_OFF_T_C(99)) {
curl_off_t m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
curl_off_t s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
- snprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T
- ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
+ msnprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T
+ ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
}
else {
/* this equals to more than 99 hours, switch to a more suitable output
@@ -53,10 +53,10 @@ static void time2str(char *r, curl_off_t seconds)
curl_off_t d = seconds / CURL_OFF_T_C(86400);
h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600);
if(d <= CURL_OFF_T_C(999))
- snprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
- "d %02" CURL_FORMAT_CURL_OFF_T "h", d, h);
+ msnprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
+ "d %02" CURL_FORMAT_CURL_OFF_T "h", d, h);
else
- snprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
+ msnprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
}
}
@@ -72,40 +72,40 @@ static char *max5data(curl_off_t bytes, char *max5)
#define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE)
if(bytes < CURL_OFF_T_C(100000))
- snprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
+ msnprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE)
- snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE);
+ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE);
else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE)
/* 'XX.XM' is good as long as we're less than 100 megs */
- snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
- CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE,
- (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) );
+ msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
+ CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE,
+ (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) );
#if (CURL_SIZEOF_CURL_OFF_T > 4)
else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE)
/* 'XXXXM' is good until we're at 10000MB or above */
- snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
+ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE)
/* 10000 MB - 100 GB, we show it as XX.XG */
- snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
- CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE,
- (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) );
+ msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
+ CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE,
+ (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) );
else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE)
/* up to 10000GB, display without decimal: XXXXG */
- snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE);
+ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE);
else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE)
/* up to 10000TB, display without decimal: XXXXT */
- snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE);
+ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE);
else
/* up to 10000PB, display without decimal: XXXXP */
- snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE);
+ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE);
/* 16384 petabytes (16 exabytes) is the maximum a 64 bit unsigned number
can hold, but our data type is signed so 8192PB will be the maximum. */
@@ -113,7 +113,7 @@ static char *max5data(curl_off_t bytes, char *max5)
#else
else
- snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
+ msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
#endif
diff --git a/lib/security.c b/lib/security.c
index 6165d0af..7f13071f 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -10,7 +10,7 @@
* Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
*
- * Copyright (C) 2001 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2001 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* All rights reserved.
*
@@ -120,7 +120,7 @@ static int ftp_send_command(struct connectdata *conn, const char *message, ...)
char print_buffer[50];
va_start(args, message);
- vsnprintf(print_buffer, sizeof(print_buffer), message, args);
+ mvsnprintf(print_buffer, sizeof(print_buffer), message, args);
va_end(args);
if(Curl_ftpsend(conn, print_buffer)) {
diff --git a/lib/sendf.c b/lib/sendf.c
index d3c10b36..e8598e61 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -237,7 +237,18 @@ void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
size_t len;
char print_buffer[2048 + 1];
va_start(ap, fmt);
- vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
+ len = mvsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
+ /*
+ * Indicate truncation of the input by replacing the last 3 characters
+ * with "...", and transfer the newline over in case the format had one.
+ */
+ if(len >= sizeof(print_buffer)) {
+ len = strlen(fmt);
+ if(fmt[--len] == '\n')
+ msnprintf(print_buffer + (sizeof(print_buffer) - 5), 5, "...\n");
+ else
+ msnprintf(print_buffer + (sizeof(print_buffer) - 4), 4, "...");
+ }
va_end(ap);
len = strlen(print_buffer);
Curl_debug(data, CURLINFO_TEXT, print_buffer, len);
@@ -255,7 +266,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
size_t len;
char error[CURL_ERROR_SIZE + 2];
va_start(ap, fmt);
- vsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
+ mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
len = strlen(error);
if(data->set.errorbuffer && !data->state.errorbuf) {
diff --git a/lib/setopt.c b/lib/setopt.c
index 22956a20..1627aba6 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -1204,6 +1204,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.low_speed_time = arg;
break;
+ case CURLOPT_CURLU:
+ /*
+ * pass CURLU to set URL
+ */
+ data->set.uh = va_arg(param, CURLU *);
+ break;
case CURLOPT_URL:
/*
* The URL to fetch.
diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c
index 96948ac4..65294bbe 100644
--- a/lib/socks_gssapi.c
+++ b/lib/socks_gssapi.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
- * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -151,8 +151,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
return CURLE_OUT_OF_MEMORY;
service.length = serviceptr_length +
strlen(conn->socks_proxy.host.name) + 1;
- snprintf(service.value, service.length + 1, "%s@%s",
- serviceptr, conn->socks_proxy.host.name);
+ msnprintf(service.value, service.length + 1, "%s@%s",
+ serviceptr, conn->socks_proxy.host.name);
gss_major_status = gss_import_name(&gss_minor_status, &service,
GSS_C_NT_HOSTBASED_SERVICE, &server);
diff --git a/lib/socks_sspi.c b/lib/socks_sspi.c
index 34699d37..bedb01eb 100644
--- a/lib/socks_sspi.c
+++ b/lib/socks_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
*
* This software is licensed as described in the file COPYING, which
@@ -107,9 +107,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
strlen(conn->socks_proxy.host.name) + 2);
if(!service_name)
return CURLE_OUT_OF_MEMORY;
- snprintf(service_name, service_length +
- strlen(conn->socks_proxy.host.name) + 2, "%s/%s",
- service, conn->socks_proxy.host.name);
+ msnprintf(service_name, service_length +
+ strlen(conn->socks_proxy.host.name) + 2, "%s/%s",
+ service, conn->socks_proxy.host.name);
}
input_desc.cBuffers = 1;
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
index 7d590891..e38c01ac 100644
--- a/lib/ssh-libssh.c
+++ b/lib/ssh-libssh.c
@@ -1342,8 +1342,8 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
- snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path,
- sshc->readdir_filename);
+ msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path,
+ sshc->readdir_filename);
state(conn, SSH_SFTP_READDIR_LINK);
break;
@@ -1406,12 +1406,12 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
}
sshc->readdir_line = new_readdir_line;
- sshc->readdir_currLen += snprintf(sshc->readdir_line +
- sshc->readdir_currLen,
- sshc->readdir_totalLen -
- sshc->readdir_currLen,
- " -> %s",
- sshc->readdir_filename);
+ sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+ sshc->readdir_currLen,
+ sshc->readdir_totalLen -
+ sshc->readdir_currLen,
+ " -> %s",
+ sshc->readdir_filename);
sftp_attributes_free(sshc->readdir_link_attrs);
sshc->readdir_link_attrs = NULL;
@@ -1421,10 +1421,10 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_SFTP_READDIR_BOTTOM);
/* FALLTHROUGH */
case SSH_SFTP_READDIR_BOTTOM:
- sshc->readdir_currLen += snprintf(sshc->readdir_line +
- sshc->readdir_currLen,
- sshc->readdir_totalLen -
- sshc->readdir_currLen, "\n");
+ sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+ sshc->readdir_currLen,
+ sshc->readdir_totalLen -
+ sshc->readdir_currLen, "\n");
result = Curl_client_write(conn, CLIENTWRITE_BODY,
sshc->readdir_line,
sshc->readdir_currLen);
diff --git a/lib/ssh.c b/lib/ssh.c
index da896196..f3b0a58b 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -599,7 +599,7 @@ static CURLcode ssh_check_fingerprint(struct connectdata *conn)
if(fingerprint) {
/* The fingerprint points to static storage (!), don't free() it. */
for(i = 0; i < 16; i++)
- snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
+ msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
}
@@ -1999,8 +1999,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
- snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
- sshc->readdir_filename);
+ msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
+ sshc->readdir_filename);
state(conn, SSH_SFTP_READDIR_LINK);
break;
}
@@ -2055,21 +2055,21 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
}
sshc->readdir_line = new_readdir_line;
- sshc->readdir_currLen += snprintf(sshc->readdir_line +
- sshc->readdir_currLen,
- sshc->readdir_totalLen -
- sshc->readdir_currLen,
- " -> %s",
- sshc->readdir_filename);
+ sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+ sshc->readdir_currLen,
+ sshc->readdir_totalLen -
+ sshc->readdir_currLen,
+ " -> %s",
+ sshc->readdir_filename);
state(conn, SSH_SFTP_READDIR_BOTTOM);
break;
case SSH_SFTP_READDIR_BOTTOM:
- sshc->readdir_currLen += snprintf(sshc->readdir_line +
- sshc->readdir_currLen,
- sshc->readdir_totalLen -
- sshc->readdir_currLen, "\n");
+ sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+ sshc->readdir_currLen,
+ sshc->readdir_totalLen -
+ sshc->readdir_currLen, "\n");
result = Curl_client_write(conn, CLIENTWRITE_BODY,
sshc->readdir_line,
sshc->readdir_currLen);
diff --git a/lib/strerror.c b/lib/strerror.c
index 47ef44a6..bf30c890 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2004 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2004 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -681,7 +681,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
if(!get_winsock_error(err, buf, max) &&
!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
LANG_NEUTRAL, buf, (DWORD)max, NULL))
- snprintf(buf, max, "Unknown error %d (%#x)", err, err);
+ msnprintf(buf, max, "Unknown error %d (%#x)", err, err);
}
#endif
@@ -695,7 +695,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
*/
if(0 != strerror_r(err, buf, max)) {
if('\0' == buf[0])
- snprintf(buf, max, "Unknown error %d", err);
+ msnprintf(buf, max, "Unknown error %d", err);
}
#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
/*
@@ -709,7 +709,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
if(msg)
strncpy(buf, msg, max);
else
- snprintf(buf, max, "Unknown error %d", err);
+ msnprintf(buf, max, "Unknown error %d", err);
}
#elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)
/*
@@ -721,7 +721,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
if(OK == strerror_r(err, buffer))
strncpy(buf, buffer, max);
else
- snprintf(buf, max, "Unknown error %d", err);
+ msnprintf(buf, max, "Unknown error %d", err);
}
#else
{
@@ -729,7 +729,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
if(msg)
strncpy(buf, msg, max);
else
- snprintf(buf, max, "Unknown error %d", err);
+ msnprintf(buf, max, "Unknown error %d", err);
}
#endif
@@ -1032,14 +1032,14 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
if(err == SEC_E_OK)
strncpy(outbuf, txt, outmax);
else if(err == SEC_E_ILLEGAL_MESSAGE)
- snprintf(outbuf, outmax,
- "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);
+ msnprintf(outbuf, outmax,
+ "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;
- snprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
+ msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
txtbuf[sizeof(txtbuf)-1] = '\0';
#ifdef _WIN32_WCE
@@ -1075,7 +1075,7 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
msg = msgbuf;
}
if(msg)
- snprintf(outbuf, outmax, "%s - %s", str, msg);
+ msnprintf(outbuf, outmax, "%s - %s", str, msg);
else
strncpy(outbuf, str, outmax);
}
diff --git a/lib/telnet.c b/lib/telnet.c
index 05fe744d..e4c0bac3 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -829,7 +829,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
/* Add the user name as an environment variable if it
was given on the command line */
if(conn->bits.user_passwd) {
- snprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
+ msnprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
beg = curl_slist_append(tn->telnet_vars, option_arg);
if(!beg) {
curl_slist_free_all(tn->telnet_vars);
@@ -935,9 +935,9 @@ static void suboption(struct connectdata *conn)
switch(CURL_SB_GET(tn)) {
case CURL_TELOPT_TTYPE:
len = strlen(tn->subopt_ttype) + 4 + 2;
- snprintf((char *)temp, sizeof(temp),
- "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE,
- CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE);
+ msnprintf((char *)temp, sizeof(temp),
+ "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE,
+ CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE);
bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
if(bytes_written < 0) {
err = SOCKERRNO;
@@ -947,9 +947,9 @@ static void suboption(struct connectdata *conn)
break;
case CURL_TELOPT_XDISPLOC:
len = strlen(tn->subopt_xdisploc) + 4 + 2;
- snprintf((char *)temp, sizeof(temp),
- "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC,
- CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE);
+ msnprintf((char *)temp, sizeof(temp),
+ "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC,
+ CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE);
bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
if(bytes_written < 0) {
err = SOCKERRNO;
@@ -958,9 +958,9 @@ static void suboption(struct connectdata *conn)
printsub(data, '>', &temp[2], len-2);
break;
case CURL_TELOPT_NEW_ENVIRON:
- snprintf((char *)temp, sizeof(temp),
- "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON,
- CURL_TELQUAL_IS);
+ msnprintf((char *)temp, sizeof(temp),
+ "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON,
+ CURL_TELQUAL_IS);
len = 4;
for(v = tn->telnet_vars; v; v = v->next) {
@@ -968,15 +968,15 @@ static void suboption(struct connectdata *conn)
/* Add the variable only if it fits */
if(len + tmplen < (int)sizeof(temp)-6) {
if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
- snprintf((char *)&temp[len], sizeof(temp) - len,
- "%c%s%c%s", CURL_NEW_ENV_VAR, varname,
- CURL_NEW_ENV_VALUE, varval);
+ msnprintf((char *)&temp[len], sizeof(temp) - len,
+ "%c%s%c%s", CURL_NEW_ENV_VAR, varname,
+ CURL_NEW_ENV_VALUE, varval);
len += tmplen;
}
}
}
- snprintf((char *)&temp[len], sizeof(temp) - len,
- "%c%c", CURL_IAC, CURL_SE);
+ msnprintf((char *)&temp[len], sizeof(temp) - len,
+ "%c%c", CURL_IAC, CURL_SE);
len += 2;
bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
if(bytes_written < 0) {
diff --git a/lib/tftp.c b/lib/tftp.c
index 5b74e8e0..269b3cde 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -496,9 +496,9 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
return CURLE_TFTP_ILLEGAL; /* too long file name field */
}
- snprintf((char *)state->spacket.data + 2,
- state->blksize,
- "%s%c%s%c", filename, '\0', mode, '\0');
+ msnprintf((char *)state->spacket.data + 2,
+ state->blksize,
+ "%s%c%s%c", filename, '\0', mode, '\0');
sbytes = 4 + strlen(filename) + strlen(mode);
/* optional addition of TFTP options */
@@ -506,8 +506,8 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
char buf[64];
/* add tsize option */
if(data->set.upload && (data->state.infilesize != -1))
- snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
- data->state.infilesize);
+ msnprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
+ data->state.infilesize);
else
strcpy(buf, "0"); /* the destination is large enough */
@@ -517,7 +517,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
sbytes += tftp_option_add(state, sbytes,
(char *)state->spacket.data + sbytes, buf);
/* add blksize option */
- snprintf(buf, sizeof(buf), "%d", state->requested_blksize);
+ msnprintf(buf, sizeof(buf), "%d", state->requested_blksize);
sbytes += tftp_option_add(state, sbytes,
(char *)state->spacket.data + sbytes,
TFTP_OPTION_BLKSIZE);
@@ -525,7 +525,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
(char *)state->spacket.data + sbytes, buf);
/* add timeout option */
- snprintf(buf, sizeof(buf), "%d", state->retry_time);
+ msnprintf(buf, sizeof(buf), "%d", state->retry_time);
sbytes += tftp_option_add(state, sbytes,
(char *)state->spacket.data + sbytes,
TFTP_OPTION_INTERVAL);
diff --git a/lib/transfer.c b/lib/transfer.c
index b73f94d9..6390821b 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -218,8 +218,8 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
endofline_native = "\r\n";
endofline_network = "\x0d\x0a";
}
- hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
- "%x%s", nread, endofline_native);
+ hexlen = msnprintf(hexbuffer, sizeof(hexbuffer),
+ "%x%s", nread, endofline_native);
/* move buffer pointer */
data->req.upload_fromhere -= hexlen;
@@ -844,6 +844,11 @@ static CURLcode readwrite_data(struct Curl_easy *data,
k->keepon &= ~KEEP_RECV;
}
+ if(k->keepon & KEEP_RECV_PAUSE) {
+ /* this is a paused transfer */
+ break;
+ }
+
} while(data_pending(conn) && maxloops--);
if(maxloops <= 0) {
@@ -1348,17 +1353,30 @@ void Curl_init_CONNECT(struct Curl_easy *data)
CURLcode Curl_pretransfer(struct Curl_easy *data)
{
CURLcode result;
- if(!data->change.url) {
+
+ if(!data->change.url && !data->set.uh) {
/* we can't do anything without URL */
failf(data, "No URL set!");
return CURLE_URL_MALFORMAT;
}
+
/* since the URL may have been redirected in a previous use of this handle */
if(data->change.url_alloc) {
/* the already set URL is allocated, free it first! */
Curl_safefree(data->change.url);
data->change.url_alloc = FALSE;
}
+
+ if(!data->change.url && data->set.uh) {
+ CURLUcode uc;
+ uc = curl_url_get(data->set.uh,
+ CURLUPART_URL, &data->set.str[STRING_SET_URL], 0);
+ if(uc) {
+ failf(data, "No URL set!");
+ return CURLE_URL_MALFORMAT;
+ }
+ }
+
data->change.url = data->set.str[STRING_SET_URL];
/* Init the SSL session ID cache here. We do it here since we want to do it
@@ -1514,13 +1532,24 @@ CURLcode Curl_follow(struct Curl_easy *data,
disallowport = TRUE;
DEBUGASSERT(data->state.uh);
- uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, 0);
- if(uc)
- return Curl_uc_to_curlcode(uc);
+ uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl,
+ (type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME : 0);
+ if(uc) {
+ if(type != FOLLOW_FAKE)
+ return Curl_uc_to_curlcode(uc);
+
+ /* the URL could not be parsed for some reason, but since this is FAKE
+ mode, just duplicate the field as-is */
+ newurl = strdup(newurl);
+ if(!newurl)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else {
- uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0);
- if(uc)
- return Curl_uc_to_curlcode(uc);
+ uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0);
+ if(uc)
+ return Curl_uc_to_curlcode(uc);
+ }
if(type == FOLLOW_FAKE) {
/* we're only figuring out the new url if we would've followed locations
diff --git a/lib/url.c b/lib/url.c
index 0d5a13f9..7839dfa7 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -127,7 +127,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "memdebug.h"
static void conn_free(struct connectdata *conn);
-static void free_fixed_hostname(struct hostname *host);
+static void free_idnconverted_hostname(struct hostname *host);
static unsigned int get_protocol_family(unsigned int protocol);
/* Some parts of the code (e.g. chunked encoding) assume this buffer has at
@@ -570,7 +570,7 @@ CURLcode Curl_open(struct Curl_easy **curl)
data->magic = CURLEASY_MAGIC_NUMBER;
- result = Curl_resolver_init(&data->state.resolver);
+ result = Curl_resolver_init(data, &data->state.resolver);
if(result) {
DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
free(data);
@@ -708,6 +708,7 @@ static void conn_free(struct connectdata *conn)
Curl_safefree(conn->trailer);
Curl_safefree(conn->host.rawalloc); /* host name buffer */
Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
+ Curl_safefree(conn->hostname_resolve);
Curl_safefree(conn->secondaryhostname);
Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
@@ -788,10 +789,10 @@ CURLcode Curl_disconnect(struct Curl_easy *data,
infof(data, "Closing connection %ld\n", conn->connection_id);
Curl_conncache_remove_conn(conn, TRUE);
- free_fixed_hostname(&conn->host);
- free_fixed_hostname(&conn->conn_to_host);
- free_fixed_hostname(&conn->http_proxy.host);
- free_fixed_hostname(&conn->socks_proxy.host);
+ free_idnconverted_hostname(&conn->host);
+ free_idnconverted_hostname(&conn->conn_to_host);
+ free_idnconverted_hostname(&conn->http_proxy.host);
+ free_idnconverted_hostname(&conn->socks_proxy.host);
DEBUGASSERT(conn->data == data);
/* this assumes that the pointer is still there after the connection was
@@ -1679,11 +1680,23 @@ static bool is_ASCII_name(const char *hostname)
}
/*
- * Perform any necessary IDN conversion of hostname
+ * Strip single trailing dot in the hostname,
+ * primarily for SNI and http host header.
*/
-static CURLcode fix_hostname(struct connectdata *conn, struct hostname *host)
+static void strip_trailing_dot(struct hostname *host)
{
size_t len;
+ len = strlen(host->name);
+ if(len && (host->name[len-1] == '.'))
+ host->name[len-1] = 0;
+}
+
+/*
+ * Perform any necessary IDN conversion of hostname
+ */
+static CURLcode idnconvert_hostname(struct connectdata *conn,
+ struct hostname *host)
+{
struct Curl_easy *data = conn->data;
#ifndef USE_LIBIDN2
@@ -1696,12 +1709,6 @@ static CURLcode fix_hostname(struct connectdata *conn, struct hostname *host)
/* set the name we use to display the host name */
host->dispname = host->name;
- len = strlen(host->name);
- if(len && (host->name[len-1] == '.'))
- /* strip off a single trailing dot if present, primarily for SNI but
- there's no use for it */
- host->name[len-1] = 0;
-
/* Check name for non-ASCII and convert hostname to ACE form if we can */
if(!is_ASCII_name(host->name)) {
#ifdef USE_LIBIDN2
@@ -1756,9 +1763,9 @@ static CURLcode fix_hostname(struct connectdata *conn, struct hostname *host)
}
/*
- * Frees data allocated by fix_hostname()
+ * Frees data allocated by idnconvert_hostname()
*/
-static void free_fixed_hostname(struct hostname *host)
+static void free_idnconverted_hostname(struct hostname *host)
{
#if defined(USE_LIBIDN2)
if(host->encalloc) {
@@ -2026,7 +2033,13 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
Curl_up_free(data); /* cleanup previous leftovers first */
/* parse the URL */
- uh = data->state.uh = curl_url();
+ if(data->set.uh) {
+ uh = data->set.uh;
+ }
+ else {
+ uh = data->state.uh = curl_url();
+ }
+
if(!uh)
return CURLE_OUT_OF_MEMORY;
@@ -2043,14 +2056,18 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
data->change.url_alloc = TRUE;
}
- uc = curl_url_set(uh, CURLUPART_URL, data->change.url,
+ if(!data->set.uh) {
+ uc = curl_url_set(uh, CURLUPART_URL, data->change.url,
CURLU_GUESS_SCHEME |
CURLU_NON_SUPPORT_SCHEME |
(data->set.disallow_username_in_url ?
CURLU_DISALLOW_USER : 0) |
(data->set.path_as_is ? CURLU_PATH_AS_IS : 0));
- if(uc)
- return Curl_uc_to_curlcode(uc);
+ if(uc) {
+ DEBUGF(infof(data, "curl_url_set rejected %s\n", data->change.url));
+ return Curl_uc_to_curlcode(uc);
+ }
+ }
uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0);
if(uc)
@@ -2191,6 +2208,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
return CURLE_OK;
}
+
/*
* If we're doing a resumed transfer, we need to setup our stuff
* properly.
@@ -2979,7 +2997,7 @@ static CURLcode parse_remote_port(struct Curl_easy *data,
char portbuf[16];
CURLUcode uc;
conn->remote_port = (unsigned short)data->set.use_port;
- snprintf(portbuf, sizeof(portbuf), "%u", conn->remote_port);
+ msnprintf(portbuf, sizeof(portbuf), "%u", conn->remote_port);
uc = curl_url_set(data->state.uh, CURLUPART_PORT, portbuf, 0);
if(uc)
return CURLE_OUT_OF_MEMORY;
@@ -2999,6 +3017,20 @@ static CURLcode override_login(struct Curl_easy *data,
bool user_changed = FALSE;
bool passwd_changed = FALSE;
CURLUcode uc;
+
+ if(data->set.use_netrc == CURL_NETRC_REQUIRED && conn->bits.user_passwd) {
+ /* ignore user+password in the URL */
+ if(*userp) {
+ Curl_safefree(*userp);
+ user_changed = TRUE;
+ }
+ if(*passwdp) {
+ Curl_safefree(*passwdp);
+ passwd_changed = TRUE;
+ }
+ conn->bits.user_passwd = FALSE; /* disable user+password */
+ }
+
if(data->set.str[STRING_USERNAME]) {
free(*userp);
*userp = strdup(data->set.str[STRING_USERNAME]);
@@ -3025,16 +3057,15 @@ static CURLcode override_login(struct Curl_easy *data,
}
conn->bits.netrc = FALSE;
- if(data->set.use_netrc != CURL_NETRC_IGNORED) {
- char *nuser = NULL;
- char *npasswd = NULL;
+ if(data->set.use_netrc != CURL_NETRC_IGNORED &&
+ (!*userp || !**userp || !*passwdp || !**passwdp)) {
+ bool netrc_user_changed = FALSE;
+ bool netrc_passwd_changed = FALSE;
int ret;
- if(data->set.use_netrc == CURL_NETRC_OPTIONAL)
- nuser = *userp; /* to separate otherwise identical machines */
-
ret = Curl_parsenetrc(conn->host.name,
- &nuser, &npasswd,
+ userp, passwdp,
+ &netrc_user_changed, &netrc_passwd_changed,
data->set.str[STRING_NETRC_FILE]);
if(ret > 0) {
infof(data, "Couldn't find host %s in the "
@@ -3051,31 +3082,11 @@ static CURLcode override_login(struct Curl_easy *data,
conn->bits.netrc = TRUE;
conn->bits.user_passwd = TRUE; /* enable user+password */
- if(data->set.use_netrc == CURL_NETRC_OPTIONAL) {
- /* prefer credentials outside netrc */
- if(nuser && !*userp) {
- free(*userp);
- *userp = nuser;
- user_changed = TRUE;
- }
- if(npasswd && !*passwdp) {
- free(*passwdp);
- *passwdp = npasswd;
- passwd_changed = TRUE;
- }
+ if(netrc_user_changed) {
+ user_changed = TRUE;
}
- else {
- /* prefer netrc credentials */
- if(nuser) {
- free(*userp);
- *userp = nuser;
- user_changed = TRUE;
- }
- if(npasswd) {
- free(*passwdp);
- *passwdp = npasswd;
- passwd_changed = TRUE;
- }
+ if(netrc_passwd_changed) {
+ passwd_changed = TRUE;
}
}
}
@@ -3369,7 +3380,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
*************************************************************/
if(conn->bits.reuse)
/* We're reusing the connection - no need to resolve anything, and
- fix_hostname() was called already in create_conn() for the re-use
+ idnconvert_hostname() was called already in create_conn() for the re-use
case. */
*async = FALSE;
@@ -3424,7 +3435,10 @@ static CURLcode resolve_server(struct Curl_easy *data,
conn->port = conn->remote_port;
/* Resolve target host right on */
- rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port,
+ conn->hostname_resolve = strdup(connhost->name);
+ if(!conn->hostname_resolve)
+ return CURLE_OUT_OF_MEMORY;
+ rc = Curl_resolv_timeout(conn, conn->hostname_resolve, (int)conn->port,
&hostaddr, timeout_ms);
if(rc == CURLRESOLV_PENDING)
*async = TRUE;
@@ -3445,7 +3459,10 @@ static CURLcode resolve_server(struct Curl_easy *data,
&conn->socks_proxy.host : &conn->http_proxy.host;
/* resolve proxy */
- rc = Curl_resolv_timeout(conn, host->name, (int)conn->port,
+ conn->hostname_resolve = strdup(host->name);
+ if(!conn->hostname_resolve)
+ return CURLE_OUT_OF_MEMORY;
+ rc = Curl_resolv_timeout(conn, conn->hostname_resolve, (int)conn->port,
&hostaddr, timeout_ms);
if(rc == CURLRESOLV_PENDING)
@@ -3475,8 +3492,8 @@ static CURLcode resolve_server(struct Curl_easy *data,
static void reuse_conn(struct connectdata *old_conn,
struct connectdata *conn)
{
- free_fixed_hostname(&old_conn->http_proxy.host);
- free_fixed_hostname(&old_conn->socks_proxy.host);
+ free_idnconverted_hostname(&old_conn->http_proxy.host);
+ free_idnconverted_hostname(&old_conn->socks_proxy.host);
free(old_conn->http_proxy.host.rawalloc);
free(old_conn->socks_proxy.host.rawalloc);
@@ -3520,14 +3537,18 @@ static void reuse_conn(struct connectdata *old_conn,
/* host can change, when doing keepalive with a proxy or if the case is
different this time etc */
- free_fixed_hostname(&conn->host);
- free_fixed_hostname(&conn->conn_to_host);
+ free_idnconverted_hostname(&conn->host);
+ free_idnconverted_hostname(&conn->conn_to_host);
Curl_safefree(conn->host.rawalloc);
Curl_safefree(conn->conn_to_host.rawalloc);
conn->host = old_conn->host;
conn->conn_to_host = old_conn->conn_to_host;
conn->conn_to_port = old_conn->conn_to_port;
conn->remote_port = old_conn->remote_port;
+ Curl_safefree(conn->hostname_resolve);
+
+ conn->hostname_resolve = old_conn->hostname_resolve;
+ old_conn->hostname_resolve = NULL;
/* persist connection info in session handle */
Curl_persistconninfo(conn);
@@ -3677,30 +3698,30 @@ static CURLcode create_conn(struct Curl_easy *data,
goto out;
/*************************************************************
- * IDN-fix the hostnames
+ * IDN-convert the hostnames
*************************************************************/
- result = fix_hostname(conn, &conn->host);
+ result = idnconvert_hostname(conn, &conn->host);
if(result)
goto out;
if(conn->bits.conn_to_host) {
- result = fix_hostname(conn, &conn->conn_to_host);
+ result = idnconvert_hostname(conn, &conn->conn_to_host);
if(result)
goto out;
}
if(conn->bits.httpproxy) {
- result = fix_hostname(conn, &conn->http_proxy.host);
+ result = idnconvert_hostname(conn, &conn->http_proxy.host);
if(result)
goto out;
}
if(conn->bits.socksproxy) {
- result = fix_hostname(conn, &conn->socks_proxy.host);
+ result = idnconvert_hostname(conn, &conn->socks_proxy.host);
if(result)
goto out;
}
/*************************************************************
* Check whether the host and the "connect to host" are equal.
- * Do this after the hostnames have been IDN-fixed.
+ * Do this after the hostnames have been IDN-converted.
*************************************************************/
if(conn->bits.conn_to_host &&
strcasecompare(conn->conn_to_host.name, conn->host.name)) {
@@ -4028,6 +4049,15 @@ static CURLcode create_conn(struct Curl_easy *data,
*************************************************************/
result = resolve_server(data, conn, async);
+ /* Strip trailing dots. resolve_server copied the name. */
+ strip_trailing_dot(&conn->host);
+ if(conn->bits.httpproxy)
+ strip_trailing_dot(&conn->http_proxy.host);
+ if(conn->bits.socksproxy)
+ strip_trailing_dot(&conn->socks_proxy.host);
+ if(conn->bits.conn_to_host)
+ strip_trailing_dot(&conn->conn_to_host);
+
out:
return result;
}
diff --git a/lib/urlapi-int.h b/lib/urlapi-int.h
index a57d2e22..75a36054 100644
--- a/lib/urlapi-int.h
+++ b/lib/urlapi-int.h
@@ -30,4 +30,9 @@ bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen);
char *Curl_concat_url(const char *base, const char *relurl);
size_t Curl_strlen_url(const char *url, bool relative);
void Curl_strcpy_url(char *output, const char *url, bool relative);
+
+#ifdef DEBUGBUILD
+CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname);
+#endif
+
#endif /* HEADER_CURL_URLAPI_INT_H */
diff --git a/lib/urlapi.c b/lib/urlapi.c
index c53e5234..5cbda6a9 100644
--- a/lib/urlapi.c
+++ b/lib/urlapi.c
@@ -67,6 +67,12 @@ struct Curl_URL {
#define DEFAULT_SCHEME "https"
+#ifdef DEBUGBUILD
+#define UNITTEST
+#else
+#define UNITTEST static
+#endif
+
static void free_urlhandle(struct Curl_URL *u)
{
free(u->scheme);
@@ -203,7 +209,7 @@ void Curl_strcpy_url(char *output, const char *url, bool relative)
/* FALLTHROUGH */
default:
if(urlchar_needs_escaping(*iptr)) {
- snprintf(optr, 4, "%%%02x", *iptr);
+ msnprintf(optr, 4, "%%%02x", *iptr);
optr += 3;
}
else
@@ -238,7 +244,7 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
#endif
for(i = 0; i < buflen && url[i]; ++i) {
char s = url[i];
- if(s == ':') {
+ if((s == ':') && (url[i + 1] == '/')) {
if(buf)
buf[i] = 0;
return TRUE;
@@ -488,19 +494,37 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
return result;
}
-static CURLUcode parse_port(struct Curl_URL *u, char *hostname)
+UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
{
- char *portptr;
+ char *portptr = NULL;
char endbracket;
int len;
- if((1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.%%]%c%n",
- &endbracket, &len)) &&
- (']' == endbracket)) {
- /* this is a RFC2732-style specified IP-address */
- portptr = &hostname[len];
- if (*portptr != ':')
+ /*
+ * Find the end of an IPv6 address, either on the ']' ending bracket or
+ * a percent-encoded zone index.
+ */
+ if(1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.]%c%n",
+ &endbracket, &len)) {
+ if(']' == endbracket)
+ portptr = &hostname[len];
+ else if('%' == endbracket) {
+ int zonelen = len;
+ if(1 == sscanf(hostname + zonelen, "25%*[^]]]%c%n", &endbracket, &len))
+ portptr = &hostname[--zonelen + len];
+ else
+ return CURLUE_MALFORMED_INPUT;
+ }
+ else
return CURLUE_MALFORMED_INPUT;
+
+ /* this is a RFC2732-style specified IP-address */
+ if(portptr && *portptr) {
+ if(*portptr != ':')
+ return CURLUE_MALFORMED_INPUT;
+ }
+ else
+ portptr = NULL;
}
else
portptr = strchr(hostname, ':');
@@ -527,7 +551,7 @@ static CURLUcode parse_port(struct Curl_URL *u, char *hostname)
*portptr++ = '\0'; /* cut off the name there */
*rest = 0;
/* generate a new to get rid of leading zeroes etc */
- snprintf(portbuf, sizeof(portbuf), "%ld", port);
+ msnprintf(portbuf, sizeof(portbuf), "%ld", port);
u->portnum = port;
u->port = strdup(portbuf);
if(!u->port)
@@ -827,7 +851,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(result)
return result;
- result = parse_port(u, hostname);
+ result = Curl_parse_port(u, hostname);
if(result)
return result;
@@ -960,7 +984,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
const struct Curl_handler *h =
Curl_builtin_scheme(u->scheme);
if(h) {
- snprintf(portbuf, sizeof(portbuf), "%ld", h->defport);
+ msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport);
ptr = portbuf;
}
}
@@ -1019,7 +1043,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
/* there's no stored port number, but asked to deliver
a default one for the scheme */
if(h) {
- snprintf(portbuf, sizeof(portbuf), "%ld", h->defport);
+ msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport);
port = portbuf;
}
}
@@ -1099,6 +1123,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
bool plusencode = FALSE;
bool urlskipslash = FALSE;
bool appendquery = FALSE;
+ bool equalsencode = FALSE;
if(!u)
return CURLUE_BAD_HANDLE;
@@ -1179,6 +1204,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
case CURLUPART_QUERY:
plusencode = urlencode;
appendquery = (flags & CURLU_APPENDQUERY)?1:0;
+ equalsencode = appendquery;
storep = &u->query;
break;
case CURLUPART_FRAGMENT:
@@ -1272,13 +1298,16 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
for(i = part, o = enc; *i; i++) {
if(Curl_isunreserved(*i) ||
((*i == '/') && urlskipslash) ||
- ((*i == '=') && appendquery) ||
+ ((*i == '=') && equalsencode) ||
((*i == '+') && plusencode)) {
+ if((*i == '=') && equalsencode)
+ /* only skip the first equals sign */
+ equalsencode = FALSE;
*o = *i;
o++;
}
else {
- snprintf(o, 4, "%%%02x", *i);
+ msnprintf(o, 4, "%%%02x", *i);
o += 3;
}
}
diff --git a/lib/urldata.h b/lib/urldata.h
index 11a6a22c..448437d2 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -828,6 +828,7 @@ struct connectdata {
int socktype; /* SOCK_STREAM or SOCK_DGRAM */
struct hostname host;
+ char *hostname_resolve; /* host name to resolve to address, allocated */
char *secondaryhostname; /* secondary socket host name (ftp) */
struct hostname conn_to_host; /* the host to connect to. valid only if
bits.conn_to_host is set */
@@ -1728,6 +1729,7 @@ struct UserDefined {
bool doh_get; /* use GET for DoH requests, instead of POST */
multidone_func fmultidone;
struct Curl_easy *dohfor; /* this is a DoH request for that transfer */
+ CURLU *uh; /* URL handle for the current parsed URL */
};
struct Names {
diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c
index ab5156eb..0f2e6509 100644
--- a/lib/vauth/digest.c
+++ b/lib/vauth/digest.c
@@ -143,7 +143,7 @@ static void auth_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */
{
int i;
for(i = 0; i < 16; i++)
- snprintf((char *) &dest[i * 2], 3, "%02x", source[i]);
+ msnprintf((char *) &dest[i * 2], 3, "%02x", source[i]);
}
/* Convert sha256 chunk to RFC7616 -suitable ascii string*/
@@ -152,7 +152,7 @@ static void auth_digest_sha256_to_ascii(unsigned char *source, /* 32 bytes */
{
int i;
for(i = 0; i < 32; i++)
- snprintf((char *) &dest[i * 2], 3, "%02x", source[i]);
+ msnprintf((char *) &dest[i * 2], 3, "%02x", source[i]);
}
/* Perform quoted-string escaping as described in RFC2616 and its errata */
@@ -432,7 +432,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
/* Convert calculated 16 octet hex into 32 bytes string */
for(i = 0; i < MD5_DIGEST_LEN; i++)
- snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]);
+ msnprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]);
/* Generate our SPN */
spn = Curl_auth_build_spn(service, realm, NULL);
@@ -455,7 +455,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
Curl_MD5_final(ctxt, digest);
for(i = 0; i < MD5_DIGEST_LEN; i++)
- snprintf(&HA2_hex[2 * i], 3, "%02x", digest[i]);
+ msnprintf(&HA2_hex[2 * i], 3, "%02x", digest[i]);
/* Now calculate the response hash */
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
@@ -485,7 +485,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
Curl_MD5_final(ctxt, digest);
for(i = 0; i < MD5_DIGEST_LEN; i++)
- snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
+ msnprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
/* Generate the response */
response = aprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\","
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index 11f42f50..458b2725 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -409,38 +409,38 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
#else
#define NTLM2FLAG 0
#endif
- snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
- NTLMSSP_SIGNATURE "%c"
- "\x01%c%c%c" /* 32-bit type = 1 */
- "%c%c%c%c" /* 32-bit NTLM flag field */
- "%c%c" /* domain length */
- "%c%c" /* domain allocated space */
- "%c%c" /* domain name offset */
- "%c%c" /* 2 zeroes */
- "%c%c" /* host length */
- "%c%c" /* host allocated space */
- "%c%c" /* host name offset */
- "%c%c" /* 2 zeroes */
- "%s" /* host name */
- "%s", /* domain string */
- 0, /* trailing zero */
- 0, 0, 0, /* part of type-1 long */
-
- LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
- NTLMFLAG_REQUEST_TARGET |
- NTLMFLAG_NEGOTIATE_NTLM_KEY |
- NTLM2FLAG |
- NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
- SHORTPAIR(domlen),
- SHORTPAIR(domlen),
- SHORTPAIR(domoff),
- 0, 0,
- SHORTPAIR(hostlen),
- SHORTPAIR(hostlen),
- SHORTPAIR(hostoff),
- 0, 0,
- host, /* this is empty */
- domain /* this is empty */);
+ msnprintf((char *)ntlmbuf, NTLM_BUFSIZE,
+ NTLMSSP_SIGNATURE "%c"
+ "\x01%c%c%c" /* 32-bit type = 1 */
+ "%c%c%c%c" /* 32-bit NTLM flag field */
+ "%c%c" /* domain length */
+ "%c%c" /* domain allocated space */
+ "%c%c" /* domain name offset */
+ "%c%c" /* 2 zeroes */
+ "%c%c" /* host length */
+ "%c%c" /* host allocated space */
+ "%c%c" /* host name offset */
+ "%c%c" /* 2 zeroes */
+ "%s" /* host name */
+ "%s", /* domain string */
+ 0, /* trailing zero */
+ 0, 0, 0, /* part of type-1 long */
+
+ LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
+ NTLMFLAG_REQUEST_TARGET |
+ NTLMFLAG_NEGOTIATE_NTLM_KEY |
+ NTLM2FLAG |
+ NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
+ SHORTPAIR(domlen),
+ SHORTPAIR(domlen),
+ SHORTPAIR(domoff),
+ 0, 0,
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostoff),
+ 0, 0,
+ host, /* this is empty */
+ domain /* this is empty */);
/* Initial packet length */
size = 32 + hostlen + domlen;
@@ -678,88 +678,88 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
hostoff = useroff + userlen;
/* Create the big type-3 message binary blob */
- size = snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
- NTLMSSP_SIGNATURE "%c"
- "\x03%c%c%c" /* 32-bit type = 3 */
-
- "%c%c" /* LanManager length */
- "%c%c" /* LanManager allocated space */
- "%c%c" /* LanManager offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* NT-response length */
- "%c%c" /* NT-response allocated space */
- "%c%c" /* NT-response offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* domain length */
- "%c%c" /* domain allocated space */
- "%c%c" /* domain name offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* user length */
- "%c%c" /* user allocated space */
- "%c%c" /* user offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* host length */
- "%c%c" /* host allocated space */
- "%c%c" /* host offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* session key length (unknown purpose) */
- "%c%c" /* session key allocated space (unknown purpose) */
- "%c%c" /* session key offset (unknown purpose) */
- "%c%c" /* 2 zeroes */
-
- "%c%c%c%c", /* flags */
-
- /* domain string */
- /* user string */
- /* host string */
- /* LanManager response */
- /* NT response */
-
- 0, /* zero termination */
- 0, 0, 0, /* type-3 long, the 24 upper bits */
-
- SHORTPAIR(0x18), /* LanManager response length, twice */
- SHORTPAIR(0x18),
- SHORTPAIR(lmrespoff),
- 0x0, 0x0,
+ size = msnprintf((char *)ntlmbuf, NTLM_BUFSIZE,
+ NTLMSSP_SIGNATURE "%c"
+ "\x03%c%c%c" /* 32-bit type = 3 */
+
+ "%c%c" /* LanManager length */
+ "%c%c" /* LanManager allocated space */
+ "%c%c" /* LanManager offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* NT-response length */
+ "%c%c" /* NT-response allocated space */
+ "%c%c" /* NT-response offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* domain length */
+ "%c%c" /* domain allocated space */
+ "%c%c" /* domain name offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* user length */
+ "%c%c" /* user allocated space */
+ "%c%c" /* user offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* host length */
+ "%c%c" /* host allocated space */
+ "%c%c" /* host offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* session key length (unknown purpose) */
+ "%c%c" /* session key allocated space (unknown purpose) */
+ "%c%c" /* session key offset (unknown purpose) */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c%c%c", /* flags */
+
+ /* domain string */
+ /* user string */
+ /* host string */
+ /* LanManager response */
+ /* NT response */
+
+ 0, /* zero termination */
+ 0, 0, 0, /* type-3 long, the 24 upper bits */
+
+ SHORTPAIR(0x18), /* LanManager response length, twice */
+ SHORTPAIR(0x18),
+ SHORTPAIR(lmrespoff),
+ 0x0, 0x0,
#ifdef USE_NTRESPONSES
- SHORTPAIR(ntresplen), /* NT-response length, twice */
- SHORTPAIR(ntresplen),
- SHORTPAIR(ntrespoff),
- 0x0, 0x0,
+ SHORTPAIR(ntresplen), /* NT-response length, twice */
+ SHORTPAIR(ntresplen),
+ SHORTPAIR(ntrespoff),
+ 0x0, 0x0,
#else
- 0x0, 0x0,
- 0x0, 0x0,
- 0x0, 0x0,
- 0x0, 0x0,
+ 0x0, 0x0,
+ 0x0, 0x0,
+ 0x0, 0x0,
+ 0x0, 0x0,
#endif
- SHORTPAIR(domlen),
- SHORTPAIR(domlen),
- SHORTPAIR(domoff),
- 0x0, 0x0,
-
- SHORTPAIR(userlen),
- SHORTPAIR(userlen),
- SHORTPAIR(useroff),
- 0x0, 0x0,
-
- SHORTPAIR(hostlen),
- SHORTPAIR(hostlen),
- SHORTPAIR(hostoff),
- 0x0, 0x0,
-
- 0x0, 0x0,
- 0x0, 0x0,
- 0x0, 0x0,
- 0x0, 0x0,
-
- LONGQUARTET(ntlm->flags));
+ SHORTPAIR(domlen),
+ SHORTPAIR(domlen),
+ SHORTPAIR(domoff),
+ 0x0, 0x0,
+
+ SHORTPAIR(userlen),
+ SHORTPAIR(userlen),
+ SHORTPAIR(useroff),
+ 0x0, 0x0,
+
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostoff),
+ 0x0, 0x0,
+
+ 0x0, 0x0,
+ 0x0, 0x0,
+ 0x0, 0x0,
+ 0x0, 0x0,
+
+ LONGQUARTET(ntlm->flags));
DEBUGASSERT(size == 64);
DEBUGASSERT(size == (size_t)lmrespoff);
diff --git a/lib/version.c b/lib/version.c
index 05c2cd8b..e553100c 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -95,7 +95,7 @@ static size_t brotli_version(char *buf, size_t bufsz)
unsigned int minor = (brotli_version & 0x00FFFFFF) >> 12;
unsigned int patch = brotli_version & 0x00000FFF;
- return snprintf(buf, bufsz, "%u.%u.%u", major, minor, patch);
+ return msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch);
}
#endif
@@ -126,12 +126,12 @@ char *curl_version(void)
}
#ifdef HAVE_LIBZ
- len = snprintf(ptr, left, " zlib/%s", zlibVersion());
+ len = msnprintf(ptr, left, " zlib/%s", zlibVersion());
left -= len;
ptr += len;
#endif
#ifdef HAVE_BROTLI
- len = snprintf(ptr, left, "%s", " brotli/");
+ len = msnprintf(ptr, left, "%s", " brotli/");
left -= len;
ptr += len;
len = brotli_version(ptr, left);
@@ -140,45 +140,45 @@ char *curl_version(void)
#endif
#ifdef USE_ARES
/* this function is only present in c-ares, not in the original ares */
- len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL));
+ len = msnprintf(ptr, left, " c-ares/%s", ares_version(NULL));
left -= len;
ptr += len;
#endif
#ifdef USE_LIBIDN2
if(idn2_check_version(IDN2_VERSION)) {
- len = snprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL));
+ len = msnprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL));
left -= len;
ptr += len;
}
#endif
#ifdef USE_LIBPSL
- len = snprintf(ptr, left, " libpsl/%s", psl_get_version());
+ len = msnprintf(ptr, left, " libpsl/%s", psl_get_version());
left -= len;
ptr += len;
#endif
#ifdef USE_WIN32_IDN
- len = snprintf(ptr, left, " WinIDN");
+ len = msnprintf(ptr, left, " WinIDN");
left -= len;
ptr += len;
#endif
#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
#ifdef _LIBICONV_VERSION
- len = snprintf(ptr, left, " iconv/%d.%d",
- _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
+ len = msnprintf(ptr, left, " iconv/%d.%d",
+ _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
#else
/* version unknown */
- len = snprintf(ptr, left, " iconv");
+ len = msnprintf(ptr, left, " iconv");
#endif /* _LIBICONV_VERSION */
left -= len;
ptr += len;
#endif
#ifdef USE_LIBSSH2
- len = snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
+ len = msnprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
left -= len;
ptr += len;
#endif
#ifdef USE_LIBSSH
- len = snprintf(ptr, left, " libssh/%s", CURL_LIBSSH_VERSION);
+ len = msnprintf(ptr, left, " libssh/%s", CURL_LIBSSH_VERSION);
left -= len;
ptr += len;
#endif
@@ -197,14 +197,14 @@ char *curl_version(void)
else
suff[0] = '\0';
- snprintf(ptr, left, " librtmp/%d.%d%s",
- RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
- suff);
+ msnprintf(ptr, left, " librtmp/%d.%d%s",
+ RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
+ suff);
/*
If another lib version is added below this one, this code would
also have to do:
- len = what snprintf() returned
+ len = what msnprintf() returned
left -= len;
ptr += len;
@@ -436,10 +436,10 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
#endif
#if defined(USE_LIBSSH2)
- snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
+ msnprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
version_info.libssh_version = ssh_buffer;
#elif defined(USE_LIBSSH)
- snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh/%s", CURL_LIBSSH_VERSION);
+ msnprintf(ssh_buffer, sizeof(ssh_buffer), "libssh/%s", CURL_LIBSSH_VERSION);
version_info.libssh_version = ssh_buffer;
#endif
diff --git a/lib/vtls/axtls.c b/lib/vtls/axtls.c
deleted file mode 100644
index b262392a..00000000
--- a/lib/vtls/axtls.c
+++ /dev/null
@@ -1,741 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>.
- * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * 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.
- *
- ***************************************************************************/
-
-/*
- * Source file for all axTLS-specific code for the TLS/SSL layer. No code
- * but vtls.c should ever call or use these functions.
- */
-
-#include "curl_setup.h"
-
-#ifdef USE_AXTLS
-
-#error axTLS support has been disabled in curl due to doubts about quality,
-#error user dedication and a lack of use/testing. We urge users to consider
-#error using a more established TLS backend instead.
-
-#include <axTLS/config.h>
-#include <axTLS/ssl.h>
-#include "axtls.h"
-
-#include "sendf.h"
-#include "inet_pton.h"
-#include "vtls.h"
-#include "parsedate.h"
-#include "connect.h" /* for the connect timeout */
-#include "select.h"
-#include "curl_printf.h"
-#include "hostcheck.h"
-#include <unistd.h>
-
-/* The last #include files should be: */
-#include "curl_memory.h"
-#include "memdebug.h"
-
-struct ssl_backend_data {
- SSL_CTX* ssl_ctx;
- SSL* ssl;
-};
-
-#define BACKEND connssl->backend
-
-static CURLcode map_error_to_curl(int axtls_err)
-{
- switch(axtls_err) {
- case SSL_ERROR_NOT_SUPPORTED:
- case SSL_ERROR_INVALID_VERSION:
- case -70: /* protocol version alert from server */
- return CURLE_UNSUPPORTED_PROTOCOL;
- break;
- case SSL_ERROR_NO_CIPHER:
- return CURLE_SSL_CIPHER;
- break;
- case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
- case SSL_ERROR_NO_CERT_DEFINED:
- case -42: /* bad certificate alert from server */
- case -43: /* unsupported cert alert from server */
- case -44: /* cert revoked alert from server */
- case -45: /* cert expired alert from server */
- case -46: /* cert unknown alert from server */
- return CURLE_SSL_CERTPROBLEM;
- break;
- case SSL_X509_ERROR(X509_NOT_OK):
- case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
- case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
- case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
- case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
- case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
- case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
- case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
- case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
- return CURLE_PEER_FAILED_VERIFICATION;
- break;
- case -48: /* unknown ca alert from server */
- return CURLE_SSL_CACERT;
- break;
- case -49: /* access denied alert from server */
- return CURLE_REMOTE_ACCESS_DENIED;
- break;
- case SSL_ERROR_CONN_LOST:
- case SSL_ERROR_SOCK_SETUP_FAILURE:
- case SSL_ERROR_INVALID_HANDSHAKE:
- case SSL_ERROR_INVALID_PROT_MSG:
- case SSL_ERROR_INVALID_HMAC:
- case SSL_ERROR_INVALID_SESSION:
- case SSL_ERROR_INVALID_KEY: /* it's too bad this doesn't map better */
- case SSL_ERROR_FINISHED_INVALID:
- case SSL_ERROR_NO_CLIENT_RENOG:
- default:
- return CURLE_SSL_CONNECT_ERROR;
- break;
- }
-}
-
-static Curl_recv axtls_recv;
-static Curl_send axtls_send;
-
-static void free_ssl_structs(struct ssl_connect_data *connssl)
-{
- if(BACKEND->ssl) {
- ssl_free(BACKEND->ssl);
- BACKEND->ssl = NULL;
- }
- if(BACKEND->ssl_ctx) {
- ssl_ctx_free(BACKEND->ssl_ctx);
- BACKEND->ssl_ctx = NULL;
- }
-}
-
-/*
- * For both blocking and non-blocking connects, this function sets up the
- * ssl context and state. This function is called after the TCP connect
- * has completed.
- */
-static CURLcode connect_prep(struct connectdata *conn, int sockindex)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct Curl_easy *data = conn->data;
- SSL_CTX *ssl_ctx;
- SSL *ssl = NULL;
- int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
- int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
- int i, ssl_fcn_return;
-
- /* Assuming users will not compile in custom key/cert to axTLS.
- * Also, even for blocking connects, use axTLS non-blocking feature.
- */
- uint32_t client_option = SSL_NO_DEFAULT_KEY |
- SSL_SERVER_VERIFY_LATER |
- SSL_CONNECT_IN_PARTS;
-
- if(connssl->state == ssl_connection_complete)
- /* to make us tolerant against being called more than once for the
- same connection */
- return CURLE_OK;
-
- if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
- failf(data, "axtls does not support CURL_SSLVERSION_MAX");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
-
- /* axTLS only supports TLSv1 */
- /* check to see if we've been told to use an explicit SSL/TLS version */
- switch(SSL_CONN_CONFIG(version)) {
- case CURL_SSLVERSION_DEFAULT:
- case CURL_SSLVERSION_TLSv1:
- break;
- default:
- failf(data, "axTLS only supports TLS 1.0 and 1.1, "
- "and it cannot be specified which one to use");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
-#ifdef AXTLSDEBUG
- client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
-#endif /* AXTLSDEBUG */
-
- /* Allocate an SSL_CTX struct */
- ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
- if(ssl_ctx == NULL) {
- failf(data, "unable to create client SSL context");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- BACKEND->ssl_ctx = ssl_ctx;
- BACKEND->ssl = NULL;
-
- /* Load the trusted CA cert bundle file */
- if(SSL_CONN_CONFIG(CAfile)) {
- if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT,
- SSL_CONN_CONFIG(CAfile), NULL) != SSL_OK) {
- infof(data, "error reading ca cert file %s \n",
- SSL_CONN_CONFIG(CAfile));
- if(SSL_CONN_CONFIG(verifypeer)) {
- return CURLE_SSL_CACERT_BADFILE;
- }
- }
- else
- infof(data, "found certificates in %s\n", SSL_CONN_CONFIG(CAfile));
- }
-
- /* gtls.c tasks we're skipping for now:
- * 1) certificate revocation list checking
- * 2) dns name assignment to host
- * 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore
- * 4) set certificate priority. axTLS ignores type and sends certs in
- * order added. can probably ignore this.
- */
-
- /* Load client certificate */
- if(SSL_SET_OPTION(cert)) {
- i = 0;
- /* Instead of trying to analyze cert type here, let axTLS try them all. */
- while(cert_types[i] != 0) {
- ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
- SSL_SET_OPTION(cert), NULL);
- if(ssl_fcn_return == SSL_OK) {
- infof(data, "successfully read cert file %s \n",
- SSL_SET_OPTION(cert));
- break;
- }
- i++;
- }
- /* Tried all cert types, none worked. */
- if(cert_types[i] == 0) {
- failf(data, "%s is not x509 or pkcs12 format",
- SSL_SET_OPTION(cert));
- return CURLE_SSL_CERTPROBLEM;
- }
- }
-
- /* Load client key.
- If a pkcs12 file successfully loaded a cert, then there's nothing to do
- because the key has already been loaded. */
- if(SSL_SET_OPTION(key) && cert_types[i] != SSL_OBJ_PKCS12) {
- i = 0;
- /* Instead of trying to analyze key type here, let axTLS try them all. */
- while(key_types[i] != 0) {
- ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
- SSL_SET_OPTION(key), NULL);
- if(ssl_fcn_return == SSL_OK) {
- infof(data, "successfully read key file %s \n",
- SSL_SET_OPTION(key));
- break;
- }
- i++;
- }
- /* Tried all key types, none worked. */
- if(key_types[i] == 0) {
- failf(data, "Failure: %s is not a supported key file",
- SSL_SET_OPTION(key));
- return CURLE_SSL_CONNECT_ERROR;
- }
- }
-
- /* gtls.c does more here that is being left out for now
- * 1) set session credentials. can probably ignore since axtls puts this
- * info in the ssl_ctx struct
- * 2) setting up callbacks. these seem gnutls specific
- */
-
- if(SSL_SET_OPTION(primary.sessionid)) {
- const uint8_t *ssl_sessionid;
- size_t ssl_idsize;
-
- /* In axTLS, handshaking happens inside ssl_client_new. */
- Curl_ssl_sessionid_lock(conn);
- if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize,
- sockindex)) {
- /* we got a session id, use it! */
- infof(data, "SSL re-using session ID\n");
- ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
- ssl_sessionid, (uint8_t)ssl_idsize, NULL);
- }
- Curl_ssl_sessionid_unlock(conn);
- }
-
- if(!ssl)
- ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0, NULL);
-
- BACKEND->ssl = ssl;
- return CURLE_OK;
-}
-
-static void Curl_axtls_close(struct connectdata *conn, int sockindex)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
- infof(conn->data, " Curl_axtls_close\n");
-
- /* line from openssl.c: (void)SSL_shutdown(BACKEND->ssl);
- axTLS compat layer does nothing for SSL_shutdown */
-
- /* The following line is from openssl.c. There seems to be no axTLS
- equivalent. ssl_free and ssl_ctx_free close things.
- SSL_set_connect_state(connssl->handle); */
-
- free_ssl_structs(connssl);
-}
-
-/*
- * For both blocking and non-blocking connects, this function finalizes the
- * SSL connection.
- */
-static CURLcode connect_finish(struct connectdata *conn, int sockindex)
-{
- struct Curl_easy *data = conn->data;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- SSL *ssl = BACKEND->ssl;
- const char *peer_CN;
- uint32_t dns_altname_index;
- const char *dns_altname;
- int8_t found_subject_alt_names = 0;
- int8_t found_subject_alt_name_matching_conn = 0;
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
- const char * const dispname = SSL_IS_PROXY() ?
- conn->http_proxy.host.dispname : conn->host.dispname;
-
- /* Here, gtls.c gets the peer certificates and fails out depending on
- * settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
- */
-
- /* Verify server's certificate */
- if(SSL_CONN_CONFIG(verifypeer)) {
- if(ssl_verify_cert(ssl) != SSL_OK) {
- Curl_axtls_close(conn, sockindex);
- failf(data, "server cert verify failed");
- return CURLE_PEER_FAILED_VERIFICATION;
- }
- }
- else
- infof(data, "\t server certificate verification SKIPPED\n");
-
- /* Here, gtls.c does issuer verification. axTLS has no straightforward
- * equivalent, so omitting for now.*/
-
- /* Here, gtls.c does the following
- * 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
- * it seems useful. This is now implemented, by Oscar Koeroo
- * 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
- * 3) displays a bunch of cert information. axTLS doesn't support most of
- * this, but a couple fields are available.
- */
-
- /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
- risk of an inifite loop */
- for(dns_altname_index = 0; ; dns_altname_index++) {
- dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
- if(dns_altname == NULL) {
- break;
- }
- found_subject_alt_names = 1;
-
- infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
- dns_altname, hostname);
- if(Curl_cert_hostcheck(dns_altname, hostname)) {
- found_subject_alt_name_matching_conn = 1;
- break;
- }
- }
-
- /* RFC2818 checks */
- if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
- if(SSL_CONN_CONFIG(verifyhost)) {
- /* Break connection ! */
- Curl_axtls_close(conn, sockindex);
- failf(data, "\tsubjectAltName(s) do not match %s\n", dispname);
- return CURLE_PEER_FAILED_VERIFICATION;
- }
- else
- infof(data, "\tsubjectAltName(s) do not match %s\n", dispname);
- }
- else if(found_subject_alt_names == 0) {
- /* Per RFC2818, when no Subject Alt Names were available, examine the peer
- CN as a legacy fallback */
- peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
- if(peer_CN == NULL) {
- if(SSL_CONN_CONFIG(verifyhost)) {
- Curl_axtls_close(conn, sockindex);
- failf(data, "unable to obtain common name from peer certificate");
- return CURLE_PEER_FAILED_VERIFICATION;
- }
- else
- infof(data, "unable to obtain common name from peer certificate");
- }
- else {
- if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
- if(SSL_CONN_CONFIG(verifyhost)) {
- /* Break connection ! */
- Curl_axtls_close(conn, sockindex);
- failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
- peer_CN, dispname);
- return CURLE_PEER_FAILED_VERIFICATION;
- }
- else
- infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
- peer_CN, dispname);
- }
- }
- }
-
- /* General housekeeping */
- connssl->state = ssl_connection_complete;
- conn->recv[sockindex] = axtls_recv;
- conn->send[sockindex] = axtls_send;
-
- /* Put our freshly minted SSL session in cache */
- if(SSL_SET_OPTION(primary.sessionid)) {
- const uint8_t *ssl_sessionid = ssl_get_session_id(ssl);
- size_t ssl_idsize = ssl_get_session_id_size(ssl);
- Curl_ssl_sessionid_lock(conn);
- if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize,
- sockindex) != CURLE_OK)
- infof(data, "failed to add session to cache\n");
- Curl_ssl_sessionid_unlock(conn);
- }
-
- return CURLE_OK;
-}
-
-/*
- * Use axTLS's non-blocking connection feature to open an SSL connection.
- * This is called after a TCP connection is already established.
- */
-static CURLcode Curl_axtls_connect_nonblocking(struct connectdata *conn,
- int sockindex, bool *done)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- CURLcode conn_step;
- int ssl_fcn_return;
- int i;
-
- *done = FALSE;
- /* connectdata is calloc'd and connecting_state is only changed in this
- function, so this is safe, as the state is effectively initialized. */
- if(connssl->connecting_state == ssl_connect_1) {
- conn_step = connect_prep(conn, sockindex);
- if(conn_step != CURLE_OK) {
- Curl_axtls_close(conn, sockindex);
- return conn_step;
- }
- connssl->connecting_state = ssl_connect_2;
- }
-
- if(connssl->connecting_state == ssl_connect_2) {
- /* Check to make sure handshake was ok. */
- if(ssl_handshake_status(BACKEND->ssl) != SSL_OK) {
- /* Loop to perform more work in between sleeps. This is work around the
- fact that axtls does not expose any knowledge about when work needs
- to be performed. This can save ~25% of time on SSL handshakes. */
- for(i = 0; i<5; i++) {
- ssl_fcn_return = ssl_read(BACKEND->ssl, NULL);
- if(ssl_fcn_return < 0) {
- Curl_axtls_close(conn, sockindex);
- ssl_display_error(ssl_fcn_return); /* goes to stdout. */
- return map_error_to_curl(ssl_fcn_return);
- }
- return CURLE_OK;
- }
- }
- infof(conn->data, "handshake completed successfully\n");
- connssl->connecting_state = ssl_connect_3;
- }
-
- if(connssl->connecting_state == ssl_connect_3) {
- conn_step = connect_finish(conn, sockindex);
- if(conn_step != CURLE_OK) {
- Curl_axtls_close(conn, sockindex);
- return conn_step;
- }
-
- /* Reset connect state */
- connssl->connecting_state = ssl_connect_1;
-
- *done = TRUE;
- return CURLE_OK;
- }
-
- /* Unrecognized state. Things are very bad. */
- connssl->state = ssl_connection_none;
- connssl->connecting_state = ssl_connect_1;
- /* Return value perhaps not strictly correct, but distinguishes the issue.*/
- return CURLE_BAD_FUNCTION_ARGUMENT;
-}
-
-
-/*
- * This function is called after the TCP connect has completed. Setup the TLS
- * layer and do all necessary magic for a blocking connect.
- */
-static CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex)
-{
- struct Curl_easy *data = conn->data;
- CURLcode conn_step = connect_prep(conn, sockindex);
- int ssl_fcn_return;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- SSL *ssl = BACKEND->ssl;
- long timeout_ms;
-
- if(conn_step != CURLE_OK) {
- Curl_axtls_close(conn, sockindex);
- return conn_step;
- }
-
- /* Check to make sure handshake was ok. */
- while(ssl_handshake_status(ssl) != SSL_OK) {
- /* 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;
- }
-
- ssl_fcn_return = ssl_read(ssl, NULL);
- if(ssl_fcn_return < 0) {
- Curl_axtls_close(conn, sockindex);
- ssl_display_error(ssl_fcn_return); /* goes to stdout. */
- return map_error_to_curl(ssl_fcn_return);
- }
- /* TODO: avoid polling */
- Curl_wait_ms(10);
- }
- infof(conn->data, "handshake completed successfully\n");
-
- conn_step = connect_finish(conn, sockindex);
- if(conn_step != CURLE_OK) {
- Curl_axtls_close(conn, sockindex);
- return conn_step;
- }
-
- return CURLE_OK;
-}
-
-/* return number of sent (non-SSL) bytes */
-static ssize_t axtls_send(struct connectdata *conn,
- int sockindex,
- const void *mem,
- size_t len,
- CURLcode *err)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- /* ssl_write() returns 'int' while write() and send() returns 'size_t' */
- int rc = ssl_write(BACKEND->ssl, mem, (int)len);
-
- infof(conn->data, " axtls_send\n");
-
- if(rc < 0) {
- *err = map_error_to_curl(rc);
- rc = -1; /* generic error code for send failure */
- }
-
- *err = CURLE_OK;
- return rc;
-}
-
-/*
- * This function is called to shut down the SSL layer but keep the
- * socket open (CCC - Clear Command Channel)
- */
-static int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
-{
- /* Outline taken from openssl.c since functions are in axTLS compat layer.
- axTLS's error set is much smaller, so a lot of error-handling was removed.
- */
- int retval = 0;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct Curl_easy *data = conn->data;
- uint8_t *buf;
- ssize_t nread;
-
- infof(conn->data, " Curl_axtls_shutdown\n");
-
- /* This has only been tested on the proftpd server, and the mod_tls code
- sends a close notify alert without waiting for a close notify alert in
- response. Thus we wait for a close notify alert from the server, but
- we do not send one. Let's hope other servers do the same... */
-
- /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
- if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
- (void)SSL_shutdown(BACKEND->ssl);
- */
-
- if(BACKEND->ssl) {
- int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
- if(what > 0) {
- /* Something to read, let's do it and hope that it is the close
- notify alert from the server. buf is managed internally by
- axTLS and will be released upon calling ssl_free via
- free_ssl_structs. */
- nread = (ssize_t)ssl_read(BACKEND->ssl, &buf);
-
- if(nread < SSL_OK) {
- failf(data, "close notify alert not received during shutdown");
- retval = -1;
- }
- }
- else if(0 == what) {
- /* timeout */
- failf(data, "SSL shutdown timeout");
- }
- else {
- /* anything that gets here is fatally bad */
- failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
- retval = -1;
- }
-
- free_ssl_structs(connssl);
- }
- return retval;
-}
-
-static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
- int num, /* socketindex */
- char *buf, /* store read data here */
- size_t buffersize, /* max amount to read */
- CURLcode *err)
-{
- struct ssl_connect_data *connssl = &conn->ssl[num];
- ssize_t ret = 0;
- uint8_t *read_buf;
-
- infof(conn->data, " axtls_recv\n");
-
- *err = CURLE_OK;
- if(connssl) {
- ret = ssl_read(BACKEND->ssl, &read_buf);
- if(ret > SSL_OK) {
- /* ssl_read returns SSL_OK if there is more data to read, so if it is
- larger, then all data has been read already. */
- memcpy(buf, read_buf,
- (size_t)ret > buffersize ? buffersize : (size_t)ret);
- }
- else if(ret == SSL_OK) {
- /* more data to be read, signal caller to call again */
- *err = CURLE_AGAIN;
- ret = -1;
- }
- else if(ret == -3) {
- /* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
- team approves proposed fix. */
- Curl_axtls_close(conn, num);
- }
- else {
- failf(conn->data, "axTLS recv error (%d)", ret);
- *err = map_error_to_curl((int) ret);
- ret = -1;
- }
- }
-
- return ret;
-}
-
-/*
- * Return codes:
- * 1 means the connection is still in place
- * 0 means the connection has been closed
- * -1 means the connection status is unknown
- */
-static int Curl_axtls_check_cxn(struct connectdata *conn)
-{
- /* openssl.c line:
- rc = SSL_peek(conn->ssl[FIRSTSOCKET].backend->ssl, (void*)&buf, 1);
- axTLS compat layer always returns the last argument, so connection is
- always alive? */
-
- infof(conn->data, " Curl_axtls_check_cxn\n");
- return 1; /* connection still in place */
-}
-
-static void Curl_axtls_session_free(void *ptr)
-{
- (void)ptr;
- /* free the ID */
- /* both openssl.c and gtls.c do something here, but axTLS's OpenSSL
- compatibility layer does nothing, so we do nothing too. */
-}
-
-static size_t Curl_axtls_version(char *buffer, size_t size)
-{
- return snprintf(buffer, size, "axTLS/%s", ssl_version());
-}
-
-static CURLcode Curl_axtls_random(struct Curl_easy *data,
- unsigned char *entropy, size_t length)
-{
- static bool ssl_seeded = FALSE;
- (void)data;
- if(!ssl_seeded) {
- ssl_seeded = TRUE;
- /* Initialize the seed if not already done. This call is not exactly thread
- * safe (and neither is the ssl_seeded check), but the worst effect of a
- * race condition is that some global resources will leak. */
- RNG_initialize();
- }
- get_random((int)length, entropy);
- return CURLE_OK;
-}
-
-static void *Curl_axtls_get_internals(struct ssl_connect_data *connssl,
- CURLINFO info UNUSED_PARAM)
-{
- (void)info;
- return BACKEND->ssl;
-}
-
-const struct Curl_ssl Curl_ssl_axtls = {
- { CURLSSLBACKEND_AXTLS, "axtls" }, /* info */
- 0, /* no fancy stuff */
- sizeof(struct ssl_backend_data),
-
- /*
- * axTLS has no global init. Everything is done through SSL and SSL_CTX
- * structs stored in connectdata structure.
- */
- Curl_none_init, /* init */
- /* axTLS has no global cleanup. */
- Curl_none_cleanup, /* cleanup */
- Curl_axtls_version, /* version */
- Curl_axtls_check_cxn, /* check_cxn */
- Curl_axtls_shutdown, /* shutdown */
- Curl_none_data_pending, /* data_pending */
- Curl_axtls_random, /* random */
- Curl_none_cert_status_request, /* cert_status_request */
- Curl_axtls_connect, /* connect */
- Curl_axtls_connect_nonblocking, /* connect_nonblocking */
- Curl_axtls_get_internals, /* get_internals */
- Curl_axtls_close, /* close_one */
- Curl_none_close_all, /* close_all */
- Curl_axtls_session_free, /* session_free */
- Curl_none_set_engine, /* set_engine */
- Curl_none_set_engine_default, /* set_engine_default */
- Curl_none_engines_list, /* engines_list */
- Curl_none_false_start, /* false_start */
- Curl_none_md5sum, /* md5sum */
- NULL /* sha256sum */
-};
-
-#endif /* USE_AXTLS */
diff --git a/lib/vtls/axtls.h b/lib/vtls/axtls.h
deleted file mode 100644
index cb818727..00000000
--- a/lib/vtls/axtls.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef HEADER_CURL_AXTLS_H
-#define HEADER_CURL_AXTLS_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu@directv.com>
- * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#ifdef USE_AXTLS
-#include "curl/curl.h"
-#include "urldata.h"
-
-extern const struct Curl_ssl Curl_ssl_axtls;
-
-#endif /* USE_AXTLS */
-#endif /* HEADER_CURL_AXTLS_H */
diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c
index e10398ac..0d45afbf 100644
--- a/lib/vtls/cyassl.c
+++ b/lib/vtls/cyassl.c
@@ -777,13 +777,13 @@ static void Curl_cyassl_session_free(void *ptr)
static size_t Curl_cyassl_version(char *buffer, size_t size)
{
#if LIBCYASSL_VERSION_HEX >= 0x03006000
- return snprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
+ return msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
#elif defined(WOLFSSL_VERSION)
- return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
+ return msnprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
#elif defined(CYASSL_VERSION)
- return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
+ return msnprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
#else
- return snprintf(buffer, size, "CyaSSL/%s", "<1.8.8");
+ return msnprintf(buffer, size, "CyaSSL/%s", "<1.8.8");
#endif
}
diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index e8116b8a..25b10128 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -950,7 +950,7 @@ static CURLcode CopyCertSubject(struct Curl_easy *data,
if(!c) {
failf(data, "SSL: invalid CA certificate subject");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
}
/* If the subject is already available as UTF-8 encoded (ie 'direct') then
@@ -970,7 +970,7 @@ static CURLcode CopyCertSubject(struct Curl_easy *data,
if(!CFStringGetCString(c, cbuf, cbuf_size,
kCFStringEncodingUTF8)) {
failf(data, "SSL: invalid CA certificate subject");
- result = CURLE_SSL_CACERT;
+ result = CURLE_PEER_FAILED_VERIFICATION;
}
else
/* pass back the buffer */
@@ -1649,7 +1649,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
CFRelease(cert);
- if(result == CURLE_SSL_CACERT)
+ if(result == CURLE_PEER_FAILED_VERIFICATION)
return CURLE_SSL_CERTPROBLEM;
if(result)
return result;
@@ -2429,37 +2429,37 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
/* These are all certificate problems with the server: */
case errSSLXCertChainInvalid:
failf(data, "SSL certificate problem: Invalid certificate chain");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLUnknownRootCert:
failf(data, "SSL certificate problem: Untrusted root certificate");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLNoRootCert:
failf(data, "SSL certificate problem: No root certificate");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLCertNotYetValid:
failf(data, "SSL certificate problem: The certificate chain had a "
"certificate that is not yet valid");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLCertExpired:
case errSSLPeerCertExpired:
failf(data, "SSL certificate problem: Certificate chain had an "
"expired certificate");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLBadCert:
case errSSLPeerBadCert:
failf(data, "SSL certificate problem: Couldn't understand the server "
"certificate format");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLPeerUnsupportedCert:
failf(data, "SSL certificate problem: An unsupported certificate "
"format was encountered");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLPeerCertRevoked:
failf(data, "SSL certificate problem: The certificate was revoked");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLPeerCertUnknown:
failf(data, "SSL certificate problem: The certificate is unknown");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
/* These are all certificate problems with the client: */
case errSecAuthFailed:
@@ -3015,7 +3015,7 @@ static void Curl_darwinssl_session_free(void *ptr)
static size_t Curl_darwinssl_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "SecureTransport");
+ return msnprintf(buffer, size, "SecureTransport");
}
/*
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index 8d1b3d6a..c4afc890 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -1314,7 +1314,7 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
static size_t Curl_gskit_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "GSKit");
+ return msnprintf(buffer, size, "GSKit");
}
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 37662a74..9035ec48 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -227,17 +227,17 @@ static void showtime(struct Curl_easy *data,
if(result)
return;
- snprintf(str,
- sizeof(str),
- "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
- text,
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
+ msnprintf(str,
+ sizeof(str),
+ "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
+ text,
+ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
infof(data, "%s\n", str);
}
#endif
@@ -1110,7 +1110,7 @@ gtls_connect_step3(struct connectdata *conn,
"CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
"none",
SSL_SET_OPTION(CRLfile)?SSL_SET_OPTION(CRLfile):"none");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "\t server certificate verification FAILED\n");
@@ -1748,7 +1748,7 @@ static void Curl_gtls_session_free(void *ptr)
static size_t Curl_gtls_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
+ return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
}
#ifndef USE_GNUTLS_NETTLE
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index c5ed8872..6a20e276 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -580,7 +580,7 @@ mbed_connect_step2(struct connectdata *conn,
if(ret & MBEDTLS_X509_BADCERT_REVOKED) {
failf(data, "Cert verify failed: BADCERT_REVOKED");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
}
if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH)
@@ -812,8 +812,8 @@ static void Curl_mbedtls_session_free(void *ptr)
static size_t Curl_mbedtls_version(char *buffer, size_t size)
{
unsigned int version = mbedtls_version_get_number();
- return snprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24,
- (version>>16)&0xff, (version>>8)&0xff);
+ return msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24,
+ (version>>16)&0xff, (version>>8)&0xff);
}
static CURLcode Curl_mbedtls_random(struct Curl_easy *data,
diff --git a/lib/vtls/mesalink.c b/lib/vtls/mesalink.c
index 6a2b67e6..db141155 100644
--- a/lib/vtls/mesalink.c
+++ b/lib/vtls/mesalink.c
@@ -5,8 +5,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2017-2018, Yiming Jing, <jingyiming@baidu.com>
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com>
+ * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -424,7 +424,7 @@ mesalink_recv(struct connectdata *conn, int num, char *buf, size_t buffersize,
static size_t
Curl_mesalink_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "MesaLink/%s", MESALINK_VERSION_STRING);
+ return msnprintf(buffer, size, "MesaLink/%s", MESALINK_VERSION_STRING);
}
static int
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index a3d3e58b..08ee1aaa 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -246,6 +246,32 @@ static void nss_print_error_message(struct Curl_easy *data, PRUint32 err)
failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
}
+static char *nss_sslver_to_name(PRUint16 nssver)
+{
+ switch(nssver) {
+ case SSL_LIBRARY_VERSION_2:
+ return strdup("SSLv2");
+ case SSL_LIBRARY_VERSION_3_0:
+ return strdup("SSLv3");
+ case SSL_LIBRARY_VERSION_TLS_1_0:
+ return strdup("TLSv1.0");
+#ifdef SSL_LIBRARY_VERSION_TLS_1_1
+ case SSL_LIBRARY_VERSION_TLS_1_1:
+ return strdup("TLSv1.1");
+#endif
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+ case SSL_LIBRARY_VERSION_TLS_1_2:
+ return strdup("TLSv1.2");
+#endif
+#ifdef SSL_LIBRARY_VERSION_TLS_1_3
+ case SSL_LIBRARY_VERSION_TLS_1_3:
+ return strdup("TLSv1.3");
+#endif
+ default:
+ return curl_maprintf("0x%04x", nssver);
+ }
+}
+
static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
char *cipher_list)
{
@@ -1638,17 +1664,6 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version)
{
switch(version) {
- case CURL_SSLVERSION_TLSv1:
- /* TODO: set sslver->max to SSL_LIBRARY_VERSION_TLS_1_3 once stable */
-#ifdef SSL_LIBRARY_VERSION_TLS_1_2
- *nssver = SSL_LIBRARY_VERSION_TLS_1_2;
-#elif defined SSL_LIBRARY_VERSION_TLS_1_1
- *nssver = SSL_LIBRARY_VERSION_TLS_1_1;
-#else
- *nssver = SSL_LIBRARY_VERSION_TLS_1_0;
-#endif
- return CURLE_OK;
-
case CURL_SSLVERSION_SSLv2:
*nssver = SSL_LIBRARY_VERSION_2;
return CURLE_OK;
@@ -1709,10 +1724,8 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
}
switch(min) {
- case CURL_SSLVERSION_DEFAULT:
- break;
case CURL_SSLVERSION_TLSv1:
- sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+ case CURL_SSLVERSION_DEFAULT:
break;
default:
result = nss_sslver_from_curl(&sslver->min, min);
@@ -1789,10 +1802,19 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode result;
bool second_layer = FALSE;
+ SSLVersionRange sslver_supported;
SSLVersionRange sslver = {
SSL_LIBRARY_VERSION_TLS_1_0, /* min */
- SSL_LIBRARY_VERSION_TLS_1_0 /* max */
+#ifdef SSL_LIBRARY_VERSION_TLS_1_3
+ SSL_LIBRARY_VERSION_TLS_1_3 /* max */
+#elif defined SSL_LIBRARY_VERSION_TLS_1_2
+ SSL_LIBRARY_VERSION_TLS_1_2
+#elif defined SSL_LIBRARY_VERSION_TLS_1_1
+ SSL_LIBRARY_VERSION_TLS_1_1
+#else
+ SSL_LIBRARY_VERSION_TLS_1_0
+#endif
};
BACKEND->data = data;
@@ -1841,6 +1863,20 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
/* enable/disable the requested SSL version(s) */
if(nss_init_sslver(&sslver, data, conn) != CURLE_OK)
goto error;
+ if(SSL_VersionRangeGetSupported(ssl_variant_stream,
+ &sslver_supported) != SECSuccess)
+ goto error;
+ if(sslver_supported.max < sslver.max && sslver_supported.max >= sslver.min) {
+ char *sslver_req_str, *sslver_supp_str;
+ sslver_req_str = nss_sslver_to_name(sslver.max);
+ sslver_supp_str = nss_sslver_to_name(sslver_supported.max);
+ if(sslver_req_str && sslver_supp_str)
+ infof(data, "Falling back from %s to max supported SSL version (%s)\n",
+ sslver_req_str, sslver_supp_str);
+ free(sslver_req_str);
+ free(sslver_supp_str);
+ sslver.max = sslver_supported.max;
+ }
if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
goto error;
@@ -2090,7 +2126,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
result = CURLE_PEER_FAILED_VERIFICATION;
else if(*certverifyresult != 0)
- result = CURLE_SSL_CACERT;
+ result = CURLE_PEER_FAILED_VERIFICATION;
goto error;
}
@@ -2164,7 +2200,7 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
if(!blocking)
/* CURLE_AGAIN in non-blocking mode is not an error */
return CURLE_OK;
- /* fall through */
+ /* FALLTHROUGH */
default:
return result;
}
@@ -2279,7 +2315,7 @@ static ssize_t nss_recv(struct connectdata *conn, /* connection data */
static size_t Curl_nss_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "NSS/%s", NSS_VERSION);
+ return msnprintf(buffer, size, "NSS/%s", NSS_VERSION);
}
/* data might be NULL */
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 4c5e8c19..8bddb9a8 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -69,7 +69,7 @@
#include <openssl/ocsp.h>
#endif
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && /* 0.9.8 or later */ \
+#if (OPENSSL_VERSION_NUMBER >= 0x0090700fL) && /* 0.9.7 or later */ \
!defined(OPENSSL_NO_ENGINE)
#define USE_OPENSSL_ENGINE
#include <openssl/engine.h>
@@ -82,6 +82,13 @@
#include "curl_memory.h"
#include "memdebug.h"
+/* Uncomment the ALLOW_RENEG line to a real #define if you want to allow TLS
+ renegotiations when built with BoringSSL. Renegotiating is non-compliant
+ with HTTP/2 and "an extremely dangerous protocol feature". Beware.
+
+#define ALLOW_RENEG 1
+ */
+
#ifndef OPENSSL_VERSION_NUMBER
#error "OPENSSL_VERSION_NUMBER not defined"
#endif
@@ -384,6 +391,31 @@ static char *ossl_strerror(unsigned long error, char *buf, size_t size)
return buf;
}
+/* Return an extra data index for the connection data.
+ * This index can be used with SSL_get_ex_data() and SSL_set_ex_data().
+ */
+static int ossl_get_ssl_conn_index(void)
+{
+ static int ssl_ex_data_conn_index = -1;
+ if(ssl_ex_data_conn_index < 0) {
+ ssl_ex_data_conn_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+ }
+ return ssl_ex_data_conn_index;
+}
+
+/* Return an extra data index for the sockindex.
+ * This index can be used with SSL_get_ex_data() and SSL_set_ex_data().
+ */
+static int ossl_get_ssl_sockindex_index(void)
+{
+ static int ssl_ex_data_sockindex_index = -1;
+ if(ssl_ex_data_sockindex_index < 0) {
+ ssl_ex_data_sockindex_index = SSL_get_ex_new_index(0, NULL, NULL, NULL,
+ NULL);
+ }
+ return ssl_ex_data_sockindex_index;
+}
+
static int passwd_callback(char *buf, int num, int encrypting,
void *global_passwd)
{
@@ -1035,6 +1067,10 @@ static int Curl_ossl_init(void)
}
#endif
+ /* Initialize the extra data indexes */
+ if(ossl_get_ssl_conn_index() < 0 || ossl_get_ssl_sockindex_index() < 0)
+ return 0;
+
return 1;
}
@@ -1049,7 +1085,7 @@ static void Curl_ossl_cleanup(void)
/* Free ciphers and digests lists */
EVP_cleanup();
-#ifdef HAVE_ENGINE_CLEANUP
+#ifdef USE_OPENSSL_ENGINE
/* Free engine list */
ENGINE_cleanup();
#endif
@@ -1867,15 +1903,8 @@ static const char *ssl_msg_type(int ssl_ver, int msg)
return "Unknown";
}
-static const char *tls_rt_type(int type, const void *buf, size_t buflen)
+static const char *tls_rt_type(int type)
{
- (void)buf;
- (void)buflen;
-#ifdef SSL3_RT_INNER_CONTENT_TYPE
- if(type == SSL3_RT_INNER_CONTENT_TYPE && buf && buflen >= 1)
- type = *(unsigned char *)buf;
-#endif
-
switch(type) {
#ifdef SSL3_RT_HEADER
case SSL3_RT_HEADER:
@@ -1945,12 +1974,20 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
case 0:
break;
default:
- snprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
+ msnprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
verstr = unknown;
break;
}
- if(ssl_ver) {
+ /* Log progress for interesting records only (like Handshake or Alert), skip
+ * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0).
+ * For TLS 1.3, skip notification of the decrypted inner Content Type.
+ */
+ if(ssl_ver
+#ifdef SSL3_RT_INNER_CONTENT_TYPE
+ && content_type != SSL3_RT_INNER_CONTENT_TYPE
+#endif
+ ) {
const char *msg_name, *tls_rt_name;
char ssl_buf[1024];
int msg_type, txt_len;
@@ -1964,17 +2001,10 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
* is at 'buf[0]'.
*/
if(ssl_ver == SSL3_VERSION_MAJOR && content_type)
- tls_rt_name = tls_rt_type(content_type, buf, len);
+ tls_rt_name = tls_rt_type(content_type);
else
tls_rt_name = "";
-#ifdef SSL3_RT_INNER_CONTENT_TYPE
- if(content_type == SSL3_RT_INNER_CONTENT_TYPE) {
- msg_type = 0;
- msg_name = "[no content]";
- }
- else
-#endif
if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
msg_type = *(char *)buf;
msg_name = "Change cipher spec";
@@ -1988,9 +2018,9 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
msg_name = ssl_msg_type(ssl_ver, msg_type);
}
- txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
- verstr, direction?"OUT":"IN",
- tls_rt_name, msg_name, msg_type);
+ txt_len = msnprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
+ verstr, direction?"OUT":"IN",
+ tls_rt_name, msg_name, msg_type);
if(0 <= txt_len && (unsigned)txt_len < sizeof(ssl_buf)) {
Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len);
}
@@ -2137,6 +2167,7 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
}
#else
(void)sockindex;
+ (void)ctx_options;
failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
return CURLE_NOT_BUILT_IN;
#endif
@@ -2189,6 +2220,62 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
return CURLE_OK;
}
+/* The "new session" callback must return zero if the session can be removed
+ * or non-zero if the session has been put into the session cache.
+ */
+static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
+{
+ int res = 0;
+ struct connectdata *conn;
+ struct Curl_easy *data;
+ int sockindex;
+ curl_socket_t *sockindex_ptr;
+ int connectdata_idx = ossl_get_ssl_conn_index();
+ int sockindex_idx = ossl_get_ssl_sockindex_index();
+
+ if(connectdata_idx < 0 || sockindex_idx < 0)
+ return 0;
+
+ conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx);
+ if(!conn)
+ return 0;
+
+ data = conn->data;
+
+ /* The sockindex has been stored as a pointer to an array element */
+ sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx);
+ sockindex = (int)(sockindex_ptr - conn->sock);
+
+ if(SSL_SET_OPTION(primary.sessionid)) {
+ bool incache;
+ void *old_ssl_sessionid = NULL;
+
+ Curl_ssl_sessionid_lock(conn);
+ incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
+ sockindex));
+ if(incache) {
+ if(old_ssl_sessionid != ssl_sessionid) {
+ infof(data, "old SSL session ID is stale, removing\n");
+ Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+ incache = FALSE;
+ }
+ }
+
+ if(!incache) {
+ if(!Curl_ssl_addsessionid(conn, ssl_sessionid,
+ 0 /* unknown size */, sockindex)) {
+ /* the session has been put into the session cache */
+ res = 1;
+ }
+ else
+ failf(data, "failed to store ssl session");
+ }
+ Curl_ssl_sessionid_unlock(conn);
+ }
+
+ return res;
+}
+
static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
{
CURLcode result = CURLE_OK;
@@ -2585,6 +2672,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
}
#endif
+ /* Enable the session cache because it's a prerequisite for the "new session"
+ * callback. Use the "external storage" mode to avoid that OpenSSL creates
+ * an internal session cache.
+ */
+ SSL_CTX_set_session_cache_mode(BACKEND->ctx,
+ SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
+ SSL_CTX_sess_set_new_cb(BACKEND->ctx, ossl_new_session_cb);
+
/* give application a chance to interfere with SSL set up. */
if(data->set.ssl.fsslctx) {
result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
@@ -2610,6 +2705,10 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
SSL_set_tlsext_status_type(BACKEND->handle, TLSEXT_STATUSTYPE_ocsp);
#endif
+#if defined(OPENSSL_IS_BORINGSSL) && defined(ALLOW_RENEG)
+ SSL_set_renegotiate_mode(BACKEND->handle, ssl_renegotiate_freely);
+#endif
+
SSL_set_connect_state(BACKEND->handle);
BACKEND->server_cert = 0x0;
@@ -2627,6 +2726,15 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
/* Check if there's a cached ID we can/should use here! */
if(SSL_SET_OPTION(primary.sessionid)) {
void *ssl_sessionid = NULL;
+ int connectdata_idx = ossl_get_ssl_conn_index();
+ int sockindex_idx = ossl_get_ssl_sockindex_index();
+
+ if(connectdata_idx >= 0 && sockindex_idx >= 0) {
+ /* Store the data needed for the "new session" callback.
+ * The sockindex is stored as a pointer to an array element. */
+ SSL_set_ex_data(BACKEND->handle, connectdata_idx, conn);
+ SSL_set_ex_data(BACKEND->handle, sockindex_idx, conn->sock + sockindex);
+ }
Curl_ssl_sessionid_lock(conn);
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
@@ -2721,14 +2829,14 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
if((lib == ERR_LIB_SSL) &&
(reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
- result = CURLE_SSL_CACERT;
+ result = CURLE_PEER_FAILED_VERIFICATION;
lerr = SSL_get_verify_result(BACKEND->handle);
if(lerr != X509_V_OK) {
*certverifyresult = lerr;
- snprintf(error_buffer, sizeof(error_buffer),
- "SSL certificate problem: %s",
- X509_verify_cert_error_string(lerr));
+ msnprintf(error_buffer, sizeof(error_buffer),
+ "SSL certificate problem: %s",
+ X509_verify_cert_error_string(lerr));
}
else
/* strcpy() is fine here as long as the string fits within
@@ -2839,7 +2947,7 @@ static void pubkey_show(struct Curl_easy *data,
char *ptr;
char namebuf[32];
- snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
+ msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
if(bn)
BN_print(mem, bn);
@@ -2900,8 +3008,8 @@ static int X509V3_ext(struct Curl_easy *data,
while((j<(size_t)biomem->length) && (biomem->data[j] == ' '))
j++;
if(j<(size_t)biomem->length)
- ptr += snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
- biomem->data[j]);
+ ptr += msnprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
+ biomem->data[j]);
}
Curl_ssl_push_certinfo(data, certnum, namebuf, buf);
@@ -3214,20 +3322,8 @@ static CURLcode servercert(struct connectdata *conn,
/* we've been asked to gather certificate info! */
(void)get_cert_chain(conn, connssl);
- fp = BIO_new(BIO_s_file());
- if(fp == NULL) {
- failf(data,
- "BIO_new return NULL, " OSSL_PACKAGE
- " error %s",
- ossl_strerror(ERR_get_error(), error_buffer,
- sizeof(error_buffer)) );
- BIO_free(mem);
- return CURLE_OUT_OF_MEMORY;
- }
-
BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle);
if(!BACKEND->server_cert) {
- BIO_free(fp);
BIO_free(mem);
if(!strict)
return CURLE_OK;
@@ -3262,7 +3358,6 @@ static CURLcode servercert(struct connectdata *conn,
if(SSL_CONN_CONFIG(verifyhost)) {
result = verifyhost(conn, BACKEND->server_cert);
if(result) {
- BIO_free(fp);
X509_free(BACKEND->server_cert);
BACKEND->server_cert = NULL;
return result;
@@ -3284,6 +3379,18 @@ static CURLcode servercert(struct connectdata *conn,
/* e.g. match issuer name with provided issuer certificate */
if(SSL_SET_OPTION(issuercert)) {
+ fp = BIO_new(BIO_s_file());
+ if(fp == NULL) {
+ failf(data,
+ "BIO_new return NULL, " OSSL_PACKAGE
+ " error %s",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)) );
+ X509_free(BACKEND->server_cert);
+ BACKEND->server_cert = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+
if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) {
if(strict)
failf(data, "SSL: Unable to open issuer cert (%s)",
@@ -3319,6 +3426,7 @@ static CURLcode servercert(struct connectdata *conn,
infof(data, " SSL certificate issuer check ok (%s)\n",
SSL_SET_OPTION(issuercert));
+ BIO_free(fp);
X509_free(issuer);
}
@@ -3347,7 +3455,6 @@ static CURLcode servercert(struct connectdata *conn,
if(SSL_CONN_CONFIG(verifystatus)) {
result = verifystatus(conn, connssl);
if(result) {
- BIO_free(fp);
X509_free(BACKEND->server_cert);
BACKEND->server_cert = NULL;
return result;
@@ -3367,7 +3474,6 @@ static CURLcode servercert(struct connectdata *conn,
failf(data, "SSL: public key does not match pinned public key!");
}
- BIO_free(fp);
X509_free(BACKEND->server_cert);
BACKEND->server_cert = NULL;
connssl->connecting_state = ssl_connect_done;
@@ -3378,52 +3484,10 @@ static CURLcode servercert(struct connectdata *conn,
static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
- if(SSL_SET_OPTION(primary.sessionid)) {
- bool incache;
- SSL_SESSION *our_ssl_sessionid;
- void *old_ssl_sessionid = NULL;
-
- our_ssl_sessionid = SSL_get1_session(BACKEND->handle);
-
- /* SSL_get1_session() will increment the reference count and the session
- will stay in memory until explicitly freed with SSL_SESSION_free(3),
- regardless of its state. */
-
- Curl_ssl_sessionid_lock(conn);
- incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
- sockindex));
- if(incache) {
- if(old_ssl_sessionid != our_ssl_sessionid) {
- infof(data, "old SSL session ID is stale, removing\n");
- Curl_ssl_delsessionid(conn, old_ssl_sessionid);
- incache = FALSE;
- }
- }
-
- if(!incache) {
- result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
- 0 /* unknown size */, sockindex);
- if(result) {
- Curl_ssl_sessionid_unlock(conn);
- failf(data, "failed to store ssl session");
- return result;
- }
- }
- else {
- /* Session was incache, so refcount already incremented earlier.
- * Avoid further increments with each SSL_get1_session() call.
- * This does not free the session as refcount remains > 0
- */
- SSL_SESSION_free(our_ssl_sessionid);
- }
- Curl_ssl_sessionid_unlock(conn);
- }
-
/*
* We check certificates to authenticate the server; otherwise we risk
* man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to
@@ -3709,7 +3773,7 @@ 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
- return snprintf(buffer, size, OSSL_PACKAGE);
+ return msnprintf(buffer, size, OSSL_PACKAGE);
#else /* OPENSSL_IS_BORINGSSL */
char sub[3];
unsigned long ssleay_value;
@@ -3736,12 +3800,12 @@ static size_t Curl_ossl_version(char *buffer, size_t size)
sub[0]='\0';
}
- return snprintf(buffer, size, "%s/%lx.%lx.%lx%s",
- OSSL_PACKAGE,
- (ssleay_value>>28)&0xf,
- (ssleay_value>>20)&0xff,
- (ssleay_value>>12)&0xff,
- sub);
+ return msnprintf(buffer, size, "%s/%lx.%lx.%lx%s",
+ OSSL_PACKAGE,
+ (ssleay_value>>28)&0xf,
+ (ssleay_value>>20)&0xff,
+ (ssleay_value>>12)&0xff,
+ sub);
#endif /* OPENSSL_IS_BORINGSSL */
}
diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c
index 27af0ccf..6ecabe94 100644
--- a/lib/vtls/polarssl.c
+++ b/lib/vtls/polarssl.c
@@ -497,7 +497,7 @@ polarssl_connect_step2(struct connectdata *conn,
if(ret & BADCERT_REVOKED) {
failf(data, "Cert verify failed: BADCERT_REVOKED");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
}
if(ret & BADCERT_CN_MISMATCH)
@@ -716,9 +716,9 @@ static void Curl_polarssl_session_free(void *ptr)
static size_t Curl_polarssl_version(char *buffer, size_t size)
{
unsigned int version = version_get_number();
- return snprintf(buffer, size, "%s/%d.%d.%d",
- version >= 0x01030A00?"mbedTLS":"PolarSSL",
- version>>24, (version>>16)&0xff, (version>>8)&0xff);
+ return msnprintf(buffer, size, "%s/%d.%d.%d",
+ version >= 0x01030A00?"mbedTLS":"PolarSSL",
+ version>>24, (version>>16)&0xff, (version>>8)&0xff);
}
static CURLcode
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index e4426924..56fd93e1 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -23,9 +23,8 @@
***************************************************************************/
/*
- * Source file for all SChannel-specific code for the TLS/SSL layer. No code
+ * Source file for all Schannel-specific code for the TLS/SSL layer. No code
* but vtls.c should ever call or use these functions.
- *
*/
/*
@@ -196,7 +195,7 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn)
schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
break;
case CURL_SSLVERSION_TLSv1_3:
- failf(data, "Schannel: TLS 1.3 is not yet supported");
+ failf(data, "schannel: TLS 1.3 is not yet supported");
return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -434,7 +433,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT,
VERSION_LESS_THAN_EQUAL)) {
- /* SChannel in Windows XP (OS version 5.1) uses legacy handshakes and
+ /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
algorithms that may not be supported by all servers. */
infof(data, "schannel: WinSSL version is old and may not be able to "
"connect to some servers due to lack of SNI, algorithms, etc.\n");
@@ -1114,13 +1113,68 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
#ifdef HAS_MANUAL_VERIFY_API
if(conn->ssl_config.verifypeer && BACKEND->use_manual_cred_validation) {
- return verify_certificate(conn, sockindex);
+ return Curl_verify_certificate(conn, sockindex);
}
#endif
return CURLE_OK;
}
+static bool
+valid_cert_encoding(const CERT_CONTEXT *cert_context)
+{
+ return (cert_context != NULL) &&
+ ((cert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
+ (cert_context->pbCertEncoded != NULL) &&
+ (cert_context->cbCertEncoded > 0);
+}
+
+typedef bool(*Read_crt_func)(const CERT_CONTEXT *ccert_context, void *arg);
+
+static void
+traverse_cert_store(const CERT_CONTEXT *context, Read_crt_func func,
+ void *arg)
+{
+ const CERT_CONTEXT *current_context = NULL;
+ bool should_continue = true;
+ while(should_continue &&
+ (current_context = CertEnumCertificatesInStore(
+ context->hCertStore,
+ current_context)) != NULL)
+ should_continue = func(current_context, arg);
+
+ if(current_context)
+ CertFreeCertificateContext(current_context);
+}
+
+static bool
+cert_counter_callback(const CERT_CONTEXT *ccert_context, void *certs_count)
+{
+ if(valid_cert_encoding(ccert_context))
+ (*(int *)certs_count)++;
+ return true;
+}
+
+struct Adder_args
+{
+ struct connectdata *conn;
+ CURLcode result;
+ int idx;
+};
+
+static bool
+add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, void *raw_arg)
+{
+ struct Adder_args *args = (struct Adder_args*)raw_arg;
+ args->result = CURLE_OK;
+ if(valid_cert_encoding(ccert_context)) {
+ const char *beg = (const char *) ccert_context->pbCertEncoded;
+ const char *end = beg + ccert_context->cbCertEncoded;
+ args->result = Curl_extract_certinfo(args->conn, (args->idx)++, beg, end);
+ }
+ return args->result == CURLE_OK;
+}
+
static CURLcode
schannel_connect_step3(struct connectdata *conn, int sockindex)
{
@@ -1230,6 +1284,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
}
if(data->set.ssl.certinfo) {
+ int certs_count = 0;
sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context);
@@ -1238,15 +1293,15 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
return CURLE_PEER_FAILED_VERIFICATION;
}
- result = Curl_ssl_init_certinfo(data, 1);
- if(!result) {
- if(((ccert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
- (ccert_context->cbCertEncoded > 0)) {
+ traverse_cert_store(ccert_context, cert_counter_callback, &certs_count);
- const char *beg = (const char *) ccert_context->pbCertEncoded;
- const char *end = beg + ccert_context->cbCertEncoded;
- result = Curl_extract_certinfo(conn, 0, beg, end);
- }
+ result = Curl_ssl_init_certinfo(data, certs_count);
+ if(!result) {
+ struct Adder_args args;
+ args.conn = conn;
+ args.idx = 0;
+ traverse_cert_store(ccert_context, add_cert_to_certinfo, &args);
+ result = args.result;
}
CertFreeCertificateContext(ccert_context);
if(result)
@@ -1994,7 +2049,7 @@ static void Curl_schannel_cleanup(void)
static size_t Curl_schannel_version(char *buffer, size_t size)
{
- size = snprintf(buffer, size, "WinSSL");
+ size = msnprintf(buffer, size, "WinSSL");
return size;
}
diff --git a/lib/vtls/schannel.h b/lib/vtls/schannel.h
index e491bd43..ee8d7d47 100644
--- a/lib/vtls/schannel.h
+++ b/lib/vtls/schannel.h
@@ -8,7 +8,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al.
- * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -53,7 +53,7 @@
extern const struct Curl_ssl Curl_ssl_schannel;
-CURLcode verify_certificate(struct connectdata *conn, int sockindex);
+CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex);
/* structs to expose only in schannel.c and schannel_verify.c */
#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c
index 2516f566..8b21624b 100644
--- a/lib/vtls/schannel_verify.c
+++ b/lib/vtls/schannel_verify.c
@@ -23,7 +23,7 @@
***************************************************************************/
/*
- * Source file for SChannel-specific certificate verification. This code should
+ * Source file for Schannel-specific certificate verification. This code should
* only be invoked by code in schannel.c.
*/
@@ -406,7 +406,7 @@ cleanup:
return result;
}
-CURLcode verify_certificate(struct connectdata *conn, int sockindex)
+CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
{
SECURITY_STATUS status;
struct Curl_easy *data = conn->data;
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 6af39fea..5e75f92e 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -700,7 +700,7 @@ CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
/* sprintf the label and colon */
- snprintf(output, outlen, "%s:", label);
+ msnprintf(output, outlen, "%s:", label);
/* memcpy the value (it might not be zero terminated) */
memcpy(&output[labellen + 1], value, valuelen);
@@ -1170,8 +1170,6 @@ static const struct Curl_ssl Curl_ssl_multi = {
const struct Curl_ssl *Curl_ssl =
#if defined(CURL_WITH_MULTI_SSL)
&Curl_ssl_multi;
-#elif defined(USE_AXTLS)
- &Curl_ssl_axtls;
#elif defined(USE_CYASSL)
&Curl_ssl_cyassl;
#elif defined(USE_DARWINSSL)
@@ -1197,9 +1195,6 @@ const struct Curl_ssl *Curl_ssl =
#endif
static const struct Curl_ssl *available_backends[] = {
-#if defined(USE_AXTLS)
- &Curl_ssl_axtls,
-#endif
#if defined(USE_CYASSL)
&Curl_ssl_cyassl,
#endif
@@ -1318,7 +1313,14 @@ CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
*avail = (const curl_ssl_backend **)&available_backends;
if(Curl_ssl != &Curl_ssl_multi)
- return id == Curl_ssl->info.id ? CURLSSLSET_OK : CURLSSLSET_TOO_LATE;
+ return id == Curl_ssl->info.id ||
+ (name && strcasecompare(name, Curl_ssl->info.name)) ?
+ CURLSSLSET_OK :
+#if defined(CURL_WITH_MULTI_SSL)
+ CURLSSLSET_TOO_LATE;
+#else
+ CURLSSLSET_UNKNOWN_BACKEND;
+#endif
for(i = 0; available_backends[i]; i++) {
if(available_backends[i]->info.id == id ||
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index 5cd11602..1f163631 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -103,7 +103,6 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
#include "nssg.h" /* NSS versions */
#include "gskit.h" /* Global Secure ToolKit versions */
#include "polarssl.h" /* PolarSSL versions */
-#include "axtls.h" /* axTLS versions */
#include "cyassl.h" /* CyaSSL versions */
#include "schannel.h" /* Schannel SSPI version */
#include "darwinssl.h" /* SecureTransport (Darwin) version */
diff --git a/lib/x509asn1.c b/lib/x509asn1.c
index a576fc70..746e1e8e 100644
--- a/lib/x509asn1.c
+++ b/lib/x509asn1.c
@@ -209,7 +209,7 @@ static const char *octet2str(const char *beg, const char *end)
buf = malloc(3 * n + 1);
if(buf)
for(n = 0; beg < end; n += 3)
- snprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++);
+ msnprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++);
}
return buf;
}