Annotation of embedaddon/miniupnpd/upnppermissions.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* $Id: upnppermissions.c,v 1.17 2012/02/15 22:43:34 nanard Exp $ */
1.1 misho 2: /* MiniUPnP project
3: * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
1.1.1.2 ! misho 4: * (c) 2006-2012 Thomas Bernard
1.1 misho 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>
1.1.1.2 ! misho 13: #include <netinet/in.h>
1.1 misho 14: #include <arpa/inet.h>
15: #include <unistd.h>
16: #include "config.h"
17: #include "upnppermissions.h"
18:
1.1.1.2 ! misho 19: /* read_permission_line()
! 20: * parse the a permission line which format is :
! 21: * (deny|allow) [0-9]+(-[0-9]+) ip/mask [0-9]+(-[0-9]+)
! 22: * ip/mask is either 192.168.1.1/24 or 192.168.1.1/255.255.255.0
! 23: */
1.1 misho 24: int
25: read_permission_line(struct upnpperm * perm,
26: char * p)
27: {
28: char * q;
29: int n_bits;
1.1.1.2 ! misho 30: int i;
1.1 misho 31:
32: /* first token: (allow|deny) */
33: while(isspace(*p))
34: p++;
35: if(0 == memcmp(p, "allow", 5))
36: {
37: perm->type = UPNPPERM_ALLOW;
38: p += 5;
39: }
40: else if(0 == memcmp(p, "deny", 4))
41: {
42: perm->type = UPNPPERM_DENY;
43: p += 4;
44: }
45: else
46: {
47: return -1;
48: }
49: while(isspace(*p))
50: p++;
1.1.1.2 ! misho 51:
! 52: /* second token: eport or eport_min-eport_max */
1.1 misho 53: if(!isdigit(*p))
54: return -1;
55: for(q = p; isdigit(*q); q++);
56: if(*q=='-')
57: {
58: *q = '\0';
1.1.1.2 ! misho 59: i = atoi(p);
! 60: if(i > 65535)
! 61: return -1;
! 62: perm->eport_min = (u_short)i;
1.1 misho 63: q++;
64: p = q;
65: while(isdigit(*q))
66: q++;
67: *q = '\0';
1.1.1.2 ! misho 68: i = atoi(p);
! 69: if(i > 65535)
! 70: return -1;
! 71: perm->eport_max = (u_short)i;
! 72: if(perm->eport_min > perm->eport_max)
! 73: return -1;
1.1 misho 74: }
1.1.1.2 ! misho 75: else if(isspace(*q))
1.1 misho 76: {
77: *q = '\0';
1.1.1.2 ! misho 78: i = atoi(p);
! 79: if(i > 65535)
! 80: return -1;
! 81: perm->eport_min = perm->eport_max = (u_short)i;
! 82: }
! 83: else
! 84: {
! 85: return -1;
1.1 misho 86: }
87: p = q + 1;
88: while(isspace(*p))
89: p++;
90:
91: /* third token: ip/mask */
92: if(!isdigit(*p))
93: return -1;
94: for(q = p; isdigit(*q) || (*q == '.'); q++);
95: if(*q=='/')
96: {
97: *q = '\0';
98: if(!inet_aton(p, &perm->address))
99: return -1;
100: q++;
101: p = q;
102: while(isdigit(*q))
103: q++;
1.1.1.2 ! misho 104: if(*q == '.')
! 105: {
! 106: while(*q == '.' || isdigit(*q))
! 107: q++;
! 108: if(!isspace(*q))
! 109: return -1;
! 110: *q = '\0';
! 111: if(!inet_aton(p, &perm->mask))
! 112: return -1;
! 113: }
! 114: else if(!isspace(*q))
! 115: return -1;
! 116: else
! 117: {
! 118: *q = '\0';
! 119: n_bits = atoi(p);
! 120: if(n_bits > 32)
! 121: return -1;
! 122: perm->mask.s_addr = htonl(n_bits ? (0xffffffffu << (32 - n_bits)) : 0);
! 123: }
1.1 misho 124: }
1.1.1.2 ! misho 125: else if(isspace(*q))
1.1 misho 126: {
127: *q = '\0';
128: if(!inet_aton(p, &perm->address))
129: return -1;
1.1.1.2 ! misho 130: perm->mask.s_addr = 0xffffffffu;
! 131: }
! 132: else
! 133: {
! 134: return -1;
1.1 misho 135: }
136: p = q + 1;
137:
138: /* fourth token: iport or iport_min-iport_max */
139: while(isspace(*p))
140: p++;
141: if(!isdigit(*p))
142: return -1;
143: for(q = p; isdigit(*q); q++);
144: if(*q=='-')
145: {
146: *q = '\0';
1.1.1.2 ! misho 147: i = atoi(p);
! 148: if(i > 65535)
! 149: return -1;
! 150: perm->iport_min = (u_short)i;
1.1 misho 151: q++;
152: p = q;
153: while(isdigit(*q))
154: q++;
155: *q = '\0';
1.1.1.2 ! misho 156: i = atoi(p);
! 157: if(i > 65535)
! 158: return -1;
! 159: perm->iport_max = (u_short)i;
! 160: if(perm->iport_min > perm->iport_max)
! 161: return -1;
1.1 misho 162: }
1.1.1.2 ! misho 163: else if(isspace(*q) || *q == '\0')
1.1 misho 164: {
165: *q = '\0';
1.1.1.2 ! misho 166: i = atoi(p);
! 167: if(i > 65535)
! 168: return -1;
! 169: perm->iport_min = perm->iport_max = (u_short)i;
! 170: }
! 171: else
! 172: {
! 173: return -1;
1.1 misho 174: }
175: #ifdef DEBUG
176: printf("perm rule added : %s %hu-%hu %08x/%08x %hu-%hu\n",
177: (perm->type==UPNPPERM_ALLOW)?"allow":"deny",
178: perm->eport_min, perm->eport_max, ntohl(perm->address.s_addr),
179: ntohl(perm->mask.s_addr), perm->iport_min, perm->iport_max);
180: #endif
181: return 0;
182: }
183:
184: #ifdef USE_MINIUPNPDCTL
185: void
186: write_permlist(int fd, const struct upnpperm * permary,
187: int nperms)
188: {
189: int l;
190: const struct upnpperm * perm;
191: int i;
192: char buf[128];
193: write(fd, "Permissions :\n", 14);
194: for(i = 0; i<nperms; i++)
195: {
196: perm = permary + i;
197: l = snprintf(buf, sizeof(buf), "%02d %s %hu-%hu %08x/%08x %hu-%hu\n",
198: i,
199: (perm->type==UPNPPERM_ALLOW)?"allow":"deny",
200: perm->eport_min, perm->eport_max, ntohl(perm->address.s_addr),
201: ntohl(perm->mask.s_addr), perm->iport_min, perm->iport_max);
202: if(l<0)
203: return;
204: write(fd, buf, l);
205: }
206: }
207: #endif
208:
209: /* match_permission()
210: * returns: 1 if eport, address, iport matches the permission rule
211: * 0 if no match */
212: static int
213: match_permission(const struct upnpperm * perm,
214: u_short eport, struct in_addr address, u_short iport)
215: {
216: if( (eport < perm->eport_min) || (perm->eport_max < eport))
217: return 0;
218: if( (iport < perm->iport_min) || (perm->iport_max < iport))
219: return 0;
220: if( (address.s_addr & perm->mask.s_addr)
221: != (perm->address.s_addr & perm->mask.s_addr) )
222: return 0;
223: return 1;
224: }
225:
226: int
227: check_upnp_rule_against_permissions(const struct upnpperm * permary,
228: int n_perms,
229: u_short eport, struct in_addr address,
230: u_short iport)
231: {
232: int i;
233: for(i=0; i<n_perms; i++)
234: {
235: if(match_permission(permary + i, eport, address, iport))
236: {
237: syslog(LOG_DEBUG,
238: "UPnP permission rule %d matched : port mapping %s",
239: i, (permary[i].type == UPNPPERM_ALLOW)?"accepted":"rejected"
240: );
241: return (permary[i].type == UPNPPERM_ALLOW);
242: }
243: }
244: syslog(LOG_DEBUG, "no permission rule matched : accept by default (n_perms=%d)", n_perms);
245: return 1; /* Default : accept */
246: }
247:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>