Configuration and ACL routines.
Showing
1 changed file
with
295 additions
and
0 deletions
comsat/cfg.c
0 → 100644
1 | /* Copyright (C) 1998,2001 Free Software Foundation, Inc. | ||
2 | |||
3 | This file is part of GNU Inetutils. | ||
4 | |||
5 | GNU Inetutils is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Inetutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Inetutils; see the file COPYING. If not, write to | ||
17 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. */ | ||
19 | |||
20 | #include "comsat.h" | ||
21 | #include <argcv.h> | ||
22 | #include <ctype.h> | ||
23 | |||
24 | typedef struct netdef netdef_t; | ||
25 | |||
26 | struct netdef | ||
27 | { | ||
28 | netdef_t *next; | ||
29 | unsigned int ipaddr; | ||
30 | unsigned int netmask; | ||
31 | }; | ||
32 | |||
33 | #define ACT_ALLOW 0 | ||
34 | #define ACT_DENY 1 | ||
35 | |||
36 | typedef struct acl acl_t; | ||
37 | |||
38 | struct acl | ||
39 | { | ||
40 | acl_t *next; | ||
41 | netdef_t *netlist; | ||
42 | int action; | ||
43 | }; | ||
44 | |||
45 | |||
46 | acl_t *acl_head, *acl_tail; | ||
47 | |||
48 | #define DOTTED_QUAD_LEN 16 | ||
49 | |||
50 | static int | ||
51 | read_address (char **line_ptr, char *ptr) | ||
52 | { | ||
53 | char *startp = *line_ptr; | ||
54 | char *endp; | ||
55 | int dotcount = 0; | ||
56 | |||
57 | for (endp = startp; *endp; endp++, ptr++) | ||
58 | if (!(isdigit (*endp) || *endp == '.')) | ||
59 | break; | ||
60 | else if (endp < startp + DOTTED_QUAD_LEN) | ||
61 | { | ||
62 | if (*endp == '.') | ||
63 | dotcount++; | ||
64 | *ptr = *endp; | ||
65 | } | ||
66 | else | ||
67 | break; | ||
68 | *line_ptr = endp; | ||
69 | *ptr = 0; | ||
70 | return dotcount; | ||
71 | } | ||
72 | |||
73 | static netdef_t * | ||
74 | netdef_parse (char *str) | ||
75 | { | ||
76 | unsigned int ipaddr, netmask; | ||
77 | netdef_t *netdef; | ||
78 | char ipbuf[DOTTED_QUAD_LEN+1]; | ||
79 | |||
80 | if (strcmp (str, "any") == 0) | ||
81 | { | ||
82 | ipaddr = 0; | ||
83 | netmask = 0; | ||
84 | } | ||
85 | else | ||
86 | { | ||
87 | read_address (&str, ipbuf); | ||
88 | ipaddr = inet_addr (ipbuf); | ||
89 | if (ipaddr == INADDR_NONE) | ||
90 | return NULL; | ||
91 | if (*str == 0) | ||
92 | netmask = 0xfffffffful; | ||
93 | else if (*str != '/') | ||
94 | return NULL; | ||
95 | else | ||
96 | { | ||
97 | str++; | ||
98 | if (read_address (&str, ipbuf) == 0) | ||
99 | { | ||
100 | /* netmask length */ | ||
101 | unsigned int len = strtoul (ipbuf, NULL, 0); | ||
102 | if (len > 32) | ||
103 | return NULL; | ||
104 | netmask = 0xfffffffful >> (32-len); | ||
105 | netmask <<= (32-len); | ||
106 | /*FIXME: hostorder?*/ | ||
107 | } | ||
108 | else | ||
109 | netmask = inet_network (ipbuf); | ||
110 | netmask = htonl (netmask); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | netdef = malloc (sizeof *netdef); | ||
115 | if (!netdef) | ||
116 | { | ||
117 | syslog (LOG_ERR, "out of memory"); | ||
118 | exit (1); | ||
119 | } | ||
120 | |||
121 | netdef->next = NULL; | ||
122 | netdef->ipaddr = ipaddr; | ||
123 | netdef->netmask = netmask; | ||
124 | |||
125 | return netdef; | ||
126 | } | ||
127 | |||
128 | void | ||
129 | read_config (char *config_file) | ||
130 | { | ||
131 | FILE *fp; | ||
132 | int line; | ||
133 | char buf[128]; | ||
134 | char *ptr; | ||
135 | |||
136 | if (!config_file) | ||
137 | return; | ||
138 | |||
139 | fp = fopen (config_file, "r"); | ||
140 | if (!fp) | ||
141 | { | ||
142 | syslog (LOG_ERR, "can't open config file %s: %m", config_file); | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | line = 0; | ||
147 | while ((ptr = fgets (buf, sizeof buf, fp))) | ||
148 | { | ||
149 | int len, i; | ||
150 | int argc; | ||
151 | char **argv; | ||
152 | int action; | ||
153 | netdef_t *head, *tail; | ||
154 | acl_t *acl; | ||
155 | |||
156 | line++; | ||
157 | len = strlen (ptr); | ||
158 | if (len > 0 && ptr[len-1] == '\n') | ||
159 | ptr[--len] = 0; | ||
160 | |||
161 | while (*ptr && isspace (*ptr)) | ||
162 | ptr++; | ||
163 | if (!*ptr || *ptr == '#') | ||
164 | continue; | ||
165 | |||
166 | argcv_get (ptr, "", &argc, &argv); | ||
167 | if (argc < 2) | ||
168 | { | ||
169 | syslog (LOG_ERR, "%s:%d: too few fields", config_file, line); | ||
170 | argcv_free (argc, argv); | ||
171 | continue; | ||
172 | } | ||
173 | |||
174 | if (strcmp (argv[0], "max-requests") == 0) | ||
175 | maxrequests = strtoul (argv[1], NULL, 0); | ||
176 | else if (strcmp (argv[0], "request-control-interval") == 0) | ||
177 | request_control_interval = strtoul (argv[1], NULL, 0); | ||
178 | else if (strcmp (argv[0], "overflow-control-interval") == 0) | ||
179 | overflow_control_interval = strtoul (argv[1], NULL, 0); | ||
180 | else if (strcmp (argv[0], "overflow-delay-time") == 0) | ||
181 | overflow_delay_time = strtoul (argv[1], NULL, 0); | ||
182 | else if (strcmp (argv[0], "max-lines") == 0) | ||
183 | maxlines = strtoul (argv[1], NULL, 0); | ||
184 | else if (strcmp (argv[0], "acl") == 0) | ||
185 | { | ||
186 | if (strcmp (argv[1], "allow") == 0) | ||
187 | action = ACT_ALLOW; | ||
188 | else if (strcmp (argv[1], "deny") == 0) | ||
189 | action = ACT_DENY; | ||
190 | else | ||
191 | { | ||
192 | syslog (LOG_ERR, "%s:%d: unknown keyword", config_file, line); | ||
193 | argcv_free (argc, argv); | ||
194 | continue; | ||
195 | } | ||
196 | |||
197 | head = tail = NULL; | ||
198 | for (i = 2; i < argc; i++) | ||
199 | { | ||
200 | netdef_t *cur = netdef_parse (argv[i]); | ||
201 | if (!cur) | ||
202 | { | ||
203 | syslog (LOG_ERR, "%s:%d: can't parse netdef: %s", | ||
204 | config_file, line, argv[i]); | ||
205 | continue; | ||
206 | } | ||
207 | if (!tail) | ||
208 | head = cur; | ||
209 | else | ||
210 | tail->next = cur; | ||
211 | tail = cur; | ||
212 | } | ||
213 | |||
214 | argcv_free (argc, argv); | ||
215 | |||
216 | acl = malloc (sizeof *acl); | ||
217 | if (!acl) | ||
218 | { | ||
219 | syslog (LOG_CRIT, "out of memory"); | ||
220 | exit (1); | ||
221 | } | ||
222 | acl->next = NULL; | ||
223 | acl->action = action; | ||
224 | acl->netlist = head; | ||
225 | |||
226 | if (!acl_tail) | ||
227 | acl_head = acl; | ||
228 | else | ||
229 | acl_tail->next = acl; | ||
230 | acl_tail = acl; | ||
231 | } | ||
232 | } | ||
233 | fclose (fp); | ||
234 | } | ||
235 | |||
236 | static void | ||
237 | netdef_free (netdef_t *netdef) | ||
238 | { | ||
239 | netdef_t *next; | ||
240 | |||
241 | while (netdef) | ||
242 | { | ||
243 | next = netdef->next; | ||
244 | free (netdef); | ||
245 | netdef = next; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | static void | ||
250 | acl_free (acl_t *acl) | ||
251 | { | ||
252 | acl_t *next; | ||
253 | |||
254 | while (acl) | ||
255 | { | ||
256 | next = acl->next; | ||
257 | netdef_free (acl->netlist); | ||
258 | free (acl); | ||
259 | acl = next; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | /*NOTE: currently unused. */ | ||
264 | void | ||
265 | discard_acl (acl_t *mark) | ||
266 | { | ||
267 | if (mark) | ||
268 | { | ||
269 | acl_free (mark->next); | ||
270 | acl_tail = mark; | ||
271 | acl_tail->next = NULL; | ||
272 | } | ||
273 | else | ||
274 | acl_head = acl_tail = NULL; | ||
275 | } | ||
276 | |||
277 | int | ||
278 | acl_match (struct sockaddr_in *sa_in) | ||
279 | { | ||
280 | acl_t *acl; | ||
281 | unsigned int ip; | ||
282 | |||
283 | ip = sa_in->sin_addr.s_addr; | ||
284 | for (acl = acl_head; acl; acl = acl->next) | ||
285 | { | ||
286 | netdef_t *net; | ||
287 | |||
288 | for (net = acl->netlist; net; net = net->next) | ||
289 | { | ||
290 | if (net->ipaddr == (ip & net->netmask)) | ||
291 | return acl->action; | ||
292 | } | ||
293 | } | ||
294 | return ACT_ALLOW; | ||
295 | } |
-
Please register or sign in to post a comment