Branch data Line data Source code
1 : : /*
2 : : ******************************************************************************
3 : : *
4 : : * File: config_init.c
5 : : *
6 : : * Purpose: Command-line and config file processing for fwknop server.
7 : : *
8 : : * Fwknop is developed primarily by the people listed in the file 'AUTHORS'.
9 : : * Copyright (C) 2009-2014 fwknop developers and contributors. For a full
10 : : * list of contributors, see the file 'CREDITS'.
11 : : *
12 : : * License (GNU General Public License):
13 : : *
14 : : * This program is free software; you can redistribute it and/or
15 : : * modify it under the terms of the GNU General Public License
16 : : * as published by the Free Software Foundation; either version 2
17 : : * of the License, or (at your option) any later version.
18 : : *
19 : : * This program is distributed in the hope that it will be useful,
20 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 : : * GNU General Public License for more details.
23 : : *
24 : : * You should have received a copy of the GNU General Public License
25 : : * along with this program; if not, write to the Free Software
26 : : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 : : * USA
28 : : *
29 : : ******************************************************************************
30 : : */
31 : : #include "fwknopd_common.h"
32 : : #include "fwknopd_errors.h"
33 : : #include "config_init.h"
34 : : #include "access.h"
35 : : #include "cmd_opts.h"
36 : : #include "utils.h"
37 : : #include "log_msg.h"
38 : :
39 : : #if FIREWALL_FIREWALLD
40 : : #include "fw_util_firewalld.h"
41 : : #elif FIREWALL_IPTABLES
42 : : #include "fw_util_iptables.h"
43 : : #endif
44 : :
45 : : /* Check to see if an integer variable has a value that is within a
46 : : * specific range
47 : : */
48 : : static void
49 : 10415 : range_check(fko_srv_options_t *opts, char *var, char *val, int low, int high)
50 : : {
51 : : int is_err;
52 : :
53 : 10415 : strtol_wrapper(val, low, high, NO_EXIT_UPON_ERR, &is_err);
54 [ + + ]: 10415 : if(is_err != FKO_SUCCESS)
55 : : {
56 : 119 : log_msg(LOG_ERR, "[*] var %s value '%s' not in the range %d-%d",
57 : : var, val, low, high);
58 : 119 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
59 : : }
60 : :
61 : 10296 : return;
62 : : }
63 : :
64 : : /* Take an index and a string value. malloc the space for the value
65 : : * and assign it to the array at the specified index.
66 : : */
67 : : static void
68 : 102288 : set_config_entry(fko_srv_options_t *opts, const int var_ndx, const char *value)
69 : : {
70 : : int space_needed;
71 : :
72 : : /* Sanity check the index value.
73 : : */
74 [ - + ]: 102288 : if(var_ndx < 0 || var_ndx >= NUMBER_OF_CONFIG_ENTRIES)
75 : : {
76 : 0 : log_msg(LOG_ERR, "[*] Index value of %i is not valid", var_ndx);
77 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
78 : : }
79 : :
80 : : /* If this particular entry was already set (i.e. not NULL), then
81 : : * assume it needs to be freed first.
82 : : */
83 [ + + ]: 102288 : if(opts->config[var_ndx] != NULL)
84 : 25843 : free(opts->config[var_ndx]);
85 : :
86 : : /* If we are setting it to NULL, do it and be done.
87 : : */
88 [ - + ]: 102288 : if(value == NULL)
89 : : {
90 : 0 : opts->config[var_ndx] = NULL;
91 : 0 : return;
92 : : }
93 : :
94 : : /* Otherwise, make the space we need and set it.
95 : : */
96 : 102288 : space_needed = strlen(value) + 1;
97 : :
98 : 102288 : opts->config[var_ndx] = calloc(1, space_needed);
99 : :
100 [ - + ]: 102288 : if(opts->config[var_ndx] == NULL)
101 : : {
102 : 0 : log_msg(LOG_ERR, "[*] Fatal memory allocation error!");
103 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
104 : : }
105 : :
106 : 102288 : strlcpy(opts->config[var_ndx], value, space_needed);
107 : :
108 : 102288 : return;
109 : : }
110 : :
111 : : /* Given a config parameter name, return its index or -1 if not found.
112 : : */
113 : : static int
114 : 10361 : config_entry_index(const fko_srv_options_t *opts, const char *var)
115 : : {
116 : : int i;
117 : :
118 [ + + ]: 347555 : for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
119 [ + + ][ + + ]: 345816 : if(opts->config[i] != NULL && CONF_VAR_IS(var, config_map[i]))
120 : 8622 : return(i);
121 : :
122 : : return(-1);
123 : : }
124 : :
125 : : /* Free the config memory
126 : : */
127 : : void
128 : 1814 : free_configs(fko_srv_options_t *opts)
129 : : {
130 : : int i;
131 : :
132 : 1814 : free_acc_stanzas(opts);
133 : :
134 [ + + ]: 90700 : for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
135 [ + + ]: 88886 : if(opts->config[i] != NULL)
136 : 76445 : free(opts->config[i]);
137 : 1814 : }
138 : :
139 : : static void
140 : 1797 : validate_int_var_ranges(fko_srv_options_t *opts)
141 : : {
142 : : #if FIREWALL_IPFW
143 : : int is_err = FKO_SUCCESS;
144 : : #endif
145 : :
146 : 1797 : range_check(opts, "PCAP_LOOP_SLEEP", opts->config[CONF_PCAP_LOOP_SLEEP],
147 : : 1, RCHK_MAX_PCAP_LOOP_SLEEP);
148 : 1764 : range_check(opts, "MAX_SPA_PACKET_AGE", opts->config[CONF_MAX_SPA_PACKET_AGE],
149 : : 1, RCHK_MAX_SPA_PACKET_AGE);
150 : 1750 : range_check(opts, "MAX_SNIFF_BYTES", opts->config[CONF_MAX_SNIFF_BYTES],
151 : : 1, RCHK_MAX_SNIFF_BYTES);
152 : 1712 : range_check(opts, "TCPSERV_PORT", opts->config[CONF_TCPSERV_PORT],
153 : : 1, RCHK_MAX_TCPSERV_PORT);
154 : 1703 : range_check(opts, "UDPSERV_PORT", opts->config[CONF_UDPSERV_PORT],
155 : : 1, RCHK_MAX_UDPSERV_PORT);
156 : 1689 : range_check(opts, "UDPSERV_PORT", opts->config[CONF_UDPSERV_SELECT_TIMEOUT],
157 : : 1, RCHK_MAX_UDPSERV_SELECT_TIMEOUT);
158 : :
159 : : #if FIREWALL_IPFW
160 : : range_check(opts, "IPFW_START_RULE_NUM", opts->config[CONF_IPFW_START_RULE_NUM],
161 : : 0, RCHK_MAX_IPFW_START_RULE_NUM);
162 : : range_check(opts, "IPFW_MAX_RULES", opts->config[CONF_IPFW_MAX_RULES],
163 : : 1, RCHK_MAX_IPFW_MAX_RULES);
164 : : range_check(opts, "IPFW_ACTIVE_SET_NUM", opts->config[CONF_IPFW_ACTIVE_SET_NUM],
165 : : 0, RCHK_MAX_IPFW_SET_NUM);
166 : : range_check(opts, "IPFW_EXPIRE_SET_NUM", opts->config[CONF_IPFW_EXPIRE_SET_NUM],
167 : : 0, RCHK_MAX_IPFW_SET_NUM);
168 : : range_check(opts, "IPFW_EXPIRE_PURGE_INTERVAL",
169 : : opts->config[CONF_IPFW_EXPIRE_PURGE_INTERVAL],
170 : : 1, RCHK_MAX_IPFW_PURGE_INTERVAL);
171 : :
172 : : /* Make sure the active and expire sets are not identical whenever
173 : : * they are non-zero
174 : : */
175 : : if((strtol_wrapper(opts->config[CONF_IPFW_ACTIVE_SET_NUM],
176 : : 0, RCHK_MAX_IPFW_SET_NUM, NO_EXIT_UPON_ERR, &is_err) > 0
177 : : && strtol_wrapper(opts->config[CONF_IPFW_EXPIRE_SET_NUM],
178 : : 0, RCHK_MAX_IPFW_SET_NUM, NO_EXIT_UPON_ERR, &is_err) > 0)
179 : : && strtol_wrapper(opts->config[CONF_IPFW_ACTIVE_SET_NUM],
180 : : 0, RCHK_MAX_IPFW_SET_NUM, NO_EXIT_UPON_ERR, &is_err)
181 : : == strtol_wrapper(opts->config[CONF_IPFW_EXPIRE_SET_NUM],
182 : : 0, RCHK_MAX_IPFW_SET_NUM, NO_EXIT_UPON_ERR, &is_err))
183 : : {
184 : : log_msg(LOG_ERR,
185 : : "[*] Cannot set identical ipfw active and expire sets.");
186 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
187 : : }
188 : :
189 : : if(is_err != FKO_SUCCESS)
190 : : {
191 : : log_msg(LOG_ERR, "[*] invalid integer conversion error.\n");
192 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
193 : : }
194 : :
195 : : #elif FIREWALL_PF
196 : : range_check(opts, "PF_EXPIRE_INTERVAL", opts->config[CONF_PF_EXPIRE_INTERVAL],
197 : : 1, RCHK_MAX_PF_EXPIRE_INTERVAL);
198 : :
199 : : #endif /* FIREWALL type */
200 : :
201 : 1678 : return;
202 : : }
203 : :
204 : : /* Parse the config file...
205 : : */
206 : : static void
207 : 3628 : parse_config_file(fko_srv_options_t *opts, const char *config_file)
208 : : {
209 : : FILE *cfile_ptr;
210 : 3628 : unsigned int numLines = 0;
211 : : unsigned int i, good_ent;
212 : : int cndx;
213 : :
214 : 3628 : char conf_line_buf[MAX_LINE_LEN] = {0};
215 : 3628 : char var[MAX_LINE_LEN] = {0};
216 : 3628 : char val[MAX_LINE_LEN] = {0};
217 : 3628 : char tmp1[MAX_LINE_LEN] = {0};
218 : 3628 : char tmp2[MAX_LINE_LEN] = {0};
219 : :
220 : : struct stat st;
221 : :
222 : : /* Make sure the config file exists.
223 : : */
224 [ - + ]: 3628 : if(stat(config_file, &st) != 0)
225 : : {
226 : 0 : log_msg(LOG_ERR, "[*] Config file: '%s' was not found.",
227 : : config_file);
228 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
229 : : }
230 : :
231 [ - + ]: 3628 : if(verify_file_perms_ownership(config_file) != 1)
232 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
233 : :
234 : : /* See the comment in the parse_access_file() function regarding security
235 : : * here relative to a TOCTOU bug flagged by Coverity.
236 : : */
237 [ - + ]: 3628 : if ((cfile_ptr = fopen(config_file, "r")) == NULL)
238 : : {
239 : 0 : log_msg(LOG_ERR, "[*] Could not open config file: %s",
240 : : config_file);
241 : 0 : perror(NULL);
242 : :
243 : 3628 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
244 : : }
245 : :
246 [ + + ]: 111880 : while ((fgets(conf_line_buf, MAX_LINE_LEN, cfile_ptr)) != NULL)
247 : : {
248 : 108252 : numLines++;
249 : 108252 : conf_line_buf[MAX_LINE_LEN-1] = '\0';
250 : :
251 : : /* Get past comments and empty lines (note: we only look at the
252 : : * first character.
253 : : */
254 [ + + ][ + - ]: 108252 : if(IS_EMPTY_LINE(conf_line_buf[0]))
[ + + ][ + + ]
255 : 8873 : continue;
256 : :
257 [ + + ]: 99379 : if(sscanf(conf_line_buf, "%s %[^;\n\r]", var, val) != 2)
258 : : {
259 : 12787 : log_msg(LOG_ERR,
260 : : "*Invalid config file entry in %s at line %i.\n - '%s'",
261 : : config_file, numLines, conf_line_buf
262 : : );
263 : 12787 : continue;
264 : : }
265 : :
266 : : good_ent = 0;
267 [ + + ]: 3397956 : for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
268 : : {
269 [ + + ]: 3347537 : if(CONF_VAR_IS(config_map[i], var))
270 : : {
271 : : /* First check to see if we need to do a varable expansion
272 : : * on this value. Note: this only supports one expansion and
273 : : * only if the value starts with the variable.
274 : : */
275 [ + + ]: 36173 : if(*val == '$')
276 : : {
277 [ + + ]: 10745 : if(sscanf((val+1), "%[A-Z_]%s", tmp1, tmp2))
278 : : {
279 [ + + ]: 10361 : if((cndx = config_entry_index(opts, tmp1)) >= 0)
280 : : {
281 : 8622 : strlcpy(val, opts->config[cndx], sizeof(val));
282 : 8622 : strlcat(val, tmp2, sizeof(val));
283 : : }
284 : : else
285 : : {
286 : : /* We didn't map the embedded variable to a valid
287 : : * config parameter
288 : : */
289 : 1739 : log_msg(LOG_ERR,
290 : : "[*] Invalid embedded variable in: '%s'", val);
291 : 1739 : break;
292 : : }
293 : : }
294 : : }
295 : :
296 : 34434 : set_config_entry(opts, i, val);
297 : 34434 : good_ent++;
298 : 34434 : break;
299 : : }
300 : : }
301 : :
302 [ + + ]: 86592 : if(good_ent == 0)
303 : 108252 : log_msg(LOG_ERR,
304 : : "[*] Ignoring unknown configuration parameter: '%s' in %s",
305 : : var, config_file
306 : : );
307 : : }
308 : :
309 : 3628 : fclose(cfile_ptr);
310 : :
311 : 3628 : return;
312 : : }
313 : :
314 : : /* Set defaults, and do sanity and bounds checks for the various options.
315 : : */
316 : : static void
317 : 1797 : validate_options(fko_srv_options_t *opts)
318 : : {
319 : 1797 : char tmp_path[MAX_PATH_LEN] = {0};
320 : :
321 : : /* If no conf dir is set in the config file, use the default.
322 : : */
323 [ + + ]: 1797 : if(opts->config[CONF_FWKNOP_CONF_DIR] == NULL)
324 : 1562 : set_config_entry(opts, CONF_FWKNOP_CONF_DIR, DEF_CONF_DIR);
325 : :
326 : : /* If no access.conf path was specified on the command line or set in
327 : : * the config file, use the default.
328 : : */
329 [ - + ]: 1797 : if(opts->config[CONF_ACCESS_FILE] == NULL)
330 : 0 : set_config_entry(opts, CONF_ACCESS_FILE, DEF_ACCESS_FILE);
331 : :
332 : : /* If the pid and digest cache files where not set in the config file or
333 : : * via command-line, then grab the defaults. Start with RUN_DIR as the
334 : : * files may depend on that.
335 : : */
336 [ + + ]: 1797 : if(opts->config[CONF_FWKNOP_RUN_DIR] == NULL)
337 : 448 : set_config_entry(opts, CONF_FWKNOP_RUN_DIR, DEF_RUN_DIR);
338 : :
339 [ + + ]: 1797 : if(opts->config[CONF_FWKNOP_PID_FILE] == NULL)
340 : : {
341 : 1536 : strlcpy(tmp_path, opts->config[CONF_FWKNOP_RUN_DIR], sizeof(tmp_path));
342 : :
343 [ + - ]: 1536 : if(tmp_path[strlen(tmp_path)-1] != '/')
344 : 1536 : strlcat(tmp_path, "/", sizeof(tmp_path));
345 : :
346 : 1536 : strlcat(tmp_path, DEF_PID_FILENAME, sizeof(tmp_path));
347 : :
348 : 1536 : set_config_entry(opts, CONF_FWKNOP_PID_FILE, tmp_path);
349 : : }
350 : :
351 : : #if USE_FILE_CACHE
352 [ + + ]: 1797 : if(opts->config[CONF_DIGEST_FILE] == NULL)
353 : : #else
354 : : if(opts->config[CONF_DIGEST_DB_FILE] == NULL)
355 : : #endif
356 : : {
357 : 1459 : strlcpy(tmp_path, opts->config[CONF_FWKNOP_RUN_DIR], sizeof(tmp_path));
358 : :
359 [ + - ]: 1459 : if(tmp_path[strlen(tmp_path)-1] != '/')
360 : 1459 : strlcat(tmp_path, "/", sizeof(tmp_path));
361 : :
362 : : #if USE_FILE_CACHE
363 : 1459 : strlcat(tmp_path, DEF_DIGEST_CACHE_FILENAME, sizeof(tmp_path));
364 : 1459 : set_config_entry(opts, CONF_DIGEST_FILE, tmp_path);
365 : : #else
366 : : strlcat(tmp_path, DEF_DIGEST_CACHE_DB_FILENAME, sizeof(tmp_path));
367 : : set_config_entry(opts, CONF_DIGEST_DB_FILE, tmp_path);
368 : : #endif
369 : : }
370 : :
371 : : /* Set remaining require CONF_ vars if they are not already set. */
372 : :
373 : : /* PCAP capture interface - note that if '-r <pcap file>' is specified
374 : : * on the command line, then this will override the pcap interface setting.
375 : : */
376 [ + + ]: 1797 : if(opts->config[CONF_PCAP_INTF] == NULL)
377 : 1475 : set_config_entry(opts, CONF_PCAP_INTF, DEF_INTERFACE);
378 : :
379 : : /* PCAP Promiscuous mode.
380 : : */
381 [ + + ]: 1797 : if(opts->config[CONF_ENABLE_PCAP_PROMISC] == NULL)
382 : 1483 : set_config_entry(opts, CONF_ENABLE_PCAP_PROMISC,
383 : : DEF_ENABLE_PCAP_PROMISC);
384 : :
385 : : /* The packet count argument to pcap_dispatch()
386 : : */
387 [ + + ]: 1797 : if(opts->config[CONF_PCAP_DISPATCH_COUNT] == NULL)
388 : 1565 : set_config_entry(opts, CONF_PCAP_DISPATCH_COUNT,
389 : : DEF_PCAP_DISPATCH_COUNT);
390 : :
391 : : /* Microseconds to sleep between pcap loop iterations
392 : : */
393 [ + + ]: 1797 : if(opts->config[CONF_PCAP_LOOP_SLEEP] == NULL)
394 : 1539 : set_config_entry(opts, CONF_PCAP_LOOP_SLEEP,
395 : : DEF_PCAP_LOOP_SLEEP);
396 : :
397 : : /* PCAP Filter.
398 : : */
399 [ + + ]: 1797 : if(opts->config[CONF_PCAP_FILTER] == NULL)
400 : 1435 : set_config_entry(opts, CONF_PCAP_FILTER, DEF_PCAP_FILTER);
401 : :
402 : : /* Enable SPA packet aging unless we're getting packet data
403 : : * directly from a pcap file
404 : : */
405 [ + + ]: 1797 : if(opts->config[CONF_ENABLE_SPA_PACKET_AGING] == NULL)
406 : : {
407 [ + + ]: 1541 : if(opts->config[CONF_PCAP_FILE] == NULL)
408 : : {
409 : 1532 : set_config_entry(opts, CONF_ENABLE_SPA_PACKET_AGING,
410 : : DEF_ENABLE_SPA_PACKET_AGING);
411 : : }
412 : : else
413 : : {
414 : 9 : set_config_entry(opts, CONF_ENABLE_SPA_PACKET_AGING, "N");
415 : : }
416 : : }
417 : :
418 : : /* SPA packet age.
419 : : */
420 [ + + ]: 1797 : if(opts->config[CONF_MAX_SPA_PACKET_AGE] == NULL)
421 : 1579 : set_config_entry(opts, CONF_MAX_SPA_PACKET_AGE,
422 : : DEF_MAX_SPA_PACKET_AGE);
423 : :
424 : :
425 : : /* Enable digest persistence.
426 : : */
427 [ + + ]: 1797 : if(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE] == NULL)
428 : 519 : set_config_entry(opts, CONF_ENABLE_DIGEST_PERSISTENCE,
429 : : DEF_ENABLE_DIGEST_PERSISTENCE);
430 : :
431 : : /* Enable destination rule.
432 : : */
433 [ + - ]: 1797 : if(opts->config[CONF_ENABLE_DESTINATION_RULE] == NULL)
434 : 1797 : set_config_entry(opts, CONF_ENABLE_DESTINATION_RULE,
435 : : DEF_ENABLE_DESTINATION_RULE);
436 : :
437 : : /* Max sniff bytes.
438 : : */
439 [ + + ]: 1797 : if(opts->config[CONF_MAX_SNIFF_BYTES] == NULL)
440 : 1610 : set_config_entry(opts, CONF_MAX_SNIFF_BYTES, DEF_MAX_SNIFF_BYTES);
441 : :
442 : : #if FIREWALL_FIREWALLD
443 : : /* Enable FIREWD forwarding.
444 : : */
445 [ + - ]: 1797 : if(opts->config[CONF_ENABLE_FIREWD_FORWARDING] == NULL)
446 : 1797 : set_config_entry(opts, CONF_ENABLE_FIREWD_FORWARDING,
447 : : DEF_ENABLE_FIREWD_FORWARDING);
448 : :
449 : : /* Enable FIREWD local NAT.
450 : : */
451 [ + - ]: 1797 : if(opts->config[CONF_ENABLE_FIREWD_LOCAL_NAT] == NULL)
452 : 1797 : set_config_entry(opts, CONF_ENABLE_FIREWD_LOCAL_NAT,
453 : : DEF_ENABLE_FIREWD_LOCAL_NAT);
454 : :
455 : : /* Enable FIREWD SNAT.
456 : : */
457 [ + - ]: 1797 : if(opts->config[CONF_ENABLE_FIREWD_SNAT] == NULL)
458 : 1797 : set_config_entry(opts, CONF_ENABLE_FIREWD_SNAT,
459 : : DEF_ENABLE_FIREWD_SNAT);
460 : :
461 : : /* Make sure we have a valid IP if SNAT is enabled
462 : : */
463 [ - + ]: 1797 : if(strncasecmp(opts->config[CONF_ENABLE_FIREWD_SNAT], "Y", 1) == 0)
464 : : {
465 : : /* Note that fw_config_init() will set use_masquerade if necessary
466 : : */
467 [ # # ]: 0 : if(opts->config[CONF_SNAT_TRANSLATE_IP] != NULL)
468 : : {
469 [ # # ]: 0 : if(! is_valid_ipv4_addr(opts->config[CONF_SNAT_TRANSLATE_IP]))
470 : : {
471 : 0 : log_msg(LOG_ERR,
472 : : "Invalid IPv4 addr for SNAT_TRANSLATE_IP"
473 : : );
474 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
475 : : }
476 : : }
477 : : }
478 : :
479 : : /* Enable FIREWD OUTPUT.
480 : : */
481 [ + - ]: 1797 : if(opts->config[CONF_ENABLE_FIREWD_OUTPUT] == NULL)
482 : 1797 : set_config_entry(opts, CONF_ENABLE_FIREWD_OUTPUT,
483 : : DEF_ENABLE_FIREWD_OUTPUT);
484 : :
485 : : /* Flush FIREWD at init.
486 : : */
487 [ + - ]: 1797 : if(opts->config[CONF_FLUSH_FIREWD_AT_INIT] == NULL)
488 : 1797 : set_config_entry(opts, CONF_FLUSH_FIREWD_AT_INIT, DEF_FLUSH_FIREWD_AT_INIT);
489 : :
490 : : /* Flush FIREWD at exit.
491 : : */
492 [ + - ]: 1797 : if(opts->config[CONF_FLUSH_FIREWD_AT_EXIT] == NULL)
493 : 1797 : set_config_entry(opts, CONF_FLUSH_FIREWD_AT_EXIT, DEF_FLUSH_FIREWD_AT_EXIT);
494 : :
495 : : /* FIREWD input access.
496 : : */
497 [ + - ]: 1797 : if(opts->config[CONF_FIREWD_INPUT_ACCESS] == NULL)
498 : 1797 : set_config_entry(opts, CONF_FIREWD_INPUT_ACCESS,
499 : : DEF_FIREWD_INPUT_ACCESS);
500 : :
501 [ - + ]: 1797 : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_INPUT_ACCESS]) != 1)
502 : : {
503 : 0 : log_msg(LOG_ERR,
504 : : "Invalid FIREWD_INPUT_ACCESS specification, see fwknopd.conf comments"
505 : : );
506 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
507 : : }
508 : :
509 : : /* FIREWD output access.
510 : : */
511 [ + - ]: 1797 : if(opts->config[CONF_FIREWD_OUTPUT_ACCESS] == NULL)
512 : 1797 : set_config_entry(opts, CONF_FIREWD_OUTPUT_ACCESS,
513 : : DEF_FIREWD_OUTPUT_ACCESS);
514 : :
515 [ - + ]: 1797 : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_OUTPUT_ACCESS]) != 1)
516 : : {
517 : 0 : log_msg(LOG_ERR,
518 : : "Invalid FIREWD_OUTPUT_ACCESS specification, see fwknopd.conf comments"
519 : : );
520 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
521 : : }
522 : :
523 : : /* FIREWD forward access.
524 : : */
525 [ + - ]: 1797 : if(opts->config[CONF_FIREWD_FORWARD_ACCESS] == NULL)
526 : 1797 : set_config_entry(opts, CONF_FIREWD_FORWARD_ACCESS,
527 : : DEF_FIREWD_FORWARD_ACCESS);
528 : :
529 [ - + ]: 1797 : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_FORWARD_ACCESS]) != 1)
530 : : {
531 : 0 : log_msg(LOG_ERR,
532 : : "Invalid FIREWD_FORWARD_ACCESS specification, see fwknopd.conf comments"
533 : : );
534 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
535 : : }
536 : :
537 : : /* FIREWD dnat access.
538 : : */
539 [ + - ]: 1797 : if(opts->config[CONF_FIREWD_DNAT_ACCESS] == NULL)
540 : 1797 : set_config_entry(opts, CONF_FIREWD_DNAT_ACCESS,
541 : : DEF_FIREWD_DNAT_ACCESS);
542 : :
543 [ - + ]: 1797 : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_DNAT_ACCESS]) != 1)
544 : : {
545 : 0 : log_msg(LOG_ERR,
546 : : "Invalid FIREWD_DNAT_ACCESS specification, see fwknopd.conf comments"
547 : : );
548 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
549 : : }
550 : :
551 : : /* FIREWD snat access.
552 : : */
553 [ + - ]: 1797 : if(opts->config[CONF_FIREWD_SNAT_ACCESS] == NULL)
554 : 1797 : set_config_entry(opts, CONF_FIREWD_SNAT_ACCESS,
555 : : DEF_FIREWD_SNAT_ACCESS);
556 : :
557 [ - + ]: 1797 : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_SNAT_ACCESS]) != 1)
558 : : {
559 : 0 : log_msg(LOG_ERR,
560 : : "Invalid FIREWD_SNAT_ACCESS specification, see fwknopd.conf comments"
561 : : );
562 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
563 : : }
564 : :
565 : : /* FIREWD masquerade access.
566 : : */
567 [ + - ]: 1797 : if(opts->config[CONF_FIREWD_MASQUERADE_ACCESS] == NULL)
568 : 1797 : set_config_entry(opts, CONF_FIREWD_MASQUERADE_ACCESS,
569 : : DEF_FIREWD_MASQUERADE_ACCESS);
570 : :
571 [ - + ]: 1797 : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_MASQUERADE_ACCESS]) != 1)
572 : : {
573 : 0 : log_msg(LOG_ERR,
574 : : "Invalid FIREWD_MASQUERADE_ACCESS specification, see fwknopd.conf comments"
575 : : );
576 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
577 : : }
578 : :
579 : : /* Check for the firewalld 'comment' match at init time
580 : : */
581 [ + - ]: 1797 : if(opts->config[CONF_ENABLE_FIREWD_COMMENT_CHECK] == NULL)
582 : 1797 : set_config_entry(opts, CONF_ENABLE_FIREWD_COMMENT_CHECK,
583 : : DEF_ENABLE_FIREWD_COMMENT_CHECK);
584 : :
585 : : #elif FIREWALL_IPTABLES
586 : : /* Enable IPT forwarding.
587 : : */
588 : : if(opts->config[CONF_ENABLE_IPT_FORWARDING] == NULL)
589 : : set_config_entry(opts, CONF_ENABLE_IPT_FORWARDING,
590 : : DEF_ENABLE_IPT_FORWARDING);
591 : :
592 : : /* Enable IPT local NAT.
593 : : */
594 : : if(opts->config[CONF_ENABLE_IPT_LOCAL_NAT] == NULL)
595 : : set_config_entry(opts, CONF_ENABLE_IPT_LOCAL_NAT,
596 : : DEF_ENABLE_IPT_LOCAL_NAT);
597 : :
598 : : /* Enable IPT SNAT.
599 : : */
600 : : if(opts->config[CONF_ENABLE_IPT_SNAT] == NULL)
601 : : set_config_entry(opts, CONF_ENABLE_IPT_SNAT,
602 : : DEF_ENABLE_IPT_SNAT);
603 : :
604 : : /* Make sure we have a valid IP if SNAT is enabled
605 : : */
606 : : if(strncasecmp(opts->config[CONF_ENABLE_IPT_SNAT], "Y", 1) == 0)
607 : : {
608 : : /* Note that fw_config_init() will set use_masquerade if necessary
609 : : */
610 : : if(opts->config[CONF_SNAT_TRANSLATE_IP] != NULL)
611 : : {
612 : : if(! is_valid_ipv4_addr(opts->config[CONF_SNAT_TRANSLATE_IP]))
613 : : {
614 : : log_msg(LOG_ERR,
615 : : "Invalid IPv4 addr for SNAT_TRANSLATE_IP"
616 : : );
617 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
618 : : }
619 : : }
620 : : }
621 : :
622 : : /* Enable IPT OUTPUT.
623 : : */
624 : : if(opts->config[CONF_ENABLE_IPT_OUTPUT] == NULL)
625 : : set_config_entry(opts, CONF_ENABLE_IPT_OUTPUT,
626 : : DEF_ENABLE_IPT_OUTPUT);
627 : :
628 : : /* Flush IPT at init.
629 : : */
630 : : if(opts->config[CONF_FLUSH_IPT_AT_INIT] == NULL)
631 : : set_config_entry(opts, CONF_FLUSH_IPT_AT_INIT, DEF_FLUSH_IPT_AT_INIT);
632 : :
633 : : /* Flush IPT at exit.
634 : : */
635 : : if(opts->config[CONF_FLUSH_IPT_AT_EXIT] == NULL)
636 : : set_config_entry(opts, CONF_FLUSH_IPT_AT_EXIT, DEF_FLUSH_IPT_AT_EXIT);
637 : :
638 : : /* IPT input access.
639 : : */
640 : : if(opts->config[CONF_IPT_INPUT_ACCESS] == NULL)
641 : : set_config_entry(opts, CONF_IPT_INPUT_ACCESS,
642 : : DEF_IPT_INPUT_ACCESS);
643 : :
644 : : if(validate_ipt_chain_conf(opts->config[CONF_IPT_INPUT_ACCESS]) != 1)
645 : : {
646 : : log_msg(LOG_ERR,
647 : : "Invalid IPT_INPUT_ACCESS specification, see fwknopd.conf comments"
648 : : );
649 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
650 : : }
651 : :
652 : : /* IPT output access.
653 : : */
654 : : if(opts->config[CONF_IPT_OUTPUT_ACCESS] == NULL)
655 : : set_config_entry(opts, CONF_IPT_OUTPUT_ACCESS,
656 : : DEF_IPT_OUTPUT_ACCESS);
657 : :
658 : : if(validate_ipt_chain_conf(opts->config[CONF_IPT_OUTPUT_ACCESS]) != 1)
659 : : {
660 : : log_msg(LOG_ERR,
661 : : "Invalid IPT_OUTPUT_ACCESS specification, see fwknopd.conf comments"
662 : : );
663 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
664 : : }
665 : :
666 : : /* IPT forward access.
667 : : */
668 : : if(opts->config[CONF_IPT_FORWARD_ACCESS] == NULL)
669 : : set_config_entry(opts, CONF_IPT_FORWARD_ACCESS,
670 : : DEF_IPT_FORWARD_ACCESS);
671 : :
672 : : if(validate_ipt_chain_conf(opts->config[CONF_IPT_FORWARD_ACCESS]) != 1)
673 : : {
674 : : log_msg(LOG_ERR,
675 : : "Invalid IPT_FORWARD_ACCESS specification, see fwknopd.conf comments"
676 : : );
677 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
678 : : }
679 : :
680 : : /* IPT dnat access.
681 : : */
682 : : if(opts->config[CONF_IPT_DNAT_ACCESS] == NULL)
683 : : set_config_entry(opts, CONF_IPT_DNAT_ACCESS,
684 : : DEF_IPT_DNAT_ACCESS);
685 : :
686 : : if(validate_ipt_chain_conf(opts->config[CONF_IPT_DNAT_ACCESS]) != 1)
687 : : {
688 : : log_msg(LOG_ERR,
689 : : "Invalid IPT_DNAT_ACCESS specification, see fwknopd.conf comments"
690 : : );
691 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
692 : : }
693 : :
694 : : /* IPT snat access.
695 : : */
696 : : if(opts->config[CONF_IPT_SNAT_ACCESS] == NULL)
697 : : set_config_entry(opts, CONF_IPT_SNAT_ACCESS,
698 : : DEF_IPT_SNAT_ACCESS);
699 : :
700 : : if(validate_ipt_chain_conf(opts->config[CONF_IPT_SNAT_ACCESS]) != 1)
701 : : {
702 : : log_msg(LOG_ERR,
703 : : "Invalid IPT_SNAT_ACCESS specification, see fwknopd.conf comments"
704 : : );
705 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
706 : : }
707 : :
708 : : /* IPT masquerade access.
709 : : */
710 : : if(opts->config[CONF_IPT_MASQUERADE_ACCESS] == NULL)
711 : : set_config_entry(opts, CONF_IPT_MASQUERADE_ACCESS,
712 : : DEF_IPT_MASQUERADE_ACCESS);
713 : :
714 : : if(validate_ipt_chain_conf(opts->config[CONF_IPT_MASQUERADE_ACCESS]) != 1)
715 : : {
716 : : log_msg(LOG_ERR,
717 : : "Invalid IPT_MASQUERADE_ACCESS specification, see fwknopd.conf comments"
718 : : );
719 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
720 : : }
721 : :
722 : : /* Check for the iptables 'comment' match at init time
723 : : */
724 : : if(opts->config[CONF_ENABLE_IPT_COMMENT_CHECK] == NULL)
725 : : set_config_entry(opts, CONF_ENABLE_IPT_COMMENT_CHECK,
726 : : DEF_ENABLE_IPT_COMMENT_CHECK);
727 : :
728 : : #elif FIREWALL_IPFW
729 : :
730 : : /* Flush ipfw rules at init.
731 : : */
732 : : if(opts->config[CONF_FLUSH_IPFW_AT_INIT] == NULL)
733 : : set_config_entry(opts, CONF_FLUSH_IPFW_AT_INIT, DEF_FLUSH_IPFW_AT_INIT);
734 : :
735 : : /* Flush ipfw rules at exit.
736 : : */
737 : : if(opts->config[CONF_FLUSH_IPFW_AT_EXIT] == NULL)
738 : : set_config_entry(opts, CONF_FLUSH_IPFW_AT_EXIT, DEF_FLUSH_IPFW_AT_EXIT);
739 : :
740 : : /* Set IPFW start rule number.
741 : : */
742 : : if(opts->config[CONF_IPFW_START_RULE_NUM] == NULL)
743 : : set_config_entry(opts, CONF_IPFW_START_RULE_NUM,
744 : : DEF_IPFW_START_RULE_NUM);
745 : :
746 : : /* Set IPFW max rules.
747 : : */
748 : : if(opts->config[CONF_IPFW_MAX_RULES] == NULL)
749 : : set_config_entry(opts, CONF_IPFW_MAX_RULES,
750 : : DEF_IPFW_MAX_RULES);
751 : :
752 : : /* Set IPFW active set number.
753 : : */
754 : : if(opts->config[CONF_IPFW_ACTIVE_SET_NUM] == NULL)
755 : : set_config_entry(opts, CONF_IPFW_ACTIVE_SET_NUM,
756 : : DEF_IPFW_ACTIVE_SET_NUM);
757 : :
758 : : /* Set IPFW expire set number.
759 : : */
760 : : if(opts->config[CONF_IPFW_EXPIRE_SET_NUM] == NULL)
761 : : set_config_entry(opts, CONF_IPFW_EXPIRE_SET_NUM,
762 : : DEF_IPFW_EXPIRE_SET_NUM);
763 : :
764 : : /* Set IPFW Dynamic rule expiry interval.
765 : : */
766 : : if(opts->config[CONF_IPFW_EXPIRE_PURGE_INTERVAL] == NULL)
767 : : set_config_entry(opts, CONF_IPFW_EXPIRE_PURGE_INTERVAL,
768 : : DEF_IPFW_EXPIRE_PURGE_INTERVAL);
769 : :
770 : : /* Set IPFW Dynamic rule expiry interval.
771 : : */
772 : : if(opts->config[CONF_IPFW_ADD_CHECK_STATE] == NULL)
773 : : set_config_entry(opts, CONF_IPFW_ADD_CHECK_STATE,
774 : : DEF_IPFW_ADD_CHECK_STATE);
775 : :
776 : : #elif FIREWALL_PF
777 : : /* Set PF anchor name
778 : : */
779 : : if(opts->config[CONF_PF_ANCHOR_NAME] == NULL)
780 : : set_config_entry(opts, CONF_PF_ANCHOR_NAME,
781 : : DEF_PF_ANCHOR_NAME);
782 : :
783 : : /* Set PF rule expiry interval.
784 : : */
785 : : if(opts->config[CONF_PF_EXPIRE_INTERVAL] == NULL)
786 : : set_config_entry(opts, CONF_PF_EXPIRE_INTERVAL,
787 : : DEF_PF_EXPIRE_INTERVAL);
788 : :
789 : : #elif FIREWALL_IPF
790 : : /* --DSS Place-holder */
791 : :
792 : : #endif /* FIREWALL type */
793 : :
794 : : /* GPG Home dir.
795 : : */
796 [ + + ]: 1797 : if(opts->config[CONF_GPG_HOME_DIR] == NULL)
797 : 1461 : set_config_entry(opts, CONF_GPG_HOME_DIR, DEF_GPG_HOME_DIR);
798 : :
799 : : /* GPG executable
800 : : */
801 [ + + ]: 1797 : if(opts->config[CONF_GPG_EXE] == NULL)
802 : 1488 : set_config_entry(opts, CONF_GPG_EXE, DEF_GPG_EXE);
803 : :
804 : : /* Enable SPA over HTTP.
805 : : */
806 [ + + ]: 1797 : if(opts->config[CONF_ENABLE_SPA_OVER_HTTP] == NULL)
807 : 1467 : set_config_entry(opts, CONF_ENABLE_SPA_OVER_HTTP,
808 : : DEF_ENABLE_SPA_OVER_HTTP);
809 : :
810 : : /* Enable TCP server.
811 : : */
812 [ + + ]: 1797 : if(opts->config[CONF_ENABLE_TCP_SERVER] == NULL)
813 : 1564 : set_config_entry(opts, CONF_ENABLE_TCP_SERVER, DEF_ENABLE_TCP_SERVER);
814 : :
815 : : /* TCP Server port.
816 : : */
817 [ + + ]: 1797 : if(opts->config[CONF_TCPSERV_PORT] == NULL)
818 : 1482 : set_config_entry(opts, CONF_TCPSERV_PORT, DEF_TCPSERV_PORT);
819 : :
820 : : /* Enable UDP server.
821 : : */
822 [ + + ]: 1797 : if(opts->config[CONF_ENABLE_UDP_SERVER] == NULL)
823 : : {
824 [ - + ][ # # ]: 1443 : if((strncasecmp(DEF_ENABLE_UDP_SERVER, "Y", 1) == 0) &&
825 : 0 : !opts->enable_udp_server)
826 : : {
827 : 0 : log_msg(LOG_ERR, "pcap capture not compiled in, forcing UDP server mode");
828 : 0 : opts->enable_udp_server = 1;
829 : : }
830 : 1443 : set_config_entry(opts, CONF_ENABLE_UDP_SERVER, DEF_ENABLE_UDP_SERVER);
831 : : }
832 : :
833 : : /* UDP Server port.
834 : : */
835 [ + + ]: 1797 : if(opts->config[CONF_UDPSERV_PORT] == NULL)
836 : 1526 : set_config_entry(opts, CONF_UDPSERV_PORT, DEF_UDPSERV_PORT);
837 : :
838 : : /* UDP server select() timeout in microseconds
839 : : */
840 [ + + ]: 1797 : if(opts->config[CONF_UDPSERV_SELECT_TIMEOUT] == NULL)
841 : 1563 : set_config_entry(opts, CONF_UDPSERV_SELECT_TIMEOUT,
842 : : DEF_UDPSERV_SELECT_TIMEOUT);
843 : :
844 : : /* Syslog identity.
845 : : */
846 [ + + ]: 1797 : if(opts->config[CONF_SYSLOG_IDENTITY] == NULL)
847 : 1467 : set_config_entry(opts, CONF_SYSLOG_IDENTITY, DEF_SYSLOG_IDENTITY);
848 : :
849 : : /* Syslog facility.
850 : : */
851 [ + + ]: 1797 : if(opts->config[CONF_SYSLOG_FACILITY] == NULL)
852 : 1530 : set_config_entry(opts, CONF_SYSLOG_FACILITY, DEF_SYSLOG_FACILITY);
853 : :
854 : :
855 : : /* Validate integer variable ranges
856 : : */
857 : 1797 : validate_int_var_ranges(opts);
858 : :
859 : : /* Some options just trigger some output of information, or trigger an
860 : : * external function, but do not actually start fwknopd. If any of those
861 : : * are set, we can return here an skip the validation routines as all
862 : : * other options will be ignored anyway.
863 : : *
864 : : * These are also mutually exclusive (for now).
865 : : */
866 [ + - ]: 1678 : if((opts->dump_config + opts->kill + opts->restart + opts->status) == 1)
867 : : return;
868 : :
869 [ - + ]: 1678 : if((opts->dump_config + opts->kill + opts->restart + opts->status) > 1)
870 : : {
871 : 0 : log_msg(LOG_ERR,
872 : : "The -D, -K, -R, and -S options are mutually exclusive. Pick only one."
873 : : );
874 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
875 : : }
876 : :
877 [ - + ]: 1678 : if(opts->config[CONF_FIREWALL_EXE] == NULL)
878 : : {
879 : 0 : log_msg(LOG_ERR,
880 : : "[*] No firewall command executable is set. Please check FIREWALL_EXE in fwknopd.conf."
881 : : );
882 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
883 : : }
884 : :
885 : : return;
886 : : }
887 : :
888 : : void
889 : 1814 : set_preconfig_entries(fko_srv_options_t *opts)
890 : : {
891 : : /* First, set any default or otherwise static settings here. Some may
892 : : * end up being overwritten via config file or command-line.
893 : : */
894 : :
895 : : /* Setup the firewall executable based on build-time info.
896 : : * --DSS Note: We will want to either force external script mode, or
897 : : * error out if we do not have a firewall executable defined.
898 : : */
899 : : #ifdef FIREWALL_EXE
900 : 1814 : set_config_entry(opts, CONF_FIREWALL_EXE, FIREWALL_EXE);
901 : : #endif
902 : :
903 : 1814 : }
904 : :
905 : : /* Initialize program configuration via config file and/or command-line
906 : : * switches.
907 : : */
908 : : void
909 : 1814 : config_init(fko_srv_options_t *opts, int argc, char **argv)
910 : : {
911 : : int cmd_arg, index, is_err;
912 : 1814 : unsigned char got_conf_file = 0, got_override_config = 0;
913 : :
914 : 1814 : char override_file[MAX_LINE_LEN] = {0};
915 : : char *ndx, *cmrk;
916 : :
917 : : /* Zero out options and opts_track.
918 : : */
919 : : memset(opts, 0x00, sizeof(fko_srv_options_t));
920 : :
921 : : /* Set some preconfiguration options (i.e. build-time defaults)
922 : : */
923 : 1814 : set_preconfig_entries(opts);
924 : :
925 : : /* In case this is a re-config.
926 : : */
927 : 1814 : optind = 0;
928 : :
929 : : /* First, scan the command-line args for -h/--help or an alternate
930 : : * configuration file. If we find an alternate config file, use it,
931 : : * otherwise use the default. We also grab any override config files
932 : : * as well.
933 : : */
934 [ + + ]: 20099 : while ((cmd_arg = getopt_long(argc, argv,
935 : : GETOPTS_OPTION_STRING, cmd_opts, &index)) != -1) {
936 : :
937 : : /* If help is wanted, give it and exit.
938 : : */
939 [ - + + + ]: 16471 : switch(cmd_arg) {
940 : : case 'h':
941 : 0 : usage();
942 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS);
943 : :
944 : : /* Look for configuration file arg.
945 : : */
946 : : case 'c':
947 : 1814 : set_config_entry(opts, CONF_CONFIG_FILE, optarg);
948 : 1814 : got_conf_file++;
949 : :
950 : : /* If we already have the config_override option, we are done.
951 : : */
952 [ + - ]: 1814 : if(got_override_config > 0)
953 : : break;
954 : :
955 : : /* Look for override configuration file arg.
956 : : */
957 : : case 'O':
958 : 3109 : set_config_entry(opts, CONF_OVERRIDE_CONFIG, optarg);
959 : 4923 : got_override_config++;
960 : :
961 : : /* If we already have the conf_file option, we are done.
962 : : */
963 : : if(got_conf_file > 0)
964 : : break;
965 : : }
966 : : }
967 : :
968 : : /* If no alternate configuration file was specified, we use the
969 : : * default.
970 : : */
971 [ - + ]: 1814 : if(opts->config[CONF_CONFIG_FILE] == NULL)
972 : 0 : set_config_entry(opts, CONF_CONFIG_FILE, DEF_CONFIG_FILE);
973 : :
974 : : /* Parse configuration file to populate any params not already specified
975 : : * via command-line options.
976 : : */
977 : 1814 : parse_config_file(opts, opts->config[CONF_CONFIG_FILE]);
978 : :
979 : : /* If there are override configuration entries, process them
980 : : * here.
981 : : */
982 [ + - ]: 1814 : if(opts->config[CONF_OVERRIDE_CONFIG] != NULL)
983 : : {
984 : : /* Make a copy of the override_config string so we can munge it.
985 : : */
986 : 1814 : strlcpy(override_file, opts->config[CONF_OVERRIDE_CONFIG], sizeof(override_file));
987 : :
988 : 1814 : ndx = override_file;
989 : 1814 : cmrk = strchr(ndx, ',');
990 : :
991 [ - + ]: 1814 : if(cmrk == NULL)
992 : : {
993 : : /* Only one to process...
994 : : */
995 : 1814 : parse_config_file(opts, ndx);
996 : :
997 : : } else {
998 : : /* Walk the string pulling the next config override
999 : : * at the comma delimiters.
1000 : : */
1001 [ # # ]: 0 : while(cmrk != NULL) {
1002 : 0 : *cmrk = '\0';
1003 : 0 : parse_config_file(opts, ndx);
1004 : 0 : ndx = cmrk + 1;
1005 : 0 : cmrk = strchr(ndx, ',');
1006 : : }
1007 : :
1008 : : /* Process the last entry
1009 : : */
1010 : 0 : parse_config_file(opts, ndx);
1011 : : }
1012 : : }
1013 : :
1014 : : /* Set up the verbosity level according to the value found in the
1015 : : * config files */
1016 [ + + ]: 1814 : if (opts->config[CONF_VERBOSE] != NULL)
1017 : : {
1018 : 451 : opts->verbose = strtol_wrapper(opts->config[CONF_VERBOSE], 0, -1,
1019 : : NO_EXIT_UPON_ERR, &is_err);
1020 [ + + ]: 451 : if(is_err != FKO_SUCCESS)
1021 : : {
1022 : 17 : log_msg(LOG_ERR, "[*] VERBOSE value '%s' not in the range (>0)",
1023 : : opts->config[CONF_VERBOSE]);
1024 : 17 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1025 : : }
1026 : : }
1027 : :
1028 : : /* Reset the options index so we can run through them again.
1029 : : */
1030 : 1797 : optind = 0;
1031 : :
1032 : : /* Last, but not least, we process command-line options (some of which
1033 : : * may override configuration file options.
1034 : : */
1035 [ + + ]: 19878 : while ((cmd_arg = getopt_long(argc, argv,
1036 : : GETOPTS_OPTION_STRING, cmd_opts, &index)) != -1) {
1037 : :
1038 [ + - + - : 16284 : switch(cmd_arg) {
+ - - + +
- - - - -
- - - - -
- - - - -
- + - + -
+ - - -
+ ]
1039 : : case 'A':
1040 : : #if AFL_FUZZING
1041 : 1002 : opts->afl_fuzzing = 1;
1042 : : #else
1043 : : log_msg(LOG_ERR, "[*] fwknopd not compiled with AFL fuzzing support");
1044 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1045 : : #endif
1046 : 1002 : break;
1047 : : case AFL_PKT_FILE:
1048 : : #if AFL_FUZZING
1049 : 0 : opts->afl_fuzzing = 1;
1050 : 0 : set_config_entry(opts, CONF_AFL_PKT_FILE, optarg);
1051 : : #else
1052 : : log_msg(LOG_ERR, "[*] fwknopd not compiled with AFL fuzzing support");
1053 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1054 : : #endif
1055 : 0 : break;
1056 : : case 'a':
1057 : 1797 : set_config_entry(opts, CONF_ACCESS_FILE, optarg);
1058 : 1797 : break;
1059 : : case 'c':
1060 : : /* This was handled earlier */
1061 : : break;
1062 : : case 'C':
1063 : 0 : opts->packet_ctr_limit = strtol_wrapper(optarg,
1064 : : 0, (2 << 30), NO_EXIT_UPON_ERR, &is_err);
1065 [ # # ]: 0 : if(is_err != FKO_SUCCESS)
1066 : : {
1067 : 0 : log_msg(LOG_ERR,
1068 : : "[*] invalid -C packet count limit '%s'",
1069 : : optarg);
1070 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1071 : : }
1072 : : break;
1073 : : case 'd':
1074 : : #if USE_FILE_CACHE
1075 : 71 : set_config_entry(opts, CONF_DIGEST_FILE, optarg);
1076 : : #else
1077 : : set_config_entry(opts, CONF_DIGEST_DB_FILE, optarg);
1078 : : #endif
1079 : 71 : break;
1080 : : case 'D':
1081 : 0 : opts->dump_config = 1;
1082 : 0 : break;
1083 : : case DUMP_SERVER_ERR_CODES:
1084 : 0 : dump_server_errors();
1085 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS);
1086 : : case EXIT_AFTER_PARSE_CONFIG:
1087 : 1349 : opts->exit_after_parse_config = 1;
1088 : 1349 : opts->foreground = 1;
1089 : 1349 : break;
1090 : : case 'f':
1091 : 1797 : opts->foreground = 1;
1092 : 1797 : break;
1093 : : case FAULT_INJECTION_TAG:
1094 : : #if HAVE_LIBFIU
1095 : : set_config_entry(opts, CONF_FAULT_INJECTION_TAG, optarg);
1096 : : #else
1097 : 0 : log_msg(LOG_ERR, "[*] fwknopd not compiled with libfiu support");
1098 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1099 : : #endif
1100 : 0 : break;
1101 : : case FW_LIST:
1102 : 0 : opts->fw_list = 1;
1103 : 0 : break;
1104 : : case FW_LIST_ALL:
1105 : 0 : opts->fw_list = 1;
1106 : 0 : opts->fw_list_all = 1;
1107 : 0 : break;
1108 : : case FW_FLUSH:
1109 : 0 : opts->fw_flush = 1;
1110 : 0 : break;
1111 : : case GPG_HOME_DIR:
1112 [ # # ]: 0 : if (is_valid_dir(optarg))
1113 : : {
1114 : 0 : set_config_entry(opts, CONF_GPG_HOME_DIR, optarg);
1115 : : }
1116 : : else
1117 : : {
1118 : 0 : log_msg(LOG_ERR,
1119 : : "[*] Directory '%s' could not stat()/does not exist?",
1120 : : optarg);
1121 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1122 : : }
1123 : : break;
1124 : : case 'i':
1125 : 0 : set_config_entry(opts, CONF_PCAP_INTF, optarg);
1126 : 0 : break;
1127 : : case FIREWD_DISABLE_CHECK_SUPPORT:
1128 : 0 : opts->firewd_disable_check_support = 1;
1129 : 0 : break;
1130 : : case IPT_DISABLE_CHECK_SUPPORT:
1131 : 0 : opts->ipt_disable_check_support = 1;
1132 : 0 : break;
1133 : : case 'K':
1134 : 0 : opts->kill = 1;
1135 : 0 : break;
1136 : : case 'l':
1137 : 0 : set_config_entry(opts, CONF_LOCALE, optarg);
1138 : 0 : break;
1139 : : case 'O':
1140 : : /* This was handled earlier */
1141 : : break;
1142 : : case 'p':
1143 : 0 : set_config_entry(opts, CONF_FWKNOP_PID_FILE, optarg);
1144 : 0 : break;
1145 : : case 'P':
1146 : 0 : set_config_entry(opts, CONF_PCAP_FILTER, optarg);
1147 : 0 : break;
1148 : : case PCAP_FILE:
1149 : 0 : set_config_entry(opts, CONF_PCAP_FILE, optarg);
1150 : 0 : break;
1151 : : case ENABLE_PCAP_ANY_DIRECTION:
1152 : 0 : opts->pcap_any_direction = 1;
1153 : 0 : break;
1154 : : case ROTATE_DIGEST_CACHE:
1155 : 0 : opts->rotate_digest_cache = 1;
1156 : 0 : break;
1157 : : case 'R':
1158 : 0 : opts->restart = 1;
1159 : 0 : break;
1160 : : case 'r':
1161 : 1349 : set_config_entry(opts, CONF_FWKNOP_RUN_DIR, optarg);
1162 : 1349 : break;
1163 : : case 'S':
1164 : 0 : opts->status = 1;
1165 : 0 : break;
1166 : : case 't':
1167 : 1797 : opts->test = 1;
1168 : 1797 : break;
1169 : : case 'U':
1170 : 0 : opts->enable_udp_server = 1;
1171 : 0 : break;
1172 : : /* Verbosity level */
1173 : : case 'v':
1174 : 4047 : opts->verbose++;
1175 : 4047 : break;
1176 : : case SYSLOG_ENABLE:
1177 : 0 : opts->syslog_enable = 1;
1178 : 0 : break;
1179 : : case 'V':
1180 : 0 : fprintf(stdout, "fwknopd server %s\n", MY_VERSION);
1181 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS);
1182 : : default:
1183 : 0 : usage();
1184 : 15006 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1185 : : }
1186 : : }
1187 : :
1188 : : /* Now that we have all of our options set, and we are actually going to
1189 : : * start fwknopd, we can validate them.
1190 : : */
1191 : 1797 : validate_options(opts);
1192 : :
1193 : 1678 : return;
1194 : : }
1195 : :
1196 : : /* Dump the configuration
1197 : : */
1198 : : void
1199 : 634 : dump_config(const fko_srv_options_t *opts)
1200 : : {
1201 : : int i;
1202 : :
1203 : 634 : fprintf(stdout, "Current fwknopd config settings:\n");
1204 : :
1205 [ + + ]: 31700 : for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
1206 [ + + ]: 31066 : fprintf(stdout, "%3i. %-28s = '%s'\n",
1207 : : i,
1208 : : config_map[i],
1209 : 31066 : (opts->config[i] == NULL) ? "<not set>" : opts->config[i]
1210 : : );
1211 : :
1212 : 634 : fprintf(stdout, "\n");
1213 : 634 : fflush(stdout);
1214 : 634 : }
1215 : :
1216 : : /* Print usage message...
1217 : : */
1218 : : void
1219 : 0 : usage(void)
1220 : : {
1221 : 0 : fprintf(stdout, "\n%s server version %s\n%s - http://www.cipherdyne.org/fwknop/\n\n",
1222 : : MY_NAME, MY_VERSION, MY_DESC);
1223 : 0 : fprintf(stdout,
1224 : : "Usage: fwknopd [options]\n\n"
1225 : : " -a, --access-file - Specify an alternate access.conf file.\n"
1226 : : " -c, --config-file - Specify an alternate configuration file.\n"
1227 : : " -f, --foreground - Run fwknopd in the foreground (do not become\n"
1228 : : " a background daemon).\n"
1229 : : " -i, --interface - Specify interface to listen for incoming SPA\n"
1230 : : " packets.\n"
1231 : : " -C, --packet-limit - Limit the number of candidate SPA packets to\n"
1232 : : " process and exit when this limit is reached.\n"
1233 : : " -d, --digest-file - Specify an alternate digest.cache file.\n"
1234 : : " -D, --dump-config - Dump the current fwknop configuration values.\n"
1235 : : " -K, --kill - Kill the currently running fwknopd.\n"
1236 : : " -l, --locale - Provide a locale setting other than the system\n"
1237 : : " default.\n"
1238 : : " -O, --override-config - Specify a file with configuration entries that will\n"
1239 : : " overide those in fwknopd.conf\n"
1240 : : " -p, --pid-file - Specify an alternate fwknopd.pid file.\n"
1241 : : " -P, --pcap-filter - Specify a Berkeley packet filter statement to\n"
1242 : : " override the PCAP_FILTER variable in fwknopd.conf.\n"
1243 : : " -R, --restart - Force the currently running fwknopd to restart.\n"
1244 : : " --rotate-digest-cache\n"
1245 : : " - Rotate the digest cache file by renaming the file\n"
1246 : : " to the same path with the -old suffix.\n"
1247 : : " -r, --run-dir - Set path to local state run directory.\n"
1248 : : " - Rotate the digest cache file by renaming it to\n"
1249 : : " '<name>-old', and starting a new one.\n"
1250 : : " -S, --status - Display the status of any running fwknopd process.\n"
1251 : : " -t, --test - Test mode, process SPA packets but do not make any\n"
1252 : : " firewall modifications.\n"
1253 : : " -U, --udp-server - Set UDP server mode.\n"
1254 : : " -v, --verbose - Set verbose mode.\n"
1255 : : " --syslog-enable - Allow messages to be sent to syslog even if the\n"
1256 : : " foreground mode is set.\n"
1257 : : " -V, --version - Print version number.\n"
1258 : : " -A, --afl-fuzzing - Run in American Fuzzy Lop (AFL) fuzzing mode so\n"
1259 : : " that plaintext SPA packets are accepted via stdin.\n"
1260 : : " -h, --help - Print this usage message and exit.\n"
1261 : : " --dump-serv-err-codes - List all server error codes (only needed by the\n"
1262 : : " test suite).\n"
1263 : : " --exit-parse-config - Parse config files and exit.\n"
1264 : : " --fault-injection-tag - Enable a fault injection tag (only needed by the\n"
1265 : : " test suite).\n"
1266 : : " --pcap-file - Read potential SPA packets from an existing pcap\n"
1267 : : " file.\n"
1268 : : " --pcap-any-direction - By default fwknopd processes packets that are\n"
1269 : : " sent to the sniffing interface, but this option\n"
1270 : : " enables processing of packets that originate from\n"
1271 : : " an interface (such as in a forwarding situation).\n"
1272 : : " --fw-list - List all firewall rules that fwknop has created\n"
1273 : : " and then exit.\n"
1274 : : " --fw-list-all - List all firewall rules in the complete policy,\n"
1275 : : " including those that have nothing to do with\n"
1276 : : " fwknop.\n"
1277 : : " --fw-flush - Flush all firewall rules created by fwknop.\n"
1278 : : " --gpg-home-dir - Specify the GPG home directory (this is normally\n"
1279 : : " done in the access.conf file).\n"
1280 : : " --gpg-exe - Specify the path to GPG (this is normally done in\n"
1281 : : " the access.conf file).\n"
1282 : : " --no-firewd-check-support\n"
1283 : : " - Disable test for 'firewall-cmd ... -C' support.\n"
1284 : : " --no-ipt-check-support - Disable test for 'iptables -C' support.\n"
1285 : : "\n"
1286 : : );
1287 : :
1288 : 0 : return;
1289 : : }
1290 : :
1291 : : /***EOF***/
|