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>