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>