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. miniUPnP client Changelog.
2016/01/22:
Improve UPNPIGD_IsConnected() to check if WAN address is not private.
2015/10/26: 2015/10/26:
snprintf() overflow check. check overflow in simpleUPnPcommand2() 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 /* vim: tabstop=4 shiftwidth=4 noexpandtab
* Project : miniupnp * Project : miniupnp
* Web : http://miniupnp.free.fr/ * Web : http://miniupnp.free.fr/
@ -72,6 +72,25 @@
#define SERVICEPREFIX "u" #define SERVICEPREFIX "u"
#define SERVICEPREFIX2 '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 */ /* root description parsing */
MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) 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 * 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 * 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. * free allocated memory.
*/ */
MINIUPNP_LIBSPEC int MINIUPNP_LIBSPEC int
@ -604,20 +623,24 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
parserootdesc(desc[i].xml, desc[i].size, data); parserootdesc(desc[i].xml, desc[i].size, data);
if(desc[i].is_igd || state >= 3 ) if(desc[i].is_igd || state >= 3 )
{ {
int is_connected;
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
/* in state 2 and 3 we dont test if device is connected ! */ /* in state 2 and 3 we dont test if device is connected ! */
if(state >= 2) if(state >= 2)
goto free_and_return; goto free_and_return;
is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG #ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n", printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL, urls->controlURL, is_connected);
UPNPIGD_IsConnected(urls, data));
#endif #endif
/* checks that status is connected AND there is a external IP address assigned */ /* checks that status is connected AND there is a external IP address assigned */
if(UPNPIGD_IsConnected(urls, data) if(is_connected &&
&& (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
if(!is_rfc1918addr(extIpAddr))
goto free_and_return; goto free_and_return;
}
FreeUPNPUrls(urls); FreeUPNPUrls(urls);
if(data->second.servicetype[0] != '\0') { if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG #ifdef DEBUG
@ -629,14 +652,16 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service)); memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG #ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n", printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL, urls->controlURL, is_connected);
UPNPIGD_IsConnected(urls, data));
#endif #endif
if(UPNPIGD_IsConnected(urls, data) if(is_connected &&
&& (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
if(!is_rfc1918addr(extIpAddr))
goto free_and_return; goto free_and_return;
}
FreeUPNPUrls(urls); FreeUPNPUrls(urls);
} }
} }