transfer: enhance secure check
No binary (build failed)
—
(log yok)
| @@ -3219,7 +3219,7 @@ static CURLcode http_header_a(struct Curl_easy *data, | |
| const char *v; | |
| struct connectdata *conn = data->conn; | |
| v = (data->asi && | |
| - | (Curl_conn_is_ssl(data->conn, FIRSTSOCKET) || |
| + | (Curl_xfer_is_secure(data) || |
| #ifdef DEBUGBUILD | |
| /* allow debug builds to circumvent the HTTPS restriction */ | |
| getenv("CURL_ALTSVC_HTTP") | |
| @@ -3573,7 +3573,7 @@ static CURLcode http_header_s(struct Curl_easy *data, | |
| #ifndef CURL_DISABLE_HSTS | |
| /* If enabled, the header is incoming and this is over HTTPS */ | |
| v = (data->hsts && | |
| - | (Curl_conn_is_ssl(conn, FIRSTSOCKET) || |
| + | (Curl_xfer_is_secure(data) || |
| #ifdef DEBUGBUILD | |
| /* allow debug builds to circumvent the HTTPS restriction */ | |
| getenv("CURL_HSTS_HTTP") | |
| @@ -4906,7 +4906,7 @@ CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers, | |
| infof(data, "set pseudo header %s to %s", HTTP_PSEUDO_SCHEME, scheme); | |
| } | |
| else { | |
| - | scheme = Curl_conn_is_ssl(data->conn, FIRSTSOCKET) ? "https" : "http"; |
| + | scheme = Curl_xfer_is_secure(data) ? "https" : "http"; |
| } | |
| } | |
| @@ -1024,7 +1024,6 @@ static CURLcode imap_state_capability_resp(struct Curl_easy *data, | |
| imapstate instate) | |
| { | |
| CURLcode result = CURLE_OK; | |
| - | struct connectdata *conn = data->conn; |
| const char *line = curlx_dyn_ptr(&imapc->pp.recvbuf); | |
| (void)instate; | |
| @@ -1076,7 +1075,7 @@ static CURLcode imap_state_capability_resp(struct Curl_easy *data, | |
| line += wordlen; | |
| } | |
| } | |
| - | else if(data->set.use_ssl && !Curl_conn_is_ssl(conn, FIRSTSOCKET)) { |
| + | else if(data->set.use_ssl && !Curl_xfer_is_secure(data)) { |
| /* PREAUTH is not compatible with STARTTLS. */ | |
| if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) { | |
| /* Switch to TLS connection now */ | |
| @@ -903,3 +903,25 @@ CURLcode Curl_xfer_pause_recv(struct Curl_easy *data, bool enable) | |
| Curl_pgrsRecvPause(data, enable); | |
| return result; | |
| } | |
| + | |
| + | bool Curl_xfer_is_secure(struct Curl_easy *data) |
| + | { |
| + | const struct Curl_scheme *scheme = NULL; |
| + | |
| + | if(data->conn) { |
| + | scheme = data->conn->scheme; |
| + | /* if we are connected, but not use SSL, the transfer is not secure. |
| + | * This covers an insecure http:// proxy that is not tunneling. |
| + | * We enforce tunneling for such cases, but better be sure here. */ |
| + | if(Curl_conn_is_connected(data->conn, FIRSTSOCKET) && |
| + | !Curl_conn_is_ssl(data->conn, FIRSTSOCKET)) |
| + | return FALSE; |
| + | } |
| + | else if(data->info.conn_scheme) { /* was connected once */ |
| + | scheme = Curl_get_scheme(data->info.conn_scheme); |
| + | } |
| + | else { /* never connected (yet?) */ |
| + | DEBUGASSERT(0); /* not implemented, would need to parse URL */ |
| + | } |
| + | return scheme ? (scheme->flags & PROTOPT_SSL) : FALSE; |
| + | } |
| @@ -143,4 +143,8 @@ bool Curl_xfer_recv_is_paused(struct Curl_easy *data); | |
| CURLcode Curl_xfer_pause_send(struct Curl_easy *data, bool enable); | |
| CURLcode Curl_xfer_pause_recv(struct Curl_easy *data, bool enable); | |
| + | /* TRUE if the transfer is secure (e.g. TLS) from libcurl to the |
| + | * URL's host. */ |
| + | bool Curl_xfer_is_secure(struct Curl_easy *data); |
| + | |
| #endif /* HEADER_CURL_TRANSFER_H */ | |
| @@ -208,7 +208,7 @@ test1548 test1549 test1550 test1551 test1552 test1553 test1554 test1555 \ | |
| test1556 test1557 test1558 test1559 test1560 test1561 test1562 test1563 \ | |
| test1564 test1565 test1566 test1567 test1568 test1569 test1570 test1571 \ | |
| test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 \ | |
| - | test1580 test1581 test1582 test1583 test1584 test1585 \ |
| + | test1580 test1581 test1582 test1583 test1584 test1585 test1586 \ |
| \ | |
| test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \ | |
| test1598 test1599 test1600 test1601 test1602 test1603 test1604 test1605 \ | |
| @@ -0,0 +1,73 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | HTTP |
| + | HTTPS proxy |
| + | HSTS |
| + | trailing-dot |
| + | </keywords> |
| + | </info> |
| + | |
| + | <reply> |
| + | <data crlf="headers"> |
| + | HTTP/1.1 200 OK |
| + | Content-Length: 6 |
| + | Strict-Transport-Security: max-age=604800 |
| + | |
| + | -foo- |
| + | </data> |
| + | <data2 crlf="headers"> |
| + | HTTP/1.1 200 OK |
| + | Content-Length: 6 |
| + | Strict-Transport-Security: max-age=6048000 |
| + | |
| + | -baa- |
| + | </data2> |
| + | </reply> |
| + | |
| + | <client> |
| + | <server> |
| + | http |
| + | https-proxy |
| + | </server> |
| + | <features> |
| + | HSTS |
| + | proxy |
| + | http |
| + | </features> |
| + | <setenv> |
| + | </setenv> |
| + | |
| + | <name> |
| + | HSTS via https: proxy ignored for http: URLs |
| + | </name> |
| + | <command> |
| + | -x https://%HOSTIP:%HTTPSPROXYPORT --proxy-insecure --hsts %LOGDIR/hsts%TESTNUMBER http://this.hsts.example./%TESTNUMBER http://another.example.com/%TESTNUMBER0002 |
| + | </command> |
| + | </client> |
| + | |
| + | <verify> |
| + | <proxy crlf="headers"> |
| + | GET http://this.hsts.example./%TESTNUMBER HTTP/1.1 |
| + | Host: this.hsts.example. |
| + | User-Agent: curl/%VERSION |
| + | Accept: */* |
| + | Proxy-Connection: Keep-Alive |
| + | |
| + | GET http://another.example.com/%TESTNUMBER0002 HTTP/1.1 |
| + | Host: another.example.com |
| + | User-Agent: curl/%VERSION |
| + | Accept: */* |
| + | Proxy-Connection: Keep-Alive |
| + | |
| + | </proxy> |
| + | |
| + | # The saved HSTS file must be empty as the HSTS headers were not secured |
| + | <file name="%LOGDIR/hsts%TESTNUMBER" mode="text"> |
| + | # Your HSTS cache. https://curl.se/docs/hsts.html |
| + | # This file was generated by libcurl! Edit at your own risk. |
| + | </file> |
| + | |
| + | </verify> |
| + | </testcase> |