mirror of
https://github.com/moparisthebest/curl
synced 2024-12-26 10:08:48 -05:00
hostip: make 'localhost' return fixed values
Resolving the case insensitive host name 'localhost' now returns the addresses 127.0.0.1 and (if IPv6 is enabled) ::1 without using any resolver. This removes the risk that users accidentally resolves 'localhost' to something else. By making sure 'localhost' is always local, we can assume a "secure context" for such transfers (for cookies etc). Closes #7039
This commit is contained in:
parent
772eacb2e3
commit
1a0ebf6632
75
lib/hostip.c
75
lib/hostip.c
@ -63,6 +63,7 @@
|
|||||||
#include "multiif.h"
|
#include "multiif.h"
|
||||||
#include "doh.h"
|
#include "doh.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
|
#include "strcase.h"
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
@ -460,6 +461,75 @@ Curl_cache_addr(struct Curl_easy *data,
|
|||||||
return dns;
|
return dns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
/* return a static IPv6 resolve for 'localhost' */
|
||||||
|
static struct Curl_addrinfo *get_localhost6(int port)
|
||||||
|
{
|
||||||
|
struct Curl_addrinfo *ca;
|
||||||
|
const size_t ss_size = sizeof(struct sockaddr_in6);
|
||||||
|
const size_t hostlen = strlen("localhost");
|
||||||
|
struct sockaddr_in6 sa6;
|
||||||
|
unsigned char ipv6[16];
|
||||||
|
unsigned short port16 = (unsigned short)(port & 0xffff);
|
||||||
|
ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1);
|
||||||
|
if(!ca)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sa6.sin6_family = AF_INET6;
|
||||||
|
sa6.sin6_port = htons(port16);
|
||||||
|
sa6.sin6_flowinfo = 0;
|
||||||
|
sa6.sin6_scope_id = 0;
|
||||||
|
Curl_inet_pton(AF_INET6, "::1", ipv6);
|
||||||
|
memcpy(&sa6.sin6_addr, ipv6, sizeof(ipv6));
|
||||||
|
|
||||||
|
ca->ai_flags = 0;
|
||||||
|
ca->ai_family = AF_INET6;
|
||||||
|
ca->ai_socktype = SOCK_STREAM;
|
||||||
|
ca->ai_protocol = IPPROTO_TCP;
|
||||||
|
ca->ai_addrlen = (curl_socklen_t)ss_size;
|
||||||
|
ca->ai_next = NULL;
|
||||||
|
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||||
|
memcpy(ca->ai_addr, &sa6, ss_size);
|
||||||
|
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
||||||
|
strcpy(ca->ai_canonname, "localhost");
|
||||||
|
return ca;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define get_localhost6(x) NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* return a static IPv4 resolve for 'localhost' */
|
||||||
|
static struct Curl_addrinfo *get_localhost(int port)
|
||||||
|
{
|
||||||
|
struct Curl_addrinfo *ca;
|
||||||
|
const size_t ss_size = sizeof(struct sockaddr_in);
|
||||||
|
const size_t hostlen = strlen("localhost");
|
||||||
|
struct sockaddr_in sa;
|
||||||
|
unsigned int ipv4;
|
||||||
|
unsigned short port16 = (unsigned short)(port & 0xffff);
|
||||||
|
ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1);
|
||||||
|
if(!ca)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sa.sin_family = AF_INET;
|
||||||
|
sa.sin_port = htons(port16);
|
||||||
|
Curl_inet_pton(AF_INET, "127.0.0.1", (char *)&ipv4);
|
||||||
|
memcpy(&sa.sin_addr, &ipv4, sizeof(ipv4));
|
||||||
|
|
||||||
|
ca->ai_flags = 0;
|
||||||
|
ca->ai_family = AF_INET;
|
||||||
|
ca->ai_socktype = SOCK_STREAM;
|
||||||
|
ca->ai_protocol = IPPROTO_TCP;
|
||||||
|
ca->ai_addrlen = (curl_socklen_t)ss_size;
|
||||||
|
ca->ai_next = NULL;
|
||||||
|
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||||
|
memcpy(ca->ai_addr, &sa, ss_size);
|
||||||
|
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
|
||||||
|
strcpy(ca->ai_canonname, "localhost");
|
||||||
|
ca->ai_next = get_localhost6(port);
|
||||||
|
return ca;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_host_is_ipnum() returns TRUE if the given string is a numerical IPv4
|
* Curl_host_is_ipnum() returns TRUE if the given string is a numerical IPv4
|
||||||
* (or IPv6 if supported) address.
|
* (or IPv6 if supported) address.
|
||||||
@ -603,9 +673,10 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
|
|||||||
if(!Curl_ipvalid(data, conn))
|
if(!Curl_ipvalid(data, conn))
|
||||||
return CURLRESOLV_ERROR;
|
return CURLRESOLV_ERROR;
|
||||||
|
|
||||||
if(allowDOH && data->set.doh && !ipnum) {
|
if(strcasecompare(hostname, "localhost"))
|
||||||
|
addr = get_localhost(port);
|
||||||
|
else if(allowDOH && data->set.doh && !ipnum)
|
||||||
addr = Curl_doh(data, hostname, port, &respwait);
|
addr = Curl_doh(data, hostname, port, &respwait);
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
/* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
|
/* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
|
||||||
non-zero value indicating that we need to wait for the response to
|
non-zero value indicating that we need to wait for the response to
|
||||||
|
Loading…
Reference in New Issue
Block a user