Revert "Revert "and added files""
[bcm963xx.git] / userapps / opensource / siproxd / src / accessctl.c
1 /*
2     Copyright (C) 2002-2005  Thomas Ries <tries@gmx.net>
3
4     This file is part of Siproxd.
5     
6     Siproxd is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10     
11     Siproxd is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15     
16     You should have received a copy of the GNU General Public License
17     along with Siproxd; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19 */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <sys/types.h>
27 #include <netinet/in.h>
28
29 #include <osipparser2/osip_parser.h>
30
31 #include "siproxd.h"
32 #include "log.h"
33
34 static char const ident[]="$Id: accessctl.c,v 1.13 2005/01/08 10:05:12 hb9xar Exp $";
35
36 /* configuration storage */
37 struct siproxd_config configuration;
38
39 /* prototypes used locally only */
40 int process_aclist (char *aclist, struct sockaddr_in from);
41
42
43 /*
44  * verifies the from address agains the access lists
45  * defined in the configuration file.
46  *
47  * returns a bitmask with ACCESSCTL_SIP, ACCESSCTL_REG
48  */
49 int accesslist_check (struct sockaddr_in from) {
50    int access = 0;
51
52    DEBUGC(DBCLASS_ACCESS,"deny  list (SIP):%s",
53       configuration.hosts_deny_sip? configuration.hosts_deny_sip : "*NULL*");
54    DEBUGC(DBCLASS_ACCESS,"allow list (SIP):%s",
55       configuration.hosts_allow_sip? configuration.hosts_allow_sip : "*NULL*");
56    DEBUGC(DBCLASS_ACCESS,"allow list (REG):%s",
57       configuration.hosts_allow_reg? configuration.hosts_allow_reg : "*NULL*");
58
59 /*
60  * check DENY list
61  */
62    if ( (configuration.hosts_deny_sip !=NULL) &&
63         (strcmp(configuration.hosts_deny_sip,"")!=0) ) {
64       /* non-empty list -> check agains it */
65       if (process_aclist(configuration.hosts_deny_sip, from)== STS_SUCCESS) {
66          /* yup - this one is blacklisted */
67          DEBUGC(DBCLASS_ACCESS,"caught by deny list");
68          return 0;
69       }
70    }
71
72 /*
73  * check SIP allow list
74  */
75    if ( (configuration.hosts_allow_sip !=NULL) &&
76         (strcmp(configuration.hosts_allow_sip,"")!=0) ) {
77       /* non-empty list -> check agains it */
78       if (process_aclist(configuration.hosts_allow_sip, from)==STS_SUCCESS) {
79          /* SIP access granted */
80          DEBUGC(DBCLASS_ACCESS,"granted SIP access");
81          access |= ACCESSCTL_SIP;
82       }
83    } else {
84       access |= ACCESSCTL_SIP;
85    }
86
87 /*
88  * check SIP registration allow list
89  */
90    if ( (configuration.hosts_allow_reg !=NULL) &&
91         (strcmp(configuration.hosts_allow_reg,"")!=0) ) {
92       /* non-empty list -> check agains it */
93       if (process_aclist(configuration.hosts_allow_reg, from)==STS_SUCCESS) {
94          /* SIP registration access granted */
95          DEBUGC(DBCLASS_ACCESS,"granted REG/SIP access");
96          access |= ACCESSCTL_REG | ACCESSCTL_SIP;
97       }
98    } else {
99       access |= ACCESSCTL_REG;
100    }
101
102    DEBUGC(DBCLASS_ACCESS,"access check =%i", access);
103    return access;
104 }
105
106
107 /*
108  * checks for a match of the 'from' address with the supplied
109  * access list.
110  *
111  * RETURNS
112  *      STS_SUCCESS for a match
113  *      STS_FAILURE for no match
114  */
115 int process_aclist (char *aclist, struct sockaddr_in from) {
116    int i, sts;
117    int lastentry;
118    char *p1, *p2;
119    char address[32]; /* dotted decimal IP - max 15 chars*/
120    char mask[8];     /* mask - max 2 digits */
121    struct in_addr inaddr;
122    unsigned int bitmask;
123
124
125    for (i=0, p1=aclist, lastentry=0;
126         !lastentry; i++) {
127
128 /*
129  * extract one entry from the access list
130  */
131       /* address */
132       p2=strchr(p1,'/');
133       if (!p2) {
134          ERROR("CONFIG: accesslist [%s]- no mask separator found", aclist);
135          return STS_FAILURE;
136       }
137       memset(address,0,sizeof(address));
138       memcpy(address,p1,p2-p1);
139
140
141       /* mask */
142       p1=strchr(p2,',');
143       p1=p2+1;
144       p2=strchr(p1,',');
145       if (!p2) { /* then this must be the last entry in the list */
146          p2=strchr(p1,'\0');
147          lastentry=1;
148       }
149       memset(mask,0,sizeof(mask));
150       memcpy(mask,p1,p2-p1);
151       p1=p2+1;
152
153       DEBUGC(DBCLASS_ACCESS,"[%i] extracted address=%s", i, address);
154       DEBUGC(DBCLASS_ACCESS,"[%i] extracted mask   =%s", i, mask);
155
156 /*
157  * check for a match
158  */
159       sts=get_ip_by_host(address, &inaddr);
160       if (sts == STS_FAILURE) {
161          DEBUGC(DBCLASS_ACCESS, "process_aclist: cannot resolve address [%s]",
162                 address);
163          return STS_FAILURE;
164       }
165
166       bitmask=~(0xffffffff>>atoi(mask));
167
168       DEBUGC(DBCLASS_ACCESS,"[%i] (%p) <-> (%p)", i,
169                             ntohl(inaddr.s_addr) & bitmask,
170                             ntohl(from.sin_addr.s_addr) & bitmask);
171
172       if ( (ntohl(inaddr.s_addr) & bitmask) == 
173            (ntohl(from.sin_addr.s_addr) & bitmask) ) return STS_SUCCESS;
174    }
175
176    return STS_FAILURE;
177 }