Annotation of embedaddon/miniupnpd/upnppermissions.c, revision 1.1
1.1 ! misho 1: /* $Id: upnppermissions.c,v 1.14 2009/12/22 17:21:43 nanard 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>