Improve UPNPIGD_IsConnected() to check if WAN address is not private.

This commit is contained in:
Thomas Bernard 2016-01-22 15:22:01 +01:00
parent 21a98adc5d
commit 99c7aeef4d
2 changed files with 41 additions and 13 deletions

View File

@ -1,6 +1,9 @@
$Id: Changelog.txt,v 1.219 2015/10/26 17:05:06 nanard Exp $
$Id: Changelog.txt,v 1.220 2016/01/22 14:19:54 nanard Exp $
miniUPnP client Changelog.
2016/01/22:
Improve UPNPIGD_IsConnected() to check if WAN address is not private.
2015/10/26:
snprintf() overflow check. check overflow in simpleUPnPcommand2()

View File

@ -1,4 +1,4 @@
/* $Id: miniupnpc.c,v 1.135 2015/07/23 20:40:08 nanard Exp $ */
/* $Id: miniupnpc.c,v 1.144 2016/01/22 14:19:55 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* Project : miniupnp
* Web : http://miniupnp.free.fr/
@ -72,6 +72,25 @@
#define SERVICEPREFIX "u"
#define SERVICEPREFIX2 'u'
/* check if an ip address is a private (LAN) address
* see https://tools.ietf.org/html/rfc1918 */
static int is_rfc1918addr(const char * addr)
{
/* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */
if(COMPARE(addr, "192.168."))
return 1;
/* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */
if(COMPARE(addr, "10."))
return 1;
/* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */
if(COMPARE(addr, "172.")) {
int i = atoi(addr + 4);
if((16 <= i) && (i <= 31))
return 1;
}
return 0;
}
/* root description parsing */
MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
{
@ -526,7 +545,7 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
* 3 = an UPnP device has been found but was not recognized as an IGD
*
* In any positive non zero return case, the urls and data structures
* passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
* passed as parameters are set. Dont forget to call FreeUPNPUrls(urls) to
* free allocated memory.
*/
MINIUPNP_LIBSPEC int
@ -604,20 +623,24 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
parserootdesc(desc[i].xml, desc[i].size, data);
if(desc[i].is_igd || state >= 3 )
{
int is_connected;
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
/* in state 2 and 3 we dont test if device is connected ! */
if(state >= 2)
goto free_and_return;
is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL,
UPNPIGD_IsConnected(urls, data));
urls->controlURL, is_connected);
#endif
/* checks that status is connected AND there is a external IP address assigned */
if(UPNPIGD_IsConnected(urls, data)
&& (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0))
goto free_and_return;
if(is_connected &&
(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
if(!is_rfc1918addr(extIpAddr))
goto free_and_return;
}
FreeUPNPUrls(urls);
if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG
@ -629,14 +652,16 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL,
UPNPIGD_IsConnected(urls, data));
urls->controlURL, is_connected);
#endif
if(UPNPIGD_IsConnected(urls, data)
&& (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0))
goto free_and_return;
if(is_connected &&
(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
if(!is_rfc1918addr(extIpAddr))
goto free_and_return;
}
FreeUPNPUrls(urls);
}
}