| From 401455229a5006bed0346fedc99791ccb53e146c Mon Sep 17 00:00:00 2001 |
| From: Daniel Stenberg <daniel@haxx.se> |
| Date: Wed, 12 Oct 2022 10:47:59 +0200 |
| Subject: [PATCH] url: use IDN decoded names for HSTS checks |
| |
| Reported-by: Hiroki Kurosawa |
| |
| Closes #9791 |
| |
| Upstream-Status: Backport [https://github.com/curl/curl/commit/53bcf55b4538067e6] |
| Signed-off-by: Robert Joslyn <robert.joslyn@redrectangle.org> |
| --- |
| lib/url.c | 91 ++++++++++++++++++++++++++++--------------------------- |
| 1 file changed, 47 insertions(+), 44 deletions(-) |
| |
| diff --git a/lib/url.c b/lib/url.c |
| index 61c99d2..6426fa7 100644 |
| --- a/lib/url.c |
| +++ b/lib/url.c |
| @@ -2024,10 +2024,56 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, |
| failf(data, "Too long host name (maximum is %d)", MAX_URL_LEN); |
| return CURLE_URL_MALFORMAT; |
| } |
| + hostname = data->state.up.hostname; |
| + |
| + if(hostname && hostname[0] == '[') { |
| + /* This looks like an IPv6 address literal. See if there is an address |
| + scope. */ |
| + size_t hlen; |
| + conn->bits.ipv6_ip = TRUE; |
| + /* cut off the brackets! */ |
| + hostname++; |
| + hlen = strlen(hostname); |
| + hostname[hlen - 1] = 0; |
| + |
| + zonefrom_url(uh, data, conn); |
| + } |
| + |
| + /* make sure the connect struct gets its own copy of the host name */ |
| + conn->host.rawalloc = strdup(hostname ? hostname : ""); |
| + if(!conn->host.rawalloc) |
| + return CURLE_OUT_OF_MEMORY; |
| + conn->host.name = conn->host.rawalloc; |
| + |
| + /************************************************************* |
| + * IDN-convert the hostnames |
| + *************************************************************/ |
| + result = Curl_idnconvert_hostname(data, &conn->host); |
| + if(result) |
| + return result; |
| + if(conn->bits.conn_to_host) { |
| + result = Curl_idnconvert_hostname(data, &conn->conn_to_host); |
| + if(result) |
| + return result; |
| + } |
| +#ifndef CURL_DISABLE_PROXY |
| + if(conn->bits.httpproxy) { |
| + result = Curl_idnconvert_hostname(data, &conn->http_proxy.host); |
| + if(result) |
| + return result; |
| + } |
| + if(conn->bits.socksproxy) { |
| + result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host); |
| + if(result) |
| + return result; |
| + } |
| +#endif |
| |
| #ifndef CURL_DISABLE_HSTS |
| + /* HSTS upgrade */ |
| if(data->hsts && strcasecompare("http", data->state.up.scheme)) { |
| - if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) { |
| + /* This MUST use the IDN decoded name */ |
| + if(Curl_hsts(data->hsts, conn->host.name, TRUE)) { |
| char *url; |
| Curl_safefree(data->state.up.scheme); |
| uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0); |
| @@ -2133,26 +2179,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, |
| |
| (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); |
| |
| - hostname = data->state.up.hostname; |
| - if(hostname && hostname[0] == '[') { |
| - /* This looks like an IPv6 address literal. See if there is an address |
| - scope. */ |
| - size_t hlen; |
| - conn->bits.ipv6_ip = TRUE; |
| - /* cut off the brackets! */ |
| - hostname++; |
| - hlen = strlen(hostname); |
| - hostname[hlen - 1] = 0; |
| - |
| - zonefrom_url(uh, data, conn); |
| - } |
| - |
| - /* make sure the connect struct gets its own copy of the host name */ |
| - conn->host.rawalloc = strdup(hostname ? hostname : ""); |
| - if(!conn->host.rawalloc) |
| - return CURLE_OUT_OF_MEMORY; |
| - conn->host.name = conn->host.rawalloc; |
| - |
| #ifdef ENABLE_IPV6 |
| if(data->set.scope_id) |
| /* Override any scope that was set above. */ |
| @@ -3781,29 +3807,6 @@ static CURLcode create_conn(struct Curl_easy *data, |
| if(result) |
| goto out; |
| |
| - /************************************************************* |
| - * IDN-convert the hostnames |
| - *************************************************************/ |
| - result = Curl_idnconvert_hostname(data, &conn->host); |
| - if(result) |
| - goto out; |
| - if(conn->bits.conn_to_host) { |
| - result = Curl_idnconvert_hostname(data, &conn->conn_to_host); |
| - if(result) |
| - goto out; |
| - } |
| -#ifndef CURL_DISABLE_PROXY |
| - if(conn->bits.httpproxy) { |
| - result = Curl_idnconvert_hostname(data, &conn->http_proxy.host); |
| - if(result) |
| - goto out; |
| - } |
| - if(conn->bits.socksproxy) { |
| - result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host); |
| - if(result) |
| - goto out; |
| - } |
| -#endif |
| |
| /************************************************************* |
| * Check whether the host and the "connect to host" are equal. |