Annotation of embedaddon/miniupnpd/upnppermissions.c, revision 1.1.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>