summaryrefslogtreecommitdiff
path: root/Utilities/cmcurl/lib
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-10-22 08:41:50 -0400
committerBrad King <brad.king@kitware.com>2018-10-22 08:48:58 -0400
commite9e8dcee6b21bafdb9593633dc845400bc060983 (patch)
treeadb81a4a209d0d2f02cf1106d5b63dbb9306de24 /Utilities/cmcurl/lib
parentded211ae469530a08774094e1162247117f85ffd (diff)
parent18812a9c3d395b368d8f3d85394b346472c8e858 (diff)
downloadcmake-e9e8dcee6b21bafdb9593633dc845400bc060983.tar.gz
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2018-09-04 (432eb5f5)
Diffstat (limited to 'Utilities/cmcurl/lib')
-rw-r--r--Utilities/cmcurl/lib/CMakeLists.txt34
-rw-r--r--Utilities/cmcurl/lib/Makefile.inc4
-rw-r--r--Utilities/cmcurl/lib/asyn-ares.c37
-rw-r--r--Utilities/cmcurl/lib/asyn-thread.c14
-rw-r--r--Utilities/cmcurl/lib/base64.c3
-rw-r--r--Utilities/cmcurl/lib/conncache.c62
-rw-r--r--Utilities/cmcurl/lib/conncache.h4
-rw-r--r--Utilities/cmcurl/lib/connect.c12
-rw-r--r--Utilities/cmcurl/lib/content_encoding.c40
-rw-r--r--Utilities/cmcurl/lib/cookie.c130
-rw-r--r--Utilities/cmcurl/lib/cookie.h4
-rw-r--r--Utilities/cmcurl/lib/curl_addrinfo.c3
-rw-r--r--Utilities/cmcurl/lib/curl_config.h.cmake6
-rw-r--r--Utilities/cmcurl/lib/curl_fnmatch.c43
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_core.c5
-rw-r--r--Utilities/cmcurl/lib/curl_sasl.c3
-rw-r--r--Utilities/cmcurl/lib/curl_setup.h15
-rw-r--r--Utilities/cmcurl/lib/curl_threads.c3
-rw-r--r--Utilities/cmcurl/lib/dict.c10
-rw-r--r--Utilities/cmcurl/lib/easy.c34
-rw-r--r--Utilities/cmcurl/lib/escape.c6
-rw-r--r--Utilities/cmcurl/lib/file.c12
-rw-r--r--Utilities/cmcurl/lib/formdata.c16
-rw-r--r--Utilities/cmcurl/lib/ftp.c16
-rw-r--r--Utilities/cmcurl/lib/getinfo.c22
-rw-r--r--Utilities/cmcurl/lib/gopher.c11
-rw-r--r--Utilities/cmcurl/lib/hash.c11
-rw-r--r--Utilities/cmcurl/lib/hmac.c4
-rw-r--r--Utilities/cmcurl/lib/hostasyn.c4
-rw-r--r--Utilities/cmcurl/lib/hostip.c38
-rw-r--r--Utilities/cmcurl/lib/hostip6.c35
-rw-r--r--Utilities/cmcurl/lib/http.c226
-rw-r--r--Utilities/cmcurl/lib/http2.c211
-rw-r--r--Utilities/cmcurl/lib/http2.h4
-rw-r--r--Utilities/cmcurl/lib/http_ntlm.c2
-rw-r--r--Utilities/cmcurl/lib/http_proxy.c7
-rw-r--r--Utilities/cmcurl/lib/imap.c16
-rw-r--r--Utilities/cmcurl/lib/inet_ntop.c2
-rw-r--r--Utilities/cmcurl/lib/ldap.c9
-rw-r--r--Utilities/cmcurl/lib/md5.c40
-rw-r--r--Utilities/cmcurl/lib/memdebug.h9
-rw-r--r--Utilities/cmcurl/lib/mime.c53
-rw-r--r--Utilities/cmcurl/lib/multi.c207
-rw-r--r--Utilities/cmcurl/lib/multihandle.h8
-rw-r--r--Utilities/cmcurl/lib/netrc.c4
-rw-r--r--Utilities/cmcurl/lib/pingpong.c10
-rw-r--r--Utilities/cmcurl/lib/pipeline.c9
-rw-r--r--Utilities/cmcurl/lib/pop3.c4
-rw-r--r--Utilities/cmcurl/lib/progress.c39
-rw-r--r--Utilities/cmcurl/lib/progress.h13
-rw-r--r--Utilities/cmcurl/lib/psl.c111
-rw-r--r--Utilities/cmcurl/lib/psl.h47
-rw-r--r--Utilities/cmcurl/lib/rand.c2
-rw-r--r--Utilities/cmcurl/lib/rtsp.c6
-rw-r--r--Utilities/cmcurl/lib/security.c4
-rw-r--r--Utilities/cmcurl/lib/select.c8
-rw-r--r--Utilities/cmcurl/lib/sendf.c48
-rw-r--r--Utilities/cmcurl/lib/sendf.h5
-rw-r--r--Utilities/cmcurl/lib/setopt.c43
-rw-r--r--Utilities/cmcurl/lib/sha256.c19
-rw-r--r--Utilities/cmcurl/lib/share.c11
-rw-r--r--Utilities/cmcurl/lib/share.h6
-rw-r--r--Utilities/cmcurl/lib/smb.c105
-rw-r--r--Utilities/cmcurl/lib/smb.h1
-rw-r--r--Utilities/cmcurl/lib/smtp.c5
-rw-r--r--Utilities/cmcurl/lib/socks.c14
-rw-r--r--Utilities/cmcurl/lib/splay.c3
-rw-r--r--Utilities/cmcurl/lib/ssh-libssh.c64
-rw-r--r--Utilities/cmcurl/lib/ssh.c45
-rw-r--r--Utilities/cmcurl/lib/ssh.h4
-rw-r--r--Utilities/cmcurl/lib/strcase.h1
-rw-r--r--Utilities/cmcurl/lib/system_win32.c15
-rw-r--r--Utilities/cmcurl/lib/telnet.c59
-rw-r--r--Utilities/cmcurl/lib/tftp.c27
-rw-r--r--Utilities/cmcurl/lib/transfer.c86
-rw-r--r--Utilities/cmcurl/lib/transfer.h4
-rw-r--r--Utilities/cmcurl/lib/url.c219
-rw-r--r--Utilities/cmcurl/lib/url.h3
-rw-r--r--Utilities/cmcurl/lib/urldata.h49
-rw-r--r--Utilities/cmcurl/lib/vauth/digest.c6
-rw-r--r--Utilities/cmcurl/lib/version.c2
-rw-r--r--Utilities/cmcurl/lib/vtls/axtls.c5
-rw-r--r--Utilities/cmcurl/lib/vtls/cyassl.c4
-rw-r--r--Utilities/cmcurl/lib/vtls/darwinssl.c79
-rw-r--r--Utilities/cmcurl/lib/vtls/gskit.c32
-rw-r--r--Utilities/cmcurl/lib/vtls/nss.c11
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.c126
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel.c205
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel.h34
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel_verify.c18
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls.c13
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls.h5
-rw-r--r--Utilities/cmcurl/lib/warnless.h3
-rw-r--r--Utilities/cmcurl/lib/x509asn1.c130
94 files changed, 1967 insertions, 1234 deletions
diff --git a/Utilities/cmcurl/lib/CMakeLists.txt b/Utilities/cmcurl/lib/CMakeLists.txt
index 9f19daa790..3d52105c6e 100644
--- a/Utilities/cmcurl/lib/CMakeLists.txt
+++ b/Utilities/cmcurl/lib/CMakeLists.txt
@@ -1,5 +1,13 @@
set(LIB_NAME cmcurl)
+if(BUILD_SHARED_LIBS)
+ set(CURL_STATICLIB NO)
+else()
+ set(CURL_STATICLIB YES)
+endif()
+
+# Use:
+# * CURL_STATICLIB
configure_file(curl_config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
@@ -59,14 +67,6 @@ if(USE_ARES)
include_directories(${CARES_INCLUDE_DIR})
endif()
-if(CURL_STATICLIB)
- # Static lib
- set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC STATIC)
-else()
- # DLL / so dynamic lib
- set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC SHARED)
-endif()
-
# For windows we want to install OPENSSL_LIBRARIES dlls
# and also copy them into the build tree so that testing
# can find them.
@@ -93,16 +93,19 @@ endif()
add_library(
${LIB_NAME}
- ${CURL_USER_DEFINED_DYNAMIC_OR_STATIC}
${HHEADERS} ${CSOURCES}
${CMAKE_CURL_SSL_DLLS}
)
+if(NOT BUILD_SHARED_LIBS)
+ set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
+endif()
+
target_link_libraries(${LIB_NAME} ${CURL_LIBS})
if(0) # This code not needed for building within CMake.
if(WIN32)
- add_definitions( -D_USRDLL )
+ add_definitions(-D_USRDLL)
endif()
endif()
@@ -119,21 +122,14 @@ set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
if(WIN32)
- if(NOT CURL_STATICLIB)
+ if(BUILD_SHARED_LIBS)
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
-
- set_target_properties (${LIB_NAME} PROPERTIES
- DEBUG_POSTFIX "-d"
- # Note: no postfix for release variants, let user choose what style of release he wants
- # MINSIZEREL_POSTFIX "-z"
- # RELWITHDEBINFO_POSTFIX "-g"
- )
endif()
endif()
target_include_directories(${LIB_NAME} INTERFACE
- $<INSTALL_INTERFACE:include>)
+ $<INSTALL_INTERFACE:include>)
install(TARGETS ${LIB_NAME}
EXPORT libcurl-target
diff --git a/Utilities/cmcurl/lib/Makefile.inc b/Utilities/cmcurl/lib/Makefile.inc
index 61c23411df..76ca6d0414 100644
--- a/Utilities/cmcurl/lib/Makefile.inc
+++ b/Utilities/cmcurl/lib/Makefile.inc
@@ -54,7 +54,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \
curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
- mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c
+ mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
@@ -74,7 +74,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \
- curl_path.h curl_ctype.h curl_range.h
+ curl_path.h curl_ctype.h curl_range.h psl.h
LIB_RCFILES = libcurl.rc
diff --git a/Utilities/cmcurl/lib/asyn-ares.c b/Utilities/cmcurl/lib/asyn-ares.c
index aa581a49a0..5cfb2602df 100644
--- a/Utilities/cmcurl/lib/asyn-ares.c
+++ b/Utilities/cmcurl/lib/asyn-ares.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
@@ -312,22 +312,25 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
conn->async.os_specific;
CURLcode result = CURLE_OK;
- *dns = NULL;
+ if(dns)
+ *dns = NULL;
waitperform(conn, 0);
if(res && !res->num_pending) {
- (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
- /* temp_ai ownership is moved to the connection, so we need not free-up
- them */
- res->temp_ai = NULL;
+ if(dns) {
+ (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
+ /* temp_ai ownership is moved to the connection, so we need not free-up
+ them */
+ res->temp_ai = NULL;
+ }
if(!conn->async.dns) {
failf(data, "Could not resolve: %s (%s)",
conn->async.hostname, ares_strerror(conn->async.status));
result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
CURLE_COULDNT_RESOLVE_HOST;
}
- else
+ else if(dns)
*dns = conn->async.dns;
destroy_async_data(&conn->async);
@@ -390,7 +393,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
timeout_ms = 1000;
waitperform(conn, timeout_ms);
- result = Curl_resolver_is_resolved(conn, &temp_entry);
+ result = Curl_resolver_is_resolved(conn, entry?&temp_entry:NULL);
if(result || conn->async.done)
break;
@@ -472,17 +475,19 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
return;
res = (struct ResolverResults *)conn->async.os_specific;
- res->num_pending--;
+ if(res) {
+ res->num_pending--;
- if(CURL_ASYNC_SUCCESS == status) {
- Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
- if(ai) {
- compound_results(res, ai);
+ if(CURL_ASYNC_SUCCESS == status) {
+ Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
+ if(ai) {
+ compound_results(res, ai);
+ }
}
+ /* A successful result overwrites any previous error */
+ if(res->last_status != ARES_SUCCESS)
+ res->last_status = status;
}
- /* A successful result overwrites any previous error */
- if(res->last_status != ARES_SUCCESS)
- res->last_status = status;
}
/*
diff --git a/Utilities/cmcurl/lib/asyn-thread.c b/Utilities/cmcurl/lib/asyn-thread.c
index b11fab2468..2a59294e5c 100644
--- a/Utilities/cmcurl/lib/asyn-thread.c
+++ b/Utilities/cmcurl/lib/asyn-thread.c
@@ -182,8 +182,6 @@ static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
return &(((struct thread_data *)conn->async.os_specific)->tsd);
}
-#define CONN_THREAD_SYNC_DATA(conn) &(((conn)->async.os_specific)->tsd);
-
/* Destroy resolver thread synchronization data */
static
void destroy_thread_sync_data(struct thread_sync_data * tsd)
@@ -481,8 +479,10 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
DEBUGASSERT(conn && td);
/* wait for the thread to resolve the name */
- if(Curl_thread_join(&td->thread_hnd))
- result = getaddrinfo_complete(conn);
+ if(Curl_thread_join(&td->thread_hnd)) {
+ if(entry)
+ result = getaddrinfo_complete(conn);
+ }
else
DEBUGASSERT(0);
@@ -572,10 +572,10 @@ int Curl_resolver_getsock(struct connectdata *conn,
(void)socks;
(void)numsocks;
ms = Curl_timediff(Curl_now(), reslv->start);
- if(ms < 10)
- milli = ms/3;
+ if(ms < 3)
+ milli = 0;
else if(ms <= 50)
- milli = 10;
+ milli = ms/3;
else if(ms <= 250)
milli = 50;
else
diff --git a/Utilities/cmcurl/lib/base64.c b/Utilities/cmcurl/lib/base64.c
index 204a2273d1..6370e4cdfb 100644
--- a/Utilities/cmcurl/lib/base64.c
+++ b/Utilities/cmcurl/lib/base64.c
@@ -49,13 +49,12 @@ static size_t decodeQuantum(unsigned char *dest, const char *src)
unsigned long i, x = 0;
for(i = 0, s = src; i < 4; i++, s++) {
- unsigned long v = 0;
-
if(*s == '=') {
x = (x << 6);
padding++;
}
else {
+ unsigned long v = 0;
p = base64;
while(*p && (*p != *s)) {
diff --git a/Utilities/cmcurl/lib/conncache.c b/Utilities/cmcurl/lib/conncache.c
index b8f5444856..6fbf3b1d27 100644
--- a/Utilities/cmcurl/lib/conncache.c
+++ b/Utilities/cmcurl/lib/conncache.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
- * 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
@@ -63,10 +63,9 @@
static void conn_llist_dtor(void *user, void *element)
{
- struct connectdata *data = element;
+ struct connectdata *conn = element;
(void)user;
-
- data->bundle = NULL;
+ conn->bundle = NULL;
}
static CURLcode bundle_create(struct Curl_easy *data,
@@ -96,14 +95,13 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
}
/* Add a connection to a bundle */
-static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
- struct connectdata *conn)
+static void bundle_add_conn(struct connectbundle *cb_ptr,
+ struct connectdata *conn)
{
Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
&conn->bundle_node);
conn->bundle = cb_ptr;
cb_ptr->num_connections++;
- return CURLE_OK;
}
/* Remove a connection from a bundle */
@@ -263,7 +261,7 @@ static void conncache_remove_bundle(struct conncache *connc,
CURLcode Curl_conncache_add_conn(struct conncache *connc,
struct connectdata *conn)
{
- CURLcode result;
+ CURLcode result = CURLE_OK;
struct connectbundle *bundle;
struct connectbundle *new_bundle = NULL;
struct Curl_easy *data = conn->data;
@@ -290,19 +288,13 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
bundle = new_bundle;
}
- result = bundle_add_conn(bundle, conn);
- if(result) {
- if(new_bundle)
- conncache_remove_bundle(data->state.conn_cache, new_bundle);
- goto unlock;
- }
-
+ bundle_add_conn(bundle, conn);
conn->connection_id = connc->next_connection_id++;
connc->num_conn++;
DEBUGF(infof(conn->data, "Added connection %ld. "
- "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n",
- conn->connection_id, (curl_off_t) connc->num_conn));
+ "The cache now contains %zu members\n",
+ conn->connection_id, connc->num_conn));
unlock:
CONN_UNLOCK(data);
@@ -320,7 +312,7 @@ void Curl_conncache_remove_conn(struct connectdata *conn, bool lock)
due to a failed connection attempt, before being added to a bundle */
if(bundle) {
if(lock) {
- CONN_LOCK(conn->data);
+ CONN_LOCK(data);
}
bundle_remove_conn(bundle, conn);
if(bundle->num_connections == 0)
@@ -328,12 +320,11 @@ void Curl_conncache_remove_conn(struct connectdata *conn, bool lock)
conn->bundle = NULL; /* removed from it */
if(connc) {
connc->num_conn--;
- DEBUGF(infof(conn->data, "The cache now contains %"
- CURL_FORMAT_CURL_OFF_TU " members\n",
- (curl_off_t) connc->num_conn));
+ DEBUGF(infof(data, "The cache now contains %zu members\n",
+ connc->num_conn));
}
if(lock) {
- CONN_UNLOCK(conn->data);
+ CONN_UNLOCK(data);
}
}
}
@@ -441,18 +432,11 @@ bool Curl_conncache_return_conn(struct connectdata *conn)
infof(data, "Connection cache is full, closing the oldest one.\n");
conn_candidate = Curl_conncache_extract_oldest(data);
-
if(conn_candidate) {
- /* Set the connection's owner correctly */
- conn_candidate->data = data;
-
/* the winner gets the honour of being disconnected */
- (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+ (void)Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE);
}
}
- CONN_LOCK(data);
- conn->inuse = FALSE; /* Mark the connection unused */
- CONN_UNLOCK(data);
return (conn_candidate == conn) ? FALSE : TRUE;
@@ -486,7 +470,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
while(curr) {
conn = curr->ptr;
- if(!conn->inuse) {
+ if(!CONN_INUSE(conn)) {
/* Set higher score for the age passed since the connection was used */
score = Curl_timediff(now, conn->now);
@@ -501,9 +485,9 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
/* remove it to prevent another thread from nicking it */
bundle_remove_conn(bundle, conn_candidate);
data->state.conn_cache->num_conn--;
- DEBUGF(infof(data, "The cache now contains %"
- CURL_FORMAT_CURL_OFF_TU " members\n",
- (curl_off_t) data->state.conn_cache->num_conn));
+ DEBUGF(infof(data, "The cache now contains %zu members\n",
+ data->state.conn_cache->num_conn));
+ conn_candidate->data = data; /* associate! */
}
return conn_candidate;
@@ -544,7 +528,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
while(curr) {
conn = curr->ptr;
- if(!conn->inuse) {
+ if(!CONN_INUSE(conn)) {
/* Set higher score for the age passed since the connection was used */
score = Curl_timediff(now, conn->now);
@@ -563,9 +547,9 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
/* remove it to prevent another thread from nicking it */
bundle_remove_conn(bundle_candidate, conn_candidate);
connc->num_conn--;
- DEBUGF(infof(data, "The cache now contains %"
- CURL_FORMAT_CURL_OFF_TU " members\n",
- (curl_off_t) connc->num_conn));
+ DEBUGF(infof(data, "The cache now contains %zu members\n",
+ connc->num_conn));
+ conn_candidate->data = data; /* associate! */
}
CONN_UNLOCK(data);
@@ -586,7 +570,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
pointer */
/* This will remove the connection from the cache */
connclose(conn, "kill all");
- (void)Curl_disconnect(conn, FALSE);
+ (void)Curl_disconnect(connc->closure_handle, conn, FALSE);
sigpipe_restore(&pipe_st);
conn = Curl_conncache_find_first_connection(connc);
diff --git a/Utilities/cmcurl/lib/conncache.h b/Utilities/cmcurl/lib/conncache.h
index d8ad80f963..eedd7a800e 100644
--- a/Utilities/cmcurl/lib/conncache.h
+++ b/Utilities/cmcurl/lib/conncache.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
@@ -63,7 +63,7 @@ size_t Curl_conncache_bundle_size(struct connectdata *conn);
bool Curl_conncache_return_conn(struct connectdata *conn);
CURLcode Curl_conncache_add_conn(struct conncache *connc,
- struct connectdata *conn);
+ struct connectdata *conn) WARN_UNUSED_RESULT;
void Curl_conncache_remove_conn(struct connectdata *conn,
bool lock);
bool Curl_conncache_foreach(struct Curl_easy *data,
diff --git a/Utilities/cmcurl/lib/connect.c b/Utilities/cmcurl/lib/connect.c
index 1a27ae1353..41f2202681 100644
--- a/Utilities/cmcurl/lib/connect.c
+++ b/Utilities/cmcurl/lib/connect.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
@@ -1237,8 +1237,6 @@ static int conn_is_conn(struct connectdata *conn, void *param)
curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
struct connectdata **connp)
{
- curl_socket_t sockfd;
-
DEBUGASSERT(data);
/* this works for an easy handle:
@@ -1261,15 +1259,15 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
return CURL_SOCKET_BAD;
}
- if(connp)
+ if(connp) {
/* only store this if the caller cares for it */
*connp = c;
- sockfd = c->sock[FIRSTSOCKET];
+ c->data = data;
+ }
+ return c->sock[FIRSTSOCKET];
}
else
return CURL_SOCKET_BAD;
-
- return sockfd;
}
/*
diff --git a/Utilities/cmcurl/lib/content_encoding.c b/Utilities/cmcurl/lib/content_encoding.c
index 7c979efcc3..6d47537883 100644
--- a/Utilities/cmcurl/lib/content_encoding.c
+++ b/Utilities/cmcurl/lib/content_encoding.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
@@ -71,13 +71,13 @@
#define RESERVED 0xE0 /* bits 5..7: reserved */
typedef enum {
- ZLIB_UNINIT, /* uninitialized */
- ZLIB_INIT, /* initialized */
- ZLIB_INFLATING, /* Inflating started. */
- ZLIB_GZIP_HEADER, /* reading gzip header */
- ZLIB_GZIP_TRAILER, /* reading gzip trailer */
- ZLIB_GZIP_INFLATING, /* inflating gzip stream */
- ZLIB_INIT_GZIP /* initialized in transparent gzip mode */
+ ZLIB_UNINIT, /* uninitialized */
+ ZLIB_INIT, /* initialized */
+ ZLIB_INFLATING, /* inflating started. */
+ ZLIB_EXTERNAL_TRAILER, /* reading external trailer */
+ ZLIB_GZIP_HEADER, /* reading gzip header */
+ ZLIB_GZIP_INFLATING, /* inflating gzip stream */
+ ZLIB_INIT_GZIP /* initialized in transparent gzip mode */
} zlibInitState;
/* Writer parameters. */
@@ -150,8 +150,8 @@ static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp)
if(result || !zp->trailerlen)
result = exit_zlib(conn, z, &zp->zlib_init, result);
else {
- /* Only occurs for gzip with zlib < 1.2.0.4. */
- zp->zlib_init = ZLIB_GZIP_TRAILER;
+ /* Only occurs for gzip with zlib < 1.2.0.4 or raw deflate. */
+ zp->zlib_init = ZLIB_EXTERNAL_TRAILER;
}
return result;
}
@@ -163,7 +163,6 @@ static CURLcode inflate_stream(struct connectdata *conn,
z_stream *z = &zp->z; /* zlib state structure */
uInt nread = z->avail_in;
Bytef *orig_in = z->next_in;
- int status; /* zlib status */
bool done = FALSE;
CURLcode result = CURLE_OK; /* Curl_client_write status */
char *decomp; /* Put the decompressed data here. */
@@ -184,13 +183,20 @@ static CURLcode inflate_stream(struct connectdata *conn,
/* because the buffer size is fixed, iteratively decompress and transfer to
the client via downstream_write function. */
while(!done) {
+ int status; /* zlib status */
done = TRUE;
/* (re)set buffer for decompressed output for every iteration */
z->next_out = (Bytef *) decomp;
z->avail_out = DSIZ;
+#ifdef Z_BLOCK
+ /* Z_BLOCK is only available in zlib ver. >= 1.2.0.5 */
status = inflate(z, Z_BLOCK);
+#else
+ /* fallback for zlib ver. < 1.2.0.5 */
+ status = inflate(z, Z_SYNC_FLUSH);
+#endif
/* Flush output data if some. */
if(z->avail_out != DSIZ) {
@@ -227,6 +233,7 @@ static CURLcode inflate_stream(struct connectdata *conn,
z->next_in = orig_in;
z->avail_in = nread;
zp->zlib_init = ZLIB_INFLATING;
+ zp->trailerlen = 4; /* Tolerate up to 4 unknown trailer bytes. */
done = FALSE;
break;
}
@@ -281,6 +288,9 @@ static CURLcode deflate_unencode_write(struct connectdata *conn,
z->next_in = (Bytef *) buf;
z->avail_in = (uInt) nbytes;
+ if(zp->zlib_init == ZLIB_EXTERNAL_TRAILER)
+ return process_trailer(conn, zp);
+
/* Now uncompress the data */
return inflate_stream(conn, writer, ZLIB_INFLATING);
}
@@ -526,7 +536,7 @@ static CURLcode gzip_unencode_write(struct connectdata *conn,
}
break;
- case ZLIB_GZIP_TRAILER:
+ case ZLIB_EXTERNAL_TRAILER:
z->next_in = (Bytef *) buf;
z->avail_in = (uInt) nbytes;
return process_trailer(conn, zp);
@@ -755,7 +765,6 @@ char *Curl_all_content_encodings(void)
const content_encoding * const *cep;
const content_encoding *ce;
char *ace;
- char *p;
for(cep = encodings; *cep; cep++) {
ce = *cep;
@@ -768,7 +777,7 @@ char *Curl_all_content_encodings(void)
ace = malloc(len);
if(ace) {
- p = ace;
+ char *p = ace;
for(cep = encodings; *cep; cep++) {
ce = *cep;
if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) {
@@ -915,10 +924,9 @@ void Curl_unencode_cleanup(struct connectdata *conn)
static const content_encoding *find_encoding(const char *name, size_t len)
{
const content_encoding * const *cep;
- const content_encoding *ce;
for(cep = encodings; *cep; cep++) {
- ce = *cep;
+ const content_encoding *ce = *cep;
if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
(ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
return ce;
diff --git a/Utilities/cmcurl/lib/cookie.c b/Utilities/cmcurl/lib/cookie.c
index 2c028b381e..da49c2a05c 100644
--- a/Utilities/cmcurl/lib/cookie.c
+++ b/Utilities/cmcurl/lib/cookie.c
@@ -40,7 +40,7 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data,
received from a server.
The function need to replace previously stored lines that this new
- line superceeds.
+ line supersedes.
It may remove lines that are expired.
@@ -84,12 +84,9 @@ Example set of cookies:
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
-#ifdef USE_LIBPSL
-# include <libpsl.h>
-#endif
-
#include "urldata.h"
#include "cookie.h"
+#include "psl.h"
#include "strtok.h"
#include "sendf.h"
#include "slist.h"
@@ -253,9 +250,9 @@ static const char *get_top_domain(const char * const domain, size_t *outlen)
len = strlen(domain);
last = memrchr(domain, '.', len);
if(last) {
- first = memrchr(domain, '.', (size_t) (last - domain));
+ first = memrchr(domain, '.', (last - domain));
if(first)
- len -= (size_t) (++first - domain);
+ len -= (++first - domain);
}
if(outlen)
@@ -379,13 +376,13 @@ static void strstore(char **str, const char *newstr)
*/
static void remove_expired(struct CookieInfo *cookies)
{
- struct Cookie *co, *nx, *pv;
+ struct Cookie *co, *nx;
curl_off_t now = (curl_off_t)time(NULL);
unsigned int i;
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
+ struct Cookie *pv = NULL;
co = cookies->cookies[i];
- pv = NULL;
while(co) {
nx = co->next;
if(co->expires && co->expires < now) {
@@ -406,6 +403,12 @@ static void remove_expired(struct CookieInfo *cookies)
}
}
+/* Make sure domain contains a dot or is localhost. */
+static bool bad_domain(const char *domain)
+{
+ return !strchr(domain, '.') && !strcasecompare(domain, "localhost");
+}
+
/****************************************************************************
*
* Curl_cookie_add()
@@ -442,10 +445,6 @@ Curl_cookie_add(struct Curl_easy *data,
bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
size_t myhash;
-#ifdef USE_LIBPSL
- const psl_ctx_t *psl;
-#endif
-
#ifdef CURL_DISABLE_VERBOSE_STRINGS
(void)data;
#endif
@@ -497,7 +496,7 @@ Curl_cookie_add(struct Curl_easy *data,
name + contents. Chrome and Firefox support 4095 or 4096 bytes
combo. */
freecookie(co);
- infof(data, "oversized cookie dropped, name/val %d + %d bytes\n",
+ infof(data, "oversized cookie dropped, name/val %zu + %zu bytes\n",
nlen, len);
return NULL;
}
@@ -585,13 +584,8 @@ Curl_cookie_add(struct Curl_easy *data,
* TLD or otherwise "protected" suffix. To reduce risk, we require a
* dot OR the exact host name being "localhost".
*/
- {
- const char *dotp;
- /* check for more dots */
- dotp = strchr(whatptr, '.');
- if(!dotp && !strcasecompare("localhost", whatptr))
- domain = ":";
- }
+ if(bad_domain(whatptr))
+ domain = ":";
#endif
is_ip = isip(domain ? domain : whatptr);
@@ -723,9 +717,9 @@ Curl_cookie_add(struct Curl_easy *data,
if(!queryp)
endslash = strrchr(path, '/');
else
- endslash = memrchr(path, '/', (size_t)(queryp - path));
+ endslash = memrchr(path, '/', (queryp - path));
if(endslash) {
- size_t pathlen = (size_t)(endslash-path + 1); /* include end slash */
+ size_t pathlen = (endslash-path + 1); /* include end slash */
co->path = malloc(pathlen + 1); /* one extra for the zero byte */
if(co->path) {
memcpy(co->path, path, pathlen);
@@ -880,9 +874,10 @@ Curl_cookie_add(struct Curl_easy *data,
}
co->livecookie = c->running;
+ co->creationtime = ++c->lastct;
/* now, we have parsed the incoming line, we must now check if this
- superceeds an already existing cookie, which it may if the previous have
+ supersedes an already existing cookie, which it may if the previous have
the same domain and path as this */
/* at first, remove expired cookies */
@@ -890,14 +885,21 @@ Curl_cookie_add(struct Curl_easy *data,
remove_expired(c);
#ifdef USE_LIBPSL
- /* Check if the domain is a Public Suffix and if yes, ignore the cookie.
- This needs a libpsl compiled with builtin data. */
+ /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */
if(domain && co->domain && !isip(co->domain)) {
- psl = psl_builtin();
- if(psl && !psl_is_cookie_domain_acceptable(psl, domain, co->domain)) {
- infof(data,
- "cookie '%s' dropped, domain '%s' must not set cookies for '%s'\n",
- co->name, domain, co->domain);
+ const psl_ctx_t *psl = Curl_psl_use(data);
+ int acceptable;
+
+ if(psl) {
+ acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain);
+ Curl_psl_release(data);
+ }
+ else
+ acceptable = !bad_domain(domain);
+
+ if(!acceptable) {
+ infof(data, "cookie '%s' dropped, domain '%s' must not "
+ "set cookies for '%s'\n", co->name, domain, co->domain);
freecookie(co);
return NULL;
}
@@ -951,6 +953,9 @@ Curl_cookie_add(struct Curl_easy *data,
if(replace_old) {
co->next = clist->next; /* get the next-pointer first */
+ /* when replacing, creationtime is kept from old */
+ co->creationtime = clist->creationtime;
+
/* then free all the old pointers */
free(clist->name);
free(clist->value);
@@ -1140,12 +1145,24 @@ static int cookie_sort(const void *p1, const void *p2)
if(l1 != l2)
return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */
- /* 3 - compare cookie names */
- if(c1->name && c2->name)
- return strcmp(c1->name, c2->name);
+ /* 3 - compare cookie name lengths */
+ l1 = c1->name ? strlen(c1->name) : 0;
+ l2 = c2->name ? strlen(c2->name) : 0;
- /* sorry, can't be more deterministic */
- return 0;
+ if(l1 != l2)
+ return (l2 > l1) ? 1 : -1;
+
+ /* 4 - compare cookie creation time */
+ return (c2->creationtime > c1->creationtime) ? 1 : -1;
+}
+
+/* sort cookies only according to creation time */
+static int cookie_sort_ct(const void *p1, const void *p2)
+{
+ struct Cookie *c1 = *(struct Cookie **)p1;
+ struct Cookie *c2 = *(struct Cookie **)p2;
+
+ return (c2->creationtime > c1->creationtime) ? 1 : -1;
}
#define CLONE(field) \
@@ -1174,6 +1191,7 @@ static struct Cookie *dup_cookie(struct Cookie *src)
d->secure = src->secure;
d->livecookie = src->livecookie;
d->httponly = src->httponly;
+ d->creationtime = src->creationtime;
}
return d;
@@ -1384,9 +1402,8 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies)
****************************************************************************/
void Curl_cookie_cleanup(struct CookieInfo *c)
{
- unsigned int i;
-
if(c) {
+ unsigned int i;
free(c->filename);
for(i = 0; i < COOKIE_HASH_SIZE; i++)
Curl_cookie_freelist(c->cookies[i]);
@@ -1439,6 +1456,8 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
bool use_stdout = FALSE;
char *format_ptr;
unsigned int i;
+ 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
@@ -1452,6 +1471,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
if(0 == c->numcookies)
return 0;
+ array = malloc(sizeof(struct Cookie *) * c->numcookies);
+ if(!array)
+ return 1;
+
if(!strcmp("-", dumphere)) {
/* use stdout */
out = stdout;
@@ -1459,8 +1482,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
}
else {
out = fopen(dumphere, FOPEN_WRITETEXT);
- if(!out)
+ if(!out) {
+ free(array);
return 1; /* failure */
+ }
}
fputs("# Netscape HTTP Cookie File\n"
@@ -1468,22 +1493,33 @@ 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;
- format_ptr = get_netscape_format(co);
- if(format_ptr == NULL) {
- fprintf(out, "#\n# Fatal libcurl error\n");
- if(!use_stdout)
- fclose(out);
- return 1;
+ 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");
+ if(!use_stdout) {
+ free(array);
+ fclose(out);
}
- fprintf(out, "%s\n", format_ptr);
- free(format_ptr);
+ return 1;
}
+ fprintf(out, "%s\n", format_ptr);
+ free(format_ptr);
}
+ free(array);
+
if(!use_stdout)
fclose(out);
diff --git a/Utilities/cmcurl/lib/cookie.h b/Utilities/cmcurl/lib/cookie.h
index 79b5928dc2..a9f90ca715 100644
--- a/Utilities/cmcurl/lib/cookie.h
+++ b/Utilities/cmcurl/lib/cookie.h
@@ -34,7 +34,7 @@ struct Cookie {
char *domain; /* domain = <this> */
curl_off_t expires; /* expires = <this> */
char *expirestr; /* the plain text version */
- bool tailmatch; /* weather we do tail-matchning of the domain name */
+ bool tailmatch; /* whether we do tail-matching of the domain name */
/* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
char *version; /* Version = <value> */
@@ -43,6 +43,7 @@ struct Cookie {
bool secure; /* whether the 'secure' keyword was used */
bool livecookie; /* updated from a server, not a stored file */
bool httponly; /* true if the httponly directive is present */
+ int creationtime; /* time when the cookie was written */
};
#define COOKIE_HASH_SIZE 256
@@ -55,6 +56,7 @@ struct CookieInfo {
bool running; /* state info, for cookie adding information */
long numcookies; /* number of cookies in the "jar" */
bool newsession; /* new session, discard session cookies on load */
+ int lastct; /* last creation-time used in the jar */
};
/* This is the maximum line length we accept for a cookie line. RFC 2109
diff --git a/Utilities/cmcurl/lib/curl_addrinfo.c b/Utilities/cmcurl/lib/curl_addrinfo.c
index 55d5a3942d..fd49679c93 100644
--- a/Utilities/cmcurl/lib/curl_addrinfo.c
+++ b/Utilities/cmcurl/lib/curl_addrinfo.c
@@ -536,7 +536,8 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
}
#endif
-#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
+ defined(HAVE_FREEADDRINFO)
/*
* curl_dofreeaddrinfo()
*
diff --git a/Utilities/cmcurl/lib/curl_config.h.cmake b/Utilities/cmcurl/lib/curl_config.h.cmake
index 24d1ca0bd5..ec4bf913a5 100644
--- a/Utilities/cmcurl/lib/curl_config.h.cmake
+++ b/Utilities/cmcurl/lib/curl_config.h.cmake
@@ -226,6 +226,9 @@
/* Define to 1 if you have the `getpwuid' function. */
#cmakedefine HAVE_GETPWUID 1
+/* Define to 1 if you have the `getpwuid_r' function. */
+#cmakedefine HAVE_GETPWUID_R 1
+
/* Define to 1 if you have the `getrlimit' function. */
#cmakedefine HAVE_GETRLIMIT 1
@@ -951,6 +954,9 @@
/* to enable Windows SSL */
#cmakedefine USE_SCHANNEL 1
+/* enable multiple SSL backends */
+#cmakedefine CURL_WITH_MULTI_SSL 1
+
/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
#cmakedefine USE_YASSLEMUL 1
diff --git a/Utilities/cmcurl/lib/curl_fnmatch.c b/Utilities/cmcurl/lib/curl_fnmatch.c
index 0179a4f717..fbfd85c438 100644
--- a/Utilities/cmcurl/lib/curl_fnmatch.c
+++ b/Utilities/cmcurl/lib/curl_fnmatch.c
@@ -30,6 +30,17 @@
/* The last #include file should be: */
#include "memdebug.h"
+#ifndef HAVE_FNMATCH
+
+/*
+ * TODO:
+ *
+ * Make this function match POSIX. Test 1307 includes a set of test patterns
+ * that returns different results with a POSIX fnmatch() than with this
+ * implementation and this is considered a bug where POSIX is the guiding
+ * light.
+ */
+
#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
@@ -334,9 +345,9 @@ static int loop(const unsigned char *pattern, const unsigned char *string,
s++;
break;
}
+ /* Syntax error in set; mismatch! */
+ return CURL_FNMATCH_NOMATCH;
- /* Syntax error in set: this must be taken as a regular character. */
- /* FALLTHROUGH */
default:
if(*p++ != *s++)
return CURL_FNMATCH_NOMATCH;
@@ -355,5 +366,31 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
if(!pattern || !string) {
return CURL_FNMATCH_FAIL;
}
- return loop((unsigned char *)pattern, (unsigned char *)string, 5);
+ return loop((unsigned char *)pattern, (unsigned char *)string, 2);
+}
+#else
+#include <fnmatch.h>
+/*
+ * @unittest: 1307
+ */
+int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
+{
+ int rc;
+ (void)ptr; /* the argument is specified by the curl_fnmatch_callback
+ prototype, but not used by Curl_fnmatch() */
+ if(!pattern || !string) {
+ return CURL_FNMATCH_FAIL;
+ }
+ rc = fnmatch(pattern, string, 0);
+ switch(rc) {
+ case 0:
+ return CURL_FNMATCH_MATCH;
+ case FNM_NOMATCH:
+ return CURL_FNMATCH_NOMATCH;
+ default:
+ return CURL_FNMATCH_FAIL;
+ }
+ /* not reached */
}
+
+#endif
diff --git a/Utilities/cmcurl/lib/curl_ntlm_core.c b/Utilities/cmcurl/lib/curl_ntlm_core.c
index e27cab353c..922e85a926 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_core.c
+++ b/Utilities/cmcurl/lib/curl_ntlm_core.c
@@ -557,8 +557,11 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
unsigned char *ntbuffer /* 21 bytes */)
{
size_t len = strlen(password);
- unsigned char *pw = len ? malloc(len * 2) : strdup("");
+ unsigned char *pw;
CURLcode result;
+ if(len > SIZE_T_MAX/2) /* avoid integer overflow */
+ return CURLE_OUT_OF_MEMORY;
+ pw = len ? malloc(len * 2) : strdup("");
if(!pw)
return CURLE_OUT_OF_MEMORY;
diff --git a/Utilities/cmcurl/lib/curl_sasl.c b/Utilities/cmcurl/lib/curl_sasl.c
index e54e4875e2..354bc54487 100644
--- a/Utilities/cmcurl/lib/curl_sasl.c
+++ b/Utilities/cmcurl/lib/curl_sasl.c
@@ -146,7 +146,6 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
const char *value, size_t len)
{
CURLcode result = CURLE_OK;
- unsigned int mechbit;
size_t mechlen;
if(!len)
@@ -160,7 +159,7 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
if(!strncmp(value, "*", len))
sasl->prefmech = SASL_AUTH_DEFAULT;
else {
- mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
+ unsigned int mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
if(mechbit && mechlen == len)
sasl->prefmech |= mechbit;
else
diff --git a/Utilities/cmcurl/lib/curl_setup.h b/Utilities/cmcurl/lib/curl_setup.h
index 7e6fd5e7e4..b056126c40 100644
--- a/Utilities/cmcurl/lib/curl_setup.h
+++ b/Utilities/cmcurl/lib/curl_setup.h
@@ -221,7 +221,7 @@
/*
* Use getaddrinfo to resolve the IPv4 address literal. If the current network
- * interface doesn’t support IPv4, but supports IPv6, NAT64, and DNS64,
+ * interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
* performing this task will result in a synthesized IPv6 address.
*/
#ifdef __APPLE__
@@ -246,6 +246,7 @@
# if defined(_UNICODE) && !defined(UNICODE)
# define UNICODE
# endif
+# include <winerror.h>
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
@@ -815,4 +816,16 @@ endings either CRLF or LF so 't' is appropriate.
#define CURL_SA_FAMILY_T unsigned short
#endif
+/* Some convenience macros to get the larger/smaller value out of two given.
+ We prefix with CURL to prevent name collisions. */
+#define CURLMAX(x,y) ((x)>(y)?(x):(y))
+#define CURLMIN(x,y) ((x)<(y)?(x):(y))
+
+/* Some versions of the Android SDK is missing the declaration */
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
+struct passwd;
+int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
+ size_t buflen, struct passwd **result);
+#endif
+
#endif /* HEADER_CURL_SETUP_H */
diff --git a/Utilities/cmcurl/lib/curl_threads.c b/Utilities/cmcurl/lib/curl_threads.c
index c1624a9136..b8f0cd35d5 100644
--- a/Utilities/cmcurl/lib/curl_threads.c
+++ b/Utilities/cmcurl/lib/curl_threads.c
@@ -108,7 +108,8 @@ curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
#ifdef _WIN32_WCE
t = CreateThread(NULL, 0, func, arg, 0, NULL);
#else
- t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL);
+ uintptr_t thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL);
+ t = (curl_thread_t)thread_handle;
#endif
if((t == 0) || (t == LongToHandle(-1L))) {
#ifdef _WIN32_WCE
diff --git a/Utilities/cmcurl/lib/dict.c b/Utilities/cmcurl/lib/dict.c
index 4fc85521d7..408d57b92f 100644
--- a/Utilities/cmcurl/lib/dict.c
+++ b/Utilities/cmcurl/lib/dict.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
@@ -95,17 +95,17 @@ static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
{
char *newp = NULL;
char *dictp;
- char *ptr;
size_t len;
- char ch;
- int olen = 0;
CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
if(!newp || result)
return NULL;
- dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
+ dictp = malloc(len*2 + 1); /* add one for terminating zero */
if(dictp) {
+ char *ptr;
+ char ch;
+ int olen = 0;
/* According to RFC2229 section 2.2, these letters need to be escaped with
\[letter] */
for(ptr = newp;
diff --git a/Utilities/cmcurl/lib/easy.c b/Utilities/cmcurl/lib/easy.c
index 6b914353de..027d0bef30 100644
--- a/Utilities/cmcurl/lib/easy.c
+++ b/Utilities/cmcurl/lib/easy.c
@@ -113,7 +113,7 @@ static CURLcode win32_init(void)
res = WSAStartup(wVersionRequested, &wsaData);
if(res != 0)
- /* Tell the user that we couldn't find a useable */
+ /* Tell the user that we couldn't find a usable */
/* winsock.dll. */
return CURLE_FAILED_INIT;
@@ -125,7 +125,7 @@ static CURLcode win32_init(void)
if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
- /* Tell the user that we couldn't find a useable */
+ /* Tell the user that we couldn't find a usable */
/* winsock.dll. */
WSACleanup();
@@ -661,38 +661,27 @@ static CURLcode easy_transfer(struct Curl_multi *multi)
bool done = FALSE;
CURLMcode mcode = CURLM_OK;
CURLcode result = CURLE_OK;
- struct curltime before;
- int without_fds = 0; /* count number of consecutive returns from
- curl_multi_wait() without any filedescriptors */
while(!done && !mcode) {
int still_running = 0;
int rc;
- before = Curl_now();
mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
if(!mcode) {
if(!rc) {
- struct curltime after = Curl_now();
+ long sleep_ms;
/* If it returns without any filedescriptor instantly, we need to
avoid busy-looping during periods where it has nothing particular
to wait for */
- if(Curl_timediff(after, before) <= 10) {
- without_fds++;
- if(without_fds > 2) {
- int sleep_ms = without_fds < 10 ? (1 << (without_fds - 1)) : 1000;
- Curl_wait_ms(sleep_ms);
- }
+ curl_multi_timeout(multi, &sleep_ms);
+ if(sleep_ms) {
+ if(sleep_ms > 1000)
+ sleep_ms = 1000;
+ Curl_wait_ms((int)sleep_ms);
}
- else
- /* it wasn't "instant", restart counter */
- without_fds = 0;
}
- else
- /* got file descriptor, restart counter */
- without_fds = 0;
mcode = curl_multi_perform(multi, &still_running);
}
@@ -969,6 +958,13 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
outcurl->change.referer_alloc = TRUE;
}
+ /* Reinitialize an SSL engine for the new handle
+ * note: the engine name has already been copied by dupset */
+ if(outcurl->set.str[STRING_SSL_ENGINE]) {
+ if(Curl_ssl_set_engine(outcurl, outcurl->set.str[STRING_SSL_ENGINE]))
+ goto fail;
+ }
+
/* Clone the resolver handle, if present, for the new handle */
if(Curl_resolver_duphandle(&outcurl->state.resolver,
data->state.resolver))
diff --git a/Utilities/cmcurl/lib/escape.c b/Utilities/cmcurl/lib/escape.c
index b7e2d32a6c..10774f0586 100644
--- a/Utilities/cmcurl/lib/escape.c
+++ b/Utilities/cmcurl/lib/escape.c
@@ -82,7 +82,6 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
size_t alloc;
char *ns;
char *testing_ptr = NULL;
- unsigned char in; /* we need to treat the characters unsigned */
size_t newlen;
size_t strindex = 0;
size_t length;
@@ -100,7 +99,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
length = alloc-1;
while(length--) {
- in = *string;
+ unsigned char in = *string; /* we need to treat the characters unsigned */
if(Curl_isunreserved(in))
/* just copy this */
@@ -150,7 +149,6 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
{
size_t alloc = (length?length:strlen(string)) + 1;
char *ns = malloc(alloc);
- unsigned char in;
size_t strindex = 0;
unsigned long hex;
CURLcode result;
@@ -159,7 +157,7 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
while(--alloc > 0) {
- in = *string;
+ unsigned char in = *string;
if(('%' == in) && (alloc > 2) &&
ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
/* this is two hexadecimal digits following a '%' */
diff --git a/Utilities/cmcurl/lib/file.c b/Utilities/cmcurl/lib/file.c
index db04cc2daf..e50e988769 100644
--- a/Utilities/cmcurl/lib/file.c
+++ b/Utilities/cmcurl/lib/file.c
@@ -256,8 +256,6 @@ static CURLcode file_upload(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
char *buf = data->state.buffer;
- size_t nread;
- size_t nwrite;
curl_off_t bytecount = 0;
struct_stat file_stat;
const char *buf2;
@@ -306,7 +304,9 @@ static CURLcode file_upload(struct connectdata *conn)
}
while(!result) {
- int readcount;
+ size_t nread;
+ size_t nwrite;
+ size_t readcount;
result = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount);
if(result)
break;
@@ -314,7 +314,7 @@ static CURLcode file_upload(struct connectdata *conn)
if(readcount <= 0) /* fix questionable compare error. curlvms */
break;
- nread = (size_t)readcount;
+ nread = readcount;
/*skip bytes before resume point*/
if(data->state.resume_from) {
@@ -378,7 +378,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
curl_off_t expected_size = 0;
bool size_known;
bool fstated = FALSE;
- ssize_t nread;
struct Curl_easy *data = conn->data;
char *buf = data->state.buffer;
curl_off_t bytecount = 0;
@@ -461,7 +460,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
return result;
/* Adjust the start offset in case we want to get the N last bytes
- * of the stream iff the filesize could be determined */
+ * of the stream if the filesize could be determined */
if(data->state.resume_from < 0) {
if(!fstated) {
failf(data, "Can't get the size of file.");
@@ -502,6 +501,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
while(!result) {
+ ssize_t nread;
/* Don't fill a whole buffer if we want less than all data */
size_t bytestoread;
diff --git a/Utilities/cmcurl/lib/formdata.c b/Utilities/cmcurl/lib/formdata.c
index f912410526..202d930c70 100644
--- a/Utilities/cmcurl/lib/formdata.c
+++ b/Utilities/cmcurl/lib/formdata.c
@@ -39,16 +39,13 @@
#include "sendf.h"
#include "strdup.h"
#include "rand.h"
+#include "warnless.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
-/* What kind of Content-Type to use on un-specified files with unrecognized
- extensions. */
-#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
-
#define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME
#define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME
#define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS
@@ -305,7 +302,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
* Set the contents property.
*/
case CURLFORM_PTRCONTENTS:
- current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
+ current_form->flags |= HTTPPOST_PTRCONTENTS;
+ /* FALLTHROUGH */
case CURLFORM_COPYCONTENTS:
if(current_form->value)
return_value = CURL_FORMADD_OPTION_TWICE;
@@ -725,7 +723,7 @@ int curl_formget(struct curl_httppost *form, void *arg,
while(!result) {
char buffer[8192];
- size_t nread = Curl_mime_read(buffer, 1, sizeof buffer, &toppart);
+ size_t nread = Curl_mime_read(buffer, 1, sizeof(buffer), &toppart);
if(!nread)
break;
@@ -812,7 +810,6 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
{
CURLcode result = CURLE_OK;
curl_mime *form = NULL;
- curl_mime *multipart;
curl_mimepart *part;
struct curl_httppost *file;
@@ -831,7 +828,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
/* Process each top part. */
for(; !result && post; post = post->next) {
/* If we have more than a file here, create a mime subpart and fill it. */
- multipart = form;
+ curl_mime *multipart = form;
if(post->more) {
part = curl_mime_addpart(form);
if(!part)
@@ -883,7 +880,8 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
compatibility: use of "-" pseudo file name should be avoided. */
result = curl_mime_data_cb(part, (curl_off_t) -1,
(curl_read_callback) fread,
- (curl_seek_callback) fseek,
+ CURLX_FUNCTION_CAST(curl_seek_callback,
+ fseek),
NULL, (void *) stdin);
}
else
diff --git a/Utilities/cmcurl/lib/ftp.c b/Utilities/cmcurl/lib/ftp.c
index a42c0c7c60..63f32cf26c 100644
--- a/Utilities/cmcurl/lib/ftp.c
+++ b/Utilities/cmcurl/lib/ftp.c
@@ -239,8 +239,8 @@ static void close_secondarysocket(struct connectdata *conn)
static void freedirs(struct ftp_conn *ftpc)
{
- int i;
if(ftpc->dirs) {
+ int i;
for(i = 0; i < ftpc->dirdepth; i++) {
free(ftpc->dirs[i]);
ftpc->dirs[i] = NULL;
@@ -637,8 +637,6 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
* line in a response or continue reading. */
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
- time_t timeout; /* timeout in milliseconds */
- time_t interval_ms;
struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK;
struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -657,7 +655,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
while(!*ftpcode && !result) {
/* check and reset timeout value every lap */
- timeout = Curl_pp_state_timeout(pp);
+ time_t timeout = Curl_pp_state_timeout(pp); /* timeout in milliseconds */
+ time_t interval_ms;
if(timeout <= 0) {
failf(data, "FTP response timeout");
@@ -1589,7 +1588,6 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
struct FTP *ftp = conn->data->req.protop;
struct Curl_easy *data = conn->data;
struct ftp_conn *ftpc = &conn->proto.ftpc;
- int seekerr = CURL_SEEKFUNC_OK;
if((data->state.resume_from && !sizechecked) ||
((data->state.resume_from > 0) && sizechecked)) {
@@ -1605,6 +1603,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
/* 3. pass file-size number of bytes in the source file */
/* 4. lower the infilesize counter */
/* => transfer as usual */
+ int seekerr = CURL_SEEKFUNC_OK;
if(data->state.resume_from < 0) {
/* Got no given size to start from, figure it out */
@@ -2782,7 +2781,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
char *ptr = &data->state.buffer[4]; /* start on the first letter */
const size_t buf_size = data->set.buffer_size;
char *dir;
- char *store;
bool entry_extracted = FALSE;
dir = malloc(nread + 1);
@@ -2805,6 +2803,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if('\"' == *ptr) {
/* it started good */
+ char *store;
ptr++;
for(store = dir; *ptr;) {
if('\"' == *ptr) {
@@ -3993,8 +3992,7 @@ CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
break;
if(conn->data->set.verbose)
- Curl_debug(conn->data, CURLINFO_HEADER_OUT,
- sptr, (size_t)bytes_written, conn);
+ Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written);
if(bytes_written != (ssize_t)write_len) {
write_len -= bytes_written;
@@ -4385,7 +4383,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
char *type;
- char command;
struct FTP *ftp;
conn->data->req.protop = ftp = malloc(sizeof(struct FTP));
@@ -4403,6 +4400,7 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
type = strstr(conn->host.rawalloc, ";type=");
if(type) {
+ char command;
*type = 0; /* it was in the middle of the hostname */
command = Curl_raw_toupper(type[6]);
conn->bits.type_set = TRUE;
diff --git a/Utilities/cmcurl/lib/getinfo.c b/Utilities/cmcurl/lib/getinfo.c
index d280eebfaf..14b456274a 100644
--- a/Utilities/cmcurl/lib/getinfo.c
+++ b/Utilities/cmcurl/lib/getinfo.c
@@ -281,6 +281,28 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
*param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
data->progress.size_ul:-1;
break;
+ case CURLINFO_TOTAL_TIME_T:
+ *param_offt = data->progress.timespent;
+ break;
+ case CURLINFO_NAMELOOKUP_TIME_T:
+ *param_offt = data->progress.t_nslookup;
+ break;
+ case CURLINFO_CONNECT_TIME_T:
+ *param_offt = data->progress.t_connect;
+ break;
+ case CURLINFO_APPCONNECT_TIME_T:
+ *param_offt = data->progress.t_appconnect;
+ break;
+ case CURLINFO_PRETRANSFER_TIME_T:
+ *param_offt = data->progress.t_pretransfer;
+ break;
+ case CURLINFO_STARTTRANSFER_TIME_T:
+ *param_offt = data->progress.t_starttransfer;
+ break;
+ case CURLINFO_REDIRECT_TIME_T:
+ *param_offt = data->progress.t_redirect;
+ break;
+
default:
return CURLE_UNKNOWN_OPTION;
}
diff --git a/Utilities/cmcurl/lib/gopher.c b/Utilities/cmcurl/lib/gopher.c
index b7c31b695e..3ecee9bdc3 100644
--- a/Utilities/cmcurl/lib/gopher.c
+++ b/Utilities/cmcurl/lib/gopher.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
@@ -89,22 +89,15 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
/* Create selector. Degenerate cases: / and /1 => convert to "" */
if(strlen(path) <= 2) {
sel = (char *)"";
- len = (int)strlen(sel);
+ len = strlen(sel);
}
else {
char *newp;
- size_t j, i;
/* Otherwise, drop / and the first character (i.e., item type) ... */
newp = path;
newp += 2;
- /* ... then turn ? into TAB for search servers, Veronica, etc. ... */
- j = strlen(newp);
- for(i = 0; i<j; i++)
- if(newp[i] == '?')
- newp[i] = '\x09';
-
/* ... and finally unescape */
result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
if(result)
diff --git a/Utilities/cmcurl/lib/hash.c b/Utilities/cmcurl/lib/hash.c
index 15a128fecc..421d68f769 100644
--- a/Utilities/cmcurl/lib/hash.c
+++ b/Utilities/cmcurl/lib/hash.c
@@ -60,8 +60,6 @@ Curl_hash_init(struct curl_hash *h,
comp_function comparator,
curl_hash_dtor dtor)
{
- int i;
-
if(!slots || !hfunc || !comparator ||!dtor) {
return 1; /* failure */
}
@@ -74,6 +72,7 @@ Curl_hash_init(struct curl_hash *h,
h->table = malloc(slots * sizeof(struct curl_llist));
if(h->table) {
+ int i;
for(i = 0; i < slots; ++i)
Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor);
return 0; /* fine */
@@ -140,11 +139,10 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
{
struct curl_llist_element *le;
- struct curl_hash_element *he;
struct curl_llist *l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
- he = le->ptr;
+ struct curl_hash_element *he = le->ptr;
if(h->comp_func(he->key, he->key_len, key, key_len)) {
Curl_llist_remove(l, le, (void *) h);
--h->size;
@@ -162,13 +160,12 @@ void *
Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
{
struct curl_llist_element *le;
- struct curl_hash_element *he;
struct curl_llist *l;
if(h) {
l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
- he = le->ptr;
+ struct curl_hash_element *he = le->ptr;
if(h->comp_func(he->key, he->key_len, key, key_len)) {
return he->ptr;
}
@@ -291,7 +288,6 @@ void Curl_hash_start_iterate(struct curl_hash *hash,
struct curl_hash_element *
Curl_hash_next_element(struct curl_hash_iterator *iter)
{
- int i;
struct curl_hash *h = iter->hash;
/* Get the next element in the current list, if any */
@@ -300,6 +296,7 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
/* If we have reached the end of the list, find the next one */
if(!iter->current_element) {
+ int i;
for(i = iter->slot_index; i < h->slots; i++) {
if(h->table[i].head) {
iter->current_element = h->table[i].head;
diff --git a/Utilities/cmcurl/lib/hmac.c b/Utilities/cmcurl/lib/hmac.c
index dae95054b0..bf49ebec54 100644
--- a/Utilities/cmcurl/lib/hmac.c
+++ b/Utilities/cmcurl/lib/hmac.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
@@ -58,7 +58,7 @@ Curl_HMAC_init(const HMAC_params * hashparams,
unsigned char b;
/* Create HMAC context. */
- i = sizeof *ctxt + 2 * hashparams->hmac_ctxtsize +
+ i = sizeof(*ctxt) + 2 * hashparams->hmac_ctxtsize +
hashparams->hmac_resultlen;
ctxt = malloc(i);
diff --git a/Utilities/cmcurl/lib/hostasyn.c b/Utilities/cmcurl/lib/hostasyn.c
index 7b6e8568a0..e7b399ed27 100644
--- a/Utilities/cmcurl/lib/hostasyn.c
+++ b/Utilities/cmcurl/lib/hostasyn.c
@@ -5,7 +5,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
@@ -131,7 +131,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn,
if(result)
/* We're not allowed to return failure with memory left allocated
in the connectdata struct, free those here */
- Curl_disconnect(conn, FALSE); /* close the connection */
+ Curl_disconnect(conn->data, conn, TRUE); /* close the connection */
return result;
}
diff --git a/Utilities/cmcurl/lib/hostip.c b/Utilities/cmcurl/lib/hostip.c
index c2f9defd94..bc20f71538 100644
--- a/Utilities/cmcurl/lib/hostip.c
+++ b/Utilities/cmcurl/lib/hostip.c
@@ -907,7 +907,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
char *entry_id;
size_t entry_len;
char address[64];
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
char *addresses = NULL;
+#endif
char *addr_begin;
char *addr_end;
char *port_ptr;
@@ -930,7 +932,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
goto err;
port = (int)tmp_port;
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
addresses = end_ptr + 1;
+#endif
while(*end_ptr) {
size_t alen;
@@ -1010,24 +1014,28 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
/* See if its already in our dns cache */
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
+ if(dns) {
+ infof(data, "RESOLVE %s:%d is - old addresses discarded!\n",
+ hostname, port);
+ /* delete old entry entry, there are two reasons for this
+ 1. old entry may have different addresses.
+ 2. even if entry with correct addresses is already in the cache,
+ but if it is close to expire, then by the time next http
+ request is made, it can get expired and pruned because old
+ entry is not necessarily marked as added by CURLOPT_RESOLVE. */
+
+ Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
+ }
/* free the allocated entry_id again */
free(entry_id);
- if(!dns) {
- /* if not in the cache already, put this host in the cache */
- dns = Curl_cache_addr(data, head, hostname, port);
- if(dns) {
- dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
- /* release the returned reference; the cache itself will keep the
- * entry alive: */
- dns->inuse--;
- }
- }
- else {
- /* this is a duplicate, free it again */
- infof(data, "RESOLVE %s:%d is already cached, %s not stored!\n",
- hostname, port, addresses);
- Curl_freeaddrinfo(head);
+ /* put this new host in the cache */
+ dns = Curl_cache_addr(data, head, hostname, port);
+ if(dns) {
+ dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
+ /* release the returned reference; the cache itself will keep the
+ * entry alive: */
+ dns->inuse--;
}
if(data->share)
diff --git a/Utilities/cmcurl/lib/hostip6.c b/Utilities/cmcurl/lib/hostip6.c
index 7c9988f41b..3bf47b467d 100644
--- a/Utilities/cmcurl/lib/hostip6.c
+++ b/Utilities/cmcurl/lib/hostip6.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
@@ -59,39 +59,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
-/* These are strictly for memory tracing and are using the same style as the
- * family otherwise present in memdebug.c. I put these ones here since they
- * require a bunch of structs I didn't want to include in memdebug.c
- */
-
-/*
- * For CURLRES_ARS, this should be written using ares_gethostbyaddr()
- * (ignoring the fact c-ares doesn't return 'serv').
- */
-
-int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
- GETNAMEINFO_TYPE_ARG2 salen,
- char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
- char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
- GETNAMEINFO_TYPE_ARG7 flags,
- int line, const char *source)
-{
- int res = (getnameinfo)(sa, salen,
- host, hostlen,
- serv, servlen,
- flags);
- if(0 == res)
- /* success */
- curl_memlog("GETNAME %s:%d getnameinfo()\n",
- source, line);
- else
- curl_memlog("GETNAME %s:%d getnameinfo() failed = %d\n",
- source, line, res);
- return res;
-}
-#endif /* defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) */
-
/*
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
*/
diff --git a/Utilities/cmcurl/lib/http.c b/Utilities/cmcurl/lib/http.c
index ff1d6813a0..e727ed8236 100644
--- a/Utilities/cmcurl/lib/http.c
+++ b/Utilities/cmcurl/lib/http.c
@@ -158,18 +158,20 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn)
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
during this request */
struct HTTP *http;
- DEBUGASSERT(conn->data->req.protop == NULL);
+ struct Curl_easy *data = conn->data;
+ DEBUGASSERT(data->req.protop == NULL);
http = calloc(1, sizeof(struct HTTP));
if(!http)
return CURLE_OUT_OF_MEMORY;
Curl_mime_initpart(&http->form, conn->data);
- conn->data->req.protop = http;
-
- Curl_http2_setup_conn(conn);
- Curl_http2_setup_req(conn->data);
+ data->req.protop = http;
+ if(!CONN_INUSE(conn))
+ /* if not alredy multi-using, setup connection details */
+ Curl_http2_setup_conn(conn);
+ Curl_http2_setup_req(data);
return CURLE_OK;
}
@@ -310,22 +312,49 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
return result;
}
+/*
+ * http_output_bearer() sets up an Authorization: header
+ * for HTTP Bearer authentication.
+ *
+ * Returns CURLcode.
+ */
+static CURLcode http_output_bearer(struct connectdata *conn)
+{
+ char **userp;
+ CURLcode result = CURLE_OK;
+
+ userp = &conn->allocptr.userpwd;
+ free(*userp);
+ *userp = aprintf("Authorization: Bearer %s\r\n",
+ conn->oauth_bearer);
+
+ if(!*userp) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto fail;
+ }
+
+ fail:
+ return result;
+}
+
/* pickoneauth() selects the most favourable authentication method from the
* ones available and the ones we want.
*
* return TRUE if one was picked
*/
-static bool pickoneauth(struct auth *pick)
+static bool pickoneauth(struct auth *pick, unsigned long mask)
{
bool picked;
/* only deal with authentication we want */
- unsigned long avail = pick->avail & pick->want;
+ unsigned long avail = pick->avail & pick->want & mask;
picked = TRUE;
/* The order of these checks is highly relevant, as this will be the order
of preference in case of the existence of multiple accepted types. */
if(avail & CURLAUTH_NEGOTIATE)
pick->picked = CURLAUTH_NEGOTIATE;
+ else if(avail & CURLAUTH_BEARER)
+ pick->picked = CURLAUTH_BEARER;
else if(avail & CURLAUTH_DIGEST)
pick->picked = CURLAUTH_DIGEST;
else if(avail & CURLAUTH_NTLM)
@@ -479,6 +508,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
bool pickhost = FALSE;
bool pickproxy = FALSE;
CURLcode result = CURLE_OK;
+ unsigned long authmask = ~0ul;
+
+ if(!conn->oauth_bearer)
+ authmask &= (unsigned long)~CURLAUTH_BEARER;
if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
/* this is a transient response code, ignore */
@@ -487,17 +520,18 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
if(data->state.authproblem)
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
- if(conn->bits.user_passwd &&
+ if((conn->bits.user_passwd || conn->oauth_bearer) &&
((data->req.httpcode == 401) ||
(conn->bits.authneg && data->req.httpcode < 300))) {
- pickhost = pickoneauth(&data->state.authhost);
+ pickhost = pickoneauth(&data->state.authhost, authmask);
if(!pickhost)
data->state.authproblem = TRUE;
}
if(conn->bits.proxy_user_passwd &&
((data->req.httpcode == 407) ||
(conn->bits.authneg && data->req.httpcode < 300))) {
- pickproxy = pickoneauth(&data->state.authproxy);
+ pickproxy = pickoneauth(&data->state.authproxy,
+ authmask & ~CURLAUTH_BEARER);
if(!pickproxy)
data->state.authproblem = TRUE;
}
@@ -628,6 +662,20 @@ output_auth_headers(struct connectdata *conn,
functions work that way */
authstatus->done = TRUE;
}
+ if(authstatus->picked == CURLAUTH_BEARER) {
+ /* Bearer */
+ if((!proxy && conn->oauth_bearer &&
+ !Curl_checkheaders(conn, "Authorization:"))) {
+ auth = "Bearer";
+ result = http_output_bearer(conn);
+ if(result)
+ return result;
+ }
+
+ /* NOTE: this function should set 'done' TRUE, as the other auth
+ functions work that way */
+ authstatus->done = TRUE;
+ }
if(auth) {
infof(data, "%s auth using %s with user '%s'\n",
@@ -674,7 +722,7 @@ Curl_http_output_auth(struct connectdata *conn,
authproxy = &data->state.authproxy;
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
- conn->bits.user_passwd)
+ conn->bits.user_passwd || conn->oauth_bearer)
/* continue please */;
else {
authhost->done = TRUE;
@@ -883,6 +931,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
data->state.authproblem = TRUE;
}
}
+ else
+ if(checkprefix("Bearer", auth)) {
+ *availp |= CURLAUTH_BEARER;
+ authp->avail |= CURLAUTH_BEARER;
+ if(authp->picked == CURLAUTH_BEARER) {
+ /* We asked for Bearer authentication but got a 40X back
+ anyway, which basically means our token isn't valid. */
+ authp->avail = CURLAUTH_NONE;
+ infof(data, "Authentication problem. Ignoring this.\n");
+ data->state.authproblem = TRUE;
+ }
+ }
/* there may be multiple methods on one line, so keep reading */
while(*auth && *auth != ',') /* read up to the next comma */
@@ -1063,7 +1123,8 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
CURLcode result;
char *ptr;
size_t size;
- struct HTTP *http = conn->data->req.protop;
+ struct Curl_easy *data = conn->data;
+ struct HTTP *http = data->req.protop;
size_t sendsize;
curl_socket_t sockfd;
size_t headersize;
@@ -1083,7 +1144,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
DEBUGASSERT(size > included_body_bytes);
- result = Curl_convert_to_network(conn->data, ptr, headersize);
+ result = Curl_convert_to_network(data, ptr, headersize);
/* Curl_convert_to_network calls failf if unsuccessful */
if(result) {
/* conversion failed, free memory and return to the caller */
@@ -1108,8 +1169,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
must copy the data to the uploadbuffer first, since that is the buffer
we will be using if this send is retried later.
*/
- memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
- ptr = conn->data->state.uploadbuffer;
+ result = Curl_get_upload_buffer(data);
+ if(result) {
+ /* malloc failed, free memory and return to the caller */
+ Curl_add_buffer_free(in);
+ return result;
+ }
+ memcpy(data->state.ulbuf, ptr, sendsize);
+ ptr = data->state.ulbuf;
}
else
sendsize = size;
@@ -1126,14 +1193,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
size_t bodylen = amount - headlen;
- if(conn->data->set.verbose) {
+ if(data->set.verbose) {
/* this data _may_ contain binary stuff */
- Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
+ Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);
if(bodylen) {
/* there was body data sent beyond the initial header part, pass that
on to the debug callback too */
- Curl_debug(conn->data, CURLINFO_DATA_OUT,
- ptr + headlen, bodylen, conn);
+ Curl_debug(data, CURLINFO_DATA_OUT,
+ ptr + headlen, bodylen);
}
}
@@ -1157,14 +1224,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
ptr = in->buffer + amount;
/* backup the currently set pointers */
- http->backup.fread_func = conn->data->state.fread_func;
- http->backup.fread_in = conn->data->state.in;
+ http->backup.fread_func = data->state.fread_func;
+ http->backup.fread_in = data->state.in;
http->backup.postdata = http->postdata;
http->backup.postsize = http->postsize;
/* set the new pointers for the request-sending */
- conn->data->state.fread_func = (curl_read_callback)readmoredata;
- conn->data->state.in = (void *)conn;
+ data->state.fread_func = (curl_read_callback)readmoredata;
+ data->state.in = (void *)conn;
http->postdata = ptr;
http->postsize = (curl_off_t)size;
@@ -1223,7 +1290,6 @@ CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
{
char *new_rb;
- size_t new_size;
if(~size < in->size_used) {
/* If resulting used size of send buffer would wrap size_t, cleanup
@@ -1236,10 +1302,10 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
if(!in->buffer ||
((in->size_used + size) > (in->size_max - 1))) {
-
/* If current buffer size isn't enough to hold the result, use a
buffer size that doubles the required size. If this new size
would wrap size_t, then just use the largest possible one */
+ size_t new_size;
if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
(~(size * 2) < (in->size_used * 2)))
@@ -1406,7 +1472,7 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
}
snprintf(proxy_header,
- sizeof proxy_header,
+ sizeof(proxy_header),
"PROXY %s %s %s %li %li\r\n",
tcp_version,
conn->data->info.conn_local_ip,
@@ -1574,7 +1640,6 @@ static CURLcode expect100(struct Curl_easy *data,
Curl_send_buffer *req_buffer)
{
CURLcode result = CURLE_OK;
- const char *ptr;
data->state.expect100header = FALSE; /* default to false unless it is set
to TRUE below */
if(use_http_1_1plus(data, conn) &&
@@ -1582,7 +1647,7 @@ static CURLcode expect100(struct Curl_easy *data,
/* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
Expect: 100-continue to the headers which actually speeds up post
operations (as there is one packet coming back from the web server) */
- ptr = Curl_checkheaders(conn, "Expect");
+ const char *ptr = Curl_checkheaders(conn, "Expect");
if(ptr) {
data->state.expect100header =
Curl_compareheader(ptr, "Expect:", "100-continue");
@@ -1819,7 +1884,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
const char *httpstring;
Curl_send_buffer *req_buffer;
curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
- int seekerr = CURL_SEEKFUNC_CANTSEEK;
/* Always consider the DO phase done after this function call, even if there
may be parts of the request that is not yet sent, since we can deal with
@@ -1863,6 +1927,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
http = data->req.protop;
+ DEBUGASSERT(http);
if(!data->state.this_is_a_follow) {
/* Free to avoid leaking memory on multiple requests*/
@@ -2088,7 +2153,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
else {
/* If the host begins with '[', we start searching for the port after
the bracket has been closed */
- int startsearch = 0;
if(*cookiehost == '[') {
char *closingbracket;
/* since the 'cookiehost' is an allocated memory area that will be
@@ -2099,6 +2163,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
*closingbracket = 0;
}
else {
+ int startsearch = 0;
char *colon = strchr(cookiehost + startsearch, ':');
if(colon)
*colon = 0; /* The host must not include an embedded port number */
@@ -2244,6 +2309,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* Now, let's read off the proper amount of bytes from the
input. */
+ int seekerr = CURL_SEEKFUNC_CANTSEEK;
if(conn->seek_func) {
Curl_set_in_callback(data, true);
seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
@@ -2828,6 +2894,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
data->req.exp100 = EXP100_SEND_DATA; /* already sent */
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
}
+ else
+ data->req.writebytecount = http->writebytecount;
}
if((conn->httpversion == 20) && data->req.upload_chunky)
@@ -2838,17 +2906,32 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
+typedef enum {
+ STATUS_UNKNOWN, /* not enough data to tell yet */
+ STATUS_DONE, /* a status line was read */
+ STATUS_BAD /* not a status line */
+} statusline;
+
+
+/* Check a string for a prefix. Check no more than 'len' bytes */
+static bool checkprefixmax(const char *prefix, const char *buffer, size_t len)
+{
+ size_t ch = CURLMIN(strlen(prefix), len);
+ return curl_strnequal(prefix, buffer, ch);
+}
+
/*
* checkhttpprefix()
*
* Returns TRUE if member of the list matches prefix of string
*/
-static bool
+static statusline
checkhttpprefix(struct Curl_easy *data,
- const char *s)
+ const char *s, size_t len)
{
struct curl_slist *head = data->set.http200aliases;
- bool rc = FALSE;
+ statusline rc = STATUS_BAD;
+ statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
#ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding using a scratch area */
char *scratch = strdup(s);
@@ -2865,15 +2948,15 @@ checkhttpprefix(struct Curl_easy *data,
#endif /* CURL_DOES_CONVERSIONS */
while(head) {
- if(checkprefix(head->data, s)) {
- rc = TRUE;
+ if(checkprefixmax(head->data, s, len)) {
+ rc = onmatch;
break;
}
head = head->next;
}
- if(!rc && (checkprefix("HTTP/", s)))
- rc = TRUE;
+ if((rc != STATUS_DONE) && (checkprefixmax("HTTP/", s, len)))
+ rc = onmatch;
#ifdef CURL_DOES_CONVERSIONS
free(scratch);
@@ -2882,11 +2965,12 @@ checkhttpprefix(struct Curl_easy *data,
}
#ifndef CURL_DISABLE_RTSP
-static bool
+static statusline
checkrtspprefix(struct Curl_easy *data,
- const char *s)
+ const char *s, size_t len)
{
- bool result = FALSE;
+ statusline result = STATUS_BAD;
+ statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
#ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding using a scratch area */
@@ -2899,30 +2983,31 @@ checkrtspprefix(struct Curl_easy *data,
/* Curl_convert_from_network calls failf if unsuccessful */
result = FALSE; /* can't return CURLE_foobar so return FALSE */
}
- else
- result = checkprefix("RTSP/", scratch)? TRUE: FALSE;
+ else if(checkprefixmax("RTSP/", scratch, len))
+ result = onmatch;
free(scratch);
#else
(void)data; /* unused */
- result = checkprefix("RTSP/", s)? TRUE: FALSE;
+ if(checkprefixmax("RTSP/", s, len))
+ result = onmatch;
#endif /* CURL_DOES_CONVERSIONS */
return result;
}
#endif /* CURL_DISABLE_RTSP */
-static bool
+static statusline
checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
- const char *s)
+ const char *s, size_t len)
{
#ifndef CURL_DISABLE_RTSP
if(conn->handler->protocol & CURLPROTO_RTSP)
- return checkrtspprefix(data, s);
+ return checkrtspprefix(data, s, len);
#else
(void)conn;
#endif /* CURL_DISABLE_RTSP */
- return checkhttpprefix(data, s);
+ return checkhttpprefix(data, s, len);
}
/*
@@ -2939,7 +3024,7 @@ static CURLcode header_append(struct Curl_easy *data,
/* The reason to have a max limit for this is to avoid the risk of a bad
server feeding libcurl with a never-ending header that will cause
reallocs infinitely */
- failf(data, "Rejected %zd bytes header (max is %d)!", newsize,
+ failf(data, "Rejected %zu bytes header (max is %d)!", newsize,
CURL_MAX_HTTP_HEADER);
return CURLE_OUT_OF_MEMORY;
}
@@ -3036,12 +3121,15 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(result)
return result;
- if(!k->headerline && (k->hbuflen>5)) {
- /* make a first check that this looks like a protocol header */
- if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
+ if(!k->headerline) {
+ /* check if this looks like a protocol header */
+ statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
+ k->hbuflen);
+ if(st == STATUS_BAD) {
/* this is not the beginning of a protocol first header line */
k->header = FALSE;
k->badheader = HEADER_ALLBAD;
+ streamclose(conn, "bad HTTP: No end-of-message indicator");
break;
}
}
@@ -3070,8 +3158,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(!k->headerline) {
/* the first read header */
- if((k->hbuflen>5) &&
- !checkprotoprefix(data, conn, data->state.headerbuff)) {
+ statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
+ k->hbuflen);
+ if(st == STATUS_BAD) {
+ streamclose(conn, "bad HTTP: No end-of-message indicator");
/* this is not the beginning of a protocol first header line */
k->header = FALSE;
if(*nread)
@@ -3354,7 +3444,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
- k->str_start, headerlen, conn);
+ k->str_start, headerlen);
break; /* exit header line loop */
}
@@ -3440,7 +3530,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
compare header line against list of aliases
*/
if(!nc) {
- if(checkhttpprefix(data, k->p)) {
+ if(checkhttpprefix(data, k->p, k->hbuflen) == STATUS_DONE) {
nc = 1;
k->httpcode = 200;
conn->httpversion = 10;
@@ -3487,21 +3577,18 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* depending on how authentication is working. Other codes
* are definitely errors, so give up here.
*/
- if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
+ if(data->state.resume_from && data->set.httpreq == HTTPREQ_GET &&
+ k->httpcode == 416) {
+ /* "Requested Range Not Satisfiable", just proceed and
+ pretend this is no error */
+ k->ignorebody = TRUE; /* Avoid appending error msg to good data. */
+ }
+ else if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
((k->httpcode != 401) || !conn->bits.user_passwd) &&
((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
-
- if(data->state.resume_from &&
- (data->set.httpreq == HTTPREQ_GET) &&
- (k->httpcode == 416)) {
- /* "Requested Range Not Satisfiable", just proceed and
- pretend this is no error */
- }
- else {
- /* serious error, go home! */
- print_http_error(data);
- return CURLE_HTTP_RETURNED_ERROR;
- }
+ /* serious error, go home! */
+ print_http_error(data);
+ return CURLE_HTTP_RETURNED_ERROR;
}
if(conn->httpversion == 10) {
@@ -3812,8 +3899,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
writetype |= CLIENTWRITE_BODY;
if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN,
- k->p, (size_t)k->hbuflen, conn);
+ Curl_debug(data, CURLINFO_HEADER_IN, k->p, (size_t)k->hbuflen);
result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
if(result)
diff --git a/Utilities/cmcurl/lib/http2.c b/Utilities/cmcurl/lib/http2.c
index da001dfd09..d769193005 100644
--- a/Utilities/cmcurl/lib/http2.c
+++ b/Utilities/cmcurl/lib/http2.c
@@ -42,7 +42,6 @@
#include "memdebug.h"
#define H2_BUFSIZE 32768
-#define MIN(x,y) ((x)<(y)?(x):(y))
#if (NGHTTP2_VERSION_NUM < 0x010000)
#error too old nghttp2 version, upgrade!
@@ -154,6 +153,11 @@ static void http2_stream_free(struct HTTP *http)
}
}
+/*
+ * Disconnects *a* connection used for HTTP/2. It might be an old one from the
+ * connection cache and not the "main" one. Don't touch the easy handle!
+ */
+
static CURLcode http2_disconnect(struct connectdata *conn,
bool dead_connection)
{
@@ -164,8 +168,6 @@ static CURLcode http2_disconnect(struct connectdata *conn,
nghttp2_session_del(c->h2);
Curl_safefree(c->inbuf);
- http2_stream_free(conn->data->req.protop);
- conn->data->state.drain = 0;
H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
@@ -345,7 +347,7 @@ const char *Curl_http2_strerror(uint32_t err)
"INADEQUATE_SECURITY", /* 0xC */
"HTTP_1_1_REQUIRED" /* 0xD */
};
- return (err < sizeof str / sizeof str[0]) ? str[err] : "unknown";
+ return (err < sizeof(str) / sizeof(str[0])) ? str[err] : "unknown";
#else
return nghttp2_http2_strerror(err);
#endif
@@ -368,6 +370,10 @@ static ssize_t send_callback(nghttp2_session *h2,
(void)h2;
(void)flags;
+ if(!c->send_underlying)
+ /* called before setup properly! */
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
data, length, &result);
@@ -441,6 +447,28 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
return NULL;
}
+/*
+ * This specific transfer on this connection has been "drained".
+ */
+static void drained_transfer(struct Curl_easy *data,
+ struct http_conn *httpc)
+{
+ DEBUGASSERT(httpc->drain_total >= data->state.drain);
+ httpc->drain_total -= data->state.drain;
+ data->state.drain = 0;
+}
+
+/*
+ * Mark this transfer to get "drained".
+ */
+static void drain_this(struct Curl_easy *data,
+ struct http_conn *httpc)
+{
+ data->state.drain++;
+ httpc->drain_total++;
+ DEBUGASSERT(httpc->drain_total >= data->state.drain);
+}
+
static struct Curl_easy *duphandle(struct Curl_easy *data)
{
struct Curl_easy *second = curl_easy_duphandle(data);
@@ -520,6 +548,7 @@ static int push_promise(struct Curl_easy *data,
if(rv) {
/* denied, kill off the new handle again */
http2_stream_free(newhandle->req.protop);
+ newhandle->req.protop = NULL;
(void)Curl_close(newhandle);
goto fail;
}
@@ -535,14 +564,22 @@ static int push_promise(struct Curl_easy *data,
if(rc) {
infof(data, "failed to add handle to multi\n");
http2_stream_free(newhandle->req.protop);
+ newhandle->req.protop = NULL;
Curl_close(newhandle);
rv = 1;
goto fail;
}
httpc = &conn->proto.httpc;
- nghttp2_session_set_stream_user_data(httpc->h2,
- frame->promised_stream_id, newhandle);
+ rv = nghttp2_session_set_stream_user_data(httpc->h2,
+ frame->promised_stream_id,
+ newhandle);
+ if(rv) {
+ infof(data, "failed to set user_data for stream %d\n",
+ frame->promised_stream_id);
+ DEBUGASSERT(0);
+ goto fail;
+ }
}
else {
H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
@@ -581,7 +618,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
if(max_conn != httpc->settings.max_concurrent_streams) {
/* only signal change if the value actually changed */
infof(conn->data,
- "Connection state changed (MAX_CONCURRENT_STREAMS == %d)!\n",
+ "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n",
httpc->settings.max_concurrent_streams);
Curl_multi_connchanged(conn->data->multi);
}
@@ -640,7 +677,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
- ncopy = MIN(stream->len, left);
+ ncopy = CURLMIN(stream->len, left);
memcpy(&stream->mem[stream->memlen],
stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
@@ -653,8 +690,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
stream->len -= ncopy;
stream->memlen += ncopy;
- data_s->state.drain++;
- httpc->drain_total++;
+ drain_this(data_s, httpc);
{
/* get the pointer from userp again since it was re-assigned above */
struct connectdata *conn_s = (struct connectdata *)userp;
@@ -683,25 +719,6 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
return 0;
}
-static int on_invalid_frame_recv(nghttp2_session *session,
- const nghttp2_frame *frame,
- int lib_error_code, void *userp)
-{
- struct Curl_easy *data_s = NULL;
- (void)userp;
-#if !defined(DEBUG_HTTP2) || defined(CURL_DISABLE_VERBOSE_STRINGS)
- (void)lib_error_code;
-#endif
-
- data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
- if(data_s) {
- H2BUGF(infof(data_s,
- "on_invalid_frame_recv() was called, error=%d:%s\n",
- lib_error_code, nghttp2_strerror(lib_error_code)));
- }
- return 0;
-}
-
static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const uint8_t *data, size_t len, void *userp)
@@ -727,14 +744,13 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
if(!stream)
return NGHTTP2_ERR_CALLBACK_FAILURE;
- nread = MIN(stream->len, len);
+ nread = CURLMIN(stream->len, len);
memcpy(&stream->mem[stream->memlen], data, nread);
stream->len -= nread;
stream->memlen += nread;
- data_s->state.drain++;
- conn->proto.httpc.drain_total++;
+ drain_this(data_s, &conn->proto.httpc);
/* if we receive data for another handle, wake that up */
if(conn->data != data_s)
@@ -768,58 +784,13 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
return 0;
}
-static int before_frame_send(nghttp2_session *session,
- const nghttp2_frame *frame,
- void *userp)
-{
- struct Curl_easy *data_s;
- (void)userp;
-
- data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
- if(data_s) {
- H2BUGF(infof(data_s, "before_frame_send() was called\n"));
- }
-
- return 0;
-}
-static int on_frame_send(nghttp2_session *session,
- const nghttp2_frame *frame,
- void *userp)
-{
- struct Curl_easy *data_s;
- (void)userp;
-
- data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
- if(data_s) {
- H2BUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
- frame->hd.length));
- }
- return 0;
-}
-static int on_frame_not_send(nghttp2_session *session,
- const nghttp2_frame *frame,
- int lib_error_code, void *userp)
-{
- struct Curl_easy *data_s;
- (void)userp;
-#if !defined(DEBUG_HTTP2) || defined(CURL_DISABLE_VERBOSE_STRINGS)
- (void)lib_error_code;
-#endif
-
- data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
- if(data_s) {
- H2BUGF(infof(data_s,
- "on_frame_not_send() was called, lib_error_code = %d\n",
- lib_error_code));
- }
- return 0;
-}
static int on_stream_close(nghttp2_session *session, int32_t stream_id,
uint32_t error_code, void *userp)
{
struct Curl_easy *data_s;
struct HTTP *stream;
struct connectdata *conn = (struct connectdata *)userp;
+ int rv;
(void)session;
(void)stream_id;
@@ -840,14 +811,19 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
return NGHTTP2_ERR_CALLBACK_FAILURE;
stream->closed = TRUE;
- data_s->state.drain++;
httpc = &conn->proto.httpc;
- httpc->drain_total++;
+ drain_this(data_s, httpc);
httpc->error_code = error_code;
/* remove the entry from the hash as the stream is now gone */
- nghttp2_session_set_stream_user_data(session, stream_id, 0);
+ rv = nghttp2_session_set_stream_user_data(session, stream_id, 0);
+ if(rv) {
+ infof(data_s, "http/2: failed to clear user_data for stream %d!\n",
+ stream_id);
+ DEBUGASSERT(0);
+ }
H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
+ stream->stream_id = 0; /* cleared */
}
return 0;
}
@@ -1052,7 +1028,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
else
return NGHTTP2_ERR_INVALID_ARGUMENT;
- nread = MIN(stream->upload_len, length);
+ nread = CURLMIN(stream->upload_len, length);
if(nread > 0) {
memcpy(buf, stream->upload_mem, nread);
stream->upload_mem += nread;
@@ -1109,6 +1085,12 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
struct HTTP *http = data->req.protop;
struct http_conn *httpc = &conn->proto.httpc;
+ if(!httpc->h2) /* not HTTP/2 ? */
+ return;
+
+ if(data->state.drain)
+ drained_transfer(data, httpc);
+
if(http->header_recvbuf) {
Curl_add_buffer_free(http->header_recvbuf);
http->header_recvbuf = NULL; /* clear the pointer */
@@ -1126,15 +1108,24 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
if(premature) {
/* RST_STREAM */
- nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, http->stream_id,
- NGHTTP2_STREAM_CLOSED);
+ if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE,
+ http->stream_id, NGHTTP2_STREAM_CLOSED))
+ (void)nghttp2_session_send(httpc->h2);
+
if(http->stream_id == httpc->pause_stream_id) {
infof(data, "stopped the pause stream!\n");
httpc->pause_stream_id = 0;
}
}
- if(http->stream_id) {
- nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
+ /* -1 means unassigned and 0 means cleared */
+ if(http->stream_id > 0) {
+ int rv = nghttp2_session_set_stream_user_data(httpc->h2,
+ http->stream_id, 0);
+ if(rv) {
+ infof(data, "http/2: failed to clear user_data for stream %d!\n",
+ http->stream_id);
+ DEBUGASSERT(0);
+ }
http->stream_id = 0;
}
}
@@ -1164,21 +1155,9 @@ CURLcode Curl_http2_init(struct connectdata *conn)
/* nghttp2_on_frame_recv_callback */
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv);
- /* nghttp2_on_invalid_frame_recv_callback */
- nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
- (callbacks, on_invalid_frame_recv);
/* nghttp2_on_data_chunk_recv_callback */
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv);
- /* nghttp2_before_frame_send_callback */
- nghttp2_session_callbacks_set_before_frame_send_callback
- (callbacks, before_frame_send);
- /* nghttp2_on_frame_send_callback */
- nghttp2_session_callbacks_set_on_frame_send_callback
- (callbacks, on_frame_send);
- /* nghttp2_on_frame_not_send_callback */
- nghttp2_session_callbacks_set_on_frame_not_send_callback
- (callbacks, on_frame_not_send);
/* nghttp2_on_stream_close_callback */
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close);
@@ -1280,7 +1259,7 @@ static int h2_process_pending_input(struct connectdata *conn,
if(rv < 0) {
failf(data,
"h2_process_pending_input: nghttp2_session_mem_recv() returned "
- "%d:%s\n", rv, nghttp2_strerror((int)rv));
+ "%zd:%s\n", rv, nghttp2_strerror((int)rv));
*err = CURLE_RECV_ERROR;
return -1;
}
@@ -1352,7 +1331,6 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
return result;
}
-
static ssize_t http2_handle_stream_close(struct connectdata *conn,
struct Curl_easy *data,
struct HTTP *stream, CURLcode *err)
@@ -1365,9 +1343,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
httpc->pause_stream_id = 0;
}
- DEBUGASSERT(httpc->drain_total >= data->state.drain);
- httpc->drain_total -= data->state.drain;
- data->state.drain = 0;
+ drained_transfer(data, httpc);
if(httpc->pause_stream_id == 0) {
if(h2_process_pending_input(conn, httpc, err) != 0) {
@@ -1388,7 +1364,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
return -1;
}
else if(httpc->error_code != NGHTTP2_NO_ERROR) {
- failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
+ failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
stream->stream_id, Curl_http2_strerror(httpc->error_code),
httpc->error_code);
*err = CURLE_HTTP2_STREAM;
@@ -1396,7 +1372,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
}
if(!stream->bodystarted) {
- failf(data, "HTTP/2 stream %u was closed cleanly, but before getting "
+ failf(data, "HTTP/2 stream %d was closed cleanly, but before getting "
" all response header fields, treated as error",
stream->stream_id);
*err = CURLE_HTTP2_STREAM;
@@ -1510,7 +1486,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
/* If there is body data pending for this stream to return, do that */
size_t left =
stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
- size_t ncopy = MIN(len, left);
+ size_t ncopy = CURLMIN(len, left);
memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
ncopy);
stream->nread_header_recvbuf += ncopy;
@@ -1546,13 +1522,13 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
}
else if(stream->pausedata) {
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
- nread = MIN(len, stream->pauselen);
+ nread = CURLMIN(len, stream->pauselen);
memcpy(mem, stream->pausedata, nread);
stream->pausedata += nread;
stream->pauselen -= nread;
- infof(data, "%zu data bytes written\n", nread);
+ infof(data, "%zd data bytes written\n", nread);
if(stream->pauselen == 0) {
H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
@@ -1635,7 +1611,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
if(nghttp2_is_fatal((int)rv)) {
- failf(data, "nghttp2_session_mem_recv() returned %d:%s\n",
+ failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n",
rv, nghttp2_strerror((int)rv));
*err = CURLE_RECV_ERROR;
return -1;
@@ -1678,9 +1654,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
stream->stream_id));
}
else if(!stream->closed) {
- DEBUGASSERT(httpc->drain_total >= data->state.drain);
- httpc->drain_total -= data->state.drain;
- data->state.drain = 0; /* this stream is hereby drained */
+ drained_transfer(data, httpc);
}
return retlen;
@@ -2040,7 +2014,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
}
infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
- stream_id, conn->data);
+ stream_id, (void *)conn->data);
stream->stream_id = stream_id;
/* this does not call h2_session_send() since there can not have been any
@@ -2154,9 +2128,14 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
return CURLE_HTTP2;
}
- nghttp2_session_set_stream_user_data(httpc->h2,
- stream->stream_id,
- conn->data);
+ rv = nghttp2_session_set_stream_user_data(httpc->h2,
+ stream->stream_id,
+ data);
+ if(rv) {
+ infof(data, "http/2: failed to set user_data for stream %d!\n",
+ stream->stream_id);
+ DEBUGASSERT(0);
+ }
}
else {
populate_settings(conn, httpc);
diff --git a/Utilities/cmcurl/lib/http2.h b/Utilities/cmcurl/lib/http2.h
index f597c805e5..21cd9b848c 100644
--- a/Utilities/cmcurl/lib/http2.h
+++ b/Utilities/cmcurl/lib/http2.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
@@ -65,7 +65,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
-#define Curl_http2_setup_conn(x)
+#define Curl_http2_setup_conn(x) Curl_nop_stmt
#define Curl_http2_setup_req(x)
#define Curl_http2_init_state(x)
#define Curl_http2_init_userset(x)
diff --git a/Utilities/cmcurl/lib/http_ntlm.c b/Utilities/cmcurl/lib/http_ntlm.c
index fd5540b5d0..a9b33f98e4 100644
--- a/Utilities/cmcurl/lib/http_ntlm.c
+++ b/Utilities/cmcurl/lib/http_ntlm.c
@@ -228,7 +228,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
/* connection is already authenticated,
* don't send a header in future requests */
ntlm->state = NTLMSTATE_LAST;
- /* fall-through */
+ /* FALLTHROUGH */
case NTLMSTATE_LAST:
Curl_safefree(*allocuserpwd);
authp->done = TRUE;
diff --git a/Utilities/cmcurl/lib/http_proxy.c b/Utilities/cmcurl/lib/http_proxy.c
index e10a488294..c8c445b821 100644
--- a/Utilities/cmcurl/lib/http_proxy.c
+++ b/Utilities/cmcurl/lib/http_proxy.c
@@ -188,12 +188,10 @@ static CURLcode CONNECT(struct connectdata *conn,
struct SingleRequest *k = &data->req;
CURLcode result;
curl_socket_t tunnelsocket = conn->sock[sockindex];
- timediff_t check;
struct http_connect_state *s = conn->connect_state;
#define SELECT_OK 0
#define SELECT_ERROR 1
-#define SELECT_TIMEOUT 2
if(Curl_connect_complete(conn))
return CURLE_OK; /* CONNECT is already completed */
@@ -201,12 +199,13 @@ static CURLcode CONNECT(struct connectdata *conn,
conn->bits.proxy_connect_closed = FALSE;
do {
+ timediff_t check;
if(TUNNEL_INIT == s->tunnel_state) {
/* BEGIN CONNECT PHASE */
char *host_port;
Curl_send_buffer *req_buffer;
- infof(data, "Establish HTTP proxy tunnel to %s:%hu\n",
+ infof(data, "Establish HTTP proxy tunnel to %s:%d\n",
hostname, remote_port);
/* This only happens if we've looped here due to authentication
@@ -419,7 +418,7 @@ static CURLcode CONNECT(struct connectdata *conn,
/* output debug if that is requested */
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
- s->line_start, (size_t)s->perline, conn);
+ s->line_start, (size_t)s->perline);
if(!data->set.suppress_connect_headers) {
/* send the header to the callback */
diff --git a/Utilities/cmcurl/lib/imap.c b/Utilities/cmcurl/lib/imap.c
index cf278a22ba..942fe7d1ef 100644
--- a/Utilities/cmcurl/lib/imap.c
+++ b/Utilities/cmcurl/lib/imap.c
@@ -609,7 +609,6 @@ static CURLcode imap_perform_list(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
struct IMAP *imap = data->req.protop;
- char *mailbox;
if(imap->custom)
/* Send the custom request */
@@ -617,7 +616,8 @@ static CURLcode imap_perform_list(struct connectdata *conn)
imap->custom_params ? imap->custom_params : "");
else {
/* Make sure the mailbox is in the correct atom format if necessary */
- mailbox = imap->mailbox ? imap_atom(imap->mailbox, true) : strdup("");
+ char *mailbox = imap->mailbox ? imap_atom(imap->mailbox, true)
+ : strdup("");
if(!mailbox)
return CURLE_OUT_OF_MEMORY;
@@ -854,7 +854,6 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct imap_conn *imapc = &conn->proto.imapc;
const char *line = data->state.buffer;
- size_t wordlen;
(void)instate; /* no use for this yet */
@@ -864,6 +863,7 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
/* Loop through the data line */
for(;;) {
+ size_t wordlen;
while(*line &&
(*line == ' ' || *line == '\t' ||
*line == '\r' || *line == '\n')) {
@@ -1046,12 +1046,12 @@ static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
struct IMAP *imap = conn->data->req.protop;
struct imap_conn *imapc = &conn->proto.imapc;
const char *line = data->state.buffer;
- char tmp[20];
(void)instate; /* no use for this yet */
if(imapcode == '*') {
/* See if this is an UIDVALIDITY response */
+ char tmp[20];
if(sscanf(line + 2, "OK [UIDVALIDITY %19[0123456789]]", tmp) == 1) {
Curl_safefree(imapc->mailbox_uidvalidity);
imapc->mailbox_uidvalidity = strdup(tmp);
@@ -1119,7 +1119,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
}
if(parsed) {
- infof(data, "Found %" CURL_FORMAT_CURL_OFF_TU " bytes to download\n",
+ infof(data, "Found %" CURL_FORMAT_CURL_OFF_T " bytes to download\n",
size);
Curl_pgrsSetDownloadSize(data, size);
@@ -1144,10 +1144,8 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
data->req.bytecount += chunk;
- infof(data, "Written %" CURL_FORMAT_CURL_OFF_TU
- " bytes, %" CURL_FORMAT_CURL_OFF_TU
- " bytes are left for transfer\n", (curl_off_t)chunk,
- size - chunk);
+ infof(data, "Written %zu bytes, %" CURL_FORMAT_CURL_OFF_TU
+ " bytes are left for transfer\n", chunk, size - chunk);
/* Have we used the entire cache or just part of it?*/
if(pp->cache_size > chunk) {
diff --git a/Utilities/cmcurl/lib/inet_ntop.c b/Utilities/cmcurl/lib/inet_ntop.c
index fb91a505db..ac5d2d4d6f 100644
--- a/Utilities/cmcurl/lib/inet_ntop.c
+++ b/Utilities/cmcurl/lib/inet_ntop.c
@@ -49,7 +49,7 @@
*/
static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
{
- char tmp[sizeof "255.255.255.255"];
+ char tmp[sizeof("255.255.255.255")];
size_t len;
DEBUGASSERT(size >= 16);
diff --git a/Utilities/cmcurl/lib/ldap.c b/Utilities/cmcurl/lib/ldap.c
index 89047bcbda..4d8f4fa288 100644
--- a/Utilities/cmcurl/lib/ldap.c
+++ b/Utilities/cmcurl/lib/ldap.c
@@ -54,15 +54,6 @@
# endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */
#endif
-/* These are macros in both <wincrypt.h> (in above <winldap.h>) and typedefs
- * in BoringSSL's <openssl/x509.h>
- */
-#ifdef HAVE_BORINGSSL
-# undef X509_NAME
-# undef X509_CERT_PAIR
-# undef X509_EXTENSIONS
-#endif
-
#include "urldata.h"
#include <curl/curl.h>
#include "sendf.h"
diff --git a/Utilities/cmcurl/lib/md5.c b/Utilities/cmcurl/lib/md5.c
index 3096602b7e..b819d39240 100644
--- a/Utilities/cmcurl/lib/md5.c
+++ b/Utilities/cmcurl/lib/md5.c
@@ -484,29 +484,35 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
#endif /* CRYPTO LIBS */
-/* Disable this picky gcc-8 compiler warning */
-#if defined(__GNUC__) && (__GNUC__ >= 8)
-#pragma GCC diagnostic ignored "-Wcast-function-type"
-#endif
-
const HMAC_params Curl_HMAC_MD5[] = {
{
- (HMAC_hinit_func) MD5_Init, /* Hash initialization function. */
- (HMAC_hupdate_func) MD5_Update, /* Hash update function. */
- (HMAC_hfinal_func) MD5_Final, /* Hash computation end function. */
- sizeof(MD5_CTX), /* Size of hash context structure. */
- 64, /* Maximum key length. */
- 16 /* Result size. */
+ /* Hash initialization function. */
+ CURLX_FUNCTION_CAST(HMAC_hinit_func, MD5_Init),
+ /* Hash update function. */
+ CURLX_FUNCTION_CAST(HMAC_hupdate_func, MD5_Update),
+ /* Hash computation end function. */
+ CURLX_FUNCTION_CAST(HMAC_hfinal_func, MD5_Final),
+ /* Size of hash context structure. */
+ sizeof(MD5_CTX),
+ /* Maximum key length. */
+ 64,
+ /* Result size. */
+ 16
}
};
const MD5_params Curl_DIGEST_MD5[] = {
{
- (Curl_MD5_init_func) MD5_Init, /* Digest initialization function */
- (Curl_MD5_update_func) MD5_Update, /* Digest update function */
- (Curl_MD5_final_func) MD5_Final, /* Digest computation end function */
- sizeof(MD5_CTX), /* Size of digest context struct */
- 16 /* Result size */
+ /* Digest initialization function */
+ CURLX_FUNCTION_CAST(Curl_MD5_init_func, MD5_Init),
+ /* Digest update function */
+ CURLX_FUNCTION_CAST(Curl_MD5_update_func, MD5_Update),
+ /* Digest computation end function */
+ CURLX_FUNCTION_CAST(Curl_MD5_final_func, MD5_Final),
+ /* Size of digest context struct */
+ sizeof(MD5_CTX),
+ /* Result size */
+ 16
}
};
@@ -527,7 +533,7 @@ MD5_context *Curl_MD5_init(const MD5_params *md5params)
MD5_context *ctxt;
/* Create MD5 context */
- ctxt = malloc(sizeof *ctxt);
+ ctxt = malloc(sizeof(*ctxt));
if(!ctxt)
return ctxt;
diff --git a/Utilities/cmcurl/lib/memdebug.h b/Utilities/cmcurl/lib/memdebug.h
index 6fb8b68511..233de65a47 100644
--- a/Utilities/cmcurl/lib/memdebug.h
+++ b/Utilities/cmcurl/lib/memdebug.h
@@ -8,7 +8,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
@@ -137,13 +137,6 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
#endif
#endif /* HAVE_GETADDRINFO */
-#ifdef HAVE_GETNAMEINFO
-#undef getnameinfo
-#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
- curl_dogetnameinfo(sa, salen, host, hostlen, serv, servlen, flags, \
- __LINE__, __FILE__)
-#endif /* HAVE_GETNAMEINFO */
-
#ifdef HAVE_FREEADDRINFO
#undef freeaddrinfo
#define freeaddrinfo(data) \
diff --git a/Utilities/cmcurl/lib/mime.c b/Utilities/cmcurl/lib/mime.c
index 4c0d2eebab..ca492d11ae 100644
--- a/Utilities/cmcurl/lib/mime.c
+++ b/Utilities/cmcurl/lib/mime.c
@@ -505,9 +505,6 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
mime_encoder_state *st = &part->encstate;
char *ptr = buffer;
size_t cursize = 0;
- int i;
- size_t len;
- size_t consumed;
int softlinebreak;
char buf[4];
@@ -516,9 +513,9 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
character constants that can be interpreted as non-ascii on some
platforms. Preserve ASCII encoding on output too. */
while(st->bufbeg < st->bufend) {
- len = 1;
- consumed = 1;
- i = st->buf[st->bufbeg];
+ size_t len = 1;
+ size_t consumed = 1;
+ int i = st->buf[st->bufbeg];
buf[0] = (char) i;
buf[1] = aschex[(i >> 4) & 0xF];
buf[2] = aschex[i & 0xF];
@@ -787,10 +784,10 @@ static size_t read_encoded_part_content(curl_mimepart *part,
st->bufbeg = 0;
st->bufend = len;
}
- if(st->bufend >= sizeof st->buf)
+ if(st->bufend >= sizeof(st->buf))
return cursize? cursize: READ_ERROR; /* Buffer full. */
sz = read_part_content(part, st->buf + st->bufend,
- sizeof st->buf - st->bufend);
+ sizeof(st->buf) - st->bufend);
switch(sz) {
case 0:
ateof = TRUE;
@@ -813,8 +810,6 @@ static size_t readback_part(curl_mimepart *part,
char *buffer, size_t bufsize)
{
size_t cursize = 0;
- size_t sz;
- struct curl_slist *hdr;
#ifdef CURL_DOES_CONVERSIONS
char *convbuf = buffer;
#endif
@@ -822,8 +817,8 @@ static size_t readback_part(curl_mimepart *part,
/* Readback from part. */
while(bufsize) {
- sz = 0;
- hdr = (struct curl_slist *) part->state.ptr;
+ size_t sz = 0;
+ struct curl_slist *hdr = (struct curl_slist *) part->state.ptr;
switch(part->state.state) {
case MIMESTATE_BEGIN:
mimesetstate(&part->state, part->flags & MIME_BODY_ONLY? MIMESTATE_BODY:
@@ -918,8 +913,6 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
{
curl_mime *mime = (curl_mime *) instream;
size_t cursize = 0;
- size_t sz;
- curl_mimepart *part;
#ifdef CURL_DOES_CONVERSIONS
char *convbuf = buffer;
#endif
@@ -927,8 +920,8 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
(void) size; /* Always 1. */
while(nitems) {
- sz = 0;
- part = mime->state.ptr;
+ size_t sz = 0;
+ curl_mimepart *part = mime->state.ptr;
switch(mime->state.state) {
case MIMESTATE_BEGIN:
case MIMESTATE_BODY:
@@ -1044,7 +1037,6 @@ static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
curl_mime *mime = (curl_mime *) instream;
curl_mimepart *part;
int result = CURL_SEEKFUNC_OK;
- int res;
if(whence != SEEK_SET || offset)
return CURL_SEEKFUNC_CANTSEEK; /* Only support full rewind. */
@@ -1053,7 +1045,7 @@ static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
return CURL_SEEKFUNC_OK; /* Already rewound. */
for(part = mime->firstpart; part; part = part->nextpart) {
- res = mime_part_rewind(part);
+ int res = mime_part_rewind(part);
if(res != CURL_SEEKFUNC_OK)
result = res;
}
@@ -1220,7 +1212,7 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
{
curl_mime *mime;
- mime = (curl_mime *) malloc(sizeof *mime);
+ mime = (curl_mime *) malloc(sizeof(*mime));
if(mime) {
mime->easy = easy;
@@ -1236,8 +1228,13 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
}
memset(mime->boundary, '-', 24);
- Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24,
- MIME_RAND_BOUNDARY_CHARS + 1);
+ if(Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24,
+ MIME_RAND_BOUNDARY_CHARS + 1)) {
+ /* failed to get random separator, bail out */
+ free(mime->boundary);
+ free(mime);
+ return NULL;
+ }
mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL);
}
@@ -1247,7 +1244,7 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
/* Initialize a mime part. */
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
{
- memset((char *) part, 0, sizeof *part);
+ memset((char *) part, 0, sizeof(*part));
part->easy = easy;
mimesetstate(&part->state, MIMESTATE_BEGIN, NULL);
}
@@ -1260,7 +1257,7 @@ curl_mimepart *curl_mime_addpart(curl_mime *mime)
if(!mime)
return NULL;
- part = (curl_mimepart *) malloc(sizeof *part);
+ part = (curl_mimepart *) malloc(sizeof(*part));
if(part) {
Curl_mime_initpart(part, mime->easy);
@@ -1349,7 +1346,6 @@ CURLcode curl_mime_data(curl_mimepart *part,
CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
{
CURLcode result = CURLE_OK;
- char *base;
if(!part)
return CURLE_BAD_FUNCTION_ARGUMENT;
@@ -1357,6 +1353,7 @@ CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
cleanup_part_content(part);
if(filename) {
+ char *base;
struct_stat sbuf;
if(stat(filename, &sbuf) || access(filename, R_OK))
@@ -1564,7 +1561,6 @@ static size_t slist_size(struct curl_slist *s,
static curl_off_t multipart_size(curl_mime *mime)
{
curl_off_t size;
- curl_off_t sz;
size_t boundarysize;
curl_mimepart *part;
@@ -1575,7 +1571,7 @@ static curl_off_t multipart_size(curl_mime *mime)
size = boundarysize; /* Final boundary - CRLF after headers. */
for(part = mime->firstpart; part; part = part->nextpart) {
- sz = Curl_mime_size(part);
+ curl_off_t sz = Curl_mime_size(part);
if(sz < 0)
size = sz;
@@ -1643,8 +1639,6 @@ static CURLcode add_content_type(struct curl_slist **slp,
const char *Curl_mime_contenttype(const char *filename)
{
- unsigned int i;
-
/*
* If no content type was specified, we scan through a few well-known
* extensions and pick the first we match!
@@ -1669,8 +1663,9 @@ const char *Curl_mime_contenttype(const char *filename)
if(filename) {
size_t len1 = strlen(filename);
const char *nameend = filename + len1;
+ unsigned int i;
- for(i = 0; i < sizeof ctts / sizeof ctts[0]; i++) {
+ for(i = 0; i < sizeof(ctts) / sizeof(ctts[0]); i++) {
size_t len2 = strlen(ctts[i].extension);
if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension))
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
index f852846952..0caf94322b 100644
--- a/Utilities/cmcurl/lib/multi.c
+++ b/Utilities/cmcurl/lib/multi.c
@@ -31,6 +31,7 @@
#include "progress.h"
#include "easyif.h"
#include "share.h"
+#include "psl.h"
#include "multiif.h"
#include "sendf.h"
#include "timeval.h"
@@ -68,8 +69,8 @@
#define GOOD_MULTI_HANDLE(x) \
((x) && (x)->type == CURL_MULTI_HANDLE)
-static void singlesocket(struct Curl_multi *multi,
- struct Curl_easy *data);
+static CURLMcode singlesocket(struct Curl_multi *multi,
+ struct Curl_easy *data);
static int update_timer(struct Curl_multi *multi);
static CURLMcode add_next_timeout(struct curltime now,
@@ -106,6 +107,16 @@ static const char * const statename[]={
/* function pointer called once when switching TO a state */
typedef void (*init_multistate_func)(struct Curl_easy *data);
+static void Curl_init_completed(struct Curl_easy *data)
+{
+ /* this is a completed transfer */
+
+ /* Important: reset the conn pointer so that we don't point to memory
+ that could be freed anytime */
+ data->easy_conn = NULL;
+ Curl_expire_clear(data); /* stop all timers */
+}
+
/* always use this function to change state, to make debugging easier */
static void mstate(struct Curl_easy *data, CURLMstate state
#ifdef DEBUGBUILD
@@ -115,17 +126,25 @@ static void mstate(struct Curl_easy *data, CURLMstate state
{
CURLMstate oldstate = data->mstate;
static const init_multistate_func finit[CURLM_STATE_LAST] = {
- NULL,
- NULL,
+ NULL, /* INIT */
+ NULL, /* CONNECT_PEND */
Curl_init_CONNECT, /* CONNECT */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- Curl_connect_free /* DO */
- /* the rest is NULL too */
+ NULL, /* WAITRESOLVE */
+ NULL, /* WAITCONNECT */
+ NULL, /* WAITPROXYCONNECT */
+ NULL, /* SENDPROTOCONNECT */
+ NULL, /* PROTOCONNECT */
+ NULL, /* WAITDO */
+ Curl_connect_free, /* DO */
+ NULL, /* DOING */
+ NULL, /* DO_MORE */
+ NULL, /* DO_DONE */
+ NULL, /* WAITPERFORM */
+ NULL, /* PERFORM */
+ NULL, /* TOOFAST */
+ NULL, /* DONE */
+ Curl_init_completed, /* COMPLETED */
+ NULL /* MSGSENT */
};
#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -409,6 +428,14 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
else
data->state.conn_cache = &multi->conn_cache;
+#ifdef USE_LIBPSL
+ /* Do the same for PSL. */
+ if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL)))
+ data->psl = &data->share->psl;
+ else
+ data->psl = &multi->psl;
+#endif
+
/* This adds the new entry at the 'end' of the doubly-linked circular
list of Curl_easy structs to try and maintain a FIFO queue so
the pipelined requests are in order. */
@@ -449,7 +476,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
happens if the lastcall time is set to the same time when the handle is
removed as when the next handle is added, as then the check in
update_timer() that prevents calling the application multiple times with
- the same timer infor will not trigger and then the new handle's timeout
+ the same timer info will not trigger and then the new handle's timeout
will not be notified to the app.
The work-around is thus simply to clear the 'lastcall' variable to force
@@ -506,6 +533,11 @@ static CURLcode multi_done(struct connectdata **connp,
/* Stop if multi_done() has already been called */
return CURLE_OK;
+ if(data->mstate == CURLM_STATE_WAITRESOLVE) {
+ /* still waiting for the resolve to complete */
+ (void)Curl_resolver_wait_resolv(conn, NULL);
+ }
+
Curl_getoff_all_pipelines(data, conn);
/* Cleanup possible redirect junk */
@@ -546,7 +578,7 @@ static CURLcode multi_done(struct connectdata **connp,
if(conn->send_pipe.size || conn->recv_pipe.size) {
/* Stop if pipeline is not empty . */
data->easy_conn = NULL;
- DEBUGF(infof(data, "Connection still in use %d/%d, "
+ DEBUGF(infof(data, "Connection still in use %zu/%zu, "
"no more multi_done now!\n",
conn->send_pipe.size, conn->recv_pipe.size));
return CURLE_OK;
@@ -560,6 +592,7 @@ static CURLcode multi_done(struct connectdata **connp,
conn->dns_entry = NULL;
}
Curl_hostcache_prune(data);
+ Curl_safefree(data->state.ulbuf);
/* if the transfer was completed in a paused state there can be buffered
data left to free */
@@ -590,7 +623,7 @@ static CURLcode multi_done(struct connectdata **connp,
#endif
) || conn->bits.close
|| (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
- CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
+ CURLcode res2 = Curl_disconnect(data, conn, premature);
/* If we had an error already, make sure we return that one. But
if we got a new error, return that. */
@@ -608,7 +641,7 @@ static CURLcode multi_done(struct connectdata **connp,
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname);
- /* the connection is no longer in use */
+ /* the connection is no longer in use by this transfer */
if(Curl_conncache_return_conn(conn)) {
/* remember the most recently used connection */
data->state.lastconnect = conn;
@@ -698,6 +731,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
Curl_getoff_all_pipelines(data, data->easy_conn);
}
+ if(data->connect_queue.ptr)
+ /* the handle was in the pending list waiting for an available connection,
+ so go ahead and remove it */
+ Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
+
if(data->dns.hostcachetype == HCACHE_MULTI) {
/* stop using the multi handle's DNS cache, *after* the possible
multi_done() call above */
@@ -727,6 +765,12 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
data->easy_conn = NULL;
}
+#ifdef USE_LIBPSL
+ /* Remove the PSL association. */
+ if(data->psl == &multi->psl)
+ data->psl = NULL;
+#endif
+
data->multi = NULL; /* clear the association to this multi handle */
/* make sure there's no pending message in the queue sent from this easy
@@ -831,12 +875,10 @@ static int multi_getsock(struct Curl_easy *data,
of sockets */
int numsocks)
{
- /* If the pipe broke, or if there's no connection left for this easy handle,
- then we MUST bail out now with no bitmask set. The no connection case can
- happen when this is called from curl_multi_remove_handle() =>
- singlesocket() => multi_getsock().
+ /* The no connection case can happen when this is called from
+ curl_multi_remove_handle() => singlesocket() => multi_getsock().
*/
- if(data->state.pipe_broke || !data->easy_conn)
+ if(!data->easy_conn)
return 0;
if(data->mstate > CURLM_STATE_CONNECT &&
@@ -902,7 +944,6 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
struct Curl_easy *data;
int this_max_fd = -1;
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
- int bitmap;
int i;
(void)exc_fd_set; /* not used */
@@ -914,7 +955,7 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
data = multi->easyp;
while(data) {
- bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+ int bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
curl_socket_t s = CURL_SOCKET_BAD;
@@ -1068,8 +1109,6 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
int pollrc;
/* wait... */
pollrc = Curl_poll(ufds, nfds, timeout_ms);
- DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n",
- nfds, timeout_ms, pollrc));
if(pollrc > 0) {
retcode = pollrc;
@@ -1312,24 +1351,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
bool stream_error = FALSE;
rc = CURLM_OK;
- /* Handle the case when the pipe breaks, i.e., the connection
- we're using gets cleaned up and we're left with nothing. */
- if(data->state.pipe_broke) {
- infof(data, "Pipe broke: handle %p, url = %s\n",
- (void *)data, data->state.path);
-
- if(data->mstate < CURLM_STATE_COMPLETED) {
- /* Head back to the CONNECT state */
- multistate(data, CURLM_STATE_CONNECT);
- rc = CURLM_CALL_MULTI_PERFORM;
- result = CURLE_OK;
- }
-
- data->state.pipe_broke = FALSE;
- data->easy_conn = NULL;
- continue;
- }
-
if(!data->easy_conn &&
data->mstate > CURLM_STATE_CONNECT &&
data->mstate < CURLM_STATE_DONE) {
@@ -1555,6 +1576,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multistate(data, CURLM_STATE_SENDPROTOCONNECT);
}
}
+ else if(result)
+ stream_error = TRUE;
break;
#endif
@@ -1909,6 +1932,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
if(!ret)
retry = (newurl)?TRUE:FALSE;
+ else if(!result)
+ result = ret;
if(retry) {
/* if we are to retry, set the result to OK and consider the
@@ -2040,16 +2065,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
break;
case CURLM_STATE_COMPLETED:
- /* this is a completed transfer, it is likely to still be connected */
-
- /* This node should be delinked from the list now and we should post
- an information message that we are complete. */
-
- /* Important: reset the conn pointer so that we don't point to memory
- that could be freed anytime */
- data->easy_conn = NULL;
-
- Curl_expire_clear(data); /* stop all timers */
break;
case CURLM_STATE_MSGSENT:
@@ -2071,8 +2086,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* NOTE: no attempt to disconnect connections must be made
in the case blocks above - cleanup happens only here */
- data->state.pipe_broke = FALSE;
-
/* Check if we can move pending requests to send pipe */
process_pending_handles(multi); /* connection */
@@ -2087,7 +2100,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* Don't attempt to send data over a connection that timed out */
bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
/* disconnect properly */
- Curl_disconnect(data->easy_conn, dead_connection);
+ Curl_disconnect(data, data->easy_conn, dead_connection);
/* This is where we make sure that the easy_conn pointer is reset.
We don't have to do this in every case block above where a
@@ -2101,6 +2114,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
multistate(data, CURLM_STATE_COMPLETED);
+ rc = CURLM_CALL_MULTI_PERFORM;
}
/* if there's still a connection to use, call the progress function */
else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
@@ -2125,14 +2139,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
msg->extmsg.data.result = result;
rc = multi_addmsg(multi, msg);
-
+ DEBUGASSERT(!data->easy_conn);
multistate(data, CURLM_STATE_MSGSENT);
}
} while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
data->result = result;
-
-
return rc;
}
@@ -2220,6 +2232,11 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
data->state.conn_cache = NULL;
data->multi = NULL; /* clear the association */
+#ifdef USE_LIBPSL
+ if(data->psl == &multi->psl)
+ data->psl = NULL;
+#endif
+
data = nextdata;
}
@@ -2232,6 +2249,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
Curl_llist_destroy(&multi->pending, NULL);
Curl_hash_destroy(&multi->hostcache);
+ Curl_psl_destroy(&multi->psl);
/* Free the blacklists by setting them to NULL */
Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
@@ -2286,8 +2304,8 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
* and if we have a different state in any of those sockets from last time we
* call the callback accordingly.
*/
-static void singlesocket(struct Curl_multi *multi,
- struct Curl_easy *data)
+static CURLMcode singlesocket(struct Curl_multi *multi,
+ struct Curl_easy *data)
{
curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
int i;
@@ -2334,7 +2352,7 @@ static void singlesocket(struct Curl_multi *multi,
entry = sh_addentry(&multi->sockhash, s, data);
if(!entry)
/* fatal */
- return;
+ return CURLM_OUT_OF_MEMORY;
}
/* we know (entry != NULL) at this point, see the logic above */
@@ -2422,6 +2440,7 @@ static void singlesocket(struct Curl_multi *multi,
memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
data->numsocks = num;
+ return CURLM_OK;
}
void Curl_updatesocket(struct Curl_easy *data)
@@ -2442,20 +2461,23 @@ void Curl_updatesocket(struct Curl_easy *data)
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
{
- struct Curl_multi *multi = conn->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 */
- struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
-
- if(entry) {
- if(multi->socket_cb)
- multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
- multi->socket_userp,
- entry->socketp);
+ if(conn->data) {
+ /* if there's still an easy handle associated with this connection */
+ struct Curl_multi *multi = conn->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 */
+ struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
+
+ if(entry) {
+ if(multi->socket_cb)
+ multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
+ multi->socket_userp,
+ entry->socketp);
- /* now remove it from the socket hash */
- sh_delentry(&multi->sockhash, s);
+ /* now remove it from the socket hash */
+ sh_delentry(&multi->sockhash, s);
+ }
}
}
}
@@ -2535,8 +2557,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
and callbacks */
if(result != CURLM_BAD_HANDLE) {
data = multi->easyp;
- while(data) {
- singlesocket(multi, data);
+ while(data && !result) {
+ result = singlesocket(multi, data);
data = data->next;
}
}
@@ -2590,10 +2612,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
/* clear the bitmask only if not locked */
data->easy_conn->cselect_bits = 0;
- if(CURLM_OK >= result)
+ if(CURLM_OK >= result) {
/* get the socket(s) and check if the state has been changed since
last */
- singlesocket(multi, data);
+ result = singlesocket(multi, data);
+ if(result)
+ return result;
+ }
/* Now we fall-through and do the timer-based stuff, since we don't want
to force the user to have to deal with timeouts as long as at least
@@ -2627,10 +2652,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
result = multi_runsingle(multi, now, data);
sigpipe_restore(&pipe_st);
- if(CURLM_OK >= result)
+ if(CURLM_OK >= result) {
/* get the socket(s) and check if the state has been changed since
last */
- singlesocket(multi, data);
+ result = singlesocket(multi, data);
+ if(result)
+ return result;
+ }
}
/* Check if there's one (more) expired timer to deal with! This function
@@ -2924,7 +2952,6 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
{
struct Curl_multi *multi = data->multi;
struct curltime *nowp = &data->state.expiretime;
- int rc;
struct curltime set;
/* this is only interesting while there is still an associated multi struct
@@ -2955,6 +2982,7 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
Compare if the new time is earlier, and only remove-old/add-new if it
is. */
timediff_t diff = Curl_timediff(set, *nowp);
+ int rc;
if(diff > 0) {
/* The current splay tree entry is sooner than this new expiry time.
@@ -3000,7 +3028,6 @@ void Curl_expire_clear(struct Curl_easy *data)
{
struct Curl_multi *multi = data->multi;
struct curltime *nowp = &data->state.expiretime;
- int rc;
/* this is only interesting while there is still an associated multi struct
remaining! */
@@ -3011,6 +3038,7 @@ void Curl_expire_clear(struct Curl_easy *data)
/* Since this is an cleared time, we must remove the previous entry from
the splay tree */
struct curl_llist *list = &data->state.timeoutlist;
+ int rc;
rc = Curl_splayremovebyaddr(multi->timetree,
&data->state.timenode,
@@ -3100,12 +3128,15 @@ static void process_pending_handles(struct Curl_multi *multi)
}
}
-void Curl_set_in_callback(struct Curl_easy *easy, bool value)
+void Curl_set_in_callback(struct Curl_easy *data, bool value)
{
- if(easy->multi_easy)
- easy->multi_easy->in_callback = value;
- else if(easy->multi)
- easy->multi->in_callback = value;
+ /* might get called when there is no data pointer! */
+ if(data) {
+ if(data->multi_easy)
+ data->multi_easy->in_callback = value;
+ else if(data->multi)
+ data->multi->in_callback = value;
+ }
}
bool Curl_is_in_callback(struct Curl_easy *easy)
diff --git a/Utilities/cmcurl/lib/multihandle.h b/Utilities/cmcurl/lib/multihandle.h
index 1a5017f4a0..ea2bf352df 100644
--- a/Utilities/cmcurl/lib/multihandle.h
+++ b/Utilities/cmcurl/lib/multihandle.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
@@ -23,6 +23,7 @@
***************************************************************************/
#include "conncache.h"
+#include "psl.h"
struct Curl_message {
struct curl_llist_element list;
@@ -97,6 +98,11 @@ struct Curl_multi {
/* Hostname cache */
struct curl_hash hostcache;
+#ifdef USE_LIBPSL
+ /* PSL cache. */
+ struct PslCache psl;
+#endif
+
/* timetree points to the splay-tree of time nodes to figure out expire
times of all currently set timers */
struct Curl_tree *timetree;
diff --git a/Utilities/cmcurl/lib/netrc.c b/Utilities/cmcurl/lib/netrc.c
index dbcc59ac93..a407bdaacc 100644
--- a/Utilities/cmcurl/lib/netrc.c
+++ b/Utilities/cmcurl/lib/netrc.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
@@ -115,7 +115,7 @@ int Curl_parsenetrc(const char *host,
char *tok;
char *tok_buf;
bool done = FALSE;
- char netrcbuffer[256];
+ char netrcbuffer[4096];
int netrcbuffsize = (int)sizeof(netrcbuffer);
while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
diff --git a/Utilities/cmcurl/lib/pingpong.c b/Utilities/cmcurl/lib/pingpong.c
index ad370ee829..2e93d201f1 100644
--- a/Utilities/cmcurl/lib/pingpong.c
+++ b/Utilities/cmcurl/lib/pingpong.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
@@ -49,7 +49,6 @@ time_t Curl_pp_state_timeout(struct pingpong *pp)
struct connectdata *conn = pp->conn;
struct Curl_easy *data = conn->data;
time_t timeout_ms; /* in milliseconds */
- time_t timeout2_ms; /* in milliseconds */
long response_time = (data->set.server_response_timeout)?
data->set.server_response_timeout: pp->response_time;
@@ -65,7 +64,7 @@ time_t Curl_pp_state_timeout(struct pingpong *pp)
if(data->set.timeout) {
/* if timeout is requested, find out how much remaining time we have */
- timeout2_ms = data->set.timeout - /* timeout time */
+ time_t timeout2_ms = data->set.timeout - /* timeout time */
Curl_timediff(Curl_now(), conn->now); /* spent time */
/* pick the lowest number */
@@ -222,8 +221,7 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
}
if(conn->data->set.verbose)
- Curl_debug(conn->data, CURLINFO_HEADER_OUT,
- s, (size_t)bytes_written, conn);
+ Curl_debug(conn->data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written);
if(bytes_written != (ssize_t)write_len) {
/* the whole chunk was not sent, keep it around and adjust sizes */
@@ -371,7 +369,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
#endif
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
- pp->linestart_resp, (size_t)perline, conn);
+ pp->linestart_resp, (size_t)perline);
/*
* We pass all response-lines to the callback function registered
diff --git a/Utilities/cmcurl/lib/pipeline.c b/Utilities/cmcurl/lib/pipeline.c
index 4d41b04139..8de3babd78 100644
--- a/Utilities/cmcurl/lib/pipeline.c
+++ b/Utilities/cmcurl/lib/pipeline.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
- * Copyright (C) 2013 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013 - 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
@@ -82,7 +82,8 @@ bool Curl_pipeline_penalized(struct Curl_easy *data,
penalized = TRUE;
infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
- CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n",
+ CURL_FORMAT_CURL_OFF_T "/%" CURL_FORMAT_CURL_OFF_T
+ "), penalized: %s\n",
conn->connection_id, (void *)conn, recv_size,
conn->chunk.datasize, penalized?"TRUE":"FALSE");
return penalized;
@@ -109,8 +110,8 @@ CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
pipeline = &conn->send_pipe;
result = addHandleToPipeline(handle, pipeline);
-
- if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
+ if((conn->bundle->multiuse == BUNDLE_PIPELINING) &&
+ (pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head)) {
/* this is a new one as head, expire it */
Curl_pipeline_leave_write(conn); /* not in use yet */
Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
diff --git a/Utilities/cmcurl/lib/pop3.c b/Utilities/cmcurl/lib/pop3.c
index 78f6afef1f..cd994f63d1 100644
--- a/Utilities/cmcurl/lib/pop3.c
+++ b/Utilities/cmcurl/lib/pop3.c
@@ -613,7 +613,6 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *line = data->state.buffer;
size_t len = strlen(line);
- size_t i;
(void)instate; /* no use for this yet */
@@ -625,6 +624,7 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
/* Does the server support APOP authentication? */
if(len >= 4 && line[len - 2] == '>') {
/* Look for the APOP timestamp */
+ size_t i;
for(i = 3; i < len - 2; ++i) {
if(line[i] == '<') {
/* Calculate the length of the timestamp */
@@ -664,7 +664,6 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *line = data->state.buffer;
size_t len = strlen(line);
- size_t wordlen;
(void)instate; /* no use for this yet */
@@ -689,6 +688,7 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
/* Loop through the data line */
for(;;) {
size_t llen;
+ size_t wordlen;
unsigned int mechbit;
while(len &&
diff --git a/Utilities/cmcurl/lib/progress.c b/Utilities/cmcurl/lib/progress.c
index f59faa3d3f..a94668dc2a 100644
--- a/Utilities/cmcurl/lib/progress.c
+++ b/Utilities/cmcurl/lib/progress.c
@@ -35,22 +35,22 @@
byte) */
static void time2str(char *r, curl_off_t seconds)
{
- curl_off_t d, h, m, s;
+ curl_off_t h;
if(seconds <= 0) {
strcpy(r, "--:--:--");
return;
}
h = seconds / CURL_OFF_T_C(3600);
if(h <= CURL_OFF_T_C(99)) {
- m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
- s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
+ 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);
}
else {
/* this equals to more than 99 hours, switch to a more suitable output
format to fit within the limits. */
- d = seconds / CURL_OFF_T_C(86400);
+ 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
@@ -369,25 +369,10 @@ void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
int Curl_pgrsUpdate(struct connectdata *conn)
{
struct curltime now;
- int result;
- char max5[6][10];
- curl_off_t dlpercen = 0;
- curl_off_t ulpercen = 0;
- curl_off_t total_percen = 0;
- curl_off_t total_transfer;
- curl_off_t total_expected_transfer;
curl_off_t timespent;
curl_off_t timespent_ms; /* milliseconds */
struct Curl_easy *data = conn->data;
int nowindex = data->progress.speeder_c% CURR_TIME;
- int checkindex;
- int countindex; /* amount of seconds stored in the speeder array */
- char time_left[10];
- char time_total[10];
- char time_spent[10];
- curl_off_t ulestimate = 0;
- curl_off_t dlestimate = 0;
- curl_off_t total_estimate;
bool shownow = FALSE;
curl_off_t dl = data->progress.downloaded;
curl_off_t ul = data->progress.uploaded;
@@ -413,6 +398,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* Calculations done at most once a second, unless end is reached */
if(data->progress.lastshow != now.tv_sec) {
+ int countindex; /* amount of seconds stored in the speeder array */
shownow = TRUE;
data->progress.lastshow = now.tv_sec;
@@ -438,6 +424,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* first of all, we don't do this if there's no counted seconds yet */
if(countindex) {
+ int checkindex;
timediff_t span_ms;
/* Get the index position to compare with the 'nowindex' position.
@@ -477,8 +464,21 @@ int Curl_pgrsUpdate(struct connectdata *conn)
if(!(data->progress.flags & PGRS_HIDE)) {
/* progress meter has not been shut off */
+ char max5[6][10];
+ curl_off_t dlpercen = 0;
+ curl_off_t ulpercen = 0;
+ curl_off_t total_percen = 0;
+ curl_off_t total_transfer;
+ curl_off_t total_expected_transfer;
+ char time_left[10];
+ char time_total[10];
+ char time_spent[10];
+ curl_off_t ulestimate = 0;
+ curl_off_t dlestimate = 0;
+ curl_off_t total_estimate;
if(data->set.fxferinfo) {
+ int result;
/* There's a callback set, call that */
Curl_set_in_callback(data, true);
result = data->set.fxferinfo(data->set.progress_client,
@@ -492,6 +492,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
return result;
}
if(data->set.fprogress) {
+ int result;
/* The older deprecated callback is set, call that */
Curl_set_in_callback(data, true);
result = data->set.fprogress(data->set.progress_client,
diff --git a/Utilities/cmcurl/lib/progress.h b/Utilities/cmcurl/lib/progress.h
index 2baa925db2..92dbcbd9a6 100644
--- a/Utilities/cmcurl/lib/progress.h
+++ b/Utilities/cmcurl/lib/progress.h
@@ -56,23 +56,10 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
struct curltime start,
struct curltime now);
-/* Don't show progress for sizes smaller than: */
-#define LEAST_SIZE_PROGRESS BUFSIZE
-
-#define PROGRESS_DOWNLOAD (1<<0)
-#define PROGRESS_UPLOAD (1<<1)
-#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD)
-
-#define PGRS_SHOW_DL (1<<0)
-#define PGRS_SHOW_UL (1<<1)
-#define PGRS_DONE_DL (1<<2)
-#define PGRS_DONE_UL (1<<3)
#define PGRS_HIDE (1<<4)
#define PGRS_UL_SIZE_KNOWN (1<<5)
#define PGRS_DL_SIZE_KNOWN (1<<6)
-
#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
-
#endif /* HEADER_CURL_PROGRESS_H */
diff --git a/Utilities/cmcurl/lib/psl.c b/Utilities/cmcurl/lib/psl.c
new file mode 100644
index 0000000000..568baff03f
--- /dev/null
+++ b/Utilities/cmcurl/lib/psl.c
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * 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
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#ifdef USE_LIBPSL
+
+#include "psl.h"
+#include "share.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+void Curl_psl_destroy(struct PslCache *pslcache)
+{
+ if(pslcache->psl) {
+ if(pslcache->dynamic)
+ psl_free((psl_ctx_t *) pslcache->psl);
+ pslcache->psl = NULL;
+ pslcache->dynamic = FALSE;
+ }
+}
+
+static time_t now_seconds(void)
+{
+ struct curltime now = Curl_now();
+
+ return now.tv_sec;
+}
+
+const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy)
+{
+ struct PslCache *pslcache = easy->psl;
+ const psl_ctx_t *psl;
+ time_t now;
+
+ if(!pslcache)
+ return NULL;
+
+ Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED);
+ now = now_seconds();
+ if(!pslcache->psl || pslcache->expires <= now) {
+ /* Let a chance to other threads to do the job: avoids deadlock. */
+ Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);
+
+ /* Update cache: this needs an exclusive lock. */
+ Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SINGLE);
+
+ /* Recheck in case another thread did the job. */
+ now = now_seconds();
+ if(!pslcache->psl || pslcache->expires <= now) {
+ bool dynamic = FALSE;
+ time_t expires = TIME_T_MAX;
+
+#if defined(PSL_VERSION_NUMBER) && PSL_VERSION_NUMBER >= 0x001000
+ psl = psl_latest(NULL);
+ dynamic = psl != NULL;
+ /* Take care of possible time computation overflow. */
+ expires = now < TIME_T_MAX - PSL_TTL? now + PSL_TTL: TIME_T_MAX;
+
+ /* Only get the built-in PSL if we do not already have the "latest". */
+ if(!psl && !pslcache->dynamic)
+#endif
+
+ psl = psl_builtin();
+
+ if(psl) {
+ Curl_psl_destroy(pslcache);
+ pslcache->psl = psl;
+ pslcache->dynamic = dynamic;
+ pslcache->expires = expires;
+ }
+ }
+ Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); /* Release exclusive lock. */
+ Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED);
+ }
+ psl = pslcache->psl;
+ if(!psl)
+ Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);
+ return psl;
+}
+
+void Curl_psl_release(struct Curl_easy *easy)
+{
+ Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);
+}
+
+#endif /* USE_LIBPSL */
diff --git a/Utilities/cmcurl/lib/psl.h b/Utilities/cmcurl/lib/psl.h
new file mode 100644
index 0000000000..e9f99d03ec
--- /dev/null
+++ b/Utilities/cmcurl/lib/psl.h
@@ -0,0 +1,47 @@
+#ifndef HEADER_PSL_H
+#define HEADER_PSL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * 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
+ * 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_LIBPSL
+#include <libpsl.h>
+
+#define PSL_TTL (72 * 3600) /* PSL time to live before a refresh. */
+
+struct PslCache {
+ const psl_ctx_t *psl; /* The PSL. */
+ time_t expires; /* Time this PSL life expires. */
+ bool dynamic; /* PSL should be released when no longer needed. */
+};
+
+const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy);
+void Curl_psl_release(struct Curl_easy *easy);
+void Curl_psl_destroy(struct PslCache *pslcache);
+
+#else
+
+#define Curl_psl_use(easy) NULL
+#define Curl_psl_release(easy)
+#define Curl_psl_destroy(pslcache)
+
+#endif /* USE_LIBPSL */
+#endif /* HEADER_PSL_H */
diff --git a/Utilities/cmcurl/lib/rand.c b/Utilities/cmcurl/lib/rand.c
index 0769ed1512..1dc2504acc 100644
--- a/Utilities/cmcurl/lib/rand.c
+++ b/Utilities/cmcurl/lib/rand.c
@@ -158,7 +158,7 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
DEBUGASSERT(num > 1);
#ifdef __clang_analyzer__
- /* This silences a scan-build warning about accesssing this buffer with
+ /* This silences a scan-build warning about accessing this buffer with
uninitialized memory. */
memset(buffer, 0, sizeof(buffer));
#endif
diff --git a/Utilities/cmcurl/lib/rtsp.c b/Utilities/cmcurl/lib/rtsp.c
index 41f3000139..182ee29588 100644
--- a/Utilities/cmcurl/lib/rtsp.c
+++ b/Utilities/cmcurl/lib/rtsp.c
@@ -218,8 +218,6 @@ static CURLcode rtsp_done(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct RTSP *rtsp = data->req.protop;
CURLcode httpStatus;
- long CSeq_sent;
- long CSeq_recv;
/* Bypass HTTP empty-reply checks on receive */
if(data->set.rtspreq == RTSPREQ_RECEIVE)
@@ -229,8 +227,8 @@ static CURLcode rtsp_done(struct connectdata *conn,
if(rtsp) {
/* Check the sequence numbers */
- CSeq_sent = rtsp->CSeq_sent;
- CSeq_recv = rtsp->CSeq_recv;
+ long CSeq_sent = rtsp->CSeq_sent;
+ long CSeq_recv = rtsp->CSeq_recv;
if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) {
failf(data,
"The CSeq of this request %ld did not match the response %ld",
diff --git a/Utilities/cmcurl/lib/security.c b/Utilities/cmcurl/lib/security.c
index d171985475..403411593c 100644
--- a/Utilities/cmcurl/lib/security.c
+++ b/Utilities/cmcurl/lib/security.c
@@ -390,7 +390,7 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
if(conn->data->set.verbose) {
buf[decoded_len] = '\n';
- Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1, conn);
+ Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1);
}
buf[decoded_len] = '\0';
@@ -488,7 +488,7 @@ static CURLcode choose_mech(struct connectdata *conn)
tmp_allocation = realloc(conn->app_data, mech->size);
if(tmp_allocation == NULL) {
- failf(data, "Failed realloc of size %u", mech->size);
+ failf(data, "Failed realloc of size %zu", mech->size);
mech = NULL;
return CURLE_OUT_OF_MEMORY;
}
diff --git a/Utilities/cmcurl/lib/select.c b/Utilities/cmcurl/lib/select.c
index 0406dd26ae..6e73890159 100644
--- a/Utilities/cmcurl/lib/select.c
+++ b/Utilities/cmcurl/lib/select.c
@@ -80,7 +80,6 @@ int Curl_wait_ms(int timeout_ms)
#endif
struct curltime initial_tv;
int pending_ms;
- int error;
#endif
int r = 0;
@@ -98,6 +97,7 @@ int Curl_wait_ms(int timeout_ms)
pending_ms = timeout_ms;
initial_tv = Curl_now();
do {
+ int error;
#if defined(HAVE_POLL_FINE)
r = poll(NULL, 0, pending_ms);
#else
@@ -160,7 +160,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
#endif
struct curltime initial_tv = {0, 0};
int pending_ms = 0;
- int error;
int r;
int ret;
@@ -210,6 +209,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
}
do {
+ int error;
if(timeout_ms < 0)
pending_ms = -1;
else if(!timeout_ms)
@@ -291,6 +291,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
do {
+ int error;
if(timeout_ms > 0) {
pending_tv.tv_sec = pending_ms / 1000;
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
@@ -402,7 +403,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
bool fds_none = TRUE;
unsigned int i;
int pending_ms = 0;
- int error;
int r;
if(ufds) {
@@ -431,6 +431,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
#ifdef HAVE_POLL_FINE
do {
+ int error;
if(timeout_ms < 0)
pending_ms = -1;
else if(!timeout_ms)
@@ -502,6 +503,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
do {
+ int error;
if(timeout_ms > 0) {
pending_tv.tv_sec = pending_ms / 1000;
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
diff --git a/Utilities/cmcurl/lib/sendf.c b/Utilities/cmcurl/lib/sendf.c
index 27c0ccc730..d3c10b3690 100644
--- a/Utilities/cmcurl/lib/sendf.c
+++ b/Utilities/cmcurl/lib/sendf.c
@@ -240,7 +240,7 @@ void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
va_end(ap);
len = strlen(print_buffer);
- Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
+ Curl_debug(data, CURLINFO_TEXT, print_buffer, len);
}
}
@@ -265,7 +265,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
if(data->set.verbose) {
error[len] = '\n';
error[++len] = '\0';
- Curl_debug(data, CURLINFO_TEXT, error, len, NULL);
+ Curl_debug(data, CURLINFO_TEXT, error, len);
}
va_end(ap);
}
@@ -300,7 +300,7 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
break;
if(data->set.verbose)
- Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
+ Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written);
if((size_t)bytes_written != write_len) {
/* if not all was written at once, we must advance the pointer, decrease
@@ -762,8 +762,8 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
}
/* return 0 on success */
-static int showit(struct Curl_easy *data, curl_infotype type,
- char *ptr, size_t size)
+int Curl_debug(struct Curl_easy *data, curl_infotype type,
+ char *ptr, size_t size)
{
static const char s_infotype[CURLINFO_END][3] = {
"* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
@@ -834,41 +834,3 @@ static int showit(struct Curl_easy *data, curl_infotype type,
#endif
return rc;
}
-
-int Curl_debug(struct Curl_easy *data, curl_infotype type,
- char *ptr, size_t size,
- struct connectdata *conn)
-{
- int rc;
- if(data->set.printhost && conn && conn->host.dispname) {
- char buffer[160];
- const char *t = NULL;
- const char *w = "Data";
- switch(type) {
- case CURLINFO_HEADER_IN:
- w = "Header";
- /* FALLTHROUGH */
- case CURLINFO_DATA_IN:
- t = "from";
- break;
- case CURLINFO_HEADER_OUT:
- w = "Header";
- /* FALLTHROUGH */
- case CURLINFO_DATA_OUT:
- t = "to";
- break;
- default:
- break;
- }
-
- if(t) {
- snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
- conn->host.dispname);
- rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
- if(rc)
- return rc;
- }
- }
- rc = showit(data, type, ptr, size);
- return rc;
-}
diff --git a/Utilities/cmcurl/lib/sendf.h b/Utilities/cmcurl/lib/sendf.h
index 7c9134decc..7627fe6c5f 100644
--- a/Utilities/cmcurl/lib/sendf.h
+++ b/Utilities/cmcurl/lib/sendf.h
@@ -84,9 +84,8 @@ CURLcode Curl_write_plain(struct connectdata *conn,
ssize_t *written);
/* the function used to output verbose information */
-int Curl_debug(struct Curl_easy *handle, curl_infotype type,
- char *data, size_t size,
- struct connectdata *conn);
+int Curl_debug(struct Curl_easy *data, curl_infotype type,
+ char *ptr, size_t size);
#endif /* HEADER_CURL_SENDF_H */
diff --git a/Utilities/cmcurl/lib/setopt.c b/Utilities/cmcurl/lib/setopt.c
index af53ee3efa..5c5f4b3817 100644
--- a/Utilities/cmcurl/lib/setopt.c
+++ b/Utilities/cmcurl/lib/setopt.c
@@ -142,6 +142,25 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
va_arg(param, char *));
break;
+ case CURLOPT_TLS13_CIPHERS:
+ if(Curl_ssl_tls13_ciphersuites()) {
+ /* set preferred list of TLS 1.3 cipher suites */
+ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_ORIG],
+ va_arg(param, char *));
+ }
+ else
+ return CURLE_NOT_BUILT_IN;
+ break;
+ case CURLOPT_PROXY_TLS13_CIPHERS:
+ if(Curl_ssl_tls13_ciphersuites()) {
+ /* set preferred list of TLS 1.3 cipher suites for proxy */
+ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_PROXY],
+ va_arg(param, char *));
+ }
+ else
+ return CURLE_NOT_BUILT_IN;
+ break;
+
case CURLOPT_RANDOM_FILE:
/*
* This is the path name to a file that contains random data to seed
@@ -1584,14 +1603,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
* String that holds the SSL crypto engine.
*/
argptr = va_arg(param, char *);
- if(argptr && argptr[0])
- result = Curl_ssl_set_engine(data, argptr);
+ if(argptr && argptr[0]) {
+ result = Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], argptr);
+ if(!result) {
+ result = Curl_ssl_set_engine(data, argptr);
+ }
+ }
break;
case CURLOPT_SSLENGINE_DEFAULT:
/*
* flag to set engine as default.
*/
+ Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], NULL);
result = Curl_ssl_set_engine_default(data);
break;
case CURLOPT_CRLF:
@@ -1942,6 +1966,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
if(data->share->sslsession == data->state.session)
data->state.session = NULL;
+#ifdef USE_LIBPSL
+ if(data->psl == &data->share->psl)
+ data->psl = data->multi? &data->multi->psl: NULL;
+#endif
+
data->share->dirty--;
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
@@ -1973,8 +2002,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
data->state.session = data->share->sslsession;
}
- Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+#ifdef USE_LIBPSL
+ if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL))
+ data->psl = &data->share->psl;
+#endif
+ Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
}
/* check for host cache not needed,
* it will be done by curl_easy_perform */
@@ -2562,6 +2595,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_DNS_SHUFFLE_ADDRESSES:
data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE;
break;
+ case CURLOPT_DISALLOW_USERNAME_IN_URL:
+ data->set.disallow_username_in_url =
+ (0 != va_arg(param, long)) ? TRUE : FALSE;
+ break;
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_UNKNOWN_OPTION;
diff --git a/Utilities/cmcurl/lib/sha256.c b/Utilities/cmcurl/lib/sha256.c
index 55716c63b0..f9287af232 100644
--- a/Utilities/cmcurl/lib/sha256.c
+++ b/Utilities/cmcurl/lib/sha256.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Florin Petriuc, <petriuc.florin@gmail.com>
+ * Copyright (C) 1998 - 2018, Florin Petriuc, <petriuc.florin@gmail.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -123,15 +123,11 @@ static const unsigned long K[64] = {
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
-#ifndef MIN
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-#endif
/* compress 512-bits */
static int sha256_compress(struct sha256_state *md,
unsigned char *buf)
{
- unsigned long S[8], W[64], t0, t1;
- unsigned long t;
+ unsigned long S[8], W[64];
int i;
/* copy state into S */
for(i = 0; i < 8; i++) {
@@ -146,12 +142,13 @@ static int sha256_compress(struct sha256_state *md,
W[i - 16];
}
/* Compress */
-#define RND(a,b,c,d,e,f,g,h,i) \
- t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
- t1 = Sigma0(a) + Maj(a, b, c); \
- d += t0; \
+#define RND(a,b,c,d,e,f,g,h,i) \
+ unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
+ unsigned long t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
h = t0 + t1;
for(i = 0; i < 64; ++i) {
+ unsigned long t;
RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
@@ -200,7 +197,7 @@ static int SHA256_Update(struct sha256_state *md,
inlen -= block_size;
}
else {
- n = MIN(inlen, (block_size - md->curlen));
+ n = CURLMIN(inlen, (block_size - md->curlen));
memcpy(md->buf + md->curlen, in, n);
md->curlen += n;
in += n;
diff --git a/Utilities/cmcurl/lib/share.c b/Utilities/cmcurl/lib/share.c
index 870b191fc2..3d5108610f 100644
--- a/Utilities/cmcurl/lib/share.c
+++ b/Utilities/cmcurl/lib/share.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
@@ -25,6 +25,7 @@
#include <curl/curl.h>
#include "urldata.h"
#include "share.h"
+#include "psl.h"
#include "vtls/vtls.h"
#include "curl_memory.h"
@@ -106,6 +107,12 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
res = CURLSHE_NOMEM;
break;
+ case CURL_LOCK_DATA_PSL:
+#ifndef USE_LIBPSL
+ res = CURLSHE_NOT_BUILT_IN;
+#endif
+ break;
+
default:
res = CURLSHE_BAD_OPTION;
}
@@ -205,6 +212,8 @@ curl_share_cleanup(struct Curl_share *share)
}
#endif
+ Curl_psl_destroy(&share->psl);
+
if(share->unlockfunc)
share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
free(share);
diff --git a/Utilities/cmcurl/lib/share.h b/Utilities/cmcurl/lib/share.h
index 4b13406d9f..a7dea41adb 100644
--- a/Utilities/cmcurl/lib/share.h
+++ b/Utilities/cmcurl/lib/share.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
@@ -25,6 +25,7 @@
#include "curl_setup.h"
#include <curl/curl.h>
#include "cookie.h"
+#include "psl.h"
#include "urldata.h"
#include "conncache.h"
@@ -49,6 +50,9 @@ struct Curl_share {
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
struct CookieInfo *cookies;
#endif
+#ifdef USE_LIBPSL
+ struct PslCache psl;
+#endif
struct curl_ssl_session *sslsession;
size_t max_ssl_sessions;
diff --git a/Utilities/cmcurl/lib/smb.c b/Utilities/cmcurl/lib/smb.c
index 9ac61505cf..e4b18fcf5f 100644
--- a/Utilities/cmcurl/lib/smb.c
+++ b/Utilities/cmcurl/lib/smb.c
@@ -59,6 +59,7 @@
static CURLcode smb_setup_connection(struct connectdata *conn);
static CURLcode smb_connect(struct connectdata *conn, bool *done);
static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
+static CURLcode smb_do(struct connectdata *conn, bool *done);
static CURLcode smb_request_state(struct connectdata *conn, bool *done);
static CURLcode smb_done(struct connectdata *conn, CURLcode status,
bool premature);
@@ -73,7 +74,7 @@ static CURLcode smb_parse_url_path(struct connectdata *conn);
const struct Curl_handler Curl_handler_smb = {
"SMB", /* scheme */
smb_setup_connection, /* setup_connection */
- ZERO_NULL, /* do_it */
+ smb_do, /* do_it */
smb_done, /* done */
ZERO_NULL, /* do_more */
smb_connect, /* connect_it */
@@ -98,7 +99,7 @@ const struct Curl_handler Curl_handler_smb = {
const struct Curl_handler Curl_handler_smbs = {
"SMBS", /* scheme */
smb_setup_connection, /* setup_connection */
- ZERO_NULL, /* do_it */
+ smb_do, /* do_it */
smb_done, /* done */
ZERO_NULL, /* do_more */
smb_connect, /* connect_it */
@@ -173,7 +174,6 @@ enum smb_req_state {
/* SMB request data */
struct smb_request {
enum smb_req_state state;
- char *share;
char *path;
unsigned short tid; /* Even if we connect to the same tree as another */
unsigned short fid; /* request, the tid will be different */
@@ -182,7 +182,7 @@ struct smb_request {
static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
{
- struct smb_conn *smb = &conn->proto.smbc;
+ struct smb_conn *smbc = &conn->proto.smbc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* For debug purposes */
static const char * const names[] = {
@@ -194,12 +194,12 @@ static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
/* LAST */
};
- if(smb->state != newstate)
+ if(smbc->state != newstate)
infof(conn->data, "SMB conn %p state change from %s to %s\n",
- (void *)smb, names[smb->state], names[newstate]);
+ (void *)smbc, names[smbc->state], names[newstate]);
#endif
- smb->state = newstate;
+ smbc->state = newstate;
}
static void request_state(struct connectdata *conn,
@@ -228,6 +228,8 @@ static void request_state(struct connectdata *conn,
req->state = newstate;
}
+/* this should setup things in the connection, not in the easy
+ handle */
static CURLcode smb_setup_connection(struct connectdata *conn)
{
struct smb_request *req;
@@ -253,7 +255,6 @@ static CURLcode smb_connect(struct connectdata *conn, bool *done)
return CURLE_LOGIN_DENIED;
/* Initialize the connection state */
- memset(smbc, 0, sizeof(*smbc));
smbc->state = SMB_CONNECTING;
smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
if(!smbc->recv_buf)
@@ -366,7 +367,7 @@ static CURLcode smb_send(struct connectdata *conn, ssize_t len,
ssize_t bytes_written;
CURLcode result;
- result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer,
+ result = Curl_write(conn, FIRSTSOCKET, conn->data->state.ulbuf,
len, &bytes_written);
if(result)
return result;
@@ -392,7 +393,7 @@ static CURLcode smb_flush(struct connectdata *conn)
return CURLE_OK;
result = Curl_write(conn, FIRSTSOCKET,
- conn->data->state.uploadbuffer + smbc->sent,
+ conn->data->state.ulbuf + smbc->sent,
len, &bytes_written);
if(result)
return result;
@@ -408,9 +409,12 @@ static CURLcode smb_flush(struct connectdata *conn)
static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
const void *msg, size_t msg_len)
{
- smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer,
+ CURLcode result = Curl_get_upload_buffer(conn->data);
+ if(result)
+ return result;
+ smb_format_message(conn, (struct smb_header *)conn->data->state.ulbuf,
cmd, msg_len);
- memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header),
+ memcpy(conn->data->state.ulbuf + sizeof(struct smb_header),
msg, msg_len);
return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
@@ -475,11 +479,11 @@ static CURLcode smb_send_setup(struct connectdata *conn)
static CURLcode smb_send_tree_connect(struct connectdata *conn)
{
- struct smb_request *req = conn->data->req.protop;
struct smb_tree_connect msg;
+ struct smb_conn *smbc = &conn->proto.smbc;
char *p = msg.bytes;
- size_t byte_count = strlen(conn->host.name) + strlen(req->share);
+ size_t byte_count = strlen(conn->host.name) + strlen(smbc->share);
byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
if(byte_count > sizeof(msg.bytes))
return CURLE_FILESIZE_EXCEEDED;
@@ -491,7 +495,7 @@ static CURLcode smb_send_tree_connect(struct connectdata *conn)
MSGCAT("\\\\");
MSGCAT(conn->host.name);
MSGCAT("\\");
- MSGCATNULL(req->share);
+ MSGCATNULL(smbc->share);
MSGCATNULL(SERVICENAME); /* Match any type of service */
byte_count = p - msg.bytes;
msg.byte_count = smb_swap16((unsigned short)byte_count);
@@ -571,11 +575,15 @@ static CURLcode smb_send_read(struct connectdata *conn)
static CURLcode smb_send_write(struct connectdata *conn)
{
- struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer;
+ struct smb_write *msg;
struct smb_request *req = conn->data->req.protop;
curl_off_t offset = conn->data->req.offset;
-
curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
+ CURLcode result = Curl_get_upload_buffer(conn->data);
+ if(result)
+ return result;
+ msg = (struct smb_write *)conn->data->state.ulbuf;
+
if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
upload_size = MAX_PAYLOAD_SIZE - 1;
@@ -602,9 +610,9 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
/* Check if there is data in the transfer buffer */
if(!smbc->send_size && smbc->upload_size) {
- int nread = smbc->upload_size > UPLOAD_BUFSIZE ? UPLOAD_BUFSIZE :
- (int) smbc->upload_size;
- conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
+ size_t nread = smbc->upload_size > UPLOAD_BUFSIZE ? UPLOAD_BUFSIZE :
+ smbc->upload_size;
+ conn->data->req.upload_fromhere = conn->data->state.ulbuf;
result = Curl_fillreadbuffer(conn, nread, &nread);
if(result && result != CURLE_AGAIN)
return result;
@@ -910,55 +918,52 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
static CURLcode smb_done(struct connectdata *conn, CURLcode status,
bool premature)
{
- struct smb_request *req = conn->data->req.protop;
-
(void) premature;
-
- Curl_safefree(req->share);
Curl_safefree(conn->data->req.protop);
-
return status;
}
static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
{
struct smb_conn *smbc = &conn->proto.smbc;
- struct smb_request *req = conn->data->req.protop;
-
(void) dead;
-
+ Curl_safefree(smbc->share);
Curl_safefree(smbc->domain);
Curl_safefree(smbc->recv_buf);
-
- /* smb_done is not always called, so cleanup the request */
- if(req) {
- Curl_safefree(req->share);
- }
-
return CURLE_OK;
}
static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks)
{
- struct smb_conn *smbc = &conn->proto.smbc;
-
if(!numsocks)
return GETSOCK_BLANK;
socks[0] = conn->sock[FIRSTSOCKET];
+ return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
+}
- if(smbc->send_size || smbc->upload_size)
- return GETSOCK_WRITESOCK(0);
+static CURLcode smb_do(struct connectdata *conn, bool *done)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ struct smb_request *req = conn->data->req.protop;
- return GETSOCK_READSOCK(0);
+ *done = FALSE;
+ if(smbc->share) {
+ req->path = strchr(smbc->share, '\0');
+ if(req->path) {
+ req->path++;
+ return CURLE_OK;
+ }
+ }
+ return CURLE_URL_MALFORMAT;
}
static CURLcode smb_parse_url_path(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct smb_request *req = data->req.protop;
+ struct smb_conn *smbc = &conn->proto.smbc;
char *path;
char *slash;
@@ -968,35 +973,29 @@ static CURLcode smb_parse_url_path(struct connectdata *conn)
return result;
/* Parse the path for the share */
- req->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
- if(!req->share) {
- free(path);
-
+ smbc->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
+ free(path);
+ if(!smbc->share)
return CURLE_OUT_OF_MEMORY;
- }
- slash = strchr(req->share, '/');
+ slash = strchr(smbc->share, '/');
if(!slash)
- slash = strchr(req->share, '\\');
+ slash = strchr(smbc->share, '\\');
/* The share must be present */
if(!slash) {
- free(path);
-
+ Curl_safefree(smbc->share);
return CURLE_URL_MALFORMAT;
}
/* Parse the path for the file path converting any forward slashes into
backslashes */
*slash++ = 0;
- req->path = slash;
+
for(; *slash; slash++) {
if(*slash == '/')
*slash = '\\';
}
-
- free(path);
-
return CURLE_OK;
}
diff --git a/Utilities/cmcurl/lib/smb.h b/Utilities/cmcurl/lib/smb.h
index c3ee7ae039..9ce6b56157 100644
--- a/Utilities/cmcurl/lib/smb.h
+++ b/Utilities/cmcurl/lib/smb.h
@@ -35,6 +35,7 @@ struct smb_conn {
enum smb_conn_state state;
char *user;
char *domain;
+ char *share;
unsigned char challenge[8];
unsigned int session_key;
unsigned short uid;
diff --git a/Utilities/cmcurl/lib/smtp.c b/Utilities/cmcurl/lib/smtp.c
index 3f3b45a954..ecf10a41ac 100644
--- a/Utilities/cmcurl/lib/smtp.c
+++ b/Utilities/cmcurl/lib/smtp.c
@@ -704,7 +704,6 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
struct smtp_conn *smtpc = &conn->proto.smtpc;
const char *line = data->state.buffer;
size_t len = strlen(line);
- size_t wordlen;
(void)instate; /* no use for this yet */
@@ -739,6 +738,7 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
/* Loop through the data line */
for(;;) {
size_t llen;
+ size_t wordlen;
unsigned int mechbit;
while(len &&
@@ -1563,13 +1563,14 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
if(!scratch || data->set.crlf) {
oldscratch = scratch;
- scratch = newscratch = malloc(2 * data->set.buffer_size);
+ scratch = newscratch = malloc(2 * UPLOAD_BUFSIZE);
if(!newscratch) {
failf(data, "Failed to alloc scratch buffer!");
return CURLE_OUT_OF_MEMORY;
}
}
+ DEBUGASSERT(UPLOAD_BUFSIZE >= nread);
/* Have we already sent part of the EOB? */
eob_sent = smtp->eob;
diff --git a/Utilities/cmcurl/lib/socks.c b/Utilities/cmcurl/lib/socks.c
index ac4270eacf..81f3eda283 100644
--- a/Utilities/cmcurl/lib/socks.c
+++ b/Utilities/cmcurl/lib/socks.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
@@ -57,10 +57,9 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
ssize_t nread;
ssize_t allread = 0;
int result;
- timediff_t timeleft;
*n = 0;
for(;;) {
- timeleft = Curl_timeleft(conn->data, NULL, TRUE);
+ timediff_t timeleft = Curl_timeleft(conn->data, NULL, TRUE);
if(timeleft < 0) {
/* we already got the timeout */
result = CURLE_OPERATION_TIMEDOUT;
@@ -116,7 +115,6 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
#define SOCKS4REQLEN 262
unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
id */
- int result;
CURLcode code;
curl_socket_t sock = conn->sock[sockindex];
struct Curl_easy *data = conn->data;
@@ -220,11 +218,12 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
* Make connection
*/
{
+ int result;
ssize_t actualread;
ssize_t written;
ssize_t hostnamelen = 0;
- int packetsize = 9 +
- (int)strlen((char *)socksreq + 8); /* size including NUL */
+ ssize_t packetsize = 9 +
+ strlen((char *)socksreq + 8); /* size including NUL */
/* If SOCKS4a, set special invalid IP address 0.0.0.x */
if(protocol4a) {
@@ -617,11 +616,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
if(dns)
hp = dns->addr;
if(hp) {
- int i;
char buf[64];
Curl_printable_address(hp, buf, sizeof(buf));
if(hp->ai_family == AF_INET) {
+ int i;
struct sockaddr_in *saddr_in;
socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
@@ -634,6 +633,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
}
#ifdef ENABLE_IPV6
else if(hp->ai_family == AF_INET6) {
+ int i;
struct sockaddr_in6 *saddr_in6;
socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
diff --git a/Utilities/cmcurl/lib/splay.c b/Utilities/cmcurl/lib/splay.c
index 69af446eb5..c54a63bbaf 100644
--- a/Utilities/cmcurl/lib/splay.c
+++ b/Utilities/cmcurl/lib/splay.c
@@ -41,7 +41,6 @@ struct Curl_tree *Curl_splay(struct curltime i,
struct Curl_tree *t)
{
struct Curl_tree N, *l, *r, *y;
- long comp;
if(t == NULL)
return t;
@@ -49,7 +48,7 @@ struct Curl_tree *Curl_splay(struct curltime i,
l = r = &N;
for(;;) {
- comp = compare(i, t->key);
+ long comp = compare(i, t->key);
if(comp < 0) {
if(t->smaller == NULL)
break;
diff --git a/Utilities/cmcurl/lib/ssh-libssh.c b/Utilities/cmcurl/lib/ssh-libssh.c
index 34ef490c4e..7d590891ca 100644
--- a/Utilities/cmcurl/lib/ssh-libssh.c
+++ b/Utilities/cmcurl/lib/ssh-libssh.c
@@ -204,11 +204,21 @@ static CURLcode sftp_error_to_CURLE(int err)
return CURLE_SSH;
}
+#ifndef DEBUGBUILD
+#define state(x,y) mystate(x,y)
+#else
+#define state(x,y) mystate(x,y, __LINE__)
+#endif
+
/*
* SSH State machine related code
*/
/* This is the ONLY way to change SSH state! */
-static void state(struct connectdata *conn, sshstate nowstate)
+static void mystate(struct connectdata *conn, sshstate nowstate
+#ifdef DEBUGBUILD
+ , int lineno
+#endif
+ )
{
struct ssh_conn *sshc = &conn->proto.sshc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -278,8 +288,9 @@ static void state(struct connectdata *conn, sshstate nowstate)
if(sshc->state != nowstate) {
- infof(conn->data, "SSH %p state change from %s to %s\n",
- (void *) sshc, names[sshc->state], names[nowstate]);
+ infof(conn->data, "SSH %p state change from %s to %s (line %d)\n",
+ (void *) sshc, names[sshc->state], names[nowstate],
+ lineno);
}
#endif
@@ -418,7 +429,7 @@ cleanup:
}
#define MOVE_TO_ERROR_STATE(_r) { \
- state(conn, SSH_SESSION_FREE); \
+ state(conn, SSH_SESSION_DISCONNECT); \
sshc->actualcode = _r; \
rc = SSH_ERROR; \
break; \
@@ -486,7 +497,7 @@ restart:
if(rc < 0)
return SSH_ERROR;
- /* fallthrough */
+ /* FALLTHROUGH */
case 1:
sshc->kbd_state = 1;
@@ -561,7 +572,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
ssh_set_blocking(sshc->ssh_session, 0);
state(conn, SSH_S_STARTUP);
- /* fall-through */
+ /* FALLTHROUGH */
case SSH_S_STARTUP:
rc = ssh_connect(sshc->ssh_session);
@@ -575,7 +586,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_HOSTKEY);
- /* fall-through */
+ /* FALLTHROUGH */
case SSH_HOSTKEY:
rc = myssh_is_known(conn);
@@ -584,7 +595,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
}
state(conn, SSH_AUTHLIST);
- /* fall through */
+ /* FALLTHROUGH */
case SSH_AUTHLIST:{
sshc->authed = FALSE;
@@ -607,6 +618,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
state(conn, SSH_AUTH_PKEY_INIT);
+ infof(data, "Authentication using SSH public key file\n");
}
else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) {
state(conn, SSH_AUTH_GSSAPI);
@@ -651,6 +663,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
if(rc != SSH_OK) {
failf(data, "Could not load private key file %s",
data->set.str[STRING_SSH_PRIVATE_KEY]);
+ MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
break;
}
@@ -659,8 +672,6 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
}
else {
- infof(data, "Authentication using SSH public key file\n");
-
rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL,
data->set.ssl.key_passwd);
if(rc == SSH_AUTH_AGAIN) {
@@ -748,7 +759,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
}
state(conn, SSH_AUTH_PASS);
- /* fall through */
+ /* FALLTHROUGH */
case SSH_AUTH_PASS:
rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd);
@@ -812,7 +823,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
state(conn, SSH_SFTP_REALPATH);
- /* fall through */
+ /* FALLTHROUGH */
case SSH_SFTP_REALPATH:
/*
* Get the "home" directory
@@ -1279,7 +1290,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
if(sshc->readdir_attrs) {
sshc->readdir_filename = sshc->readdir_attrs->name;
sshc->readdir_longentry = sshc->readdir_attrs->longname;
- sshc->readdir_len = (int)strlen(sshc->readdir_filename);
+ sshc->readdir_len = strlen(sshc->readdir_filename);
if(data->set.ftp_list_only) {
char *tmpLine;
@@ -1306,11 +1317,11 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
if(data->set.verbose) {
Curl_debug(data, CURLINFO_DATA_OUT,
(char *)sshc->readdir_filename,
- sshc->readdir_len, conn);
+ sshc->readdir_len);
}
}
else {
- sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
+ sshc->readdir_currLen = strlen(sshc->readdir_longentry);
sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
if(!sshc->readdir_line) {
@@ -1371,12 +1382,12 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
if(sshc->readdir_filename == NULL)
sshc->readdir_len = 0;
else
- sshc->readdir_len = (int)strlen(sshc->readdir_tmp);
+ sshc->readdir_len = strlen(sshc->readdir_tmp);
sshc->readdir_longentry = NULL;
sshc->readdir_filename = sshc->readdir_tmp;
}
else {
- sshc->readdir_len = (int)strlen(sshc->readdir_link_attrs->name);
+ sshc->readdir_len = strlen(sshc->readdir_link_attrs->name);
sshc->readdir_filename = sshc->readdir_link_attrs->name;
sshc->readdir_longentry = sshc->readdir_link_attrs->longname;
}
@@ -1408,7 +1419,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
sshc->readdir_longentry = NULL;
state(conn, SSH_SFTP_READDIR_BOTTOM);
- /* fall through */
+ /* FALLTHROUGH */
case SSH_SFTP_READDIR_BOTTOM:
sshc->readdir_currLen += snprintf(sshc->readdir_line +
sshc->readdir_currLen,
@@ -1423,7 +1434,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
/* output debug output if that is requested */
if(data->set.verbose) {
Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
- sshc->readdir_currLen, conn);
+ sshc->readdir_currLen);
}
data->req.bytecount += sshc->readdir_currLen;
}
@@ -1740,7 +1751,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
}
state(conn, SSH_SCP_DOWNLOAD);
- /* fall through */
+ /* FALLTHROUGH */
case SSH_SCP_DOWNLOAD:{
curl_off_t bytecount;
@@ -1805,7 +1816,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
ssh_set_blocking(sshc->ssh_session, 0);
state(conn, SSH_SESSION_DISCONNECT);
- /* fall through */
+ /* FALLTHROUGH */
case SSH_SESSION_DISCONNECT:
/* during weird times when we've been prematurely aborted, the channel
@@ -1822,7 +1833,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
conn->data->state.most_recent_ftp_entrypath = NULL;
state(conn, SSH_SESSION_FREE);
- /* fall through */
+ /* FALLTHROUGH */
case SSH_SESSION_FREE:
if(sshc->ssh_session) {
ssh_free(sshc->ssh_session);
@@ -2379,7 +2390,8 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
/* Post quote commands are executed after the SFTP_CLOSE state to avoid
errors that could happen due to open file handles during POSTQUOTE
operation */
- if(!status && !premature && conn->data->set.postquote) {
+ if(!status && !premature && conn->data->set.postquote &&
+ !conn->bits.retry) {
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
state(conn, SSH_SFTP_CLOSE);
}
@@ -2437,7 +2449,7 @@ static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
return -1;
}
- /* fall-through */
+ /* FALLTHROUGH */
case 1:
conn->proto.sshc.sftp_recv_state = 1;
@@ -2500,8 +2512,8 @@ static void sftp_quote(struct connectdata *conn)
return;
}
if(data->set.verbose) {
- Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4, conn);
- Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
+ Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
+ Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
}
/* this sends an FTP-like "header" to the header callback so that the
current directory can be read very similar to how it is read when
diff --git a/Utilities/cmcurl/lib/ssh.c b/Utilities/cmcurl/lib/ssh.c
index bf7bd54f90..a4b2ca43ab 100644
--- a/Utilities/cmcurl/lib/ssh.c
+++ b/Utilities/cmcurl/lib/ssh.c
@@ -659,7 +659,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
libssh2_session_set_blocking(sshc->ssh_session, 0);
state(conn, SSH_S_STARTUP);
- /* fall-through */
+ /* FALLTHROUGH */
case SSH_S_STARTUP:
rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
@@ -675,7 +675,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_HOSTKEY);
- /* fall-through */
+ /* FALLTHROUGH */
case SSH_HOSTKEY:
/*
* Before we authenticate we should check the hostkey's fingerprint
@@ -1175,8 +1175,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(data->set.verbose) {
- Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
- Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
+ Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
+ Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
}
/* this sends an FTP-like "header" to the header callback so that the
current directory can be read very similar to how it is read when
@@ -1933,17 +1933,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
case SSH_SFTP_READDIR:
- sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
- sshc->readdir_filename,
- PATH_MAX,
- sshc->readdir_longentry,
- PATH_MAX,
- &sshc->readdir_attrs);
- if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
- rc = LIBSSH2_ERROR_EAGAIN;
+ rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
+ sshc->readdir_filename,
+ PATH_MAX,
+ sshc->readdir_longentry,
+ PATH_MAX,
+ &sshc->readdir_attrs);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
- if(sshc->readdir_len > 0) {
+ if(rc > 0) {
+ sshc->readdir_len = (size_t) rc;
sshc->readdir_filename[sshc->readdir_len] = '\0';
if(data->set.ftp_list_only) {
@@ -1970,11 +1970,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* output debug output if that is requested */
if(data->set.verbose) {
Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
- sshc->readdir_len, conn);
+ sshc->readdir_len);
}
}
else {
- sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
+ sshc->readdir_currLen = strlen(sshc->readdir_longentry);
sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
if(!sshc->readdir_line) {
@@ -2008,13 +2008,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
}
- else if(sshc->readdir_len == 0) {
+ else if(rc == 0) {
Curl_safefree(sshc->readdir_filename);
Curl_safefree(sshc->readdir_longentry);
state(conn, SSH_SFTP_READDIR_DONE);
break;
}
- else if(sshc->readdir_len <= 0) {
+ else if(rc < 0) {
err = sftp_libssh2_last_error(sshc->sftp_session);
result = sftp_libssh2_error_to_CURLE(err);
sshc->actualcode = result?result:CURLE_SSH;
@@ -2029,16 +2029,16 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
case SSH_SFTP_READDIR_LINK:
- sshc->readdir_len =
+ rc =
libssh2_sftp_symlink_ex(sshc->sftp_session,
sshc->readdir_linkPath,
curlx_uztoui(strlen(sshc->readdir_linkPath)),
sshc->readdir_filename,
PATH_MAX, LIBSSH2_SFTP_READLINK);
- if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
- rc = LIBSSH2_ERROR_EAGAIN;
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
+ sshc->readdir_len = (size_t) rc;
Curl_safefree(sshc->readdir_linkPath);
/* get room for the filename and extra output */
@@ -2079,7 +2079,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* output debug output if that is requested */
if(data->set.verbose) {
Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
- sshc->readdir_currLen, conn);
+ sshc->readdir_currLen);
}
data->req.bytecount += sshc->readdir_currLen;
}
@@ -3219,7 +3219,8 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
/* Post quote commands are executed after the SFTP_CLOSE state to avoid
errors that could happen due to open file handles during POSTQUOTE
operation */
- if(!status && !premature && conn->data->set.postquote) {
+ if(!status && !premature && conn->data->set.postquote &&
+ !conn->bits.retry) {
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
state(conn, SSH_SFTP_CLOSE);
}
diff --git a/Utilities/cmcurl/lib/ssh.h b/Utilities/cmcurl/lib/ssh.h
index 1c13550774..0620aac328 100644
--- a/Utilities/cmcurl/lib/ssh.h
+++ b/Utilities/cmcurl/lib/ssh.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
@@ -131,7 +131,7 @@ struct ssh_conn {
quote command fails) */
char *homedir; /* when doing SFTP we figure out home dir in the
connect phase */
- int readdir_len, readdir_totalLen, readdir_currLen;
+ size_t readdir_len, readdir_totalLen, readdir_currLen;
char *readdir_line;
char *readdir_linkPath;
/* end of READDIR stuff */
diff --git a/Utilities/cmcurl/lib/strcase.h b/Utilities/cmcurl/lib/strcase.h
index ea2abc8b60..6fee3840e6 100644
--- a/Utilities/cmcurl/lib/strcase.h
+++ b/Utilities/cmcurl/lib/strcase.h
@@ -46,6 +46,5 @@ char Curl_raw_toupper(char in);
#define checkprefix(a,b) curl_strnequal(a,b,strlen(a))
void Curl_strntoupper(char *dest, const char *src, size_t n);
-char Curl_raw_toupper(char in);
#endif /* HEADER_CURL_STRCASE_H */
diff --git a/Utilities/cmcurl/lib/system_win32.c b/Utilities/cmcurl/lib/system_win32.c
index cfbbf32797..6b8004e5bb 100644
--- a/Utilities/cmcurl/lib/system_win32.c
+++ b/Utilities/cmcurl/lib/system_win32.c
@@ -26,6 +26,7 @@
#include <curl/curl.h>
#include "system_win32.h"
+#include "warnless.h"
/* The last #include files should be: */
#include "curl_memory.h"
@@ -134,8 +135,9 @@ bool Curl_verify_windows_version(const unsigned int majorVersion,
break;
case VERSION_LESS_THAN_EQUAL:
- if(osver.dwMajorVersion <= majorVersion &&
- osver.dwMinorVersion <= minorVersion)
+ if(osver.dwMajorVersion < majorVersion ||
+ (osver.dwMajorVersion == majorVersion &&
+ osver.dwMinorVersion <= minorVersion))
matched = TRUE;
break;
@@ -146,8 +148,9 @@ bool Curl_verify_windows_version(const unsigned int majorVersion,
break;
case VERSION_GREATER_THAN_EQUAL:
- if(osver.dwMajorVersion >= majorVersion &&
- osver.dwMinorVersion >= minorVersion)
+ if(osver.dwMajorVersion > majorVersion ||
+ (osver.dwMajorVersion == majorVersion &&
+ osver.dwMinorVersion >= minorVersion))
matched = TRUE;
break;
@@ -278,7 +281,9 @@ HMODULE Curl_load_library(LPCTSTR filename)
/* Attempt to find LoadLibraryEx() which is only available on Windows 2000
and above */
- pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX);
+ pLoadLibraryEx =
+ CURLX_FUNCTION_CAST(LOADLIBRARYEX_FN,
+ (GetProcAddress(hKernel32, LOADLIBARYEX)));
/* Detect if there's already a path in the filename and load the library if
there is. Note: Both back slashes and forward slashes have been supported
diff --git a/Utilities/cmcurl/lib/telnet.c b/Utilities/cmcurl/lib/telnet.c
index d71c8e067a..05fe744dbd 100644
--- a/Utilities/cmcurl/lib/telnet.c
+++ b/Utilities/cmcurl/lib/telnet.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
@@ -52,10 +52,6 @@
#include "connect.h"
#include "progress.h"
#include "system_win32.h"
-
-#define TELOPTS
-#define TELCMDS
-
#include "arpa_telnet.h"
#include "select.h"
#include "strcase.h"
@@ -74,10 +70,10 @@
x->subend = x->subpointer; \
CURL_SB_CLEAR(x); \
} WHILE_FALSE
-#define CURL_SB_ACCUM(x,c) \
- do { \
- if(x->subpointer < (x->subbuffer + sizeof x->subbuffer)) \
- *x->subpointer++ = (c); \
+#define CURL_SB_ACCUM(x,c) \
+ do { \
+ if(x->subpointer < (x->subbuffer + sizeof(x->subbuffer))) \
+ *x->subpointer++ = (c); \
} WHILE_FALSE
#define CURL_SB_GET(x) ((*x->subpointer++)&0xff)
@@ -92,6 +88,7 @@
#endif
#ifdef USE_WINSOCK
+typedef WSAEVENT (WINAPI *WSOCK2_EVENT)(void);
typedef FARPROC WSOCK2_FUNC;
static CURLcode check_wsock2(struct Curl_easy *data);
#endif
@@ -109,8 +106,10 @@ static void printoption(struct Curl_easy *data,
static void negotiate(struct connectdata *);
static void send_negotiation(struct connectdata *, int cmd, int option);
-static void set_local_option(struct connectdata *, int cmd, int option);
-static void set_remote_option(struct connectdata *, int cmd, int option);
+static void set_local_option(struct connectdata *conn,
+ int option, int newstate);
+static void set_remote_option(struct connectdata *conn,
+ int option, int newstate);
static void printsub(struct Curl_easy *data,
int direction, unsigned char *pointer,
@@ -311,9 +310,6 @@ static void negotiate(struct connectdata *conn)
static void printoption(struct Curl_easy *data,
const char *direction, int cmd, int option)
{
- const char *fmt;
- const char *opt;
-
if(data->set.verbose) {
if(cmd == CURL_IAC) {
if(CURL_TELCMD_OK(option))
@@ -322,9 +318,12 @@ static void printoption(struct Curl_easy *data,
infof(data, "%s IAC %d\n", direction, option);
}
else {
- fmt = (cmd == CURL_WILL) ? "WILL" : (cmd == CURL_WONT) ? "WONT" :
- (cmd == CURL_DO) ? "DO" : (cmd == CURL_DONT) ? "DONT" : 0;
+ const char *fmt = (cmd == CURL_WILL) ? "WILL" :
+ (cmd == CURL_WONT) ? "WONT" :
+ (cmd == CURL_DO) ? "DO" :
+ (cmd == CURL_DONT) ? "DONT" : 0;
if(fmt) {
+ const char *opt;
if(CURL_TELOPT_OK(option))
opt = CURL_TELOPT(option);
else if(option == CURL_TELOPT_EXOPL)
@@ -348,7 +347,6 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)
{
unsigned char buf[3];
ssize_t bytes_written;
- int err;
struct Curl_easy *data = conn->data;
buf[0] = CURL_IAC;
@@ -357,7 +355,7 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)
bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3);
if(bytes_written < 0) {
- err = SOCKERRNO;
+ int err = SOCKERRNO;
failf(data,"Sending data failed (%d)",err);
}
@@ -710,9 +708,8 @@ static void printsub(struct Curl_easy *data,
unsigned char *pointer, /* where suboption data is */
size_t length) /* length of suboption data */
{
- unsigned int i = 0;
-
if(data->set.verbose) {
+ unsigned int i = 0;
if(direction) {
infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
if(length >= 3) {
@@ -764,7 +761,7 @@ static void printsub(struct Curl_easy *data,
switch(pointer[0]) {
case CURL_TELOPT_NAWS:
if(length > 4)
- infof(data, "Width: %hu ; Height: %hu", (pointer[1]<<8) | pointer[2],
+ infof(data, "Width: %d ; Height: %d", (pointer[1]<<8) | pointer[2],
(pointer[3]<<8) | pointer[4]);
break;
default:
@@ -928,7 +925,6 @@ static void suboption(struct connectdata *conn)
unsigned char temp[2048];
ssize_t bytes_written;
size_t len;
- size_t tmplen;
int err;
char varname[128] = "";
char varval[128] = "";
@@ -968,7 +964,7 @@ static void suboption(struct connectdata *conn)
len = 4;
for(v = tn->telnet_vars; v; v = v->next) {
- tmplen = (strlen(v->data) + 1);
+ size_t tmplen = (strlen(v->data) + 1);
/* Add the variable only if it fits */
if(len + tmplen < (int)sizeof(temp)-6) {
if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
@@ -1017,7 +1013,7 @@ static void sendsuboption(struct connectdata *conn, int option)
CURL_SB_ACCUM(tn, CURL_IAC);
CURL_SB_ACCUM(tn, CURL_SB);
CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
- /* We must deal either with litte or big endian processors */
+ /* We must deal either with little or big endian processors */
/* Window size must be sent according to the 'network order' */
x = htons(tn->subopt_wsx);
y = htons(tn->subopt_wsy);
@@ -1223,7 +1219,7 @@ CURLcode telrcv(struct connectdata *conn,
static CURLcode send_telnet_data(struct connectdata *conn,
char *buffer, ssize_t nread)
{
- ssize_t escapes, i, j, outlen;
+ ssize_t escapes, i, outlen;
unsigned char *outbuf = NULL;
CURLcode result = CURLE_OK;
ssize_t bytes_written, total_written;
@@ -1238,6 +1234,7 @@ static CURLcode send_telnet_data(struct connectdata *conn,
if(outlen == nread)
outbuf = (unsigned char *)buffer;
else {
+ ssize_t j;
outbuf = malloc(nread + escapes + 1);
if(!outbuf)
return CURLE_OUT_OF_MEMORY;
@@ -1306,7 +1303,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
#ifdef USE_WINSOCK
HMODULE wsock2;
WSOCK2_FUNC close_event_func;
- WSOCK2_FUNC create_event_func;
+ WSOCK2_EVENT create_event_func;
WSOCK2_FUNC event_select_func;
WSOCK2_FUNC enum_netevents_func;
WSAEVENT event_handle;
@@ -1315,7 +1312,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
HANDLE objs[2];
DWORD obj_count;
DWORD wait_timeout;
- DWORD waitret;
DWORD readfile_read;
int err;
#else
@@ -1361,7 +1357,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
}
/* Grab a pointer to WSACreateEvent */
- create_event_func = GetProcAddress(wsock2, "WSACreateEvent");
+ create_event_func =
+ CURLX_FUNCTION_CAST(WSOCK2_EVENT,
+ (GetProcAddress(wsock2, "WSACreateEvent")));
if(create_event_func == NULL) {
failf(data, "failed to find WSACreateEvent function (%u)", GetLastError());
FreeLibrary(wsock2);
@@ -1438,7 +1436,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
/* Keep on listening and act on events */
while(keepon) {
const DWORD buf_size = (DWORD)data->set.buffer_size;
- waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
+ DWORD waitret = WaitForMultipleObjects(obj_count, objs,
+ FALSE, wait_timeout);
switch(waitret) {
case WAIT_TIMEOUT:
{
@@ -1607,7 +1606,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
case 0: /* timeout */
pfd[0].revents = 0;
pfd[1].revents = 0;
- /* fall through */
+ /* FALLTHROUGH */
default: /* read! */
if(pfd[0].revents & POLLIN) {
/* read data from network */
diff --git a/Utilities/cmcurl/lib/tftp.c b/Utilities/cmcurl/lib/tftp.c
index b32960f82b..e5bc80b02b 100644
--- a/Utilities/cmcurl/lib/tftp.c
+++ b/Utilities/cmcurl/lib/tftp.c
@@ -451,7 +451,6 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
ssize_t senddata;
const char *mode = "octet";
char *filename;
- char buf[64];
struct Curl_easy *data = state->conn->data;
CURLcode result = CURLE_OK;
@@ -504,6 +503,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
/* optional addition of TFTP options */
if(!data->set.tftp_no_options) {
+ char buf[64];
/* add tsize option */
if(data->set.upload && (data->state.infilesize != -1))
snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
@@ -710,10 +710,9 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
{
struct Curl_easy *data = state->conn->data;
ssize_t sbytes;
- int rblock;
CURLcode result = CURLE_OK;
struct SingleRequest *k = &data->req;
- int cb; /* Bytes currently read */
+ size_t cb; /* Bytes currently read */
switch(event) {
@@ -721,7 +720,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
case TFTP_EVENT_OACK:
if(event == TFTP_EVENT_ACK) {
/* Ack the packet */
- rblock = getrpacketblock(&state->rpacket);
+ int rblock = getrpacketblock(&state->rpacket);
if(rblock != state->block &&
/* There's a bug in tftpd-hpa that causes it to send us an ack for
@@ -766,7 +765,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
state->retries = 0;
setpacketevent(&state->spacket, TFTP_EVENT_DATA);
setpacketblock(&state->spacket, state->block);
- if(state->block > 1 && state->sbytes < (int)state->blksize) {
+ if(state->block > 1 && state->sbytes < state->blksize) {
state->state = TFTP_STATE_FIN;
return CURLE_OK;
}
@@ -782,7 +781,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
&cb);
if(result)
return result;
- state->sbytes += cb;
+ state->sbytes += (int)cb;
state->conn->data->req.upload_fromhere += cb;
} while(state->sbytes < state->blksize && cb != 0);
@@ -969,7 +968,7 @@ static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
static CURLcode tftp_connect(struct connectdata *conn, bool *done)
{
tftp_state_data_t *state;
- int blksize, rc;
+ int blksize;
blksize = TFTP_BLKSIZE_DEFAULT;
@@ -1028,8 +1027,8 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
* assume uses the same IP version and thus hopefully this works for both
* IPv4 and IPv6...
*/
- rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
- conn->ip_addr->ai_addrlen);
+ int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
+ conn->ip_addr->ai_addrlen);
if(rc) {
failf(conn->data, "bind() failed; %s",
Curl_strerror(conn, SOCKERRNO));
@@ -1148,8 +1147,11 @@ static CURLcode tftp_receive_packet(struct connectdata *conn)
case TFTP_EVENT_ERROR:
{
unsigned short error = getrpacketblock(&state->rpacket);
+ char *str = (char *)state->rpacket.data + 4;
+ size_t strn = state->rbytes - 4;
state->error = (tftp_error_t)error;
- infof(data, "%s\n", (const char *)state->rpacket.data + 4);
+ if(Curl_strnlen(str, strn) < strn)
+ infof(data, "TFTP error: %s\n", str);
break;
}
case TFTP_EVENT_ACK:
@@ -1221,7 +1223,6 @@ static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
**********************************************************/
static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
{
- int rc;
tftp_event_t event;
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
@@ -1245,7 +1246,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
}
else {
/* no timeouts to handle, check our socket */
- rc = SOCKET_READABLE(state->sockfd, 0);
+ int rc = SOCKET_READABLE(state->sockfd, 0);
if(rc == -1) {
/* bail out */
@@ -1368,7 +1369,6 @@ static CURLcode tftp_setup_connection(struct connectdata * conn)
{
struct Curl_easy *data = conn->data;
char *type;
- char command;
conn->socktype = SOCK_DGRAM; /* UDP datagram based */
@@ -1380,6 +1380,7 @@ static CURLcode tftp_setup_connection(struct connectdata * conn)
type = strstr(conn->host.rawalloc, ";mode=");
if(type) {
+ char command;
*type = 0; /* it was in the middle of the hostname */
command = Curl_raw_toupper(type[6]);
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c
index 131f2dc7c0..7159d5c823 100644
--- a/Utilities/cmcurl/lib/transfer.c
+++ b/Utilities/cmcurl/lib/transfer.c
@@ -106,15 +106,26 @@ char *Curl_checkheaders(const struct connectdata *conn,
}
#endif
+CURLcode Curl_get_upload_buffer(struct Curl_easy *data)
+{
+ if(!data->state.ulbuf) {
+ data->state.ulbuf = malloc(data->set.upload_buffer_size);
+ if(!data->state.ulbuf)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ return CURLE_OK;
+}
+
/*
* This function will call the read callback to fill our buffer with data
* to upload.
*/
-CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
+ size_t *nreadp)
{
struct Curl_easy *data = conn->data;
- size_t buffersize = (size_t)bytes;
- int nread;
+ size_t buffersize = bytes;
+ size_t nread;
#ifdef CURL_DOES_CONVERSIONS
bool sending_http_headers = FALSE;
@@ -134,11 +145,9 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
}
- /* this function returns a size_t, so we typecast to int to prevent warnings
- with picky compilers */
Curl_set_in_callback(data, true);
- nread = (int)data->state.fread_func(data->req.upload_fromhere, 1,
- buffersize, data->state.in);
+ nread = data->state.fread_func(data->req.upload_fromhere, 1,
+ buffersize, data->state.in);
Curl_set_in_callback(data, false);
if(nread == CURL_READFUNC_ABORT) {
@@ -167,7 +176,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
return CURLE_OK; /* nothing was read */
}
- else if((size_t)nread > buffersize) {
+ else if(nread > buffersize) {
/* the read function returned a too large value */
*nreadp = 0;
failf(data, "read function returned funny value");
@@ -226,13 +235,13 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
#ifdef CURL_DOES_CONVERSIONS
{
CURLcode result;
- int length;
+ size_t length;
if(data->set.prefer_ascii)
/* translate the protocol and data */
length = nread;
else
/* just translate the protocol portion */
- length = (int)strlen(hexbuffer);
+ length = strlen(hexbuffer);
result = Curl_convert_to_network(data, data->req.upload_fromhere,
length);
/* Curl_convert_to_network calls failf if unsuccessful */
@@ -247,7 +256,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
infof(data, "Signaling end of chunked upload via terminating chunk.\n");
}
- nread += (int)strlen(endofline_native); /* for the added end of line */
+ nread += strlen(endofline_native); /* for the added end of line */
}
#ifdef CURL_DOES_CONVERSIONS
else if((data->set.prefer_ascii) && (!sending_http_headers)) {
@@ -444,7 +453,6 @@ static CURLcode readwrite_data(struct Curl_easy *data,
CURLcode result = CURLE_OK;
ssize_t nread; /* number of bytes read */
size_t excess = 0; /* excess bytes read */
- bool is_empty_data = FALSE;
bool readmore = FALSE; /* used by RTP to signal for more data */
int maxloops = 100;
@@ -454,6 +462,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* This is where we loop until we have read everything there is to
read or we get a CURLE_AGAIN */
do {
+ bool is_empty_data = FALSE;
size_t buffersize = data->set.buffer_size;
size_t bytestoread = buffersize;
@@ -660,14 +669,14 @@ static CURLcode readwrite_data(struct Curl_easy *data,
if(data->set.verbose) {
if(k->badheader) {
Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
- (size_t)k->hbuflen, conn);
+ (size_t)k->hbuflen);
if(k->badheader == HEADER_PARTHEADER)
Curl_debug(data, CURLINFO_DATA_IN,
- k->str, (size_t)nread, conn);
+ k->str, (size_t)nread);
}
else
Curl_debug(data, CURLINFO_DATA_IN,
- k->str, (size_t)nread, conn);
+ k->str, (size_t)nread);
}
#ifndef CURL_DISABLE_HTTP
@@ -797,7 +806,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
nread);
}
}
- else
+ else if(!k->ignorebody)
result = Curl_unencode_write(conn, k->writer_stack, k->str, nread);
}
k->badheader = HEADER_NORMAL; /* taken care of now */
@@ -869,6 +878,26 @@ static CURLcode done_sending(struct connectdata *conn,
return CURLE_OK;
}
+#ifdef WIN32
+#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
+#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
+#endif
+
+static void win_update_buffer_size(curl_socket_t sockfd)
+{
+ int result;
+ ULONG ideal;
+ DWORD ideallen;
+ result = WSAIoctl(sockfd, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0,
+ &ideal, sizeof(ideal), &ideallen, 0, 0);
+ if(result == 0) {
+ setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
+ (const char *)&ideal, sizeof(ideal));
+ }
+}
+#else
+#define win_update_buffer_size(x)
+#endif
/*
* Send data to upload to the server, when the socket is writable.
@@ -894,13 +923,16 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
/* only read more data if there's no upload data already
present in the upload buffer */
if(0 == k->upload_present) {
+ result = Curl_get_upload_buffer(data);
+ if(result)
+ return result;
/* init the "upload from here" pointer */
- k->upload_fromhere = data->state.uploadbuffer;
+ k->upload_fromhere = data->state.ulbuf;
if(!k->upload_done) {
/* HTTP pollution, this should be written nicer to become more
protocol agnostic. */
- int fillcount;
+ size_t fillcount;
struct HTTP *http = k->protop;
if((k->exp100 == EXP100_SENDING_REQUEST) &&
@@ -931,7 +963,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
if(result)
return result;
- nread = (ssize_t)fillcount;
+ nread = fillcount;
}
else
nread = 0; /* we're done uploading/reading */
@@ -959,7 +991,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
(data->set.crlf))) {
/* Do we need to allocate a scratch buffer? */
if(!data->state.scratch) {
- data->state.scratch = malloc(2 * data->set.buffer_size);
+ data->state.scratch = malloc(2 * UPLOAD_BUFSIZE);
if(!data->state.scratch) {
failf(data, "Failed to alloc scratch buffer!");
@@ -1020,14 +1052,15 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
k->upload_fromhere, /* buffer pointer */
k->upload_present, /* buffer size */
&bytes_written); /* actually sent */
-
if(result)
return result;
+ win_update_buffer_size(conn->writesockfd);
+
if(data->set.verbose)
/* show the data before we change the pointer upload_fromhere */
Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
- (size_t)bytes_written, conn);
+ (size_t)bytes_written);
k->writebytecount += bytes_written;
@@ -1050,7 +1083,10 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
}
else {
/* we've uploaded that buffer now */
- k->upload_fromhere = data->state.uploadbuffer;
+ result = Curl_get_upload_buffer(data);
+ if(result)
+ return result;
+ k->upload_fromhere = data->state.ulbuf;
k->upload_present = 0; /* no more bytes left */
if(k->upload_done) {
@@ -1482,7 +1518,7 @@ static size_t strlen_url(const char *url, bool relative)
switch(*ptr) {
case '?':
left = FALSE;
- /* fall through */
+ /* FALLTHROUGH */
default:
if(urlchar_needs_escaping(*ptr))
newlen += 2;
@@ -1527,7 +1563,7 @@ static void strcpy_url(char *output, const char *url, bool relative)
switch(*iptr) {
case '?':
left = FALSE;
- /* fall through */
+ /* FALLTHROUGH */
default:
if(urlchar_needs_escaping(*iptr)) {
snprintf(optr, 4, "%%%02x", *iptr);
diff --git a/Utilities/cmcurl/lib/transfer.h b/Utilities/cmcurl/lib/transfer.h
index 9ba398d27d..9263e5b69f 100644
--- a/Utilities/cmcurl/lib/transfer.h
+++ b/Utilities/cmcurl/lib/transfer.h
@@ -51,9 +51,11 @@ int Curl_single_getsock(const struct connectdata *conn,
curl_socket_t *socks,
int numsocks);
CURLcode Curl_readrewind(struct connectdata *conn);
-CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
+ size_t *nreadp);
CURLcode Curl_retry_request(struct connectdata *conn, char **url);
bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
+CURLcode Curl_get_upload_buffer(struct Curl_easy *data);
/* This sets up a forthcoming transfer */
void
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
index 701f83ab3b..f159008898 100644
--- a/Utilities/cmcurl/lib/url.c
+++ b/Utilities/cmcurl/lib/url.c
@@ -127,7 +127,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
static void conn_free(struct connectdata *conn);
static void free_fixed_hostname(struct hostname *host);
-static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
static CURLcode parse_url_login(struct Curl_easy *data,
struct connectdata *conn,
char **userptr, char **passwdptr,
@@ -368,11 +367,9 @@ CURLcode Curl_close(struct Curl_easy *data)
Curl_safefree(data->state.buffer);
Curl_safefree(data->state.headerbuff);
-
+ Curl_safefree(data->state.ulbuf);
Curl_flush_cookies(data, 1);
-
Curl_digest_cleanup(data);
-
Curl_safefree(data->info.contenttype);
Curl_safefree(data->info.wouldredirect);
@@ -535,6 +532,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->expect_100_timeout = 1000L; /* Wait for a second by default. */
set->sep_headers = TRUE; /* separated header lists by default */
set->buffer_size = READBUFFER_SIZE;
+ set->upload_buffer_size = UPLOAD_BUFSIZE;
set->happy_eyeballs_timeout = CURL_HET_DEFAULT;
Curl_http2_init_userset(set);
@@ -734,20 +732,23 @@ static void conn_free(struct connectdata *conn)
* primary connection, like when freeing room in the connection cache or
* killing of a dead old connection.
*
+ * A connection needs an easy handle when closing down. We support this passed
+ * in separately since the connection to get closed here is often already
+ * disassociated from an easy handle.
+ *
* This function MUST NOT reset state in the Curl_easy struct if that
* isn't strictly bound to the life-time of *this* particular connection.
*
*/
-CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
+CURLcode Curl_disconnect(struct Curl_easy *data,
+ struct connectdata *conn, bool dead_connection)
{
- struct Curl_easy *data;
if(!conn)
return CURLE_OK; /* this is closed and fine already */
- data = conn->data;
if(!data) {
- DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
+ DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n"));
return CURLE_OK;
}
@@ -755,13 +756,12 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
* If this connection isn't marked to force-close, leave it open if there
* are other users of it
*/
- if(!conn->bits.close &&
- (conn->send_pipe.size + conn->recv_pipe.size)) {
- DEBUGF(infof(data, "Curl_disconnect, usecounter: %d\n",
- conn->send_pipe.size + conn->recv_pipe.size));
+ if(CONN_INUSE(conn) && !dead_connection) {
+ DEBUGF(infof(data, "Curl_disconnect when inuse: %zu\n", CONN_INUSE(conn)));
return CURLE_OK;
}
+ conn->data = data;
if(conn->dns_entry != NULL) {
Curl_resolv_unlock(data, conn->dns_entry);
conn->dns_entry = NULL;
@@ -787,16 +787,12 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
free_fixed_hostname(&conn->http_proxy.host);
free_fixed_hostname(&conn->socks_proxy.host);
+ DEBUGASSERT(conn->data == data);
+ /* this assumes that the pointer is still there after the connection was
+ detected from the cache */
Curl_ssl_close(conn, FIRSTSOCKET);
- /* Indicate to all handles on the pipe that we're dead */
- if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
- signalPipeClose(&conn->send_pipe, TRUE);
- signalPipeClose(&conn->recv_pipe, TRUE);
- }
-
conn_free(conn);
-
return CURLE_OK;
}
@@ -848,6 +844,7 @@ static int IsPipeliningPossible(const struct Curl_easy *handle,
return avail;
}
+/* Returns non-zero if a handle was removed */
int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
struct curl_llist *pipeline)
{
@@ -884,6 +881,16 @@ static void Curl_printPipeline(struct curl_llist *pipeline)
static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
{
struct curl_llist_element *curr = pipeline->head;
+#ifdef DEBUGBUILD
+ {
+ struct curl_llist_element *p = pipeline->head;
+ while(p) {
+ struct Curl_easy *e = p->ptr;
+ DEBUGASSERT(GOOD_EASY_HANDLE(e));
+ p = p->next;
+ }
+ }
+#endif
if(curr) {
return (struct Curl_easy *) curr->ptr;
}
@@ -896,41 +903,22 @@ static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
void Curl_getoff_all_pipelines(struct Curl_easy *data,
struct connectdata *conn)
{
- bool recv_head = (conn->readchannel_inuse &&
- Curl_recvpipe_head(data, conn));
- bool send_head = (conn->writechannel_inuse &&
- Curl_sendpipe_head(data, conn));
-
- if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head)
- Curl_pipeline_leave_read(conn);
- if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head)
- Curl_pipeline_leave_write(conn);
-}
-
-static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
-{
- struct curl_llist_element *curr;
-
- if(!pipeline)
+ if(!conn->bundle)
return;
+ if(conn->bundle->multiuse == BUNDLE_PIPELINING) {
+ bool recv_head = (conn->readchannel_inuse &&
+ Curl_recvpipe_head(data, conn));
+ bool send_head = (conn->writechannel_inuse &&
+ Curl_sendpipe_head(data, conn));
- curr = pipeline->head;
- while(curr) {
- struct curl_llist_element *next = curr->next;
- struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
-
-#ifdef DEBUGBUILD /* debug-only code */
- if(data->magic != CURLEASY_MAGIC_NUMBER) {
- /* MAJOR BADNESS */
- infof(data, "signalPipeClose() found BAAD easy handle\n");
- }
-#endif
-
- if(pipe_broke)
- data->state.pipe_broke = TRUE;
- Curl_multi_handlePipeBreak(data);
- Curl_llist_remove(pipeline, curr, NULL);
- curr = next;
+ if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head)
+ Curl_pipeline_leave_read(conn);
+ if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head)
+ Curl_pipeline_leave_write(conn);
+ }
+ else {
+ (void)Curl_removeHandleFromPipeline(data, &conn->recv_pipe);
+ (void)Curl_removeHandleFromPipeline(data, &conn->send_pipe);
}
}
@@ -959,12 +947,13 @@ static bool extract_if_dead(struct connectdata *conn,
struct Curl_easy *data)
{
size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size;
- if(!pipeLen && !conn->inuse) {
+ if(!pipeLen && !CONN_INUSE(conn)) {
/* The check for a dead socket makes sense only if there are no
handles in pipeline and the connection isn't already marked in
use */
bool dead;
+ conn->data = data;
if(conn->handler->connection_check) {
/* The protocol has a special method for checking the state of the
connection. Use it to check if the connection is dead. */
@@ -979,9 +968,9 @@ static bool extract_if_dead(struct connectdata *conn,
}
if(dead) {
- conn->data = data;
infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
Curl_conncache_remove_conn(conn, FALSE);
+ conn->data = NULL; /* detach */
return TRUE;
}
}
@@ -1025,7 +1014,7 @@ static void prune_dead_connections(struct Curl_easy *data)
while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
call_extract_if_dead)) {
/* disconnect it */
- (void)Curl_disconnect(prune.extracted, /* dead_connection */TRUE);
+ (void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE);
}
data->state.conn_cache->last_cleanup = now;
}
@@ -1139,7 +1128,7 @@ ConnectionExists(struct Curl_easy *data,
if(extract_if_dead(check, data)) {
/* disconnect it */
- (void)Curl_disconnect(check, /* dead_connection */TRUE);
+ (void)Curl_disconnect(data, check, /* dead_connection */TRUE);
continue;
}
@@ -1267,12 +1256,12 @@ ConnectionExists(struct Curl_easy *data,
}
}
- if(!canpipe && check->inuse)
+ if(!canpipe && CONN_INUSE(check))
/* this request can't be pipelined but the checked connection is
already in use so we skip it */
continue;
- if((check->inuse) && (check->data->multi != needle->data->multi))
+ if(CONN_INUSE(check) && (check->data->multi != needle->data->multi))
/* this could be subject for pipeline/multiplex use, but only
if they belong to the same multi handle */
continue;
@@ -1464,7 +1453,7 @@ ConnectionExists(struct Curl_easy *data,
if(chosen) {
/* mark it as used before releasing the lock */
- chosen->inuse = TRUE;
+ chosen->data = data; /* own it! */
Curl_conncache_unlock(needle);
*usethis = chosen;
return TRUE; /* yes, we found one to use! */
@@ -1554,7 +1543,11 @@ int Curl_protocol_getsock(struct connectdata *conn,
{
if(conn->handler->proto_getsock)
return conn->handler->proto_getsock(conn, socks, numsocks);
- return GETSOCK_BLANK;
+ /* Backup getsock logic. Since there is a live socket in use, we must wait
+ for it or it will be removed from watching when the multi_socket API is
+ used. */
+ socks[0] = conn->sock[FIRSTSOCKET];
+ return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
}
int Curl_doing_getsock(struct connectdata *conn,
@@ -1999,7 +1992,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
char *fragment;
char *path = data->state.path;
char *query;
- int i;
int rc;
const char *protop = "";
CURLcode result;
@@ -2051,6 +2043,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
; /* do nothing */
}
else { /* check for a scheme */
+ int i;
for(i = 0; i < 16 && data->change.url[i]; ++i) {
if(data->change.url[i] == '/')
break;
@@ -2203,7 +2196,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
size_t s = strlen(slashbuf);
protop = protobuf;
if(s != 2) {
- infof(data, "Unwillingly accepted illegal URL using %d slash%s!\n",
+ infof(data, "Unwillingly accepted illegal URL using %zu slash%s!\n",
s, s>1?"es":"");
if(data->change.url_alloc)
@@ -2449,7 +2442,7 @@ static CURLcode setup_range(struct Curl_easy *data)
free(s->range);
if(s->resume_from)
- s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
+ s->range = aprintf("%" CURL_FORMAT_CURL_OFF_T "-", s->resume_from);
else
s->range = strdup(data->set.str[STRING_SET_RANGE]);
@@ -2481,18 +2474,6 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
{
const struct Curl_handler * p;
CURLcode result;
- struct Curl_easy *data = conn->data;
-
- /* in some case in the multi state-machine, we go back to the CONNECT state
- and then a second (or third or...) call to this function will be made
- without doing a DISCONNECT or DONE in between (since the connection is
- yet in place) and therefore this function needs to first make sure
- there's no lingering previous data allocated. */
- Curl_free_request_state(data);
-
- memset(&data->req, 0, sizeof(struct SingleRequest));
- data->req.maxdownload = -1;
-
conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
/* Perform setup complement if some. */
@@ -2539,14 +2520,13 @@ static bool check_noproxy(const char *name, const char *no_proxy)
* not be proxied, or an asterisk to override
* all proxy variables)
*/
- size_t tok_start;
- size_t tok_end;
- const char *separator = ", ";
- size_t no_proxy_len;
- size_t namelen;
- char *endptr;
-
if(no_proxy && no_proxy[0]) {
+ size_t tok_start;
+ size_t tok_end;
+ const char *separator = ", ";
+ size_t no_proxy_len;
+ size_t namelen;
+ char *endptr;
if(strcasecompare("*", no_proxy)) {
return TRUE;
}
@@ -3166,6 +3146,13 @@ static CURLcode parse_url_login(struct Curl_easy *data,
if(userp) {
char *newname;
+ if(data->set.disallow_username_in_url) {
+ failf(data, "Option DISALLOW_USERNAME_IN_URL is set "
+ "and url contains username.");
+ result = CURLE_LOGIN_DENIED;
+ goto out;
+ }
+
/* We have a user in the URL */
conn->bits.userpwd_in_url = TRUE;
conn->bits.user_passwd = TRUE; /* enable user+password */
@@ -3982,6 +3969,7 @@ static void reuse_conn(struct connectdata *old_conn,
Curl_safefree(old_conn->user);
Curl_safefree(old_conn->passwd);
+ Curl_safefree(old_conn->options);
Curl_safefree(old_conn->http_proxy.user);
Curl_safefree(old_conn->socks_proxy.user);
Curl_safefree(old_conn->http_proxy.passwd);
@@ -4297,7 +4285,9 @@ static CURLcode create_conn(struct Curl_easy *data,
conn->data = data;
conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
- Curl_conncache_add_conn(data->state.conn_cache, conn);
+ result = Curl_conncache_add_conn(data->state.conn_cache, conn);
+ if(result)
+ goto out;
/*
* Setup whatever necessary for a resumed transfer
@@ -4343,6 +4333,10 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
data->set.proxy_ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
+ data->set.ssl.primary.cipher_list13 =
+ data->set.str[STRING_SSL_CIPHER13_LIST_ORIG];
+ data->set.proxy_ssl.primary.cipher_list13 =
+ data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
@@ -4468,13 +4462,11 @@ static CURLcode create_conn(struct Curl_easy *data,
conn_candidate = Curl_conncache_extract_bundle(data, bundle);
Curl_conncache_unlock(conn);
- if(conn_candidate) {
- /* Set the connection's owner correctly, then kill it */
- conn_candidate->data = data;
- (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
- }
+ if(conn_candidate)
+ (void)Curl_disconnect(data, conn_candidate,
+ /* dead_connection */ FALSE);
else {
- infof(data, "No more connections allowed to host: %d\n",
+ infof(data, "No more connections allowed to host: %zu\n",
max_host_connections);
connections_available = FALSE;
}
@@ -4491,12 +4483,9 @@ static CURLcode create_conn(struct Curl_easy *data,
/* The cache is full. Let's see if we can kill a connection. */
conn_candidate = Curl_conncache_extract_oldest(data);
-
- if(conn_candidate) {
- /* Set the connection's owner correctly, then kill it */
- conn_candidate->data = data;
- (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
- }
+ if(conn_candidate)
+ (void)Curl_disconnect(data, conn_candidate,
+ /* dead_connection */ FALSE);
else {
infof(data, "No connections available in cache\n");
connections_available = FALSE;
@@ -4513,14 +4502,13 @@ static CURLcode create_conn(struct Curl_easy *data,
goto out;
}
else {
- /* Mark the connection as used, before we add it */
- conn->inuse = TRUE;
-
/*
* This is a brand new connection, so let's store it in the connection
* cache of ours!
*/
- Curl_conncache_add_conn(data->state.conn_cache, conn);
+ result = Curl_conncache_add_conn(data->state.conn_cache, conn);
+ if(result)
+ goto out;
}
#if defined(USE_NTLM)
@@ -4656,12 +4644,16 @@ CURLcode Curl_connect(struct Curl_easy *data,
*asyncp = FALSE; /* assume synchronous resolves by default */
+ /* init the single-transfer specific data */
+ Curl_free_request_state(data);
+ memset(&data->req, 0, sizeof(struct SingleRequest));
+ data->req.maxdownload = -1;
+
/* call the stuff that needs to be called */
result = create_conn(data, in_connect, asyncp);
if(!result) {
- /* no error */
- if((*in_connect)->send_pipe.size || (*in_connect)->recv_pipe.size)
+ if(CONN_INUSE(*in_connect))
/* pipelining */
*protocol_done = TRUE;
else if(!*asyncp) {
@@ -4676,12 +4668,11 @@ CURLcode Curl_connect(struct Curl_easy *data,
*in_connect = NULL;
return result;
}
-
- if(result && *in_connect) {
- /* We're not allowed to return failure with memory left allocated
- in the connectdata struct, free those here */
- Curl_disconnect(*in_connect, FALSE); /* close the connection */
- *in_connect = NULL; /* return a NULL */
+ else if(result && *in_connect) {
+ /* We're not allowed to return failure with memory left allocated in the
+ connectdata struct, free those here */
+ Curl_disconnect(data, *in_connect, TRUE);
+ *in_connect = NULL; /* return a NULL */
}
return result;
@@ -4701,16 +4692,18 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
{
struct SingleRequest *k = &data->req;
- conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
- use */
+ if(conn) {
+ conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
+ use */
+ /* if the protocol used doesn't support wildcards, switch it off */
+ if(data->state.wildcardmatch &&
+ !(conn->handler->flags & PROTOPT_WILDCARD))
+ data->state.wildcardmatch = FALSE;
+ }
data->state.done = FALSE; /* *_done() is not called yet */
data->state.expect100header = FALSE;
- /* if the protocol used doesn't support wildcards, switch it off */
- if(data->state.wildcardmatch &&
- !(conn->handler->flags & PROTOPT_WILDCARD))
- data->state.wildcardmatch = FALSE;
if(data->set.opt_no_body)
/* in HTTP lingo, no body means using the HEAD request... */
diff --git a/Utilities/cmcurl/lib/url.h b/Utilities/cmcurl/lib/url.h
index a70bd5466a..ef3ebf03e1 100644
--- a/Utilities/cmcurl/lib/url.h
+++ b/Utilities/cmcurl/lib/url.h
@@ -39,7 +39,8 @@ void Curl_freeset(struct Curl_easy * data);
CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
CURLcode Curl_connect(struct Curl_easy *, struct connectdata **,
bool *async, bool *protocol_connect);
-CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
+CURLcode Curl_disconnect(struct Curl_easy *data,
+ struct connectdata *, bool dead_connection);
CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
diff --git a/Utilities/cmcurl/lib/urldata.h b/Utilities/cmcurl/lib/urldata.h
index 7fae00fd96..67db3b2fca 100644
--- a/Utilities/cmcurl/lib/urldata.h
+++ b/Utilities/cmcurl/lib/urldata.h
@@ -80,6 +80,7 @@
#define RESP_TIMEOUT (1800*1000)
#include "cookie.h"
+#include "psl.h"
#include "formdata.h"
#ifdef HAVE_NETINET_IN_H
@@ -142,8 +143,13 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
#endif /* HAVE_LIBSSH2_H */
/* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as
- it needs to hold a full buffer as could be sent in a write callback */
-#define UPLOAD_BUFSIZE CURL_MAX_WRITE_SIZE
+ it needs to hold a full buffer as could be sent in a write callback.
+
+ The size was 16KB for many years but was bumped to 64KB because it makes
+ libcurl able to do significantly faster uploads in some circumstances. Even
+ larger buffers can help further, but this is deemed a fair memory/speed
+ compromise. */
+#define UPLOAD_BUFSIZE 65536
/* The "master buffer" is for HTTP pipelining */
#define MASTERBUF_SIZE 16384
@@ -156,11 +162,6 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
#define GOOD_EASY_HANDLE(x) \
((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
-/* Some convenience macros to get the larger/smaller value out of two given.
- We prefix with CURL to prevent name collisions. */
-#define CURLMAX(x,y) ((x)>(y)?(x):(y))
-#define CURLMIN(x,y) ((x)<(y)?(x):(y))
-
#ifdef HAVE_GSSAPI
/* Types needed for krb5-ftp connections */
struct krb5buffer {
@@ -226,6 +227,7 @@ struct ssl_primary_config {
char *random_file; /* path to file containing "random" data */
char *egdsocket; /* path to file containing the EGD daemon socket */
char *cipher_list; /* list of ciphers to use */
+ char *cipher_list13; /* list of TLS 1.3 cipher suites to use */
};
struct ssl_config_data {
@@ -779,11 +781,12 @@ struct connectdata {
curl_closesocket_callback fclosesocket; /* function closing the socket(s) */
void *closesocket_client;
- bool inuse; /* This is a marker for the connection cache logic. If this is
- TRUE this handle is being used by one or more easy handles
- and can only used by any other easy handle without careful
- consideration (== only for pipelining/multiplexing) and it
- cannot be used by another multi handle! */
+ /* This is used by the connection cache logic. If this returns TRUE, this
+ handle is being used by one or more easy handles and can only used by any
+ other easy handle without careful consideration (== only for
+ pipelining/multiplexing) and it cannot be used by another multi
+ handle! */
+#define CONN_INUSE(c) ((c)->send_pipe.size + (c)->recv_pipe.size)
/**** Fields set when inited and not modified again */
long connection_id; /* Contains a unique number to make it easier to
@@ -1222,7 +1225,7 @@ struct UrlState {
size_t headersize; /* size of the allocation */
char *buffer; /* download buffer */
- char uploadbuffer[UPLOAD_BUFSIZE + 1]; /* upload buffer */
+ char *ulbuf; /* alloced upload buffer or NULL */
curl_off_t current_speed; /* the ProgressShow() function sets this,
bytes / second */
bool this_is_a_follow; /* this is a followed Location: request */
@@ -1265,7 +1268,7 @@ struct UrlState {
void *resolver; /* resolver state, if it is used in the URL state -
ares_channel f.e. */
-#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+#if defined(USE_OPENSSL)
/* void instead of ENGINE to avoid bleeding OpenSSL into this header */
void *engine;
#endif /* USE_OPENSSL */
@@ -1284,9 +1287,6 @@ struct UrlState {
involved in this request */
bool expect100header; /* TRUE if we added Expect: 100-continue */
- bool pipe_broke; /* TRUE if the connection we were pipelined on broke
- and we need to restart from the beginning */
-
#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
!defined(__SYMBIAN32__)
/* do FTP line-end conversions on most platforms */
@@ -1346,7 +1346,7 @@ struct DynamicStatic {
char *url; /* work URL, copied from UserDefined */
bool url_alloc; /* URL string is malloc()'ed */
char *referer; /* referer string */
- bool referer_alloc; /* referer sting is malloc()ed */
+ bool referer_alloc; /* referer string is malloc()ed */
struct curl_slist *cookielist; /* list of cookie files set by
curl_easy_setopt(COOKIEFILE) calls */
struct curl_slist *resolve; /* set to point to the set.resolve list when
@@ -1400,6 +1400,8 @@ enum dupstring {
STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */
STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */
STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */
+ STRING_SSL_CIPHER13_LIST_ORIG, /* list of TLS 1.3 ciphers to use */
+ STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */
STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */
STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
STRING_USERAGENT, /* User-Agent string */
@@ -1407,6 +1409,7 @@ enum dupstring {
STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */
STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */
STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */
+ STRING_SSL_ENGINE, /* name of ssl engine */
STRING_USERNAME, /* <username>, if used */
STRING_PASSWORD, /* <password>, if used */
STRING_OPTIONS, /* <options>, if used */
@@ -1559,6 +1562,8 @@ struct UserDefined {
curl_proxytype proxytype; /* what kind of proxy that is in use */
long dns_cache_timeout; /* DNS cache timeout */
long buffer_size; /* size of receive buffer to use */
+ long upload_buffer_size; /* size of upload buffer to use,
+ keep it >= CURL_MAX_WRITE_SIZE */
void *private_data; /* application-private data */
struct curl_slist *http200aliases; /* linked list of aliases for http200 */
@@ -1581,8 +1586,6 @@ struct UserDefined {
/* Here follows boolean settings that define how to behave during
this session. They are STATIC, set by libcurl users or at least initially
and they don't change during operations. */
-
- bool printhost; /* printing host name in debug info */
bool get_filetime; /* get the time and get of the remote file */
bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */
bool prefer_ascii; /* ASCII rather than binary */
@@ -1676,7 +1679,7 @@ struct UserDefined {
bool stream_depends_e; /* set or don't set the Exclusive bit */
int stream_weight;
- bool haproxyprotocol; /* whether to send HAProxy PROXY protocol header */
+ bool haproxyprotocol; /* whether to send HAProxy PROXY protocol v1 header */
struct Curl_http2_dep *stream_dependents;
@@ -1685,6 +1688,7 @@ struct UserDefined {
curl_resolver_start_callback resolver_start; /* optional callback called
before resolver start */
void *resolver_start_client; /* pointer to pass to resolver start callback */
+ bool disallow_username_in_url; /* disallow username in url */
};
struct Names {
@@ -1736,6 +1740,9 @@ struct Curl_easy {
struct to which this "belongs" when used
by the easy interface */
struct Curl_share *share; /* Share, handles global variable mutexing */
+#ifdef USE_LIBPSL
+ struct PslCache *psl; /* The associated PSL cache. */
+#endif
struct SingleRequest req; /* Request-specific data */
struct UserDefined set; /* values set by the libcurl user */
struct DynamicStatic change; /* possibly modified userdefined data */
diff --git a/Utilities/cmcurl/lib/vauth/digest.c b/Utilities/cmcurl/lib/vauth/digest.c
index 131d9da8c4..cc6f16972a 100644
--- a/Utilities/cmcurl/lib/vauth/digest.c
+++ b/Utilities/cmcurl/lib/vauth/digest.c
@@ -158,7 +158,7 @@ static void auth_digest_sha256_to_ascii(unsigned char *source, /* 32 bytes */
/* Perform quoted-string escaping as described in RFC2616 and its errata */
static char *auth_digest_string_quoted(const char *source)
{
- char *dest, *d;
+ char *dest;
const char *s = source;
size_t n = 1; /* null terminator */
@@ -173,8 +173,8 @@ static char *auth_digest_string_quoted(const char *source)
dest = malloc(n);
if(dest) {
+ char *d = dest;
s = source;
- d = dest;
while(*s) {
if(*s == '"' || *s == '\\') {
*d++ = '\\';
@@ -696,7 +696,6 @@ static CURLcode _Curl_auth_create_digest_http_message(
unsigned char ha1[65]; /* 64 digits and 1 zero byte */
unsigned char ha2[65]; /* 64 digits and 1 zero byte */
char userh[65];
- char cnoncebuf[33];
char *cnonce = NULL;
size_t cnonce_sz = 0;
char *userp_quoted;
@@ -707,6 +706,7 @@ static CURLcode _Curl_auth_create_digest_http_message(
digest->nc = 1;
if(!digest->cnonce) {
+ char cnoncebuf[33];
result = Curl_rand_hex(data, (unsigned char *)cnoncebuf,
sizeof(cnoncebuf));
if(result)
diff --git a/Utilities/cmcurl/lib/version.c b/Utilities/cmcurl/lib/version.c
index 5b0d05a150..05c2cd8b06 100644
--- a/Utilities/cmcurl/lib/version.c
+++ b/Utilities/cmcurl/lib/version.c
@@ -445,7 +445,7 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
#ifdef HAVE_BROTLI
version_info.brotli_ver_num = BrotliDecoderVersion();
- brotli_version(brotli_buffer, sizeof brotli_buffer);
+ brotli_version(brotli_buffer, sizeof(brotli_buffer));
version_info.brotli_version = brotli_buffer;
#endif
diff --git a/Utilities/cmcurl/lib/vtls/axtls.c b/Utilities/cmcurl/lib/vtls/axtls.c
index 5ed898b4f4..b262392a00 100644
--- a/Utilities/cmcurl/lib/vtls/axtls.c
+++ b/Utilities/cmcurl/lib/vtls/axtls.c
@@ -29,6 +29,11 @@
#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"
diff --git a/Utilities/cmcurl/lib/vtls/cyassl.c b/Utilities/cmcurl/lib/vtls/cyassl.c
index 20ce460e83..e10398ac3f 100644
--- a/Utilities/cmcurl/lib/vtls/cyassl.c
+++ b/Utilities/cmcurl/lib/vtls/cyassl.c
@@ -569,7 +569,7 @@ cyassl_connect_step2(struct connectdata *conn,
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
}
- memset(&x509_parsed, 0, sizeof x509_parsed);
+ memset(&x509_parsed, 0, sizeof(x509_parsed));
if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
@@ -968,6 +968,8 @@ static CURLcode Curl_cyassl_random(struct Curl_easy *data,
return CURLE_FAILED_INIT;
if(RNG_GenerateBlock(&rng, entropy, (unsigned)length))
return CURLE_FAILED_INIT;
+ if(FreeRng(&rng))
+ return CURLE_FAILED_INIT;
return CURLE_OK;
}
diff --git a/Utilities/cmcurl/lib/vtls/darwinssl.c b/Utilities/cmcurl/lib/vtls/darwinssl.c
index 45fe49d82b..1aea0dc3dd 100644
--- a/Utilities/cmcurl/lib/vtls/darwinssl.c
+++ b/Utilities/cmcurl/lib/vtls/darwinssl.c
@@ -1252,14 +1252,13 @@ static CURLcode darwinssl_version_from_curl(SSLProtocol *darwinver,
return CURLE_OK;
case CURL_SSLVERSION_TLSv1_3:
/* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */
-#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
- /* We can assume __builtin_available() will always work in the
- 10.13/11.0 SDK: */
+#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
*darwinver = kTLSProtocol13;
return CURLE_OK;
}
-#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
+ HAVE_BUILTIN_AVAILABLE == 1 */
break;
}
return CURLE_SSL_CONNECT_ERROR;
@@ -1278,7 +1277,7 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
/* macOS 10.5-10.7 supported TLS 1.0 only.
macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
-#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3;
}
@@ -1287,7 +1286,8 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
}
#else
max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
-#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
+ HAVE_BUILTIN_AVAILABLE == 1 */
switch(ssl_version) {
case CURL_SSLVERSION_DEFAULT:
@@ -1430,7 +1430,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
(void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
-#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
(void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol13);
}
@@ -1439,7 +1439,8 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
#else
(void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
-#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
+ HAVE_BUILTIN_AVAILABLE == 1 */
break;
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
@@ -1572,6 +1573,35 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
+ if(conn->bits.tls_enable_alpn) {
+ if(__builtin_available(macOS 10.13.4, iOS 11, *)) {
+ CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0,
+ &kCFTypeArrayCallBacks);
+
+#ifdef USE_NGHTTP2
+ if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+ (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+ CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID));
+ infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ }
+#endif
+
+ CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1));
+ infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+ /* expects length prefixed preference ordered list of protocols in wire
+ * format
+ */
+ err = SSLSetALPNProtocols(BACKEND->ssl_ctx, alpnArr);
+ if(err != noErr)
+ infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n",
+ err);
+ CFRelease(alpnArr);
+ }
+ }
+#endif
+
if(SSL_SET_OPTION(key)) {
infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
"Transport. The private key must be in the Keychain.\n");
@@ -2466,6 +2496,39 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
break;
}
+#if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
+ if(conn->bits.tls_enable_alpn) {
+ if(__builtin_available(macOS 10.13.4, iOS 11, *)) {
+ CFArrayRef alpnArr = NULL;
+ CFStringRef chosenProtocol = NULL;
+ err = SSLCopyALPNProtocols(BACKEND->ssl_ctx, &alpnArr);
+
+ if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1)
+ chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0);
+
+#ifdef USE_NGHTTP2
+ if(chosenProtocol &&
+ !CFStringCompare(chosenProtocol, CFSTR(NGHTTP2_PROTO_VERSION_ID),
+ 0)) {
+ conn->negnpn = CURL_HTTP_VERSION_2;
+ }
+ else
+#endif
+ if(chosenProtocol &&
+ !CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) {
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+ }
+ else
+ infof(data, "ALPN, server did not agree to a protocol\n");
+
+ /* chosenProtocol is a reference to the string within alpnArr
+ and doesn't need to be freed separately */
+ if(alpnArr)
+ CFRelease(alpnArr);
+ }
+ }
+#endif
+
return CURLE_OK;
}
}
diff --git a/Utilities/cmcurl/lib/vtls/gskit.c b/Utilities/cmcurl/lib/vtls/gskit.c
index b0856cdf44..a0b49601f7 100644
--- a/Utilities/cmcurl/lib/vtls/gskit.c
+++ b/Utilities/cmcurl/lib/vtls/gskit.c
@@ -328,7 +328,7 @@ static CURLcode set_ciphers(struct connectdata *conn,
GSKit tokens are always shorter than their cipher names, allocated buffers
will always be large enough to accommodate the result. */
l = strlen(cipherlist) + 1;
- memset((char *) ciphers, 0, sizeof ciphers);
+ memset((char *) ciphers, 0, sizeof(ciphers));
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
ciphers[i].buf = malloc(l);
if(!ciphers[i].buf) {
@@ -536,18 +536,18 @@ inetsocketpair(int sv[2])
lfd = socket(AF_INET, SOCK_STREAM, 0);
if(lfd < 0)
return -1;
- memset((char *) &addr1, 0, sizeof addr1);
+ memset((char *) &addr1, 0, sizeof(addr1));
addr1.sin_family = AF_INET;
addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr1.sin_port = 0;
- if(bind(lfd, (struct sockaddr *) &addr1, sizeof addr1) ||
+ if(bind(lfd, (struct sockaddr *) &addr1, sizeof(addr1)) ||
listen(lfd, 2) < 0) {
close(lfd);
return -1;
}
/* Get the allocated port. */
- len = sizeof addr1;
+ len = sizeof(addr1);
if(getsockname(lfd, (struct sockaddr *) &addr1, &len) < 0) {
close(lfd);
return -1;
@@ -562,7 +562,7 @@ inetsocketpair(int sv[2])
/* Request unblocking connection to the listening socket. */
curlx_nonblock(cfd, TRUE);
- if(connect(cfd, (struct sockaddr *) &addr1, sizeof addr1) < 0 &&
+ if(connect(cfd, (struct sockaddr *) &addr1, sizeof(addr1)) < 0 &&
errno != EINPROGRESS) {
close(lfd);
close(cfd);
@@ -570,7 +570,7 @@ inetsocketpair(int sv[2])
}
/* Get the client dynamic port for intrusion check below. */
- len = sizeof addr2;
+ len = sizeof(addr2);
if(getsockname(cfd, (struct sockaddr *) &addr2, &len) < 0) {
close(lfd);
close(cfd);
@@ -580,7 +580,7 @@ inetsocketpair(int sv[2])
/* Accept the incoming connection and get the server socket. */
curlx_nonblock(lfd, TRUE);
for(;;) {
- len = sizeof addr1;
+ len = sizeof(addr1);
sfd = accept(lfd, (struct sockaddr *) &addr1, &len);
if(sfd < 0) {
close(lfd);
@@ -644,7 +644,7 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
/* Try getting data from HTTPS proxy and pipe it upstream. */
n = 0;
i = gsk_secure_soc_read(connproxyssl->backend->handle,
- buf, sizeof buf, &n);
+ buf, sizeof(buf), &n);
switch(i) {
case GSK_OK:
if(n) {
@@ -665,7 +665,7 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
if(FD_ISSET(BACKEND->remotefd, &fds_read) &&
FD_ISSET(conn->sock[sockindex], &fds_write)) {
/* Pipe data to HTTPS proxy. */
- n = read(BACKEND->remotefd, buf, sizeof buf);
+ n = read(BACKEND->remotefd, buf, sizeof(buf));
if(n < 0)
return -1;
if(n) {
@@ -864,13 +864,13 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
BACKEND->localfd = sockpair[0];
BACKEND->remotefd = sockpair[1];
setsockopt(BACKEND->localfd, SOL_SOCKET, SO_RCVBUF,
- (void *) sobufsize, sizeof sobufsize);
+ (void *) sobufsize, sizeof(sobufsize));
setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_RCVBUF,
- (void *) sobufsize, sizeof sobufsize);
+ (void *) sobufsize, sizeof(sobufsize));
setsockopt(BACKEND->localfd, SOL_SOCKET, SO_SNDBUF,
- (void *) sobufsize, sizeof sobufsize);
+ (void *) sobufsize, sizeof(sobufsize));
setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_SNDBUF,
- (void *) sobufsize, sizeof sobufsize);
+ (void *) sobufsize, sizeof(sobufsize));
curlx_nonblock(BACKEND->localfd, TRUE);
curlx_nonblock(BACKEND->remotefd, TRUE);
}
@@ -977,7 +977,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
if(!result) {
/* Start handshake. Try asynchronous first. */
- memset(&commarea, 0, sizeof commarea);
+ memset(&commarea, 0, sizeof(commarea));
BACKEND->iocport = QsoCreateIOCompletionPort();
if(BACKEND->iocport != -1) {
result = gskit_status(data,
@@ -1333,11 +1333,11 @@ static int Curl_gskit_check_cxn(struct connectdata *cxn)
return 0; /* connection has been closed */
err = 0;
- errlen = sizeof err;
+ errlen = sizeof(err);
if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
(unsigned char *) &err, &errlen) ||
- errlen != sizeof err || err)
+ errlen != sizeof(err) || err)
return 0; /* connection has been closed */
return -1; /* connection status unknown */
diff --git a/Utilities/cmcurl/lib/vtls/nss.c b/Utilities/cmcurl/lib/vtls/nss.c
index 7cd450cda9..89f8183970 100644
--- a/Utilities/cmcurl/lib/vtls/nss.c
+++ b/Utilities/cmcurl/lib/vtls/nss.c
@@ -394,7 +394,7 @@ static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
/* wrap 'ptr' as list node and tail-insert into 'list' */
static CURLcode insert_wrapped_ptr(struct curl_llist *list, void *ptr)
{
- struct ptr_list_wrap *wrap = malloc(sizeof *wrap);
+ struct ptr_list_wrap *wrap = malloc(sizeof(*wrap));
if(!wrap)
return CURLE_OUT_OF_MEMORY;
@@ -914,11 +914,11 @@ static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
PRTime now;
int i;
- if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
- SECSuccess && channel.length == sizeof channel &&
+ if(SSL_GetChannelInfo(sock, &channel, sizeof(channel)) ==
+ SECSuccess && channel.length == sizeof(channel) &&
channel.cipherSuite) {
if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
- &suite, sizeof suite) == SECSuccess) {
+ &suite, sizeof(suite)) == SECSuccess) {
infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName);
}
}
@@ -1345,7 +1345,8 @@ static CURLcode nss_init(struct Curl_easy *data)
return CURLE_OUT_OF_MEMORY;
/* the default methods just call down to the lower I/O layer */
- memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(), sizeof nspr_io_methods);
+ memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(),
+ sizeof(nspr_io_methods));
/* override certain methods in the table by our wrappers */
nspr_io_methods.recv = nspr_io_recv;
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index f6a4bd3fbf..a487f553c9 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -50,9 +50,6 @@
#include "hostcheck.h"
#include "curl_printf.h"
#include <openssl/ssl.h>
-#ifdef HAVE_OPENSSL_ENGINE_H
-#include <openssl/engine.h>
-#endif
#include <openssl/rand.h>
#include <openssl/x509v3.h>
#ifndef OPENSSL_NO_DSA
@@ -72,6 +69,12 @@
#include <openssl/ocsp.h>
#endif
+#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && /* 1.0.0 or later */ \
+ !defined(OPENSSL_NO_ENGINE)
+#define USE_OPENSSL_ENGINE
+#include <openssl/engine.h>
+#endif
+
#include "warnless.h"
#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */
@@ -83,7 +86,7 @@
#error "OPENSSL_VERSION_NUMBER not defined"
#endif
-#if defined(HAVE_OPENSSL_ENGINE_H)
+#ifdef USE_OPENSSL_ENGINE
#include <openssl/ui.h>
#endif
@@ -166,6 +169,17 @@ static unsigned long OpenSSL_version_num(void)
#define HAVE_KEYLOG_CALLBACK
#endif
+/* Whether SSL_CTX_set_ciphersuites is available.
+ * OpenSSL: supported since 1.1.1 (commit a53b5be6a05)
+ * BoringSSL: no
+ * LibreSSL: no
+ */
+#if ((OPENSSL_VERSION_NUMBER >= 0x10101000L) && \
+ !defined(LIBRESSL_VERSION_NUMBER) && \
+ !defined(OPENSSL_IS_BORINGSSL))
+#define HAVE_SSL_CTX_SET_CIPHERSUITES
+#endif
+
#if defined(LIBRESSL_VERSION_NUMBER)
#define OSSL_PACKAGE "LibreSSL"
#elif defined(OPENSSL_IS_BORINGSSL)
@@ -504,7 +518,7 @@ static int do_file_type(const char *type)
return -1;
}
-#if defined(HAVE_OPENSSL_ENGINE_H)
+#ifdef USE_OPENSSL_ENGINE
/*
* Supply default password to the engine user interface conversation.
* The password is passed by OpenSSL engine from ENGINE_load_private_key()
@@ -544,8 +558,20 @@ static int ssl_ui_writer(UI *ui, UI_STRING *uis)
}
return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
}
+
+/*
+ * Check if a given string is a PKCS#11 URI
+ */
+static bool is_pkcs11_uri(const char *string)
+{
+ return (string && strncasecompare(string, "pkcs11:", 7));
+}
+
#endif
+static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
+ const char *engine);
+
static
int cert_stuff(struct connectdata *conn,
SSL_CTX* ctx,
@@ -606,8 +632,18 @@ int cert_stuff(struct connectdata *conn,
}
break;
case SSL_FILETYPE_ENGINE:
-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
+#if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
{
+ /* Implicitly use pkcs11 engine if none was provided and the
+ * cert_file is a PKCS#11 URI */
+ if(!data->state.engine) {
+ if(is_pkcs11_uri(cert_file)) {
+ if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) {
+ return 0;
+ }
+ }
+ }
+
if(data->state.engine) {
const char *cmd_name = "LOAD_CERT_CTRL";
struct {
@@ -781,9 +817,20 @@ int cert_stuff(struct connectdata *conn,
}
break;
case SSL_FILETYPE_ENGINE:
-#ifdef HAVE_OPENSSL_ENGINE_H
+#ifdef USE_OPENSSL_ENGINE
{ /* XXXX still needs some work */
EVP_PKEY *priv_key = NULL;
+
+ /* Implicitly use pkcs11 engine if none was provided and the
+ * key_file is a PKCS#11 URI */
+ if(!data->state.engine) {
+ if(is_pkcs11_uri(key_file)) {
+ if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) {
+ return 0;
+ }
+ }
+ }
+
if(data->state.engine) {
UI_METHOD *ui_method =
UI_create_method((char *)"curl user interface");
@@ -1088,7 +1135,7 @@ static int Curl_ossl_check_cxn(struct connectdata *conn)
static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
const char *engine)
{
-#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+#ifdef USE_OPENSSL_ENGINE
ENGINE *e;
#if OPENSSL_VERSION_NUMBER >= 0x00909000L
@@ -1133,7 +1180,7 @@ static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
*/
static CURLcode Curl_ossl_set_engine_default(struct Curl_easy *data)
{
-#ifdef HAVE_OPENSSL_ENGINE_H
+#ifdef USE_OPENSSL_ENGINE
if(data->state.engine) {
if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
infof(data, "set default crypto engine '%s'\n",
@@ -1156,7 +1203,7 @@ static CURLcode Curl_ossl_set_engine_default(struct Curl_easy *data)
static struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data)
{
struct curl_slist *list = NULL;
-#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+#ifdef USE_OPENSSL_ENGINE
struct curl_slist *beg;
ENGINE *e;
@@ -1312,7 +1359,7 @@ static void Curl_ossl_session_free(void *ptr)
*/
static void Curl_ossl_close_all(struct Curl_easy *data)
{
-#ifdef HAVE_OPENSSL_ENGINE_H
+#ifdef USE_OPENSSL_ENGINE
if(data->state.engine) {
ENGINE_finish(data->state.engine);
ENGINE_free(data->state.engine);
@@ -1922,7 +1969,15 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
}
else
#endif
- {
+ if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
+ msg_type = *(char *)buf;
+ msg_name = "Change cipher spec";
+ }
+ else if(content_type == SSL3_RT_ALERT) {
+ msg_type = (((char *)buf)[0] << 8) + ((char *)buf)[1];
+ msg_name = SSL_alert_desc_string_long(msg_type);
+ }
+ else {
msg_type = *(char *)buf;
msg_name = ssl_msg_type(ssl_ver, msg_type);
}
@@ -1931,12 +1986,12 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
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, NULL);
+ Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len);
}
}
Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
- CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
+ CURLINFO_SSL_DATA_IN, (char *)buf, len);
(void) ssl;
}
#endif
@@ -2064,10 +2119,6 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
long ssl_version = SSL_CONN_CONFIG(version);
long ssl_version_max = SSL_CONN_CONFIG(version_max);
- if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
- ssl_version_max = ssl_version << 16;
- }
-
switch(ssl_version) {
case CURL_SSLVERSION_TLSv1_3:
#ifdef TLS1_3_VERSION
@@ -2099,8 +2150,7 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
#endif
/* FALLTHROUGH */
case CURL_SSLVERSION_TLSv1_0:
- *ctx_options |= SSL_OP_NO_SSLv2;
- *ctx_options |= SSL_OP_NO_SSLv3;
+ case CURL_SSLVERSION_TLSv1:
break;
}
@@ -2116,12 +2166,12 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
#endif
/* FALLTHROUGH */
case CURL_SSLVERSION_MAX_TLSv1_2:
- case CURL_SSLVERSION_MAX_DEFAULT:
#ifdef TLS1_3_VERSION
*ctx_options |= SSL_OP_NO_TLSv1_3;
#endif
break;
case CURL_SSLVERSION_MAX_TLSv1_3:
+ case CURL_SSLVERSION_MAX_DEFAULT:
#ifdef TLS1_3_VERSION
break;
#else
@@ -2305,11 +2355,6 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
switch(ssl_version) {
case CURL_SSLVERSION_SSLv3:
-#ifdef USE_TLS_SRP
- if(ssl_authtype == CURL_TLSAUTH_SRP) {
- infof(data, "Set version TLSv1.x for SRP authorisation\n");
- }
-#endif
ctx_options |= SSL_OP_NO_SSLv2;
ctx_options |= SSL_OP_NO_TLSv1;
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
@@ -2323,21 +2368,20 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
- ctx_options |= SSL_OP_NO_SSLv2;
- ctx_options |= SSL_OP_NO_SSLv3;
- break;
-
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
+ /* asking for any TLS version as the minimum, means no SSL versions
+ allowed */
+ ctx_options |= SSL_OP_NO_SSLv2;
+ ctx_options |= SSL_OP_NO_SSLv3;
result = set_ssl_version_min_max(&ctx_options, conn, sockindex);
if(result != CURLE_OK)
return result;
break;
case CURL_SSLVERSION_SSLv2:
-#ifndef OPENSSL_NO_SSL2
ctx_options |= SSL_OP_NO_SSLv3;
ctx_options |= SSL_OP_NO_TLSv1;
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
@@ -2348,10 +2392,6 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#endif
#endif
break;
-#else
- failf(data, OSSL_PACKAGE " was built without SSLv2 support");
- return CURLE_NOT_BUILT_IN;
-#endif
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
@@ -2414,6 +2454,19 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
infof(data, "Cipher selection: %s\n", ciphers);
}
+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
+ {
+ char *ciphers13 = SSL_CONN_CONFIG(cipher_list13);
+ if(ciphers13) {
+ if(!SSL_CTX_set_ciphersuites(BACKEND->ctx, ciphers13)) {
+ failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers);
+ return CURLE_SSL_CIPHER;
+ }
+ infof(data, "TLS 1.3 cipher selection: %s\n", ciphers13);
+ }
+ }
+#endif
+
#ifdef USE_TLS_SRP
if(ssl_authtype == CURL_TLSAUTH_SRP) {
char * const ssl_username = SSL_SET_OPTION(username);
@@ -3754,6 +3807,9 @@ const struct Curl_ssl Curl_ssl_openssl = {
SSLSUPP_CERTINFO |
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_SSL_CTX |
+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
+ SSLSUPP_TLS13_CIPHERSUITES |
+#endif
SSLSUPP_HTTPS_PROXY,
sizeof(struct ssl_backend_data),
diff --git a/Utilities/cmcurl/lib/vtls/schannel.c b/Utilities/cmcurl/lib/vtls/schannel.c
index 2cfd5c19f5..8f6c301d11 100644
--- a/Utilities/cmcurl/lib/vtls/schannel.c
+++ b/Utilities/cmcurl/lib/vtls/schannel.c
@@ -90,11 +90,17 @@
#endif
#endif
+#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX)
+#define HAS_CLIENT_CERT_PATH
+#endif
+
+#ifdef HAS_CLIENT_CERT_PATH
#ifdef UNICODE
#define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_W
#else
#define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_A
#endif
+#endif
#ifndef SP_PROT_SSL2_CLIENT
#define SP_PROT_SSL2_CLIENT 0x00000008
@@ -199,6 +205,155 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn)
return CURLE_OK;
}
+/*longest is 26, buffer is slightly bigger*/
+#define LONGEST_ALG_ID 32
+#define CIPHEROPTION(X) \
+if(strcmp(#X, tmp) == 0) \
+ return X
+
+static int
+get_alg_id_by_name(char *name)
+{
+ char tmp[LONGEST_ALG_ID] = { 0 };
+ char *nameEnd = strchr(name, ':');
+ size_t n = nameEnd ? min((size_t)(nameEnd - name), LONGEST_ALG_ID - 1) : \
+ min(strlen(name), LONGEST_ALG_ID - 1);
+ strncpy(tmp, name, n);
+ tmp[n] = 0;
+ CIPHEROPTION(CALG_MD2);
+ CIPHEROPTION(CALG_MD4);
+ CIPHEROPTION(CALG_MD5);
+ CIPHEROPTION(CALG_SHA);
+ CIPHEROPTION(CALG_SHA1);
+ CIPHEROPTION(CALG_MAC);
+ CIPHEROPTION(CALG_RSA_SIGN);
+ CIPHEROPTION(CALG_DSS_SIGN);
+/*ifdefs for the options that are defined conditionally in wincrypt.h*/
+#ifdef CALG_NO_SIGN
+ CIPHEROPTION(CALG_NO_SIGN);
+#endif
+ CIPHEROPTION(CALG_RSA_KEYX);
+ CIPHEROPTION(CALG_DES);
+#ifdef CALG_3DES_112
+ CIPHEROPTION(CALG_3DES_112);
+#endif
+ CIPHEROPTION(CALG_3DES);
+ CIPHEROPTION(CALG_DESX);
+ CIPHEROPTION(CALG_RC2);
+ CIPHEROPTION(CALG_RC4);
+ CIPHEROPTION(CALG_SEAL);
+#ifdef CALG_DH_SF
+ CIPHEROPTION(CALG_DH_SF);
+#endif
+ CIPHEROPTION(CALG_DH_EPHEM);
+#ifdef CALG_AGREEDKEY_ANY
+ CIPHEROPTION(CALG_AGREEDKEY_ANY);
+#endif
+#ifdef CALG_HUGHES_MD5
+ CIPHEROPTION(CALG_HUGHES_MD5);
+#endif
+ CIPHEROPTION(CALG_SKIPJACK);
+#ifdef CALG_TEK
+ CIPHEROPTION(CALG_TEK);
+#endif
+ CIPHEROPTION(CALG_CYLINK_MEK);
+ CIPHEROPTION(CALG_SSL3_SHAMD5);
+#ifdef CALG_SSL3_MASTER
+ CIPHEROPTION(CALG_SSL3_MASTER);
+#endif
+#ifdef CALG_SCHANNEL_MASTER_HASH
+ CIPHEROPTION(CALG_SCHANNEL_MASTER_HASH);
+#endif
+#ifdef CALG_SCHANNEL_MAC_KEY
+ CIPHEROPTION(CALG_SCHANNEL_MAC_KEY);
+#endif
+#ifdef CALG_SCHANNEL_ENC_KEY
+ CIPHEROPTION(CALG_SCHANNEL_ENC_KEY);
+#endif
+#ifdef CALG_PCT1_MASTER
+ CIPHEROPTION(CALG_PCT1_MASTER);
+#endif
+#ifdef CALG_SSL2_MASTER
+ CIPHEROPTION(CALG_SSL2_MASTER);
+#endif
+#ifdef CALG_TLS1_MASTER
+ CIPHEROPTION(CALG_TLS1_MASTER);
+#endif
+#ifdef CALG_RC5
+ CIPHEROPTION(CALG_RC5);
+#endif
+#ifdef CALG_HMAC
+ CIPHEROPTION(CALG_HMAC);
+#endif
+#if !defined(__W32API_MAJOR_VERSION) || \
+ !defined(__W32API_MINOR_VERSION) || \
+ defined(__MINGW64_VERSION_MAJOR) || \
+ (__W32API_MAJOR_VERSION > 5) || \
+ ((__W32API_MAJOR_VERSION == 5) && (__W32API_MINOR_VERSION > 0))
+ /* CALG_TLS1PRF has a syntax error in MinGW's w32api up to version 5.0,
+ see https://osdn.net/projects/mingw/ticket/38391 */
+ CIPHEROPTION(CALG_TLS1PRF);
+#endif
+#ifdef CALG_HASH_REPLACE_OWF
+ CIPHEROPTION(CALG_HASH_REPLACE_OWF);
+#endif
+#ifdef CALG_AES_128
+ CIPHEROPTION(CALG_AES_128);
+#endif
+#ifdef CALG_AES_192
+ CIPHEROPTION(CALG_AES_192);
+#endif
+#ifdef CALG_AES_256
+ CIPHEROPTION(CALG_AES_256);
+#endif
+#ifdef CALG_AES
+ CIPHEROPTION(CALG_AES);
+#endif
+#ifdef CALG_SHA_256
+ CIPHEROPTION(CALG_SHA_256);
+#endif
+#ifdef CALG_SHA_384
+ CIPHEROPTION(CALG_SHA_384);
+#endif
+#ifdef CALG_SHA_512
+ CIPHEROPTION(CALG_SHA_512);
+#endif
+#ifdef CALG_ECDH
+ CIPHEROPTION(CALG_ECDH);
+#endif
+#ifdef CALG_ECMQV
+ CIPHEROPTION(CALG_ECMQV);
+#endif
+#ifdef CALG_ECDSA
+ CIPHEROPTION(CALG_ECDSA);
+#endif
+ return 0;
+}
+
+static CURLcode
+set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers)
+{
+ char *startCur = ciphers;
+ int algCount = 0;
+ static ALG_ID algIds[45]; /*There are 45 listed in the MS headers*/
+ while(startCur && (0 != *startCur) && (algCount < 45)) {
+ long alg = strtol(startCur, 0, 0);
+ if(!alg)
+ alg = get_alg_id_by_name(startCur);
+ if(alg)
+ algIds[algCount++] = alg;
+ else
+ return CURLE_SSL_CIPHER;
+ startCur = strchr(startCur, ':');
+ if(startCur)
+ startCur++;
+ }
+ schannel_cred->palgSupportedAlgs = algIds;
+ schannel_cred->cSupportedAlgs = algCount;
+ return CURLE_OK;
+}
+
+#ifdef HAS_CLIENT_CERT_PATH
static CURLcode
get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
TCHAR **thumbprint)
@@ -248,6 +403,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
return CURLE_OK;
}
+#endif
static CURLcode
schannel_connect_step1(struct connectdata *conn, int sockindex)
@@ -299,10 +455,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
#endif
#ifdef _WIN32_WCE
+#ifdef HAS_MANUAL_VERIFY_API
/* certificate validation on CE doesn't seem to work right; we'll
* do it following a more manual process. */
BACKEND->use_manual_cred_validation = true;
#else
+#error "compiler too old to support requisite manual cert verify for Win CE"
+#endif
+#else
+#ifdef HAS_MANUAL_VERIFY_API
if(SSL_CONN_CONFIG(CAfile)) {
if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
@@ -316,6 +477,12 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
}
else
BACKEND->use_manual_cred_validation = false;
+#else
+ if(SSL_CONN_CONFIG(CAfile)) {
+ failf(data, "schannel: CA cert support not built in");
+ return CURLE_NOT_BUILT_IN;
+ }
+#endif
#endif
BACKEND->cred = NULL;
@@ -341,9 +508,11 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
if(conn->ssl_config.verifypeer) {
+#ifdef HAS_MANUAL_VERIFY_API
if(BACKEND->use_manual_cred_validation)
schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION;
else
+#endif
schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
/* TODO s/data->set.ssl.no_revoke/SSL_SET_OPTION(no_revoke)/g */
@@ -401,6 +570,16 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
return CURLE_SSL_CONNECT_ERROR;
}
+ if(SSL_CONN_CONFIG(cipher_list)) {
+ result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list));
+ if(CURLE_OK != result) {
+ failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
+ return result;
+ }
+ }
+
+
+#ifdef HAS_CLIENT_CERT_PATH
/* client certificate */
if(data->set.ssl.cert) {
DWORD cert_store_name;
@@ -417,14 +596,21 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
result = get_cert_location(cert_path, &cert_store_name,
&cert_store_path, &cert_thumbprint_str);
if(result != CURLE_OK) {
+ failf(data, "schannel: Failed to get certificate location for %s",
+ cert_path);
Curl_unicodefree(cert_path);
return result;
}
- cert_store = CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0,
- (HCRYPTPROV)NULL,
- cert_store_name, cert_store_path);
+ cert_store =
+ CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0,
+ (HCRYPTPROV)NULL,
+ CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name,
+ cert_store_path);
if(!cert_store) {
+ failf(data, "schannel: Failed to open cert store %x %s, "
+ "last error is %x",
+ cert_store_name, cert_store_path, GetLastError());
Curl_unicodefree(cert_path);
return CURLE_SSL_CONNECT_ERROR;
}
@@ -453,6 +639,12 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
CertCloseStore(cert_store, 0);
}
+#else
+ if(data->set.ssl.cert) {
+ failf(data, "schannel: client cert support not built in");
+ return CURLE_NOT_BUILT_IN;
+ }
+#endif
/* allocate memory for the re-usable credential handle */
BACKEND->cred = (struct curl_schannel_cred *)
@@ -877,9 +1069,11 @@ 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);
}
+#endif
return CURLE_OK;
}
@@ -1819,7 +2013,7 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex,
x509_der = (const char *)pCertContextServer->pbCertEncoded;
x509_der_len = pCertContextServer->cbCertEncoded;
- memset(&x509_parsed, 0, sizeof x509_parsed);
+ memset(&x509_parsed, 0, sizeof(x509_parsed));
if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
break;
@@ -1870,7 +2064,8 @@ static void Curl_schannel_checksum(const unsigned char *input,
if(!CryptCreateHash(hProv, algId, 0, 0, &hHash))
break; /* failed */
- if(!CryptHashData(hHash, (const BYTE*)input, (DWORD)inputlen, 0))
+ /* workaround for original MinGW, should be (const BYTE*) */
+ if(!CryptHashData(hHash, (BYTE*)input, (DWORD)inputlen, 0))
break; /* failed */
/* get hash size */
diff --git a/Utilities/cmcurl/lib/vtls/schannel.h b/Utilities/cmcurl/lib/vtls/schannel.h
index 4476900270..51417affe1 100644
--- a/Utilities/cmcurl/lib/vtls/schannel.h
+++ b/Utilities/cmcurl/lib/vtls/schannel.h
@@ -32,12 +32,44 @@
#include "urldata.h"
+/* <wincrypt.h> has been included via the above <schnlsp.h>.
+ * Or in case of ldap.c, it was included via <winldap.h>.
+ * And since <wincrypt.h> has this:
+ * #define X509_NAME ((LPCSTR) 7)
+ *
+ * And in BoringSSL's <openssl/base.h> there is:
+ * typedef struct X509_name_st X509_NAME;
+ * etc.
+ *
+ * this wil cause all kinds of C-preprocessing paste errors in
+ * BoringSSL's <openssl/x509.h>: So just undefine those defines here
+ * (and only here).
+ */
+#if defined(HAVE_BORINGSSL) || defined(OPENSSL_IS_BORINGSSL)
+# undef X509_NAME
+# undef X509_CERT_PAIR
+# undef X509_EXTENSIONS
+#endif
+
extern const struct Curl_ssl Curl_ssl_schannel;
CURLcode verify_certificate(struct connectdata *conn, int sockindex);
/* structs to expose only in schannel.c and schannel_verify.c */
#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
+
+#ifdef __MINGW32__
+#include <_mingw.h>
+#ifdef __MINGW64_VERSION_MAJOR
+#define HAS_MANUAL_VERIFY_API
+#endif
+#else
+#include <wincrypt.h>
+#ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN
+#define HAS_MANUAL_VERIFY_API
+#endif
+#endif
+
struct curl_schannel_cred {
CredHandle cred_handle;
TimeStamp time_stamp;
@@ -66,7 +98,9 @@ struct ssl_backend_data {
bool recv_sspi_close_notify; /* true if connection closed by close_notify */
bool recv_connection_closed; /* true if connection closed, regardless how */
bool use_alpn; /* true if ALPN is used for this connection */
+#ifdef HAS_MANUAL_VERIFY_API
bool use_manual_cred_validation; /* true if manual cred validation is used */
+#endif
};
#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */
diff --git a/Utilities/cmcurl/lib/vtls/schannel_verify.c b/Utilities/cmcurl/lib/vtls/schannel_verify.c
index db187dd6bf..5a7092a21a 100644
--- a/Utilities/cmcurl/lib/vtls/schannel_verify.c
+++ b/Utilities/cmcurl/lib/vtls/schannel_verify.c
@@ -30,14 +30,15 @@
#include "curl_setup.h"
#ifdef USE_SCHANNEL
-
-#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
-
#ifndef USE_WINDOWS_SSPI
# error "Can't compile SCHANNEL support without SSPI."
#endif
+#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
#include "schannel.h"
+
+#ifdef HAS_MANUAL_VERIFY_API
+
#include "vtls.h"
#include "sendf.h"
#include "strerror.h"
@@ -53,7 +54,7 @@
#define BACKEND connssl->backend
#define MAX_CAFILE_SIZE 1048576 /* 1 MiB */
-#define BEGIN_CERT "-----BEGIN CERTIFICATE-----\n"
+#define BEGIN_CERT "-----BEGIN CERTIFICATE-----"
#define END_CERT "\n-----END CERTIFICATE-----"
typedef struct {
@@ -71,6 +72,10 @@ typedef struct {
HCERTSTORE hExclusiveTrustedPeople;
} CERT_CHAIN_ENGINE_CONFIG_WIN7, *PCERT_CHAIN_ENGINE_CONFIG_WIN7;
+static int is_cr_or_lf(char c)
+{
+ return c == '\r' || c == '\n';
+}
static CURLcode add_certs_to_store(HCERTSTORE trust_store,
const char *ca_file,
@@ -177,7 +182,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
current_ca_file_ptr = ca_file_buffer;
while(more_certs && *current_ca_file_ptr != '\0') {
char *begin_cert_ptr = strstr(current_ca_file_ptr, BEGIN_CERT);
- if(!begin_cert_ptr) {
+ if(!begin_cert_ptr || !is_cr_or_lf(begin_cert_ptr[strlen(BEGIN_CERT)])) {
more_certs = 0;
}
else {
@@ -209,7 +214,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,
NULL,
NULL,
NULL,
- &cert_context)) {
+ (const void **)&cert_context)) {
failf(data,
"schannel: failed to extract certificate from CA file "
@@ -548,4 +553,5 @@ CURLcode verify_certificate(struct connectdata *conn, int sockindex)
return result;
}
+#endif /* HAS_MANUAL_VERIFY_API */
#endif /* USE_SCHANNEL */
diff --git a/Utilities/cmcurl/lib/vtls/vtls.c b/Utilities/cmcurl/lib/vtls/vtls.c
index ee5bc7a0a6..b61c64034a 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.c
+++ b/Utilities/cmcurl/lib/vtls/vtls.c
@@ -96,7 +96,8 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
Curl_safe_strcasecompare(data->clientcert, needle->clientcert) &&
Curl_safe_strcasecompare(data->random_file, needle->random_file) &&
Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) &&
- Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list))
+ Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
+ Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13))
return TRUE;
return FALSE;
@@ -119,6 +120,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
CLONE_STRING(random_file);
CLONE_STRING(egdsocket);
CLONE_STRING(cipher_list);
+ CLONE_STRING(cipher_list13);
return TRUE;
}
@@ -131,6 +133,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
Curl_safefree(sslc->random_file);
Curl_safefree(sslc->egdsocket);
Curl_safefree(sslc->cipher_list);
+ Curl_safefree(sslc->cipher_list13);
}
#ifdef USE_SSL
@@ -980,6 +983,14 @@ bool Curl_ssl_false_start(void)
}
/*
+ * Check whether the SSL backend supports setting TLS 1.3 cipher suites
+ */
+bool Curl_ssl_tls13_ciphersuites(void)
+{
+ return Curl_ssl->supports & SSLSUPP_TLS13_CIPHERSUITES;
+}
+
+/*
* Default implementations for unsupported functions.
*/
diff --git a/Utilities/cmcurl/lib/vtls/vtls.h b/Utilities/cmcurl/lib/vtls/vtls.h
index e7b87c4d3f..40f9d74793 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.h
+++ b/Utilities/cmcurl/lib/vtls/vtls.h
@@ -31,6 +31,7 @@ struct ssl_connect_data;
#define SSLSUPP_PINNEDPUBKEY (1<<2) /* supports CURLOPT_PINNEDPUBLICKEY */
#define SSLSUPP_SSL_CTX (1<<3) /* supports CURLOPT_SSL_CTX */
#define SSLSUPP_HTTPS_PROXY (1<<4) /* supports access via HTTPS proxies */
+#define SSLSUPP_TLS13_CIPHERSUITES (1<<5) /* supports TLS 1.3 ciphersuites */
struct Curl_ssl {
/*
@@ -93,6 +94,7 @@ CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine);
CURLcode Curl_none_set_engine_default(struct Curl_easy *data);
struct curl_slist *Curl_none_engines_list(struct Curl_easy *data);
bool Curl_none_false_start(void);
+bool Curl_ssl_tls13_ciphersuites(void);
CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
unsigned char *md5sum, size_t md5len);
@@ -246,7 +248,7 @@ bool Curl_ssl_false_start(void);
#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
-#else
+#else /* if not USE_SSL */
/* When SSL support is not present, just define away these function calls */
#define Curl_ssl_init() 1
@@ -270,6 +272,7 @@ bool Curl_ssl_false_start(void);
#define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN)
#define Curl_ssl_cert_status_request() FALSE
#define Curl_ssl_false_start() FALSE
+#define Curl_ssl_tls13_ciphersuites() FALSE
#endif
#endif /* HEADER_CURL_VTLS_H */
diff --git a/Utilities/cmcurl/lib/warnless.h b/Utilities/cmcurl/lib/warnless.h
index f6a2d744b7..284ea1e752 100644
--- a/Utilities/cmcurl/lib/warnless.h
+++ b/Utilities/cmcurl/lib/warnless.h
@@ -26,6 +26,9 @@
#include <curl/curl.h> /* for curl_socket_t */
#endif
+#define CURLX_FUNCTION_CAST(target_type, func) \
+ (target_type)(void (*) (void))(func)
+
unsigned short curlx_ultous(unsigned long ulnum);
unsigned char curlx_ultouc(unsigned long ulnum);
diff --git a/Utilities/cmcurl/lib/x509asn1.c b/Utilities/cmcurl/lib/x509asn1.c
index bba20233f2..72a0b4a000 100644
--- a/Utilities/cmcurl/lib/x509asn1.c
+++ b/Utilities/cmcurl/lib/x509asn1.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
@@ -40,10 +40,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-/* For overflow checks. */
-#define CURL_SIZE_T_MAX ((size_t)-1)
-
-
/* ASN.1 OIDs. */
static const char cnOID[] = "2.5.4.3"; /* Common name. */
static const char sanOID[] = "2.5.29.17"; /* Subject alternative name. */
@@ -108,8 +104,8 @@ static const curl_OID OIDtable[] = {
*/
-const char *Curl_getASN1Element(curl_asn1Element *elem,
- const char *beg, const char *end)
+static const char *getASN1Element(curl_asn1Element *elem,
+ const char *beg, const char *end)
{
unsigned char b;
unsigned long len;
@@ -146,7 +142,7 @@ const char *Curl_getASN1Element(curl_asn1Element *elem,
return (const char *) NULL;
elem->beg = beg;
while(beg < end && *beg) {
- beg = Curl_getASN1Element(&lelem, beg, end);
+ beg = getASN1Element(&lelem, beg, end);
if(!beg)
return (const char *) NULL;
}
@@ -206,7 +202,7 @@ static const char *octet2str(const char *beg, const char *end)
/* Convert an ASN.1 octet string to a printable string.
Return the dynamically allocated string, or NULL if an error occurs. */
- if(n <= (CURL_SIZE_T_MAX - 1) / 3) {
+ if(n <= (SIZE_T_MAX - 1) / 3) {
buf = malloc(3 * n + 1);
if(buf)
for(n = 0; beg < end; n += 3)
@@ -287,7 +283,7 @@ utf8asn1str(char **to, int type, const char *from, const char *end)
if(inlength % size)
return -1; /* Length inconsistent with character size. */
- if(inlength / size > (CURL_SIZE_T_MAX - 1) / 4)
+ if(inlength / size > (SIZE_T_MAX - 1) / 4)
return -1; /* Too big. */
buf = malloc(4 * (inlength / size) + 1);
if(!buf)
@@ -306,10 +302,10 @@ utf8asn1str(char **to, int type, const char *from, const char *end)
case 4:
wc = (wc << 8) | *(const unsigned char *) from++;
wc = (wc << 8) | *(const unsigned char *) from++;
- /* fallthrough */
+ /* FALLTHROUGH */
case 2:
wc = (wc << 8) | *(const unsigned char *) from++;
- /* fallthrough */
+ /* FALLTHROUGH */
default: /* case 1: */
wc = (wc << 8) | *(const unsigned char *) from++;
}
@@ -546,7 +542,7 @@ static const char *UTime2str(const char *beg, const char *end)
tzl, tzp);
}
-const char *Curl_ASN1tostr(curl_asn1Element *elem, int type)
+static const char *ASN1tostr(curl_asn1Element *elem, int type)
{
/* Convert an ASN.1 element to a printable string.
Return the dynamically allocated string, or NULL if an error occurs. */
@@ -605,12 +601,12 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
Return the total string length, even if larger than `n'. */
for(p1 = dn->beg; p1 < dn->end;) {
- p1 = Curl_getASN1Element(&rdn, p1, dn->end);
+ p1 = getASN1Element(&rdn, p1, dn->end);
for(p2 = rdn.beg; p2 < rdn.end;) {
- p2 = Curl_getASN1Element(&atv, p2, rdn.end);
- p3 = Curl_getASN1Element(&oid, atv.beg, atv.end);
- Curl_getASN1Element(&value, p3, atv.end);
- str = Curl_ASN1tostr(&oid, 0);
+ p2 = getASN1Element(&atv, p2, rdn.end);
+ p3 = getASN1Element(&oid, atv.beg, atv.end);
+ getASN1Element(&value, p3, atv.end);
+ str = ASN1tostr(&oid, 0);
if(!str)
return -1;
@@ -640,7 +636,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
l++;
/* Generate value. */
- str = Curl_ASN1tostr(&value, 0);
+ str = ASN1tostr(&value, 0);
if(!str)
return -1;
for(p3 = str; *p3; p3++) {
@@ -655,7 +651,7 @@ static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
return l;
}
-const char *Curl_DNtostr(curl_asn1Element *dn)
+static const char *DNtostr(curl_asn1Element *dn)
{
char *buf = (char *) NULL;
ssize_t n = encodeDN(buf, 0, dn);
@@ -694,17 +690,17 @@ int Curl_parseX509(curl_X509certificate *cert,
cert->certificate.end = end;
/* Get the sequence content. */
- if(!Curl_getASN1Element(&elem, beg, end))
+ if(!getASN1Element(&elem, beg, end))
return -1; /* Invalid bounds/size. */
beg = elem.beg;
end = elem.end;
/* Get tbsCertificate. */
- beg = Curl_getASN1Element(&tbsCertificate, beg, end);
+ beg = getASN1Element(&tbsCertificate, beg, end);
/* Skip the signatureAlgorithm. */
- beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
+ beg = getASN1Element(&cert->signatureAlgorithm, beg, end);
/* Get the signatureValue. */
- Curl_getASN1Element(&cert->signature, beg, end);
+ getASN1Element(&cert->signature, beg, end);
/* Parse TBSCertificate. */
beg = tbsCertificate.beg;
@@ -712,29 +708,29 @@ int Curl_parseX509(curl_X509certificate *cert,
/* Get optional version, get serialNumber. */
cert->version.header = NULL;
cert->version.beg = &defaultVersion;
- cert->version.end = &defaultVersion + sizeof defaultVersion;;
- beg = Curl_getASN1Element(&elem, beg, end);
+ cert->version.end = &defaultVersion + sizeof(defaultVersion);
+ beg = getASN1Element(&elem, beg, end);
if(elem.tag == 0) {
- Curl_getASN1Element(&cert->version, elem.beg, elem.end);
- beg = Curl_getASN1Element(&elem, beg, end);
+ getASN1Element(&cert->version, elem.beg, elem.end);
+ beg = getASN1Element(&elem, beg, end);
}
cert->serialNumber = elem;
/* Get signature algorithm. */
- beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
+ beg = getASN1Element(&cert->signatureAlgorithm, beg, end);
/* Get issuer. */
- beg = Curl_getASN1Element(&cert->issuer, beg, end);
+ beg = getASN1Element(&cert->issuer, beg, end);
/* Get notBefore and notAfter. */
- beg = Curl_getASN1Element(&elem, beg, end);
- ccp = Curl_getASN1Element(&cert->notBefore, elem.beg, elem.end);
- Curl_getASN1Element(&cert->notAfter, ccp, elem.end);
+ beg = getASN1Element(&elem, beg, end);
+ ccp = getASN1Element(&cert->notBefore, elem.beg, elem.end);
+ getASN1Element(&cert->notAfter, ccp, elem.end);
/* Get subject. */
- beg = Curl_getASN1Element(&cert->subject, beg, end);
+ beg = getASN1Element(&cert->subject, beg, end);
/* Get subjectPublicKeyAlgorithm and subjectPublicKey. */
- beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
- ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm,
+ beg = getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
+ ccp = getASN1Element(&cert->subjectPublicKeyAlgorithm,
cert->subjectPublicKeyInfo.beg,
cert->subjectPublicKeyInfo.end);
- Curl_getASN1Element(&cert->subjectPublicKey, ccp,
+ getASN1Element(&cert->subjectPublicKey, ccp,
cert->subjectPublicKeyInfo.end);
/* Get optional issuerUiqueID, subjectUniqueID and extensions. */
cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0;
@@ -745,19 +741,19 @@ int Curl_parseX509(curl_X509certificate *cert,
cert->extensions.header = NULL;
cert->extensions.beg = cert->extensions.end = "";
if(beg < end)
- beg = Curl_getASN1Element(&elem, beg, end);
+ beg = getASN1Element(&elem, beg, end);
if(elem.tag == 1) {
cert->issuerUniqueID = elem;
if(beg < end)
- beg = Curl_getASN1Element(&elem, beg, end);
+ beg = getASN1Element(&elem, beg, end);
}
if(elem.tag == 2) {
cert->subjectUniqueID = elem;
if(beg < end)
- beg = Curl_getASN1Element(&elem, beg, end);
+ beg = getASN1Element(&elem, beg, end);
}
if(elem.tag == 3)
- Curl_getASN1Element(&cert->extensions, elem.beg, elem.end);
+ getASN1Element(&cert->extensions, elem.beg, elem.end);
return 0;
}
@@ -785,12 +781,12 @@ static const char *dumpAlgo(curl_asn1Element *param,
/* Get algorithm parameters and return algorithm name. */
- beg = Curl_getASN1Element(&oid, beg, end);
+ beg = getASN1Element(&oid, beg, end);
param->header = NULL;
param->tag = 0;
param->beg = param->end = end;
if(beg < end)
- Curl_getASN1Element(param, beg, end);
+ getASN1Element(param, beg, end);
return OID2str(oid.beg, oid.end, TRUE);
}
@@ -801,7 +797,7 @@ static void do_pubkey_field(struct Curl_easy *data, int certnum,
/* Generate a certificate information record for the public key. */
- output = Curl_ASN1tostr(elem, 0);
+ output = ASN1tostr(elem, 0);
if(output) {
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, label, output);
@@ -825,10 +821,10 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
/* Generate all information records for the public key. */
/* Get the public key (single element). */
- Curl_getASN1Element(&pk, pubkey->beg + 1, pubkey->end);
+ getASN1Element(&pk, pubkey->beg + 1, pubkey->end);
if(strcasecompare(algo, "rsaEncryption")) {
- p = Curl_getASN1Element(&elem, pk.beg, pk.end);
+ p = getASN1Element(&elem, pk.beg, pk.end);
/* Compute key length. */
for(q = elem.beg; !*q && q < elem.end; q++)
;
@@ -849,22 +845,22 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
}
/* Generate coefficients. */
do_pubkey_field(data, certnum, "rsa(n)", &elem);
- Curl_getASN1Element(&elem, p, pk.end);
+ getASN1Element(&elem, p, pk.end);
do_pubkey_field(data, certnum, "rsa(e)", &elem);
}
else if(strcasecompare(algo, "dsa")) {
- p = Curl_getASN1Element(&elem, param->beg, param->end);
+ p = getASN1Element(&elem, param->beg, param->end);
do_pubkey_field(data, certnum, "dsa(p)", &elem);
- p = Curl_getASN1Element(&elem, p, param->end);
+ p = getASN1Element(&elem, p, param->end);
do_pubkey_field(data, certnum, "dsa(q)", &elem);
- Curl_getASN1Element(&elem, p, param->end);
+ getASN1Element(&elem, p, param->end);
do_pubkey_field(data, certnum, "dsa(g)", &elem);
do_pubkey_field(data, certnum, "dsa(pub_key)", &pk);
}
else if(strcasecompare(algo, "dhpublicnumber")) {
- p = Curl_getASN1Element(&elem, param->beg, param->end);
+ p = getASN1Element(&elem, param->beg, param->end);
do_pubkey_field(data, certnum, "dh(p)", &elem);
- Curl_getASN1Element(&elem, param->beg, param->end);
+ getASN1Element(&elem, param->beg, param->end);
do_pubkey_field(data, certnum, "dh(g)", &elem);
do_pubkey_field(data, certnum, "dh(pub_key)", &pk);
}
@@ -903,7 +899,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
/* Subject. */
- ccp = Curl_DNtostr(&cert.subject);
+ ccp = DNtostr(&cert.subject);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
@@ -913,7 +909,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
free((char *) ccp);
/* Issuer. */
- ccp = Curl_DNtostr(&cert.issuer);
+ ccp = DNtostr(&cert.issuer);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
@@ -937,7 +933,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
infof(data, " Version: %lu (0x%lx)\n", version + 1, version);
/* Serial number. */
- ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
+ ccp = ASN1tostr(&cert.serialNumber, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
@@ -958,7 +954,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
free((char *) ccp);
/* Start Date. */
- ccp = Curl_ASN1tostr(&cert.notBefore, 0);
+ ccp = ASN1tostr(&cert.notBefore, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
@@ -968,7 +964,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
free((char *) ccp);
/* Expire Date. */
- ccp = Curl_ASN1tostr(&cert.notAfter, 0);
+ ccp = ASN1tostr(&cert.notAfter, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
@@ -992,7 +988,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn,
/* TODO: extensions. */
/* Signature. */
- ccp = Curl_ASN1tostr(&cert.signature, 0);
+ ccp = ASN1tostr(&cert.signature, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
@@ -1051,7 +1047,7 @@ static const char *checkOID(const char *beg, const char *end,
/* Check if first ASN.1 element at `beg' is the given OID.
Return a pointer in the source after the OID if found, else NULL. */
- ccp = Curl_getASN1Element(&e, beg, end);
+ ccp = getASN1Element(&e, beg, end);
if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
return (const char *) NULL;
@@ -1110,19 +1106,19 @@ CURLcode Curl_verifyhost(struct connectdata *conn,
/* Process extensions. */
for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) {
- p = Curl_getASN1Element(&ext, p, cert.extensions.end);
+ p = getASN1Element(&ext, p, cert.extensions.end);
/* Check if extension is a subjectAlternativeName. */
ext.beg = checkOID(ext.beg, ext.end, sanOID);
if(ext.beg) {
- ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
+ ext.beg = getASN1Element(&elem, ext.beg, ext.end);
/* Skip critical if present. */
if(elem.tag == CURL_ASN1_BOOLEAN)
- ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
+ ext.beg = getASN1Element(&elem, ext.beg, ext.end);
/* Parse the octet string contents: is a single sequence. */
- Curl_getASN1Element(&elem, elem.beg, elem.end);
+ getASN1Element(&elem, elem.beg, elem.end);
/* Check all GeneralNames. */
for(q = elem.beg; matched != 1 && q < elem.end;) {
- q = Curl_getASN1Element(&name, q, elem.end);
+ q = getASN1Element(&name, q, elem.end);
switch(name.tag) {
case 2: /* DNS name. */
len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING,
@@ -1162,9 +1158,9 @@ CURLcode Curl_verifyhost(struct connectdata *conn,
/* we have to look to the last occurrence of a commonName in the
distinguished one to get the most significant one. */
while(q < cert.subject.end) {
- q = Curl_getASN1Element(&dn, q, cert.subject.end);
+ q = getASN1Element(&dn, q, cert.subject.end);
for(p = dn.beg; p < dn.end;) {
- p = Curl_getASN1Element(&elem, p, dn.end);
+ p = getASN1Element(&elem, p, dn.end);
/* We have a DN's AttributeTypeAndValue: check it in case it's a CN. */
elem.beg = checkOID(elem.beg, elem.end, cnOID);
if(elem.beg)
@@ -1173,7 +1169,7 @@ CURLcode Curl_verifyhost(struct connectdata *conn,
}
/* Check the CN if found. */
- if(!Curl_getASN1Element(&elem, name.beg, name.end))
+ if(!getASN1Element(&elem, name.beg, name.end))
failf(data, "SSL: unable to obtain common name from peer certificate");
else {
len = utf8asn1str(&dnsname, elem.tag, elem.beg, elem.end);