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)) {
|
if(!inet_aton(lan_addr->ext_ip_str, &lan_addr->ext_ip_addr)) {
|
||||||
/* error */
|
/* error */
|
||||||
fprintf(stderr, "Error parsing address : %s\n", lan_addr->ext_ip_str);
|
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 pid;
|
||||||
int debug_flag = 0;
|
int debug_flag = 0;
|
||||||
int openlog_option;
|
int openlog_option;
|
||||||
|
struct in_addr addr;
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
/*const char * logfilename = 0;*/
|
/*const char * logfilename = 0;*/
|
||||||
const char * presurl = 0;
|
const char * presurl = 0;
|
||||||
|
@ -1606,6 +1613,17 @@ init(int argc, char * * argv, struct runtime_vars * v)
|
||||||
goto print_usage;
|
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)
|
if(debug_flag)
|
||||||
{
|
{
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
|
|
|
@ -94,6 +94,7 @@ error:
|
||||||
static void FillPublicAddressResponse(unsigned char * resp, in_addr_t senderaddr)
|
static void FillPublicAddressResponse(unsigned char * resp, in_addr_t senderaddr)
|
||||||
{
|
{
|
||||||
#ifndef MULTIPLE_EXTERNAL_IP
|
#ifndef MULTIPLE_EXTERNAL_IP
|
||||||
|
struct in_addr addr;
|
||||||
char tmp[16];
|
char tmp[16];
|
||||||
UNUSED(senderaddr);
|
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') {
|
if(!ext_if_name || ext_if_name[0]=='\0') {
|
||||||
resp[3] = 3; /* Network Failure (e.g. NAT box itself
|
resp[3] = 3; /* Network Failure (e.g. NAT box itself
|
||||||
* has not obtained a DHCP lease) */
|
* 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);
|
syslog(LOG_ERR, "Failed to get IP for interface %s", ext_if_name);
|
||||||
resp[3] = 3; /* Network Failure (e.g. NAT box itself
|
resp[3] = 3; /* Network Failure (e.g. NAT box itself
|
||||||
* has not obtained a DHCP lease) */
|
* 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 {
|
} else {
|
||||||
inet_pton(AF_INET, tmp, resp+8); /* ok */
|
inet_pton(AF_INET, tmp, resp+8); /* ok */
|
||||||
}
|
}
|
||||||
|
|
|
@ -1281,8 +1281,9 @@ genEventVars(int * len, const struct serviceDesc * s)
|
||||||
if(use_ext_ip_addr)
|
if(use_ext_ip_addr)
|
||||||
str = strcat_str(str, len, &tmplen, use_ext_ip_addr);
|
str = strcat_str(str, len, &tmplen, use_ext_ip_addr);
|
||||||
else {
|
else {
|
||||||
|
struct in_addr addr;
|
||||||
char ext_ip_addr[INET_ADDRSTRLEN];
|
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");
|
str = strcat_str(str, len, &tmplen, "0.0.0.0");
|
||||||
} else {
|
} else {
|
||||||
str = strcat_str(str, len, &tmplen, ext_ip_addr);
|
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 */
|
* There is usually no NAT with IPv6 */
|
||||||
|
|
||||||
#ifndef MULTIPLE_EXTERNAL_IP
|
#ifndef MULTIPLE_EXTERNAL_IP
|
||||||
|
struct in_addr addr;
|
||||||
if(use_ext_ip_addr)
|
if(use_ext_ip_addr)
|
||||||
{
|
{
|
||||||
strncpy(ext_ip_addr, use_ext_ip_addr, INET_ADDRSTRLEN);
|
strncpy(ext_ip_addr, use_ext_ip_addr, INET_ADDRSTRLEN);
|
||||||
ext_ip_addr[INET_ADDRSTRLEN - 1] = '\0';
|
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",
|
syslog(LOG_ERR, "Failed to get ip address for interface %s",
|
||||||
ext_if_name);
|
ext_if_name);
|
||||||
strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN);
|
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
|
#else
|
||||||
struct lan_addr_s * lan_addr;
|
struct lan_addr_s * lan_addr;
|
||||||
strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN);
|
strncpy(ext_ip_addr, "0.0.0.0", INET_ADDRSTRLEN);
|
||||||
|
|
Loading…
Reference in New Issue