summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/cookie.c3
-rw-r--r--lib/multi.c42
-rw-r--r--lib/sendf.c4
-rw-r--r--lib/socks.c208
-rw-r--r--lib/vssh/wolfssh.c288
-rw-r--r--lib/vtls/mbedtls.c39
-rw-r--r--lib/vtls/openssl.c35
7 files changed, 330 insertions, 289 deletions
diff --git a/lib/cookie.c b/lib/cookie.c
index b72dd99bc..99b5e43d6 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -1615,6 +1615,9 @@ static struct curl_slist *cookie_list(struct Curl_easy *data)
if(!data->cookies || (data->cookies->numcookies == 0))
return NULL;
+ /* at first, remove expired cookies */
+ remove_expired(data->cookies);
+
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
for(n = Curl_llist_head(&data->cookies->cookielist[i]); n;
n = Curl_node_next(n)) {
diff --git a/lib/multi.c b/lib/multi.c
index d38155cd9..1c09b14b6 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1026,9 +1026,13 @@ CURLMcode Curl_multi_pollset(struct Curl_easy *data,
case MSTATE_CONNECTING:
case MSTATE_TUNNELING:
- result = mstate_connecting_pollset(data, ps);
- if(!result)
- result = Curl_conn_adjust_pollset(data, data->conn, ps);
+ if(!Curl_xfer_recv_is_paused(data)) {
+ result = mstate_connecting_pollset(data, ps);
+ if(!result)
+ result = Curl_conn_adjust_pollset(data, data->conn, ps);
+ }
+ else
+ expect_sockets = FALSE;
break;
case MSTATE_PROTOCONNECT:
@@ -2434,22 +2438,24 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
case MSTATE_CONNECTING:
/* awaiting a completion of an asynch TCP connect */
DEBUGASSERT(data->conn);
- result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
- if(connected && !result) {
- if(!data->conn->bits.reuse &&
- Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) {
- /* new connection, can multiplex, wake pending handles */
- process_pending_handles(data->multi);
+ if(!Curl_xfer_recv_is_paused(data)) {
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
+ if(connected && !result) {
+ if(!data->conn->bits.reuse &&
+ Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) {
+ /* new connection, can multiplex, wake pending handles */
+ process_pending_handles(data->multi);
+ }
+ rc = CURLM_CALL_MULTI_PERFORM;
+ multistate(data, MSTATE_PROTOCONNECT);
+ }
+ else if(result) {
+ /* failure detected */
+ multi_posttransfer(data);
+ multi_done(data, result, TRUE);
+ stream_error = TRUE;
+ break;
}
- rc = CURLM_CALL_MULTI_PERFORM;
- multistate(data, MSTATE_PROTOCONNECT);
- }
- else if(result) {
- /* failure detected */
- multi_posttransfer(data);
- multi_done(data, result, TRUE);
- stream_error = TRUE;
- break;
}
break;
diff --git a/lib/sendf.c b/lib/sendf.c
index 6bd4b1bfb..43b30ecc7 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -293,9 +293,9 @@ static CURLcode cw_download_write(struct Curl_easy *data,
}
if((type & CLIENTWRITE_EOS) && !data->req.no_body &&
- (data->req.maxdownload > data->req.bytecount)) {
+ (data->req.size > data->req.bytecount)) {
failf(data, "end of response with %" FMT_OFF_T " bytes missing",
- data->req.maxdownload - data->req.bytecount);
+ data->req.size - data->req.bytecount);
return CURLE_PARTIAL_FILE;
}
}
diff --git a/lib/socks.c b/lib/socks.c
index 4f9c98dba..8084489c9 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -529,6 +529,110 @@ CONNECT_REQ_INIT:
return CURLPX_OK; /* Proxy was successful! */
}
+static CURLproxycode socks5_init(struct Curl_cfilter *cf,
+ struct socks_state *sx,
+ struct Curl_easy *data,
+ const bool socks5_resolve_local,
+ const size_t hostname_len)
+{
+ struct connectdata *conn = cf->conn;
+ const unsigned char auth = data->set.socks5auth;
+ unsigned char *socksreq = sx->buffer;
+
+ if(conn->bits.httpproxy)
+ CURL_TRC_CF(data, cf, "SOCKS5: connecting to HTTP proxy %s port %d",
+ sx->hostname, sx->remote_port);
+
+ /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
+ if(!socks5_resolve_local && hostname_len > 255) {
+ failf(data, "SOCKS5: the destination hostname is too long to be "
+ "resolved remotely by the proxy.");
+ return CURLPX_LONG_HOSTNAME;
+ }
+
+ if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
+ infof(data, "warning: unsupported value passed to "
+ "CURLOPT_SOCKS5_AUTH: %u", auth);
+ if(!(auth & CURLAUTH_BASIC))
+ /* disable username/password auth */
+ sx->proxy_user = NULL;
+
+ if(!sx->outstanding) {
+ size_t idx = 0;
+ socksreq[idx++] = 5; /* version */
+ idx++; /* number of authentication methods */
+ socksreq[idx++] = 0; /* no authentication */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ if(auth & CURLAUTH_GSSAPI)
+ socksreq[idx++] = 1; /* GSS-API */
+#endif
+ if(sx->proxy_user)
+ socksreq[idx++] = 2; /* username/password */
+ /* write the number of authentication methods */
+ socksreq[1] = (unsigned char) (idx - 2);
+
+ sx->outp = socksreq;
+ DEBUGASSERT(idx <= sizeof(sx->buffer));
+ sx->outstanding = idx;
+ }
+
+ return socks_state_send(cf, sx, data, CURLPX_SEND_CONNECT,
+ "initial SOCKS5 request");
+}
+
+static CURLproxycode socks5_auth_init(struct Curl_cfilter *cf,
+ struct socks_state *sx,
+ struct Curl_easy *data)
+{
+ /* Needs username and password */
+ size_t proxy_user_len, proxy_password_len;
+ size_t len = 0;
+ unsigned char *socksreq = sx->buffer;
+
+ if(sx->proxy_user && sx->proxy_password) {
+ proxy_user_len = strlen(sx->proxy_user);
+ proxy_password_len = strlen(sx->proxy_password);
+ }
+ else {
+ proxy_user_len = 0;
+ proxy_password_len = 0;
+ }
+
+ /* username/password request looks like
+ * +----+------+----------+------+----------+
+ * |VER | ULEN | UNAME | PLEN | PASSWD |
+ * +----+------+----------+------+----------+
+ * | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
+ * +----+------+----------+------+----------+
+ */
+ socksreq[len++] = 1; /* username/pw subnegotiation version */
+ socksreq[len++] = (unsigned char) proxy_user_len;
+ if(sx->proxy_user && proxy_user_len) {
+ /* the length must fit in a single byte */
+ if(proxy_user_len > 255) {
+ failf(data, "Excessive username length for proxy auth");
+ return CURLPX_LONG_USER;
+ }
+ memcpy(socksreq + len, sx->proxy_user, proxy_user_len);
+ }
+ len += proxy_user_len;
+ socksreq[len++] = (unsigned char) proxy_password_len;
+ if(sx->proxy_password && proxy_password_len) {
+ /* the length must fit in a single byte */
+ if(proxy_password_len > 255) {
+ failf(data, "Excessive password length for proxy auth");
+ return CURLPX_LONG_PASSWD;
+ }
+ memcpy(socksreq + len, sx->proxy_password, proxy_password_len);
+ }
+ len += proxy_password_len;
+ sxstate(sx, cf, data, CONNECT_AUTH_SEND);
+ DEBUGASSERT(len <= sizeof(sx->buffer));
+ sx->outstanding = len;
+ sx->outp = socksreq;
+ return CURLPX_OK;
+}
+
/*
* This function logs in to a SOCKS5 proxy and sends the specifics to the final
* destination server.
@@ -555,66 +659,20 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
*/
struct connectdata *conn = cf->conn;
unsigned char *socksreq = sx->buffer;
- size_t idx;
CURLcode result;
CURLproxycode presult;
bool socks5_resolve_local =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS5);
const size_t hostname_len = strlen(sx->hostname);
size_t len = 0;
- const unsigned char auth = data->set.socks5auth;
bool allow_gssapi = FALSE;
struct Curl_dns_entry *dns = NULL;
switch(sx->state) {
case CONNECT_SOCKS_INIT:
- if(conn->bits.httpproxy)
- CURL_TRC_CF(data, cf, "SOCKS5: connecting to HTTP proxy %s port %d",
- sx->hostname, sx->remote_port);
-
- /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
- if(!socks5_resolve_local && hostname_len > 255) {
- failf(data, "SOCKS5: the destination hostname is too long to be "
- "resolved remotely by the proxy.");
- return CURLPX_LONG_HOSTNAME;
- }
-
- if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
- infof(data, "warning: unsupported value passed to "
- "CURLOPT_SOCKS5_AUTH: %u", auth);
- if(!(auth & CURLAUTH_BASIC))
- /* disable username/password auth */
- sx->proxy_user = NULL;
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- if(auth & CURLAUTH_GSSAPI)
- allow_gssapi = TRUE;
-#endif
-
- if(!sx->outstanding) {
- idx = 0;
- socksreq[idx++] = 5; /* version */
- idx++; /* number of authentication methods */
- socksreq[idx++] = 0; /* no authentication */
- if(allow_gssapi)
- socksreq[idx++] = 1; /* GSS-API */
- if(sx->proxy_user)
- socksreq[idx++] = 2; /* username/password */
- /* write the number of authentication methods */
- socksreq[1] = (unsigned char) (idx - 2);
-
- sx->outp = socksreq;
- DEBUGASSERT(idx <= sizeof(sx->buffer));
- sx->outstanding = idx;
- }
-
- presult = socks_state_send(cf, sx, data, CURLPX_SEND_CONNECT,
- "initial SOCKS5 request");
- if(CURLPX_OK != presult)
+ presult = socks5_init(cf, sx, data, socks5_resolve_local, hostname_len);
+ if(presult || sx->outstanding)
return presult;
- else if(sx->outstanding) {
- /* remain in sending state */
- return CURLPX_OK;
- }
sxstate(sx, cf, data, CONNECT_SOCKS_READ);
goto CONNECT_SOCKS_READ_INIT;
case CONNECT_SOCKS_SEND:
@@ -635,6 +693,10 @@ CONNECT_SOCKS_READ_INIT:
case CONNECT_SOCKS_READ:
presult = socks_state_recv(cf, sx, data, CURLPX_RECV_CONNECT,
"initial SOCKS5 response");
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ if(data->set.socks5auth & CURLAUTH_GSSAPI)
+ allow_gssapi = TRUE;
+#endif
if(CURLPX_OK != presult)
return presult;
else if(sx->outstanding) {
@@ -690,52 +752,10 @@ CONNECT_SOCKS_READ_INIT:
break;
CONNECT_AUTH_INIT:
- case CONNECT_AUTH_INIT: {
- /* Needs username and password */
- size_t proxy_user_len, proxy_password_len;
- if(sx->proxy_user && sx->proxy_password) {
- proxy_user_len = strlen(sx->proxy_user);
- proxy_password_len = strlen(sx->proxy_password);
- }
- else {
- proxy_user_len = 0;
- proxy_password_len = 0;
- }
-
- /* username/password request looks like
- * +----+------+----------+------+----------+
- * |VER | ULEN | UNAME | PLEN | PASSWD |
- * +----+------+----------+------+----------+
- * | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
- * +----+------+----------+------+----------+
- */
- len = 0;
- socksreq[len++] = 1; /* username/pw subnegotiation version */
- socksreq[len++] = (unsigned char) proxy_user_len;
- if(sx->proxy_user && proxy_user_len) {
- /* the length must fit in a single byte */
- if(proxy_user_len > 255) {
- failf(data, "Excessive username length for proxy auth");
- return CURLPX_LONG_USER;
- }
- memcpy(socksreq + len, sx->proxy_user, proxy_user_len);
- }
- len += proxy_user_len;
- socksreq[len++] = (unsigned char) proxy_password_len;
- if(sx->proxy_password && proxy_password_len) {
- /* the length must fit in a single byte */
- if(proxy_password_len > 255) {
- failf(data, "Excessive password length for proxy auth");
- return CURLPX_LONG_PASSWD;
- }
- memcpy(socksreq + len, sx->proxy_password, proxy_password_len);
- }
- len += proxy_password_len;
- sxstate(sx, cf, data, CONNECT_AUTH_SEND);
- DEBUGASSERT(len <= sizeof(sx->buffer));
- sx->outstanding = len;
- sx->outp = socksreq;
- }
+ case CONNECT_AUTH_INIT:
+ presult = socks5_auth_init(cf, sx, data);
+ if(presult)
+ return presult;
FALLTHROUGH();
case CONNECT_AUTH_SEND:
presult = socks_state_send(cf, sx, data, CURLPX_SEND_AUTH,
diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c
index 556eda0cb..7cd0402a9 100644
--- a/lib/vssh/wolfssh.c
+++ b/lib/vssh/wolfssh.c
@@ -463,6 +463,150 @@ error:
return CURLE_FAILED_INIT;
}
+static CURLcode wssh_sftp_upload_init(struct Curl_easy *data,
+ struct ssh_conn *sshc,
+ struct SSHPROTO *sftp_scp,
+ bool *block)
+{
+ word32 flags;
+ WS_SFTP_FILEATRB createattrs;
+ struct connectdata *conn = data->conn;
+ int rc;
+ if(data->state.resume_from) {
+ WS_SFTP_FILEATRB attrs;
+ if(data->state.resume_from < 0) {
+ rc = wolfSSH_SFTP_STAT(sshc->ssh_session, sftp_scp->path,
+ &attrs);
+ if(rc != WS_SUCCESS)
+ return CURLE_SSH;
+
+ if(rc) {
+ data->state.resume_from = 0;
+ }
+ else {
+ curl_off_t size = ((curl_off_t)attrs.sz[1] << 32) | attrs.sz[0];
+ if(size < 0) {
+ failf(data, "Bad file size (%" FMT_OFF_T ")", size);
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ data->state.resume_from = size;
+ }
+ }
+ }
+
+ if(data->set.remote_append)
+ /* Try to open for append, but create if nonexisting */
+ flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_APPEND;
+ else if(data->state.resume_from > 0)
+ /* If we have restart position then open for append */
+ flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_APPEND;
+ else
+ /* Clear file before writing (normal behavior) */
+ flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_TRUNC;
+
+ memset(&createattrs, 0, sizeof(createattrs));
+ createattrs.per = (word32)data->set.new_file_perms;
+ sshc->handleSz = sizeof(sshc->handle);
+ rc = wolfSSH_SFTP_Open(sshc->ssh_session, sftp_scp->path,
+ flags, &createattrs,
+ sshc->handle, &sshc->handleSz);
+ if(rc == WS_FATAL_ERROR)
+ rc = wolfSSH_get_error(sshc->ssh_session);
+ if(rc == WS_WANT_READ) {
+ *block = TRUE;
+ conn->waitfor = KEEP_RECV;
+ return CURLE_OK;
+ }
+ else if(rc == WS_WANT_WRITE) {
+ *block = TRUE;
+ conn->waitfor = KEEP_SEND;
+ return CURLE_OK;
+ }
+ else if(rc == WS_SUCCESS) {
+ infof(data, "wolfssh SFTP open succeeded");
+ }
+ else {
+ failf(data, "wolfssh SFTP upload open failed: %d", rc);
+ return CURLE_SSH;
+ }
+ wssh_state(data, sshc, SSH_SFTP_DOWNLOAD_STAT);
+
+ /* If we have a restart point then we need to seek to the correct
+ position. */
+ if(data->state.resume_from > 0) {
+ /* Let's read off the proper amount of bytes from the input. */
+ int seekerr = CURL_SEEKFUNC_OK;
+ if(data->set.seek_func) {
+ Curl_set_in_callback(data, TRUE);
+ seekerr = data->set.seek_func(data->set.seek_client,
+ data->state.resume_from, SEEK_SET);
+ Curl_set_in_callback(data, FALSE);
+ }
+
+ if(seekerr != CURL_SEEKFUNC_OK) {
+ curl_off_t passed = 0;
+
+ if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+ failf(data, "Could not seek stream");
+ return CURLE_FTP_COULDNT_USE_REST;
+ }
+ /* seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */
+ do {
+ char scratch[4*1024];
+ size_t readthisamountnow =
+ (data->state.resume_from - passed >
+ (curl_off_t)sizeof(scratch)) ?
+ sizeof(scratch) : curlx_sotouz(data->state.resume_from - passed);
+
+ size_t actuallyread;
+ Curl_set_in_callback(data, TRUE);
+ actuallyread = data->state.fread_func(scratch, 1,
+ readthisamountnow,
+ data->state.in);
+ Curl_set_in_callback(data, FALSE);
+
+ passed += actuallyread;
+ if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+ /* this checks for greater-than only to make sure that the
+ CURL_READFUNC_ABORT return code still aborts */
+ failf(data, "Failed to read data");
+ return CURLE_FTP_COULDNT_USE_REST;
+ }
+ } while(passed < data->state.resume_from);
+ }
+
+ /* now, decrease the size of the read */
+ if(data->state.infilesize > 0) {
+ data->state.infilesize -= data->state.resume_from;
+ data->req.size = data->state.infilesize;
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+ }
+
+ sshc->offset += data->state.resume_from;
+ }
+ if(data->state.infilesize > 0) {
+ data->req.size = data->state.infilesize;
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+ }
+ /* upload data */
+ Curl_xfer_setup_send(data, FIRSTSOCKET);
+
+ /* not set by Curl_xfer_setup to preserve keepon bits */
+ data->conn->recv_idx = FIRSTSOCKET;
+
+ /* store this original bitmask setup to use later on if we cannot
+ figure out a "real" bitmask */
+ sshc->orig_waitfor = data->req.keepon;
+
+ /* since we do not really wait for anything at this point, we want the state
+ machine to move on as soon as possible */
+ Curl_multi_mark_dirty(data);
+
+ wssh_state(data, sshc, SSH_STOP);
+
+ return CURLE_OK;
+}
+
/*
* wssh_statemach_act() runs the SSH state machine as far as it can without
* blocking and without reaching the end. The data the pointer 'block' points
@@ -597,148 +741,10 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data,
wssh_state(data, sshc, SSH_SFTP_DOWNLOAD_INIT);
}
break;
- case SSH_SFTP_UPLOAD_INIT: {
- word32 flags;
- WS_SFTP_FILEATRB createattrs;
- if(data->state.resume_from) {
- WS_SFTP_FILEATRB attrs;
- if(data->state.resume_from < 0) {
- rc = wolfSSH_SFTP_STAT(sshc->ssh_session, sftp_scp->path,
- &attrs);
- if(rc != WS_SUCCESS)
- break;
-
- if(rc) {
- data->state.resume_from = 0;
- }
- else {
- curl_off_t size = ((curl_off_t)attrs.sz[1] << 32) | attrs.sz[0];
- if(size < 0) {
- failf(data, "Bad file size (%" FMT_OFF_T ")", size);
- return CURLE_BAD_DOWNLOAD_RESUME;
- }
- data->state.resume_from = size;
- }
- }
- }
-
- if(data->set.remote_append)
- /* Try to open for append, but create if nonexisting */
- flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_APPEND;
- else if(data->state.resume_from > 0)
- /* If we have restart position then open for append */
- flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_APPEND;
- else
- /* Clear file before writing (normal behavior) */
- flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_TRUNC;
-
- memset(&createattrs, 0, sizeof(createattrs));
- createattrs.per = (word32)data->set.new_file_perms;
- sshc->handleSz = sizeof(sshc->handle);
- rc = wolfSSH_SFTP_Open(sshc->ssh_session, sftp_scp->path,
- flags, &createattrs,
- sshc->handle, &sshc->handleSz);
- if(rc == WS_FATAL_ERROR)
- rc = wolfSSH_get_error(sshc->ssh_session);
- if(rc == WS_WANT_READ) {
- *block = TRUE;
- conn->waitfor = KEEP_RECV;
- return CURLE_OK;
- }
- else if(rc == WS_WANT_WRITE) {
- *block = TRUE;
- conn->waitfor = KEEP_SEND;
- return CURLE_OK;
- }
- else if(rc == WS_SUCCESS) {
- infof(data, "wolfssh SFTP open succeeded");
- }
- else {
- failf(data, "wolfssh SFTP upload open failed: %d", rc);
- return CURLE_SSH;
- }
- wssh_state(data, sshc, SSH_SFTP_DOWNLOAD_STAT);
-
- /* If we have a restart point then we need to seek to the correct
- position. */
- if(data->state.resume_from > 0) {
- /* Let's read off the proper amount of bytes from the input. */
- int seekerr = CURL_SEEKFUNC_OK;
- if(data->set.seek_func) {
- Curl_set_in_callback(data, TRUE);
- seekerr = data->set.seek_func(data->set.seek_client,
- data->state.resume_from, SEEK_SET);
- Curl_set_in_callback(data, FALSE);
- }
-
- if(seekerr != CURL_SEEKFUNC_OK) {
- curl_off_t passed = 0;
-
- if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
- failf(data, "Could not seek stream");
- return CURLE_FTP_COULDNT_USE_REST;
- }
- /* seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */
- do {
- char scratch[4*1024];
- size_t readthisamountnow =
- (data->state.resume_from - passed >
- (curl_off_t)sizeof(scratch)) ?
- sizeof(scratch) : curlx_sotouz(data->state.resume_from - passed);
-
- size_t actuallyread;
- Curl_set_in_callback(data, TRUE);
- actuallyread = data->state.fread_func(scratch, 1,
- readthisamountnow,
- data->state.in);
- Curl_set_in_callback(data, FALSE);
-
- passed += actuallyread;
- if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
- /* this checks for greater-than only to make sure that the
- CURL_READFUNC_ABORT return code still aborts */
- failf(data, "Failed to read data");
- return CURLE_FTP_COULDNT_USE_REST;
- }
- } while(passed < data->state.resume_from);
- }
-
- /* now, decrease the size of the read */
- if(data->state.infilesize > 0) {
- data->state.infilesize -= data->state.resume_from;
- data->req.size = data->state.infilesize;
- Curl_pgrsSetUploadSize(data, data->state.infilesize);
- }
-
- sshc->offset += data->state.resume_from;
- }
- if(data->state.infilesize > 0) {
- data->req.size = data->state.infilesize;
- Curl_pgrsSetUploadSize(data, data->state.infilesize);
- }
- /* upload data */
- Curl_xfer_setup_send(data, FIRSTSOCKET);
-
- /* not set by Curl_xfer_setup to preserve keepon bits */
- data->conn->recv_idx = FIRSTSOCKET;
-
- if(result) {
- wssh_state(data, sshc, SSH_SFTP_CLOSE);
- sshc->actualcode = result;
- }
- else {
- /* store this original bitmask setup to use later on if we cannot
- figure out a "real" bitmask */
- sshc->orig_waitfor = data->req.keepon;
-
- /* since we do not really wait for anything at this point, we want the
- state machine to move on as soon as possible */
- Curl_multi_mark_dirty(data);
-
- wssh_state(data, sshc, SSH_STOP);
- }
+ case SSH_SFTP_UPLOAD_INIT:
+ result = wssh_sftp_upload_init(data, sshc, sftp_scp, block);
break;
- }
+
case SSH_SFTP_DOWNLOAD_INIT:
sshc->handleSz = sizeof(sshc->handle);
rc = wolfSSH_SFTP_Open(sshc->ssh_session, sftp_scp->path,
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index 06ae10232..a820a98b8 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -107,19 +107,6 @@ struct mbed_ssl_backend_data {
#define mbedtls_strerror(a,b,c) b[0] = 0
#endif
-/* PSA can be used independently of TLS 1.3 */
-#if defined(MBEDTLS_USE_PSA_CRYPTO) && MBEDTLS_VERSION_NUMBER >= 0x03060000
-#define HAS_PSA_SUPPORT
-#endif
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && MBEDTLS_VERSION_NUMBER >= 0x03060000
-#define HAS_TLS13_SUPPORT
-#endif
-
-#if defined(HAS_TLS13_SUPPORT) && defined(MBEDTLS_SSL_SESSION_TICKETS)
-#define HAS_SESSION_TICKETS
-#endif
-
#ifdef HAS_THREADING_SUPPORT
static mbedtls_entropy_context ts_entropy;
@@ -260,7 +247,7 @@ mbed_set_ssl_version_min_max(struct Curl_easy *data,
mbedtls_ssl_protocol_version ver_min = MBEDTLS_SSL_VERSION_TLS1_2;
mbedtls_ssl_protocol_version ver_max =
-#ifdef HAS_TLS13_SUPPORT
+#ifdef MBEDTLS_SSL_PROTO_TLS1_3
MBEDTLS_SSL_VERSION_TLS1_3
#else
MBEDTLS_SSL_VERSION_TLS1_2
@@ -276,7 +263,7 @@ mbed_set_ssl_version_min_max(struct Curl_easy *data,
ver_min = MBEDTLS_SSL_VERSION_TLS1_2;
break;
case CURL_SSLVERSION_TLSv1_3:
-#ifdef HAS_TLS13_SUPPORT
+#ifdef MBEDTLS_SSL_PROTO_TLS1_3
ver_min = MBEDTLS_SSL_VERSION_TLS1_3;
break;
#endif
@@ -290,7 +277,7 @@ mbed_set_ssl_version_min_max(struct Curl_easy *data,
case CURL_SSLVERSION_MAX_DEFAULT:
case CURL_SSLVERSION_MAX_NONE:
case CURL_SSLVERSION_MAX_TLSv1_3:
-#ifdef HAS_TLS13_SUPPORT
+#ifdef MBEDTLS_SSL_PROTO_TLS1_3
ver_max = MBEDTLS_SSL_VERSION_TLS1_3;
break;
#endif
@@ -363,7 +350,7 @@ mbed_set_selected_ciphers(struct Curl_easy *data,
if(!selected)
return CURLE_OUT_OF_MEMORY;
-#ifndef HAS_TLS13_SUPPORT
+#ifndef MBEDTLS_SSL_PROTO_TLS1_3
(void)ciphers13, (void)j;
#else
if(!ciphers13) {
@@ -411,7 +398,7 @@ add_ciphers:
selected[count++] = id;
}
-#ifdef HAS_TLS13_SUPPORT
+#ifdef MBEDTLS_SSL_PROTO_TLS1_3
if(ciphers == ciphers13 && ciphers12) {
ciphers = ciphers12;
goto add_ciphers;
@@ -760,7 +747,7 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
return CURLE_SSL_CONNECT_ERROR;
}
-#if defined(HAS_SESSION_TICKETS) && MBEDTLS_VERSION_NUMBER >= 0x03060100
+#ifdef MBEDTLS_SSL_SESSION_TICKETS
/* New in mbedTLS 3.6.1, need to enable, default is now disabled */
mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(&backend->config,
MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED);
@@ -799,7 +786,7 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
mbedtls_bio_cf_read,
NULL /* rev_timeout() */);
-#ifndef HAS_TLS13_SUPPORT
+#ifndef MBEDTLS_SSL_PROTO_TLS1_3
if(conn_config->cipher_list) {
CURLcode result = mbed_set_selected_ciphers(data, backend,
conn_config->cipher_list,
@@ -1149,7 +1136,7 @@ static CURLcode mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> -0x%04X",
len, -nwritten);
result = ((nwritten == MBEDTLS_ERR_SSL_WANT_WRITE)
-#ifdef HAS_TLS13_SUPPORT
+#ifdef MBEDTLS_SSL_PROTO_TLS1_3
|| (nwritten == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
#endif
) ? CURLE_AGAIN : CURLE_SEND_ERROR;
@@ -1219,7 +1206,7 @@ static CURLcode mbedtls_shutdown(struct Curl_cfilter *cf,
* WANT_READ, but has not encountered an EAGAIN. */
if(ret == MBEDTLS_ERR_SSL_WANT_READ)
ret = mbedtls_ssl_read(&backend->ssl, buf, sizeof(buf));
-#ifdef HAS_TLS13_SUPPORT
+#ifdef MBEDTLS_SSL_PROTO_TLS1_3
if(ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
continue;
#endif
@@ -1301,7 +1288,7 @@ static CURLcode mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
CURL_TRC_CF(data, cf, "mbedtls_ssl_read(len=%zu) -> -0x%04X",
buffersize, -nread);
switch(nread) {
-#ifdef HAS_SESSION_TICKETS
+#ifdef MBEDTLS_SSL_SESSION_TICKETS
case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET:
mbed_new_session(cf, data);
FALLTHROUGH();
@@ -1431,7 +1418,7 @@ static int mbedtls_init(void)
#ifdef HAS_THREADING_SUPPORT
entropy_init_mutex(&ts_entropy);
#endif
-#ifdef HAS_PSA_SUPPORT
+#ifdef MBEDTLS_USE_PSA_CRYPTO /* requires mbedTLS 3.6.0+ */
{
int ret;
#ifdef HAS_THREADING_SUPPORT
@@ -1444,7 +1431,7 @@ static int mbedtls_init(void)
if(ret != PSA_SUCCESS)
return 0;
}
-#endif /* HAS_PSA_SUPPORT */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
return 1;
}
@@ -1498,7 +1485,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
SSLSUPP_CERTINFO |
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_SSL_CTX |
-#ifdef HAS_TLS13_SUPPORT
+#ifdef MBEDTLS_SSL_PROTO_TLS1_3 /* requires mbedTLS 3.6.0+ */
SSLSUPP_TLS13_CIPHERSUITES |
#endif
SSLSUPP_HTTPS_PROXY |
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index dc4a6d122..e25c57304 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -61,6 +61,7 @@
#include "../vauth/vauth.h"
#include "keylog.h"
#include "hostcheck.h"
+#include "../transfer.h"
#include "../multiif.h"
#include "../curlx/strparse.h"
#include "../strdup.h"
@@ -850,13 +851,19 @@ static void ossl_keylog_callback(const SSL *ssl, const char *line)
static void
ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done)
{
- const SSL_SESSION *session = SSL_get_session(ssl);
+ const SSL_SESSION *session;
unsigned char client_random[SSL3_RANDOM_SIZE];
unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
int master_key_length = 0;
- if(!session || *keylog_done)
+ ERR_set_mark();
+
+ session = SSL_get_session(ssl);
+
+ if(!session || *keylog_done) {
+ ERR_pop_to_mark();
return;
+ }
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
/* ssl->s3 is not checked in OpenSSL 1.1.0-pre6, but let's assume that
@@ -872,6 +879,8 @@ ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done)
}
#endif
+ ERR_pop_to_mark();
+
/* The handshake has not progressed sufficiently yet, or this is a TLS 1.3
* session (when curl was built with older OpenSSL headers and running with
* newer OpenSSL runtime libraries). */
@@ -3327,10 +3336,8 @@ static CURLcode import_windows_cert_store(struct Curl_easy *data,
continue;
x509 = d2i_X509(NULL, &encoded_cert, (long)pContext->cbCertEncoded);
- if(!x509) {
- ERR_clear_error();
+ if(!x509)
continue;
- }
/* Try to import the certificate. This may fail for legitimate
reasons such as duplicate certificate, which is allowed by MS but
@@ -3661,6 +3668,8 @@ CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf,
!ssl_config->primary.CRLfile &&
!ssl_config->native_ca_store;
+ ERR_set_mark();
+
cached_store = ossl_get_cached_x509_store(cf, data);
if(cached_store && cache_criteria_met && X509_STORE_up_ref(cached_store)) {
SSL_CTX_set_cert_store(ssl_ctx, cached_store);
@@ -3674,6 +3683,8 @@ CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf,
}
}
+ ERR_pop_to_mark();
+
return result;
}
#else /* HAVE_SSL_X509_STORE_SHARE */
@@ -3681,9 +3692,17 @@ CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf,
struct Curl_easy *data,
SSL_CTX *ssl_ctx)
{
- X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
+ CURLcode result;
+ X509_STORE *store;
+
+ ERR_set_mark();
+
+ store = SSL_CTX_get_cert_store(ssl_ctx);
+ result = ossl_populate_x509_store(cf, data, store);
- return ossl_populate_x509_store(cf, data, store);
+ ERR_pop_to_mark();
+
+ return result;
}
#endif /* HAVE_SSL_X509_STORE_SHARE */
@@ -4584,7 +4603,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
#ifdef SSL_ERROR_WANT_RETRY_VERIFY
if(SSL_ERROR_WANT_RETRY_VERIFY == detail) {
CURL_TRC_CF(data, cf, "SSL_connect() -> want retry_verify");
- connssl->io_need = CURL_SSL_IO_NEED_RECV;
+ Curl_xfer_pause_recv(data, TRUE);
return CURLE_AGAIN;
}
#endif