diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/cookie.c | 3 | ||||
-rw-r--r-- | lib/multi.c | 42 | ||||
-rw-r--r-- | lib/sendf.c | 4 | ||||
-rw-r--r-- | lib/socks.c | 208 | ||||
-rw-r--r-- | lib/vssh/wolfssh.c | 288 | ||||
-rw-r--r-- | lib/vtls/mbedtls.c | 39 | ||||
-rw-r--r-- | lib/vtls/openssl.c | 35 |
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 |