--- embedaddon/miniupnpd/upnppermissions.c 2012/02/21 23:16:02 1.1.1.1 +++ embedaddon/miniupnpd/upnppermissions.c 2013/07/22 00:32:35 1.1.1.2 @@ -1,7 +1,7 @@ -/* $Id: upnppermissions.c,v 1.1.1.1 2012/02/21 23:16:02 misho Exp $ */ +/* $Id: upnppermissions.c,v 1.1.1.2 2013/07/22 00:32:35 misho Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006 Thomas Bernard + * (c) 2006-2012 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -10,17 +10,24 @@ #include #include #include +#include #include #include #include "config.h" #include "upnppermissions.h" +/* read_permission_line() + * parse the a permission line which format is : + * (deny|allow) [0-9]+(-[0-9]+) ip/mask [0-9]+(-[0-9]+) + * ip/mask is either 192.168.1.1/24 or 192.168.1.1/255.255.255.0 + */ int read_permission_line(struct upnpperm * perm, char * p) { char * q; int n_bits; + int i; /* first token: (allow|deny) */ while(isspace(*p)) @@ -39,29 +46,44 @@ read_permission_line(struct upnpperm * perm, { return -1; } - - /* second token: eport or eport_min-eport_max */ while(isspace(*p)) p++; + + /* second token: eport or eport_min-eport_max */ if(!isdigit(*p)) return -1; for(q = p; isdigit(*q); q++); if(*q=='-') { *q = '\0'; - perm->eport_min = (u_short)atoi(p); + i = atoi(p); + if(i > 65535) + return -1; + perm->eport_min = (u_short)i; q++; p = q; while(isdigit(*q)) q++; *q = '\0'; - perm->eport_max = (u_short)atoi(p); + i = atoi(p); + if(i > 65535) + return -1; + perm->eport_max = (u_short)i; + if(perm->eport_min > perm->eport_max) + return -1; } - else + else if(isspace(*q)) { *q = '\0'; - perm->eport_min = perm->eport_max = (u_short)atoi(p); + i = atoi(p); + if(i > 65535) + return -1; + perm->eport_min = perm->eport_max = (u_short)i; } + else + { + return -1; + } p = q + 1; while(isspace(*p)) p++; @@ -79,17 +101,38 @@ read_permission_line(struct upnpperm * perm, p = q; while(isdigit(*q)) q++; - *q = '\0'; - n_bits = atoi(p); - perm->mask.s_addr = htonl(n_bits ? (0xffffffff << (32 - n_bits)) : 0); + if(*q == '.') + { + while(*q == '.' || isdigit(*q)) + q++; + if(!isspace(*q)) + return -1; + *q = '\0'; + if(!inet_aton(p, &perm->mask)) + return -1; + } + else if(!isspace(*q)) + return -1; + else + { + *q = '\0'; + n_bits = atoi(p); + if(n_bits > 32) + return -1; + perm->mask.s_addr = htonl(n_bits ? (0xffffffffu << (32 - n_bits)) : 0); + } } - else + else if(isspace(*q)) { *q = '\0'; if(!inet_aton(p, &perm->address)) return -1; - perm->mask.s_addr = 0xffffffff; + perm->mask.s_addr = 0xffffffffu; } + else + { + return -1; + } p = q + 1; /* fourth token: iport or iport_min-iport_max */ @@ -101,18 +144,33 @@ read_permission_line(struct upnpperm * perm, if(*q=='-') { *q = '\0'; - perm->iport_min = (u_short)atoi(p); + i = atoi(p); + if(i > 65535) + return -1; + perm->iport_min = (u_short)i; q++; p = q; while(isdigit(*q)) q++; *q = '\0'; - perm->iport_max = (u_short)atoi(p); + i = atoi(p); + if(i > 65535) + return -1; + perm->iport_max = (u_short)i; + if(perm->iport_min > perm->iport_max) + return -1; } - else + else if(isspace(*q) || *q == '\0') { *q = '\0'; - perm->iport_min = perm->iport_max = (u_short)atoi(p); + i = atoi(p); + if(i > 65535) + return -1; + perm->iport_min = perm->iport_max = (u_short)i; + } + else + { + return -1; } #ifdef DEBUG printf("perm rule added : %s %hu-%hu %08x/%08x %hu-%hu\n",