miniupnpd: Add validation that public ip address is not reserved and is really public
This ensures that all requests for getting public IP address (either via UPnP IGD or PCP/PMP) would contain correct public IP address or an error (instead of some invalid private/reserved IP address).
This commit is contained in:
parent
c35935c61d
commit
cce19781e6
|
@ -990,6 +990,12 @@ parselanaddr(struct lan_addr_s * lan_addr, const char * str)
|
|||
if(!inet_aton(lan_addr->ext_ip_str, &lan_addr->ext_ip_addr)) {
|
||||
/* error */
|
||||
fprintf(stderr, "Error parsing address : %s\n", lan_addr->ext_ip_str);
|
||||
return -1;
|
||||
}
|
||||
if(addr_is_reserved(&lan_addr->ext_ip_addr)) {
|
||||
/* error */
|
||||
fprintf(stderr, "Error: option ext_ip address contains reserved / private address : %s\n", lan_addr->ext_ip_str);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1070,6 +1076,7 @@ init(int argc, char * * argv, struct runtime_vars * v)
|
|||
int pid;
|
||||
int debug_flag = 0;
|
||||
int openlog_option;
|
||||
struct in_addr addr;
|
||||
struct sigaction sa;
|
||||
/*const char * logfilename = 0;*/
|
||||
const char * presurl = 0;
|
||||
|
@ -1606,6 +1613,17 @@ init(int argc, char * * argv, struct runtime_vars * v)
|
|||
goto print_usage;
|
||||
}
|
||||
|
||||
if (use_ext_ip_addr) {
|
||||
if (inet_pton(AF_INET, use_ext_ip_addr, &addr) != 1) {
|
||||
fprintf(stderr, "Error: option ext_ip contains invalid address %s\n", use_ext_ip_addr);
|
||||
return 1;
|
||||
}
|
||||
if (addr_is_reserved(&addr)) {
|
||||
fprintf(stderr, "Error: option ext_ip contains reserved / private address %s, not public routable\n", use_ext_ip_addr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(debug_flag)
|
||||
{
|
||||
pid = getpid();
|
||||
|
|
|
@ -94,6 +94,7 @@ error:
|
|||
static void FillPublicAddressResponse(unsigned char * resp, in_addr_t senderaddr)
|
||||
{
|
||||
#ifndef MULTIPLE_EXTERNAL_IP
|
||||
struct in_addr addr;
|
||||
char tmp[16];
|
||||
UNUSED(senderaddr);
|
||||
|
||||
|
@ -103,10 +104,13 @@ static void FillPublicAddressResponse(unsigned char * resp, in_addr_t senderaddr
|
|||
if(!ext_if_name || ext_if_name[0]=='\0') {
|
||||
resp[3] = 3; /* Network Failure (e.g. NAT box itself
|
||||
* has not obtained a DHCP lease) */
|
||||
} else if(getifaddr(ext_if_name, tmp, INET_ADDRSTRLEN, NULL, NULL) < 0) {
|
||||
} else if(getifaddr(ext_if_name, tmp, INET_ADDRSTRLEN, &addr, NULL) < 0) {
|
||||
syslog(LOG_ERR, "Failed to get IP for interface %s", ext_if_name);
|
||||
resp[3] = 3; /* Network Failure (e.g. NAT box itself
|
||||
* has not obtained a DHCP lease) */
|
||||
} else if (addr_is_reserved(&addr)) {
|
||||
resp[3] = 3; /* Network Failure, box has not obtained
|
||||
public IP address */
|
||||
} else {
|
||||
inet_pton(AF_INET, tmp, resp+8); /* ok */
|
||||
}
|
||||
|
|
|
@ -1281,8 +1281,9 @@ genEventVars(int * len, const struct serviceDesc * s)
|
|||
if(use_ext_ip_addr)
|
||||
str = strcat_str(str, len, &tmplen, use_ext_ip_addr);
|
||||
else {
|
||||
struct in_addr addr;
|
||||
char ext_ip_addr[INET_ADDRSTRLEN];
|
||||
if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0) {
|
||||
if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, &addr, NULL) < 0 || addr_is_reserved(&addr)) {
|
||||
str = strcat_str(str, len, &tmplen, "0.0.0.0");
|
||||
} else {
|
||||
str = strcat_str(str, len, &tmplen, ext_ip_addr);
|
||||
|
|
|
@ -332,17 +332,20 @@ GetExternalIPAddress(struct upnphttp * h, const char * action, const char * ns)
|
|||
* There is usually no NAT with IPv6 */
|
||||
|
||||
#ifndef MULTIPLE_EXTERNAL_IP
|
||||
struct in_addr addr;
|
||||
if(use_ext_ip_addr)
|
||||
{
|
||||
strncpy(ext_ip_addr, use_ext_ip_addr, INET_ADDRSTRLEN);
|
||||
ext_ip_addr[INET_ADDRSTRLEN - 1] = '\0';
|
||||
}
|
||||
else if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0)
|
||||
else if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, &addr, NULL) < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to get ip address for interface %s",
|
||||
ext_if_name);
|
||||
strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN);
|
||||
}
|
||||
if (addr_is_reserved(&addr))
|
||||
strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN);
|
||||
#else
|
||||
struct lan_addr_s * lan_addr;
|
||||
strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN);
|
||||
|
|
Loading…
Reference in New Issue