summaryrefslogtreecommitdiff
path: root/libs/libcurl/src
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src')
-rw-r--r--libs/libcurl/src/checksrc.pl2
-rw-r--r--libs/libcurl/src/config-win32.h9
-rw-r--r--libs/libcurl/src/cookie.c19
-rw-r--r--libs/libcurl/src/easy.c51
-rw-r--r--libs/libcurl/src/formdata.c12
-rw-r--r--libs/libcurl/src/http2.c2
-rw-r--r--libs/libcurl/src/libcurl.plist6
-rw-r--r--libs/libcurl/src/mime.c229
-rw-r--r--libs/libcurl/src/mime.h6
-rw-r--r--libs/libcurl/src/multi.c6
-rw-r--r--libs/libcurl/src/setopt.c24
-rw-r--r--libs/libcurl/src/sha256.c74
-rw-r--r--libs/libcurl/src/socks.c10
-rw-r--r--libs/libcurl/src/transfer.c9
-rw-r--r--libs/libcurl/src/urldata.h8
-rw-r--r--libs/libcurl/src/version.c192
-rw-r--r--libs/libcurl/src/vquic/ngtcp2.c2
-rw-r--r--libs/libcurl/src/vquic/quiche.c2
-rw-r--r--libs/libcurl/src/vssh/libssh.c20
-rw-r--r--libs/libcurl/src/vssh/libssh2.c41
-rw-r--r--libs/libcurl/src/vtls/polarssl.c931
-rw-r--r--libs/libcurl/src/vtls/polarssl.h32
-rw-r--r--libs/libcurl/src/vtls/polarssl_threadlock.c144
-rw-r--r--libs/libcurl/src/vtls/polarssl_threadlock.h48
-rw-r--r--libs/libcurl/src/vtls/schannel.c10
-rw-r--r--libs/libcurl/src/vtls/vtls.h1
26 files changed, 499 insertions, 1391 deletions
diff --git a/libs/libcurl/src/checksrc.pl b/libs/libcurl/src/checksrc.pl
index 8343645610..e1bb1a6339 100644
--- a/libs/libcurl/src/checksrc.pl
+++ b/libs/libcurl/src/checksrc.pl
@@ -36,7 +36,7 @@ my $file;
my $dir=".";
my $wlist="";
my @alist;
-my $windows_os = $^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'cygwin';
+my $windows_os = $^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys';
my $verbose;
my %whitelist;
diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h
index da385c2ac7..d19665d71a 100644
--- a/libs/libcurl/src/config-win32.h
+++ b/libs/libcurl/src/config-win32.h
@@ -183,7 +183,7 @@
/* #define HAVE_DOPRNT 1 */
/* Define if you have the ftruncate function. */
-#define HAVE_FTRUNCATE 1
+/* #define HAVE_FTRUNCATE 1 */
/* Define to 1 if you have the `getpeername' function. */
#define HAVE_GETPEERNAME 1
@@ -246,10 +246,6 @@
/* Define if you have the socket function. */
#define HAVE_SOCKET 1
-/* Define if libSSH2 is in use */
-#define USE_LIBSSH2 1
-#define HAVE_LIBSSH2_H 1
-
/* Define if you have the strcasecmp function. */
/* #define HAVE_STRCASECMP 1 */
@@ -717,9 +713,6 @@ Vista
# define CURL_DISABLE_LDAP 1
#endif
-/* if SSL is enabled */
-#define USE_OPENSSL 1
-
/* Define to use the Windows crypto library. */
#if !defined(CURL_WINDOWS_APP)
#define USE_WIN32_CRYPTO
diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c
index 69bc04260a..68054e1c4c 100644
--- a/libs/libcurl/src/cookie.c
+++ b/libs/libcurl/src/cookie.c
@@ -245,18 +245,17 @@ pathmatched:
*/
static const char *get_top_domain(const char * const domain, size_t *outlen)
{
- size_t len;
+ size_t len = 0;
const char *first = NULL, *last;
- if(!domain)
- return NULL;
-
- len = strlen(domain);
- last = memrchr(domain, '.', len);
- if(last) {
- first = memrchr(domain, '.', (last - domain));
- if(first)
- len -= (++first - domain);
+ if(domain) {
+ len = strlen(domain);
+ last = memrchr(domain, '.', len);
+ if(last) {
+ first = memrchr(domain, '.', (last - domain));
+ if(first)
+ len -= (++first - domain);
+ }
}
if(outlen)
diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c
index 1a6912748e..b648e80c14 100644
--- a/libs/libcurl/src/easy.c
+++ b/libs/libcurl/src/easy.c
@@ -83,8 +83,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-void Curl_version_init(void);
-
/* true globals -- for curl_global_init() and curl_global_cleanup() */
static unsigned int initialized;
static long init_flags;
@@ -201,8 +199,6 @@ static CURLcode global_init(long flags, bool memoryfuncs)
init_flags = flags;
- Curl_version_init();
-
return CURLE_OK;
fail:
@@ -887,6 +883,17 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
data->state.resolver))
goto fail;
+#ifdef USE_ARES
+ if(Curl_set_dns_servers(outcurl, data->set.str[STRING_DNS_SERVERS]))
+ goto fail;
+ if(Curl_set_dns_interface(outcurl, data->set.str[STRING_DNS_INTERFACE]))
+ goto fail;
+ if(Curl_set_dns_local_ip4(outcurl, data->set.str[STRING_DNS_LOCAL_IP4]))
+ goto fail;
+ if(Curl_set_dns_local_ip6(outcurl, data->set.str[STRING_DNS_LOCAL_IP6]))
+ goto fail;
+#endif /* USE_ARES */
+
Curl_convert_setup(outcurl);
Curl_initinfo(outcurl);
@@ -973,16 +980,37 @@ void curl_easy_reset(struct Curl_easy *data)
*/
CURLcode curl_easy_pause(struct Curl_easy *data, int action)
{
- struct SingleRequest *k = &data->req;
+ struct SingleRequest *k;
CURLcode result = CURLE_OK;
+ int oldstate;
+ int newstate;
- /* first switch off both pause bits */
- int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
+ if(!GOOD_EASY_HANDLE(data) || !data->conn)
+ /* crazy input, don't continue */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
- /* set the new desired pause bits */
- newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
+ k = &data->req;
+ oldstate = k->keepon & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
+
+ /* first switch off both pause bits then set the new pause bits */
+ newstate = (k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) |
+ ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
+ if((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) == oldstate) {
+ /* Not changing any pause state, return */
+ DEBUGF(infof(data, "pause: no change, early return\n"));
+ return CURLE_OK;
+ }
+
+ /* Unpause parts in active mime tree. */
+ if((k->keepon & ~newstate & KEEP_SEND_PAUSE) &&
+ (data->mstate == CURLM_STATE_PERFORM ||
+ data->mstate == CURLM_STATE_TOOFAST) &&
+ data->state.fread_func == (curl_read_callback) Curl_mime_read) {
+ Curl_mime_unpause(data->state.in);
+ }
+
/* put it back in the keepon */
k->keepon = newstate;
@@ -1033,8 +1061,11 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
to have this handle checked soon */
if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) {
- data->state.drain++;
Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
+
+ /* 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);
}
diff --git a/libs/libcurl/src/formdata.c b/libs/libcurl/src/formdata.c
index 50a37e0e74..57ec6ad254 100644
--- a/libs/libcurl/src/formdata.c
+++ b/libs/libcurl/src/formdata.c
@@ -728,14 +728,10 @@ int curl_formget(struct curl_httppost *form, void *arg,
if(!nread)
break;
- switch(nread) {
- default:
- if(append(arg, buffer, nread) != nread)
- result = CURLE_READ_ERROR;
- break;
- case CURL_READFUNC_ABORT:
- case CURL_READFUNC_PAUSE:
- break;
+ if(nread > sizeof(buffer) || append(arg, buffer, nread) != nread) {
+ result = CURLE_READ_ERROR;
+ if(nread == CURL_READFUNC_ABORT)
+ result = CURLE_ABORTED_BY_CALLBACK;
}
}
diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c
index 72b38a3f66..41d8db6856 100644
--- a/libs/libcurl/src/http2.c
+++ b/libs/libcurl/src/http2.c
@@ -333,7 +333,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
int Curl_http2_ver(char *p, size_t len)
{
nghttp2_info *h2 = nghttp2_version(0);
- return msnprintf(p, len, " nghttp2/%s", h2->version_str);
+ return msnprintf(p, len, "nghttp2/%s", h2->version_str);
}
/*
diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist
index f0001fee06..0b521b0f86 100644
--- a/libs/libcurl/src/libcurl.plist
+++ b/libs/libcurl/src/libcurl.plist
@@ -15,7 +15,7 @@
<string>se.haxx.curl.libcurl</string>
<key>CFBundleVersion</key>
- <string>7.69.0</string>
+ <string>7.69.1</string>
<key>CFBundleName</key>
<string>libcurl</string>
@@ -27,9 +27,9 @@
<string>????</string>
<key>CFBundleShortVersionString</key>
- <string>libcurl 7.69.0</string>
+ <string>libcurl 7.69.1</string>
<key>CFBundleGetInfoString</key>
- <string>libcurl.plist 7.69.0</string>
+ <string>libcurl.plist 7.69.1</string>
</dict>
</plist>
diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c
index 2571287c6a..b72732310d 100644
--- a/libs/libcurl/src/mime.c
+++ b/libs/libcurl/src/mime.c
@@ -26,6 +26,7 @@
#include "mime.h"
#include "non-ascii.h"
+#include "warnless.h"
#include "urldata.h"
#include "sendf.h"
@@ -52,6 +53,10 @@
#define READ_ERROR ((size_t) -1)
+#define STOP_FILLING ((size_t) -2)
+
+static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
+ void *instream, bool *hasread);
/* Encoders. */
static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
@@ -354,10 +359,15 @@ static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
(void) ateof;
+ if(!size)
+ return STOP_FILLING;
+
if(size > insize)
size = insize;
+
if(size)
- memcpy(buffer, st->buf, size);
+ memcpy(buffer, st->buf + st->bufbeg, size);
+
st->bufbeg += size;
return size;
}
@@ -377,6 +387,9 @@ static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
(void) ateof;
+ if(!size)
+ return STOP_FILLING;
+
if(size > cursize)
size = cursize;
@@ -404,8 +417,11 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
/* Line full ? */
if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) {
/* Yes, we need 2 characters for CRLF. */
- if(size < 2)
+ if(size < 2) {
+ if(!cursize)
+ return STOP_FILLING;
break;
+ }
*ptr++ = '\r';
*ptr++ = '\n';
st->pos = 0;
@@ -414,7 +430,12 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
}
/* Be sure there is enough space and input data for a base64 group. */
- if(size < 4 || st->bufend - st->bufbeg < 3)
+ if(size < 4) {
+ if(!cursize)
+ return STOP_FILLING;
+ break;
+ }
+ if(st->bufend - st->bufbeg < 3)
break;
/* Encode three bytes as four characters. */
@@ -431,25 +452,31 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
}
/* If at eof, we have to flush the buffered data. */
- if(ateof && size >= 4) {
- /* Buffered data size can only be 0, 1 or 2. */
- ptr[2] = ptr[3] = '=';
- i = 0;
- switch(st->bufend - st->bufbeg) {
- case 2:
- i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
- /* FALLTHROUGH */
- case 1:
- i |= (st->buf[st->bufbeg] & 0xFF) << 16;
- ptr[0] = base64[(i >> 18) & 0x3F];
- ptr[1] = base64[(i >> 12) & 0x3F];
- if(++st->bufbeg != st->bufend) {
- ptr[2] = base64[(i >> 6) & 0x3F];
- st->bufbeg++;
+ if(ateof) {
+ if(size < 4) {
+ if(!cursize)
+ return STOP_FILLING;
+ }
+ else {
+ /* Buffered data size can only be 0, 1 or 2. */
+ ptr[2] = ptr[3] = '=';
+ i = 0;
+ switch(st->bufend - st->bufbeg) {
+ case 2:
+ i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
+ /* FALLTHROUGH */
+ case 1:
+ i |= (st->buf[st->bufbeg] & 0xFF) << 16;
+ ptr[0] = base64[(i >> 18) & 0x3F];
+ ptr[1] = base64[(i >> 12) & 0x3F];
+ if(++st->bufbeg != st->bufend) {
+ ptr[2] = base64[(i >> 6) & 0x3F];
+ st->bufbeg++;
+ }
+ cursize += 4;
+ st->pos += 4;
+ break;
}
- cursize += 4;
- st->pos += 4;
- break;
}
}
@@ -581,8 +608,11 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
}
/* If the output buffer would overflow, do not store. */
- if(len > size)
+ if(len > size) {
+ if(!cursize)
+ return STOP_FILLING;
break;
+ }
/* Append to output buffer. */
memcpy(ptr, buf, len);
@@ -612,16 +642,18 @@ static size_t mime_mem_read(char *buffer, size_t size, size_t nitems,
void *instream)
{
curl_mimepart *part = (curl_mimepart *) instream;
- size_t sz = (size_t) part->datasize - part->state.offset;
+ size_t sz = curlx_sotouz(part->datasize - part->state.offset);
(void) size; /* Always 1.*/
+ if(!nitems)
+ return STOP_FILLING;
+
if(sz > nitems)
sz = nitems;
if(sz)
- memcpy(buffer, (char *) &part->data[part->state.offset], sz);
+ memcpy(buffer, part->data + curlx_sotouz(part->state.offset), sz);
- part->state.offset += sz;
return sz;
}
@@ -641,7 +673,7 @@ static int mime_mem_seek(void *instream, curl_off_t offset, int whence)
if(offset < 0 || offset > part->datasize)
return CURL_SEEKFUNC_FAIL;
- part->state.offset = (size_t) offset;
+ part->state.offset = offset;
return CURL_SEEKFUNC_OK;
}
@@ -668,6 +700,9 @@ static size_t mime_file_read(char *buffer, size_t size, size_t nitems,
{
curl_mimepart *part = (curl_mimepart *) instream;
+ if(!nitems)
+ return STOP_FILLING;
+
if(mime_open_file(part))
return READ_ERROR;
@@ -711,15 +746,16 @@ static size_t readback_bytes(mime_state *state,
const char *trail)
{
size_t sz;
+ size_t offset = curlx_sotouz(state->offset);
- if(numbytes > state->offset) {
- sz = numbytes - state->offset;
- bytes += state->offset;
+ if(numbytes > offset) {
+ sz = numbytes - offset;
+ bytes += offset;
}
else {
size_t tsz = strlen(trail);
- sz = state->offset - numbytes;
+ sz = offset - numbytes;
if(sz >= tsz)
return 0;
bytes = trail + sz;
@@ -736,25 +772,79 @@ static size_t readback_bytes(mime_state *state,
/* Read a non-encoded part content. */
static size_t read_part_content(curl_mimepart *part,
- char *buffer, size_t bufsize)
+ char *buffer, size_t bufsize, bool *hasread)
{
size_t sz = 0;
- if(part->readfunc)
- sz = part->readfunc(buffer, 1, bufsize, part->arg);
+ switch(part->lastreadstatus) {
+ case 0:
+ case CURL_READFUNC_ABORT:
+ case CURL_READFUNC_PAUSE:
+ case READ_ERROR:
+ return part->lastreadstatus;
+ default:
+ break;
+ }
+
+ /* If we can determine we are at end of part data, spare a read. */
+ if(part->datasize != (curl_off_t) -1 &&
+ part->state.offset >= part->datasize) {
+ /* sz is already zero. */
+ }
+ else {
+ switch(part->kind) {
+ case MIMEKIND_MULTIPART:
+ /*
+ * Cannot be processed as other kinds since read function requires
+ * an additional parameter and is highly recursive.
+ */
+ sz = mime_subparts_read(buffer, 1, bufsize, part->arg, hasread);
+ break;
+ case MIMEKIND_FILE:
+ if(part->fp && feof(part->fp))
+ break; /* At EOF. */
+ /* FALLTHROUGH */
+ default:
+ if(part->readfunc) {
+ if(!(part->flags & MIME_FAST_READ)) {
+ if(*hasread)
+ return STOP_FILLING;
+ *hasread = TRUE;
+ }
+ sz = part->readfunc(buffer, 1, bufsize, part->arg);
+ }
+ break;
+ }
+ }
+
+ switch(sz) {
+ case STOP_FILLING:
+ break;
+ case 0:
+ case CURL_READFUNC_ABORT:
+ case CURL_READFUNC_PAUSE:
+ case READ_ERROR:
+ part->lastreadstatus = sz;
+ break;
+ default:
+ part->state.offset += sz;
+ part->lastreadstatus = sz;
+ break;
+ }
+
return sz;
}
/* Read and encode part content. */
-static size_t read_encoded_part_content(curl_mimepart *part,
- char *buffer, size_t bufsize)
+static size_t read_encoded_part_content(curl_mimepart *part, char *buffer,
+ size_t bufsize, bool *hasread)
{
mime_encoder_state *st = &part->encstate;
size_t cursize = 0;
size_t sz;
bool ateof = FALSE;
- while(bufsize) {
+ for(;;) {
if(st->bufbeg < st->bufend || ateof) {
/* Encode buffered data. */
sz = part->encoder->encodefunc(buffer, bufsize, ateof, part);
@@ -763,9 +853,8 @@ static size_t read_encoded_part_content(curl_mimepart *part,
if(ateof)
return cursize;
break;
- case CURL_READFUNC_ABORT:
- case CURL_READFUNC_PAUSE:
case READ_ERROR:
+ case STOP_FILLING:
return cursize? cursize: sz;
default:
cursize += sz;
@@ -787,7 +876,7 @@ static size_t read_encoded_part_content(curl_mimepart *part,
if(st->bufend >= sizeof(st->buf))
return cursize? cursize: READ_ERROR; /* Buffer full. */
sz = read_part_content(part, st->buf + st->bufend,
- sizeof(st->buf) - st->bufend);
+ sizeof(st->buf) - st->bufend, hasread);
switch(sz) {
case 0:
ateof = TRUE;
@@ -795,6 +884,7 @@ static size_t read_encoded_part_content(curl_mimepart *part,
case CURL_READFUNC_ABORT:
case CURL_READFUNC_PAUSE:
case READ_ERROR:
+ case STOP_FILLING:
return cursize? cursize: sz;
default:
st->bufend += sz;
@@ -802,12 +892,12 @@ static size_t read_encoded_part_content(curl_mimepart *part,
}
}
- return cursize;
+ /* NOTREACHED */
}
/* Readback a mime part. */
static size_t readback_part(curl_mimepart *part,
- char *buffer, size_t bufsize)
+ char *buffer, size_t bufsize, bool *hasread)
{
size_t cursize = 0;
#ifdef CURL_DOES_CONVERSIONS
@@ -866,9 +956,9 @@ static size_t readback_part(curl_mimepart *part,
break;
case MIMESTATE_CONTENT:
if(part->encoder)
- sz = read_encoded_part_content(part, buffer, bufsize);
+ sz = read_encoded_part_content(part, buffer, bufsize, hasread);
else
- sz = read_part_content(part, buffer, bufsize);
+ sz = read_part_content(part, buffer, bufsize, hasread);
switch(sz) {
case 0:
mimesetstate(&part->state, MIMESTATE_END, NULL);
@@ -881,6 +971,7 @@ static size_t readback_part(curl_mimepart *part,
case CURL_READFUNC_ABORT:
case CURL_READFUNC_PAUSE:
case READ_ERROR:
+ case STOP_FILLING:
return cursize? cursize: sz;
}
break;
@@ -909,9 +1000,9 @@ static size_t readback_part(curl_mimepart *part,
return cursize;
}
-/* Readback from mime. */
+/* Readback from mime. Warning: not a read callback function. */
static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
- void *instream)
+ void *instream, bool *hasread)
{
curl_mime *mime = (curl_mime *) instream;
size_t cursize = 0;
@@ -932,7 +1023,7 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
#endif
mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart);
/* The first boundary always follows the header termination empty line,
- so is always preceded by a CRLK. We can then spare 2 characters
+ so is always preceded by a CRLF. We can then spare 2 characters
by skipping the leading CRLF in boundary. */
mime->state.offset += 2;
break;
@@ -962,11 +1053,12 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
mimesetstate(&mime->state, MIMESTATE_END, NULL);
break;
}
- sz = readback_part(part, buffer, nitems);
+ sz = readback_part(part, buffer, nitems, hasread);
switch(sz) {
case CURL_READFUNC_ABORT:
case CURL_READFUNC_PAUSE:
case READ_ERROR:
+ case STOP_FILLING:
return cursize? cursize: sz;
case 0:
#ifdef CURL_DOES_CONVERSIONS
@@ -1031,6 +1123,7 @@ static int mime_part_rewind(curl_mimepart *part)
if(res == CURL_SEEKFUNC_OK)
mimesetstate(&part->state, targetstate, NULL);
+ part->lastreadstatus = 1; /* Successful read status. */
return res;
}
@@ -1073,6 +1166,8 @@ static void cleanup_part_content(curl_mimepart *part)
part->datasize = (curl_off_t) 0; /* No size yet. */
cleanup_encoder_state(&part->encstate);
part->kind = MIMEKIND_NONE;
+ part->flags &= ~MIME_FAST_READ;
+ part->lastreadstatus = 1; /* Successful read status. */
}
static void mime_subparts_free(void *ptr)
@@ -1238,6 +1333,7 @@ void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
{
memset((char *) part, 0, sizeof(*part));
part->easy = easy;
+ part->lastreadstatus = 1; /* Successful read status. */
mimesetstate(&part->state, MIMESTATE_BEGIN, NULL);
}
@@ -1328,6 +1424,7 @@ CURLcode curl_mime_data(curl_mimepart *part,
part->readfunc = mime_mem_read;
part->seekfunc = mime_mem_seek;
part->freefunc = mime_mem_free;
+ part->flags |= MIME_FAST_READ;
part->kind = MIMEKIND_DATA;
}
@@ -1502,7 +1599,7 @@ CURLcode Curl_mime_set_subparts(curl_mimepart *part,
}
subparts->parent = part;
- part->readfunc = mime_subparts_read;
+ /* Subparts are processed internally: no read callback. */
part->seekfunc = mime_subparts_seek;
part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind;
part->arg = subparts;
@@ -1524,9 +1621,23 @@ CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
{
curl_mimepart *part = (curl_mimepart *) instream;
+ size_t ret;
+ bool hasread;
(void) size; /* Always 1. */
- return readback_part(part, buffer, nitems);
+
+ do {
+ hasread = FALSE;
+ ret = readback_part(part, buffer, nitems, &hasread);
+ /*
+ * If this is not possible to get some data without calling more than
+ * one read callback (probably because a content encoder is not able to
+ * deliver a new bunch for the few data accumulated so far), force another
+ * read until we get enough data or a special exit code.
+ */
+ } while(ret == STOP_FILLING);
+
+ return ret;
}
/* Rewind mime stream. */
@@ -1805,6 +1916,26 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
return ret;
}
+/* Recursively reset paused status in the given part. */
+void Curl_mime_unpause(curl_mimepart *part)
+{
+ if(part) {
+ if(part->lastreadstatus == CURL_READFUNC_PAUSE)
+ part->lastreadstatus = 1; /* Successful read status. */
+ if(part->kind == MIMEKIND_MULTIPART) {
+ curl_mime *mime = (curl_mime *) part->arg;
+
+ if(mime) {
+ curl_mimepart *subpart;
+
+ for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart)
+ Curl_mime_unpause(subpart);
+ }
+ }
+ }
+}
+
+
#else /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
/* Mime not compiled in: define stubs for externally-referenced functions. */
diff --git a/libs/libcurl/src/mime.h b/libs/libcurl/src/mime.h
index 4312125796..d7f25132e3 100644
--- a/libs/libcurl/src/mime.h
+++ b/libs/libcurl/src/mime.h
@@ -31,6 +31,7 @@
/* Part flags. */
#define MIME_USERHEADERS_OWNER (1 << 0)
#define MIME_BODY_ONLY (1 << 1)
+#define MIME_FAST_READ (1 << 2)
#define FILE_CONTENTTYPE_DEFAULT "application/octet-stream"
#define MULTIPART_CONTENTTYPE_DEFAULT "multipart/mixed"
@@ -87,7 +88,7 @@ typedef struct {
typedef struct {
enum mimestate state; /* Current state token. */
void *ptr; /* State-dependent pointer. */
- size_t offset; /* State-dependent offset. */
+ curl_off_t offset; /* State-dependent offset. */
} mime_state;
/* minimum buffer size for the boundary string */
@@ -125,6 +126,7 @@ struct curl_mimepart_s {
mime_state state; /* Current readback state. */
const mime_encoder *encoder; /* Content data encoder. */
mime_encoder_state encstate; /* Data encoder state. */
+ size_t lastreadstatus; /* Last read callback returned status. */
};
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
@@ -147,6 +149,7 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems,
void *instream);
CURLcode Curl_mime_rewind(curl_mimepart *part);
const char *Curl_mime_contenttype(const char *filename);
+void Curl_mime_unpause(curl_mimepart *part);
#else
/* if disabled */
@@ -158,6 +161,7 @@ const char *Curl_mime_contenttype(const char *filename);
#define Curl_mime_size(x) (curl_off_t) -1
#define Curl_mime_read NULL
#define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define Curl_mime_unpause(x)
#endif
diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c
index cef2805c8e..e10e752931 100644
--- a/libs/libcurl/src/multi.c
+++ b/libs/libcurl/src/multi.c
@@ -1194,14 +1194,16 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
if(ufds[curlfds + extra_nfds].revents & POLLIN) {
char buf[64];
+ ssize_t nread;
while(1) {
/* the reading socket is non-blocking, try to read
data from it until it receives an error (except EINTR).
In normal cases it will get EAGAIN or EWOULDBLOCK
when there is no more data, breaking the loop. */
- if(sread(multi->wakeup_pair[0], buf, sizeof(buf)) <= 0) {
+ nread = sread(multi->wakeup_pair[0], buf, sizeof(buf));
+ if(nread <= 0) {
#ifndef USE_WINSOCK
- if(EINTR == SOCKERRNO)
+ if(nread < 0 && EINTR == SOCKERRNO)
continue;
#endif
break;
diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c
index 2e494a6df9..4648c872b4 100644
--- a/libs/libcurl/src/setopt.c
+++ b/libs/libcurl/src/setopt.c
@@ -2583,16 +2583,32 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
#endif
#ifdef USE_ARES
case CURLOPT_DNS_SERVERS:
- result = Curl_set_dns_servers(data, va_arg(param, char *));
+ result = Curl_setstropt(&data->set.str[STRING_DNS_SERVERS],
+ va_arg(param, char *));
+ if(result)
+ return result;
+ result = Curl_set_dns_servers(data, data->set.str[STRING_DNS_SERVERS]);
break;
case CURLOPT_DNS_INTERFACE:
- result = Curl_set_dns_interface(data, va_arg(param, char *));
+ result = Curl_setstropt(&data->set.str[STRING_DNS_INTERFACE],
+ va_arg(param, char *));
+ if(result)
+ return result;
+ result = Curl_set_dns_interface(data, data->set.str[STRING_DNS_INTERFACE]);
break;
case CURLOPT_DNS_LOCAL_IP4:
- result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
+ result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP4],
+ va_arg(param, char *));
+ if(result)
+ return result;
+ result = Curl_set_dns_local_ip4(data, data->set.str[STRING_DNS_LOCAL_IP4]);
break;
case CURLOPT_DNS_LOCAL_IP6:
- result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
+ result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP6],
+ va_arg(param, char *));
+ if(result)
+ return result;
+ result = Curl_set_dns_local_ip6(data, data->set.str[STRING_DNS_LOCAL_IP6]);
break;
#endif
case CURLOPT_TCP_KEEPALIVE:
diff --git a/libs/libcurl/src/sha256.c b/libs/libcurl/src/sha256.c
index 97214182be..352d577e8d 100644
--- a/libs/libcurl/src/sha256.c
+++ b/libs/libcurl/src/sha256.c
@@ -161,6 +161,80 @@ static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
#endif
}
+#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
+ (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
+ (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
+
+#include <CommonCrypto/CommonDigest.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef CC_SHA256_CTX SHA256_CTX;
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+ (void) CC_SHA256_Init(ctx);
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+ const unsigned char *data,
+ unsigned int length)
+{
+ (void) CC_SHA256_Update(ctx, data, length);
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+ (void) CC_SHA256_Final(digest, ctx);
+}
+
+#elif defined(USE_WIN32_CRYPTO)
+
+#include <wincrypt.h>
+
+typedef struct {
+ HCRYPTPROV hCryptProv;
+ HCRYPTHASH hHash;
+} SHA256_CTX;
+
+#if !defined(CALG_SHA_256)
+#define CALG_SHA_256 0x0000800c
+#endif
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+ if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+ PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
+ CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
+ }
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+ const unsigned char *data,
+ unsigned int length)
+{
+ CryptHashData(ctx->hHash, (unsigned char *) data, length, 0);
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+ unsigned long length;
+
+ CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
+ if(length == SHA256_DIGEST_LENGTH)
+ CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
+
+ if(ctx->hHash)
+ CryptDestroyHash(ctx->hHash);
+
+ if(ctx->hCryptProv)
+ CryptReleaseContext(ctx->hCryptProv, 0);
+}
+
#else
/* When no other crypto library is available we use this code segment */
diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c
index 0fb97e1e5d..37099130e5 100644
--- a/libs/libcurl/src/socks.c
+++ b/libs/libcurl/src/socks.c
@@ -205,6 +205,8 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
switch(sx->state) {
case CONNECT_SOCKS_INIT:
+ /* SOCKS4 can only do IPv4, insist! */
+ conn->ip_version = CURL_IPRESOLVE_V4;
if(conn->bits.httpproxy)
infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
protocol4a ? "a" : "", hostname, remote_port);
@@ -261,8 +263,8 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
}
else {
result = Curl_resolv_check(data->conn, &dns);
- /* stay in the state or error out */
- return result;
+ if(!dns)
+ return result;
}
/* FALLTHROUGH */
CONNECT_RESOLVED:
@@ -763,8 +765,8 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
if(!dns) {
result = Curl_resolv_check(data->conn, &dns);
- /* stay in the state or error out */
- return result;
+ if(!dns)
+ return result;
}
/* FALLTHROUGH */
CONNECT_RESOLVED:
diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c
index 827076183f..e76834eb34 100644
--- a/libs/libcurl/src/transfer.c
+++ b/libs/libcurl/src/transfer.c
@@ -890,7 +890,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
} /* if(!header and data to read) */
- if(conn->handler->readwrite && excess && !conn->bits.stream_was_rewound) {
+ if(conn->handler->readwrite && excess) {
/* Parse the excess data */
k->str += nread;
@@ -1217,8 +1217,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
else
fd_write = CURL_SOCKET_BAD;
- if(data->state.drain) {
- data->state.drain--;
+ if(conn->data->state.drain) {
select_res |= CURL_CSELECT_IN;
DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n"));
}
@@ -1235,9 +1234,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* We go ahead and do a read if we have a readable socket or if
the stream was rewound (in which case we have data in a
buffer) */
- if((k->keepon & KEEP_RECV) &&
- ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
-
+ if((k->keepon & KEEP_RECV) && (select_res & CURL_CSELECT_IN)) {
result = readwrite_data(data, conn, k, &didwhat, done, comeback);
if(result || *done)
return result;
diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h
index e1348cf29b..fbb8b645ec 100644
--- a/libs/libcurl/src/urldata.h
+++ b/libs/libcurl/src/urldata.h
@@ -464,8 +464,6 @@ struct ConnectBits {
#endif
BIT(netrc); /* name+password provided by netrc */
BIT(userpwd_in_url); /* name+password found in url */
- BIT(stream_was_rewound); /* The stream was rewound after a request read
- past the end of its response byte boundary */
BIT(proxy_connect_closed); /* TRUE if a proxy disconnected the connection
in a CONNECT request with auth, so that
libcurl should reconnect and continue. */
@@ -1579,6 +1577,11 @@ enum dupstring {
STRING_TEMP_URL, /* temp URL storage for proxy use */
+ STRING_DNS_SERVERS,
+ STRING_DNS_INTERFACE,
+ STRING_DNS_LOCAL_IP4,
+ STRING_DNS_LOCAL_IP6,
+
/* -- end of zero-terminated strings -- */
STRING_LASTZEROTERMINATED,
@@ -1587,6 +1590,7 @@ enum dupstring {
STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */
+
STRING_LAST /* not used, just an end-of-list marker */
};
diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c
index 77aca7cbe8..8170106eea 100644
--- a/libs/libcurl/src/version.c
+++ b/libs/libcurl/src/version.c
@@ -66,16 +66,6 @@
#include <brotli/decode.h>
#endif
-void Curl_version_init(void);
-
-/* For thread safety purposes this function is called by global_init so that
- the static data in both version functions is initialized. */
-void Curl_version_init(void)
-{
- curl_version();
- curl_version_info(CURLVERSION_NOW);
-}
-
#ifdef HAVE_BROTLI
static size_t brotli_version(char *buf, size_t bufsz)
{
@@ -88,95 +78,108 @@ static size_t brotli_version(char *buf, size_t bufsz)
}
#endif
+/*
+ * curl_version() returns a pointer to a static buffer.
+ *
+ * It is implemented to work multi-threaded by making sure repeated invokes
+ * generate the exact same string and never write any temporary data like
+ * zeros in the data.
+ */
char *curl_version(void)
{
- static bool initialized;
- static char version[250];
- char *ptr = version;
- size_t len;
- size_t left = sizeof(version);
-
- if(initialized)
- return version;
-
- strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION);
- len = strlen(ptr);
- left -= len;
- ptr += len;
-
- len = Curl_ssl_version(ptr + 1, left - 1);
-
- if(len > 0) {
- *ptr = ' ';
- left -= ++len;
- ptr += len;
- }
+ static char out[250];
+ char *outp;
+ size_t outlen;
+ const char *src[14];
+#ifdef USE_SSL
+ char ssl_version[40];
+#endif
+#ifdef HAVE_LIBZ
+ char z_version[40];
+#endif
+#ifdef HAVE_BROTLI
+ char br_version[40] = "brotli/";
+#endif
+#ifdef USE_ARES
+ char cares_version[40];
+#endif
+#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN)
+ char idn_version[40];
+#endif
+#ifdef USE_LIBPSL
+ char psl_version[40];
+#endif
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+ char iconv_version[40]="iconv";
+#endif
+#ifdef USE_SSH
+ char ssh_version[40];
+#endif
+#ifdef USE_NGHTTP2
+ char h2_version[40];
+#endif
+#ifdef ENABLE_QUIC
+ char h3_version[40];
+#endif
+#ifdef USE_LIBRTMP
+ char rtmp_version[40];
+#endif
+ int i = 0;
+ int j;
+ src[i++] = LIBCURL_NAME "/" LIBCURL_VERSION;
+#ifdef USE_SSL
+ Curl_ssl_version(ssl_version, sizeof(ssl_version));
+ src[i++] = ssl_version;
+#endif
#ifdef HAVE_LIBZ
- len = msnprintf(ptr, left, " zlib/%s", zlibVersion());
- left -= len;
- ptr += len;
+ msnprintf(z_version, sizeof(z_version), "zlib/%s", zlibVersion());
+ src[i++] = z_version;
#endif
#ifdef HAVE_BROTLI
- len = msnprintf(ptr, left, "%s", " brotli/");
- left -= len;
- ptr += len;
- len = brotli_version(ptr, left);
- left -= len;
- ptr += len;
+ brotli_version(&br_version[7], sizeof(br_version) - 7);
+ src[i++] = br_version;
#endif
#ifdef USE_ARES
- /* this function is only present in c-ares, not in the original ares */
- len = msnprintf(ptr, left, " c-ares/%s", ares_version(NULL));
- left -= len;
- ptr += len;
+ msnprintf(cares_version, sizeof(cares_version),
+ "c-ares/%s", ares_version(NULL));
+ src[i++] = cares_version;
#endif
#ifdef USE_LIBIDN2
if(idn2_check_version(IDN2_VERSION)) {
- len = msnprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL));
- left -= len;
- ptr += len;
+ msnprintf(idn_version, sizeof(idn_version),
+ "libidn2/%s", idn2_check_version(NULL));
+ src[i++] = idn_version;
}
+#elif defined(USE_WIN32_IDN)
+ msnprintf(idn_version, sizeof(idn_version), "WinIDN");
+ src[i++] = idn_version;
#endif
+
#ifdef USE_LIBPSL
- len = msnprintf(ptr, left, " libpsl/%s", psl_get_version());
- left -= len;
- ptr += len;
-#endif
-#ifdef USE_WIN32_IDN
- len = msnprintf(ptr, left, " WinIDN");
- left -= len;
- ptr += len;
+ msnprintf(psl_version, sizeof(psl_version), "libpsl/%s", psl_get_version());
+ src[i++] = psl_version;
#endif
#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
#ifdef _LIBICONV_VERSION
- len = msnprintf(ptr, left, " iconv/%d.%d",
- _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
+ msnprintf(iconv_version, sizeof(iconv_version), "iconv/%d.%d",
+ _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
#else
- /* version unknown */
- len = msnprintf(ptr, left, " iconv");
+ /* version unknown, let the default stand */
#endif /* _LIBICONV_VERSION */
- left -= len;
- ptr += len;
+ src[i++] = iconv_version;
#endif
#ifdef USE_SSH
- if(left) {
- *ptr++=' ';
- left--;
- }
- len = Curl_ssh_version(ptr, left);
- left -= len;
- ptr += len;
+ Curl_ssh_version(ssh_version, sizeof(ssh_version));
+ src[i++] = ssh_version;
#endif
#ifdef USE_NGHTTP2
- len = Curl_http2_ver(ptr, left);
- left -= len;
- ptr += len;
+ Curl_http2_ver(h2_version, sizeof(h2_version));
+ src[i++] = h2_version;
#endif
#ifdef ENABLE_QUIC
- len = Curl_quic_ver(ptr, left);
- left -= len;
- ptr += len;
+ Curl_quic_ver(h3_version, sizeof(h3_version));
+ src[i++] = h3_version;
#endif
#ifdef USE_LIBRTMP
{
@@ -188,27 +191,32 @@ char *curl_version(void)
else
suff[0] = '\0';
- msnprintf(ptr, left, " librtmp/%d.%d%s",
+ msnprintf(rtmp_version, sizeof(rtmp_version), "librtmp/%d.%d%s",
RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
suff);
-/*
- If another lib version is added below this one, this code would
- also have to do:
-
- len = what msnprintf() returned
-
- left -= len;
- ptr += len;
-*/
+ src[i++] = rtmp_version;
}
#endif
- /* Silent scan-build even if librtmp is not enabled. */
- (void) left;
- (void) ptr;
+ outp = &out[0];
+ outlen = sizeof(out);
+ for(j = 0; j < i; j++) {
+ size_t n = strlen(src[j]);
+ /* we need room for a space, the string and the final zero */
+ if(outlen <= (n + 2))
+ break;
+ if(j) {
+ /* prepend a space if not the first */
+ *outp++ = ' ';
+ outlen--;
+ }
+ memcpy(outp, src[j], n);
+ outp += n;
+ outlen -= n;
+ }
+ *outp = 0;
- initialized = true;
- return version;
+ return out;
}
/* data for curl_version_info
@@ -391,7 +399,6 @@ static curl_version_info_data version_info = {
curl_version_info_data *curl_version_info(CURLversion stamp)
{
- static bool initialized;
#if defined(USE_SSH)
static char ssh_buffer[80];
#endif
@@ -406,9 +413,6 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
static char brotli_buffer[80];
#endif
- if(initialized)
- return &version_info;
-
#ifdef USE_SSL
Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
version_info.ssl_version = ssl_buffer;
@@ -476,7 +480,5 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
#endif
(void)stamp; /* avoid compiler warnings, we don't use this */
-
- initialized = true;
return &version_info;
}
diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c
index 0788404c02..2f6ee8bdf9 100644
--- a/libs/libcurl/src/vquic/ngtcp2.c
+++ b/libs/libcurl/src/vquic/ngtcp2.c
@@ -641,7 +641,7 @@ int Curl_quic_ver(char *p, size_t len)
{
ngtcp2_info *ng2 = ngtcp2_version(0);
nghttp3_info *ht3 = nghttp3_version(0);
- return msnprintf(p, len, " ngtcp2/%s nghttp3/%s",
+ return msnprintf(p, len, "ngtcp2/%s nghttp3/%s",
ng2->version_str, ht3->version_str);
}
diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c
index d09ba7038a..c40e5e937c 100644
--- a/libs/libcurl/src/vquic/quiche.c
+++ b/libs/libcurl/src/vquic/quiche.c
@@ -532,7 +532,7 @@ static ssize_t h3_stream_send(struct connectdata *conn,
*/
int Curl_quic_ver(char *p, size_t len)
{
- return msnprintf(p, len, " quiche/%s", quiche_version());
+ return msnprintf(p, len, "quiche/%s", quiche_version());
}
/* Index where :authority header field will appear in request header
diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c
index 647b4d4913..08d9f9e0fb 100644
--- a/libs/libcurl/src/vssh/libssh.c
+++ b/libs/libcurl/src/vssh/libssh.c
@@ -345,13 +345,27 @@ static int myssh_is_known(struct connectdata *conn)
return rc;
if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
+ int i;
+ char md5buffer[33];
+ const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
+
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5,
&hash, &hlen);
- if(rc != SSH_OK)
+ if(rc != SSH_OK || hlen != 16) {
+ failf(data,
+ "Denied establishing ssh session: md5 fingerprint not available");
goto cleanup;
+ }
+
+ for(i = 0; i < 16; i++)
+ msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char)hash[i]);
+
+ infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
- if(hlen != strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) ||
- memcmp(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], hash, hlen)) {
+ if(!strcasecompare(md5buffer, pubkey_md5)) {
+ failf(data,
+ "Denied establishing ssh session: mismatch md5 fingerprint. "
+ "Remote %s is not equal to %s", md5buffer, pubkey_md5);
rc = SSH_ERROR;
goto cleanup;
}
diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c
index 8e043747e7..c487ccabb5 100644
--- a/libs/libcurl/src/vssh/libssh2.c
+++ b/libs/libcurl/src/vssh/libssh2.c
@@ -694,31 +694,40 @@ static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn)
while(!libssh2_knownhost_get(sshc->kh, &store, store)) {
/* For non-standard ports, the name will be enclosed in */
/* square brackets, followed by a colon and the port */
- if(store->name[0] == '[') {
- kh_name_end = strstr(store->name, "]:");
- if(!kh_name_end) {
- infof(data, "Invalid host pattern %s in %s\n",
- store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
- continue;
- }
- port = atoi(kh_name_end + 2);
- if(kh_name_end && (port == conn->remote_port)) {
- kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end);
- if(strncmp(store->name + 1, conn->host.name, kh_name_size) == 0) {
+ if(store) {
+ if(store->name) {
+ if(store->name[0] == '[') {
+ kh_name_end = strstr(store->name, "]:");
+ if(!kh_name_end) {
+ infof(data, "Invalid host pattern %s in %s\n",
+ store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+ continue;
+ }
+ port = atoi(kh_name_end + 2);
+ if(kh_name_end && (port == conn->remote_port)) {
+ kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end);
+ if(strncmp(store->name + 1,
+ conn->host.name, kh_name_size) == 0) {
+ found = true;
+ break;
+ }
+ }
+ }
+ else if(strcmp(store->name, conn->host.name) == 0) {
found = true;
break;
}
}
- }
- else if(strcmp(store->name, conn->host.name) == 0) {
- found = true;
- break;
+ else {
+ found = true;
+ break;
+ }
}
}
if(found) {
infof(data, "Found host %s in %s\n",
- store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+ conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
diff --git a/libs/libcurl/src/vtls/polarssl.c b/libs/libcurl/src/vtls/polarssl.c
deleted file mode 100644
index 9e7dd90437..0000000000
--- a/libs/libcurl/src/vtls/polarssl.c
+++ /dev/null
@@ -1,931 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-/*
- * Source file for all PolarSSL-specific code for the TLS/SSL layer. No code
- * but vtls.c should ever call or use these functions.
- *
- */
-
-#include "curl_setup.h"
-
-#ifdef USE_POLARSSL
-#include <polarssl/net.h>
-#include <polarssl/ssl.h>
-#include <polarssl/certs.h>
-#include <polarssl/x509.h>
-#include <polarssl/version.h>
-#include <polarssl/sha256.h>
-
-#if POLARSSL_VERSION_NUMBER < 0x01030000
-#error too old PolarSSL
-#endif
-
-#include <polarssl/error.h>
-#include <polarssl/entropy.h>
-#include <polarssl/ctr_drbg.h>
-
-#include "urldata.h"
-#include "sendf.h"
-#include "inet_pton.h"
-#include "polarssl.h"
-#include "vtls.h"
-#include "parsedate.h"
-#include "connect.h" /* for the connect timeout */
-#include "select.h"
-#include "strcase.h"
-#include "polarssl_threadlock.h"
-#include "multiif.h"
-#include "curl_printf.h"
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* See https://tls.mbed.org/discussions/generic/
- howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
-*/
-#define RSA_PUB_DER_MAX_BYTES (38 + 2 * POLARSSL_MPI_MAX_SIZE)
-#define ECP_PUB_DER_MAX_BYTES (30 + 2 * POLARSSL_ECP_MAX_BYTES)
-
-#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
- RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
-
-struct ssl_backend_data {
- ctr_drbg_context ctr_drbg;
- entropy_context entropy;
- ssl_context ssl;
- int server_fd;
- x509_crt cacert;
- x509_crt clicert;
- x509_crl crl;
- rsa_context rsa;
-};
-
-#define BACKEND connssl->backend
-
-/* apply threading? */
-#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
-#define THREADING_SUPPORT
-#endif
-
-#ifndef POLARSSL_ERROR_C
-#define error_strerror(x,y,z)
-#endif /* POLARSSL_ERROR_C */
-
-
-#if defined(THREADING_SUPPORT)
-static entropy_context entropy;
-
-static int entropy_init_initialized = 0;
-
-/* start of entropy_init_mutex() */
-static void entropy_init_mutex(entropy_context *ctx)
-{
- /* lock 0 = entropy_init_mutex() */
- Curl_polarsslthreadlock_lock_function(0);
- if(entropy_init_initialized == 0) {
- entropy_init(ctx);
- entropy_init_initialized = 1;
- }
- Curl_polarsslthreadlock_unlock_function(0);
-}
-/* end of entropy_init_mutex() */
-
-/* start of entropy_func_mutex() */
-static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
-{
- int ret;
- /* lock 1 = entropy_func_mutex() */
- Curl_polarsslthreadlock_lock_function(1);
- ret = entropy_func(data, output, len);
- Curl_polarsslthreadlock_unlock_function(1);
-
- return ret;
-}
-/* end of entropy_func_mutex() */
-
-#endif /* THREADING_SUPPORT */
-
-/* Define this to enable lots of debugging for PolarSSL */
-#undef POLARSSL_DEBUG
-
-#ifdef POLARSSL_DEBUG
-static void polarssl_debug(void *context, int level, const char *line)
-{
- struct Curl_easy *data = NULL;
-
- if(!context)
- return;
-
- data = (struct Curl_easy *)context;
-
- infof(data, "%s", line);
- (void) level;
-}
-#else
-#endif
-
-/* ALPN for http2? */
-#ifdef POLARSSL_SSL_ALPN
-# define HAS_ALPN
-#endif
-
-static Curl_recv polarssl_recv;
-static Curl_send polarssl_send;
-
-static CURLcode polarssl_version_from_curl(int *polarver, long ssl_version)
-{
- switch(ssl_version) {
- case CURL_SSLVERSION_TLSv1_0:
- *polarver = SSL_MINOR_VERSION_1;
- return CURLE_OK;
- case CURL_SSLVERSION_TLSv1_1:
- *polarver = SSL_MINOR_VERSION_2;
- return CURLE_OK;
- case CURL_SSLVERSION_TLSv1_2:
- *polarver = SSL_MINOR_VERSION_3;
- return CURLE_OK;
- case CURL_SSLVERSION_TLSv1_3:
- break;
- }
- return CURLE_SSL_CONNECT_ERROR;
-}
-
-static CURLcode
-set_ssl_version_min_max(struct connectdata *conn, int sockindex)
-{
- struct Curl_easy *data = conn->data;
- struct ssl_connect_data* connssl = &conn->ssl[sockindex];
- long ssl_version = SSL_CONN_CONFIG(version);
- long ssl_version_max = SSL_CONN_CONFIG(version_max);
- int ssl_min_ver = SSL_MINOR_VERSION_1;
- int ssl_max_ver = SSL_MINOR_VERSION_1;
- CURLcode result = CURLE_OK;
-
- switch(ssl_version) {
- case CURL_SSLVERSION_DEFAULT:
- case CURL_SSLVERSION_TLSv1:
- ssl_version = CURL_SSLVERSION_TLSv1_0;
- break;
- }
-
- switch(ssl_version_max) {
- case CURL_SSLVERSION_MAX_NONE:
- case CURL_SSLVERSION_MAX_DEFAULT:
- ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
- break;
- }
-
- result = polarssl_version_from_curl(&ssl_min_ver, ssl_version);
- if(result) {
- failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
- return result;
- }
- result = polarssl_version_from_curl(&ssl_max_ver, ssl_version_max >> 16);
- if(result) {
- failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
- return result;
- }
-
- ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver);
- ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver);
-
- return result;
-}
-
-static CURLcode
-polarssl_connect_step1(struct connectdata *conn,
- int sockindex)
-{
- struct Curl_easy *data = conn->data;
- struct ssl_connect_data* connssl = &conn->ssl[sockindex];
- const char *capath = SSL_CONN_CONFIG(CApath);
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
- const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
- int ret = -1;
- char errorbuf[128];
- errorbuf[0] = 0;
-
- /* PolarSSL only supports SSLv3 and TLSv1 */
- if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
- failf(data, "PolarSSL does not support SSLv2");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
-#ifdef THREADING_SUPPORT
- entropy_init_mutex(&entropy);
-
- if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy,
- NULL, 0)) != 0) {
- error_strerror(ret, errorbuf, sizeof(errorbuf));
- failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
- -ret, errorbuf);
- }
-#else
- entropy_init(&BACKEND->entropy);
-
- if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy,
- NULL, 0)) != 0) {
- error_strerror(ret, errorbuf, sizeof(errorbuf));
- failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
- -ret, errorbuf);
- }
-#endif /* THREADING_SUPPORT */
-
- /* Load the trusted CA */
- memset(&BACKEND->cacert, 0, sizeof(x509_crt));
-
- if(SSL_CONN_CONFIG(CAfile)) {
- ret = x509_crt_parse_file(&BACKEND->cacert,
- SSL_CONN_CONFIG(CAfile));
-
- if(ret<0) {
- error_strerror(ret, errorbuf, sizeof(errorbuf));
- failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
- SSL_CONN_CONFIG(CAfile), -ret, errorbuf);
-
- if(SSL_CONN_CONFIG(verifypeer))
- return CURLE_SSL_CACERT_BADFILE;
- }
- }
-
- if(capath) {
- ret = x509_crt_parse_path(&BACKEND->cacert, capath);
-
- if(ret<0) {
- error_strerror(ret, errorbuf, sizeof(errorbuf));
- failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
- capath, -ret, errorbuf);
-
- if(SSL_CONN_CONFIG(verifypeer))
- return CURLE_SSL_CACERT_BADFILE;
- }
- }
-
- /* Load the client certificate */
- memset(&BACKEND->clicert, 0, sizeof(x509_crt));
-
- if(SSL_SET_OPTION(cert)) {
- ret = x509_crt_parse_file(&BACKEND->clicert,
- SSL_SET_OPTION(cert));
-
- if(ret) {
- error_strerror(ret, errorbuf, sizeof(errorbuf));
- failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
- SSL_SET_OPTION(cert), -ret, errorbuf);
-
- return CURLE_SSL_CERTPROBLEM;
- }
- }
-
- /* Load the client private key */
- if(SSL_SET_OPTION(key)) {
- pk_context pk;
- pk_init(&pk);
- ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key),
- SSL_SET_OPTION(key_passwd));
- if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
- ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
- if(ret == 0)
- rsa_copy(&BACKEND->rsa, pk_rsa(pk));
- else
- rsa_free(&BACKEND->rsa);
- pk_free(&pk);
-
- if(ret) {
- error_strerror(ret, errorbuf, sizeof(errorbuf));
- failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
- SSL_SET_OPTION(key), -ret, errorbuf);
-
- return CURLE_SSL_CERTPROBLEM;
- }
- }
-
- /* Load the CRL */
- memset(&BACKEND->crl, 0, sizeof(x509_crl));
-
- if(SSL_SET_OPTION(CRLfile)) {
- ret = x509_crl_parse_file(&BACKEND->crl,
- SSL_SET_OPTION(CRLfile));
-
- if(ret) {
- error_strerror(ret, errorbuf, sizeof(errorbuf));
- failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
- SSL_SET_OPTION(CRLfile), -ret, errorbuf);
-
- return CURLE_SSL_CRL_BADFILE;
- }
- }
-
- infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port);
-
- if(ssl_init(&BACKEND->ssl)) {
- failf(data, "PolarSSL: ssl_init failed");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- switch(SSL_CONN_CONFIG(version)) {
- case CURL_SSLVERSION_DEFAULT:
- case CURL_SSLVERSION_TLSv1:
- ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
- SSL_MINOR_VERSION_1);
- break;
- case CURL_SSLVERSION_SSLv3:
- ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
- SSL_MINOR_VERSION_0);
- ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
- SSL_MINOR_VERSION_0);
- infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
- break;
- case CURL_SSLVERSION_TLSv1_0:
- case CURL_SSLVERSION_TLSv1_1:
- case CURL_SSLVERSION_TLSv1_2:
- case CURL_SSLVERSION_TLSv1_3:
- {
- CURLcode result = set_ssl_version_min_max(conn, sockindex);
- if(result != CURLE_OK)
- return result;
- break;
- }
- default:
- failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT);
- ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL);
-
- ssl_set_rng(&BACKEND->ssl, ctr_drbg_random,
- &BACKEND->ctr_drbg);
- ssl_set_bio(&BACKEND->ssl,
- net_recv, &conn->sock[sockindex],
- net_send, &conn->sock[sockindex]);
-
- ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites());
-
- /* Check if there's a cached ID we can/should use here! */
- if(SSL_SET_OPTION(primary.sessionid)) {
- void *old_session = NULL;
-
- Curl_ssl_sessionid_lock(conn);
- if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
- ret = ssl_set_session(&BACKEND->ssl, old_session);
- if(ret) {
- Curl_ssl_sessionid_unlock(conn);
- failf(data, "ssl_set_session returned -0x%x", -ret);
- return CURLE_SSL_CONNECT_ERROR;
- }
- infof(data, "PolarSSL re-using session\n");
- }
- Curl_ssl_sessionid_unlock(conn);
- }
-
- ssl_set_ca_chain(&BACKEND->ssl,
- &BACKEND->cacert,
- &BACKEND->crl,
- hostname);
-
- ssl_set_own_cert_rsa(&BACKEND->ssl,
- &BACKEND->clicert, &BACKEND->rsa);
-
- if(ssl_set_hostname(&BACKEND->ssl, hostname)) {
- /* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name
- to set in the SNI extension. So even if curl connects to a host
- specified as an IP address, this function must be used. */
- failf(data, "couldn't set hostname in PolarSSL");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
-#ifdef HAS_ALPN
- if(conn->bits.tls_enable_alpn) {
- static const char *protocols[3];
- int cur = 0;
-
-#ifdef USE_NGHTTP2
- if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
- protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
- infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
- }
-#endif
-
- protocols[cur++] = ALPN_HTTP_1_1;
- infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
-
- protocols[cur] = NULL;
-
- ssl_set_alpn_protocols(&BACKEND->ssl, protocols);
- }
-#endif
-
-#ifdef POLARSSL_DEBUG
- ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data);
-#endif
-
- connssl->connecting_state = ssl_connect_2;
-
- return CURLE_OK;
-}
-
-static CURLcode
-polarssl_connect_step2(struct connectdata *conn,
- int sockindex)
-{
- int ret;
- struct Curl_easy *data = conn->data;
- struct ssl_connect_data* connssl = &conn->ssl[sockindex];
- char buffer[1024];
- const char * const pinnedpubkey = SSL_IS_PROXY() ?
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
-
-
- char errorbuf[128];
- errorbuf[0] = 0;
-
- conn->recv[sockindex] = polarssl_recv;
- conn->send[sockindex] = polarssl_send;
-
- ret = ssl_handshake(&BACKEND->ssl);
-
- switch(ret) {
- case 0:
- break;
-
- case POLARSSL_ERR_NET_WANT_READ:
- connssl->connecting_state = ssl_connect_2_reading;
- return CURLE_OK;
-
- case POLARSSL_ERR_NET_WANT_WRITE:
- connssl->connecting_state = ssl_connect_2_writing;
- return CURLE_OK;
-
- default:
- error_strerror(ret, errorbuf, sizeof(errorbuf));
- failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
- -ret, errorbuf);
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
- ssl_get_ciphersuite(&BACKEND->ssl) );
-
- ret = ssl_get_verify_result(&BACKEND->ssl);
-
- if(ret && SSL_CONN_CONFIG(verifypeer)) {
- if(ret & BADCERT_EXPIRED)
- failf(data, "Cert verify failed: BADCERT_EXPIRED");
-
- if(ret & BADCERT_REVOKED) {
- failf(data, "Cert verify failed: BADCERT_REVOKED");
- return CURLE_PEER_FAILED_VERIFICATION;
- }
-
- if(ret & BADCERT_CN_MISMATCH)
- failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
-
- if(ret & BADCERT_NOT_TRUSTED)
- failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
-
- return CURLE_PEER_FAILED_VERIFICATION;
- }
-
- if(ssl_get_peer_cert(&(BACKEND->ssl))) {
- /* If the session was resumed, there will be no peer certs */
- memset(buffer, 0, sizeof(buffer));
-
- if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
- ssl_get_peer_cert(&(BACKEND->ssl))) != -1)
- infof(data, "Dumping cert info:\n%s\n", buffer);
- }
-
- /* adapted from mbedtls.c */
- if(pinnedpubkey) {
- int size;
- CURLcode result;
- x509_crt *p;
- unsigned char pubkey[PUB_DER_MAX_BYTES];
- const x509_crt *peercert;
-
- peercert = ssl_get_peer_cert(&BACKEND->ssl);
-
- if(!peercert || !peercert->raw.p || !peercert->raw.len) {
- failf(data, "Failed due to missing peer certificate");
- return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
- }
-
- p = calloc(1, sizeof(*p));
-
- if(!p)
- return CURLE_OUT_OF_MEMORY;
-
- x509_crt_init(p);
-
- /* Make a copy of our const peercert because pk_write_pubkey_der
- needs a non-const key, for now.
- https://github.com/ARMmbed/mbedtls/issues/396 */
- if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
- failf(data, "Failed copying peer certificate");
- x509_crt_free(p);
- free(p);
- return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
- }
-
- size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
-
- if(size <= 0) {
- failf(data, "Failed copying public key from peer certificate");
- x509_crt_free(p);
- free(p);
- return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
- }
-
- /* pk_write_pubkey_der writes data at the end of the buffer. */
- result = Curl_pin_peer_pubkey(data,
- pinnedpubkey,
- &pubkey[PUB_DER_MAX_BYTES - size], size);
- if(result) {
- x509_crt_free(p);
- free(p);
- return result;
- }
-
- x509_crt_free(p);
- free(p);
- }
-
-#ifdef HAS_ALPN
- if(conn->bits.tls_enable_alpn) {
- const char *next_protocol = ssl_get_alpn_protocol(&BACKEND->ssl);
-
- if(next_protocol != NULL) {
- infof(data, "ALPN, server accepted to use %s\n", next_protocol);
-
-#ifdef USE_NGHTTP2
- if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
- NGHTTP2_PROTO_VERSION_ID_LEN)) {
- conn->negnpn = CURL_HTTP_VERSION_2;
- }
- else
-#endif
- if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
- }
- }
- else
- infof(data, "ALPN, server did not agree to a protocol\n");
- Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
- BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
- }
-#endif
-
- connssl->connecting_state = ssl_connect_3;
- infof(data, "SSL connected\n");
-
- return CURLE_OK;
-}
-
-static CURLcode
-polarssl_connect_step3(struct connectdata *conn,
- int sockindex)
-{
- CURLcode retcode = CURLE_OK;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct Curl_easy *data = conn->data;
-
- DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
-
- if(SSL_SET_OPTION(primary.sessionid)) {
- int ret;
- ssl_session *our_ssl_sessionid;
- void *old_ssl_sessionid = NULL;
-
- our_ssl_sessionid = calloc(1, sizeof(ssl_session));
- if(!our_ssl_sessionid)
- return CURLE_OUT_OF_MEMORY;
-
- ret = ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
- if(ret) {
- failf(data, "ssl_get_session returned -0x%x", -ret);
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- /* If there's already a matching session in the cache, delete it */
- Curl_ssl_sessionid_lock(conn);
- if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
- Curl_ssl_delsessionid(conn, old_ssl_sessionid);
-
- retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
- Curl_ssl_sessionid_unlock(conn);
- if(retcode) {
- free(our_ssl_sessionid);
- failf(data, "failed to store ssl session");
- return retcode;
- }
- }
-
- connssl->connecting_state = ssl_connect_done;
-
- return CURLE_OK;
-}
-
-static ssize_t polarssl_send(struct connectdata *conn,
- int sockindex,
- const void *mem,
- size_t len,
- CURLcode *curlcode)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- int ret = -1;
-
- ret = ssl_write(&BACKEND->ssl,
- (unsigned char *)mem, len);
-
- if(ret < 0) {
- *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ?
- CURLE_AGAIN : CURLE_SEND_ERROR;
- ret = -1;
- }
-
- return ret;
-}
-
-static void Curl_polarssl_close(struct connectdata *conn, int sockindex)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- rsa_free(&BACKEND->rsa);
- x509_crt_free(&BACKEND->clicert);
- x509_crt_free(&BACKEND->cacert);
- x509_crl_free(&BACKEND->crl);
- ssl_free(&BACKEND->ssl);
-}
-
-static ssize_t polarssl_recv(struct connectdata *conn,
- int num,
- char *buf,
- size_t buffersize,
- CURLcode *curlcode)
-{
- struct ssl_connect_data *connssl = &conn->ssl[num];
- int ret = -1;
- ssize_t len = -1;
-
- memset(buf, 0, buffersize);
- ret = ssl_read(&BACKEND->ssl, (unsigned char *)buf, buffersize);
-
- if(ret <= 0) {
- if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
- return 0;
-
- *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ?
- CURLE_AGAIN : CURLE_RECV_ERROR;
- return -1;
- }
-
- len = ret;
-
- return len;
-}
-
-static void Curl_polarssl_session_free(void *ptr)
-{
- ssl_session_free(ptr);
- free(ptr);
-}
-
-/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and
- higher) will be mbed TLS branded.. */
-
-static size_t Curl_polarssl_version(char *buffer, size_t size)
-{
- unsigned int version = version_get_number();
- return msnprintf(buffer, size, "%s/%d.%d.%d",
- version >= 0x01030A00?"mbedTLS":"PolarSSL",
- version>>24, (version>>16)&0xff, (version>>8)&0xff);
-}
-
-static CURLcode
-polarssl_connect_common(struct connectdata *conn,
- int sockindex,
- bool nonblocking,
- bool *done)
-{
- CURLcode result;
- struct Curl_easy *data = conn->data;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
- timediff_t timeout_ms;
- int what;
-
- /* check if the connection has already been established */
- if(ssl_connection_complete == connssl->state) {
- *done = TRUE;
- return CURLE_OK;
- }
-
- if(ssl_connect_1 == connssl->connecting_state) {
- /* Find out how much more time we're allowed */
- timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
- if(timeout_ms < 0) {
- /* no need to continue if time already is up */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- result = polarssl_connect_step1(conn, sockindex);
- if(result)
- return result;
- }
-
- while(ssl_connect_2 == connssl->connecting_state ||
- ssl_connect_2_reading == connssl->connecting_state ||
- ssl_connect_2_writing == connssl->connecting_state) {
-
- /* check allowed time left */
- timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
- if(timeout_ms < 0) {
- /* no need to continue if time already is up */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- /* if ssl is expecting something, check if it's available. */
- if(connssl->connecting_state == ssl_connect_2_reading ||
- connssl->connecting_state == ssl_connect_2_writing) {
-
- curl_socket_t writefd = ssl_connect_2_writing ==
- connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
- curl_socket_t readfd = ssl_connect_2_reading ==
- connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
-
- what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
- nonblocking?0:(time_t)timeout_ms);
- if(what < 0) {
- /* fatal error */
- failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
- return CURLE_SSL_CONNECT_ERROR;
- }
- else if(0 == what) {
- if(nonblocking) {
- *done = FALSE;
- return CURLE_OK;
- }
- else {
- /* timeout */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
- }
- /* socket is readable or writable */
- }
-
- /* Run transaction, and return to the caller if it failed or if
- * this connection is part of a multi handle and this loop would
- * execute again. This permits the owner of a multi handle to
- * abort a connection attempt before step2 has completed while
- * ensuring that a client using select() or epoll() will always
- * have a valid fdset to wait on.
- */
- result = polarssl_connect_step2(conn, sockindex);
- if(result || (nonblocking &&
- (ssl_connect_2 == connssl->connecting_state ||
- ssl_connect_2_reading == connssl->connecting_state ||
- ssl_connect_2_writing == connssl->connecting_state)))
- return result;
-
- } /* repeat step2 until all transactions are done. */
-
- if(ssl_connect_3 == connssl->connecting_state) {
- result = polarssl_connect_step3(conn, sockindex);
- if(result)
- return result;
- }
-
- if(ssl_connect_done == connssl->connecting_state) {
- connssl->state = ssl_connection_complete;
- conn->recv[sockindex] = polarssl_recv;
- conn->send[sockindex] = polarssl_send;
- *done = TRUE;
- }
- else
- *done = FALSE;
-
- /* Reset our connect state machine */
- connssl->connecting_state = ssl_connect_1;
-
- return CURLE_OK;
-}
-
-static CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn,
- int sockindex, bool *done)
-{
- return polarssl_connect_common(conn, sockindex, TRUE, done);
-}
-
-
-static CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex)
-{
- CURLcode result;
- bool done = FALSE;
-
- result = polarssl_connect_common(conn, sockindex, FALSE, &done);
- if(result)
- return result;
-
- DEBUGASSERT(done);
-
- return CURLE_OK;
-}
-
-/*
- * return 0 error initializing SSL
- * return 1 SSL initialized successfully
- */
-static int Curl_polarssl_init(void)
-{
- return Curl_polarsslthreadlock_thread_setup();
-}
-
-static void Curl_polarssl_cleanup(void)
-{
- (void)Curl_polarsslthreadlock_thread_cleanup();
-}
-
-static bool Curl_polarssl_data_pending(const struct connectdata *conn,
- int sockindex)
-{
- const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- return ssl_get_bytes_avail(&BACKEND->ssl) != 0;
-}
-
-static CURLcode Curl_polarssl_sha256sum(const unsigned char *input,
- size_t inputlen,
- unsigned char *sha256sum,
- size_t sha256len UNUSED_PARAM)
-{
- (void)sha256len;
- sha256(input, inputlen, sha256sum, 0);
- return CURLE_OK;
-}
-
-static void *Curl_polarssl_get_internals(struct ssl_connect_data *connssl,
- CURLINFO info UNUSED_PARAM)
-{
- (void)info;
- return &BACKEND->ssl;
-}
-
-const struct Curl_ssl Curl_ssl_polarssl = {
- { CURLSSLBACKEND_POLARSSL, "polarssl" }, /* info */
-
- SSLSUPP_CA_PATH |
- SSLSUPP_PINNEDPUBKEY,
-
- sizeof(struct ssl_backend_data),
-
- Curl_polarssl_init, /* init */
- Curl_polarssl_cleanup, /* cleanup */
- Curl_polarssl_version, /* version */
- Curl_none_check_cxn, /* check_cxn */
- Curl_none_shutdown, /* shutdown */
- Curl_polarssl_data_pending, /* data_pending */
- /* This might cause libcurl to use a weeker random! */
- Curl_none_random, /* random */
- Curl_none_cert_status_request, /* cert_status_request */
- Curl_polarssl_connect, /* connect */
- Curl_polarssl_connect_nonblocking, /* connect_nonblocking */
- Curl_polarssl_get_internals, /* get_internals */
- Curl_polarssl_close, /* close_one */
- Curl_none_close_all, /* close_all */
- Curl_polarssl_session_free, /* session_free */
- Curl_none_set_engine, /* set_engine */
- Curl_none_set_engine_default, /* set_engine_default */
- Curl_none_engines_list, /* engines_list */
- Curl_none_false_start, /* false_start */
- Curl_none_md5sum, /* md5sum */
- Curl_polarssl_sha256sum /* sha256sum */
-};
-
-#endif /* USE_POLARSSL */
diff --git a/libs/libcurl/src/vtls/polarssl.h b/libs/libcurl/src/vtls/polarssl.h
deleted file mode 100644
index f36f24f8df..0000000000
--- a/libs/libcurl/src/vtls/polarssl.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef HEADER_CURL_POLARSSL_H
-#define HEADER_CURL_POLARSSL_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#ifdef USE_POLARSSL
-
-extern const struct Curl_ssl Curl_ssl_polarssl;
-
-#endif /* USE_POLARSSL */
-#endif /* HEADER_CURL_POLARSSL_H */
diff --git a/libs/libcurl/src/vtls/polarssl_threadlock.c b/libs/libcurl/src/vtls/polarssl_threadlock.c
deleted file mode 100644
index 4e269c8e6a..0000000000
--- a/libs/libcurl/src/vtls/polarssl_threadlock.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2013 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#if (defined(USE_POLARSSL) || defined(USE_MBEDTLS)) && \
- ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
- (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)))
-
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
-# include <pthread.h>
-# define POLARSSL_MUTEX_T pthread_mutex_t
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
-# include <process.h>
-# define POLARSSL_MUTEX_T HANDLE
-#endif
-
-#include "polarssl_threadlock.h"
-#include "curl_printf.h"
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* number of thread locks */
-#define NUMT 2
-
-/* This array will store all of the mutexes available to PolarSSL. */
-static POLARSSL_MUTEX_T *mutex_buf = NULL;
-
-int Curl_polarsslthreadlock_thread_setup(void)
-{
- int i;
-
- mutex_buf = calloc(NUMT * sizeof(POLARSSL_MUTEX_T), 1);
- if(!mutex_buf)
- return 0; /* error, no number of threads defined */
-
- for(i = 0; i < NUMT; i++) {
- int ret;
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
- ret = pthread_mutex_init(&mutex_buf[i], NULL);
- if(ret)
- return 0; /* pthread_mutex_init failed */
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
- mutex_buf[i] = CreateMutex(0, FALSE, 0);
- if(mutex_buf[i] == 0)
- return 0; /* CreateMutex failed */
-#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
- }
-
- return 1; /* OK */
-}
-
-int Curl_polarsslthreadlock_thread_cleanup(void)
-{
- int i;
-
- if(!mutex_buf)
- return 0; /* error, no threads locks defined */
-
- for(i = 0; i < NUMT; i++) {
- int ret;
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
- ret = pthread_mutex_destroy(&mutex_buf[i]);
- if(ret)
- return 0; /* pthread_mutex_destroy failed */
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
- ret = CloseHandle(mutex_buf[i]);
- if(!ret)
- return 0; /* CloseHandle failed */
-#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
- }
- free(mutex_buf);
- mutex_buf = NULL;
-
- return 1; /* OK */
-}
-
-int Curl_polarsslthreadlock_lock_function(int n)
-{
- if(n < NUMT) {
- int ret;
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
- ret = pthread_mutex_lock(&mutex_buf[n]);
- if(ret) {
- DEBUGF(fprintf(stderr,
- "Error: polarsslthreadlock_lock_function failed\n"));
- return 0; /* pthread_mutex_lock failed */
- }
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
- ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0);
- if(ret) {
- DEBUGF(fprintf(stderr,
- "Error: polarsslthreadlock_lock_function failed\n"));
- return 0; /* pthread_mutex_lock failed */
- }
-#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
- }
- return 1; /* OK */
-}
-
-int Curl_polarsslthreadlock_unlock_function(int n)
-{
- if(n < NUMT) {
- int ret;
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
- ret = pthread_mutex_unlock(&mutex_buf[n]);
- if(ret) {
- DEBUGF(fprintf(stderr,
- "Error: polarsslthreadlock_unlock_function failed\n"));
- return 0; /* pthread_mutex_unlock failed */
- }
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
- ret = ReleaseMutex(mutex_buf[n]);
- if(!ret) {
- DEBUGF(fprintf(stderr,
- "Error: polarsslthreadlock_unlock_function failed\n"));
- return 0; /* pthread_mutex_lock failed */
- }
-#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
- }
- return 1; /* OK */
-}
-
-#endif /* USE_POLARSSL || USE_MBEDTLS */
diff --git a/libs/libcurl/src/vtls/polarssl_threadlock.h b/libs/libcurl/src/vtls/polarssl_threadlock.h
deleted file mode 100644
index c1900bfe81..0000000000
--- a/libs/libcurl/src/vtls/polarssl_threadlock.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef HEADER_CURL_POLARSSL_THREADLOCK_H
-#define HEADER_CURL_POLARSSL_THREADLOCK_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2013 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#if (defined USE_POLARSSL) || (defined USE_MBEDTLS)
-
-#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
- (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H))
-
-int Curl_polarsslthreadlock_thread_setup(void);
-int Curl_polarsslthreadlock_thread_cleanup(void);
-int Curl_polarsslthreadlock_lock_function(int n);
-int Curl_polarsslthreadlock_unlock_function(int n);
-
-#else
-
-#define Curl_polarsslthreadlock_thread_setup() 1
-#define Curl_polarsslthreadlock_thread_cleanup() 1
-#define Curl_polarsslthreadlock_lock_function(x) 1
-#define Curl_polarsslthreadlock_unlock_function(x) 1
-
-#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
-
-#endif /* USE_POLARSSL */
-
-#endif /* HEADER_CURL_POLARSSL_THREADLOCK_H */
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c
index 0818d947a4..f665ee3404 100644
--- a/libs/libcurl/src/vtls/schannel.c
+++ b/libs/libcurl/src/vtls/schannel.c
@@ -27,16 +27,6 @@
* but vtls.c should ever call or use these functions.
*/
-/*
- * Based upon the PolarSSL implementation in polarssl.c and polarssl.h:
- * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * Thanks for code and inspiration!
- */
-
#include "curl_setup.h"
#ifdef USE_SCHANNEL
diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h
index f58adee6e8..a81b2f22d1 100644
--- a/libs/libcurl/src/vtls/vtls.h
+++ b/libs/libcurl/src/vtls/vtls.h
@@ -262,7 +262,6 @@ bool Curl_ssl_false_start(void);
#define Curl_ssl_send(a,b,c,d,e) -1
#define Curl_ssl_recv(a,b,c,d,e) -1
#define Curl_ssl_initsessions(x,y) CURLE_OK
-#define Curl_ssl_version(x,y) 0
#define Curl_ssl_data_pending(x,y) 0
#define Curl_ssl_check_cxn(x) 0
#define Curl_ssl_free_certinfo(x) Curl_nop_stmt