File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpd / upnppermissions.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:16:02 2012 UTC (12 years, 5 months ago) by misho
Branches: miniupnpd, elwix, MAIN
CVS tags: v1_6elwix, v1_5, HEAD
miniupnpd

    1: /* $Id: upnppermissions.c,v 1.1.1.1 2012/02/21 23:16:02 misho Exp $ */
    2: /* MiniUPnP project
    3:  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
    4:  * (c) 2006 Thomas Bernard
    5:  * This software is subject to the conditions detailed
    6:  * in the LICENCE file provided within the distribution */
    7: 
    8: #include <ctype.h>
    9: #include <string.h>
   10: #include <stdlib.h>
   11: #include <stdio.h>
   12: #include <syslog.h>
   13: #include <arpa/inet.h>
   14: #include <unistd.h>
   15: #include "config.h"
   16: #include "upnppermissions.h"
   17: 
   18: int
   19: read_permission_line(struct upnpperm * perm,
   20:                      char * p)
   21: {
   22: 	char * q;
   23: 	int n_bits;
   24: 
   25: 	/* first token: (allow|deny) */
   26: 	while(isspace(*p))
   27: 		p++;
   28: 	if(0 == memcmp(p, "allow", 5))
   29: 	{
   30: 		perm->type = UPNPPERM_ALLOW;
   31: 		p += 5;
   32: 	}
   33: 	else if(0 == memcmp(p, "deny", 4))
   34: 	{
   35: 		perm->type = UPNPPERM_DENY;
   36: 		p += 4;
   37: 	}
   38: 	else
   39: 	{
   40: 		return -1;
   41: 	}
   42: 
   43: 	/* second token: eport or eport_min-eport_max */
   44: 	while(isspace(*p))
   45: 		p++;
   46: 	if(!isdigit(*p))
   47: 		return -1;
   48: 	for(q = p; isdigit(*q); q++);
   49: 	if(*q=='-')
   50: 	{
   51: 		*q = '\0';
   52: 		perm->eport_min = (u_short)atoi(p);
   53: 		q++;
   54: 		p = q;
   55: 		while(isdigit(*q))
   56: 			q++;
   57: 		*q = '\0';
   58: 		perm->eport_max = (u_short)atoi(p);
   59: 	}
   60: 	else
   61: 	{
   62: 		*q = '\0';
   63: 		perm->eport_min = perm->eport_max = (u_short)atoi(p);
   64: 	}
   65: 	p = q + 1;
   66: 	while(isspace(*p))
   67: 		p++;
   68: 
   69: 	/* third token:  ip/mask */
   70: 	if(!isdigit(*p))
   71: 		return -1;
   72: 	for(q = p; isdigit(*q) || (*q == '.'); q++);
   73: 	if(*q=='/')
   74: 	{
   75: 		*q = '\0';
   76: 		if(!inet_aton(p, &perm->address))
   77: 			return -1;
   78: 		q++;
   79: 		p = q;
   80: 		while(isdigit(*q))
   81: 			q++;
   82: 		*q = '\0';
   83: 		n_bits = atoi(p);
   84: 		perm->mask.s_addr = htonl(n_bits ? (0xffffffff << (32 - n_bits)) : 0);
   85: 	}
   86: 	else
   87: 	{
   88: 		*q = '\0';
   89: 		if(!inet_aton(p, &perm->address))
   90: 			return -1;
   91: 		perm->mask.s_addr = 0xffffffff;
   92: 	}
   93: 	p = q + 1;
   94: 
   95: 	/* fourth token: iport or iport_min-iport_max */
   96: 	while(isspace(*p))
   97: 		p++;
   98: 	if(!isdigit(*p))
   99: 		return -1;
  100: 	for(q = p; isdigit(*q); q++);
  101: 	if(*q=='-')
  102: 	{
  103: 		*q = '\0';
  104: 		perm->iport_min = (u_short)atoi(p);
  105: 		q++;
  106: 		p = q;
  107: 		while(isdigit(*q))
  108: 			q++;
  109: 		*q = '\0';
  110: 		perm->iport_max = (u_short)atoi(p);
  111: 	}
  112: 	else
  113: 	{
  114: 		*q = '\0';
  115: 		perm->iport_min = perm->iport_max = (u_short)atoi(p);
  116: 	}
  117: #ifdef DEBUG
  118: 	printf("perm rule added : %s %hu-%hu %08x/%08x %hu-%hu\n",
  119: 	       (perm->type==UPNPPERM_ALLOW)?"allow":"deny",
  120: 	       perm->eport_min, perm->eport_max, ntohl(perm->address.s_addr),
  121: 	       ntohl(perm->mask.s_addr), perm->iport_min, perm->iport_max);
  122: #endif
  123: 	return 0;
  124: }
  125: 
  126: #ifdef USE_MINIUPNPDCTL
  127: void
  128: write_permlist(int fd, const struct upnpperm * permary,
  129:                int nperms)
  130: {
  131: 	int l;
  132: 	const struct upnpperm * perm;
  133: 	int i;
  134: 	char buf[128];
  135: 	write(fd, "Permissions :\n", 14);
  136: 	for(i = 0; i<nperms; i++)
  137: 	{
  138: 		perm = permary + i;
  139: 		l = snprintf(buf, sizeof(buf), "%02d %s %hu-%hu %08x/%08x %hu-%hu\n",
  140: 	       i,
  141:     	   (perm->type==UPNPPERM_ALLOW)?"allow":"deny",
  142: 	       perm->eport_min, perm->eport_max, ntohl(perm->address.s_addr),
  143: 	       ntohl(perm->mask.s_addr), perm->iport_min, perm->iport_max);
  144: 		if(l<0)
  145: 			return;
  146: 		write(fd, buf, l);
  147: 	}
  148: }
  149: #endif
  150: 
  151: /* match_permission()
  152:  * returns: 1 if eport, address, iport matches the permission rule
  153:  *          0 if no match */
  154: static int
  155: match_permission(const struct upnpperm * perm,
  156:                  u_short eport, struct in_addr address, u_short iport)
  157: {
  158: 	if( (eport < perm->eport_min) || (perm->eport_max < eport))
  159: 		return 0;
  160: 	if( (iport < perm->iport_min) || (perm->iport_max < iport))
  161: 		return 0;
  162: 	if( (address.s_addr & perm->mask.s_addr)
  163: 	   != (perm->address.s_addr & perm->mask.s_addr) )
  164: 		return 0;
  165: 	return 1;
  166: }
  167: 
  168: int
  169: check_upnp_rule_against_permissions(const struct upnpperm * permary,
  170:                                     int n_perms,
  171:                                     u_short eport, struct in_addr address,
  172:                                     u_short iport)
  173: {
  174: 	int i;
  175: 	for(i=0; i<n_perms; i++)
  176: 	{
  177: 		if(match_permission(permary + i, eport, address, iport))
  178: 		{
  179: 			syslog(LOG_DEBUG,
  180: 			       "UPnP permission rule %d matched : port mapping %s",
  181: 			       i, (permary[i].type == UPNPPERM_ALLOW)?"accepted":"rejected"
  182: 			       );
  183: 			return (permary[i].type == UPNPPERM_ALLOW);
  184: 		}
  185: 	}
  186: 	syslog(LOG_DEBUG, "no permission rule matched : accept by default (n_perms=%d)", n_perms);
  187: 	return 1;	/* Default : accept */
  188: }
  189: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>