aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/curl/lib
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.ru>2022-04-20 17:40:08 +0300
committerthegeorg <thegeorg@yandex-team.ru>2022-04-20 17:40:08 +0300
commit31ff69685d432e9506ba2cad2e4cb05528021282 (patch)
tree70ed539fcc48dd4d1981fd4785797a11cd7e4006 /contrib/libs/curl/lib
parent9abb1ba6ed6c2852738c0f69367b9c0bff668676 (diff)
downloadydb-31ff69685d432e9506ba2cad2e4cb05528021282.tar.gz
Update contrib/libs/curl to 7.81.0
ref:47b24ca6f73cd31c101d7e08fb558fb7ddd6b54f
Diffstat (limited to 'contrib/libs/curl/lib')
-rw-r--r--contrib/libs/curl/lib/asyn-ares.c4
-rw-r--r--contrib/libs/curl/lib/conncache.c13
-rw-r--r--contrib/libs/curl/lib/connect.c46
-rw-r--r--contrib/libs/curl/lib/cookie.c2
-rw-r--r--contrib/libs/curl/lib/curl_config-linux.h6
-rw-r--r--contrib/libs/curl/lib/curl_hmac.h4
-rw-r--r--contrib/libs/curl/lib/curl_md5.h8
-rw-r--r--contrib/libs/curl/lib/curl_sha256.h4
-rw-r--r--contrib/libs/curl/lib/curl_sspi.c4
-rw-r--r--contrib/libs/curl/lib/easy.c10
-rw-r--r--contrib/libs/curl/lib/easyoptions.c3
-rw-r--r--contrib/libs/curl/lib/ftp.c13
-rw-r--r--contrib/libs/curl/lib/hash.c82
-rw-r--r--contrib/libs/curl/lib/hash.h12
-rw-r--r--contrib/libs/curl/lib/hostcheck.c2
-rw-r--r--contrib/libs/curl/lib/hostip.c25
-rw-r--r--contrib/libs/curl/lib/hostip.h4
-rw-r--r--contrib/libs/curl/lib/http.c13
-rw-r--r--contrib/libs/curl/lib/http.h4
-rw-r--r--contrib/libs/curl/lib/http2.c5
-rw-r--r--contrib/libs/curl/lib/http_aws_sigv4.c14
-rw-r--r--contrib/libs/curl/lib/http_proxy.c21
-rw-r--r--contrib/libs/curl/lib/http_proxy.h3
-rw-r--r--contrib/libs/curl/lib/if2ip.c4
-rw-r--r--contrib/libs/curl/lib/imap.c2
-rw-r--r--contrib/libs/curl/lib/inet_pton.c6
-rw-r--r--contrib/libs/curl/lib/krb5.c2
-rw-r--r--contrib/libs/curl/lib/ldap.c7
-rw-r--r--contrib/libs/curl/lib/md4.c4
-rw-r--r--contrib/libs/curl/lib/md5.c23
-rw-r--r--contrib/libs/curl/lib/mime.c64
-rw-r--r--contrib/libs/curl/lib/mprintf.c2
-rw-r--r--contrib/libs/curl/lib/multi.c226
-rw-r--r--contrib/libs/curl/lib/multihandle.h2
-rw-r--r--contrib/libs/curl/lib/multiif.h4
-rw-r--r--contrib/libs/curl/lib/openldap.c833
-rw-r--r--contrib/libs/curl/lib/setopt.c13
-rw-r--r--contrib/libs/curl/lib/sha256.c41
-rw-r--r--contrib/libs/curl/lib/share.c6
-rw-r--r--contrib/libs/curl/lib/smtp.c2
-rw-r--r--contrib/libs/curl/lib/socks.c33
-rw-r--r--contrib/libs/curl/lib/splay.c2
-rw-r--r--contrib/libs/curl/lib/strerror.c59
-rw-r--r--contrib/libs/curl/lib/system_win32.c2
-rw-r--r--contrib/libs/curl/lib/tftp.c2
-rw-r--r--contrib/libs/curl/lib/transfer.c2
-rw-r--r--contrib/libs/curl/lib/url.c40
-rw-r--r--contrib/libs/curl/lib/urlapi-int.h4
-rw-r--r--contrib/libs/curl/lib/urlapi.c212
-rw-r--r--contrib/libs/curl/lib/urldata.h6
-rw-r--r--contrib/libs/curl/lib/vauth/digest.c11
-rw-r--r--contrib/libs/curl/lib/vauth/ntlm.c4
-rw-r--r--contrib/libs/curl/lib/version_win32.c82
-rw-r--r--contrib/libs/curl/lib/version_win32.h3
-rw-r--r--contrib/libs/curl/lib/vquic/ngtcp2.c57
-rw-r--r--contrib/libs/curl/lib/vssh/libssh2.c13
-rw-r--r--contrib/libs/curl/lib/vtls/gtls.c34
-rw-r--r--contrib/libs/curl/lib/vtls/gtls.h8
-rw-r--r--contrib/libs/curl/lib/vtls/mbedtls.c53
-rw-r--r--contrib/libs/curl/lib/vtls/mesalink.c91
-rw-r--r--contrib/libs/curl/lib/vtls/nss.c100
-rw-r--r--contrib/libs/curl/lib/vtls/openssl.c180
-rw-r--r--contrib/libs/curl/lib/vtls/openssl.h8
-rw-r--r--contrib/libs/curl/lib/vtls/rustls.c61
-rw-r--r--contrib/libs/curl/lib/vtls/schannel.c397
-rw-r--r--contrib/libs/curl/lib/vtls/schannel_verify.c5
-rw-r--r--contrib/libs/curl/lib/vtls/sectransp.c30
-rw-r--r--contrib/libs/curl/lib/x509asn1.c127
68 files changed, 1945 insertions, 1224 deletions
diff --git a/contrib/libs/curl/lib/asyn-ares.c b/contrib/libs/curl/lib/asyn-ares.c
index f8a21175abb..2cedaa671e9 100644
--- a/contrib/libs/curl/lib/asyn-ares.c
+++ b/contrib/libs/curl/lib/asyn-ares.c
@@ -111,7 +111,9 @@ struct thread_data {
struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
parts */
int last_status;
+#ifndef HAVE_CARES_GETADDRINFO
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
+#endif
};
/* How long we are willing to wait for additional parallel responses after
@@ -377,6 +379,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
waitperform(data, 0);
+#ifndef HAVE_CARES_GETADDRINFO
/* Now that we've checked for any last minute results above, see if there are
any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
expires. */
@@ -399,6 +402,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
ares_cancel((ares_channel)data->state.async.resolver);
DEBUGASSERT(res->num_pending == 0);
}
+#endif
if(res && !res->num_pending) {
(void)Curl_addrinfo_callback(data, res->last_status, res->temp_ai);
diff --git a/contrib/libs/curl/lib/conncache.c b/contrib/libs/curl/lib/conncache.c
index f5ba8ff70a8..fec1937f0bb 100644
--- a/contrib/libs/curl/lib/conncache.c
+++ b/contrib/libs/curl/lib/conncache.c
@@ -113,21 +113,16 @@ static void free_bundle_hash_entry(void *freethis)
int Curl_conncache_init(struct conncache *connc, int size)
{
- int rc;
-
/* allocate a new easy handle to use when closing cached connections */
connc->closure_handle = curl_easy_init();
if(!connc->closure_handle)
return 1; /* bad */
- rc = Curl_hash_init(&connc->hash, size, Curl_hash_str,
- Curl_str_key_compare, free_bundle_hash_entry);
- if(rc)
- Curl_close(&connc->closure_handle);
- else
- connc->closure_handle->state.conn_cache = connc;
+ Curl_hash_init(&connc->hash, size, Curl_hash_str,
+ Curl_str_key_compare, free_bundle_hash_entry);
+ connc->closure_handle->state.conn_cache = connc;
- return rc;
+ return 0; /* good */
}
void Curl_conncache_destroy(struct conncache *connc)
diff --git a/contrib/libs/curl/lib/connect.c b/contrib/libs/curl/lib/connect.c
index af60947314f..5252f9714d0 100644
--- a/contrib/libs/curl/lib/connect.c
+++ b/contrib/libs/curl/lib/connect.c
@@ -744,15 +744,17 @@ void Curl_conninfo_local(struct Curl_easy *data, curl_socket_t sockfd,
void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t sockfd)
{
- /* 'local_ip' and 'local_port' get filled with local's numerical ip address
- and port number whenever an outgoing connection is **established** from
- the primary socket to a remote address. */
+ /* 'local_ip' and 'local_port' get filled with local's numerical
+ ip address and port number whenever an outgoing connection is
+ **established** from the primary socket to a remote address. */
char local_ip[MAX_IPADR_LEN] = "";
int local_port = -1;
- if(!conn->bits.reuse && !conn->bits.tcp_fastopen)
- Curl_conninfo_remote(data, conn, sockfd);
- Curl_conninfo_local(data, sockfd, local_ip, &local_port);
+ if(conn->transport == TRNSPRT_TCP) {
+ if(!conn->bits.reuse && !conn->bits.tcp_fastopen)
+ Curl_conninfo_remote(data, conn, sockfd);
+ Curl_conninfo_local(data, sockfd, local_ip, &local_port);
+ } /* end of TCP-only section */
/* persist connection info in session handle */
Curl_persistconninfo(data, conn, local_ip, local_port);
@@ -892,6 +894,8 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
connkeep(conn, "HTTP/3 default");
return CURLE_OK;
}
+ /* When a QUIC connect attempt fails, the better error explanation is in
+ 'result' and not in errno */
if(result) {
conn->tempsock[i] = CURL_SOCKET_BAD;
error = SOCKERRNO;
@@ -975,6 +979,13 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
char buffer[STRERROR_LEN];
Curl_printable_address(conn->tempaddr[i], ipaddress,
sizeof(ipaddress));
+#ifdef ENABLE_QUIC
+ if(conn->transport == TRNSPRT_QUIC) {
+ infof(data, "connect to %s port %u failed: %s",
+ ipaddress, conn->port, curl_easy_strerror(result));
+ }
+ else
+#endif
infof(data, "connect to %s port %u failed: %s",
ipaddress, conn->port,
Curl_strerror(error, buffer, sizeof(buffer)));
@@ -986,9 +997,11 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
ainext(conn, i, TRUE);
status = trynextip(data, conn, sockindex, i);
if((status != CURLE_COULDNT_CONNECT) ||
- conn->tempsock[other] == CURL_SOCKET_BAD)
+ conn->tempsock[other] == CURL_SOCKET_BAD) {
/* the last attempt failed and no other sockets remain open */
- result = status;
+ if(!result)
+ result = status;
+ }
}
}
}
@@ -1014,6 +1027,7 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
/* no more addresses to try */
const char *hostname;
char buffer[STRERROR_LEN];
+ CURLcode failreason = result;
/* if the first address family runs out of addresses to try before the
happy eyeball timeout, go ahead and try the next family now */
@@ -1021,6 +1035,8 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
if(!result)
return result;
+ result = failreason;
+
#ifndef CURL_DISABLE_PROXY
if(conn->bits.socksproxy)
hostname = conn->socks_proxy.host.name;
@@ -1034,10 +1050,14 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
hostname = conn->host.name;
failf(data, "Failed to connect to %s port %u after "
- "%" CURL_FORMAT_TIMEDIFF_T " ms: %s",
- hostname, conn->port,
- Curl_timediff(now, data->progress.t_startsingle),
- Curl_strerror(error, buffer, sizeof(buffer)));
+ "%" CURL_FORMAT_TIMEDIFF_T " ms: %s",
+ hostname, conn->port,
+ Curl_timediff(now, data->progress.t_startsingle),
+#ifdef ENABLE_QUIC
+ (conn->transport == TRNSPRT_QUIC) ?
+ curl_easy_strerror(result) :
+#endif
+ Curl_strerror(error, buffer, sizeof(buffer)));
Curl_quic_disconnect(data, conn, 0);
Curl_quic_disconnect(data, conn, 1);
@@ -1125,7 +1145,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
static int detectOsState = DETECT_OS_NONE;
if(detectOsState == DETECT_OS_NONE) {
- if(curlx_verify_windows_version(6, 0, PLATFORM_WINNT,
+ if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL))
detectOsState = DETECT_OS_VISTA_OR_LATER;
else
diff --git a/contrib/libs/curl/lib/cookie.c b/contrib/libs/curl/lib/cookie.c
index b7531f74244..d418efa33d5 100644
--- a/contrib/libs/curl/lib/cookie.c
+++ b/contrib/libs/curl/lib/cookie.c
@@ -1164,7 +1164,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
bool fromfile = TRUE;
char *line = NULL;
- if(NULL == inc) {
+ if(!inc) {
/* we didn't get a struct, create one */
c = calloc(1, sizeof(struct CookieInfo));
if(!c)
diff --git a/contrib/libs/curl/lib/curl_config-linux.h b/contrib/libs/curl/lib/curl_config-linux.h
index 984a078525b..804397de28f 100644
--- a/contrib/libs/curl/lib/curl_config-linux.h
+++ b/contrib/libs/curl/lib/curl_config-linux.h
@@ -499,9 +499,6 @@
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#define HAVE_OPENSSL_SSL_H 1
-/* Define to 1 if you have the `OpenSSL_version' function. */
-#define HAVE_OPENSSL_VERSION 1
-
/* Define to 1 if you have the <openssl/x509.h> header file. */
#define HAVE_OPENSSL_X509_H 1
@@ -601,9 +598,6 @@
/* Define to 1 if you have the <socket.h> header file. */
/* #undef HAVE_SOCKET_H */
-/* Define to 1 if you have the `SSLv2_client_method' function. */
-/* #undef HAVE_SSLV2_CLIENT_METHOD */
-
/* Define to 1 if you have the `SSL_get_ech_status' function. */
/* #undef HAVE_SSL_GET_ECH_STATUS */
diff --git a/contrib/libs/curl/lib/curl_hmac.h b/contrib/libs/curl/lib/curl_hmac.h
index 84c73121bda..5755655d024 100644
--- a/contrib/libs/curl/lib/curl_hmac.h
+++ b/contrib/libs/curl/lib/curl_hmac.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -26,7 +26,7 @@
#define HMAC_MD5_LENGTH 16
-typedef void (* HMAC_hinit_func)(void *context);
+typedef CURLcode (* HMAC_hinit_func)(void *context);
typedef void (* HMAC_hupdate_func)(void *context,
const unsigned char *data,
unsigned int len);
diff --git a/contrib/libs/curl/lib/curl_md5.h b/contrib/libs/curl/lib/curl_md5.h
index 5739c89ca41..b7d7c1f5d25 100644
--- a/contrib/libs/curl/lib/curl_md5.h
+++ b/contrib/libs/curl/lib/curl_md5.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -27,7 +27,7 @@
#define MD5_DIGEST_LEN 16
-typedef void (* Curl_MD5_init_func)(void *context);
+typedef CURLcode (* Curl_MD5_init_func)(void *context);
typedef void (* Curl_MD5_update_func)(void *context,
const unsigned char *data,
unsigned int len);
@@ -49,8 +49,8 @@ struct MD5_context {
extern const struct MD5_params Curl_DIGEST_MD5[1];
extern const struct HMAC_params Curl_HMAC_MD5[1];
-void Curl_md5it(unsigned char *output, const unsigned char *input,
- const size_t len);
+CURLcode Curl_md5it(unsigned char *output, const unsigned char *input,
+ const size_t len);
struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params);
CURLcode Curl_MD5_update(struct MD5_context *context,
diff --git a/contrib/libs/curl/lib/curl_sha256.h b/contrib/libs/curl/lib/curl_sha256.h
index 3cafe8ee7b2..7b408ef5482 100644
--- a/contrib/libs/curl/lib/curl_sha256.h
+++ b/contrib/libs/curl/lib/curl_sha256.h
@@ -37,8 +37,8 @@ extern const struct HMAC_params Curl_HMAC_SHA256[1];
#define SHA256_DIGEST_LENGTH 32
#endif
-void Curl_sha256it(unsigned char *outbuffer, const unsigned char *input,
- const size_t len);
+CURLcode Curl_sha256it(unsigned char *outbuffer, const unsigned char *input,
+ const size_t len);
#endif
diff --git a/contrib/libs/curl/lib/curl_sspi.c b/contrib/libs/curl/lib/curl_sspi.c
index 06841ddec69..339bf549fbb 100644
--- a/contrib/libs/curl/lib/curl_sspi.c
+++ b/contrib/libs/curl/lib/curl_sspi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, 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
@@ -83,7 +83,7 @@ CURLcode Curl_sspi_global_init(void)
* have both these DLLs (security.dll forwards calls to secur32.dll) */
/* Load SSPI dll into the address space of the calling process */
- if(curlx_verify_windows_version(4, 0, PLATFORM_WINNT, VERSION_EQUAL))
+ if(curlx_verify_windows_version(4, 0, 0, PLATFORM_WINNT, VERSION_EQUAL))
s_hSecDll = Curl_load_library(TEXT("security.dll"));
else
s_hSecDll = Curl_load_library(TEXT("secur32.dll"));
diff --git a/contrib/libs/curl/lib/easy.c b/contrib/libs/curl/lib/easy.c
index 2aca93845b4..20293a710b9 100644
--- a/contrib/libs/curl/lib/easy.c
+++ b/contrib/libs/curl/lib/easy.c
@@ -822,7 +822,7 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
{
struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy));
- if(NULL == outcurl)
+ if(!outcurl)
goto fail;
/*
@@ -1087,14 +1087,16 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
/* if not pausing again, force a recv/send check of this connection as
the data might've been read off the socket already */
data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT;
- if(data->multi)
- Curl_update_timer(data->multi);
+ if(data->multi) {
+ if(Curl_update_timer(data->multi))
+ return CURLE_ABORTED_BY_CALLBACK;
+ }
}
if(!data->state.done)
/* This transfer may have been moved in or out of the bundle, update the
corresponding socket callback, if used */
- Curl_updatesocket(data);
+ result = Curl_updatesocket(data);
return result;
}
diff --git a/contrib/libs/curl/lib/easyoptions.c b/contrib/libs/curl/lib/easyoptions.c
index b6131d4321c..04871ad1e3b 100644
--- a/contrib/libs/curl/lib/easyoptions.c
+++ b/contrib/libs/curl/lib/easyoptions.c
@@ -170,6 +170,7 @@ struct curl_easyoption Curl_easyopts[] = {
{"MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE, CURLOT_OFF_T, 0},
{"MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE, CURLOT_OFF_T, 0},
{"MIMEPOST", CURLOPT_MIMEPOST, CURLOT_OBJECT, 0},
+ {"MIME_OPTIONS", CURLOPT_MIME_OPTIONS, CURLOT_LONG, 0},
{"NETRC", CURLOPT_NETRC, CURLOT_VALUES, 0},
{"NETRC_FILE", CURLOPT_NETRC_FILE, CURLOT_STRING, 0},
{"NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS, CURLOT_LONG, 0},
@@ -359,6 +360,6 @@ struct curl_easyoption Curl_easyopts[] = {
*/
int Curl_easyopts_check(void)
{
- return ((CURLOPT_LASTENTRY%10000) != (314 + 1));
+ return ((CURLOPT_LASTENTRY%10000) != (315 + 1));
}
#endif
diff --git a/contrib/libs/curl/lib/ftp.c b/contrib/libs/curl/lib/ftp.c
index a8d209e3fb4..f6921e42620 100644
--- a/contrib/libs/curl/lib/ftp.c
+++ b/contrib/libs/curl/lib/ftp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, 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
@@ -1004,7 +1004,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
}
/* parse the port */
- if(ip_end != NULL) {
+ if(ip_end) {
port_start = strchr(ip_end, ':');
if(port_start) {
port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10));
@@ -4102,6 +4102,11 @@ static CURLcode ftp_disconnect(struct Curl_easy *data,
return CURLE_OK;
}
+#ifdef _MSC_VER
+/* warning C4706: assignment within conditional expression */
+#pragma warning(disable:4706)
+#endif
+
/***********************************************************************
*
* ftp_parse_url_path()
@@ -4190,7 +4195,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
}
/* parse the URL path into separate path components */
- while((slashPos = strchr(curPos, '/')) != NULL) {
+ while((slashPos = strchr(curPos, '/'))) {
size_t compLen = slashPos - curPos;
/* path starts with a slash: add that as a directory */
@@ -4357,7 +4362,7 @@ static CURLcode ftp_setup_connection(struct Curl_easy *data,
struct FTP *ftp;
data->req.p.ftp = ftp = calloc(sizeof(struct FTP), 1);
- if(NULL == ftp)
+ if(!ftp)
return CURLE_OUT_OF_MEMORY;
ftp->path = &data->state.up.path[1]; /* don't include the initial slash */
diff --git a/contrib/libs/curl/lib/hash.c b/contrib/libs/curl/lib/hash.c
index 12e7aa5f278..8848906947b 100644
--- a/contrib/libs/curl/lib/hash.c
+++ b/contrib/libs/curl/lib/hash.c
@@ -53,32 +53,25 @@ hash_element_dtor(void *user, void *element)
* @unittest: 1602
* @unittest: 1603
*/
-int
+void
Curl_hash_init(struct Curl_hash *h,
int slots,
hash_function hfunc,
comp_function comparator,
Curl_hash_dtor dtor)
{
- if(!slots || !hfunc || !comparator ||!dtor) {
- return 1; /* failure */
- }
+ DEBUGASSERT(h);
+ DEBUGASSERT(slots);
+ DEBUGASSERT(hfunc);
+ DEBUGASSERT(comparator);
+ DEBUGASSERT(dtor);
+ h->table = NULL;
h->hash_func = hfunc;
h->comp_func = comparator;
h->dtor = dtor;
h->size = 0;
h->slots = slots;
-
- 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 */
- }
- h->slots = 0;
- return 1; /* failure */
}
static struct Curl_hash_element *
@@ -98,8 +91,9 @@ mk_hash_element(const void *key, size_t key_len, const void *p)
#define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)]
-/* Insert the data in the hash. If there already was a match in the hash,
- * that data is replaced.
+/* Insert the data in the hash. If there already was a match in the hash, that
+ * data is replaced. This function also "lazily" allocates the table if
+ * needed, as it isn't done in the _init function (anymore).
*
* @unittest: 1305
* @unittest: 1602
@@ -110,7 +104,20 @@ Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
{
struct Curl_hash_element *he;
struct Curl_llist_element *le;
- struct Curl_llist *l = FETCH_LIST(h, key, key_len);
+ struct Curl_llist *l;
+
+ DEBUGASSERT(h);
+ DEBUGASSERT(h->slots);
+ if(!h->table) {
+ int i;
+ h->table = malloc(h->slots * sizeof(struct Curl_llist));
+ if(!h->table)
+ return NULL; /* OOM */
+ for(i = 0; i < h->slots; ++i)
+ Curl_llist_init(&h->table[i], hash_element_dtor);
+ }
+
+ l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
he = (struct Curl_hash_element *) le->ptr;
@@ -139,14 +146,20 @@ 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_llist *l = FETCH_LIST(h, key, key_len);
+ struct Curl_llist *l;
- for(le = l->head; le; le = le->next) {
- 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;
- return 0;
+ DEBUGASSERT(h);
+ DEBUGASSERT(h->slots);
+ if(h->table) {
+ l = FETCH_LIST(h, key, key_len);
+
+ for(le = l->head; le; le = le->next) {
+ 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;
+ return 0;
+ }
}
}
return 1;
@@ -162,7 +175,9 @@ Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len)
struct Curl_llist_element *le;
struct Curl_llist *l;
- if(h) {
+ DEBUGASSERT(h);
+ if(h->table) {
+ DEBUGASSERT(h->slots);
l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
struct Curl_hash_element *he = le->ptr;
@@ -204,13 +219,13 @@ Curl_hash_apply(Curl_hash *h, void *user,
void
Curl_hash_destroy(struct Curl_hash *h)
{
- int i;
-
- for(i = 0; i < h->slots; ++i) {
- Curl_llist_destroy(&h->table[i], (void *) h);
+ if(h->table) {
+ int i;
+ for(i = 0; i < h->slots; ++i) {
+ Curl_llist_destroy(&h->table[i], (void *) h);
+ }
+ Curl_safefree(h->table);
}
-
- Curl_safefree(h->table);
h->size = 0;
h->slots = 0;
}
@@ -235,7 +250,7 @@ Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user,
struct Curl_llist *list;
int i;
- if(!h)
+ if(!h || !h->table)
return;
for(i = 0; i < h->slots; ++i) {
@@ -290,6 +305,9 @@ Curl_hash_next_element(struct Curl_hash_iterator *iter)
{
struct Curl_hash *h = iter->hash;
+ if(!h->table)
+ return NULL; /* empty hash, nothing to return */
+
/* Get the next element in the current list, if any */
if(iter->current_element)
iter->current_element = iter->current_element->next;
diff --git a/contrib/libs/curl/lib/hash.h b/contrib/libs/curl/lib/hash.h
index b7f828e0716..e166916a90b 100644
--- a/contrib/libs/curl/lib/hash.h
+++ b/contrib/libs/curl/lib/hash.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, 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
@@ -69,11 +69,11 @@ struct Curl_hash_iterator {
struct Curl_llist_element *current_element;
};
-int Curl_hash_init(struct Curl_hash *h,
- int slots,
- hash_function hfunc,
- comp_function comparator,
- Curl_hash_dtor dtor);
+void Curl_hash_init(struct Curl_hash *h,
+ int slots,
+ hash_function hfunc,
+ comp_function comparator,
+ Curl_hash_dtor dtor);
void *Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p);
int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len);
diff --git a/contrib/libs/curl/lib/hostcheck.c b/contrib/libs/curl/lib/hostcheck.c
index 7f2d5ce0ce1..3e436f03517 100644
--- a/contrib/libs/curl/lib/hostcheck.c
+++ b/contrib/libs/curl/lib/hostcheck.c
@@ -89,7 +89,7 @@ static int hostmatch(char *hostname, char *pattern)
match. */
wildcard_enabled = 1;
pattern_label_end = strchr(pattern, '.');
- if(!pattern_label_end || strchr(pattern_label_end + 1, '.') == NULL ||
+ if(!pattern_label_end || !strchr(pattern_label_end + 1, '.') ||
pattern_wildcard > pattern_label_end ||
strncasecompare(pattern, "xn--", 4)) {
wildcard_enabled = 0;
diff --git a/contrib/libs/curl/lib/hostip.c b/contrib/libs/curl/lib/hostip.c
index 62537f82372..0ea005e4d2e 100644
--- a/contrib/libs/curl/lib/hostip.c
+++ b/contrib/libs/curl/lib/hostip.c
@@ -609,7 +609,11 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
struct connectdata *conn = data->conn;
*entry = NULL;
+#ifndef CURL_DISABLE_DOH
conn->bits.doh = FALSE; /* default is not */
+#else
+ (void)allowDOH;
+#endif
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
@@ -630,11 +634,15 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
struct Curl_addrinfo *addr = NULL;
int respwait = 0;
+#if !defined(CURL_DISABLE_DOH) || !defined(USE_RESOLVE_ON_IPS)
struct in_addr in;
+#endif
+#ifndef CURL_DISABLE_DOH
#ifndef USE_RESOLVE_ON_IPS
const
#endif
bool ipnum = FALSE;
+#endif
/* notify the resolver start callback */
if(data->set.resolver_start) {
@@ -686,6 +694,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
#endif /* ENABLE_IPV6 */
#else /* if USE_RESOLVE_ON_IPS */
+#ifndef CURL_DISABLE_DOH
/* First check if this is an IPv4 address string */
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
/* This is a dotted IP address 123.123.123.123-style */
@@ -699,6 +708,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
ipnum = TRUE;
}
#endif /* ENABLE_IPV6 */
+#endif /* CURL_DISABLE_DOH */
#endif /* !USE_RESOLVE_ON_IPS */
@@ -708,8 +718,10 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
if(strcasecompare(hostname, "localhost"))
addr = get_localhost(port);
+#ifndef CURL_DISABLE_DOH
else if(allowDOH && data->set.doh && !ipnum)
addr = Curl_doh(data, hostname, port, &respwait);
+#endif
else {
/* Check what IP specifics the app has requested and if we can provide
* it. If not, bail out. */
@@ -977,12 +989,12 @@ static void freednsentry(void *freethis)
}
/*
- * Curl_mk_dnscache() inits a new DNS cache and returns success/failure.
+ * Curl_init_dnscache() inits a new DNS cache.
*/
-int Curl_mk_dnscache(struct Curl_hash *hash)
+void Curl_init_dnscache(struct Curl_hash *hash)
{
- return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
- freednsentry);
+ Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
+ freednsentry);
}
/*
@@ -1210,9 +1222,10 @@ CURLcode Curl_resolv_check(struct Curl_easy *data,
#if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH)
(void)dns;
#endif
-
+#ifndef CURL_DISABLE_DOH
if(data->conn->bits.doh)
return Curl_doh_is_resolved(data, dns);
+#endif
return Curl_resolver_is_resolved(data, dns);
}
@@ -1220,10 +1233,12 @@ int Curl_resolv_getsock(struct Curl_easy *data,
curl_socket_t *socks)
{
#ifdef CURLRES_ASYNCH
+#ifndef CURL_DISABLE_DOH
if(data->conn->bits.doh)
/* nothing to wait for during DoH resolve, those handles have their own
sockets */
return GETSOCK_BLANK;
+#endif
return Curl_resolver_getsock(data, socks);
#else
(void)data;
diff --git a/contrib/libs/curl/lib/hostip.h b/contrib/libs/curl/lib/hostip.h
index 67a688aebdc..1db5981842f 100644
--- a/contrib/libs/curl/lib/hostip.h
+++ b/contrib/libs/curl/lib/hostip.h
@@ -129,8 +129,8 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
void Curl_resolv_unlock(struct Curl_easy *data,
struct Curl_dns_entry *dns);
-/* init a new dns cache and return success */
-int Curl_mk_dnscache(struct Curl_hash *hash);
+/* init a new dns cache */
+void Curl_init_dnscache(struct Curl_hash *hash);
/* prune old entries from the DNS cache */
void Curl_hostcache_prune(struct Curl_easy *data);
diff --git a/contrib/libs/curl/lib/http.c b/contrib/libs/curl/lib/http.c
index 838c5bf4019..04dc034fd0b 100644
--- a/contrib/libs/curl/lib/http.c
+++ b/contrib/libs/curl/lib/http.c
@@ -1153,7 +1153,6 @@ static bool http_should_fail(struct Curl_easy *data)
return data->state.authproblem;
}
-#ifndef USE_HYPER
/*
* readmoredata() is a "fread() emulation" to provide POST and/or request
* data. It is used when a huge POST is to be made and the entire chunk wasn't
@@ -1412,8 +1411,6 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
return result;
}
-#endif
-
/* end of the add_buffer functions */
/* ------------------------------------------------------------------------- */
@@ -2375,6 +2372,9 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
#ifndef USE_HYPER
/* Hyper always handles the body separately */
curl_off_t included_body = 0;
+#else
+ /* from this point down, this function should not be used */
+#define Curl_buffer_send(a,b,c,d,e) CURLE_OK
#endif
CURLcode result = CURLE_OK;
struct HTTP *http = data->req.p.http;
@@ -2685,7 +2685,6 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
/* issue the request */
result = Curl_buffer_send(r, data, &data->info.request_size, 0,
FIRSTSOCKET);
-
if(result)
failf(data, "Failed sending HTTP request");
else
@@ -3312,7 +3311,7 @@ checkhttpprefix(struct Curl_easy *data,
#ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding using a scratch area */
char *scratch = strdup(s);
- if(NULL == scratch) {
+ if(!scratch) {
failf(data, "Failed to allocate memory for conversion!");
return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
}
@@ -3352,7 +3351,7 @@ checkrtspprefix(struct Curl_easy *data,
#ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding using a scratch area */
char *scratch = strdup(s);
- if(NULL == scratch) {
+ if(!scratch) {
failf(data, "Failed to allocate memory for conversion!");
return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
}
@@ -4245,7 +4244,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
The sscanf() line above will also allow zero-prefixed and negative
numbers, so we check for that too here.
*/
- else if(ISDIGIT(digit4) || (k->httpcode < 100)) {
+ else if(ISDIGIT(digit4) || (nc >= 4 && k->httpcode < 100)) {
failf(data, "Unsupported response code in HTTP response");
return CURLE_UNSUPPORTED_PROTOCOL;
}
diff --git a/contrib/libs/curl/lib/http.h b/contrib/libs/curl/lib/http.h
index cb5b56faf37..b4aaba2a26b 100644
--- a/contrib/libs/curl/lib/http.h
+++ b/contrib/libs/curl/lib/http.h
@@ -54,15 +54,11 @@ char *Curl_copy_header_value(const char *header);
char *Curl_checkProxyheaders(struct Curl_easy *data,
const struct connectdata *conn,
const char *thisheader);
-#ifndef USE_HYPER
CURLcode Curl_buffer_send(struct dynbuf *in,
struct Curl_easy *data,
curl_off_t *bytes_written,
curl_off_t included_body_bytes,
int socketindex);
-#else
-#define Curl_buffer_send(a,b,c,d,e) CURLE_OK
-#endif
CURLcode Curl_add_timecondition(struct Curl_easy *data,
#ifndef USE_HYPER
diff --git a/contrib/libs/curl/lib/http2.c b/contrib/libs/curl/lib/http2.c
index 992fbbb26db..e74400a4caa 100644
--- a/contrib/libs/curl/lib/http2.c
+++ b/contrib/libs/curl/lib/http2.c
@@ -505,10 +505,13 @@ static int set_transfer_url(struct Curl_easy *data,
struct curl_pushheaders *hp)
{
const char *v;
- CURLU *u = curl_url();
CURLUcode uc;
char *url = NULL;
int rc = 0;
+ CURLU *u = curl_url();
+
+ if(!u)
+ return 5;
v = curl_pushheader_byname(hp, ":scheme");
if(v) {
diff --git a/contrib/libs/curl/lib/http_aws_sigv4.c b/contrib/libs/curl/lib/http_aws_sigv4.c
index cbbecb71298..751e5af5f91 100644
--- a/contrib/libs/curl/lib/http_aws_sigv4.c
+++ b/contrib/libs/curl/lib/http_aws_sigv4.c
@@ -286,8 +286,11 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
post_data_len = strlen(post_data);
else
post_data_len = (size_t)data->set.postfieldsize;
- Curl_sha256it(sha_hash,
- (const unsigned char *) post_data, post_data_len);
+ if(Curl_sha256it(sha_hash, (const unsigned char *) post_data,
+ post_data_len)) {
+ goto fail;
+ }
+
sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
Curl_http_method(data, conn, &method, &httpreq);
@@ -320,8 +323,11 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
goto fail;
}
- Curl_sha256it(sha_hash, (unsigned char *) canonical_request,
- strlen(canonical_request));
+ if(Curl_sha256it(sha_hash, (unsigned char *) canonical_request,
+ strlen(canonical_request))) {
+ goto fail;
+ }
+
sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
/*
diff --git a/contrib/libs/curl/lib/http_proxy.c b/contrib/libs/curl/lib/http_proxy.c
index bc0d0bfcc38..2324b6effd8 100644
--- a/contrib/libs/curl/lib/http_proxy.c
+++ b/contrib/libs/curl/lib/http_proxy.c
@@ -158,6 +158,10 @@ static CURLcode connect_init(struct Curl_easy *data, bool reinit)
{
struct http_connect_state *s;
struct connectdata *conn = data->conn;
+ if(conn->handler->flags & PROTOPT_NOTCPPROXY) {
+ failf(data, "%s cannot be done over CONNECT", conn->handler->scheme);
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ }
if(!reinit) {
CURLcode result;
DEBUGASSERT(!conn->connect_state);
@@ -198,17 +202,18 @@ static CURLcode connect_init(struct Curl_easy *data, bool reinit)
return CURLE_OK;
}
-static void connect_done(struct Curl_easy *data)
+void Curl_connect_done(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
struct http_connect_state *s = conn->connect_state;
- if(s->tunnel_state != TUNNEL_EXIT) {
+ if(s && (s->tunnel_state != TUNNEL_EXIT)) {
s->tunnel_state = TUNNEL_EXIT;
Curl_dyn_free(&s->rcvbuf);
Curl_dyn_free(&s->req);
- /* restore the protocol pointer */
- data->req.p.http = s->prot_save;
+ /* restore the protocol pointer, if not already done */
+ if(s->prot_save)
+ data->req.p.http = s->prot_save;
s->prot_save = NULL;
data->info.httpcode = 0; /* clear it as it might've been used for the
proxy */
@@ -662,15 +667,13 @@ static CURLcode CONNECT(struct Curl_easy *data,
if(s->close_connection && data->req.newurl) {
conn->bits.proxy_connect_closed = TRUE;
infof(data, "Connect me again please");
- connect_done(data);
+ Curl_connect_done(data);
}
else {
free(data->req.newurl);
data->req.newurl = NULL;
/* failure, close this connection to avoid re-use */
streamclose(conn, "proxy CONNECT failure");
- Curl_closesocket(data, conn, conn->sock[sockindex]);
- conn->sock[sockindex] = CURL_SOCKET_BAD;
}
/* to back to init state */
@@ -974,7 +977,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
if(conn->bits.close && data->req.newurl) {
conn->bits.proxy_connect_closed = TRUE;
infof(data, "Connect me again please");
- connect_done(data);
+ Curl_connect_done(data);
}
else {
free(data->req.newurl);
@@ -1048,7 +1051,7 @@ CURLcode Curl_proxyCONNECT(struct Curl_easy *data,
result = CONNECT(data, sockindex, hostname, remote_port);
if(result || Curl_connect_complete(conn))
- connect_done(data);
+ Curl_connect_done(data);
return result;
}
diff --git a/contrib/libs/curl/lib/http_proxy.h b/contrib/libs/curl/lib/http_proxy.h
index cdf8de4fba8..2820e11841c 100644
--- a/contrib/libs/curl/lib/http_proxy.h
+++ b/contrib/libs/curl/lib/http_proxy.h
@@ -39,6 +39,7 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex);
bool Curl_connect_complete(struct connectdata *conn);
bool Curl_connect_ongoing(struct connectdata *conn);
int Curl_connect_getsock(struct connectdata *conn);
+void Curl_connect_done(struct Curl_easy *data);
#else
#define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN
@@ -46,10 +47,10 @@ int Curl_connect_getsock(struct connectdata *conn);
#define Curl_connect_complete(x) CURLE_OK
#define Curl_connect_ongoing(x) FALSE
#define Curl_connect_getsock(x) 0
+#define Curl_connect_done(x)
#endif
void Curl_connect_free(struct Curl_easy *data);
-void Curl_connect_done(struct Curl_easy *data);
/* struct for HTTP CONNECT state data */
struct http_connect_state {
diff --git a/contrib/libs/curl/lib/if2ip.c b/contrib/libs/curl/lib/if2ip.c
index 21e00b1f169..132b3eeeea3 100644
--- a/contrib/libs/curl/lib/if2ip.c
+++ b/contrib/libs/curl/lib/if2ip.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, 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
@@ -114,7 +114,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
if(getifaddrs(&head) >= 0) {
for(iface = head; iface != NULL; iface = iface->ifa_next) {
- if(iface->ifa_addr != NULL) {
+ if(iface->ifa_addr) {
if(iface->ifa_addr->sa_family == af) {
if(strcasecompare(iface->ifa_name, interf)) {
void *addr;
diff --git a/contrib/libs/curl/lib/imap.c b/contrib/libs/curl/lib/imap.c
index bea964f79a9..958ad1456c1 100644
--- a/contrib/libs/curl/lib/imap.c
+++ b/contrib/libs/curl/lib/imap.c
@@ -329,7 +329,7 @@ static bool imap_endofresp(struct Curl_easy *data, struct connectdata *conn,
/* Do we have a continuation response? This should be a + symbol followed by
a space and optionally some text as per RFC-3501 for the AUTHENTICATE and
APPEND commands and as outlined in Section 4. Examples of RFC-4959 but
- some e-mail servers ignore this and only send a single + instead. */
+ some email servers ignore this and only send a single + instead. */
if(imap && !imap->custom && ((len == 3 && line[0] == '+') ||
(len >= 2 && !memcmp("+ ", line, 2)))) {
switch(imapc->state) {
diff --git a/contrib/libs/curl/lib/inet_pton.c b/contrib/libs/curl/lib/inet_pton.c
index 4923cae245f..ada57af289a 100644
--- a/contrib/libs/curl/lib/inet_pton.c
+++ b/contrib/libs/curl/lib/inet_pton.c
@@ -1,6 +1,6 @@
/* This is from the BIND 4.9.4 release, modified to compile by itself */
-/* Copyright (c) 1996 - 2020 by Internet Software Consortium.
+/* Copyright (c) 1996 - 2021 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -174,7 +174,7 @@ inet_pton6(const char *src, unsigned char *dst)
pch = strchr((xdigits = xdigits_l), ch);
if(!pch)
pch = strchr((xdigits = xdigits_u), ch);
- if(pch != NULL) {
+ if(pch) {
val <<= 4;
val |= (pch - xdigits);
if(++saw_xdigit > 4)
@@ -211,7 +211,7 @@ inet_pton6(const char *src, unsigned char *dst)
*tp++ = (unsigned char) ((val >> 8) & 0xff);
*tp++ = (unsigned char) (val & 0xff);
}
- if(colonp != NULL) {
+ if(colonp) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
diff --git a/contrib/libs/curl/lib/krb5.c b/contrib/libs/curl/lib/krb5.c
index 57cfbf42829..ebccc6790f8 100644
--- a/contrib/libs/curl/lib/krb5.c
+++ b/contrib/libs/curl/lib/krb5.c
@@ -880,7 +880,7 @@ Curl_sec_login(struct Curl_easy *data, struct connectdata *conn)
void
Curl_sec_end(struct connectdata *conn)
{
- if(conn->mech != NULL && conn->mech->end)
+ if(conn->mech && conn->mech->end)
conn->mech->end(conn->app_data);
free(conn->app_data);
conn->app_data = NULL;
diff --git a/contrib/libs/curl/lib/ldap.c b/contrib/libs/curl/lib/ldap.c
index 1e2253bbf86..8170c31677b 100644
--- a/contrib/libs/curl/lib/ldap.c
+++ b/contrib/libs/curl/lib/ldap.c
@@ -464,6 +464,11 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
#endif
#endif /* CURL_LDAP_USE_SSL */
}
+ else if(data->set.use_ssl > CURLUSESSL_TRY) {
+ failf(data, "LDAP local: explicit TLS not supported");
+ result = CURLE_NOT_BUILT_IN;
+ goto quit;
+ }
else {
server = ldap_init(host, (int)conn->port);
if(!server) {
@@ -590,7 +595,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
attr_len = strlen(attr);
vals = ldap_get_values_len(server, entryIterator, attribute);
- if(vals != NULL) {
+ if(vals) {
for(i = 0; (vals[i] != NULL); i++) {
result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
if(result) {
diff --git a/contrib/libs/curl/lib/md4.c b/contrib/libs/curl/lib/md4.c
index 87b56213632..7778de9ac3f 100644
--- a/contrib/libs/curl/lib/md4.c
+++ b/contrib/libs/curl/lib/md4.c
@@ -189,7 +189,7 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
{
if(!ctx->data) {
ctx->data = malloc(size);
- if(ctx->data != NULL) {
+ if(ctx->data) {
memcpy(ctx->data, data, size);
ctx->size = size;
}
@@ -198,7 +198,7 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
{
- if(ctx->data != NULL) {
+ if(ctx->data) {
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
mbedtls_md4(ctx->data, ctx->size, result);
#else
diff --git a/contrib/libs/curl/lib/md5.c b/contrib/libs/curl/lib/md5.c
index 63371511b70..a1e514d357b 100644
--- a/contrib/libs/curl/lib/md5.c
+++ b/contrib/libs/curl/lib/md5.c
@@ -62,9 +62,10 @@
typedef struct md5_ctx MD5_CTX;
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
{
md5_init(ctx);
+ return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx,
@@ -98,13 +99,14 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
typedef mbedtls_md5_context MD5_CTX;
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
{
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
(void) mbedtls_md5_starts(ctx);
#else
(void) mbedtls_md5_starts_ret(ctx);
#endif
+ return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx,
@@ -146,9 +148,10 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
/* The last #include file should be: */
#include "memdebug.h"
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
{
CC_MD5_Init(ctx);
+ return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx,
@@ -176,12 +179,13 @@ struct md5_ctx {
};
typedef struct md5_ctx MD5_CTX;
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
{
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
}
+ return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx,
@@ -261,7 +265,7 @@ struct md5_ctx {
};
typedef struct md5_ctx MD5_CTX;
-static void MD5_Init(MD5_CTX *ctx);
+static CURLcode MD5_Init(MD5_CTX *ctx);
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
@@ -422,7 +426,7 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
return ptr;
}
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
@@ -431,6 +435,8 @@ static void MD5_Init(MD5_CTX *ctx)
ctx->lo = 0;
ctx->hi = 0;
+
+ return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
@@ -555,8 +561,9 @@ const struct MD5_params Curl_DIGEST_MD5[] = {
/*
* @unittest: 1601
+ * Returns CURLE_OK on success.
*/
-void Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
+CURLcode Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
const size_t len)
{
MD5_CTX ctx;
@@ -564,6 +571,8 @@ void Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
MD5_Init(&ctx);
MD5_Update(&ctx, input, curlx_uztoui(len));
MD5_Final(outbuffer, &ctx);
+
+ return CURLE_OK;
}
struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params)
diff --git a/contrib/libs/curl/lib/mime.c b/contrib/libs/curl/lib/mime.c
index f40cc1a618a..7783b8990a0 100644
--- a/contrib/libs/curl/lib/mime.c
+++ b/contrib/libs/curl/lib/mime.c
@@ -40,6 +40,7 @@
#include "rand.h"
#include "slist.h"
#include "strcase.h"
+#include "dynbuf.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -279,29 +280,52 @@ static void mimesetstate(struct mime_state *state,
/* Escape header string into allocated memory. */
-static char *escape_string(const char *src)
-{
- size_t bytecount = 0;
- size_t i;
- char *dst;
+static char *escape_string(struct Curl_easy *data,
+ const char *src, enum mimestrategy strategy)
+{
+ CURLcode result;
+ struct dynbuf db;
+ const char * const *table;
+ const char * const *p;
+ /* replace first character by rest of string. */
+ static const char * const mimetable[] = {
+ "\\\\\\",
+ "\"\\\"",
+ NULL
+ };
+ /* WHATWG HTML living standard 4.10.21.8 2 specifies:
+ For field names and filenames for file fields, the result of the
+ encoding in the previous bullet point must be escaped by replacing
+ any 0x0A (LF) bytes with the byte sequence `%0A`, 0x0D (CR) with `%0D`
+ and 0x22 (") with `%22`.
+ The user agent must not perform any other escapes. */
+ static const char * const formtable[] = {
+ "\"%22",
+ "\r%0D",
+ "\n%0A",
+ NULL
+ };
- for(i = 0; src[i]; i++)
- if(src[i] == '"' || src[i] == '\\')
- bytecount++;
+ table = formtable;
+ /* data can be NULL when this function is called indirectly from
+ curl_formget(). */
+ if(strategy == MIMESTRATEGY_MAIL ||
+ (data && (data->set.mime_options & CURLMIMEOPT_FORMESCAPE)))
+ table = mimetable;
- bytecount += i;
- dst = malloc(bytecount + 1);
- if(!dst)
- return NULL;
+ Curl_dyn_init(&db, CURL_MAX_INPUT_LENGTH);
- for(i = 0; *src; src++) {
- if(*src == '"' || *src == '\\')
- dst[i++] = '\\';
- dst[i++] = *src;
+ for(result = Curl_dyn_add(&db, ""); !result && *src; src++) {
+ for(p = table; *p && **p != *src; p++)
+ ;
+
+ if(*p)
+ result = Curl_dyn_add(&db, *p + 1);
+ else
+ result = Curl_dyn_addn(&db, src, 1);
}
- dst[i] = '\0';
- return dst;
+ return Curl_dyn_ptr(&db);
}
/* Check if header matches. */
@@ -1866,12 +1890,12 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
char *filename = NULL;
if(part->name) {
- name = escape_string(part->name);
+ name = escape_string(part->easy, part->name, strategy);
if(!name)
ret = CURLE_OUT_OF_MEMORY;
}
if(!ret && part->filename) {
- filename = escape_string(part->filename);
+ filename = escape_string(part->easy, part->filename, strategy);
if(!filename)
ret = CURLE_OUT_OF_MEMORY;
}
diff --git a/contrib/libs/curl/lib/mprintf.c b/contrib/libs/curl/lib/mprintf.c
index 7a1aec570e5..0fd3afc8aef 100644
--- a/contrib/libs/curl/lib/mprintf.c
+++ b/contrib/libs/curl/lib/mprintf.c
@@ -858,7 +858,7 @@ static int dprintf_formatf(
{
void *ptr;
ptr = (void *) p->data.ptr;
- if(ptr != NULL) {
+ if(ptr) {
/* If the pointer is not NULL, write it as a %#x spec. */
base = 16;
digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
diff --git a/contrib/libs/curl/lib/multi.c b/contrib/libs/curl/lib/multi.c
index 9dfa844d7d4..a58b8c543aa 100644
--- a/contrib/libs/curl/lib/multi.c
+++ b/contrib/libs/curl/lib/multi.c
@@ -243,6 +243,26 @@ static void trhash_dtor(void *nada)
(void)nada;
}
+/*
+ * The sockhash has its own separate subhash in each entry that need to be
+ * safely destroyed first.
+ */
+static void sockhash_destroy(struct Curl_hash *h)
+{
+ struct Curl_hash_iterator iter;
+ struct Curl_hash_element *he;
+
+ DEBUGASSERT(h);
+ Curl_hash_start_iterate(h, &iter);
+ he = Curl_hash_next_element(&iter);
+ while(he) {
+ struct Curl_sh_entry *sh = (struct Curl_sh_entry *)he->ptr;
+ Curl_hash_destroy(&sh->transfers);
+ he = Curl_hash_next_element(&iter);
+ }
+ Curl_hash_destroy(h);
+}
+
/* make sure this socket is present in the hash for this handle */
static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh,
@@ -261,11 +281,8 @@ static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh,
if(!check)
return NULL; /* major failure */
- if(Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash,
- trhash_compare, trhash_dtor)) {
- free(check);
- return NULL;
- }
+ Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash, trhash_compare,
+ trhash_dtor);
/* make/add new hash entry */
if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
@@ -332,10 +349,10 @@ static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
* per call."
*
*/
-static int sh_init(struct Curl_hash *hash, int hashsize)
+static void sh_init(struct Curl_hash *hash, int hashsize)
{
- return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
- sh_freeentry);
+ Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
+ sh_freeentry);
}
/*
@@ -362,11 +379,9 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
multi->magic = CURL_MULTI_HANDLE;
- if(Curl_mk_dnscache(&multi->hostcache))
- goto error;
+ Curl_init_dnscache(&multi->hostcache);
- if(sh_init(&multi->sockhash, hashsize))
- goto error;
+ sh_init(&multi->sockhash, hashsize);
if(Curl_conncache_init(&multi->conn_cache, chashsize))
goto error;
@@ -405,7 +420,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
error:
- Curl_hash_destroy(&multi->sockhash);
+ sockhash_destroy(&multi->sockhash);
Curl_hash_destroy(&multi->hostcache);
Curl_conncache_destroy(&multi->conn_cache);
Curl_llist_destroy(&multi->msglist, NULL);
@@ -424,6 +439,7 @@ struct Curl_multi *curl_multi_init(void)
CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
struct Curl_easy *data)
{
+ CURLMcode rc;
/* First, make some basic checks that the CURLM handle is a good handle */
if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE;
@@ -440,6 +456,15 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
if(multi->in_callback)
return CURLM_RECURSIVE_API_CALL;
+ if(multi->dead) {
+ /* a "dead" handle cannot get added transfers while any existing easy
+ handles are still alive - but if there are none alive anymore, it is
+ fine to start over and unmark the "deadness" of this handle */
+ if(multi->num_alive)
+ return CURLM_ABORTED_BY_CALLBACK;
+ multi->dead = FALSE;
+ }
+
/* Initialize timeout list for this handle */
Curl_llist_init(&data->state.timeoutlist, NULL);
@@ -452,6 +477,34 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
if(data->set.errorbuffer)
data->set.errorbuffer[0] = 0;
+ /* make the Curl_easy refer back to this multi handle - before Curl_expire()
+ is called. */
+ data->multi = multi;
+
+ /* Set the timeout for this handle to expire really soon so that it will
+ be taken care of even when this handle is added in the midst of operation
+ when only the curl_multi_socket() API is used. During that flow, only
+ sockets that time-out or have actions will be dealt with. Since this
+ handle has no action yet, we make sure it times out to get things to
+ happen. */
+ Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+ /* A somewhat crude work-around for a little glitch in Curl_update_timer()
+ that 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
+ Curl_update_timer() that prevents calling the application multiple times
+ with 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
+ Curl_update_timer() to always trigger a callback to the app when a new
+ easy handle is added */
+ memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
+
+ rc = Curl_update_timer(multi);
+ if(rc)
+ return rc;
+
/* set the easy handle */
multistate(data, MSTATE_INIT);
@@ -492,35 +545,12 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
multi->easylp = multi->easyp = data; /* both first and last */
}
- /* make the Curl_easy refer back to this multi handle */
- data->multi = multi;
-
- /* Set the timeout for this handle to expire really soon so that it will
- be taken care of even when this handle is added in the midst of operation
- when only the curl_multi_socket() API is used. During that flow, only
- sockets that time-out or have actions will be dealt with. Since this
- handle has no action yet, we make sure it times out to get things to
- happen. */
- Curl_expire(data, 0, EXPIRE_RUN_NOW);
-
/* increase the node-counter */
multi->num_easy++;
/* increase the alive-counter */
multi->num_alive++;
- /* A somewhat crude work-around for a little glitch in Curl_update_timer()
- that 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
- Curl_update_timer() that prevents calling the application multiple times
- with 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
- Curl_update_timer() to always trigger a callback to the app when a new
- easy handle is added */
- memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
-
CONNCACHE_LOCK(data);
/* The closure handle only ever has default timeouts set. To improve the
state somewhat we clone the timeouts from each added handle so that the
@@ -533,14 +563,13 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
data->set.no_signal;
CONNCACHE_UNLOCK(data);
- Curl_update_timer(multi);
return CURLM_OK;
}
#if 0
/* Debug-function, used like this:
*
- * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
+ * Curl_hash_print(&multi->sockhash, debug_print_sock_hash);
*
* Enable the hash print function first by editing hash.c
*/
@@ -548,8 +577,8 @@ static void debug_print_sock_hash(void *p)
{
struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
- fprintf(stderr, " [easy %p/magic %x/socket %d]",
- (void *)sh->data, sh->data->magic, (int)sh->socket);
+ fprintf(stderr, " [readers %u][writers %u]",
+ sh->readers, sh->writers);
}
#endif
@@ -562,7 +591,8 @@ static CURLcode multi_done(struct Curl_easy *data,
struct connectdata *conn = data->conn;
unsigned int i;
- DEBUGF(infof(data, "multi_done"));
+ DEBUGF(infof(data, "multi_done: status: %d prem: %d done: %d",
+ (int)status, (int)premature, data->state.done));
if(data->state.done)
/* Stop if multi_done() has already been called */
@@ -721,6 +751,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
struct Curl_easy *easy = data;
bool premature;
struct Curl_llist_element *e;
+ CURLMcode rc;
/* First, make some basic checks that the CURLM handle is a good handle */
if(!GOOD_MULTI_HANDLE(multi))
@@ -794,8 +825,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
/* change state without using multistate(), only to make singlesocket() do
what we want */
data->mstate = MSTATE_COMPLETED;
- singlesocket(multi, easy); /* to let the application know what sockets that
- vanish with this handle */
+
+ /* This ignores the return code even in case of problems because there's
+ nothing more to do about that, here */
+ (void)singlesocket(multi, easy); /* to let the application know what sockets
+ that vanish with this handle */
/* Remove the association between the connection and the handle */
Curl_detach_connnection(data);
@@ -860,7 +894,9 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
process_pending_handles(multi);
- Curl_update_timer(multi);
+ rc = Curl_update_timer(multi);
+ if(rc)
+ return rc;
return CURLM_OK;
}
@@ -880,6 +916,7 @@ void Curl_detach_connnection(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
if(conn) {
+ Curl_connect_done(data); /* if mid-CONNECT, shut it down */
Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL);
Curl_ssl_detach_conn(data, conn);
}
@@ -1744,6 +1781,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(!GOOD_EASY_HANDLE(data))
return CURLM_BAD_EASY_HANDLE;
+ if(multi->dead) {
+ /* a multi-level callback returned error before, meaning every individual
+ transfer now has failed */
+ result = CURLE_ABORTED_BY_CALLBACK;
+ Curl_posttransfer(data);
+ multi_done(data, result, FALSE);
+ multistate(data, MSTATE_COMPLETED);
+ }
+
do {
/* A "stream" here is a logical stream if the protocol can handle that
(HTTP/2), or the full connection for older protocols */
@@ -1894,7 +1940,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
down. If the name has not yet been resolved, it is likely
that new sockets have been opened in an attempt to contact
another resolver. */
- singlesocket(multi, data);
+ rc = singlesocket(multi, data);
+ if(rc)
+ return rc;
if(dns) {
/* Perform the next step in the connection phase, and then move on
@@ -2619,7 +2667,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
*running_handles = multi->num_alive;
if(CURLM_OK >= returncode)
- Curl_update_timer(multi);
+ returncode = Curl_update_timer(multi);
return returncode;
}
@@ -2664,7 +2712,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
/* Close all the connections in the connection cache */
Curl_conncache_close_all_connections(&multi->conn_cache);
- Curl_hash_destroy(&multi->sockhash);
+ sockhash_destroy(&multi->sockhash);
Curl_conncache_destroy(&multi->conn_cache);
Curl_llist_destroy(&multi->msglist, NULL);
Curl_llist_destroy(&multi->pending, NULL);
@@ -2739,6 +2787,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
int num;
unsigned int curraction;
unsigned char actions[MAX_SOCKSPEREASYHANDLE];
+ int rc;
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
socks[i] = CURL_SOCKET_BAD;
@@ -2810,8 +2859,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
/* add 'data' to the transfer hash on this socket! */
if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */
- sizeof(struct Curl_easy *), data))
+ sizeof(struct Curl_easy *), data)) {
+ Curl_hash_destroy(&entry->transfers);
return CURLM_OUT_OF_MEMORY;
+ }
}
comboaction = (entry->writers? CURL_POLL_OUT : 0) |
@@ -2822,9 +2873,14 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
/* same, continue */
continue;
- if(multi->socket_cb)
- multi->socket_cb(data, s, comboaction, multi->socket_userp,
- entry->socketp);
+ if(multi->socket_cb) {
+ rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
+ entry->socketp);
+ if(rc == -1) {
+ multi->dead = TRUE;
+ return CURLM_ABORTED_BY_CALLBACK;
+ }
+ }
entry->action = comboaction; /* store the current action state */
}
@@ -2859,10 +2915,14 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
if(oldactions & CURL_POLL_IN)
entry->readers--;
if(!entry->users) {
- if(multi->socket_cb)
- multi->socket_cb(data, s, CURL_POLL_REMOVE,
- multi->socket_userp,
- entry->socketp);
+ if(multi->socket_cb) {
+ rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
+ multi->socket_userp, entry->socketp);
+ if(rc == -1) {
+ multi->dead = TRUE;
+ return CURLM_ABORTED_BY_CALLBACK;
+ }
+ }
sh_delentry(entry, &multi->sockhash, s);
}
else {
@@ -2881,9 +2941,11 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
return CURLM_OK;
}
-void Curl_updatesocket(struct Curl_easy *data)
+CURLcode Curl_updatesocket(struct Curl_easy *data)
{
- singlesocket(data->multi, data);
+ if(singlesocket(data->multi, data))
+ return CURLE_ABORTED_BY_CALLBACK;
+ return CURLE_OK;
}
@@ -2908,13 +2970,18 @@ void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s)
struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
if(entry) {
+ int rc = 0;
if(multi->socket_cb)
- multi->socket_cb(data, s, CURL_POLL_REMOVE,
- multi->socket_userp,
- entry->socketp);
+ rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
+ multi->socket_userp, entry->socketp);
/* now remove it from the socket hash */
sh_delentry(entry, &multi->sockhash, s);
+ if(rc == -1)
+ /* This just marks the multi handle as "dead" without returning an
+ error code primarily because this function is used from many
+ places where propagating an error back is tricky. */
+ multi->dead = TRUE;
}
}
}
@@ -3174,7 +3241,7 @@ CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
return CURLM_RECURSIVE_API_CALL;
result = multi_socket(multi, FALSE, s, 0, running_handles);
if(CURLM_OK >= result)
- Curl_update_timer(multi);
+ result = Curl_update_timer(multi);
return result;
}
@@ -3186,7 +3253,7 @@ CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
return CURLM_RECURSIVE_API_CALL;
result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
if(CURLM_OK >= result)
- Curl_update_timer(multi);
+ result = Curl_update_timer(multi);
return result;
}
@@ -3197,7 +3264,7 @@ CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
return CURLM_RECURSIVE_API_CALL;
result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
if(CURLM_OK >= result)
- Curl_update_timer(multi);
+ result = Curl_update_timer(multi);
return result;
}
@@ -3206,6 +3273,11 @@ static CURLMcode multi_timeout(struct Curl_multi *multi,
{
static const struct curltime tv_zero = {0, 0};
+ if(multi->dead) {
+ *timeout_ms = 0;
+ return CURLM_OK;
+ }
+
if(multi->timetree) {
/* we have a tree of expire times */
struct curltime now = Curl_now();
@@ -3257,14 +3329,15 @@ CURLMcode curl_multi_timeout(struct Curl_multi *multi,
* Tell the application it should update its timers, if it subscribes to the
* update timer callback.
*/
-void Curl_update_timer(struct Curl_multi *multi)
+CURLMcode Curl_update_timer(struct Curl_multi *multi)
{
long timeout_ms;
+ int rc;
- if(!multi->timer_cb)
- return;
+ if(!multi->timer_cb || multi->dead)
+ return CURLM_OK;
if(multi_timeout(multi, &timeout_ms)) {
- return;
+ return CURLM_OK;
}
if(timeout_ms < 0) {
static const struct curltime none = {0, 0};
@@ -3272,10 +3345,14 @@ void Curl_update_timer(struct Curl_multi *multi)
multi->timer_lastcall = none;
/* there's no timeout now but there was one previously, tell the app to
disable it */
- multi->timer_cb(multi, -1, multi->timer_userp);
- return;
+ rc = multi->timer_cb(multi, -1, multi->timer_userp);
+ if(rc == -1) {
+ multi->dead = TRUE;
+ return CURLM_ABORTED_BY_CALLBACK;
+ }
+ return CURLM_OK;
}
- return;
+ return CURLM_OK;
}
/* When multi_timeout() is done, multi->timetree points to the node with the
@@ -3283,11 +3360,16 @@ void Curl_update_timer(struct Curl_multi *multi)
* if this is the same (fixed) time as we got in a previous call and then
* avoid calling the callback again. */
if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
- return;
+ return CURLM_OK;
multi->timer_lastcall = multi->timetree->key;
- multi->timer_cb(multi, timeout_ms, multi->timer_userp);
+ rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp);
+ if(rc == -1) {
+ multi->dead = TRUE;
+ return CURLM_ABORTED_BY_CALLBACK;
+ }
+ return CURLM_OK;
}
/*
diff --git a/contrib/libs/curl/lib/multihandle.h b/contrib/libs/curl/lib/multihandle.h
index 2e4a6ffba5b..db7f130efd6 100644
--- a/contrib/libs/curl/lib/multihandle.h
+++ b/contrib/libs/curl/lib/multihandle.h
@@ -156,6 +156,8 @@ struct Curl_multi {
#ifdef USE_OPENSSL
bool ssl_seeded;
#endif
+ bool dead; /* a callback returned error, everything needs to crash and
+ burn */
};
#endif /* HEADER_CURL_MULTIHANDLE_H */
diff --git a/contrib/libs/curl/lib/multiif.h b/contrib/libs/curl/lib/multiif.h
index 2fbef53c48e..f4d0ada8e8f 100644
--- a/contrib/libs/curl/lib/multiif.h
+++ b/contrib/libs/curl/lib/multiif.h
@@ -26,11 +26,11 @@
* Prototypes for library-wide functions provided by multi.c
*/
-void Curl_updatesocket(struct Curl_easy *data);
+CURLcode Curl_updatesocket(struct Curl_easy *data);
void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id);
void Curl_expire_clear(struct Curl_easy *data);
void Curl_expire_done(struct Curl_easy *data, expire_id id);
-void Curl_update_timer(struct Curl_multi *multi);
+CURLMcode Curl_update_timer(struct Curl_multi *multi) WARN_UNUSED_RESULT;
void Curl_attach_connnection(struct Curl_easy *data,
struct connectdata *conn);
void Curl_detach_connnection(struct Curl_easy *data);
diff --git a/contrib/libs/curl/lib/openldap.c b/contrib/libs/curl/lib/openldap.c
index 06c5aa0202c..f2c1cee0708 100644
--- a/contrib/libs/curl/lib/openldap.c
+++ b/contrib/libs/curl/lib/openldap.c
@@ -70,6 +70,17 @@
*/
/* #define CURL_OPENLDAP_DEBUG */
+/* Machine states. */
+typedef enum {
+ OLDAP_STOP, /* Do nothing state, stops the state machine */
+ OLDAP_SSL, /* Performing SSL handshake. */
+ OLDAP_STARTTLS, /* STARTTLS request sent. */
+ OLDAP_TLS, /* Performing TLS handshake. */
+ OLDAP_BIND, /* Simple bind reply. */
+ OLDAP_BINDV2, /* Simple bind reply in protocol version 2. */
+ OLDAP_LAST /* Never used */
+} ldapstate;
+
#ifndef _LDAP_PVT_H
extern int ldap_pvt_url_scheme2proto(const char *);
extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
@@ -143,29 +154,13 @@ const struct Curl_handler Curl_handler_ldaps = {
};
#endif
-static const char *url_errs[] = {
- "success",
- "out of memory",
- "bad parameter",
- "unrecognized scheme",
- "unbalanced delimiter",
- "bad URL",
- "bad host or port",
- "bad or missing attributes",
- "bad or missing scope",
- "bad or missing filter",
- "bad or missing extensions"
-};
-
struct ldapconninfo {
- LDAP *ld;
- Curl_recv *recv; /* for stacking SSL handler */
+ LDAP *ld; /* Openldap connection handle. */
+ Curl_recv *recv; /* For stacking SSL handler */
Curl_send *send;
- int proto;
- int msgid;
- bool ssldone;
- bool sslinst;
- bool didbind;
+ ldapstate state; /* Current machine state. */
+ int proto; /* LDAP_PROTO_TCP/LDAP_PROTO_UDP/LDAP_PROTO_IPC */
+ int msgid; /* Current message id. */
};
struct ldapreqinfo {
@@ -173,194 +168,379 @@ struct ldapreqinfo {
int nument;
};
-static CURLcode oldap_setup_connection(struct Curl_easy *data,
- struct connectdata *conn)
+/*
+ * state()
+ *
+ * This is the ONLY way to change LDAP state!
+ */
+static void state(struct Curl_easy *data, ldapstate newstate)
{
- struct ldapconninfo *li;
- LDAPURLDesc *lud;
- int rc, proto;
- CURLcode status;
+ struct ldapconninfo *ldapc = data->conn->proto.ldapc;
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* for debug purposes */
+ static const char * const names[] = {
+ "STOP",
+ "SSL",
+ "STARTTLS",
+ "TLS",
+ "BIND",
+ "BINDV2",
+ /* LAST */
+ };
+
+ if(ldapc->state != newstate)
+ infof(data, "LDAP %p state change from %s to %s",
+ (void *)ldapc, names[ldapc->state], names[newstate]);
+#endif
+
+ ldapc->state = newstate;
+}
- rc = ldap_url_parse(data->state.url, &lud);
+/* Map some particular LDAP error codes to CURLcode values. */
+static CURLcode oldap_map_error(int rc, CURLcode result)
+{
+ switch(rc) {
+ case LDAP_NO_MEMORY:
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ case LDAP_INVALID_CREDENTIALS:
+ result = CURLE_LOGIN_DENIED;
+ break;
+ case LDAP_PROTOCOL_ERROR:
+ result = CURLE_UNSUPPORTED_PROTOCOL;
+ break;
+ case LDAP_INSUFFICIENT_ACCESS:
+ result = CURLE_REMOTE_ACCESS_DENIED;
+ break;
+ }
+ return result;
+}
+
+static CURLcode oldap_url_parse(struct Curl_easy *data, LDAPURLDesc **ludp)
+{
+ CURLcode result = CURLE_OK;
+ int rc = LDAP_URL_ERR_BADURL;
+ static const char * const url_errs[] = {
+ "success",
+ "out of memory",
+ "bad parameter",
+ "unrecognized scheme",
+ "unbalanced delimiter",
+ "bad URL",
+ "bad host or port",
+ "bad or missing attributes",
+ "bad or missing scope",
+ "bad or missing filter",
+ "bad or missing extensions"
+ };
+
+ *ludp = NULL;
+ if(!data->state.up.user && !data->state.up.password &&
+ !data->state.up.options)
+ rc = ldap_url_parse(data->state.url, ludp);
if(rc != LDAP_URL_SUCCESS) {
const char *msg = "url parsing problem";
- status = CURLE_URL_MALFORMAT;
- if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
- if(rc == LDAP_URL_ERR_MEM)
- status = CURLE_OUT_OF_MEMORY;
+
+ result = rc == LDAP_URL_ERR_MEM? CURLE_OUT_OF_MEMORY: CURLE_URL_MALFORMAT;
+ rc -= LDAP_URL_SUCCESS;
+ if((size_t) rc < sizeof(url_errs) / sizeof(url_errs[0]))
msg = url_errs[rc];
- }
failf(data, "LDAP local: %s", msg);
- return status;
}
- proto = ldap_pvt_url_scheme2proto(lud->lud_scheme);
+ return result;
+}
+
+static CURLcode oldap_setup_connection(struct Curl_easy *data,
+ struct connectdata *conn)
+{
+ CURLcode result;
+ LDAPURLDesc *lud;
+ struct ldapconninfo *li;
+
+ /* Early URL syntax check. */
+ result = oldap_url_parse(data, &lud);
ldap_free_urldesc(lud);
- li = calloc(1, sizeof(struct ldapconninfo));
- if(!li)
- return CURLE_OUT_OF_MEMORY;
- li->proto = proto;
- conn->proto.ldapc = li;
- connkeep(conn, "OpenLDAP default");
- return CURLE_OK;
+ if(!result) {
+ li = calloc(1, sizeof(struct ldapconninfo));
+ if(!li)
+ result = CURLE_OUT_OF_MEMORY;
+ else {
+ li->proto = ldap_pvt_url_scheme2proto(data->state.up.scheme);
+ conn->proto.ldapc = li;
+ connkeep(conn, "OpenLDAP default");
+
+ /* Clear the TLS upgraded flag */
+ conn->bits.tls_upgraded = FALSE;
+ }
+ }
+
+ return result;
+}
+
+/* Starts LDAP simple bind. */
+static CURLcode oldap_perform_bind(struct Curl_easy *data, ldapstate newstate)
+{
+ CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
+ struct ldapconninfo *li = conn->proto.ldapc;
+ char *binddn = NULL;
+ struct berval passwd;
+ int rc;
+
+ passwd.bv_val = NULL;
+ passwd.bv_len = 0;
+
+ if(conn->bits.user_passwd) {
+ binddn = conn->user;
+ passwd.bv_val = conn->passwd;
+ passwd.bv_len = strlen(passwd.bv_val);
+ }
+
+ rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
+ NULL, NULL, &li->msgid);
+ if(rc == LDAP_SUCCESS)
+ state(data, newstate);
+ else
+ result = oldap_map_error(rc,
+ conn->bits.user_passwd?
+ CURLE_LOGIN_DENIED: CURLE_LDAP_CANNOT_BIND);
+ return result;
}
#ifdef USE_SSL
static Sockbuf_IO ldapsb_tls;
-#endif
-static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
+static bool ssl_installed(struct connectdata *conn)
+{
+ return conn->proto.ldapc->recv != NULL;
+}
+
+static CURLcode oldap_ssl_connect(struct Curl_easy *data, ldapstate newstate)
{
+ CURLcode result = CURLE_OK;
struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
- int rc, proto = LDAP_VERSION3;
- char hosturl[1024];
- char *ptr;
+ bool ssldone = 0;
- (void)done;
+ result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
+ FIRSTSOCKET, &ssldone);
+ if(!result) {
+ state(data, newstate);
- strcpy(hosturl, "ldap");
- ptr = hosturl + 4;
- if(conn->handler->flags & PROTOPT_SSL)
- *ptr++ = 's';
- msnprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
- conn->host.name, conn->remote_port);
+ if(ssldone) {
+ Sockbuf *sb;
-#ifdef CURL_OPENLDAP_DEBUG
- static int do_trace = 0;
- const char *env = getenv("CURL_OPENLDAP_TRACE");
- do_trace = (env && strtol(env, NULL, 10) > 0);
- if(do_trace) {
- ldap_set_option(li->ld, LDAP_OPT_DEBUG_LEVEL, &do_trace);
+ /* Install the libcurl SSL handlers into the sockbuf. */
+ ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
+ ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data);
+ li->recv = conn->recv[FIRSTSOCKET];
+ li->send = conn->send[FIRSTSOCKET];
+ }
}
+
+ return result;
+}
+
+/* Send the STARTTLS request */
+static CURLcode oldap_perform_starttls(struct Curl_easy *data)
+{
+ CURLcode result = CURLE_OK;
+ struct ldapconninfo *li = data->conn->proto.ldapc;
+ int rc = ldap_start_tls(li->ld, NULL, NULL, &li->msgid);
+
+ if(rc == LDAP_SUCCESS)
+ state(data, OLDAP_STARTTLS);
+ else
+ result = oldap_map_error(rc, CURLE_USE_SSL_FAILED);
+ return result;
+}
#endif
+static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
+{
+ struct connectdata *conn = data->conn;
+ struct ldapconninfo *li = conn->proto.ldapc;
+ static const int version = LDAP_VERSION3;
+ int rc;
+ char *hosturl;
+#ifdef CURL_OPENLDAP_DEBUG
+ static int do_trace = -1;
+#endif
+
+ (void)done;
+
+ hosturl = aprintf("ldap%s://%s:%d",
+ conn->handler->flags & PROTOPT_SSL? "s": "",
+ conn->host.name, conn->remote_port);
+ if(!hosturl)
+ return CURLE_OUT_OF_MEMORY;
+
rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
if(rc) {
failf(data, "LDAP local: Cannot connect to %s, %s",
hosturl, ldap_err2string(rc));
+ free(hosturl);
return CURLE_COULDNT_CONNECT;
}
- ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+ free(hosturl);
+
+#ifdef CURL_OPENLDAP_DEBUG
+ if(do_trace < 0) {
+ const char *env = getenv("CURL_OPENLDAP_TRACE");
+ do_trace = (env && strtol(env, NULL, 10) > 0);
+ }
+ if(do_trace)
+ ldap_set_option(li->ld, LDAP_OPT_DEBUG_LEVEL, &do_trace);
+#endif
+
+ /* Try version 3 first. */
+ ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+
+ /* Do not chase referrals. */
+ ldap_set_option(li->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
#ifdef USE_SSL
- if(conn->handler->flags & PROTOPT_SSL) {
- CURLcode result;
- result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
- FIRSTSOCKET, &li->ssldone);
- if(result)
+ if(conn->handler->flags & PROTOPT_SSL)
+ return oldap_ssl_connect(data, OLDAP_SSL);
+
+ if(data->set.use_ssl) {
+ CURLcode result = oldap_perform_starttls(data);
+
+ if(!result || data->set.use_ssl != CURLUSESSL_TRY)
return result;
}
#endif
- return CURLE_OK;
+ /* Force bind even if anonymous bind is not needed in protocol version 3
+ to detect missing version 3 support. */
+ return oldap_perform_bind(data, OLDAP_BIND);
}
-static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
+/* Handle a simple bind response. */
+static CURLcode oldap_state_bind_resp(struct Curl_easy *data, LDAPMessage *msg,
+ int code)
{
struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
- LDAPMessage *msg = NULL;
- struct timeval tv = {0, 1}, *tvp;
- int rc, err;
- char *info = NULL;
+ CURLcode result = CURLE_OK;
+ struct berval *bv = NULL;
+ int rc;
-#ifdef USE_SSL
- if(conn->handler->flags & PROTOPT_SSL) {
- /* Is the SSL handshake complete yet? */
- if(!li->ssldone) {
- CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
- FIRSTSOCKET,
- &li->ssldone);
- if(result || !li->ssldone)
- return result;
- }
+ if(code != LDAP_SUCCESS)
+ return oldap_map_error(code, CURLE_LDAP_CANNOT_BIND);
- /* Have we installed the libcurl SSL handlers into the sockbuf yet? */
- if(!li->sslinst) {
- Sockbuf *sb;
- ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
- ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data);
- li->sslinst = TRUE;
- li->recv = conn->recv[FIRSTSOCKET];
- li->send = conn->send[FIRSTSOCKET];
- }
+ rc = ldap_parse_sasl_bind_result(li->ld, msg, &bv, 0);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: bind ldap_parse_sasl_bind_result %s",
+ ldap_err2string(rc));
+ result = oldap_map_error(rc, CURLE_LDAP_CANNOT_BIND);
}
-#endif
+ else
+ state(data, OLDAP_STOP);
- tvp = &tv;
-
- retry:
- if(!li->didbind) {
- char *binddn;
- struct berval passwd;
+ if(bv)
+ ber_bvfree(bv);
+ return result;
+}
- if(conn->bits.user_passwd) {
- binddn = conn->user;
- passwd.bv_val = conn->passwd;
- passwd.bv_len = strlen(passwd.bv_val);
+static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ struct connectdata *conn = data->conn;
+ struct ldapconninfo *li = conn->proto.ldapc;
+ LDAPMessage *msg = NULL;
+ struct timeval tv = {0, 0};
+ int code = LDAP_SUCCESS;
+ int rc;
+
+ if(li->state != OLDAP_SSL && li->state != OLDAP_TLS) {
+ /* Get response to last command. */
+ rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, &tv, &msg);
+ if(!rc)
+ return CURLE_OK; /* Timed out. */
+ if(rc < 0) {
+ failf(data, "LDAP local: connecting ldap_result %s",
+ ldap_err2string(rc));
+ return oldap_map_error(rc, CURLE_COULDNT_CONNECT);
}
+
+ /* Get error code from message. */
+ rc = ldap_parse_result(li->ld, msg, &code, NULL, NULL, NULL, NULL, 0);
+ if(rc)
+ code = rc;
else {
- binddn = NULL;
- passwd.bv_val = NULL;
- passwd.bv_len = 0;
+ /* store the latest code for later retrieval */
+ data->info.httpcode = code;
}
- rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
- NULL, NULL, &li->msgid);
- if(rc)
- return CURLE_LDAP_CANNOT_BIND;
- li->didbind = TRUE;
- if(tvp)
- return CURLE_OK;
- }
- rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg);
- if(rc < 0) {
- failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
- return CURLE_LDAP_CANNOT_BIND;
- }
- if(rc == 0) {
- /* timed out */
- return CURLE_OK;
- }
+ /* If protocol version 3 is not supported, fallback to version 2. */
+ if(code == LDAP_PROTOCOL_ERROR && li->state != OLDAP_BINDV2
+#ifdef USE_SSL
+ && (ssl_installed(conn) || data->set.use_ssl <= CURLUSESSL_TRY)
+#endif
+ ) {
+ static const int version = LDAP_VERSION2;
- rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1);
- if(rc) {
- failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
- return CURLE_LDAP_CANNOT_BIND;
+ ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+ ldap_msgfree(msg);
+ return oldap_perform_bind(data, OLDAP_BINDV2);
+ }
}
- /* Try to fallback to LDAPv2? */
- if(err == LDAP_PROTOCOL_ERROR) {
- int proto;
- ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
- if(proto == LDAP_VERSION3) {
- if(info) {
- ldap_memfree(info);
- info = NULL;
+ /* Handle response message according to current state. */
+ switch(li->state) {
+
+#ifdef USE_SSL
+ case OLDAP_SSL:
+ result = oldap_ssl_connect(data, OLDAP_SSL);
+ if(!result && ssl_installed(conn))
+ result = oldap_perform_bind(data, OLDAP_BIND);
+ break;
+ case OLDAP_STARTTLS:
+ if(code != LDAP_SUCCESS) {
+ if(data->set.use_ssl != CURLUSESSL_TRY)
+ result = oldap_map_error(code, CURLE_USE_SSL_FAILED);
+ else
+ result = oldap_perform_bind(data, OLDAP_BIND);
+ break;
+ }
+ /* FALLTHROUGH */
+ case OLDAP_TLS:
+ result = oldap_ssl_connect(data, OLDAP_TLS);
+ if(result && data->set.use_ssl != CURLUSESSL_TRY)
+ result = oldap_map_error(code, CURLE_USE_SSL_FAILED);
+ else if(ssl_installed(conn)) {
+ conn->bits.tls_upgraded = TRUE;
+ if(conn->bits.user_passwd)
+ result = oldap_perform_bind(data, OLDAP_BIND);
+ else {
+ state(data, OLDAP_STOP); /* Version 3 supported: no bind required */
+ result = CURLE_OK;
}
- proto = LDAP_VERSION2;
- ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
- li->didbind = FALSE;
- goto retry;
}
- }
+ break;
+#endif
- if(err) {
- failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
- info ? info : "");
- if(info)
- ldap_memfree(info);
- return CURLE_LOGIN_DENIED;
+ case OLDAP_BIND:
+ case OLDAP_BINDV2:
+ result = oldap_state_bind_resp(data, msg, code);
+ break;
+ default:
+ /* internal error */
+ result = CURLE_COULDNT_CONNECT;
+ break;
}
- if(info)
- ldap_memfree(info);
- conn->recv[FIRSTSOCKET] = oldap_recv;
- *done = TRUE;
+ ldap_msgfree(msg);
- return CURLE_OK;
+ *done = li->state == OLDAP_STOP;
+ if(*done)
+ conn->recv[FIRSTSOCKET] = oldap_recv;
+
+ return result;
}
static CURLcode oldap_disconnect(struct Curl_easy *data,
@@ -373,7 +553,7 @@ static CURLcode oldap_disconnect(struct Curl_easy *data,
if(li) {
if(li->ld) {
#ifdef USE_SSL
- if(conn->ssl[FIRSTSOCKET].use) {
+ if(ssl_installed(conn)) {
Sockbuf *sb;
ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data);
@@ -393,44 +573,40 @@ static CURLcode oldap_do(struct Curl_easy *data, bool *done)
struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
struct ldapreqinfo *lr;
- CURLcode status = CURLE_OK;
- int rc = 0;
- LDAPURLDesc *ludp = NULL;
+ CURLcode result;
+ int rc;
+ LDAPURLDesc *lud;
int msgid;
connkeep(conn, "OpenLDAP do");
infof(data, "LDAP local: %s", data->state.url);
- rc = ldap_url_parse(data->state.url, &ludp);
- if(rc != LDAP_URL_SUCCESS) {
- const char *msg = "url parsing problem";
- status = CURLE_URL_MALFORMAT;
- if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
- if(rc == LDAP_URL_ERR_MEM)
- status = CURLE_OUT_OF_MEMORY;
- msg = url_errs[rc];
+ result = oldap_url_parse(data, &lud);
+ if(!result) {
+ rc = ldap_search_ext(li->ld, lud->lud_dn, lud->lud_scope,
+ lud->lud_filter, lud->lud_attrs, 0,
+ NULL, NULL, NULL, 0, &msgid);
+ ldap_free_urldesc(lud);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
+ result = CURLE_LDAP_SEARCH_FAILED;
+ }
+ else {
+ lr = calloc(1, sizeof(struct ldapreqinfo));
+ if(!lr) {
+ ldap_abandon_ext(li->ld, msgid, NULL, NULL);
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ else {
+ lr->msgid = msgid;
+ data->req.p.ldap = lr;
+ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
+ *done = TRUE;
+ }
}
- failf(data, "LDAP local: %s", msg);
- return status;
- }
-
- rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope,
- ludp->lud_filter, ludp->lud_attrs, 0,
- NULL, NULL, NULL, 0, &msgid);
- ldap_free_urldesc(ludp);
- if(rc != LDAP_SUCCESS) {
- failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
- return CURLE_LDAP_SEARCH_FAILED;
}
- lr = calloc(1, sizeof(struct ldapreqinfo));
- if(!lr)
- return CURLE_OUT_OF_MEMORY;
- lr->msgid = msgid;
- data->req.p.ldap = lr;
- Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
- *done = TRUE;
- return CURLE_OK;
+ return result;
}
static CURLcode oldap_done(struct Curl_easy *data, CURLcode res,
@@ -456,163 +632,146 @@ static CURLcode oldap_done(struct Curl_easy *data, CURLcode res,
return CURLE_OK;
}
+static CURLcode client_write(struct Curl_easy *data, const char *prefix,
+ const char *value, size_t len, const char *suffix)
+{
+ CURLcode result = CURLE_OK;
+ size_t l;
+
+ if(prefix) {
+ l = strlen(prefix);
+ /* If we have a zero-length value and the prefix ends with a space
+ separator, drop the latter. */
+ if(!len && l && prefix[l - 1] == ' ')
+ l--;
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) prefix, l);
+ if(!result)
+ data->req.bytecount += l;
+ }
+ if(!result && value) {
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) value, len);
+ if(!result)
+ data->req.bytecount += len;
+ }
+ if(!result && suffix) {
+ l = strlen(suffix);
+ result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) suffix, l);
+ if(!result)
+ data->req.bytecount += l;
+ }
+ return result;
+}
+
static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
size_t len, CURLcode *err)
{
struct connectdata *conn = data->conn;
struct ldapconninfo *li = conn->proto.ldapc;
struct ldapreqinfo *lr = data->req.p.ldap;
- int rc, ret;
+ int rc;
LDAPMessage *msg = NULL;
- LDAPMessage *ent;
BerElement *ber = NULL;
- struct timeval tv = {0, 1};
+ struct timeval tv = {0, 0};
+ struct berval bv, *bvals;
+ int binary = 0;
+ CURLcode result = CURLE_AGAIN;
+ int code;
+ char *info = NULL;
(void)len;
(void)buf;
(void)sockindex;
- rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
+ rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_ONE, &tv, &msg);
if(rc < 0) {
failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
- *err = CURLE_RECV_ERROR;
- return -1;
+ result = CURLE_RECV_ERROR;
}
- *err = CURLE_AGAIN;
- ret = -1;
+ *err = result;
- /* timed out */
+ /* error or timed out */
if(!msg)
- return ret;
-
- for(ent = ldap_first_message(li->ld, msg); ent;
- ent = ldap_next_message(li->ld, ent)) {
- struct berval bv, *bvals;
- int binary = 0, msgtype;
- CURLcode writeerr;
-
- msgtype = ldap_msgtype(ent);
- if(msgtype == LDAP_RES_SEARCH_RESULT) {
- int code;
- char *info = NULL;
- rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
- if(rc) {
- failf(data, "LDAP local: search ldap_parse_result %s",
- ldap_err2string(rc));
- *err = CURLE_LDAP_SEARCH_FAILED;
- }
- else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
- failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
- info ? info : "");
- *err = CURLE_LDAP_SEARCH_FAILED;
- }
- else {
- /* successful */
- if(code == LDAP_SIZELIMIT_EXCEEDED)
- infof(data, "There are more than %d entries", lr->nument);
- data->req.size = data->req.bytecount;
- *err = CURLE_OK;
- ret = 0;
- }
- lr->msgid = 0;
- ldap_memfree(info);
+ return -1;
+
+ result = CURLE_OK;
+
+ switch(ldap_msgtype(msg)) {
+ case LDAP_RES_SEARCH_RESULT:
+ lr->msgid = 0;
+ rc = ldap_parse_result(li->ld, msg, &code, NULL, &info, NULL, NULL, 0);
+ if(rc) {
+ failf(data, "LDAP local: search ldap_parse_result %s",
+ ldap_err2string(rc));
+ result = CURLE_LDAP_SEARCH_FAILED;
break;
}
- else if(msgtype != LDAP_RES_SEARCH_ENTRY)
- continue;
+ /* store the latest code for later retrieval */
+ data->info.httpcode = code;
+
+ switch(code) {
+ case LDAP_SIZELIMIT_EXCEEDED:
+ infof(data, "There are more than %d entries", lr->nument);
+ /* FALLTHROUGH */
+ case LDAP_SUCCESS:
+ data->req.size = data->req.bytecount;
+ break;
+ default:
+ failf(data, "LDAP remote: search failed %s %s", ldap_err2string(code),
+ info ? info : "");
+ result = CURLE_LDAP_SEARCH_FAILED;
+ break;
+ }
+ if(info)
+ ldap_memfree(info);
+ break;
+ case LDAP_RES_SEARCH_ENTRY:
lr->nument++;
- rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
+ rc = ldap_get_dn_ber(li->ld, msg, &ber, &bv);
if(rc < 0) {
- *err = CURLE_RECV_ERROR;
- return -1;
- }
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
-
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
- bv.bv_len);
- if(writeerr) {
- *err = writeerr;
- return -1;
+ result = CURLE_RECV_ERROR;
+ break;
}
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
- data->req.bytecount += bv.bv_len + 5;
+ result = client_write(data, "DN: ", bv.bv_val, bv.bv_len, "\n");
+ if(result)
+ break;
- for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals);
+ for(rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals);
rc == LDAP_SUCCESS;
- rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals)) {
+ rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals)) {
int i;
if(!bv.bv_val)
break;
- if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
- binary = 1;
- else
- binary = 0;
-
if(!bvals) {
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
- bv.bv_len);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)":\n", 2);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
- data->req.bytecount += bv.bv_len + 3;
+ result = client_write(data, "\t", bv.bv_val, bv.bv_len, ":\n");
+ if(result)
+ break;
continue;
}
+ binary = bv.bv_len > 7 &&
+ !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7);
+
for(i = 0; bvals[i].bv_val != NULL; i++) {
int binval = 0;
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
- bv.bv_len);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
-
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)":", 1);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
- data->req.bytecount += bv.bv_len + 2;
+ result = client_write(data, "\t", bv.bv_val, bv.bv_len, ":");
+ if(result)
+ break;
if(!binary) {
/* check for leading or trailing whitespace */
if(ISSPACE(bvals[i].bv_val[0]) ||
- ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
+ ISSPACE(bvals[i].bv_val[bvals[i].bv_len - 1]))
binval = 1;
else {
/* check for unprintable characters */
unsigned int j;
- for(j = 0; j<bvals[i].bv_len; j++)
+ for(j = 0; j < bvals[i].bv_len; j++)
if(!ISPRINT(bvals[i].bv_val[j])) {
binval = 1;
break;
@@ -622,80 +781,42 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
if(binary || binval) {
char *val_b64 = NULL;
size_t val_b64_sz = 0;
- /* Binary value, encode to base64. */
- CURLcode error = Curl_base64_encode(data,
- bvals[i].bv_val,
- bvals[i].bv_len,
- &val_b64,
- &val_b64_sz);
- if(error) {
- ber_memfree(bvals);
- ber_free(ber, 0);
- ldap_msgfree(msg);
- *err = error;
- return -1;
- }
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY,
- (char *)": ", 2);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
-
- data->req.bytecount += 2;
- if(val_b64_sz > 0) {
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, val_b64,
- val_b64_sz);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
- free(val_b64);
- data->req.bytecount += val_b64_sz;
- }
- }
- else {
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)" ", 1);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, bvals[i].bv_val,
- bvals[i].bv_len);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
-
- data->req.bytecount += bvals[i].bv_len + 1;
- }
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
- if(writeerr) {
- *err = writeerr;
- return -1;
+ /* Binary value, encode to base64. */
+ if(bvals[i].bv_len)
+ result = Curl_base64_encode(data, bvals[i].bv_val, bvals[i].bv_len,
+ &val_b64, &val_b64_sz);
+ if(!result)
+ result = client_write(data, ": ", val_b64, val_b64_sz, "\n");
+ free(val_b64);
}
-
- data->req.bytecount++;
+ else
+ result = client_write(data, " ",
+ bvals[i].bv_val, bvals[i].bv_len, "\n");
+ if(result)
+ break;
}
+
ber_memfree(bvals);
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
- if(writeerr) {
- *err = writeerr;
- return -1;
- }
- data->req.bytecount++;
- }
- writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
- if(writeerr) {
- *err = writeerr;
- return -1;
+ bvals = NULL;
+ if(!result)
+ result = client_write(data, "\n", NULL, 0, NULL);
+ if(result)
+ break;
}
- data->req.bytecount++;
+
ber_free(ber, 0);
+
+ if(!result)
+ result = client_write(data, "\n", NULL, 0, NULL);
+ if(!result)
+ result = CURLE_AGAIN;
+ break;
}
+
ldap_msgfree(msg);
- return ret;
+ *err = result;
+ return result? -1: 0;
}
#ifdef USE_SSL
diff --git a/contrib/libs/curl/lib/setopt.c b/contrib/libs/curl/lib/setopt.c
index 56d9c49926c..599ed5d994e 100644
--- a/contrib/libs/curl/lib/setopt.c
+++ b/contrib/libs/curl/lib/setopt.c
@@ -1870,6 +1870,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.ssl.primary.verifypeer;
}
break;
+#ifndef CURL_DISABLE_DOH
case CURLOPT_DOH_SSL_VERIFYPEER:
/*
* Enable peer SSL verifying for DoH.
@@ -1877,6 +1878,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.doh_verifypeer = (0 != va_arg(param, long)) ?
TRUE : FALSE;
break;
+#endif
#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSL_VERIFYPEER:
/*
@@ -1909,6 +1911,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.ssl.primary.verifyhost;
}
break;
+#ifndef CURL_DISABLE_DOH
case CURLOPT_DOH_SSL_VERIFYHOST:
/*
* Enable verification of the host name in the peer certificate for DoH
@@ -1918,6 +1921,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
/* Treat both 1 and 2 as TRUE */
data->set.doh_verifyhost = (bool)((arg & 3) ? TRUE : FALSE);
break;
+#endif
#ifndef CURL_DISABLE_PROXY
case CURLOPT_PROXY_SSL_VERIFYHOST:
/*
@@ -1953,6 +1957,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.ssl.primary.verifystatus;
}
break;
+#ifndef CURL_DISABLE_DOH
case CURLOPT_DOH_SSL_VERIFYSTATUS:
/*
* Enable certificate status verifying for DoH.
@@ -1965,6 +1970,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.doh_verifystatus = (0 != va_arg(param, long)) ?
TRUE : FALSE;
break;
+#endif
case CURLOPT_SSL_CTX_FUNCTION:
/*
* Set a SSL_CTX callback
@@ -2609,6 +2615,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
#endif
+#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
+ !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
+ case CURLOPT_MIME_OPTIONS:
+ data->set.mime_options = va_arg(param, long);
+ break;
+#endif
+
case CURLOPT_SASL_AUTHZID:
/* Authorisation identity (identity to act as) */
result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID],
diff --git a/contrib/libs/curl/lib/sha256.c b/contrib/libs/curl/lib/sha256.c
index 068ecccf2f4..1317d30023f 100644
--- a/contrib/libs/curl/lib/sha256.c
+++ b/contrib/libs/curl/lib/sha256.c
@@ -82,10 +82,14 @@ struct sha256_ctx {
};
typedef struct sha256_ctx my_sha256_ctx;
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
{
ctx->openssl_ctx = EVP_MD_CTX_create();
+ if(!ctx->openssl_ctx)
+ return CURLE_OUT_OF_MEMORY;
+
EVP_DigestInit_ex(ctx->openssl_ctx, EVP_sha256(), NULL);
+ return CURLE_OK;
}
static void my_sha256_update(my_sha256_ctx *ctx,
@@ -112,9 +116,10 @@ static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
typedef struct sha256_ctx my_sha256_ctx;
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
{
sha256_init(ctx);
+ return CURLE_OK;
}
static void my_sha256_update(my_sha256_ctx *ctx,
@@ -140,13 +145,14 @@ static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
typedef mbedtls_sha256_context my_sha256_ctx;
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
{
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
(void) mbedtls_sha256_starts(ctx, 0);
#else
(void) mbedtls_sha256_starts_ret(ctx, 0);
#endif
+ return CURLE_OK;
}
static void my_sha256_update(my_sha256_ctx *ctx,
@@ -183,9 +189,10 @@ static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
typedef CC_SHA256_CTX my_sha256_ctx;
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
{
(void) CC_SHA256_Init(ctx);
+ return CURLE_OK;
}
static void my_sha256_update(my_sha256_ctx *ctx,
@@ -214,12 +221,14 @@ typedef struct sha256_ctx my_sha256_ctx;
#define CALG_SHA_256 0x0000800c
#endif
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
{
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
}
+
+ return CURLE_OK;
}
static void my_sha256_update(my_sha256_ctx *ctx,
@@ -375,7 +384,7 @@ static int sha256_compress(struct sha256_state *md,
}
/* Initialize the hash state */
-static void my_sha256_init(struct sha256_state *md)
+static CURLcode my_sha256_init(struct sha256_state *md)
{
md->curlen = 0;
md->length = 0;
@@ -387,6 +396,8 @@ static void my_sha256_init(struct sha256_state *md)
md->state[5] = 0x9B05688CUL;
md->state[6] = 0x1F83D9ABUL;
md->state[7] = 0x5BE0CD19UL;
+
+ return CURLE_OK;
}
/*
@@ -394,7 +405,7 @@ static void my_sha256_init(struct sha256_state *md)
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
- @return CRYPT_OK if successful
+ @return 0 if successful
*/
static int my_sha256_update(struct sha256_state *md,
const unsigned char *in,
@@ -435,7 +446,7 @@ static int my_sha256_update(struct sha256_state *md,
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (32 bytes)
- @return CRYPT_OK if successful
+ @return 0 if successful
*/
static int my_sha256_final(unsigned char *out,
struct sha256_state *md)
@@ -491,15 +502,21 @@ static int my_sha256_final(unsigned char *out,
* output [in/out] - The output buffer.
* input [in] - The input data.
* length [in] - The input length.
+ *
+ * Returns CURLE_OK on success.
*/
-void Curl_sha256it(unsigned char *output, const unsigned char *input,
+CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input,
const size_t length)
{
+ CURLcode result;
my_sha256_ctx ctx;
- my_sha256_init(&ctx);
- my_sha256_update(&ctx, input, curlx_uztoui(length));
- my_sha256_final(output, &ctx);
+ result = my_sha256_init(&ctx);
+ if(!result) {
+ my_sha256_update(&ctx, input, curlx_uztoui(length));
+ my_sha256_final(output, &ctx);
+ }
+ return result;
}
diff --git a/contrib/libs/curl/lib/share.c b/contrib/libs/curl/lib/share.c
index 9c43c8f7053..403563fdd6e 100644
--- a/contrib/libs/curl/lib/share.c
+++ b/contrib/libs/curl/lib/share.c
@@ -39,11 +39,7 @@ curl_share_init(void)
if(share) {
share->magic = CURL_GOOD_SHARE;
share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
-
- if(Curl_mk_dnscache(&share->hostcache)) {
- free(share);
- return NULL;
- }
+ Curl_init_dnscache(&share->hostcache);
}
return share;
diff --git a/contrib/libs/curl/lib/smtp.c b/contrib/libs/curl/lib/smtp.c
index 8e0b0460968..6c082937835 100644
--- a/contrib/libs/curl/lib/smtp.c
+++ b/contrib/libs/curl/lib/smtp.c
@@ -222,7 +222,7 @@ static bool smtp_endofresp(struct Curl_easy *data, struct connectdata *conn,
/* Do we have a command response? This should be the response code followed
by a space and optionally some text as per RFC-5321 and as outlined in
- Section 4. Examples of RFC-4954 but some e-mail servers ignore this and
+ Section 4. Examples of RFC-4954 but some email servers ignore this and
only send the response code instead as per Section 4.2. */
if(line[3] == ' ' || len == 5) {
char tmpline[6];
diff --git a/contrib/libs/curl/lib/socks.c b/contrib/libs/curl/lib/socks.c
index db4c80834e3..a014aa6684c 100644
--- a/contrib/libs/curl/lib/socks.c
+++ b/contrib/libs/curl/lib/socks.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -38,6 +38,7 @@
#include "timeval.h"
#include "socks.h"
#include "multiif.h" /* for getsock macros */
+#include "inet_pton.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -856,10 +857,32 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
socksreq[len++] = 0; /* must be zero */
if(!socks5_resolve_local) {
- socksreq[len++] = 3; /* ATYP: domain name = 3 */
- socksreq[len++] = (char) hostname_len; /* one byte address length */
- memcpy(&socksreq[len], hostname, hostname_len); /* address w/o NULL */
- len += hostname_len;
+ /* ATYP: domain name = 3,
+ IPv6 == 4,
+ IPv4 == 1 */
+ unsigned char ip4[4];
+#ifdef ENABLE_IPV6
+ if(conn->bits.ipv6_ip) {
+ char ip6[16];
+ if(1 != Curl_inet_pton(AF_INET6, hostname, ip6))
+ return CURLPX_BAD_ADDRESS_TYPE;
+ socksreq[len++] = 4;
+ memcpy(&socksreq[len], ip6, sizeof(ip6));
+ len += sizeof(ip6);
+ }
+ else
+#endif
+ if(1 == Curl_inet_pton(AF_INET, hostname, ip4)) {
+ socksreq[len++] = 1;
+ memcpy(&socksreq[len], ip4, sizeof(ip4));
+ len += sizeof(ip4);
+ }
+ else {
+ socksreq[len++] = 3;
+ socksreq[len++] = (char) hostname_len; /* one byte address length */
+ memcpy(&socksreq[len], hostname, hostname_len); /* address w/o NULL */
+ len += hostname_len;
+ }
infof(data, "SOCKS5 connect to %s:%d (remotely resolved)",
hostname, remote_port);
}
diff --git a/contrib/libs/curl/lib/splay.c b/contrib/libs/curl/lib/splay.c
index 1c1dafb920b..bcc0795212a 100644
--- a/contrib/libs/curl/lib/splay.c
+++ b/contrib/libs/curl/lib/splay.c
@@ -107,7 +107,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i,
if(!node)
return t;
- if(t != NULL) {
+ if(t) {
t = Curl_splay(i, t);
if(compare(i, t->key) == 0) {
/* There already exists a node in the tree with the very same key. Build
diff --git a/contrib/libs/curl/lib/strerror.c b/contrib/libs/curl/lib/strerror.c
index 9d47c477d56..7a53087983b 100644
--- a/contrib/libs/curl/lib/strerror.c
+++ b/contrib/libs/curl/lib/strerror.c
@@ -404,6 +404,9 @@ curl_multi_strerror(CURLMcode error)
case CURLM_BAD_FUNCTION_ARGUMENT:
return "A libcurl function was given a bad argument";
+ case CURLM_ABORTED_BY_CALLBACK:
+ return "Operation was aborted by an application callback";
+
case CURLM_LAST:
break;
}
@@ -468,10 +471,10 @@ curl_url_strerror(CURLUcode error)
return "An invalid 'part' argument was passed as argument";
case CURLUE_MALFORMED_INPUT:
- return "A malformed input was passed to a URL API function";
+ return "Malformed input to a URL function";
case CURLUE_BAD_PORT_NUMBER:
- return "The port number was not a decimal number between 0 and 65535";
+ return "Port number was not a decimal number between 0 and 65535";
case CURLUE_UNSUPPORTED_SCHEME:
return "This libcurl build doesn't support the given URL scheme";
@@ -489,28 +492,64 @@ curl_url_strerror(CURLUcode error)
return "An unknown part ID was passed to a URL API function";
case CURLUE_NO_SCHEME:
- return "There is no scheme part in the URL";
+ return "No scheme part in the URL";
case CURLUE_NO_USER:
- return "There is no user part in the URL";
+ return "No user part in the URL";
case CURLUE_NO_PASSWORD:
- return "There is no password part in the URL";
+ return "No password part in the URL";
case CURLUE_NO_OPTIONS:
- return "There is no options part in the URL";
+ return "No options part in the URL";
case CURLUE_NO_HOST:
- return "There is no host part in the URL";
+ return "No host part in the URL";
case CURLUE_NO_PORT:
- return "There is no port part in the URL";
+ return "No port part in the URL";
case CURLUE_NO_QUERY:
- return "There is no query part in the URL";
+ return "No query part in the URL";
case CURLUE_NO_FRAGMENT:
- return "There is no fragment part in the URL";
+ return "No fragment part in the URL";
+
+ case CURLUE_NO_ZONEID:
+ return "No zoneid part in the URL";
+
+ case CURLUE_BAD_LOGIN:
+ return "Bad login part";
+
+ case CURLUE_BAD_IPV6:
+ return "Bad IPv6 address";
+
+ case CURLUE_BAD_HOSTNAME:
+ return "Bad hostname";
+
+ case CURLUE_BAD_FILE_URL:
+ return "Bad file:// URL";
+
+ case CURLUE_BAD_SLASHES:
+ return "Unsupported number of slashes";
+
+ case CURLUE_BAD_SCHEME:
+ return "Bad scheme";
+
+ case CURLUE_BAD_PATH:
+ return "Bad path";
+
+ case CURLUE_BAD_FRAGMENT:
+ return "Bad fragment";
+
+ case CURLUE_BAD_QUERY:
+ return "Bad query";
+
+ case CURLUE_BAD_PASSWORD:
+ return "Bad password";
+
+ case CURLUE_BAD_USER:
+ return "Bad user";
case CURLUE_LAST:
break;
diff --git a/contrib/libs/curl/lib/system_win32.c b/contrib/libs/curl/lib/system_win32.c
index d4e194831fc..9a6dd9cef6f 100644
--- a/contrib/libs/curl/lib/system_win32.c
+++ b/contrib/libs/curl/lib/system_win32.c
@@ -104,7 +104,7 @@ CURLcode Curl_win32_init(long flags)
/* curlx_verify_windows_version must be called during init at least once
because it has its own initialization routine. */
- if(curlx_verify_windows_version(6, 0, PLATFORM_WINNT,
+ if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
Curl_isVistaOrGreater = TRUE;
}
diff --git a/contrib/libs/curl/lib/tftp.c b/contrib/libs/curl/lib/tftp.c
index 7e5246f0109..f8c68441cac 100644
--- a/contrib/libs/curl/lib/tftp.c
+++ b/contrib/libs/curl/lib/tftp.c
@@ -186,7 +186,7 @@ const struct Curl_handler Curl_handler_tftp = {
PORT_TFTP, /* defport */
CURLPROTO_TFTP, /* protocol */
CURLPROTO_TFTP, /* family */
- PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
+ PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY /* flags */
};
/**********************************************************
diff --git a/contrib/libs/curl/lib/transfer.c b/contrib/libs/curl/lib/transfer.c
index 05fec7998ce..22704fa1583 100644
--- a/contrib/libs/curl/lib/transfer.c
+++ b/contrib/libs/curl/lib/transfer.c
@@ -1631,7 +1631,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
if((type != FOLLOW_RETRY) &&
(data->req.httpcode != 401) && (data->req.httpcode != 407) &&
- Curl_is_absolute_url(newurl, NULL, MAX_SCHEME_LEN))
+ Curl_is_absolute_url(newurl, NULL, 0))
/* If this is not redirect due to a 401 or 407 response and an absolute
URL: don't allow a custom port number */
disallowport = TRUE;
diff --git a/contrib/libs/curl/lib/url.c b/contrib/libs/curl/lib/url.c
index 9a1a14a2621..3fdf02d8ec7 100644
--- a/contrib/libs/curl/lib/url.c
+++ b/contrib/libs/curl/lib/url.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, 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,6 +137,15 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "curl_memory.h"
#include "memdebug.h"
+/* Count of the backend ssl objects to allocate */
+#ifdef USE_SSL
+# ifndef CURL_DISABLE_PROXY
+# define SSL_BACKEND_CNT 4
+# else
+# define SSL_BACKEND_CNT 2
+# endif
+#endif
+
static void conn_free(struct connectdata *conn);
/* Some parts of the code (e.g. chunked encoding) assume this buffer has at
@@ -354,9 +363,7 @@ static void up_free(struct Curl_easy *data)
* This is the internal function curl_easy_cleanup() calls. This should
* cleanup and free all resources associated with this sessionhandle.
*
- * NOTE: if we ever add something that attempts to write to a socket or
- * similar here, we must ignore SIGPIPE first. It is currently only done
- * when curl_easy_perform() is invoked.
+ * We ignore SIGPIPE when this is called from curl_easy_cleanup.
*/
CURLcode Curl_close(struct Curl_easy **datap)
@@ -542,8 +549,10 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
* libcurl 7.10 introduced SSL verification *by default*! This needs to be
* switched off unless wanted.
*/
+#ifndef CURL_DISABLE_DOH
set->doh_verifyhost = TRUE;
set->doh_verifypeer = TRUE;
+#endif
set->ssl.primary.verifypeer = TRUE;
set->ssl.primary.verifyhost = TRUE;
#ifdef USE_TLS_SRP
@@ -845,7 +854,7 @@ CURLcode Curl_disconnect(struct Curl_easy *data,
return CURLE_OK;
}
- if(conn->dns_entry != NULL) {
+ if(conn->dns_entry) {
Curl_resolv_unlock(data, conn->dns_entry);
conn->dns_entry = NULL;
}
@@ -1300,13 +1309,12 @@ ConnectionExists(struct Curl_easy *data,
if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
continue;
}
- else {
- if(!Curl_ssl_config_matches(&needle->ssl_config,
- &check->ssl_config))
- continue;
- if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
- continue;
- }
+
+ if(!Curl_ssl_config_matches(&needle->ssl_config,
+ &check->ssl_config))
+ continue;
+ if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
+ continue;
}
}
#endif
@@ -1683,7 +1691,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
data becomes proxy backend data). */
{
size_t sslsize = Curl_ssl->sizeof_ssl_backend_data;
- char *ssl = calloc(4, sslsize);
+ char *ssl = calloc(SSL_BACKEND_CNT, sslsize);
if(!ssl) {
free(conn);
return NULL;
@@ -1950,7 +1958,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
if(data->set.str[STRING_DEFAULT_PROTOCOL] &&
- !Curl_is_absolute_url(data->state.url, NULL, MAX_SCHEME_LEN)) {
+ !Curl_is_absolute_url(data->state.url, NULL, 0)) {
char *url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL],
data->state.url);
if(!url)
@@ -2593,7 +2601,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
if(data->set.str[STRING_PROXY]) {
proxy = strdup(data->set.str[STRING_PROXY]);
/* if global proxy is set, this is it */
- if(NULL == proxy) {
+ if(!proxy) {
failf(data, "memory shortage");
result = CURLE_OUT_OF_MEMORY;
goto out;
@@ -2603,7 +2611,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
if(data->set.str[STRING_PRE_PROXY]) {
socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
/* if global socks proxy is set, this is it */
- if(NULL == socksproxy) {
+ if(!socksproxy) {
failf(data, "memory shortage");
result = CURLE_OUT_OF_MEMORY;
goto out;
diff --git a/contrib/libs/curl/lib/urlapi-int.h b/contrib/libs/curl/lib/urlapi-int.h
index 42572330946..bd6b6017515 100644
--- a/contrib/libs/curl/lib/urlapi-int.h
+++ b/contrib/libs/curl/lib/urlapi-int.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -22,8 +22,6 @@
*
***************************************************************************/
#include "curl_setup.h"
-/* scheme is not URL encoded, the longest libcurl supported ones are... */
-#define MAX_SCHEME_LEN 40
bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen);
diff --git a/contrib/libs/curl/lib/urlapi.c b/contrib/libs/curl/lib/urlapi.c
index 6d116b61bf7..d29aeb238f6 100644
--- a/contrib/libs/curl/lib/urlapi.c
+++ b/contrib/libs/curl/lib/urlapi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -30,6 +30,7 @@
#include "escape.h"
#include "curl_ctype.h"
#include "inet_pton.h"
+#include "inet_ntop.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -50,6 +51,9 @@
((str)[1] == ':' || (str)[1] == '|') && \
((str)[2] == '/' || (str)[2] == '\\' || (str)[2] == 0))
+/* scheme is not URL encoded, the longest libcurl supported ones are... */
+#define MAX_SCHEME_LEN 40
+
/* Internal representation of CURLU. Point to URL-encoded strings. */
struct Curl_URL {
char *scheme;
@@ -228,33 +232,40 @@ static void strcpy_url(char *output, const char *url, bool relative)
}
/*
- * Returns true if the given URL is absolute (as opposed to relative) within
- * the buffer size. Returns the scheme in the buffer if TRUE and 'buf' is
- * non-NULL.
+ * Returns true if the given URL is absolute (as opposed to relative). Returns
+ * the scheme in the buffer if TRUE and 'buf' is non-NULL. The buflen must
+ * be larger than MAX_SCHEME_LEN if buf is set.
*/
bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
{
size_t i;
+ DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN));
+ (void)buflen; /* only used in debug-builds */
+ if(buf)
+ buf[0] = 0; /* always leave a defined value in buf */
#ifdef WIN32
if(STARTS_WITH_DRIVE_PREFIX(url))
return FALSE;
#endif
- for(i = 0; i < buflen && url[i]; ++i) {
+ for(i = 0; i < MAX_SCHEME_LEN; ++i) {
char s = url[i];
- if((s == ':') && (url[i + 1] == '/')) {
- if(buf)
- buf[i] = 0;
- return TRUE;
- }
- /* RFC 3986 3.1 explains:
- scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
- */
- else if(ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') ) {
- if(buf)
- buf[i] = (char)TOLOWER(s);
+ if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) {
+ /* RFC 3986 3.1 explains:
+ scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ */
}
- else
+ else {
break;
+ }
+ }
+ if(i && (url[i] == ':') && (url[i + 1] == '/')) {
+ if(buf) {
+ buf[i] = 0;
+ while(i--) {
+ buf[i] = (char)TOLOWER(url[i]);
+ }
+ }
+ return TRUE;
}
return FALSE;
}
@@ -418,6 +429,29 @@ static char *concat_url(const char *base, const char *relurl)
return newest;
}
+/* scan for byte values < 31 or 127 */
+static bool junkscan(const char *part, unsigned int flags)
+{
+ if(part) {
+ static const char badbytes[]={
+ /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x7f, 0x00 /* null-terminate */
+ };
+ size_t n = strlen(part);
+ size_t nfine = strcspn(part, badbytes);
+ if(nfine != n)
+ /* since we don't know which part is scanned, return a generic error
+ code */
+ return TRUE;
+ if(!(flags & CURLU_ALLOW_SPACE) && strchr(part, ' '))
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*
* parse_hostname_login()
*
@@ -465,7 +499,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
(h && (h->flags & PROTOPT_URLOPTIONS)) ?
&optionsp:NULL);
if(ccode) {
- result = CURLUE_MALFORMED_INPUT;
+ result = CURLUE_BAD_LOGIN;
goto out;
}
@@ -475,15 +509,28 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
result = CURLUE_USER_NOT_ALLOWED;
goto out;
}
-
+ if(junkscan(userp, flags)) {
+ result = CURLUE_BAD_USER;
+ goto out;
+ }
u->user = userp;
}
- if(passwdp)
+ if(passwdp) {
+ if(junkscan(passwdp, flags)) {
+ result = CURLUE_BAD_PASSWORD;
+ goto out;
+ }
u->password = passwdp;
+ }
- if(optionsp)
+ if(optionsp) {
+ if(junkscan(optionsp, flags)) {
+ result = CURLUE_BAD_LOGIN;
+ goto out;
+ }
u->options = optionsp;
+ }
return CURLUE_OK;
out:
@@ -491,6 +538,9 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
free(userp);
free(passwdp);
free(optionsp);
+ u->user = NULL;
+ u->password = NULL;
+ u->options = NULL;
return result;
}
@@ -514,19 +564,19 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
int zonelen = len;
if(1 == sscanf(hostname + zonelen, "%*[^]]%c%n", &endbracket, &len)) {
if(']' != endbracket)
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_IPV6;
portptr = &hostname[--zonelen + len + 1];
}
else
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_IPV6;
}
else
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_IPV6;
/* this is a RFC2732-style specified IP-address */
if(portptr && *portptr) {
if(*portptr != ':')
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_IPV6;
}
else
portptr = NULL;
@@ -556,9 +606,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
port = strtol(portptr + 1, &rest, 10); /* Port number must be decimal */
- if((port <= 0) || (port > 0xffff))
- /* Single unix standard says port numbers are 16 bits long, but we don't
- treat port zero as OK. */
+ if(port > 0xffff)
return CURLUE_BAD_PORT_NUMBER;
if(rest[0])
@@ -577,46 +625,20 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
return CURLUE_OK;
}
-/* scan for byte values < 31 or 127 */
-static bool junkscan(const char *part, unsigned int flags)
-{
- if(part) {
- static const char badbytes[]={
- /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x7f, 0x00 /* null-terminate */
- };
- size_t n = strlen(part);
- size_t nfine = strcspn(part, badbytes);
- if(nfine != n)
- /* since we don't know which part is scanned, return a generic error
- code */
- return TRUE;
- if(!(flags & CURLU_ALLOW_SPACE) && strchr(part, ' '))
- return TRUE;
- }
- return FALSE;
-}
-
static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
{
size_t len;
size_t hlen = strlen(hostname);
if(hostname[0] == '[') {
-#ifdef ENABLE_IPV6
- char dest[16]; /* fits a binary IPv6 address */
-#endif
const char *l = "0123456789abcdefABCDEF:.";
if(hlen < 4) /* '[::]' is the shortest possible valid string */
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_IPV6;
hostname++;
hlen -= 2;
if(hostname[hlen] != ']')
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_IPV6;
/* only valid letters are ok */
len = strspn(hostname, l);
@@ -633,6 +655,7 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
while(*h && (*h != ']') && (i < 15))
zoneid[i++] = *h++;
if(!i || (']' != *h))
+ /* impossible to reach? */
return CURLUE_MALFORMED_INPUT;
zoneid[i] = 0;
u->zoneid = strdup(zoneid);
@@ -642,14 +665,26 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
hostname[len + 1] = 0; /* terminate the hostname */
}
else
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_IPV6;
/* hostname is fine */
}
#ifdef ENABLE_IPV6
- hostname[hlen] = 0; /* end the address there */
- if(1 != Curl_inet_pton(AF_INET6, hostname, dest))
- return CURLUE_MALFORMED_INPUT;
- hostname[hlen] = ']'; /* restore ending bracket */
+ {
+ char dest[16]; /* fits a binary IPv6 address */
+ char norm[MAX_IPADR_LEN];
+ hostname[hlen] = 0; /* end the address there */
+ if(1 != Curl_inet_pton(AF_INET6, hostname, dest))
+ return CURLUE_BAD_IPV6;
+
+ /* check if it can be done shorter */
+ if(Curl_inet_ntop(AF_INET6, dest, norm, sizeof(norm)) &&
+ (strlen(norm) < hlen)) {
+ strcpy(hostname, norm);
+ hlen = strlen(norm);
+ hostname[hlen + 1] = 0;
+ }
+ hostname[hlen] = ']'; /* restore ending bracket */
+ }
#endif
}
else {
@@ -657,7 +692,7 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
len = strcspn(hostname, " \r\n");
if(hlen != len)
/* hostname with bad content */
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_HOSTNAME;
}
if(!hostname[0])
return CURLUE_NO_HOST;
@@ -772,7 +807,7 @@ static CURLUcode decode_host(char *hostname, char **outp)
CURLcode result = Curl_urldecode(NULL, hostname, 0,
outp, &dlen, REJECT_CTRL);
if(result)
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_HOSTNAME;
}
return CURLUE_OK;
@@ -817,7 +852,11 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
}
/* handle the file: scheme */
- if(url_has_scheme && strcasecompare(schemebuf, "file")) {
+ if(url_has_scheme && !strcmp(schemebuf, "file")) {
+ if(urllen <= 6)
+ /* file:/ is not enough to actually be a complete file: URL */
+ return CURLUE_BAD_FILE_URL;
+
/* path has been allocated large enough to hold this */
strcpy(path, &url[5]);
@@ -870,7 +909,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
host name */
path = strpbrk(ptr, "/\\:*?\"<>|");
if(!path || *path != '/')
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_FILE_URL;
len = path - ptr;
if(len) {
@@ -883,7 +922,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
#else
/* Invalid file://hostname/, expected localhost or 127.0.0.1 or
none */
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_FILE_URL;
#endif
}
}
@@ -900,7 +939,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) ||
STARTS_WITH_URL_DRIVE_PREFIX(path)) {
/* File drive letters are only accepted in MSDOS/Windows */
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_FILE_URL;
}
#else
/* If the path starts with a slash and a drive letter, ditch the slash */
@@ -927,7 +966,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
}
if((i < 1) || (i>3))
/* less than one or more than three slashes */
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_SLASHES;
schemep = schemebuf;
if(!Curl_builtin_scheme(schemep) &&
@@ -935,13 +974,13 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
return CURLUE_UNSUPPORTED_SCHEME;
if(junkscan(schemep, flags))
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_SCHEME;
}
else {
/* no scheme! */
if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME)))
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_SCHEME;
if(flags & CURLU_DEFAULT_SCHEME)
schemep = DEFAULT_SCHEME;
@@ -952,7 +991,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
}
hostp = p; /* host name starts here */
- while(*p && !HOSTNAME_END(*p)) /* find end of host name */
+ /* find the end of the host name + port number */
+ while(*p && !HOSTNAME_END(*p))
p++;
len = p - hostp;
@@ -962,7 +1002,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
}
else {
if(!(flags & CURLU_NO_AUTHORITY))
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_NO_HOST;
}
len = strlen(p);
@@ -976,9 +1016,6 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
}
}
- if(junkscan(path, flags))
- return CURLUE_MALFORMED_INPUT;
-
if((flags & CURLU_URLENCODE) && path[0]) {
/* worst case output length is 3x the original! */
char *newp = malloc(strlen(path) * 3);
@@ -992,6 +1029,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
fragment = strchr(path, '#');
if(fragment) {
*fragment++ = 0;
+ if(junkscan(fragment, flags))
+ return CURLUE_BAD_FRAGMENT;
if(fragment[0]) {
u->fragment = strdup(fragment);
if(!u->fragment)
@@ -1002,12 +1041,17 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
query = strchr(path, '?');
if(query) {
*query++ = 0;
+ if(junkscan(query, flags))
+ return CURLUE_BAD_QUERY;
/* done even if the query part is a blank string */
u->query = strdup(query);
if(!u->query)
return CURLUE_OUT_OF_MEMORY;
}
+ if(junkscan(path, flags))
+ return CURLUE_BAD_PATH;
+
if(!path[0])
/* if there's no path left set, unset */
path = NULL;
@@ -1037,12 +1081,10 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(hostname) {
char normalized_ipv4[sizeof("255.255.255.255") + 1];
+
/*
* Parse the login details and strip them out of the host name.
*/
- if(junkscan(hostname, flags))
- return CURLUE_MALFORMED_INPUT;
-
result = parse_hostname_login(u, &hostname, flags);
if(result)
return result;
@@ -1051,6 +1093,9 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(result)
return result;
+ if(junkscan(hostname, flags))
+ return CURLUE_BAD_HOSTNAME;
+
if(0 == strlen(hostname) && (flags & CURLU_NO_AUTHORITY)) {
/* Skip hostname check, it's allowed to be empty. */
u->host = strdup("");
@@ -1196,6 +1241,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
break;
case CURLUPART_ZONEID:
ptr = u->zoneid;
+ ifmissing = CURLUE_NO_ZONEID;
break;
case CURLUPART_PORT:
ptr = u->port;
@@ -1453,7 +1499,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
case CURLUPART_SCHEME:
if(strlen(part) > MAX_SCHEME_LEN)
/* too long */
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_SCHEME;
if(!(flags & CURLU_NON_SUPPORT_SCHEME) &&
/* verify that it is a fine scheme */
!Curl_builtin_scheme(part))
@@ -1474,7 +1520,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
size_t len = strcspn(part, " \r\n");
if(strlen(part) != len)
/* hostname with bad content */
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_HOSTNAME;
storep = &u->host;
Curl_safefree(u->zoneid);
break;
@@ -1491,7 +1537,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_BAD_PORT_NUMBER;
if(*endp)
/* weirdly provided number, not good! */
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_PORT_NUMBER;
storep = &u->port;
}
break;
@@ -1520,7 +1566,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
char *redired_url;
CURLU *handle2;
- if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN + 1)) {
+ if(Curl_is_absolute_url(part, NULL, 0)) {
handle2 = curl_url();
if(!handle2)
return CURLUE_OUT_OF_MEMORY;
@@ -1655,7 +1701,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
else {
if(hostname_check(u, (char *)newp)) {
free((char *)newp);
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_HOSTNAME;
}
}
}
diff --git a/contrib/libs/curl/lib/urldata.h b/contrib/libs/curl/lib/urldata.h
index 76488b25492..93aea806910 100644
--- a/contrib/libs/curl/lib/urldata.h
+++ b/contrib/libs/curl/lib/urldata.h
@@ -518,7 +518,9 @@ struct ConnectBits {
BIT(tls_enable_npn); /* TLS NPN extension? */
BIT(tls_enable_alpn); /* TLS ALPN extension? */
BIT(connect_only);
+#ifndef CURL_DISABLE_DOH
BIT(doh);
+#endif
#ifdef USE_UNIX_SOCKETS
BIT(abstract_unix_socket);
#endif
@@ -835,6 +837,7 @@ struct Curl_handler {
#define PROTOPT_WILDCARD (1<<12) /* protocol supports wildcard matching */
#define PROTOPT_USERPWDCTRL (1<<13) /* Allow "control bytes" (< 32 ascii) in
user name and password */
+#define PROTOPT_NOTCPPROXY (1<<14) /* this protocol can't proxy over TCP */
#define CONNCHECK_NONE 0 /* No checks */
#define CONNCHECK_ISDEAD (1<<0) /* Check if the connection is dead. */
@@ -1749,6 +1752,7 @@ struct UserDefined {
unsigned int scope_id; /* Scope id for IPv6 */
long allowed_protocols;
long redir_protocols;
+ long mime_options; /* Mime option flags. */
struct curl_slist *mail_rcpt; /* linked list of mail recipients */
/* Common RTSP header options */
Curl_RtspReq rtspreq; /* RTSP request type */
@@ -1856,10 +1860,12 @@ struct UserDefined {
header */
BIT(abstract_unix_socket);
BIT(disallow_username_in_url); /* disallow username in url */
+#ifndef CURL_DISABLE_DOH
BIT(doh); /* DNS-over-HTTPS enabled */
BIT(doh_verifypeer); /* DoH certificate peer verification */
BIT(doh_verifyhost); /* DoH certificate hostname verification */
BIT(doh_verifystatus); /* DoH certificate status verification */
+#endif
BIT(http09_allowed); /* allow HTTP/0.9 responses */
BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some
recipients */
diff --git a/contrib/libs/curl/lib/vauth/digest.c b/contrib/libs/curl/lib/vauth/digest.c
index a04ffab6fb3..d8aac66bdaf 100644
--- a/contrib/libs/curl/lib/vauth/digest.c
+++ b/contrib/libs/curl/lib/vauth/digest.c
@@ -230,7 +230,7 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value)
return CURLE_OUT_OF_MEMORY;
token = strtok_r(tmp, ",", &tok_buf);
- while(token != NULL) {
+ while(token) {
if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH))
*value |= DIGEST_QOP_VALUE_AUTH;
else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
@@ -556,7 +556,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
return CURLE_OUT_OF_MEMORY;
token = strtok_r(tmp, ",", &tok_buf);
- while(token != NULL) {
+ while(token) {
if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
foundAuth = TRUE;
}
@@ -666,8 +666,8 @@ static CURLcode auth_create_digest_http_message(
struct digestdata *digest,
char **outptr, size_t *outlen,
void (*convert_to_ascii)(unsigned char *, unsigned char *),
- void (*hash)(unsigned char *, const unsigned char *,
- const size_t))
+ CURLcode (*hash)(unsigned char *, const unsigned char *,
+ const size_t))
{
CURLcode result;
unsigned char hashbuf[32]; /* 32 bytes/256 bits */
@@ -722,8 +722,7 @@ static CURLcode auth_create_digest_http_message(
unq(nonce-value) ":" unq(cnonce-value)
*/
- hashthis = aprintf("%s:%s:%s", digest->userhash ? userh : userp,
- digest->realm, passwdp);
+ hashthis = aprintf("%s:%s:%s", userp, digest->realm, passwdp);
if(!hashthis)
return CURLE_OUT_OF_MEMORY;
diff --git a/contrib/libs/curl/lib/vauth/ntlm.c b/contrib/libs/curl/lib/vauth/ntlm.c
index 0aa3f1c8ca5..04f6590acfc 100644
--- a/contrib/libs/curl/lib/vauth/ntlm.c
+++ b/contrib/libs/curl/lib/vauth/ntlm.c
@@ -603,7 +603,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
memcpy(tmp, &ntlm->nonce[0], 8);
memcpy(tmp + 8, entropy, 8);
- Curl_md5it(md5sum, tmp, 16);
+ result = Curl_md5it(md5sum, tmp, 16);
+ if(result)
+ return result;
/* We shall only use the first 8 bytes of md5sum, but the des code in
Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
diff --git a/contrib/libs/curl/lib/version_win32.c b/contrib/libs/curl/lib/version_win32.c
index 2f845413ccb..79a2aa6ab45 100644
--- a/contrib/libs/curl/lib/version_win32.c
+++ b/contrib/libs/curl/lib/version_win32.c
@@ -57,6 +57,8 @@ struct OUR_OSVERSIONINFOEXW {
*
* majorVersion [in] - The major version number.
* minorVersion [in] - The minor version number.
+ * buildVersion [in] - The build version number. If 0, this parameter is
+ * ignored.
* platform [in] - The optional platform identifier.
* condition [in] - The test condition used to specifier whether we are
* checking a version less then, equal to or greater than
@@ -67,6 +69,7 @@ struct OUR_OSVERSIONINFOEXW {
*/
bool curlx_verify_windows_version(const unsigned int majorVersion,
const unsigned int minorVersion,
+ const unsigned int buildVersion,
const PlatformIdentifier platform,
const VersionCondition condition)
{
@@ -118,34 +121,52 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
case VERSION_LESS_THAN:
if(osver.dwMajorVersion < majorVersion ||
(osver.dwMajorVersion == majorVersion &&
- osver.dwMinorVersion < minorVersion))
+ osver.dwMinorVersion < minorVersion) ||
+ (buildVersion != 0 &&
+ (osver.dwMajorVersion == majorVersion &&
+ osver.dwMinorVersion == minorVersion &&
+ osver.dwBuildNumber < buildVersion)))
matched = TRUE;
break;
case VERSION_LESS_THAN_EQUAL:
if(osver.dwMajorVersion < majorVersion ||
(osver.dwMajorVersion == majorVersion &&
- osver.dwMinorVersion <= minorVersion))
+ osver.dwMinorVersion < minorVersion) ||
+ (osver.dwMajorVersion == majorVersion &&
+ osver.dwMinorVersion == minorVersion &&
+ (buildVersion == 0 ||
+ osver.dwBuildNumber <= buildVersion)))
matched = TRUE;
break;
case VERSION_EQUAL:
if(osver.dwMajorVersion == majorVersion &&
- osver.dwMinorVersion == minorVersion)
+ osver.dwMinorVersion == minorVersion &&
+ (buildVersion == 0 ||
+ osver.dwBuildNumber == buildVersion))
matched = TRUE;
break;
case VERSION_GREATER_THAN_EQUAL:
if(osver.dwMajorVersion > majorVersion ||
(osver.dwMajorVersion == majorVersion &&
- osver.dwMinorVersion >= minorVersion))
+ osver.dwMinorVersion > minorVersion) ||
+ (osver.dwMajorVersion == majorVersion &&
+ osver.dwMinorVersion == minorVersion &&
+ (buildVersion == 0 ||
+ osver.dwBuildNumber >= buildVersion)))
matched = TRUE;
break;
case VERSION_GREATER_THAN:
if(osver.dwMajorVersion > majorVersion ||
(osver.dwMajorVersion == majorVersion &&
- osver.dwMinorVersion > minorVersion))
+ osver.dwMinorVersion > minorVersion) ||
+ (buildVersion != 0 &&
+ (osver.dwMajorVersion == majorVersion &&
+ osver.dwMinorVersion == minorVersion &&
+ osver.dwBuildNumber > buildVersion)))
matched = TRUE;
break;
}
@@ -161,6 +182,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
case PLATFORM_WINNT:
if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
matched = FALSE;
+ break;
default: /* like platform == PLATFORM_DONT_CARE */
break;
@@ -172,8 +194,11 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
struct OUR_OSVERSIONINFOEXW osver;
BYTE majorCondition;
BYTE minorCondition;
+ BYTE buildCondition;
BYTE spMajorCondition;
BYTE spMinorCondition;
+ DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION |
+ VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;
typedef LONG (APIENTRY *RTLVERIFYVERSIONINFO_FN)
(struct OUR_OSVERSIONINFOEXW *, ULONG, ULONGLONG);
@@ -190,6 +215,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
case VERSION_LESS_THAN:
majorCondition = VER_LESS;
minorCondition = VER_LESS;
+ buildCondition = VER_LESS;
spMajorCondition = VER_LESS_EQUAL;
spMinorCondition = VER_LESS_EQUAL;
break;
@@ -197,6 +223,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
case VERSION_LESS_THAN_EQUAL:
majorCondition = VER_LESS_EQUAL;
minorCondition = VER_LESS_EQUAL;
+ buildCondition = VER_LESS_EQUAL;
spMajorCondition = VER_LESS_EQUAL;
spMinorCondition = VER_LESS_EQUAL;
break;
@@ -204,6 +231,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
case VERSION_EQUAL:
majorCondition = VER_EQUAL;
minorCondition = VER_EQUAL;
+ buildCondition = VER_EQUAL;
spMajorCondition = VER_GREATER_EQUAL;
spMinorCondition = VER_GREATER_EQUAL;
break;
@@ -211,6 +239,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
case VERSION_GREATER_THAN_EQUAL:
majorCondition = VER_GREATER_EQUAL;
minorCondition = VER_GREATER_EQUAL;
+ buildCondition = VER_GREATER_EQUAL;
spMajorCondition = VER_GREATER_EQUAL;
spMinorCondition = VER_GREATER_EQUAL;
break;
@@ -218,6 +247,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
case VERSION_GREATER_THAN:
majorCondition = VER_GREATER;
minorCondition = VER_GREATER;
+ buildCondition = VER_GREATER;
spMajorCondition = VER_GREATER_EQUAL;
spMinorCondition = VER_GREATER_EQUAL;
break;
@@ -230,6 +260,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
osver.dwOSVersionInfoSize = sizeof(osver);
osver.dwMajorVersion = majorVersion;
osver.dwMinorVersion = minorVersion;
+ osver.dwBuildNumber = buildVersion;
if(platform == PLATFORM_WINDOWS)
osver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
else if(platform == PLATFORM_WINNT)
@@ -239,26 +270,43 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
cm = VerSetConditionMask(cm, VER_MINORVERSION, minorCondition);
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, spMajorCondition);
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, spMinorCondition);
- if(platform != PLATFORM_DONT_CARE)
+
+ if(platform != PLATFORM_DONT_CARE) {
cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
+ dwTypeMask |= VER_PLATFORMID;
+ }
/* Later versions of Windows have version functions that may not return the
real version of Windows unless the application is so manifested. We prefer
the real version always, so we use the Rtl variant of the function when
possible. Note though the function signatures have underlying fundamental
types that are the same, the return values are different. */
- if(pRtlVerifyVersionInfo) {
- matched = !pRtlVerifyVersionInfo(&osver,
- (VER_MAJORVERSION | VER_MINORVERSION |
- VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
- cm);
- }
- else {
- matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
- (VER_MAJORVERSION | VER_MINORVERSION |
- VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
- cm);
+ if(pRtlVerifyVersionInfo)
+ matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
+ else
+ matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver, dwTypeMask, cm);
+
+ /* Compare the build number separately. VerifyVersionInfo normally compares
+ major.minor in hierarchical order (eg 1.9 is less than 2.0) but does not
+ do the same for build (eg 1.9 build 222 is not less than 2.0 build 111).
+ Build comparison is only needed when build numbers are equal (eg 1.9 is
+ always less than 2.0 so build comparison is not needed). */
+ if(matched && buildVersion &&
+ (condition == VERSION_EQUAL ||
+ ((condition == VERSION_GREATER_THAN_EQUAL ||
+ condition == VERSION_LESS_THAN_EQUAL) &&
+ curlx_verify_windows_version(majorVersion, minorVersion, 0,
+ platform, VERSION_EQUAL)))) {
+
+ cm = VerSetConditionMask(0, VER_BUILDNUMBER, buildCondition);
+ dwTypeMask = VER_BUILDNUMBER;
+ if(pRtlVerifyVersionInfo)
+ matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
+ else
+ matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
+ dwTypeMask, cm);
}
+
#endif
return matched;
diff --git a/contrib/libs/curl/lib/version_win32.h b/contrib/libs/curl/lib/version_win32.h
index 9b1bd88874e..38af87fa097 100644
--- a/contrib/libs/curl/lib/version_win32.h
+++ b/contrib/libs/curl/lib/version_win32.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2016 - 2020, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2016 - 2021, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -45,6 +45,7 @@ typedef enum {
/* This is used to verify if we are running on a specific windows version */
bool curlx_verify_windows_version(const unsigned int majorVersion,
const unsigned int minorVersion,
+ const unsigned int buildVersion,
const PlatformIdentifier platform,
const VersionCondition condition);
diff --git a/contrib/libs/curl/lib/vquic/ngtcp2.c b/contrib/libs/curl/lib/vquic/ngtcp2.c
index e1f2d020dfe..008862d4bd6 100644
--- a/contrib/libs/curl/lib/vquic/ngtcp2.c
+++ b/contrib/libs/curl/lib/vquic/ngtcp2.c
@@ -29,8 +29,10 @@
#ifdef USE_OPENSSL
#include <openssl/err.h>
#error #include <ngtcp2/ngtcp2_crypto_openssl.h>
+#include "vtls/openssl.h"
#elif defined(USE_GNUTLS)
#error #include <ngtcp2/ngtcp2_crypto_gnutls.h>
+#include "vtls/gtls.h"
#endif
#include "urldata.h"
#include "sendf.h"
@@ -287,6 +289,27 @@ static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
}
+ {
+ struct connectdata *conn = data->conn;
+ const char * const ssl_cafile = conn->ssl_config.CAfile;
+ const char * const ssl_capath = conn->ssl_config.CApath;
+
+ if(conn->ssl_config.verifypeer) {
+ SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
+ /* tell OpenSSL where to find CA certificates that are used to verify
+ the server's certificate. */
+ if(!SSL_CTX_load_verify_locations(ssl_ctx, ssl_cafile, ssl_capath)) {
+ /* Fail if we insist on successfully verifying the server. */
+ failf(data, "error setting certificate verify locations:"
+ " CAfile: %s CApath: %s",
+ ssl_cafile ? ssl_cafile : "none",
+ ssl_capath ? ssl_capath : "none");
+ return NULL;
+ }
+ infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
+ infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
+ }
+ }
return ssl_ctx;
}
@@ -1638,8 +1661,10 @@ static ssize_t ngh3_stream_send(struct Curl_easy *data,
return sent;
}
-static void ng_has_connected(struct connectdata *conn, int tempindex)
+static CURLcode ng_has_connected(struct Curl_easy *data,
+ struct connectdata *conn, int tempindex)
{
+ CURLcode result = CURLE_OK;
conn->recv[FIRSTSOCKET] = ngh3_stream_recv;
conn->send[FIRSTSOCKET] = ngh3_stream_send;
conn->handler = &Curl_handler_http3;
@@ -1647,6 +1672,27 @@ static void ng_has_connected(struct connectdata *conn, int tempindex)
conn->httpversion = 30;
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
conn->quic = &conn->hequic[tempindex];
+
+ if(conn->ssl_config.verifyhost) {
+#ifdef USE_OPENSSL
+ X509 *server_cert;
+ CURLcode result;
+ server_cert = SSL_get_peer_certificate(conn->quic->ssl);
+ if(!server_cert) {
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ result = Curl_ossl_verifyhost(data, conn, server_cert);
+ X509_free(server_cert);
+ if(result)
+ return result;
+ infof(data, "Verified certificate just fine");
+#else
+ result = Curl_gtls_verifyserver(data, conn, conn->quic->ssl, FIRSTSOCKET);
+#endif
+ }
+ else
+ infof(data, "Skipped certificate verification");
+ return result;
}
/*
@@ -1670,8 +1716,9 @@ CURLcode Curl_quic_is_connected(struct Curl_easy *data,
goto error;
if(ngtcp2_conn_get_handshake_completed(qs->qconn)) {
- *done = TRUE;
- ng_has_connected(conn, sockindex);
+ result = ng_has_connected(data, conn, sockindex);
+ if(!result)
+ *done = TRUE;
}
return result;
@@ -1718,6 +1765,10 @@ static CURLcode ng_process_ingress(struct Curl_easy *data,
rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts);
if(rv) {
/* TODO Send CONNECTION_CLOSE if possible */
+ if(rv == NGTCP2_ERR_CRYPTO)
+ /* this is a "TLS problem", but a failed certificate verification
+ is a common reason for this */
+ return CURLE_PEER_FAILED_VERIFICATION;
return CURLE_RECV_ERROR;
}
}
diff --git a/contrib/libs/curl/lib/vssh/libssh2.c b/contrib/libs/curl/lib/vssh/libssh2.c
index 74909c460c0..df8c71a3b4c 100644
--- a/contrib/libs/curl/lib/vssh/libssh2.c
+++ b/contrib/libs/curl/lib/vssh/libssh2.c
@@ -645,8 +645,8 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
hostkey = libssh2_session_hostkey(sshc->ssh_session, &len, NULL);
if(hostkey) {
- Curl_sha256it(hash, (const unsigned char *) hostkey, len);
- fingerprint = (char *) hash;
+ if(!Curl_sha256it(hash, (const unsigned char *) hostkey, len))
+ fingerprint = (char *) hash;
}
#endif
@@ -661,16 +661,15 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
/* The length of fingerprint is 32 bytes for SHA256.
* See libssh2_hostkey_hash documentation. */
- if(Curl_base64_encode (data, fingerprint, 32, &fingerprint_b64,
- &fingerprint_b64_len) != CURLE_OK) {
+ if(Curl_base64_encode(data, fingerprint, 32, &fingerprint_b64,
+ &fingerprint_b64_len) != CURLE_OK) {
state(data, SSH_SESSION_FREE);
sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
return sshc->actualcode;
}
if(!fingerprint_b64) {
- failf(data,
- "sha256 fingerprint could not be encoded");
+ failf(data, "sha256 fingerprint could not be encoded");
state(data, SSH_SESSION_FREE);
sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
return sshc->actualcode;
@@ -698,7 +697,7 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
failf(data,
"Denied establishing ssh session: mismatch sha256 fingerprint. "
- "Remote %s is not equal to %s", fingerprint, pubkey_sha256);
+ "Remote %s is not equal to %s", fingerprint_b64, pubkey_sha256);
state(data, SSH_SESSION_FREE);
sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
return sshc->actualcode;
diff --git a/contrib/libs/curl/lib/vtls/gtls.c b/contrib/libs/curl/lib/vtls/gtls.c
index 2053fd439da..18864aa4b28 100644
--- a/contrib/libs/curl/lib/vtls/gtls.c
+++ b/contrib/libs/curl/lib/vtls/gtls.c
@@ -497,6 +497,7 @@ gtls_connect_step1(struct Curl_easy *data,
/* use system ca certificate store as fallback */
if(SSL_CONN_CONFIG(verifypeer) &&
!(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
+ /* this ignores errors on purpose */
gnutls_certificate_set_x509_system_trust(backend->cred);
}
#endif
@@ -631,7 +632,10 @@ gtls_connect_step1(struct Curl_easy *data,
cur++;
infof(data, "ALPN, offering %s", ALPN_HTTP_1_1);
- gnutls_alpn_set_protocols(session, protocols, cur, 0);
+ if(gnutls_alpn_set_protocols(session, protocols, cur, 0)) {
+ failf(data, "failed setting ALPN");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
}
if(SSL_SET_OPTION(primary.clientcert)) {
@@ -757,10 +761,10 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
/* if a path wasn't specified, don't pin */
- if(NULL == pinnedpubkey)
+ if(!pinnedpubkey)
return CURLE_OK;
- if(NULL == cert)
+ if(!cert)
return result;
do {
@@ -778,7 +782,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
break; /* failed */
buff1 = malloc(len1);
- if(NULL == buff1)
+ if(!buff1)
break; /* failed */
len2 = len1;
@@ -793,7 +797,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
} while(0);
- if(NULL != key)
+ if(key)
gnutls_pubkey_deinit(key);
Curl_safefree(buff1);
@@ -804,10 +808,11 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
static Curl_recv gtls_recv;
static Curl_send gtls_send;
-static CURLcode
-gtls_connect_step3(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+CURLcode
+Curl_gtls_verifyserver(struct Curl_easy *data,
+ struct connectdata *conn,
+ gnutls_session_t session,
+ int sockindex)
{
unsigned int cert_list_size;
const gnutls_datum_t *chainp;
@@ -819,9 +824,6 @@ gtls_connect_step3(struct Curl_easy *data,
size_t size;
time_t certclock;
const char *ptr;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct ssl_backend_data *backend = connssl->backend;
- gnutls_session_t session = backend->session;
int rc;
gnutls_datum_t proto;
CURLcode result = CURLE_OK;
@@ -1265,8 +1267,6 @@ gtls_connect_step3(struct Curl_easy *data,
}
conn->ssl[sockindex].state = ssl_connection_complete;
- conn->recv[sockindex] = gtls_recv;
- conn->send[sockindex] = gtls_send;
if(SSL_SET_OPTION(primary.sessionid)) {
/* we always unconditionally get the session id here, as even if we
@@ -1351,9 +1351,13 @@ gtls_connect_common(struct Curl_easy *data,
/* Finish connecting once the handshake is done */
if(ssl_connect_1 == connssl->connecting_state) {
- rc = gtls_connect_step3(data, conn, sockindex);
+ struct ssl_backend_data *backend = connssl->backend;
+ gnutls_session_t session = backend->session;
+ rc = Curl_gtls_verifyserver(data, conn, session, sockindex);
if(rc)
return rc;
+ conn->recv[sockindex] = gtls_recv;
+ conn->send[sockindex] = gtls_send;
}
*done = ssl_connect_1 == connssl->connecting_state;
diff --git a/contrib/libs/curl/lib/vtls/gtls.h b/contrib/libs/curl/lib/vtls/gtls.h
index 1a146a3a936..642d5f093a1 100644
--- a/contrib/libs/curl/lib/vtls/gtls.h
+++ b/contrib/libs/curl/lib/vtls/gtls.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -27,7 +27,11 @@
#ifdef USE_GNUTLS
#include "urldata.h"
-
+#include <gnutls/gnutls.h>
+CURLcode
+Curl_gtls_verifyserver(struct Curl_easy *data, struct connectdata *conn,
+ gnutls_session_t session,
+ int sockindex);
extern const struct Curl_ssl Curl_ssl_gnutls;
#endif /* USE_GNUTLS */
diff --git a/contrib/libs/curl/lib/vtls/mbedtls.c b/contrib/libs/curl/lib/vtls/mbedtls.c
index 3b08df96622..e177d3990db 100644
--- a/contrib/libs/curl/lib/vtls/mbedtls.c
+++ b/contrib/libs/curl/lib/vtls/mbedtls.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
@@ -270,7 +270,10 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
- const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+ const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
+ const char * const ssl_cafile =
+ /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
+ (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
@@ -316,16 +319,34 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
/* Load the trusted CA */
mbedtls_x509_crt_init(&backend->cacert);
- if(ssl_cafile) {
+ if(ca_info_blob && verifypeer) {
+ /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
+ terminated even when provided the exact length, forcing us to waste
+ extra memory here. */
+ unsigned char *newblob = malloc(ca_info_blob->len + 1);
+ if(!newblob)
+ return CURLE_OUT_OF_MEMORY;
+ memcpy(newblob, ca_info_blob->data, ca_info_blob->len);
+ newblob[ca_info_blob->len] = 0; /* null terminate */
+ ret = mbedtls_x509_crt_parse(&backend->cacert, newblob,
+ ca_info_blob->len + 1);
+ free(newblob);
+ if(ret<0) {
+ mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+ failf(data, "Error importing ca cert blob - mbedTLS: (-0x%04X) %s",
+ -ret, errorbuf);
+ return ret;
+ }
+ }
+
+ if(ssl_cafile && verifypeer) {
ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile);
if(ret<0) {
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
ssl_cafile, -ret, errorbuf);
-
- if(verifypeer)
- return CURLE_SSL_CACERT_BADFILE;
+ return CURLE_SSL_CACERT_BADFILE;
}
}
@@ -358,10 +379,17 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
if(ssl_cert_blob) {
- const unsigned char *blob_data =
- (const unsigned char *)ssl_cert_blob->data;
- ret = mbedtls_x509_crt_parse(&backend->clicert, blob_data,
+ /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
+ terminated even when provided the exact length, forcing us to waste
+ extra memory here. */
+ unsigned char *newblob = malloc(ssl_cert_blob->len + 1);
+ if(!newblob)
+ return CURLE_OUT_OF_MEMORY;
+ memcpy(newblob, ssl_cert_blob->data, ssl_cert_blob->len);
+ newblob[ssl_cert_blob->len] = 0; /* null terminate */
+ ret = mbedtls_x509_crt_parse(&backend->clicert, newblob,
ssl_cert_blob->len);
+ free(newblob);
if(ret) {
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
@@ -671,7 +699,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
mbedtls_x509_crt *p = NULL;
unsigned char *pubkey = NULL;
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER == 0x03000000
if(!peercert || !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p) ||
!peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len)) {
#else
@@ -698,7 +726,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
needs a non-const key, for now.
https://github.com/ARMmbed/mbedtls/issues/396 */
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER == 0x03000000
if(mbedtls_x509_crt_parse_der(p,
peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p),
peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len))) {
@@ -710,7 +738,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
goto pinnedpubkey_error;
}
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER == 0x03000000
size = mbedtls_pk_write_pubkey_der(&p->MBEDTLS_PRIVATE(pk), pubkey,
PUB_DER_MAX_BYTES);
#else
@@ -1154,6 +1182,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
{ CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */
SSLSUPP_CA_PATH |
+ SSLSUPP_CAINFO_BLOB |
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_SSL_CTX,
diff --git a/contrib/libs/curl/lib/vtls/mesalink.c b/contrib/libs/curl/lib/vtls/mesalink.c
index 0a1dea3ac02..35a916586e7 100644
--- a/contrib/libs/curl/lib/vtls/mesalink.c
+++ b/contrib/libs/curl/lib/vtls/mesalink.c
@@ -68,8 +68,6 @@ struct ssl_backend_data
SSL *handle;
};
-#define BACKEND connssl->backend
-
static Curl_recv mesalink_recv;
static Curl_send mesalink_send;
@@ -100,9 +98,9 @@ mesalink_connect_step1(struct Curl_easy *data,
#endif
const char * const hostname = SSL_HOST_NAME();
size_t hostname_len = strlen(hostname);
-
SSL_METHOD *req_method = NULL;
curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
if(connssl->state == ssl_connection_complete)
return CURLE_OK;
@@ -139,22 +137,22 @@ mesalink_connect_step1(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
- if(BACKEND->ctx)
- SSL_CTX_free(BACKEND->ctx);
- BACKEND->ctx = SSL_CTX_new(req_method);
+ if(backend->ctx)
+ SSL_CTX_free(backend->ctx);
+ backend->ctx = SSL_CTX_new(req_method);
- if(!BACKEND->ctx) {
+ if(!backend->ctx) {
failf(data, "SSL: couldn't create a context!");
return CURLE_OUT_OF_MEMORY;
}
SSL_CTX_set_verify(
- BACKEND->ctx, SSL_CONN_CONFIG(verifypeer) ?
+ backend->ctx, SSL_CONN_CONFIG(verifypeer) ?
SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath)) {
- if(!SSL_CTX_load_verify_locations(BACKEND->ctx, SSL_CONN_CONFIG(CAfile),
- SSL_CONN_CONFIG(CApath))) {
+ if(!SSL_CTX_load_verify_locations(backend->ctx, SSL_CONN_CONFIG(CAfile),
+ SSL_CONN_CONFIG(CApath))) {
if(SSL_CONN_CONFIG(verifypeer)) {
failf(data,
"error setting certificate verify locations: "
@@ -181,7 +179,7 @@ mesalink_connect_step1(struct Curl_easy *data,
if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) {
int file_type = do_file_type(SSL_SET_OPTION(cert_type));
- if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx,
+ if(SSL_CTX_use_certificate_chain_file(backend->ctx,
SSL_SET_OPTION(primary.clientcert),
file_type) != 1) {
failf(data, "unable to use client certificate (no key or wrong pass"
@@ -190,8 +188,8 @@ mesalink_connect_step1(struct Curl_easy *data,
}
file_type = do_file_type(SSL_SET_OPTION(key_type));
- if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
- file_type) != 1) {
+ if(SSL_CTX_use_PrivateKey_file(backend->ctx, SSL_SET_OPTION(key),
+ file_type) != 1) {
failf(data, "unable to set private key");
return CURLE_SSL_CONNECT_ERROR;
}
@@ -204,7 +202,7 @@ mesalink_connect_step1(struct Curl_easy *data,
ciphers = SSL_CONN_CONFIG(cipher_list);
if(ciphers) {
#ifdef MESALINK_HAVE_CIPHER
- if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
+ if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
failf(data, "failed setting cipher list: %s", ciphers);
return CURLE_SSL_CIPHER;
}
@@ -212,10 +210,10 @@ mesalink_connect_step1(struct Curl_easy *data,
infof(data, "Cipher selection: %s", ciphers);
}
- if(BACKEND->handle)
- SSL_free(BACKEND->handle);
- BACKEND->handle = SSL_new(BACKEND->ctx);
- if(!BACKEND->handle) {
+ if(backend->handle)
+ SSL_free(backend->handle);
+ backend->handle = SSL_new(backend->ctx);
+ if(!backend->handle) {
failf(data, "SSL: couldn't create a context (handle)!");
return CURLE_OUT_OF_MEMORY;
}
@@ -227,7 +225,7 @@ mesalink_connect_step1(struct Curl_easy *data,
#endif
) {
/* hostname is not a valid IP address */
- if(SSL_set_tlsext_host_name(BACKEND->handle, hostname) != SSL_SUCCESS) {
+ if(SSL_set_tlsext_host_name(backend->handle, hostname) != SSL_SUCCESS) {
failf(data,
"WARNING: failed to configure server name indication (SNI) "
"TLS extension\n");
@@ -244,7 +242,7 @@ mesalink_connect_step1(struct Curl_easy *data,
|| strncmp(hostname, "[::1]", 5) == 0
#endif
) {
- SSL_set_tlsext_host_name(BACKEND->handle, "localhost");
+ SSL_set_tlsext_host_name(backend->handle, "localhost");
}
else
#endif
@@ -264,12 +262,12 @@ mesalink_connect_step1(struct Curl_easy *data,
SSL_IS_PROXY() ? TRUE : FALSE,
&ssl_sessionid, NULL, sockindex)) {
/* we got a session id, use it! */
- if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
+ if(!SSL_set_session(backend->handle, ssl_sessionid)) {
Curl_ssl_sessionid_unlock(data);
failf(
data,
"SSL: SSL_set_session failed: %s",
- ERR_error_string(SSL_get_error(BACKEND->handle, 0), error_buffer));
+ ERR_error_string(SSL_get_error(backend->handle, 0), error_buffer));
return CURLE_SSL_CONNECT_ERROR;
}
/* Informational message */
@@ -279,7 +277,7 @@ mesalink_connect_step1(struct Curl_easy *data,
}
#endif /* MESALINK_HAVE_SESSION */
- if(SSL_set_fd(BACKEND->handle, (int)sockfd) != SSL_SUCCESS) {
+ if(SSL_set_fd(backend->handle, (int)sockfd) != SSL_SUCCESS) {
failf(data, "SSL: SSL_set_fd failed");
return CURLE_SSL_CONNECT_ERROR;
}
@@ -294,13 +292,14 @@ mesalink_connect_step2(struct Curl_easy *data,
{
int ret = -1;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
conn->recv[sockindex] = mesalink_recv;
conn->send[sockindex] = mesalink_send;
- ret = SSL_connect(BACKEND->handle);
+ ret = SSL_connect(backend->handle);
if(ret != SSL_SUCCESS) {
- int detail = SSL_get_error(BACKEND->handle, ret);
+ int detail = SSL_get_error(backend->handle, ret);
if(SSL_ERROR_WANT_CONNECT == detail || SSL_ERROR_WANT_READ == detail) {
connssl->connecting_state = ssl_connect_2_reading;
@@ -327,8 +326,8 @@ mesalink_connect_step2(struct Curl_easy *data,
connssl->connecting_state = ssl_connect_3;
infof(data,
"SSL connection using %s / %s",
- SSL_get_version(BACKEND->handle),
- SSL_get_cipher_name(BACKEND->handle));
+ SSL_get_version(backend->handle),
+ SSL_get_cipher_name(backend->handle));
return CURLE_OK;
}
@@ -347,8 +346,9 @@ mesalink_connect_step3(struct connectdata *conn, int sockindex)
SSL_SESSION *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
+ struct ssl_backend_data *backend = connssl->backend;
- our_ssl_sessionid = SSL_get_session(BACKEND->handle);
+ our_ssl_sessionid = SSL_get_session(backend->handle);
Curl_ssl_sessionid_lock(data);
incache =
@@ -387,12 +387,13 @@ mesalink_send(struct Curl_easy *data, int sockindex, const void *mem,
{
struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
char error_buffer[MESALINK_MAX_ERROR_SZ];
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
- int rc = SSL_write(BACKEND->handle, mem, memlen);
+ int rc = SSL_write(backend->handle, mem, memlen);
if(rc < 0) {
- int err = SSL_get_error(BACKEND->handle, rc);
+ int err = SSL_get_error(backend->handle, rc);
switch(err) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
@@ -415,17 +416,18 @@ static void
mesalink_close(struct Curl_easy *data, struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
(void) data;
- if(BACKEND->handle) {
- (void)SSL_shutdown(BACKEND->handle);
- SSL_free(BACKEND->handle);
- BACKEND->handle = NULL;
+ if(backend->handle) {
+ (void)SSL_shutdown(backend->handle);
+ SSL_free(backend->handle);
+ backend->handle = NULL;
}
- if(BACKEND->ctx) {
- SSL_CTX_free(BACKEND->ctx);
- BACKEND->ctx = NULL;
+ if(backend->ctx) {
+ SSL_CTX_free(backend->ctx);
+ backend->ctx = NULL;
}
}
@@ -435,12 +437,13 @@ mesalink_recv(struct Curl_easy *data, int num, char *buf, size_t buffersize,
{
struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[num];
+ struct ssl_backend_data *backend = connssl->backend;
char error_buffer[MESALINK_MAX_ERROR_SZ];
int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
- int nread = SSL_read(BACKEND->handle, buf, buffsize);
+ int nread = SSL_read(backend->handle, buf, buffsize);
if(nread <= 0) {
- int err = SSL_get_error(BACKEND->handle, nread);
+ int err = SSL_get_error(backend->handle, nread);
switch(err) {
case SSL_ERROR_ZERO_RETURN: /* no more data */
@@ -485,12 +488,13 @@ mesalink_shutdown(struct Curl_easy *data,
{
int retval = 0;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
(void) data;
- if(BACKEND->handle) {
- SSL_free(BACKEND->handle);
- BACKEND->handle = NULL;
+ if(backend->handle) {
+ SSL_free(backend->handle);
+ backend->handle = NULL;
}
return retval;
}
@@ -636,8 +640,9 @@ static void *
mesalink_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
+ struct ssl_backend_data *backend = connssl->backend;
(void)info;
- return BACKEND->handle;
+ return backend->handle;
}
const struct Curl_ssl Curl_ssl_mesalink = {
diff --git a/contrib/libs/curl/lib/vtls/nss.c b/contrib/libs/curl/lib/vtls/nss.c
index 1897b9ab1d5..2b44f051265 100644
--- a/contrib/libs/curl/lib/vtls/nss.c
+++ b/contrib/libs/curl/lib/vtls/nss.c
@@ -304,13 +304,14 @@ static char *nss_sslver_to_name(PRUint16 nssver)
}
}
-static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
- char *cipher_list)
+/* the longest cipher name this supports */
+#define MAX_CIPHER_LENGTH 128
+
+static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc *model,
+ const char *cipher_list)
{
unsigned int i;
- PRBool cipher_state[NUM_OF_CIPHERS];
- PRBool found;
- char *cipher;
+ const char *cipher;
/* use accessors to avoid dynamic linking issues after an update of NSS */
const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers();
@@ -326,51 +327,52 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE);
}
- /* Set every entry in our list to false */
- for(i = 0; i < NUM_OF_CIPHERS; i++) {
- cipher_state[i] = PR_FALSE;
- }
-
cipher = cipher_list;
- while(cipher_list && (cipher_list[0])) {
+ while(cipher && cipher[0]) {
+ const char *end;
+ char name[MAX_CIPHER_LENGTH + 1];
+ size_t len;
+ bool found = FALSE;
while((*cipher) && (ISSPACE(*cipher)))
++cipher;
- cipher_list = strpbrk(cipher, ":, ");
- if(cipher_list) {
- *cipher_list++ = '\0';
- }
-
- found = PR_FALSE;
-
- for(i = 0; i<NUM_OF_CIPHERS; i++) {
- if(strcasecompare(cipher, cipherlist[i].name)) {
- cipher_state[i] = PR_TRUE;
- found = PR_TRUE;
- break;
- }
- }
+ end = strpbrk(cipher, ":, ");
+ if(end)
+ len = end - cipher;
+ else
+ len = strlen(cipher);
- if(found == PR_FALSE) {
- failf(data, "Unknown cipher in list: %s", cipher);
+ if(len > MAX_CIPHER_LENGTH) {
+ failf(data, "Bad cipher list");
return SECFailure;
}
-
- if(cipher_list) {
- cipher = cipher_list;
+ else if(len) {
+ memcpy(name, cipher, len);
+ name[len] = 0;
+
+ for(i = 0; i<NUM_OF_CIPHERS; i++) {
+ if(strcasecompare(name, cipherlist[i].name)) {
+ /* Enable the selected cipher */
+ if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) !=
+ SECSuccess) {
+ failf(data, "cipher-suite not supported by NSS: %s", name);
+ return SECFailure;
+ }
+ found = TRUE;
+ break;
+ }
+ }
}
- }
- /* Finally actually enable the selected ciphers */
- for(i = 0; i<NUM_OF_CIPHERS; i++) {
- if(!cipher_state[i])
- continue;
-
- if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) != SECSuccess) {
- failf(data, "cipher-suite not supported by NSS: %s", cipherlist[i].name);
+ if(!found && len) {
+ failf(data, "Unknown cipher: %s", name);
return SECFailure;
}
+ if(end)
+ cipher = ++end;
+ else
+ break;
}
return SECSuccess;
@@ -782,7 +784,7 @@ static char *nss_get_password(PK11SlotInfo *slot, PRBool retry, void *arg)
{
(void)slot; /* unused */
- if(retry || NULL == arg)
+ if(retry || !arg)
return NULL;
else
return (char *)PORT_Strdup((char *)arg);
@@ -1168,7 +1170,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
struct SECKEYPrivateKeyStr *key;
PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname);
- if(NULL == slot) {
+ if(!slot) {
failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
return SECFailure;
}
@@ -1182,7 +1184,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
SECITEM_FreeItem(&cert_der, PR_FALSE);
- if(NULL == cert) {
+ if(!cert) {
failf(data, "NSS: client certificate from file not found");
PK11_FreeSlot(slot);
return SECFailure;
@@ -1190,7 +1192,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
PK11_FreeSlot(slot);
- if(NULL == key) {
+ if(!key) {
failf(data, "NSS: private key from file not found");
CERT_DestroyCertificate(cert);
return SECFailure;
@@ -1207,9 +1209,9 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
/* use the default NSS hook */
if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
pRetCert, pRetKey)
- || NULL == *pRetCert) {
+ || !*pRetCert) {
- if(NULL == nickname)
+ if(!nickname)
failf(data, "NSS: client certificate not found (nickname not "
"specified)");
else
@@ -1220,7 +1222,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
/* get certificate nickname if any */
nickname = (*pRetCert)->nickname;
- if(NULL == nickname)
+ if(!nickname)
nickname = "[unknown]";
if(!strncmp(nickname, pem_slotname, sizeof(pem_slotname) - 1U)) {
@@ -1229,7 +1231,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
return SECFailure;
}
- if(NULL == *pRetKey) {
+ if(!*pRetKey) {
failf(data, "NSS: private key not found for certificate: %s", nickname);
return SECFailure;
}
@@ -1344,7 +1346,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
PRErrorCode err;
const char *err_name;
- if(nss_context != NULL)
+ if(nss_context)
return CURLE_OK;
memset((void *) &initparams, '\0', sizeof(initparams));
@@ -1360,7 +1362,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
free(certpath);
- if(nss_context != NULL)
+ if(nss_context)
return CURLE_OK;
err = PR_GetError();
@@ -1372,7 +1374,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
| NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
| NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
- if(nss_context != NULL)
+ if(nss_context)
return CURLE_OK;
err = PR_GetError();
diff --git a/contrib/libs/curl/lib/vtls/openssl.c b/contrib/libs/curl/lib/vtls/openssl.c
index a1baef9c3f1..8c0f946dd51 100644
--- a/contrib/libs/curl/lib/vtls/openssl.c
+++ b/contrib/libs/curl/lib/vtls/openssl.c
@@ -171,6 +171,21 @@
#define OPENSSL_load_builtin_modules(x)
#endif
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+#define HAVE_EVP_PKEY_GET_PARAMS 1
+#else
+#define SSL_get1_peer_certificate SSL_get_peer_certificate
+#endif
+
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+#error #include <openssl/core_names.h>
+#define DECLARE_PKEY_PARAM_BIGNUM(name) BIGNUM *name = NULL
+#define FREE_PKEY_PARAM_BIGNUM(name) BN_clear_free(name)
+#else
+#define DECLARE_PKEY_PARAM_BIGNUM(name) const BIGNUM *name
+#define FREE_PKEY_PARAM_BIGNUM(name)
+#endif
+
/*
* Whether SSL_CTX_set_keylog_callback is available.
* OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287
@@ -231,6 +246,13 @@
#define HAVE_RANDOM_INIT_BY_DEFAULT 1
#endif
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+ !(defined(LIBRESSL_VERSION_NUMBER) && \
+ LIBRESSL_VERSION_NUMBER < 0x2070100fL) && \
+ !defined(OPENSSL_IS_BORINGSSL)
+#define HAVE_OPENSSL_VERSION
+#endif
+
struct ssl_backend_data {
struct Curl_easy *logger; /* transfer handle to pass trace logs to, only
using sockindex 0 */
@@ -1099,7 +1121,8 @@ int cert_stuff(struct Curl_easy *data,
EVP_PKEY_free(pktmp);
}
-#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL)
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL) && \
+ !defined(OPENSSL_NO_DEPRECATED_3_0)
{
/* If RSA is used, don't check the private key if its flags indicate
* it doesn't support it. */
@@ -1412,6 +1435,12 @@ static void ossl_closeone(struct Curl_easy *data,
if(backend->handle) {
char buf[32];
set_logger(conn, data);
+ /*
+ * The conn->sock[0] socket is passed to openssl with SSL_set_fd(). Make
+ * sure the socket is not closed before calling OpenSSL functions that
+ * will use it.
+ */
+ DEBUGASSERT(conn->sock[FIRSTSOCKET] != CURL_SOCKET_BAD);
/* Maybe the server has already sent a close notify alert.
Read it to avoid an RST on the TCP connection. */
@@ -1650,9 +1679,10 @@ static bool subj_alt_hostcheck(struct Curl_easy *data,
hostname. In this case, the iPAddress subjectAltName must be present
in the certificate and must exactly match the IP in the URI.
+ This function is now used from ngtcp2 (QUIC) as well.
*/
-static CURLcode verifyhost(struct Curl_easy *data, struct connectdata *conn,
- X509 *server_cert)
+CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
+ X509 *server_cert)
{
bool matched = FALSE;
int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
@@ -1937,7 +1967,7 @@ static CURLcode verifystatus(struct Curl_easy *data,
}
/* Compute the certificate's ID */
- cert = SSL_get_peer_certificate(backend->handle);
+ cert = SSL_get1_peer_certificate(backend->handle);
if(!cert) {
failf(data, "Error getting peer certificate");
result = CURLE_SSL_INVALIDCERTSTATUS;
@@ -3466,10 +3496,7 @@ static void pubkey_show(struct Curl_easy *data,
int num,
const char *type,
const char *name,
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
- const
-#endif
- BIGNUM *bn)
+ const BIGNUM *bn)
{
char *ptr;
char namebuf[32];
@@ -3534,12 +3561,6 @@ typedef size_t numcert_t;
typedef int numcert_t;
#endif
-#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
-#define OSSL3_CONST const
-#else
-#define OSSL3_CONST
-#endif
-
static CURLcode get_cert_chain(struct Curl_easy *data,
struct ssl_connect_data *connssl)
{
@@ -3563,6 +3584,9 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
}
mem = BIO_new(BIO_s_mem());
+ if(!mem) {
+ return CURLE_OUT_OF_MEMORY;
+ }
for(i = 0; i < (int)numcerts; i++) {
ASN1_INTEGER *num;
@@ -3647,92 +3671,115 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
switch(pktype) {
case EVP_PKEY_RSA:
{
- OSSL3_CONST RSA *rsa;
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ RSA *rsa;
#ifdef HAVE_OPAQUE_EVP_PKEY
rsa = EVP_PKEY_get0_RSA(pubkey);
#else
rsa = pubkey->pkey.rsa;
-#endif
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
{
- const BIGNUM *n;
- const BIGNUM *e;
-
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(n);
+ DECLARE_PKEY_PARAM_BIGNUM(e);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e);
+#else
RSA_get0_key(rsa, &n, &e, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
BIO_printf(mem, "%d", BN_num_bits(n));
+#else
+ BIO_printf(mem, "%d", BN_num_bits(rsa->n));
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
push_certinfo("RSA Public Key", i);
print_pubkey_BN(rsa, n, i);
print_pubkey_BN(rsa, e, i);
+ FREE_PKEY_PARAM_BIGNUM(n);
+ FREE_PKEY_PARAM_BIGNUM(e);
}
-#else
- BIO_printf(mem, "%d", BN_num_bits(rsa->n));
- push_certinfo("RSA Public Key", i);
- print_pubkey_BN(rsa, n, i);
- print_pubkey_BN(rsa, e, i);
-#endif
break;
}
case EVP_PKEY_DSA:
{
#ifndef OPENSSL_NO_DSA
- OSSL3_CONST DSA *dsa;
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ DSA *dsa;
#ifdef HAVE_OPAQUE_EVP_PKEY
dsa = EVP_PKEY_get0_DSA(pubkey);
#else
dsa = pubkey->pkey.dsa;
-#endif
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
{
- const BIGNUM *p;
- const BIGNUM *q;
- const BIGNUM *g;
- const BIGNUM *pub_key;
-
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(p);
+ DECLARE_PKEY_PARAM_BIGNUM(q);
+ DECLARE_PKEY_PARAM_BIGNUM(g);
+ DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
DSA_get0_pqg(dsa, &p, &q, &g);
DSA_get0_key(dsa, &pub_key, NULL);
-
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
print_pubkey_BN(dsa, p, i);
print_pubkey_BN(dsa, q, i);
print_pubkey_BN(dsa, g, i);
print_pubkey_BN(dsa, pub_key, i);
+ FREE_PKEY_PARAM_BIGNUM(p);
+ FREE_PKEY_PARAM_BIGNUM(q);
+ FREE_PKEY_PARAM_BIGNUM(g);
+ FREE_PKEY_PARAM_BIGNUM(pub_key);
}
-#else
- print_pubkey_BN(dsa, p, i);
- print_pubkey_BN(dsa, q, i);
- print_pubkey_BN(dsa, g, i);
- print_pubkey_BN(dsa, pub_key, i);
-#endif
#endif /* !OPENSSL_NO_DSA */
break;
}
case EVP_PKEY_DH:
{
- OSSL3_CONST DH *dh;
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ DH *dh;
#ifdef HAVE_OPAQUE_EVP_PKEY
dh = EVP_PKEY_get0_DH(pubkey);
#else
dh = pubkey->pkey.dh;
-#endif
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
{
- const BIGNUM *p;
- const BIGNUM *q;
- const BIGNUM *g;
- const BIGNUM *pub_key;
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(p);
+ DECLARE_PKEY_PARAM_BIGNUM(q);
+ DECLARE_PKEY_PARAM_BIGNUM(g);
+ DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
DH_get0_pqg(dh, &p, &q, &g);
DH_get0_key(dh, &pub_key, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
print_pubkey_BN(dh, p, i);
print_pubkey_BN(dh, q, i);
print_pubkey_BN(dh, g, i);
+#else
+ print_pubkey_BN(dh, p, i);
+ print_pubkey_BN(dh, g, i);
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
print_pubkey_BN(dh, pub_key, i);
+ FREE_PKEY_PARAM_BIGNUM(p);
+ FREE_PKEY_PARAM_BIGNUM(q);
+ FREE_PKEY_PARAM_BIGNUM(g);
+ FREE_PKEY_PARAM_BIGNUM(pub_key);
}
-#else
- print_pubkey_BN(dh, p, i);
- print_pubkey_BN(dh, g, i);
- print_pubkey_BN(dh, pub_key, i);
-#endif
break;
}
}
@@ -3836,11 +3883,20 @@ static CURLcode servercert(struct Curl_easy *data,
BIO *mem = BIO_new(BIO_s_mem());
struct ssl_backend_data *backend = connssl->backend;
+ if(!mem) {
+ failf(data,
+ "BIO_new return NULL, " OSSL_PACKAGE
+ " error %s",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)) );
+ return CURLE_OUT_OF_MEMORY;
+ }
+
if(data->set.ssl.certinfo)
/* we've been asked to gather certificate info! */
(void)get_cert_chain(data, connssl);
- backend->server_cert = SSL_get_peer_certificate(backend->handle);
+ backend->server_cert = SSL_get1_peer_certificate(backend->handle);
if(!backend->server_cert) {
BIO_free(mem);
if(!strict)
@@ -3874,7 +3930,7 @@ static CURLcode servercert(struct Curl_easy *data,
BIO_free(mem);
if(SSL_CONN_CONFIG(verifyhost)) {
- result = verifyhost(data, conn, backend->server_cert);
+ result = Curl_ossl_verifyhost(data, conn, backend->server_cert);
if(result) {
X509_free(backend->server_cert);
backend->server_cert = NULL;
@@ -4354,13 +4410,7 @@ static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
static size_t ossl_version(char *buffer, size_t size)
{
#ifdef LIBRESSL_VERSION_NUMBER
-#if LIBRESSL_VERSION_NUMBER < 0x2070100fL
- return msnprintf(buffer, size, "%s/%lx.%lx.%lx",
- OSSL_PACKAGE,
- (LIBRESSL_VERSION_NUMBER>>28)&0xf,
- (LIBRESSL_VERSION_NUMBER>>20)&0xff,
- (LIBRESSL_VERSION_NUMBER>>12)&0xff);
-#else /* OpenSSL_version() first appeared in LibreSSL 2.7.1 */
+#ifdef HAVE_OPENSSL_VERSION
char *p;
int count;
const char *ver = OpenSSL_version(OPENSSL_VERSION);
@@ -4374,6 +4424,12 @@ static size_t ossl_version(char *buffer, size_t size)
*p = '_';
}
return count;
+#else
+ return msnprintf(buffer, size, "%s/%lx.%lx.%lx",
+ OSSL_PACKAGE,
+ (LIBRESSL_VERSION_NUMBER>>28)&0xf,
+ (LIBRESSL_VERSION_NUMBER>>20)&0xff,
+ (LIBRESSL_VERSION_NUMBER>>12)&0xff);
#endif
#elif defined(OPENSSL_IS_BORINGSSL)
return msnprintf(buffer, size, OSSL_PACKAGE);
diff --git a/contrib/libs/curl/lib/vtls/openssl.h b/contrib/libs/curl/lib/vtls/openssl.h
index 2f6e1b2db8e..28058453c0b 100644
--- a/contrib/libs/curl/lib/vtls/openssl.h
+++ b/contrib/libs/curl/lib/vtls/openssl.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -26,11 +26,15 @@
#ifdef USE_OPENSSL
/*
- * This header should only be needed to get included by vtls.c and openssl.c
+ * This header should only be needed to get included by vtls.c, openssl.c
+ * and ngtcp2.c
*/
+#include <openssl/x509v3.h>
#include "urldata.h"
+CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
+ X509 *server_cert);
extern const struct Curl_ssl Curl_ssl_openssl;
#endif /* USE_OPENSSL */
diff --git a/contrib/libs/curl/lib/vtls/rustls.c b/contrib/libs/curl/lib/vtls/rustls.c
index 29bb4259a44..6dbb1ef3cd7 100644
--- a/contrib/libs/curl/lib/vtls/rustls.c
+++ b/contrib/libs/curl/lib/vtls/rustls.c
@@ -27,7 +27,7 @@
#include "curl_printf.h"
#include <errno.h>
-#error #include <crustls.h>
+#include <rustls.h>
#include "inet_pton.h"
#include "urldata.h"
@@ -138,11 +138,6 @@ cr_recv(struct Curl_easy *data, int sockindex,
*err = CURLE_READ_ERROR;
return -1;
}
- else if(tls_bytes_read == 0) {
- failf(data, "connection closed without TLS close_notify alert");
- *err = CURLE_READ_ERROR;
- return -1;
- }
infof(data, "cr_recv read %ld bytes from the network", tls_bytes_read);
@@ -161,22 +156,21 @@ cr_recv(struct Curl_easy *data, int sockindex,
(uint8_t *)plainbuf + plain_bytes_copied,
plainlen - plain_bytes_copied,
&n);
- if(rresult == RUSTLS_RESULT_ALERT_CLOSE_NOTIFY) {
- *err = CURLE_OK;
- return 0;
+ if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) {
+ infof(data, "cr_recv got PLAINTEXT_EMPTY. will try again later.");
+ backend->data_pending = FALSE;
+ break;
}
else if(rresult != RUSTLS_RESULT_OK) {
- failf(data, "error in rustls_connection_read");
+ /* n always equals 0 in this case, don't need to check it */
+ failf(data, "error in rustls_connection_read: %d", rresult);
*err = CURLE_READ_ERROR;
return -1;
}
else if(n == 0) {
- /* rustls returns 0 from connection_read to mean "all currently
- available data has been read." If we bring in more ciphertext with
- read_tls, more plaintext will become available. So don't tell curl
- this is an EOF. Instead, say "come back later." */
- infof(data, "cr_recv got 0 bytes of plaintext");
- backend->data_pending = FALSE;
+ /* n == 0 indicates clean EOF, but we may have read some other
+ plaintext bytes before we reached this. Break out of the loop
+ so we can figure out whether to return success or EOF. */
break;
}
else {
@@ -185,15 +179,23 @@ cr_recv(struct Curl_easy *data, int sockindex,
}
}
- /* If we wrote out 0 plaintext bytes, it might just mean we haven't yet
- read a full TLS record. Return CURLE_AGAIN so curl doesn't treat this
- as EOF. */
- if(plain_bytes_copied == 0) {
+ if(plain_bytes_copied) {
+ *err = CURLE_OK;
+ return plain_bytes_copied;
+ }
+
+ /* If we wrote out 0 plaintext bytes, that means either we hit a clean EOF,
+ OR we got a RUSTLS_RESULT_PLAINTEXT_EMPTY.
+ If the latter, return CURLE_AGAIN so curl doesn't treat this as EOF. */
+ if(!backend->data_pending) {
*err = CURLE_AGAIN;
return -1;
}
- return plain_bytes_copied;
+ /* Zero bytes read, and no RUSTLS_RESULT_PLAINTEXT_EMPTY, means the TCP
+ connection was cleanly closed (with a close_notify alert). */
+ *err = CURLE_OK;
+ return 0;
}
/*
@@ -309,10 +311,10 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
config_builder = rustls_client_config_builder_new();
#ifdef USE_HTTP2
infof(data, "offering ALPN for HTTP/1.1 and HTTP/2");
- rustls_client_config_builder_set_protocols(config_builder, alpn, 2);
+ rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 2);
#else
infof(data, "offering ALPN for HTTP/1.1 only");
- rustls_client_config_builder_set_protocols(config_builder, alpn, 1);
+ rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 1);
#endif
if(!verifypeer) {
rustls_client_config_builder_dangerous_set_certificate_verifier(
@@ -358,7 +360,7 @@ cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn,
size_t len = 0;
rustls_connection_get_alpn_protocol(rconn, &protocol, &len);
- if(NULL == protocol) {
+ if(!protocol) {
infof(data, "ALPN, server did not agree to a protocol");
return;
}
@@ -414,9 +416,6 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
/*
* Connection has been established according to rustls. Set send/recv
* handlers, and update the state machine.
- * This check has to come last because is_handshaking starts out false,
- * then becomes true when we first write data, then becomes false again
- * once the handshake is done.
*/
if(!rustls_connection_is_handshaking(rconn)) {
infof(data, "Done handshaking");
@@ -543,6 +542,12 @@ cr_close(struct Curl_easy *data, struct connectdata *conn,
}
}
+static size_t cr_version(char *buffer, size_t size)
+{
+ struct rustls_str ver = rustls_version();
+ return msnprintf(buffer, size, "%.*s", (int)ver.len, ver.data);
+}
+
const struct Curl_ssl Curl_ssl_rustls = {
{ CURLSSLBACKEND_RUSTLS, "rustls" },
SSLSUPP_TLS13_CIPHERSUITES, /* supports */
@@ -550,7 +555,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
Curl_none_init, /* init */
Curl_none_cleanup, /* cleanup */
- rustls_version, /* version */
+ cr_version, /* version */
Curl_none_check_cxn, /* check_cxn */
Curl_none_shutdown, /* shutdown */
cr_data_pending, /* data_pending */
diff --git a/contrib/libs/curl/lib/vtls/schannel.c b/contrib/libs/curl/lib/vtls/schannel.c
index 44c59e7796b..0a8e60610d8 100644
--- a/contrib/libs/curl/lib/vtls/schannel.c
+++ b/contrib/libs/curl/lib/vtls/schannel.c
@@ -147,8 +147,6 @@
#define ALG_CLASS_DHASH ALG_CLASS_HASH
#endif
-#define BACKEND connssl->backend
-
static Curl_recv schannel_recv;
static Curl_send schannel_send;
@@ -423,6 +421,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
PCCERT_CONTEXT client_certs[1] = { NULL };
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
+ struct ssl_backend_data *backend = connssl->backend;
/* setup Schannel API options */
memset(&schannel_cred, 0, sizeof(schannel_cred));
@@ -430,7 +429,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
if(conn->ssl_config.verifypeer) {
#ifdef HAS_MANUAL_VERIFY_API
- if(BACKEND->use_manual_cred_validation)
+ if(backend->use_manual_cred_validation)
schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION;
else
#endif
@@ -503,7 +502,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
if(SSL_CONN_CONFIG(cipher_list)) {
result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list),
- BACKEND->algIds);
+ backend->algIds);
if(CURLE_OK != result) {
failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
return result;
@@ -600,7 +599,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
datablob.pbData = (BYTE*)certdata;
datablob.cbData = (DWORD)certsize;
- if(data->set.ssl.key_passwd != NULL)
+ if(data->set.ssl.key_passwd)
pwd_len = strlen(data->set.ssl.key_passwd);
pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1));
if(pszPassword) {
@@ -704,9 +703,9 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
#endif
/* allocate memory for the re-usable credential handle */
- BACKEND->cred = (struct Curl_schannel_cred *)
+ backend->cred = (struct Curl_schannel_cred *)
calloc(1, sizeof(struct Curl_schannel_cred));
- if(!BACKEND->cred) {
+ if(!backend->cred) {
failf(data, "schannel: unable to allocate memory");
if(client_certs[0])
@@ -714,14 +713,14 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
- BACKEND->cred->refcount = 1;
+ backend->cred->refcount = 1;
sspi_status =
s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
SECPKG_CRED_OUTBOUND, NULL,
&schannel_cred, NULL, NULL,
- &BACKEND->cred->cred_handle,
- &BACKEND->cred->time_stamp);
+ &backend->cred->cred_handle,
+ &backend->cred->time_stamp);
if(client_certs[0])
CertFreeCertificateContext(client_certs[0]);
@@ -730,7 +729,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
char buffer[STRERROR_LEN];
failf(data, "schannel: AcquireCredentialsHandle failed: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
- Curl_safefree(BACKEND->cred);
+ Curl_safefree(backend->cred);
switch(sspi_status) {
case SEC_E_INSUFFICIENT_MEMORY:
return CURLE_OUT_OF_MEMORY;
@@ -769,12 +768,13 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
TCHAR *host_name;
CURLcode result;
char * const hostname = SSL_HOST_NAME();
+ struct ssl_backend_data *backend = connssl->backend;
DEBUGF(infof(data,
"schannel: SSL/TLS connection with %s port %hu (step 1/3)",
hostname, conn->remote_port));
- if(curlx_verify_windows_version(5, 1, PLATFORM_WINNT,
+ if(curlx_verify_windows_version(5, 1, 0, PLATFORM_WINNT,
VERSION_LESS_THAN_EQUAL)) {
/* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
algorithms that may not be supported by all servers. */
@@ -785,29 +785,29 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#ifdef HAS_ALPN
/* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
Also it doesn't seem to be supported for Wine, see curl bug #983. */
- BACKEND->use_alpn = conn->bits.tls_enable_alpn &&
+ backend->use_alpn = conn->bits.tls_enable_alpn &&
!GetProcAddress(GetModuleHandle(TEXT("ntdll")),
"wine_get_version") &&
- curlx_verify_windows_version(6, 3, PLATFORM_WINNT,
+ curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL);
#else
- BACKEND->use_alpn = false;
+ backend->use_alpn = false;
#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;
+ 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) || SSL_CONN_CONFIG(ca_info_blob)) {
- if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT,
+ if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
- BACKEND->use_manual_cred_validation = true;
+ backend->use_manual_cred_validation = true;
}
else {
failf(data, "schannel: this version of Windows is too old to support "
@@ -816,7 +816,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
}
else
- BACKEND->use_manual_cred_validation = false;
+ backend->use_manual_cred_validation = false;
#else
if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) {
failf(data, "schannel: CA cert support not built in");
@@ -825,7 +825,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif
#endif
- BACKEND->cred = NULL;
+ backend->cred = NULL;
/* check for an existing re-usable credential handle */
if(SSL_SET_OPTION(primary.sessionid)) {
@@ -833,19 +833,19 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
if(!Curl_ssl_getsessionid(data, conn,
SSL_IS_PROXY() ? TRUE : FALSE,
(void **)&old_cred, NULL, sockindex)) {
- BACKEND->cred = old_cred;
+ backend->cred = old_cred;
DEBUGF(infof(data, "schannel: re-using existing credential handle"));
/* increment the reference counter of the credential/session handle */
- BACKEND->cred->refcount++;
+ backend->cred->refcount++;
DEBUGF(infof(data,
"schannel: incremented credential handle refcount = %d",
- BACKEND->cred->refcount));
+ backend->cred->refcount));
}
Curl_ssl_sessionid_unlock(data);
}
- if(!BACKEND->cred) {
+ if(!backend->cred) {
result = schannel_acquire_credential_handle(data, conn, sockindex);
if(result != CURLE_OK) {
return result;
@@ -862,7 +862,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
#ifdef HAS_ALPN
- if(BACKEND->use_alpn) {
+ if(backend->use_alpn) {
int cur = 0;
int list_start_index = 0;
unsigned int *extension_len = NULL;
@@ -920,18 +920,18 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
/* security request flags */
- BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
+ backend->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_STREAM;
if(!SSL_SET_OPTION(auto_client_cert)) {
- BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+ backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
}
/* allocate memory for the security context handle */
- BACKEND->ctxt = (struct Curl_schannel_ctxt *)
+ backend->ctxt = (struct Curl_schannel_ctxt *)
calloc(1, sizeof(struct Curl_schannel_ctxt));
- if(!BACKEND->ctxt) {
+ if(!backend->ctxt) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
@@ -948,16 +948,16 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
us problems with inbuf regardless. https://github.com/curl/curl/issues/983
*/
sspi_status = s_pSecFn->InitializeSecurityContext(
- &BACKEND->cred->cred_handle, NULL, host_name, BACKEND->req_flags, 0, 0,
- (BACKEND->use_alpn ? &inbuf_desc : NULL),
- 0, &BACKEND->ctxt->ctxt_handle,
- &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
+ &backend->cred->cred_handle, NULL, host_name, backend->req_flags, 0, 0,
+ (backend->use_alpn ? &inbuf_desc : NULL),
+ 0, &backend->ctxt->ctxt_handle,
+ &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp);
curlx_unicodefree(host_name);
if(sspi_status != SEC_I_CONTINUE_NEEDED) {
char buffer[STRERROR_LEN];
- Curl_safefree(BACKEND->ctxt);
+ Curl_safefree(backend->ctxt);
switch(sspi_status) {
case SEC_E_INSUFFICIENT_MEMORY:
failf(data, "schannel: initial InitializeSecurityContext failed: %s",
@@ -1001,10 +1001,10 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
DEBUGF(infof(data, "schannel: sent initial handshake data: "
"sent %zd bytes", written));
- BACKEND->recv_unrecoverable_err = CURLE_OK;
- BACKEND->recv_sspi_close_notify = false;
- BACKEND->recv_connection_closed = false;
- BACKEND->encdata_is_incomplete = false;
+ backend->recv_unrecoverable_err = CURLE_OK;
+ backend->recv_sspi_close_notify = false;
+ backend->recv_connection_closed = false;
+ backend->encdata_is_incomplete = false;
/* continue to second handshake step */
connssl->connecting_state = ssl_connect_2;
@@ -1029,6 +1029,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
bool doread;
char * const hostname = SSL_HOST_NAME();
const char *pubkey_ptr;
+ struct ssl_backend_data *backend = connssl->backend;
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
@@ -1036,39 +1037,39 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
"schannel: SSL/TLS connection with %s port %hu (step 2/3)",
hostname, conn->remote_port));
- if(!BACKEND->cred || !BACKEND->ctxt)
+ if(!backend->cred || !backend->ctxt)
return CURLE_SSL_CONNECT_ERROR;
/* buffer to store previously received and decrypted data */
- if(!BACKEND->decdata_buffer) {
- BACKEND->decdata_offset = 0;
- BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
- BACKEND->decdata_buffer = malloc(BACKEND->decdata_length);
- if(!BACKEND->decdata_buffer) {
+ if(!backend->decdata_buffer) {
+ backend->decdata_offset = 0;
+ backend->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+ backend->decdata_buffer = malloc(backend->decdata_length);
+ if(!backend->decdata_buffer) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
}
/* buffer to store previously received and encrypted data */
- if(!BACKEND->encdata_buffer) {
- BACKEND->encdata_is_incomplete = false;
- BACKEND->encdata_offset = 0;
- BACKEND->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
- BACKEND->encdata_buffer = malloc(BACKEND->encdata_length);
- if(!BACKEND->encdata_buffer) {
+ if(!backend->encdata_buffer) {
+ backend->encdata_is_incomplete = false;
+ backend->encdata_offset = 0;
+ backend->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+ backend->encdata_buffer = malloc(backend->encdata_length);
+ if(!backend->encdata_buffer) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
}
/* if we need a bigger buffer to read a full message, increase buffer now */
- if(BACKEND->encdata_length - BACKEND->encdata_offset <
+ if(backend->encdata_length - backend->encdata_offset <
CURL_SCHANNEL_BUFFER_FREE_SIZE) {
/* increase internal encrypted data buffer */
- size_t reallocated_length = BACKEND->encdata_offset +
+ size_t reallocated_length = backend->encdata_offset +
CURL_SCHANNEL_BUFFER_FREE_SIZE;
- reallocated_buffer = realloc(BACKEND->encdata_buffer,
+ reallocated_buffer = realloc(backend->encdata_buffer,
reallocated_length);
if(!reallocated_buffer) {
@@ -1076,8 +1077,8 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
}
else {
- BACKEND->encdata_buffer = reallocated_buffer;
- BACKEND->encdata_length = reallocated_length;
+ backend->encdata_buffer = reallocated_buffer;
+ backend->encdata_length = reallocated_length;
}
}
@@ -1086,10 +1087,10 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
if(doread) {
/* read encrypted handshake data from socket */
result = Curl_read_plain(conn->sock[sockindex],
- (char *) (BACKEND->encdata_buffer +
- BACKEND->encdata_offset),
- BACKEND->encdata_length -
- BACKEND->encdata_offset,
+ (char *) (backend->encdata_buffer +
+ backend->encdata_offset),
+ backend->encdata_length -
+ backend->encdata_offset,
&nread);
if(result == CURLE_AGAIN) {
if(connssl->connecting_state != ssl_connect_2_writing)
@@ -1105,18 +1106,18 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
/* increase encrypted data buffer offset */
- BACKEND->encdata_offset += nread;
- BACKEND->encdata_is_incomplete = false;
+ backend->encdata_offset += nread;
+ backend->encdata_is_incomplete = false;
DEBUGF(infof(data, "schannel: encrypted data got %zd", nread));
}
DEBUGF(infof(data,
"schannel: encrypted data buffer: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
/* setup input buffers */
- InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset),
- curlx_uztoul(BACKEND->encdata_offset));
+ InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(backend->encdata_offset),
+ curlx_uztoul(backend->encdata_offset));
InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&inbuf_desc, inbuf, 2);
@@ -1132,17 +1133,17 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
/* copy received handshake data into input buffer */
- memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer,
- BACKEND->encdata_offset);
+ memcpy(inbuf[0].pvBuffer, backend->encdata_buffer,
+ backend->encdata_offset);
host_name = curlx_convert_UTF8_to_tchar(hostname);
if(!host_name)
return CURLE_OUT_OF_MEMORY;
sspi_status = s_pSecFn->InitializeSecurityContext(
- &BACKEND->cred->cred_handle, &BACKEND->ctxt->ctxt_handle,
- host_name, BACKEND->req_flags, 0, 0, &inbuf_desc, 0, NULL,
- &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
+ &backend->cred->cred_handle, &backend->ctxt->ctxt_handle,
+ host_name, backend->req_flags, 0, 0, &inbuf_desc, 0, NULL,
+ &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp);
curlx_unicodefree(host_name);
@@ -1151,7 +1152,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* check if the handshake was incomplete */
if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
- BACKEND->encdata_is_incomplete = true;
+ backend->encdata_is_incomplete = true;
connssl->connecting_state = ssl_connect_2_reading;
DEBUGF(infof(data,
"schannel: received incomplete message, need more data"));
@@ -1162,8 +1163,8 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
the handshake without one. This will allow connections to servers which
request a client certificate but do not require it. */
if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
- !(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
- BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+ !(backend->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
+ backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
connssl->connecting_state = ssl_connect_2_writing;
DEBUGF(infof(data,
"schannel: a client certificate has been requested"));
@@ -1191,7 +1192,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
/* free obsolete buffer */
- if(outbuf[i].pvBuffer != NULL) {
+ if(outbuf[i].pvBuffer) {
s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer);
}
}
@@ -1245,11 +1246,11 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
*/
/* check if the remaining data is less than the total amount
and therefore begins after the already processed data */
- if(BACKEND->encdata_offset > inbuf[1].cbBuffer) {
- memmove(BACKEND->encdata_buffer,
- (BACKEND->encdata_buffer + BACKEND->encdata_offset) -
+ if(backend->encdata_offset > inbuf[1].cbBuffer) {
+ memmove(backend->encdata_buffer,
+ (backend->encdata_buffer + backend->encdata_offset) -
inbuf[1].cbBuffer, inbuf[1].cbBuffer);
- BACKEND->encdata_offset = inbuf[1].cbBuffer;
+ backend->encdata_offset = inbuf[1].cbBuffer;
if(sspi_status == SEC_I_CONTINUE_NEEDED) {
doread = FALSE;
continue;
@@ -1257,7 +1258,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
}
else {
- BACKEND->encdata_offset = 0;
+ backend->encdata_offset = 0;
}
break;
}
@@ -1284,7 +1285,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
#ifdef HAS_MANUAL_VERIFY_API
- if(conn->ssl_config.verifypeer && BACKEND->use_manual_cred_validation) {
+ if(conn->ssl_config.verifypeer && backend->use_manual_cred_validation) {
return Curl_verify_certificate(data, conn, sockindex);
}
#endif
@@ -1366,6 +1367,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
#ifdef HAS_ALPN
SecPkgContext_ApplicationProtocol alpn_result;
#endif
+ struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -1373,28 +1375,28 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
"schannel: SSL/TLS connection with %s port %hu (step 3/3)",
hostname, conn->remote_port));
- if(!BACKEND->cred)
+ if(!backend->cred)
return CURLE_SSL_CONNECT_ERROR;
/* check if the required context attributes are met */
- if(BACKEND->ret_flags != BACKEND->req_flags) {
- if(!(BACKEND->ret_flags & ISC_RET_SEQUENCE_DETECT))
+ if(backend->ret_flags != backend->req_flags) {
+ if(!(backend->ret_flags & ISC_RET_SEQUENCE_DETECT))
failf(data, "schannel: failed to setup sequence detection");
- if(!(BACKEND->ret_flags & ISC_RET_REPLAY_DETECT))
+ if(!(backend->ret_flags & ISC_RET_REPLAY_DETECT))
failf(data, "schannel: failed to setup replay detection");
- if(!(BACKEND->ret_flags & ISC_RET_CONFIDENTIALITY))
+ if(!(backend->ret_flags & ISC_RET_CONFIDENTIALITY))
failf(data, "schannel: failed to setup confidentiality");
- if(!(BACKEND->ret_flags & ISC_RET_ALLOCATED_MEMORY))
+ if(!(backend->ret_flags & ISC_RET_ALLOCATED_MEMORY))
failf(data, "schannel: failed to setup memory allocation");
- if(!(BACKEND->ret_flags & ISC_RET_STREAM))
+ if(!(backend->ret_flags & ISC_RET_STREAM))
failf(data, "schannel: failed to setup stream orientation");
return CURLE_SSL_CONNECT_ERROR;
}
#ifdef HAS_ALPN
- if(BACKEND->use_alpn) {
+ if(backend->use_alpn) {
sspi_status =
- s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
SECPKG_ATTR_APPLICATION_PROTOCOL,
&alpn_result);
@@ -1439,7 +1441,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
incache = !(Curl_ssl_getsessionid(data, conn, isproxy, (void **)&old_cred,
NULL, sockindex));
if(incache) {
- if(old_cred != BACKEND->cred) {
+ if(old_cred != backend->cred) {
DEBUGF(infof(data,
"schannel: old credential handle is stale, removing"));
/* we're not taking old_cred ownership here, no refcount++ is needed */
@@ -1448,7 +1450,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
}
if(!incache) {
- result = Curl_ssl_addsessionid(data, conn, isproxy, BACKEND->cred,
+ result = Curl_ssl_addsessionid(data, conn, isproxy, backend->cred,
sizeof(struct Curl_schannel_cred),
sockindex, &added);
if(result) {
@@ -1458,7 +1460,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
else if(added) {
/* this cred session is now also referenced by sessionid cache */
- BACKEND->cred->refcount++;
+ backend->cred->refcount++;
DEBUGF(infof(data,
"schannel: stored credential handle in session cache"));
}
@@ -1469,7 +1471,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
if(data->set.ssl.certinfo) {
int certs_count = 0;
sspi_status =
- s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&ccert_context);
@@ -1606,7 +1608,10 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
* binding to pass the IIS extended protection checks.
* Available on Windows 7 or later.
*/
- conn->sslContext = &BACKEND->ctxt->ctxt_handle;
+ {
+ struct ssl_backend_data *backend = connssl->backend;
+ conn->sslContext = &backend->ctxt->ctxt_handle;
+ }
#endif
*done = TRUE;
@@ -1633,13 +1638,14 @@ schannel_send(struct Curl_easy *data, int sockindex,
SecBufferDesc outbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
+ struct ssl_backend_data *backend = connssl->backend;
/* check if the maximum stream sizes were queried */
- if(BACKEND->stream_sizes.cbMaximumMessage == 0) {
+ if(backend->stream_sizes.cbMaximumMessage == 0) {
sspi_status = s_pSecFn->QueryContextAttributes(
- &BACKEND->ctxt->ctxt_handle,
+ &backend->ctxt->ctxt_handle,
SECPKG_ATTR_STREAM_SIZES,
- &BACKEND->stream_sizes);
+ &backend->stream_sizes);
if(sspi_status != SEC_E_OK) {
*err = CURLE_SEND_ERROR;
return -1;
@@ -1647,13 +1653,13 @@ schannel_send(struct Curl_easy *data, int sockindex,
}
/* check if the buffer is longer than the maximum message length */
- if(len > BACKEND->stream_sizes.cbMaximumMessage) {
- len = BACKEND->stream_sizes.cbMaximumMessage;
+ if(len > backend->stream_sizes.cbMaximumMessage) {
+ len = backend->stream_sizes.cbMaximumMessage;
}
/* calculate the complete message length and allocate a buffer for it */
- data_len = BACKEND->stream_sizes.cbHeader + len +
- BACKEND->stream_sizes.cbTrailer;
+ data_len = backend->stream_sizes.cbHeader + len +
+ backend->stream_sizes.cbTrailer;
ptr = (unsigned char *) malloc(data_len);
if(!ptr) {
*err = CURLE_OUT_OF_MEMORY;
@@ -1662,12 +1668,12 @@ schannel_send(struct Curl_easy *data, int sockindex,
/* setup output buffers (header, data, trailer, empty) */
InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
- ptr, BACKEND->stream_sizes.cbHeader);
+ ptr, backend->stream_sizes.cbHeader);
InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
- ptr + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
+ ptr + backend->stream_sizes.cbHeader, curlx_uztoul(len));
InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
- ptr + BACKEND->stream_sizes.cbHeader + len,
- BACKEND->stream_sizes.cbTrailer);
+ ptr + backend->stream_sizes.cbHeader + len,
+ backend->stream_sizes.cbTrailer);
InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&outbuf_desc, outbuf, 4);
@@ -1675,7 +1681,7 @@ schannel_send(struct Curl_easy *data, int sockindex,
memcpy(outbuf[1].pvBuffer, buf, len);
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
- sspi_status = s_pSecFn->EncryptMessage(&BACKEND->ctxt->ctxt_handle, 0,
+ sspi_status = s_pSecFn->EncryptMessage(&backend->ctxt->ctxt_handle, 0,
&outbuf_desc, 0);
/* check if the message was encrypted */
@@ -1780,9 +1786,10 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* we want the length of the encrypted buffer to be at least large enough
that it can hold all the bytes requested and some TLS record overhead. */
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
+ struct ssl_backend_data *backend = connssl->backend;
/****************************************************************************
- * Don't return or set BACKEND->recv_unrecoverable_err unless in the cleanup.
+ * Don't return or set backend->recv_unrecoverable_err unless in the cleanup.
* The pattern for return error is set *err, optional infof, goto cleanup.
*
* Our priority is to always return as much decrypted data to the caller as
@@ -1794,16 +1801,16 @@ schannel_recv(struct Curl_easy *data, int sockindex,
DEBUGF(infof(data, "schannel: client wants to read %zu bytes", len));
*err = CURLE_OK;
- if(len && len <= BACKEND->decdata_offset) {
+ if(len && len <= backend->decdata_offset) {
infof(data, "schannel: enough decrypted data is already available");
goto cleanup;
}
- else if(BACKEND->recv_unrecoverable_err) {
- *err = BACKEND->recv_unrecoverable_err;
+ else if(backend->recv_unrecoverable_err) {
+ *err = backend->recv_unrecoverable_err;
infof(data, "schannel: an unrecoverable error occurred in a prior call");
goto cleanup;
}
- else if(BACKEND->recv_sspi_close_notify) {
+ else if(backend->recv_sspi_close_notify) {
/* once a server has indicated shutdown there is no more encrypted data */
infof(data, "schannel: server indicated shutdown in a prior call");
goto cleanup;
@@ -1813,17 +1820,17 @@ schannel_recv(struct Curl_easy *data, int sockindex,
immediately because there may be data to decrypt (in the case we want to
decrypt all encrypted cached data) so handle !len later in cleanup.
*/
- else if(len && !BACKEND->recv_connection_closed) {
+ else if(len && !backend->recv_connection_closed) {
/* increase enc buffer in order to fit the requested amount of data */
- size = BACKEND->encdata_length - BACKEND->encdata_offset;
+ size = backend->encdata_length - backend->encdata_offset;
if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
- BACKEND->encdata_length < min_encdata_length) {
- reallocated_length = BACKEND->encdata_offset +
+ backend->encdata_length < min_encdata_length) {
+ reallocated_length = backend->encdata_offset +
CURL_SCHANNEL_BUFFER_FREE_SIZE;
if(reallocated_length < min_encdata_length) {
reallocated_length = min_encdata_length;
}
- reallocated_buffer = realloc(BACKEND->encdata_buffer,
+ reallocated_buffer = realloc(backend->encdata_buffer,
reallocated_length);
if(!reallocated_buffer) {
*err = CURLE_OUT_OF_MEMORY;
@@ -1831,21 +1838,21 @@ schannel_recv(struct Curl_easy *data, int sockindex,
goto cleanup;
}
- BACKEND->encdata_buffer = reallocated_buffer;
- BACKEND->encdata_length = reallocated_length;
- size = BACKEND->encdata_length - BACKEND->encdata_offset;
+ backend->encdata_buffer = reallocated_buffer;
+ backend->encdata_length = reallocated_length;
+ size = backend->encdata_length - backend->encdata_offset;
DEBUGF(infof(data, "schannel: encdata_buffer resized %zu",
- BACKEND->encdata_length));
+ backend->encdata_length));
}
DEBUGF(infof(data,
"schannel: encrypted data buffer: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
/* read encrypted data from socket */
*err = Curl_read_plain(conn->sock[sockindex],
- (char *)(BACKEND->encdata_buffer +
- BACKEND->encdata_offset),
+ (char *)(backend->encdata_buffer +
+ backend->encdata_offset),
size, &nread);
if(*err) {
nread = -1;
@@ -1858,27 +1865,27 @@ schannel_recv(struct Curl_easy *data, int sockindex,
infof(data, "schannel: Curl_read_plain returned error %d", *err);
}
else if(nread == 0) {
- BACKEND->recv_connection_closed = true;
+ backend->recv_connection_closed = true;
DEBUGF(infof(data, "schannel: server closed the connection"));
}
else if(nread > 0) {
- BACKEND->encdata_offset += (size_t)nread;
- BACKEND->encdata_is_incomplete = false;
+ backend->encdata_offset += (size_t)nread;
+ backend->encdata_is_incomplete = false;
DEBUGF(infof(data, "schannel: encrypted data got %zd", nread));
}
}
DEBUGF(infof(data,
"schannel: encrypted data buffer: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
/* decrypt loop */
- while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK &&
- (!len || BACKEND->decdata_offset < len ||
- BACKEND->recv_connection_closed)) {
+ while(backend->encdata_offset > 0 && sspi_status == SEC_E_OK &&
+ (!len || backend->decdata_offset < len ||
+ backend->recv_connection_closed)) {
/* prepare data buffer for DecryptMessage call */
- InitSecBuffer(&inbuf[0], SECBUFFER_DATA, BACKEND->encdata_buffer,
- curlx_uztoul(BACKEND->encdata_offset));
+ InitSecBuffer(&inbuf[0], SECBUFFER_DATA, backend->encdata_buffer,
+ curlx_uztoul(backend->encdata_offset));
/* we need 3 more empty input buffers for possible output */
InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
@@ -1888,7 +1895,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
*/
- sspi_status = s_pSecFn->DecryptMessage(&BACKEND->ctxt->ctxt_handle,
+ sspi_status = s_pSecFn->DecryptMessage(&backend->ctxt->ctxt_handle,
&inbuf_desc, 0, NULL);
/* check if everything went fine (server may want to renegotiate
@@ -1904,37 +1911,37 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* increase buffer in order to fit the received amount of data */
size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
- if(BACKEND->decdata_length - BACKEND->decdata_offset < size ||
- BACKEND->decdata_length < len) {
+ if(backend->decdata_length - backend->decdata_offset < size ||
+ backend->decdata_length < len) {
/* increase internal decrypted data buffer */
- reallocated_length = BACKEND->decdata_offset + size;
+ reallocated_length = backend->decdata_offset + size;
/* make sure that the requested amount of data fits */
if(reallocated_length < len) {
reallocated_length = len;
}
- reallocated_buffer = realloc(BACKEND->decdata_buffer,
+ reallocated_buffer = realloc(backend->decdata_buffer,
reallocated_length);
if(!reallocated_buffer) {
*err = CURLE_OUT_OF_MEMORY;
failf(data, "schannel: unable to re-allocate memory");
goto cleanup;
}
- BACKEND->decdata_buffer = reallocated_buffer;
- BACKEND->decdata_length = reallocated_length;
+ backend->decdata_buffer = reallocated_buffer;
+ backend->decdata_length = reallocated_length;
}
/* copy decrypted data to internal buffer */
size = inbuf[1].cbBuffer;
if(size) {
- memcpy(BACKEND->decdata_buffer + BACKEND->decdata_offset,
+ memcpy(backend->decdata_buffer + backend->decdata_offset,
inbuf[1].pvBuffer, size);
- BACKEND->decdata_offset += size;
+ backend->decdata_offset += size;
}
DEBUGF(infof(data, "schannel: decrypted data added: %zu", size));
DEBUGF(infof(data,
"schannel: decrypted cached: offset %zu length %zu",
- BACKEND->decdata_offset, BACKEND->decdata_length));
+ backend->decdata_offset, backend->decdata_length));
}
/* check for remaining encrypted data */
@@ -1945,22 +1952,22 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* check if the remaining data is less than the total amount
* and therefore begins after the already processed data
*/
- if(BACKEND->encdata_offset > inbuf[3].cbBuffer) {
+ if(backend->encdata_offset > inbuf[3].cbBuffer) {
/* move remaining encrypted data forward to the beginning of
buffer */
- memmove(BACKEND->encdata_buffer,
- (BACKEND->encdata_buffer + BACKEND->encdata_offset) -
+ memmove(backend->encdata_buffer,
+ (backend->encdata_buffer + backend->encdata_offset) -
inbuf[3].cbBuffer, inbuf[3].cbBuffer);
- BACKEND->encdata_offset = inbuf[3].cbBuffer;
+ backend->encdata_offset = inbuf[3].cbBuffer;
}
DEBUGF(infof(data,
"schannel: encrypted cached: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
}
else {
/* reset encrypted buffer offset, because there is no data remaining */
- BACKEND->encdata_offset = 0;
+ backend->encdata_offset = 0;
}
/* check if server wants to renegotiate the connection context */
@@ -1970,7 +1977,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
infof(data, "schannel: can't renegotiate, an error is pending");
goto cleanup;
}
- if(BACKEND->encdata_offset) {
+ if(backend->encdata_offset) {
*err = CURLE_RECV_ERROR;
infof(data, "schannel: can't renegotiate, "
"encrypted data available");
@@ -1994,16 +2001,16 @@ schannel_recv(struct Curl_easy *data, int sockindex,
else if(sspi_status == SEC_I_CONTEXT_EXPIRED) {
/* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
returned so we have to work around that in cleanup. */
- BACKEND->recv_sspi_close_notify = true;
- if(!BACKEND->recv_connection_closed) {
- BACKEND->recv_connection_closed = true;
+ backend->recv_sspi_close_notify = true;
+ if(!backend->recv_connection_closed) {
+ backend->recv_connection_closed = true;
infof(data, "schannel: server closed the connection");
}
goto cleanup;
}
}
else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
- BACKEND->encdata_is_incomplete = true;
+ backend->encdata_is_incomplete = true;
if(!*err)
*err = CURLE_AGAIN;
infof(data, "schannel: failed to decrypt data, need more data");
@@ -2022,11 +2029,11 @@ schannel_recv(struct Curl_easy *data, int sockindex,
DEBUGF(infof(data,
"schannel: encrypted data buffer: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
DEBUGF(infof(data,
"schannel: decrypted data buffer: offset %zu length %zu",
- BACKEND->decdata_offset, BACKEND->decdata_length));
+ backend->decdata_offset, backend->decdata_length));
cleanup:
/* Warning- there is no guarantee the encdata state is valid at this point */
@@ -2043,13 +2050,13 @@ schannel_recv(struct Curl_easy *data, int sockindex,
assume it was graceful (close_notify) since there doesn't seem to be a
way to tell.
*/
- if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed &&
- !BACKEND->recv_sspi_close_notify) {
- bool isWin2k = curlx_verify_windows_version(5, 0, PLATFORM_WINNT,
+ if(len && !backend->decdata_offset && backend->recv_connection_closed &&
+ !backend->recv_sspi_close_notify) {
+ bool isWin2k = curlx_verify_windows_version(5, 0, 0, PLATFORM_WINNT,
VERSION_EQUAL);
if(isWin2k && sspi_status == SEC_E_OK)
- BACKEND->recv_sspi_close_notify = true;
+ backend->recv_sspi_close_notify = true;
else {
*err = CURLE_RECV_ERROR;
infof(data, "schannel: server closed abruptly (missing close_notify)");
@@ -2058,23 +2065,23 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* Any error other than CURLE_AGAIN is an unrecoverable error. */
if(*err && *err != CURLE_AGAIN)
- BACKEND->recv_unrecoverable_err = *err;
+ backend->recv_unrecoverable_err = *err;
- size = len < BACKEND->decdata_offset ? len : BACKEND->decdata_offset;
+ size = len < backend->decdata_offset ? len : backend->decdata_offset;
if(size) {
- memcpy(buf, BACKEND->decdata_buffer, size);
- memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size,
- BACKEND->decdata_offset - size);
- BACKEND->decdata_offset -= size;
+ memcpy(buf, backend->decdata_buffer, size);
+ memmove(backend->decdata_buffer, backend->decdata_buffer + size,
+ backend->decdata_offset - size);
+ backend->decdata_offset -= size;
DEBUGF(infof(data, "schannel: decrypted data returned %zu", size));
DEBUGF(infof(data,
"schannel: decrypted data buffer: offset %zu length %zu",
- BACKEND->decdata_offset, BACKEND->decdata_length));
+ backend->decdata_offset, backend->decdata_length));
*err = CURLE_OK;
return (ssize_t)size;
}
- if(!*err && !BACKEND->recv_connection_closed)
+ if(!*err && !backend->recv_connection_closed)
*err = CURLE_AGAIN;
/* It's debatable what to return when !len. We could return whatever error
@@ -2113,10 +2120,11 @@ static bool schannel_data_pending(const struct connectdata *conn,
int sockindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
if(connssl->use) /* SSL/TLS is in use */
- return (BACKEND->decdata_offset > 0 ||
- (BACKEND->encdata_offset > 0 && !BACKEND->encdata_is_incomplete));
+ return (backend->decdata_offset > 0 ||
+ (backend->encdata_offset > 0 && !backend->encdata_is_incomplete));
else
return FALSE;
}
@@ -2146,6 +2154,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
*/
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
char * const hostname = SSL_HOST_NAME();
+ struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(data);
@@ -2154,7 +2163,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
hostname, conn->remote_port);
}
- if(connssl->use && BACKEND->cred && BACKEND->ctxt) {
+ if(connssl->use && backend->cred && backend->ctxt) {
SecBufferDesc BuffDesc;
SecBuffer Buffer;
SECURITY_STATUS sspi_status;
@@ -2167,7 +2176,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
InitSecBufferDesc(&BuffDesc, &Buffer, 1);
- sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle,
+ sspi_status = s_pSecFn->ApplyControlToken(&backend->ctxt->ctxt_handle,
&BuffDesc);
if(sspi_status != SEC_E_OK) {
@@ -2185,18 +2194,18 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
sspi_status = s_pSecFn->InitializeSecurityContext(
- &BACKEND->cred->cred_handle,
- &BACKEND->ctxt->ctxt_handle,
+ &backend->cred->cred_handle,
+ &backend->ctxt->ctxt_handle,
host_name,
- BACKEND->req_flags,
+ backend->req_flags,
0,
0,
NULL,
0,
- &BACKEND->ctxt->ctxt_handle,
+ &backend->ctxt->ctxt_handle,
&outbuf_desc,
- &BACKEND->ret_flags,
- &BACKEND->ctxt->time_stamp);
+ &backend->ret_flags,
+ &backend->ctxt->time_stamp);
curlx_unicodefree(host_name);
@@ -2215,33 +2224,33 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
}
/* free SSPI Schannel API security context handle */
- if(BACKEND->ctxt) {
+ if(backend->ctxt) {
DEBUGF(infof(data, "schannel: clear security context handle"));
- s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle);
- Curl_safefree(BACKEND->ctxt);
+ s_pSecFn->DeleteSecurityContext(&backend->ctxt->ctxt_handle);
+ Curl_safefree(backend->ctxt);
}
/* free SSPI Schannel API credential handle */
- if(BACKEND->cred) {
+ if(backend->cred) {
Curl_ssl_sessionid_lock(data);
- schannel_session_free(BACKEND->cred);
+ schannel_session_free(backend->cred);
Curl_ssl_sessionid_unlock(data);
- BACKEND->cred = NULL;
+ backend->cred = NULL;
}
/* free internal buffer for received encrypted data */
- if(BACKEND->encdata_buffer != NULL) {
- Curl_safefree(BACKEND->encdata_buffer);
- BACKEND->encdata_length = 0;
- BACKEND->encdata_offset = 0;
- BACKEND->encdata_is_incomplete = false;
+ if(backend->encdata_buffer) {
+ Curl_safefree(backend->encdata_buffer);
+ backend->encdata_length = 0;
+ backend->encdata_offset = 0;
+ backend->encdata_is_incomplete = false;
}
/* free internal buffer for received decrypted data */
- if(BACKEND->decdata_buffer != NULL) {
- Curl_safefree(BACKEND->decdata_buffer);
- BACKEND->decdata_length = 0;
- BACKEND->decdata_offset = 0;
+ if(backend->decdata_buffer) {
+ Curl_safefree(backend->decdata_buffer);
+ backend->decdata_length = 0;
+ backend->decdata_offset = 0;
}
return CURLE_OK;
@@ -2299,6 +2308,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
const char *pinnedpubkey)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
CERT_CONTEXT *pCertContextServer = NULL;
/* Result is returned to caller */
@@ -2316,7 +2326,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
struct Curl_asn1Element *pubkey;
sspi_status =
- s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&pCertContextServer);
@@ -2422,8 +2432,9 @@ static CURLcode schannel_sha256sum(const unsigned char *input,
static void *schannel_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
+ struct ssl_backend_data *backend = connssl->backend;
(void)info;
- return &BACKEND->ctxt->ctxt_handle;
+ return &backend->ctxt->ctxt_handle;
}
const struct Curl_ssl Curl_ssl_schannel = {
diff --git a/contrib/libs/curl/lib/vtls/schannel_verify.c b/contrib/libs/curl/lib/vtls/schannel_verify.c
index 1b283d0453b..4966cd49456 100644
--- a/contrib/libs/curl/lib/vtls/schannel_verify.c
+++ b/contrib/libs/curl/lib/vtls/schannel_verify.c
@@ -355,7 +355,7 @@ static DWORD cert_get_name_string(struct Curl_easy *data,
DWORD i;
/* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */
- if(curlx_verify_windows_version(6, 2, PLATFORM_WINNT,
+ if(curlx_verify_windows_version(6, 2, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
/* CertGetNameString will provide the 8-bit character string without
@@ -597,7 +597,8 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
* trusted certificates. This is only supported on Windows 7+.
*/
- if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_LESS_THAN)) {
+ if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
+ VERSION_LESS_THAN)) {
failf(data, "schannel: this version of Windows is too old to support "
"certificate verification via CA bundle file.");
result = CURLE_SSL_CACERT_BADFILE;
diff --git a/contrib/libs/curl/lib/vtls/sectransp.c b/contrib/libs/curl/lib/vtls/sectransp.c
index 0bf515460dd..f7a20b20b12 100644
--- a/contrib/libs/curl/lib/vtls/sectransp.c
+++ b/contrib/libs/curl/lib/vtls/sectransp.c
@@ -997,14 +997,14 @@ CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
#else
#if CURL_BUILD_MAC_10_7
/* Lion & later: Get the long description if we can. */
- if(SecCertificateCopyLongDescription != NULL)
+ if(SecCertificateCopyLongDescription)
server_cert_summary =
SecCertificateCopyLongDescription(NULL, cert, NULL);
else
#endif /* CURL_BUILD_MAC_10_7 */
#if CURL_BUILD_MAC_10_6
/* Snow Leopard: Get the certificate summary. */
- if(SecCertificateCopySubjectSummary != NULL)
+ if(SecCertificateCopySubjectSummary)
server_cert_summary = SecCertificateCopySubjectSummary(cert);
else
#endif /* CURL_BUILD_MAC_10_6 */
@@ -1118,7 +1118,7 @@ static OSStatus CopyIdentityWithLabel(char *label,
/* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
kSecClassIdentity was introduced in Lion. If both exist, let's use them
to find the certificate. */
- if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
+ if(SecItemCopyMatching && kSecClassIdentity) {
CFTypeRef keys[5];
CFTypeRef values[5];
CFDictionaryRef query_dict;
@@ -1248,7 +1248,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
password ? 1L : 0L, NULL, NULL);
- if(options != NULL) {
+ if(options) {
status = SecPKCS12Import(pkcs_data, options, &items);
CFRelease(options);
}
@@ -1406,7 +1406,7 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
}
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
- if(SSLSetProtocolVersionMax != NULL) {
+ if(SSLSetProtocolVersionMax) {
SSLProtocol darwin_ver_min = kTLSProtocol1;
SSLProtocol darwin_ver_max = kTLSProtocol1;
CURLcode result = sectransp_version_from_curl(&darwin_ver_min,
@@ -1608,7 +1608,7 @@ static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data,
if(tls_name) {
table_cipher_name = ciphertable[i].name;
}
- else if(ciphertable[i].alias_name != NULL) {
+ else if(ciphertable[i].alias_name) {
table_cipher_name = ciphertable[i].alias_name;
}
else {
@@ -1688,7 +1688,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#endif /* CURL_BUILD_MAC */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
- if(SSLCreateContext != NULL) { /* use the newer API if available */
+ if(SSLCreateContext) { /* use the newer API if available */
if(backend->ssl_ctx)
CFRelease(backend->ssl_ctx);
backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
@@ -1722,7 +1722,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
/* check to see if we've been told to use an explicit SSL/TLS version */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
- if(SSLSetProtocolVersionMax != NULL) {
+ if(SSLSetProtocolVersionMax) {
switch(conn->ssl_config.version) {
case CURL_SSLVERSION_TLSv1:
(void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
@@ -1980,9 +1980,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
Darwin 15.x.x is El Capitan (10.11)
*/
#if CURL_BUILD_MAC
- if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
+ if(SSLSetSessionOption && darwinver_maj >= 13) {
#else
- if(SSLSetSessionOption != NULL) {
+ if(SSLSetSessionOption) {
#endif /* CURL_BUILD_MAC */
bool break_on_auth = !conn->ssl_config.verifypeer ||
ssl_cafile || ssl_cablob;
@@ -2065,7 +2065,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
/* We want to enable 1/n-1 when using a CBC cipher unless the user
specifically doesn't want us doing that: */
- if(SSLSetSessionOption != NULL) {
+ if(SSLSetSessionOption) {
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
!SSL_SET_OPTION(enable_beast));
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
@@ -2521,7 +2521,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
} while(0);
Curl_safefree(realpubkey);
- if(publicKeyBits != NULL)
+ if(publicKeyBits)
CFRelease(publicKeyBits);
return result;
@@ -2947,7 +2947,7 @@ collect_server_cert(struct Curl_easy *data,
private API and doesn't work as expected. So we have to look for
a different symbol to make sure this code is only executed under
Lion or later. */
- if(SecTrustEvaluateAsync != NULL) {
+ if(SecTrustEvaluateAsync) {
#pragma unused(server_certs)
err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
@@ -3165,7 +3165,7 @@ static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
if(backend->ssl_ctx) {
(void)SSLClose(backend->ssl_ctx);
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
- if(SSLCreateContext != NULL)
+ if(SSLCreateContext)
CFRelease(backend->ssl_ctx);
#if CURL_SUPPORT_MAC_10_8
else
@@ -3329,7 +3329,7 @@ static CURLcode sectransp_sha256sum(const unsigned char *tmp, /* input */
static bool sectransp_false_start(void)
{
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
- if(SSLSetSessionOption != NULL)
+ if(SSLSetSessionOption)
return TRUE;
#endif
return FALSE;
diff --git a/contrib/libs/curl/lib/x509asn1.c b/contrib/libs/curl/lib/x509asn1.c
index 1bdaeadc809..0341543a2b4 100644
--- a/contrib/libs/curl/lib/x509asn1.c
+++ b/contrib/libs/curl/lib/x509asn1.c
@@ -608,7 +608,10 @@ static const char *ASN1tostr(struct Curl_asn1Element *elem, int type)
/*
* ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at
- * `buf'. Return the total string length, even if larger than `buflen'.
+ * `buf'.
+ *
+ * Returns the total string length, even if larger than `buflen' or -1 on
+ * error.
*/
static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn)
{
@@ -692,7 +695,10 @@ static const char *DNtostr(struct Curl_asn1Element *dn)
if(buflen >= 0) {
buf = malloc(buflen + 1);
if(buf) {
- encodeDN(buf, buflen + 1, dn);
+ if(encodeDN(buf, buflen + 1, dn) == -1) {
+ free(buf);
+ return NULL;
+ }
buf[buflen] = '\0';
}
}
@@ -855,26 +861,30 @@ static const char *dumpAlgo(struct Curl_asn1Element *param,
return OID2str(oid.beg, oid.end, TRUE);
}
-static void do_pubkey_field(struct Curl_easy *data, int certnum,
- const char *label, struct Curl_asn1Element *elem)
+/* return 0 on success, 1 on error */
+static int do_pubkey_field(struct Curl_easy *data, int certnum,
+ const char *label, struct Curl_asn1Element *elem)
{
const char *output;
+ CURLcode result = CURLE_OK;
/* Generate a certificate information record for the public key. */
output = ASN1tostr(elem, 0);
if(output) {
if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, label, output);
- if(!certnum)
+ result = Curl_ssl_push_certinfo(data, certnum, label, output);
+ if(!certnum && !result)
infof(data, " %s: %s", label, output);
free((char *) output);
}
+ return result ? 1 : 0;
}
-static void do_pubkey(struct Curl_easy *data, int certnum,
- const char *algo, struct Curl_asn1Element *param,
- struct Curl_asn1Element *pubkey)
+/* return 0 on success, 1 on error */
+static int do_pubkey(struct Curl_easy *data, int certnum,
+ const char *algo, struct Curl_asn1Element *param,
+ struct Curl_asn1Element *pubkey)
{
struct Curl_asn1Element elem;
struct Curl_asn1Element pk;
@@ -884,7 +894,7 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
/* Get the public key (single element). */
if(!getASN1Element(&pk, pubkey->beg + 1, pubkey->end))
- return;
+ return 1;
if(strcasecompare(algo, "rsaEncryption")) {
const char *q;
@@ -892,7 +902,7 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
p = getASN1Element(&elem, pk.beg, pk.end);
if(!p)
- return;
+ return 1;
/* Compute key length. */
for(q = elem.beg; !*q && q < elem.end; q++)
@@ -910,26 +920,35 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
if(data->set.ssl.certinfo) {
q = curl_maprintf("%lu", len);
if(q) {
- Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
+ CURLcode result =
+ Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
free((char *) q);
+ if(result)
+ return 1;
}
}
/* Generate coefficients. */
- do_pubkey_field(data, certnum, "rsa(n)", &elem);
+ if(do_pubkey_field(data, certnum, "rsa(n)", &elem))
+ return 1;
if(!getASN1Element(&elem, p, pk.end))
- return;
- do_pubkey_field(data, certnum, "rsa(e)", &elem);
+ return 1;
+ if(do_pubkey_field(data, certnum, "rsa(e)", &elem))
+ return 1;
}
else if(strcasecompare(algo, "dsa")) {
p = getASN1Element(&elem, param->beg, param->end);
if(p) {
- do_pubkey_field(data, certnum, "dsa(p)", &elem);
+ if(do_pubkey_field(data, certnum, "dsa(p)", &elem))
+ return 1;
p = getASN1Element(&elem, p, param->end);
if(p) {
- do_pubkey_field(data, certnum, "dsa(q)", &elem);
+ if(do_pubkey_field(data, certnum, "dsa(q)", &elem))
+ return 1;
if(getASN1Element(&elem, p, param->end)) {
- do_pubkey_field(data, certnum, "dsa(g)", &elem);
- do_pubkey_field(data, certnum, "dsa(pub_key)", &pk);
+ if(do_pubkey_field(data, certnum, "dsa(g)", &elem))
+ return 1;
+ if(do_pubkey_field(data, certnum, "dsa(pub_key)", &pk))
+ return 1;
}
}
}
@@ -937,13 +956,17 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
else if(strcasecompare(algo, "dhpublicnumber")) {
p = getASN1Element(&elem, param->beg, param->end);
if(p) {
- do_pubkey_field(data, certnum, "dh(p)", &elem);
+ if(do_pubkey_field(data, certnum, "dh(p)", &elem))
+ return 1;
if(getASN1Element(&elem, param->beg, param->end)) {
- do_pubkey_field(data, certnum, "dh(g)", &elem);
- do_pubkey_field(data, certnum, "dh(pub_key)", &pk);
+ if(do_pubkey_field(data, certnum, "dh(g)", &elem))
+ return 1;
+ if(do_pubkey_field(data, certnum, "dh(pub_key)", &pk))
+ return 1;
}
}
}
+ return 0;
}
CURLcode Curl_extract_certinfo(struct Curl_easy *data,
@@ -957,7 +980,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
char *cp1;
size_t cl1;
char *cp2;
- CURLcode result;
+ CURLcode result = CURLE_OK;
unsigned long version;
size_t i;
size_t j;
@@ -976,8 +999,11 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
ccp = DNtostr(&cert.subject);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
- if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
+ if(data->set.ssl.certinfo) {
+ result = Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
+ if(result)
+ return result;
+ }
if(!certnum)
infof(data, "%2d Subject: %s", certnum, ccp);
free((char *) ccp);
@@ -986,11 +1012,14 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
ccp = DNtostr(&cert.issuer);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
- if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
+ if(data->set.ssl.certinfo) {
+ result = Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
+ }
if(!certnum)
infof(data, " Issuer: %s", ccp);
free((char *) ccp);
+ if(result)
+ return result;
/* Version (always fits in less than 32 bits). */
version = 0;
@@ -1000,8 +1029,10 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
ccp = curl_maprintf("%lx", version);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
- Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
+ result = Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
free((char *) ccp);
+ if(result)
+ return result;
}
if(!certnum)
infof(data, " Version: %lu (0x%lx)", version + 1, version);
@@ -1011,10 +1042,12 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
+ result = Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
if(!certnum)
infof(data, " Serial Number: %s", ccp);
free((char *) ccp);
+ if(result)
+ return result;
/* Signature algorithm .*/
ccp = dumpAlgo(&param, cert.signatureAlgorithm.beg,
@@ -1022,30 +1055,36 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
+ result = Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
if(!certnum)
infof(data, " Signature Algorithm: %s", ccp);
free((char *) ccp);
+ if(result)
+ return result;
/* Start Date. */
ccp = ASN1tostr(&cert.notBefore, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
+ result = Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
if(!certnum)
infof(data, " Start Date: %s", ccp);
free((char *) ccp);
+ if(result)
+ return result;
/* Expire Date. */
ccp = ASN1tostr(&cert.notAfter, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
+ result = Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
if(!certnum)
infof(data, " Expire Date: %s", ccp);
free((char *) ccp);
+ if(result)
+ return result;
/* Public Key Algorithm. */
ccp = dumpAlgo(&param, cert.subjectPublicKeyAlgorithm.beg,
@@ -1053,21 +1092,31 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
- if(!certnum)
- infof(data, " Public Key Algorithm: %s", ccp);
- do_pubkey(data, certnum, ccp, &param, &cert.subjectPublicKey);
+ result = Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm",
+ ccp);
+ if(!result) {
+ int ret;
+ if(!certnum)
+ infof(data, " Public Key Algorithm: %s", ccp);
+ ret = do_pubkey(data, certnum, ccp, &param, &cert.subjectPublicKey);
+ if(ret)
+ result = CURLE_OUT_OF_MEMORY; /* the most likely error */
+ }
free((char *) ccp);
+ if(result)
+ return result;
/* Signature. */
ccp = ASN1tostr(&cert.signature, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
+ result = Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
if(!certnum)
infof(data, " Signature: %s", ccp);
free((char *) ccp);
+ if(result)
+ return result;
/* Generate PEM certificate. */
result = Curl_base64_encode(data, cert.certificate.beg,
@@ -1097,11 +1146,11 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
cp2[i] = '\0';
free(cp1);
if(data->set.ssl.certinfo)
- Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
+ result = Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
if(!certnum)
infof(data, "%s", cp2);
free(cp2);
- return CURLE_OK;
+ return result;
}
#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL