1 |
|
|
/* $OpenBSD: acl.c,v 1.15 2013/12/04 02:18:05 deraadt Exp $ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se> |
5 |
|
|
* All rights reserved. |
6 |
|
|
* |
7 |
|
|
* Redistribution and use in source and binary forms, with or without |
8 |
|
|
* modification, are permitted provided that the following conditions |
9 |
|
|
* are met: |
10 |
|
|
* 1. Redistributions of source code must retain the above copyright |
11 |
|
|
* notice, this list of conditions and the following disclaimer. |
12 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
13 |
|
|
* notice, this list of conditions and the following disclaimer in the |
14 |
|
|
* documentation and/or other materials provided with the distribution. |
15 |
|
|
* |
16 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
17 |
|
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 |
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 |
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
20 |
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
21 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
22 |
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
23 |
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
24 |
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
25 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 |
|
|
* SUCH DAMAGE. |
27 |
|
|
*/ |
28 |
|
|
|
29 |
|
|
#include <sys/types.h> |
30 |
|
|
#include <sys/socket.h> |
31 |
|
|
#include <netinet/in.h> |
32 |
|
|
#include <arpa/inet.h> |
33 |
|
|
#include <stdio.h> |
34 |
|
|
#include <stdlib.h> |
35 |
|
|
#include <ctype.h> |
36 |
|
|
#include <string.h> |
37 |
|
|
#include <netdb.h> |
38 |
|
|
#include "acl.h" |
39 |
|
|
|
40 |
|
|
#define TRUE 1 |
41 |
|
|
#define FALSE 0 |
42 |
|
|
|
43 |
|
|
static struct aclent *acl_root = NULL; |
44 |
|
|
|
45 |
|
|
static int |
46 |
|
|
acl_read_line(FILE *fp, char *buf, int size) |
47 |
|
|
{ |
48 |
|
|
int len = 0; |
49 |
|
|
char *c, *p, l; |
50 |
|
|
|
51 |
|
|
/* Read a line, and remove any comment, trim space */ |
52 |
|
|
|
53 |
|
|
do { |
54 |
|
|
while (fgets(buf, size, fp)) { |
55 |
|
|
c = buf; |
56 |
|
|
while (*c != '\0') { |
57 |
|
|
if (*c == '#' || *c == '\n') { |
58 |
|
|
*c = '\0'; |
59 |
|
|
} else { |
60 |
|
|
c++; |
61 |
|
|
} |
62 |
|
|
} |
63 |
|
|
|
64 |
|
|
c = p = buf; l = ' '; |
65 |
|
|
while (*c != '\0') { |
66 |
|
|
if (isspace((unsigned char)l) && |
67 |
|
|
isspace((unsigned char)*c)) { |
68 |
|
|
c++; |
69 |
|
|
} else { |
70 |
|
|
l = *c++; *p = l; p++; |
71 |
|
|
} |
72 |
|
|
} |
73 |
|
|
*p = '\0'; |
74 |
|
|
|
75 |
|
|
if (p != buf) { |
76 |
|
|
--p; |
77 |
|
|
if (isspace((unsigned char)*p) != 0) { |
78 |
|
|
*p = '\0'; |
79 |
|
|
} |
80 |
|
|
} |
81 |
|
|
|
82 |
|
|
len = strlen(buf); |
83 |
|
|
return len + 1; |
84 |
|
|
} |
85 |
|
|
} while (size > 0 && !feof(fp)); |
86 |
|
|
return len; |
87 |
|
|
} |
88 |
|
|
|
89 |
|
|
int |
90 |
|
|
acl_check_host(struct in_addr *addr) |
91 |
|
|
{ |
92 |
|
|
struct aclent *p; |
93 |
|
|
|
94 |
|
|
p = acl_root; |
95 |
|
|
while (p != NULL) { |
96 |
|
|
if ((addr->s_addr & p->s_mask) == p->s_addr) |
97 |
|
|
return(p->allow); |
98 |
|
|
p = p->next; |
99 |
|
|
} |
100 |
|
|
return(TRUE); |
101 |
|
|
} |
102 |
|
|
|
103 |
|
|
static void |
104 |
|
|
acl_add_net(int allow, struct in_addr *addr, struct in_addr *mask) |
105 |
|
|
{ |
106 |
|
|
struct aclent *acl, *p; |
107 |
|
|
|
108 |
|
|
acl = malloc(sizeof(struct aclent)); |
109 |
|
|
acl->next = NULL; |
110 |
|
|
acl->allow = allow; |
111 |
|
|
acl->s_addr = addr->s_addr; |
112 |
|
|
acl->s_mask = mask->s_addr; |
113 |
|
|
|
114 |
|
|
if (acl_root == NULL) { |
115 |
|
|
acl_root = acl; |
116 |
|
|
} else { |
117 |
|
|
p = acl_root; |
118 |
|
|
while (p->next != NULL) |
119 |
|
|
p = p->next; |
120 |
|
|
p->next = acl; |
121 |
|
|
} |
122 |
|
|
} |
123 |
|
|
|
124 |
|
|
static void |
125 |
|
|
acl_add_host(int allow, struct in_addr *addr) |
126 |
|
|
{ |
127 |
|
|
struct in_addr mask; |
128 |
|
|
|
129 |
|
|
mask.s_addr = htonl(0xffffffff); |
130 |
|
|
acl_add_net(allow, addr, &mask); |
131 |
|
|
} |
132 |
|
|
|
133 |
|
|
int |
134 |
|
|
acl_init(char *file) |
135 |
|
|
{ |
136 |
|
|
char data_line[1024], *p, *k; |
137 |
|
|
int line_no = 0, len, i, state; |
138 |
|
|
int allow = TRUE, error_cnt = 0; |
139 |
|
|
struct in_addr addr, mask, *host_addr; |
140 |
|
|
struct hostent *host; |
141 |
|
|
struct netent *net; |
142 |
|
|
FILE *data_file = NULL; |
143 |
|
|
|
144 |
|
|
if (file != NULL) |
145 |
|
|
data_file = fopen(file, "r"); |
146 |
|
|
|
147 |
|
|
while (data_file != NULL && |
148 |
|
|
acl_read_line(data_file, data_line, sizeof(data_line))) { |
149 |
|
|
|
150 |
|
|
line_no++; |
151 |
|
|
len = strlen(data_line); |
152 |
|
|
if (len == 0) |
153 |
|
|
continue; |
154 |
|
|
p = (char *) &data_line; |
155 |
|
|
|
156 |
|
|
/* State 1: Initial State */ |
157 |
|
|
|
158 |
|
|
state = ACLS_INIT; |
159 |
|
|
addr.s_addr = mask.s_addr = 0; |
160 |
|
|
|
161 |
|
|
k = p; /* save start of verb */ |
162 |
|
|
i = 0; |
163 |
|
|
while (*p != '\0' && |
164 |
|
|
!isspace((*p = tolower(*p)))) { |
165 |
|
|
p++; |
166 |
|
|
i++; |
167 |
|
|
} |
168 |
|
|
|
169 |
|
|
if (*p != '\0') |
170 |
|
|
*p++ = '\0'; |
171 |
|
|
|
172 |
|
|
if (strcmp(k, "allow") == 0) { |
173 |
|
|
allow = TRUE; |
174 |
|
|
state = ACLS_ALLOW; |
175 |
|
|
} |
176 |
|
|
|
177 |
|
|
if (strcmp(k, "deny") == 0) { |
178 |
|
|
allow = FALSE; |
179 |
|
|
state = ACLS_DENY; |
180 |
|
|
} |
181 |
|
|
|
182 |
|
|
if (state == ACLS_INIT) |
183 |
|
|
state = ACLE_UVERB; |
184 |
|
|
|
185 |
|
|
/* State 2: allow row */ |
186 |
|
|
/* State 3: deny row */ |
187 |
|
|
|
188 |
|
|
if (*p != '\0' && |
189 |
|
|
(state == ACLS_ALLOW || state == ACLS_DENY)) { |
190 |
|
|
k = p; /* save start of verb */ |
191 |
|
|
i = 0; |
192 |
|
|
while (*p != '\0' && |
193 |
|
|
!isspace((*p = tolower(*p)))) { |
194 |
|
|
p++; |
195 |
|
|
i++; |
196 |
|
|
} |
197 |
|
|
|
198 |
|
|
if (*p != '\0') |
199 |
|
|
*p++ = '\0'; |
200 |
|
|
|
201 |
|
|
if (strcmp(k, "all") == 0) |
202 |
|
|
state = state + ACLD_ALL; |
203 |
|
|
|
204 |
|
|
if (strcmp(k, "host") == 0) |
205 |
|
|
state = state + ACLD_HOST; |
206 |
|
|
|
207 |
|
|
if (strcmp(k, "net") == 0) |
208 |
|
|
state = state + ACLD_NET; |
209 |
|
|
|
210 |
|
|
if (state == ACLS_ALLOW || state == ACLS_DENY) |
211 |
|
|
state = ACLE_U2VERB; |
212 |
|
|
} |
213 |
|
|
|
214 |
|
|
if (state == ACLS_ALLOW || state == ACLS_DENY) |
215 |
|
|
state = ACLE_UEOL; |
216 |
|
|
|
217 |
|
|
/* State 4 & 5: all state, remove any comment */ |
218 |
|
|
|
219 |
|
|
if (*p == '\0' && |
220 |
|
|
(state == ACLS_ALLOW_ALL || state == ACLS_DENY_ALL)) { |
221 |
|
|
acl_add_net(allow, &addr, &mask); |
222 |
|
|
state = ACLE_OK; |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
/* State 6 & 7: host line */ |
226 |
|
|
/* State 8 & 9: net line */ |
227 |
|
|
|
228 |
|
|
if (*p != '\0' && |
229 |
|
|
state >= ACLS_ALLOW_HOST && state <= ACLS_DENY_NET) { |
230 |
|
|
|
231 |
|
|
k = p; /* save start of verb */ |
232 |
|
|
i = 0; |
233 |
|
|
while (*p != '\0' && |
234 |
|
|
!isspace((*p = tolower(*p)))) { |
235 |
|
|
p++; |
236 |
|
|
i++; |
237 |
|
|
} |
238 |
|
|
|
239 |
|
|
if (*p != '\0') |
240 |
|
|
*p++ = '\0'; |
241 |
|
|
|
242 |
|
|
if (state == ACLS_ALLOW_HOST || state == ACLS_DENY_HOST) { |
243 |
|
|
if (*k >= '0' && *k <= '9') { |
244 |
|
|
(void)inet_aton(k, &addr); |
245 |
|
|
acl_add_host(allow, &addr); |
246 |
|
|
state = state + ACLD_HOST_DONE; |
247 |
|
|
} else { |
248 |
|
|
host = gethostbyname(k); |
249 |
|
|
if (host == NULL) { |
250 |
|
|
state = ACLE_NOHOST; |
251 |
|
|
} else { |
252 |
|
|
if (host->h_addrtype == AF_INET) { |
253 |
|
|
while ((host_addr = (struct in_addr *) *host->h_addr_list++) != NULL) |
254 |
|
|
acl_add_host(allow, host_addr); |
255 |
|
|
} |
256 |
|
|
state = state + ACLD_HOST_DONE; |
257 |
|
|
} |
258 |
|
|
} |
259 |
|
|
} |
260 |
|
|
|
261 |
|
|
if (state == ACLS_ALLOW_NET || state == ACLS_DENY_NET) { |
262 |
|
|
if (*k >= '0' && *k <= '9') { |
263 |
|
|
(void)inet_aton(k, &addr); |
264 |
|
|
state = state + ACLD_NET_DONE; |
265 |
|
|
} else { |
266 |
|
|
net = getnetbyname(k); |
267 |
|
|
if (net == NULL) { |
268 |
|
|
state = ACLE_NONET; |
269 |
|
|
} else { |
270 |
|
|
addr.s_addr = ntohl(net->n_net); |
271 |
|
|
state = state + ACLD_NET_DONE; |
272 |
|
|
} |
273 |
|
|
} |
274 |
|
|
} |
275 |
|
|
|
276 |
|
|
} |
277 |
|
|
|
278 |
|
|
if (state >= ACLS_ALLOW_HOST && state <= ACLS_DENY_NET) |
279 |
|
|
state = ACLE_UEOL; |
280 |
|
|
|
281 |
|
|
|
282 |
|
|
/* State 10 & 11: allow/deny host line */ |
283 |
|
|
if (*p == '\0' && |
284 |
|
|
(state == ACLS_ALLOW_HOST_DONE || state == ACLS_DENY_HOST_DONE)) |
285 |
|
|
state = ACLE_OK; |
286 |
|
|
|
287 |
|
|
/* State 12 & 13: allow/deny net line */ |
288 |
|
|
if (*p == '\0' && |
289 |
|
|
(state == ACLS_ALLOW_NET_DONE || state == ACLS_DENY_NET_DONE)) { |
290 |
|
|
mask.s_addr = htonl(0xffffff00); |
291 |
|
|
if (ntohl(addr.s_addr) < 0xc0000000) |
292 |
|
|
mask.s_addr = htonl(0xffff0000); |
293 |
|
|
if (ntohl(addr.s_addr) < 0x80000000) |
294 |
|
|
mask.s_addr = htonl(0xff000000); |
295 |
|
|
acl_add_net(allow, &addr, &mask); |
296 |
|
|
state = ACLE_OK; |
297 |
|
|
} |
298 |
|
|
|
299 |
|
|
if (*p != '\0' && |
300 |
|
|
(state == ACLS_ALLOW_NET_DONE || state == ACLS_DENY_NET_DONE)) { |
301 |
|
|
|
302 |
|
|
k = p; /* save start of verb */ |
303 |
|
|
i = 0; |
304 |
|
|
while (*p != '\0' && |
305 |
|
|
!isspace((*p = tolower(*p)))) { |
306 |
|
|
p++; |
307 |
|
|
i++; |
308 |
|
|
} |
309 |
|
|
|
310 |
|
|
if (*p != '\0') |
311 |
|
|
*p++ = '\0'; |
312 |
|
|
|
313 |
|
|
if (strcmp(k, "netmask") == 0) |
314 |
|
|
state = state + ACLD_NET_MASK; |
315 |
|
|
|
316 |
|
|
if (state == ACLS_ALLOW_NET_DONE || |
317 |
|
|
state == ACLS_DENY_NET_DONE) |
318 |
|
|
state = ACLE_NONETMASK; |
319 |
|
|
} |
320 |
|
|
|
321 |
|
|
/* State 14 & 15: allow/deny net netmask line */ |
322 |
|
|
if (*p != '\0' && |
323 |
|
|
(state == ACLS_ALLOW_NET_MASK || state == ACLS_DENY_NET_MASK)) { |
324 |
|
|
|
325 |
|
|
k = p; /* save start of verb */ |
326 |
|
|
i = 0; |
327 |
|
|
while (*p != '\0' && |
328 |
|
|
!isspace((*p = tolower(*p)))) { |
329 |
|
|
p++; |
330 |
|
|
i++; |
331 |
|
|
} |
332 |
|
|
|
333 |
|
|
if (*p != '\0') |
334 |
|
|
*p++ = '\0'; |
335 |
|
|
|
336 |
|
|
if (state == ACLS_ALLOW_NET_MASK || |
337 |
|
|
state == ACLS_DENY_NET_MASK) { |
338 |
|
|
if (*k >= '0' && *k <= '9') { |
339 |
|
|
(void)inet_aton(k, &mask); |
340 |
|
|
state = state + ACLD_NET_EOL; |
341 |
|
|
} else { |
342 |
|
|
net = getnetbyname(k); |
343 |
|
|
if (net == NULL) { |
344 |
|
|
state = ACLE_NONET; |
345 |
|
|
} else { |
346 |
|
|
mask.s_addr = ntohl(net->n_net); |
347 |
|
|
state = state + ACLD_NET_EOL; |
348 |
|
|
} |
349 |
|
|
} |
350 |
|
|
} |
351 |
|
|
|
352 |
|
|
} |
353 |
|
|
|
354 |
|
|
if (state == ACLS_ALLOW_NET_MASK || state == ACLS_DENY_NET_MASK) |
355 |
|
|
state = ACLE_UEOL; |
356 |
|
|
|
357 |
|
|
/* State 16 & 17: allow/deny host line */ |
358 |
|
|
if (*p == '\0' && |
359 |
|
|
(state == ACLS_ALLOW_NET_EOL || state == ACLS_DENY_NET_EOL)) { |
360 |
|
|
acl_add_net(allow, &addr, &mask); |
361 |
|
|
state = ACLE_OK; |
362 |
|
|
} |
363 |
|
|
|
364 |
|
|
switch (state) { |
365 |
|
|
case ACLE_NONETMASK: |
366 |
|
|
fprintf(stderr, |
367 |
|
|
"acl: excpected \"netmask\" missing at line %d\n", |
368 |
|
|
line_no); |
369 |
|
|
break; |
370 |
|
|
case ACLE_NONET: |
371 |
|
|
error_cnt++; |
372 |
|
|
fprintf(stderr, "acl: unknown network at line %d\n", |
373 |
|
|
line_no); |
374 |
|
|
break; |
375 |
|
|
case ACLE_NOHOST: |
376 |
|
|
error_cnt++; |
377 |
|
|
fprintf(stderr, "acl: unknown host at line %d\n", |
378 |
|
|
line_no); |
379 |
|
|
break; |
380 |
|
|
case ACLE_UVERB: |
381 |
|
|
error_cnt++; |
382 |
|
|
fprintf(stderr, "acl: unknown verb at line %d\n", |
383 |
|
|
line_no); |
384 |
|
|
break; |
385 |
|
|
case ACLE_U2VERB: |
386 |
|
|
error_cnt++; |
387 |
|
|
fprintf(stderr, |
388 |
|
|
"acl: unknown secondary verb at line %d\n", |
389 |
|
|
line_no); |
390 |
|
|
break; |
391 |
|
|
case ACLE_UEOL: |
392 |
|
|
error_cnt++; |
393 |
|
|
fprintf(stderr, |
394 |
|
|
"acl: unexpected end of line at line %d\n", |
395 |
|
|
line_no); |
396 |
|
|
break; |
397 |
|
|
case ACLE_OK: |
398 |
|
|
break; |
399 |
|
|
default: |
400 |
|
|
error_cnt++; |
401 |
|
|
fprintf(stderr, "acl: unexpected state %d %s\n", |
402 |
|
|
state, k); |
403 |
|
|
} |
404 |
|
|
|
405 |
|
|
} |
406 |
|
|
|
407 |
|
|
if (data_file != NULL) { |
408 |
|
|
(void)fflush(stderr); |
409 |
|
|
(void)fclose(data_file); |
410 |
|
|
} |
411 |
|
|
|
412 |
|
|
/* Always add a last allow all if file don't exists or */ |
413 |
|
|
/* the file doesn't cover all cases. */ |
414 |
|
|
addr.s_addr = mask.s_addr = 0; |
415 |
|
|
allow = TRUE; |
416 |
|
|
acl_add_net(allow, &addr, &mask); |
417 |
|
|
return(error_cnt); |
418 |
|
|
} |
419 |
|
|
|
420 |
|
|
int |
421 |
|
|
acl_securenet(char *file) |
422 |
|
|
{ |
423 |
|
|
char data_line[1024], *p, *k; |
424 |
|
|
int line_no = 0, len, i, allow = TRUE, state; |
425 |
|
|
int error_cnt = 0; |
426 |
|
|
struct in_addr addr, mask; |
427 |
|
|
struct netent *net; |
428 |
|
|
FILE *data_file = NULL; |
429 |
|
|
|
430 |
|
|
if (file != NULL) |
431 |
|
|
data_file = fopen(file, "r"); |
432 |
|
|
|
433 |
|
|
/* Always add a localhost allow first, to be compatible with sun */ |
434 |
|
|
addr.s_addr = htonl(0x7f000001); |
435 |
|
|
mask.s_addr = htonl(0xffffffff); |
436 |
|
|
allow = TRUE; |
437 |
|
|
acl_add_net(allow, &addr, &mask); |
438 |
|
|
|
439 |
|
|
while (data_file != NULL && |
440 |
|
|
acl_read_line(data_file, data_line, sizeof(data_line))) { |
441 |
|
|
line_no++; |
442 |
|
|
len = strlen(data_line); |
443 |
|
|
if (len == 0) |
444 |
|
|
continue; |
445 |
|
|
p = (char *) &data_line; |
446 |
|
|
|
447 |
|
|
/* State 1: Initial State */ |
448 |
|
|
state = ACLS_INIT; |
449 |
|
|
addr.s_addr = mask.s_addr = 0; |
450 |
|
|
|
451 |
|
|
k = p; /* save start of verb */ |
452 |
|
|
i = 0; |
453 |
|
|
while (*p != '\0' && |
454 |
|
|
!isspace((*p = tolower(*p)))) { |
455 |
|
|
p++; |
456 |
|
|
i++; |
457 |
|
|
} |
458 |
|
|
|
459 |
|
|
if (*p != '\0') { |
460 |
|
|
*p++ = '\0'; |
461 |
|
|
state = ACLS_ALLOW_NET_MASK; |
462 |
|
|
} |
463 |
|
|
|
464 |
|
|
if (state == ACLS_INIT) |
465 |
|
|
state = ACLE_UEOL; |
466 |
|
|
|
467 |
|
|
if (state == ACLS_ALLOW_NET_MASK) { |
468 |
|
|
if (*k >= '0' && *k <= '9') { |
469 |
|
|
(void)inet_aton(k, &mask); |
470 |
|
|
state = ACLS_ALLOW_NET; |
471 |
|
|
} else { |
472 |
|
|
net = getnetbyname(k); |
473 |
|
|
if (net == NULL) { |
474 |
|
|
state = ACLE_NONET; |
475 |
|
|
} else { |
476 |
|
|
mask.s_addr = ntohl(net->n_net); |
477 |
|
|
state = ACLS_ALLOW_NET; |
478 |
|
|
} |
479 |
|
|
} |
480 |
|
|
|
481 |
|
|
k = p; /* save start of verb */ |
482 |
|
|
i = 0; |
483 |
|
|
while (*p != '\0' && |
484 |
|
|
!isspace((*p = tolower(*p)))) { |
485 |
|
|
p++; |
486 |
|
|
i++; |
487 |
|
|
} |
488 |
|
|
|
489 |
|
|
if (*p != '\0') |
490 |
|
|
*p++ = '\0'; |
491 |
|
|
} |
492 |
|
|
|
493 |
|
|
if (state == ACLS_ALLOW_NET_MASK) |
494 |
|
|
state = ACLE_UEOL; |
495 |
|
|
|
496 |
|
|
if (state == ACLS_ALLOW_NET) { |
497 |
|
|
if (*k >= '0' && *k <= '9') { |
498 |
|
|
(void)inet_aton(k, &addr); |
499 |
|
|
state = ACLS_ALLOW_NET_EOL; |
500 |
|
|
} else { |
501 |
|
|
net = getnetbyname(k); |
502 |
|
|
if (net == NULL) { |
503 |
|
|
state = ACLE_NONET; |
504 |
|
|
} else { |
505 |
|
|
addr.s_addr = ntohl(net->n_net); |
506 |
|
|
state = ACLS_ALLOW_NET_EOL; |
507 |
|
|
} |
508 |
|
|
} |
509 |
|
|
} |
510 |
|
|
|
511 |
|
|
if (state == ACLS_ALLOW_NET) |
512 |
|
|
state = ACLE_UEOL; |
513 |
|
|
|
514 |
|
|
if (*p == '\0' && state == ACLS_ALLOW_NET_EOL) { |
515 |
|
|
acl_add_net(allow, &addr, &mask); |
516 |
|
|
state = ACLE_OK; |
517 |
|
|
} |
518 |
|
|
|
519 |
|
|
switch (state) { |
520 |
|
|
case ACLE_NONET: |
521 |
|
|
error_cnt++; |
522 |
|
|
fprintf(stderr, |
523 |
|
|
"securenet: unknown network at line %d\n", |
524 |
|
|
line_no); |
525 |
|
|
break; |
526 |
|
|
case ACLE_UEOL: |
527 |
|
|
error_cnt++; |
528 |
|
|
fprintf(stderr, |
529 |
|
|
"securenet: unexpected end of line at line %d\n", |
530 |
|
|
line_no); |
531 |
|
|
break; |
532 |
|
|
case ACLE_OK: |
533 |
|
|
break; |
534 |
|
|
default: |
535 |
|
|
error_cnt++; |
536 |
|
|
fprintf(stderr, "securenet: unexpected state %d %s\n", |
537 |
|
|
state, k); |
538 |
|
|
} |
539 |
|
|
} |
540 |
|
|
|
541 |
|
|
if (data_file != NULL) { |
542 |
|
|
(void)fflush(stderr); |
543 |
|
|
(void)fclose(data_file); |
544 |
|
|
|
545 |
|
|
/* Always add a last deny all if file exists */ |
546 |
|
|
addr.s_addr = mask.s_addr = 0; |
547 |
|
|
allow = FALSE; |
548 |
|
|
acl_add_net(allow, &addr, &mask); |
549 |
|
|
} |
550 |
|
|
|
551 |
|
|
/* Always add a last allow all if file don't exists */ |
552 |
|
|
|
553 |
|
|
addr.s_addr = mask.s_addr = 0; |
554 |
|
|
allow = TRUE; |
555 |
|
|
acl_add_net(allow, &addr, &mask); |
556 |
|
|
return(error_cnt); |
557 |
|
|
} |
558 |
|
|
|
559 |
|
|
void |
560 |
|
|
acl_reset(void) |
561 |
|
|
{ |
562 |
|
|
struct aclent *p; |
563 |
|
|
|
564 |
|
|
while (acl_root != NULL) { |
565 |
|
|
p = acl_root->next; |
566 |
|
|
free(acl_root); |
567 |
|
|
acl_root = p; |
568 |
|
|
} |
569 |
|
|
} |