Add new iptables handle task
[rahunas] / src / rh-config.c
1 /**
2  * RahuNAS configuration
3  * Author: Suriya Soutmun <darksolar@gmail.com>
4  * Date:   2008-11-26
5  */
6 #include <ctype.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <syslog.h>
10 #include <dirent.h>
11 #include <errno.h>
12
13 #include "rahunasd.h"
14 #include "rh-config.h"
15
16 enum lcfg_status rahunas_visitor(const char *key, void *data, size_t size, 
17                                  void *user_data) {
18   char *value = strndup(data, size);
19   union rahunas_config *config = (union rahunas_config *)user_data;
20   char *clone_key = NULL;
21   char *sep = NULL; 
22   char *main_key = NULL;
23   char *sub_key = NULL;
24   enum config_type cfg_type;
25
26   if(config == NULL)
27     return lcfg_status_error;
28
29   if(value == NULL)
30     return lcfg_status_error;
31
32   clone_key = strdup(key);
33   if (clone_key == NULL)
34     return lcfg_status_error;
35
36   sep = strstr(clone_key, ".");
37   main_key = clone_key;
38   sub_key = sep + 1;
39   *sep = '\0';
40
41   if (strncmp(main_key, "main", 4) == 0) {
42     cfg_type = MAIN;
43   } else {
44     cfg_type = VSERVER;
45     if (config->rh_vserver.vserver_name == NULL)
46       config->rh_vserver.vserver_name = strdup(main_key);
47   }
48
49   switch (cfg_type) {
50     case MAIN:
51       if (strncmp(sub_key, "conf_dir", 8) == 0) {
52         if (config->rh_main.conf_dir != NULL)
53           free(config->rh_main.conf_dir);
54         config->rh_main.conf_dir = strdup(value);
55       } else if (strncmp(sub_key, "log_file", 8) == 0) {
56         if (config->rh_main.log_file != NULL)
57           free(config->rh_main.log_file);
58         config->rh_main.log_file = strdup(value); 
59       } else if (strncmp(sub_key, "dhcp", 4) == 0) {
60         if (config->rh_main.dhcp != NULL)
61           free(config->rh_main.dhcp);
62         config->rh_main.dhcp = strdup(value);
63       } else if (strncmp(sub_key, "bandwidth_shape", 15) == 0) {
64         if (strncmp(value, "yes", 3) == 0)
65           config->rh_main.bandwidth_shape = 1; 
66         else
67           config->rh_main.bandwidth_shape = 0;
68       } else if (strncmp(sub_key, "bittorrent_download_max", 23) == 0) {
69         config->rh_main.bittorrent_download_max = atoi(value); 
70       } else if (strncmp(sub_key, "bittorrent_upload_max", 21) == 0) {
71         config->rh_main.bittorrent_upload_max = atoi(value); 
72       } else if (strncmp(sub_key, "polling_interval", 16) == 0) {
73         config->rh_main.polling_interval = atoi(value);
74       }      
75       break;
76
77     case VSERVER:
78       if (strncmp(sub_key, "vserver_id", 10) == 0) {
79         config->rh_vserver.vserver_id = atoi(value);
80       } else if (strncmp(sub_key, "dev_external", 12) == 0) {
81         if (config->rh_vserver.dev_external != NULL)
82           free(config->rh_vserver.dev_external);
83         config->rh_vserver.dev_external = strdup(value);
84       } else if (strncmp(sub_key, "dev_internal", 12) == 0) {
85         if (config->rh_vserver.dev_internal != NULL)
86           free(config->rh_vserver.dev_internal);
87         config->rh_vserver.dev_internal = strdup(value);
88       } else if (strncmp(sub_key, "vlan", 4) == 0) {
89         if (config->rh_vserver.vlan != NULL)
90           free(config->rh_vserver.vlan);
91         config->rh_vserver.vlan = strdup(value);
92       } else if (strncmp(sub_key, "vlan_raw_dev_external", 21) == 0) {
93         if (config->rh_vserver.vlan_raw_dev_external != NULL)
94           free(config->rh_vserver.vlan_raw_dev_external);
95         config->rh_vserver.vlan_raw_dev_external = strdup(value);
96        } else if (strncmp(sub_key, "vlan_raw_dev_internal", 21) == 0) {
97         if (config->rh_vserver.vlan_raw_dev_internal != NULL)
98           free(config->rh_vserver.vlan_raw_dev_internal);
99         config->rh_vserver.vlan_raw_dev_internal = strdup(value);
100       } else if (strncmp(sub_key, "bridge", 6) == 0) {
101         if (config->rh_vserver.bridge != NULL)
102           free(config->rh_vserver.bridge);
103         config->rh_vserver.bridge = strdup(value);
104       } else if (strncmp(sub_key, "masquerade", 10) == 0) {
105         if (config->rh_vserver.masquerade != NULL)
106           free(config->rh_vserver.masquerade);
107         config->rh_vserver.masquerade = strdup(value);
108       } else if (strncmp(sub_key, "ignore_mac", 10) == 0) {
109         if (config->rh_vserver.ignore_mac != NULL)
110           free(config->rh_vserver.ignore_mac);
111         config->rh_vserver.ignore_mac = strdup(value);
112       } else if (strncmp(sub_key, "vserver_ip", 10) == 0) {
113         if (config->rh_vserver.vserver_ip != NULL)
114           free(config->rh_vserver.vserver_ip);
115         config->rh_vserver.vserver_ip = strdup(value); 
116       } else if (strncmp(sub_key, "vserver_fqdn", 12) == 0) {
117         if (config->rh_vserver.vserver_fqdn != NULL)
118           free(config->rh_vserver.vserver_fqdn);
119         config->rh_vserver.vserver_fqdn = strdup(value);
120       } else if (strncmp(sub_key, "vserver_ports_allow", 19) == 0) {
121         if (config->rh_vserver.vserver_ports_allow != NULL)
122           free(config->rh_vserver.vserver_ports_allow);
123         config->rh_vserver.vserver_ports_allow = strdup(value);
124       } else if (strncmp(sub_key, "vserver_ports_intercept", 23) == 0) {
125         if (config->rh_vserver.vserver_ports_intercept != NULL)
126           free(config->rh_vserver.vserver_ports_intercept);
127         config->rh_vserver.vserver_ports_intercept = strdup(value);
128       } else if (strncmp(sub_key, "clients", 7) == 0) {
129         if (config->rh_vserver.clients != NULL)
130           free(config->rh_vserver.clients);
131         config->rh_vserver.clients = strdup(value);
132       } else if (strncmp(sub_key, "excluded", 8) == 0) {
133         if (config->rh_vserver.excluded != NULL)
134           free(config->rh_vserver.excluded);
135         config->rh_vserver.excluded = strdup(value);
136       } else if (strncmp(sub_key, "idle_timeout", 12) == 0) {
137         config->rh_vserver.idle_timeout = atoi(value);
138       } else if (strncmp(sub_key, "dns", 3) == 0) {
139         if (config->rh_vserver.dns != NULL)
140           free(config->rh_vserver.dns);
141         config->rh_vserver.dns = strdup(value);
142       } else if (strncmp(sub_key, "ssh", 3) == 0) {
143         if (config->rh_vserver.ssh != NULL)
144           free(config->rh_vserver.ssh);
145         config->rh_vserver.ssh = strdup(value);
146       } else if (strncmp(sub_key, "proxy", 5) == 0) {
147         if (strncmp(sub_key, "proxy_host", 10) == 0) {
148           if (config->rh_vserver.proxy_host != NULL)
149             free(config->rh_vserver.proxy_host);
150           config->rh_vserver.proxy_host = strdup(value);
151         } else if (strncmp(sub_key, "proxy_port", 10) == 0) {
152           if (config->rh_vserver.proxy_port != NULL)
153             free(config->rh_vserver.proxy_port);
154           config->rh_vserver.proxy_port = strdup(value);
155         } else {
156           if (config->rh_vserver.proxy != NULL)
157             free(config->rh_vserver.proxy);
158           config->rh_vserver.proxy = strdup(value);
159         }
160       } else if (strncmp(sub_key, "bittorrent", 10) == 0) {
161         if (strncmp(sub_key, "bittorrent_allow", 16) == 0) {
162           if (config->rh_vserver.bittorrent_allow != NULL)
163             free(config->rh_vserver.bittorrent_allow);
164           config->rh_vserver.bittorrent_allow = strdup(value);
165         } else {
166           if (config->rh_vserver.bittorrent != NULL)
167             free(config->rh_vserver.bittorrent);
168           config->rh_vserver.bittorrent = strdup(value);
169         }
170       } else if (strncmp(sub_key, "radius_host", 11) == 0) {
171         if (config->rh_vserver.radius_host != NULL)
172           free(config->rh_vserver.radius_host);
173         config->rh_vserver.radius_host = strdup(value);
174       } else if (strncmp(sub_key, "radius_secret", 13) == 0) {
175         if (config->rh_vserver.radius_secret != NULL)
176           free(config->rh_vserver.radius_secret);
177         config->rh_vserver.radius_secret = strdup(value);
178       } else if (strncmp(sub_key, "radius_encrypt", 14) == 0) {
179         if (config->rh_vserver.radius_encrypt != NULL)
180           free(config->rh_vserver.radius_encrypt);
181         config->rh_vserver.radius_encrypt = strdup(value);
182       } else if (strncmp(sub_key, "radius_auth_port", 16) == 0) {
183         if (config->rh_vserver.radius_auth_port != NULL)
184           free(config->rh_vserver.radius_auth_port);
185         config->rh_vserver.radius_auth_port = strdup(value);
186       } else if (strncmp(sub_key, "radius_account_port", 19) == 0) {
187         if (config->rh_vserver.radius_account_port != NULL)
188           free(config->rh_vserver.radius_account_port);
189         config->rh_vserver.radius_account_port = strdup(value);
190       } else if (strncmp(sub_key, "nas_identifier", 14) == 0) {
191         if (config->rh_vserver.nas_identifier != NULL)
192           free(config->rh_vserver.nas_identifier);
193         config->rh_vserver.nas_identifier = strdup(value);
194       } else if (strncmp(sub_key, "nas_port", 8) == 0) {
195         if (config->rh_vserver.nas_port != NULL)
196           free(config->rh_vserver.nas_port);
197         config->rh_vserver.nas_port = strdup(value);
198       } else if (strncmp(sub_key, "nas_login_title", 15) == 0) {
199         if (config->rh_vserver.nas_login_title != NULL)
200           free(config->rh_vserver.nas_login_title);
201         config->rh_vserver.nas_login_title = strdup(value);
202       } else if (strncmp(sub_key, "nas_default_redirect", 20) == 0) {
203         if (config->rh_vserver.nas_default_redirect != NULL)
204           free(config->rh_vserver.nas_default_redirect);
205         config->rh_vserver.nas_default_redirect = strdup(value);
206       } else if (strncmp(sub_key, "nas_default_language", 20) == 0) {
207         if (config->rh_vserver.nas_default_language != NULL)
208           free(config->rh_vserver.nas_default_language);
209         config->rh_vserver.nas_default_language = strdup(value);
210       } else if (strncmp(sub_key, "nas_weblogin_template", 21) == 0) {
211         if (config->rh_vserver.nas_weblogin_template != NULL)
212           free(config->rh_vserver.nas_weblogin_template);
213         config->rh_vserver.nas_weblogin_template = strdup(value);
214       }
215       break;
216   }
217
218   
219   rh_free(&clone_key);
220
221   return lcfg_status_ok;
222 }
223
224 int get_config(const char *cfg_file, union rahunas_config *config) {
225   lcfg_visitor_function visitor_func = rahunas_visitor;
226   struct lcfg *c = lcfg_new(cfg_file);
227   
228   syslog(LOG_INFO, "Parsing config file: %s", cfg_file);
229
230   if (lcfg_parse(c) != lcfg_status_ok) {
231     syslog(LOG_ERR, "config error: %s", lcfg_error_get(c));
232     lcfg_delete(c);
233     return -1;
234   }
235
236   syslog(LOG_INFO, "Processing config file: %s", cfg_file);
237   if (lcfg_accept(c, visitor_func, config) != lcfg_status_ok) {
238     syslog(LOG_ERR, "config error: %s", lcfg_error_get(c));
239     lcfg_delete(c);
240     return -1;
241   }
242
243   lcfg_delete(c);
244
245   return 0;
246 }
247
248
249 int get_value(const char *cfg_file, const char *key, void **data, size_t *len)
250 {
251   lcfg_visitor_function visitor_func = rahunas_visitor;
252   struct lcfg *c = lcfg_new(cfg_file);
253   
254   if (lcfg_parse(c) != lcfg_status_ok) {
255     syslog(LOG_ERR, "config error: %s", lcfg_error_get(c));
256     lcfg_delete(c);
257     return -1;
258   }
259
260   if (lcfg_value_get(c, key, data, len) != lcfg_status_ok) {
261     lcfg_delete(c);
262     return -1;
263   } 
264
265   lcfg_delete(c);
266
267   return 0;
268 }
269
270 int get_vservers_config(const char *conf_dir, struct main_server *server)
271 {
272   DIR *dp;
273   struct dirent *dirp;
274   void *data = NULL;
275   size_t len;
276   char conf_file[200];
277
278   if ((dp = opendir(conf_dir)) == NULL)
279     return errno;
280   
281   while ((dirp = readdir(dp)) != NULL) {
282     if (strstr(dirp->d_name, ".conf") == NULL)
283       continue;
284
285     memset(conf_file, 0, sizeof(conf_file));
286
287     strncat(conf_file, conf_dir, sizeof(conf_file));
288     strncat(conf_file, "/", 1);
289     strncat(conf_file, dirp->d_name, sizeof(conf_file));
290
291     syslog(LOG_INFO, "Loading config file: %s", conf_file);
292     
293     register_vserver(server, conf_file);
294   }
295   
296   closedir(dp);
297   return 0;
298 }
299
300
301 int cleanup_vserver_config(struct rahunas_vserver_config *config)
302 {
303   rh_free(&(config->vserver_name));  
304   rh_free(&(config->dev_external));
305   rh_free(&(config->dev_internal));
306   rh_free(&(config->vlan));
307   rh_free(&(config->vlan_raw_dev_external));
308   rh_free(&(config->vlan_raw_dev_internal));
309   rh_free(&(config->bridge));
310   rh_free(&(config->masquerade));
311   rh_free(&(config->ignore_mac));
312   rh_free(&(config->vserver_ip));
313   rh_free(&(config->vserver_fqdn));
314   rh_free(&(config->vserver_ports_allow));
315   rh_free(&(config->vserver_ports_intercept));
316   rh_free(&(config->clients));
317   rh_free(&(config->excluded));
318   rh_free(&(config->dns));
319   rh_free(&(config->ssh));
320   rh_free(&(config->proxy));
321   rh_free(&(config->proxy_host));
322   rh_free(&(config->proxy_port));
323   rh_free(&(config->bittorrent));
324   rh_free(&(config->bittorrent_allow));
325   rh_free(&(config->radius_host));
326   rh_free(&(config->radius_secret));
327   rh_free(&(config->radius_encrypt));
328   rh_free(&(config->radius_auth_port));
329   rh_free(&(config->radius_account_port));
330   rh_free(&(config->nas_identifier));
331   rh_free(&(config->nas_port));
332   rh_free(&(config->nas_login_title));
333   rh_free(&(config->nas_default_redirect));
334   rh_free(&(config->nas_default_language));
335   rh_free(&(config->nas_weblogin_template));
336
337   return 0;
338 }
339
340 int cleanup_mainserver_config(struct rahunas_main_config *config)
341 {
342   rh_free(&(config->conf_dir));  
343   rh_free(&(config->log_file));
344   rh_free(&(config->dhcp));
345
346   return 0;
347 }