1From 53bcf55b4538067e6dc36242168866becb987bb7 Mon Sep 17 00:00:00 2001 2From: Daniel Stenberg <daniel@haxx.se> 3Date: Wed, 12 Oct 2022 10:47:59 +0200 4Subject: [PATCH] url: use IDN decoded names for HSTS checks 5 6Reported-by: Hiroki Kurosawa 7 8Closes #9791 9 10Conflict: Context adaptation 11Reference: https://github.com/curl/curl/commit/53bcf55b4538067e6dc36242168866becb987bb7 12 13--- 14 lib/url.c | 91 ++++++++++++++++++++++++++++--------------------------- 15 1 file changed, 47 insertions(+), 44 deletions(-) 16 17diff --git a/lib/url.c b/lib/url.c 18index a3be56bced9de..690c53c81a3c1 100644 19--- a/lib/url.c 20+++ b/lib/url.c 21@@ -2036,10 +2036,56 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, 22 if(!strcasecompare("file", data->state.up.scheme)) 23 return CURLE_OUT_OF_MEMORY; 24 } 25+ hostname = data->state.up.hostname; 26+ 27+ if(hostname && hostname[0] == '[') { 28+ /* This looks like an IPv6 address literal. See if there is an address 29+ scope. */ 30+ size_t hlen; 31+ conn->bits.ipv6_ip = TRUE; 32+ /* cut off the brackets! */ 33+ hostname++; 34+ hlen = strlen(hostname); 35+ hostname[hlen - 1] = 0; 36+ 37+ zonefrom_url(uh, data, conn); 38+ } 39+ 40+ /* make sure the connect struct gets its own copy of the host name */ 41+ conn->host.rawalloc = strdup(hostname ? hostname : ""); 42+ if(!conn->host.rawalloc) 43+ return CURLE_OUT_OF_MEMORY; 44+ conn->host.name = conn->host.rawalloc; 45+ 46+ /************************************************************* 47+ * IDN-convert the hostnames 48+ *************************************************************/ 49+ result = Curl_idnconvert_hostname(data, &conn->host); 50+ if(result) 51+ return result; 52+ if(conn->bits.conn_to_host) { 53+ result = Curl_idnconvert_hostname(data, &conn->conn_to_host); 54+ if(result) 55+ return result; 56+ } 57+#ifndef CURL_DISABLE_PROXY 58+ if(conn->bits.httpproxy) { 59+ result = Curl_idnconvert_hostname(data, &conn->http_proxy.host); 60+ if(result) 61+ return result; 62+ } 63+ if(conn->bits.socksproxy) { 64+ result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host); 65+ if(result) 66+ return result; 67+ } 68+#endif 69 70 #ifndef CURL_DISABLE_HSTS 71+ /* HSTS upgrade */ 72 if(data->hsts && strcasecompare("http", data->state.up.scheme)) { 73- if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) { 74+ /* This MUST use the IDN decoded name */ 75+ if(Curl_hsts(data->hsts, conn->host.name, TRUE)) { 76 char *url; 77 Curl_safefree(data->state.up.scheme); 78 uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0); 79@@ -2145,26 +2191,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, 80 81 (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); 82 83- hostname = data->state.up.hostname; 84- if(hostname && hostname[0] == '[') { 85- /* This looks like an IPv6 address literal. See if there is an address 86- scope. */ 87- size_t hlen; 88- conn->bits.ipv6_ip = TRUE; 89- /* cut off the brackets! */ 90- hostname++; 91- hlen = strlen(hostname); 92- hostname[hlen - 1] = 0; 93- 94- zonefrom_url(uh, data, conn); 95- } 96- 97- /* make sure the connect struct gets its own copy of the host name */ 98- conn->host.rawalloc = strdup(hostname ? hostname : ""); 99- if(!conn->host.rawalloc) 100- return CURLE_OUT_OF_MEMORY; 101- conn->host.name = conn->host.rawalloc; 102- 103 if(data->set.scope_id) 104 /* Override any scope that was set above. */ 105 conn->scope_id = data->set.scope_id; 106@@ -3713,29 +3739,6 @@ static CURLcode create_conn(struct Curl_easy *data, 107 if(result) 108 goto out; 109 110- /************************************************************* 111- * IDN-convert the hostnames 112- *************************************************************/ 113- result = Curl_idnconvert_hostname(data, &conn->host); 114- if(result) 115- goto out; 116- if(conn->bits.conn_to_host) { 117- result = Curl_idnconvert_hostname(data, &conn->conn_to_host); 118- if(result) 119- goto out; 120- } 121-#ifndef CURL_DISABLE_PROXY 122- if(conn->bits.httpproxy) { 123- result = Curl_idnconvert_hostname(data, &conn->http_proxy.host); 124- if(result) 125- goto out; 126- } 127- if(conn->bits.socksproxy) { 128- result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host); 129- if(result) 130- goto out; 131- } 132-#endif 133 134 /************************************************************* 135 * Check whether the host and the "connect to host" are equal. 136