From: Daniel Stenberg Date: Sat, 29 May 2021 21:57:58 +0000 (+0200) Subject: hsts: ignore numberical IP address hosts X-Git-Tag: curl-7_78_0~244 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1c1d9f1affbd3367bcb24062e261d0ea5d185e3a;p=thirdparty%2Fcurl.git hsts: ignore numberical IP address hosts Also, use a single function library-wide for detecting if a given hostname is a numerical IP address. Reported-by: Harry Sintonen Fixes #7146 Closes #7149 --- diff --git a/lib/cookie.c b/lib/cookie.c index 941623f9d2..638201fba7 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -146,31 +146,6 @@ static bool tailmatch(const char *cooke_domain, const char *hostname) return FALSE; } -/* - * isip - * - * Returns true if the given string is an IPv4 or IPv6 address (if IPv6 has - * been enabled while building libcurl, and false otherwise. - */ -static bool isip(const char *domain) -{ - struct in_addr addr; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif - - if(Curl_inet_pton(AF_INET, domain, &addr) -#ifdef ENABLE_IPV6 - || Curl_inet_pton(AF_INET6, domain, &addr6) -#endif - ) { - /* domain name given as IP address */ - return TRUE; - } - - return FALSE; -} - /* * matching cookie path and url path * RFC6265 5.1.4 Paths and Path-Match @@ -303,7 +278,7 @@ static size_t cookiehash(const char * const domain) const char *top; size_t len; - if(!domain || isip(domain)) + if(!domain || Curl_host_is_ipnum(domain)) return 0; top = get_top_domain(domain, &len); @@ -645,7 +620,7 @@ Curl_cookie_add(struct Curl_easy *data, domain = ":"; #endif - is_ip = isip(domain ? domain : whatptr); + is_ip = Curl_host_is_ipnum(domain ? domain : whatptr); if(!domain || (is_ip && !strcmp(whatptr, domain)) @@ -996,7 +971,7 @@ Curl_cookie_add(struct Curl_easy *data, * must also check that the data handle isn't NULL since the psl code will * dereference it. */ - if(data && (domain && co->domain && !isip(co->domain))) { + if(data && (domain && co->domain && !Curl_host_is_ipnum(co->domain))) { const psl_ctx_t *psl = Curl_psl_use(data); int acceptable; @@ -1355,7 +1330,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, remove_expired(c); /* check if host is an IP(v4|v6) address */ - is_ip = isip(host); + is_ip = Curl_host_is_ipnum(host); co = c->cookies[myhash]; diff --git a/lib/hostcheck.c b/lib/hostcheck.c index 49dbab3472..cf267a7659 100644 --- a/lib/hostcheck.c +++ b/lib/hostcheck.c @@ -36,7 +36,7 @@ #include "hostcheck.h" #include "strcase.h" -#include "inet_pton.h" +#include "hostip.h" #include "curl_memory.h" /* The last #include file should be: */ @@ -67,10 +67,6 @@ static int hostmatch(char *hostname, char *pattern) const char *pattern_label_end, *pattern_wildcard, *hostname_label_end; int wildcard_enabled; size_t prefixlen, suffixlen; - struct in_addr ignored; -#ifdef ENABLE_IPV6 - struct sockaddr_in6 si6; -#endif /* normalize pattern and hostname by stripping off trailing dots */ size_t len = strlen(hostname); @@ -86,12 +82,8 @@ static int hostmatch(char *hostname, char *pattern) CURL_HOST_MATCH : CURL_HOST_NOMATCH; /* detect IP address as hostname and fail the match if so */ - if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0) - return CURL_HOST_NOMATCH; -#ifdef ENABLE_IPV6 - if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0) + if(Curl_host_is_ipnum(hostname)) return CURL_HOST_NOMATCH; -#endif /* We require at least 2 dots in pattern to avoid too wide wildcard match. */ diff --git a/lib/hostip.c b/lib/hostip.c index e0e3cfc2cb..b0d2db0b42 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -460,6 +460,25 @@ Curl_cache_addr(struct Curl_easy *data, return dns; } +/* + * Curl_host_is_ipnum() returns TRUE if the given string is a numerical IPv4 + * (or IPv6 if supported) address. + */ +bool Curl_host_is_ipnum(const char *hostname) +{ + struct in_addr in; +#ifdef ENABLE_IPV6 + struct in6_addr in6; +#endif + if(Curl_inet_pton(AF_INET, hostname, &in) > 0 +#ifdef ENABLE_IPV6 + || Curl_inet_pton(AF_INET6, hostname, &in6) > 0 +#endif + ) + return TRUE; + return FALSE; +} + /* * Curl_resolv() is the main name resolve function within libcurl. It resolves * a name and returns a pointer to the entry in the 'entry' argument (if one diff --git a/lib/hostip.h b/lib/hostip.h index d178976aa1..28f3b84018 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -71,6 +71,8 @@ struct Curl_dns_entry { long inuse; }; +bool Curl_host_is_ipnum(const char *hostname); + /* * Curl_resolv() returns an entry with the info for the specified host * and port. diff --git a/lib/hsts.c b/lib/hsts.c index ef166f196c..0d5a584012 100644 --- a/lib/hsts.c +++ b/lib/hsts.c @@ -138,6 +138,11 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, struct stsentry *sts; time_t now = time(NULL); + if(Curl_host_is_ipnum(hostname)) + /* "explicit IP address identification of all forms is excluded." + / RFC 6797 */ + return CURLE_OK; + do { while(*p && ISSPACE(*p)) p++; diff --git a/lib/url.c b/lib/url.c index 1ee38af0d5..edcdf54b1a 100644 --- a/lib/url.c +++ b/lib/url.c @@ -92,7 +92,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "speedcheck.h" #include "warnless.h" #include "non-ascii.h" -#include "inet_pton.h" #include "getinfo.h" #include "urlapi-int.h" #include "system_win32.h"