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 : 22282 : range_check(fko_srv_options_t *opts, char *var, char *val, int low, int high)
50 : : {
51 : : int is_err;
52 : :
53 : 22282 : strtol_wrapper(val, low, high, NO_EXIT_UPON_ERR, &is_err);
54 [ + + ]: 22282 : if(is_err != FKO_SUCCESS)
55 : : {
56 : 3 : log_msg(LOG_ERR, "[*] var %s value '%s' not in the range %d-%d",
57 : : var, val, low, high);
58 : 3 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
59 : : }
60 : :
61 : 22279 : 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 : 172324 : 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 [ - + ]: 172324 : 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 [ + + ]: 172324 : if(opts->config[var_ndx] != NULL)
84 : 363 : free(opts->config[var_ndx]);
85 : :
86 : : /* If we are setting it to NULL, do it and be done.
87 : : */
88 [ - + ]: 172324 : 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 : 172324 : space_needed = strlen(value) + 1;
97 : :
98 : 172324 : opts->config[var_ndx] = calloc(1, space_needed);
99 : :
100 [ + + ]: 172324 : if(opts->config[var_ndx] == NULL)
101 : : {
102 : 1595 : log_msg(LOG_ERR, "[*] Fatal memory allocation error!");
103 : 1595 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
104 : : }
105 : :
106 : 170729 : strlcpy(opts->config[var_ndx], value, space_needed);
107 : :
108 : 170729 : return;
109 : : }
110 : :
111 : : /* Given a config parameter name, return its index or -1 if not found.
112 : : */
113 : : static int
114 : 6 : config_entry_index(const fko_srv_options_t *opts, const char *var)
115 : : {
116 : : int i;
117 : :
118 [ + + ]: 268 : for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
119 [ + + ][ + + ]: 264 : if(opts->config[i] != NULL && CONF_VAR_IS(var, config_map[i]))
120 : : return(i);
121 : :
122 : : return(-1);
123 : : }
124 : :
125 : : /* Free the config memory
126 : : */
127 : : void
128 : 5501 : free_configs(fko_srv_options_t *opts)
129 : : {
130 : : int i;
131 : :
132 : 5501 : free_acc_stanzas(opts);
133 : :
134 [ + + ]: 264048 : for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
135 [ + + ]: 258547 : if(opts->config[i] != NULL)
136 : 170119 : free(opts->config[i]);
137 : 5501 : }
138 : :
139 : : static void
140 : 3715 : validate_int_var_ranges(fko_srv_options_t *opts)
141 : : {
142 : : #if FIREWALL_IPFW
143 : : int is_err = FKO_SUCCESS;
144 : : #endif
145 : :
146 : 3715 : range_check(opts, "PCAP_LOOP_SLEEP", opts->config[CONF_PCAP_LOOP_SLEEP],
147 : : 1, RCHK_MAX_PCAP_LOOP_SLEEP);
148 : 3714 : range_check(opts, "MAX_SPA_PACKET_AGE", opts->config[CONF_MAX_SPA_PACKET_AGE],
149 : : 1, RCHK_MAX_SPA_PACKET_AGE);
150 : 3714 : range_check(opts, "MAX_SNIFF_BYTES", opts->config[CONF_MAX_SNIFF_BYTES],
151 : : 1, RCHK_MAX_SNIFF_BYTES);
152 : 3714 : range_check(opts, "TCPSERV_PORT", opts->config[CONF_TCPSERV_PORT],
153 : : 1, RCHK_MAX_TCPSERV_PORT);
154 : 3713 : range_check(opts, "UDPSERV_PORT", opts->config[CONF_UDPSERV_PORT],
155 : : 1, RCHK_MAX_UDPSERV_PORT);
156 : 3712 : 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 : 3712 : return;
202 : : }
203 : :
204 : : /* Parse the config file...
205 : : */
206 : : static void
207 : 10351 : parse_config_file(fko_srv_options_t *opts, const char *config_file)
208 : : {
209 : : FILE *cfile_ptr;
210 : 10351 : unsigned int numLines = 0;
211 : : unsigned int i, good_ent;
212 : : int cndx;
213 : :
214 : 10351 : char conf_line_buf[MAX_LINE_LEN] = {0};
215 : 10351 : char var[MAX_LINE_LEN] = {0};
216 : 10351 : char val[MAX_LINE_LEN] = {0};
217 : 10351 : char tmp1[MAX_LINE_LEN] = {0};
218 : 10351 : char tmp2[MAX_LINE_LEN] = {0};
219 : :
220 : : struct stat st;
221 : :
222 : : /* Make sure the config file exists.
223 : : */
224 [ + + ]: 10351 : if(stat(config_file, &st) != 0)
225 : : {
226 : 3 : log_msg(LOG_ERR, "[*] Config file: '%s' was not found.",
227 : : config_file);
228 : 3 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
229 : : }
230 : :
231 [ + + ]: 10348 : if(verify_file_perms_ownership(config_file) != 1)
232 : 1 : 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 [ + + ]: 10347 : if ((cfile_ptr = fopen(config_file, "r")) == NULL)
238 : : {
239 : 175 : log_msg(LOG_ERR, "[*] Could not open config file: %s",
240 : : config_file);
241 : 175 : perror(NULL);
242 : :
243 : 10347 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
244 : : }
245 : :
246 [ + + ]: 20563 : while ((fgets(conf_line_buf, MAX_LINE_LEN, cfile_ptr)) != NULL)
247 : : {
248 : 10391 : numLines++;
249 : 10391 : 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 [ + + ][ + - ]: 10391 : if(IS_EMPTY_LINE(conf_line_buf[0]))
[ + - ][ - + ]
255 : 9661 : continue;
256 : :
257 [ + + ]: 730 : if(sscanf(conf_line_buf, "%s %[^;\n\r]", var, val) != 2)
258 : : {
259 : 2 : 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 : 2 : continue;
264 : : }
265 : :
266 : : good_ent = 0;
267 [ + - ]: 15889 : for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
268 : : {
269 [ + + ]: 15889 : 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 [ + + ]: 728 : if(*val == '$')
276 : : {
277 [ + - ]: 6 : if(sscanf((val+1), "%[A-Z_]%s", tmp1, tmp2))
278 : : {
279 [ + + ]: 6 : if((cndx = config_entry_index(opts, tmp1)) >= 0)
280 : : {
281 : 2 : strlcpy(val, opts->config[cndx], sizeof(val));
282 : 2 : 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 : 4 : log_msg(LOG_ERR,
290 : : "[*] Invalid embedded variable in: '%s'", val);
291 : 4 : break;
292 : : }
293 : : }
294 : : }
295 : :
296 : 724 : set_config_entry(opts, i, val);
297 : 724 : good_ent++;
298 : 724 : break;
299 : : }
300 : : }
301 : :
302 [ + + ]: 728 : if(good_ent == 0)
303 : 10391 : log_msg(LOG_ERR,
304 : : "[*] Ignoring unknown configuration parameter: '%s' in %s",
305 : : var, config_file
306 : : );
307 : : }
308 : :
309 : 10172 : fclose(cfile_ptr);
310 : :
311 : 10172 : return;
312 : : }
313 : :
314 : : /* Set defaults, and do sanity and bounds checks for the various options.
315 : : */
316 : : static void
317 : 4756 : validate_options(fko_srv_options_t *opts)
318 : : {
319 : 4756 : char tmp_path[MAX_PATH_LEN] = {0};
320 : :
321 : : /* If no conf dir is set in the config file, use the default.
322 : : */
323 [ + - ]: 4756 : if(opts->config[CONF_FWKNOP_CONF_DIR] == NULL)
324 : 4756 : 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 [ - + ]: 4691 : 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 [ + + ]: 4691 : if(opts->config[CONF_FWKNOP_RUN_DIR] == NULL)
337 : 4686 : set_config_entry(opts, CONF_FWKNOP_RUN_DIR, DEF_RUN_DIR);
338 : :
339 [ + + ]: 4634 : if(opts->config[CONF_FWKNOP_PID_FILE] == NULL)
340 : : {
341 : 19 : strlcpy(tmp_path, opts->config[CONF_FWKNOP_RUN_DIR], sizeof(tmp_path));
342 : :
343 [ + - ]: 19 : if(tmp_path[strlen(tmp_path)-1] != '/')
344 : 19 : strlcat(tmp_path, "/", sizeof(tmp_path));
345 : :
346 : 19 : strlcat(tmp_path, DEF_PID_FILENAME, sizeof(tmp_path));
347 : :
348 : 19 : set_config_entry(opts, CONF_FWKNOP_PID_FILE, tmp_path);
349 : : }
350 : :
351 : : #if USE_FILE_CACHE
352 [ + + ]: 4634 : if(opts->config[CONF_DIGEST_FILE] == NULL)
353 : : #else
354 : : if(opts->config[CONF_DIGEST_DB_FILE] == NULL)
355 : : #endif
356 : : {
357 : 18 : strlcpy(tmp_path, opts->config[CONF_FWKNOP_RUN_DIR], sizeof(tmp_path));
358 : :
359 [ + - ]: 18 : if(tmp_path[strlen(tmp_path)-1] != '/')
360 : 18 : strlcat(tmp_path, "/", sizeof(tmp_path));
361 : :
362 : :
363 : : #if USE_FILE_CACHE
364 : 18 : strlcat(tmp_path, DEF_DIGEST_CACHE_FILENAME, sizeof(tmp_path));
365 : 18 : set_config_entry(opts, CONF_DIGEST_FILE, tmp_path);
366 : : #else
367 : : strlcat(tmp_path, DEF_DIGEST_CACHE_DB_FILENAME, sizeof(tmp_path));
368 : : set_config_entry(opts, CONF_DIGEST_DB_FILE, tmp_path);
369 : : #endif
370 : : }
371 : :
372 : : /* Set remaining require CONF_ vars if they are not already set. */
373 : :
374 : : /* PCAP capture interface - note that if '-r <pcap file>' is specified
375 : : * on the command line, then this will override the pcap interface setting.
376 : : */
377 [ + + ]: 4634 : if(opts->config[CONF_PCAP_INTF] == NULL)
378 : 2615 : set_config_entry(opts, CONF_PCAP_INTF, DEF_INTERFACE);
379 : :
380 : : /* PCAP Promiscuous mode.
381 : : */
382 [ + + ]: 4616 : if(opts->config[CONF_ENABLE_PCAP_PROMISC] == NULL)
383 : 4613 : set_config_entry(opts, CONF_ENABLE_PCAP_PROMISC,
384 : : DEF_ENABLE_PCAP_PROMISC);
385 : :
386 : : /* The packet count argument to pcap_dispatch()
387 : : */
388 [ + + ]: 4570 : if(opts->config[CONF_PCAP_DISPATCH_COUNT] == NULL)
389 : 4569 : set_config_entry(opts, CONF_PCAP_DISPATCH_COUNT,
390 : : DEF_PCAP_DISPATCH_COUNT);
391 : :
392 : : /* Microseconds to sleep between pcap loop iterations
393 : : */
394 [ + + ]: 4509 : if(opts->config[CONF_PCAP_LOOP_SLEEP] == NULL)
395 : 4508 : set_config_entry(opts, CONF_PCAP_LOOP_SLEEP,
396 : : DEF_PCAP_LOOP_SLEEP);
397 : :
398 : : /* PCAP Filter.
399 : : */
400 [ + + ]: 4446 : if(opts->config[CONF_PCAP_FILTER] == NULL)
401 : 4432 : set_config_entry(opts, CONF_PCAP_FILTER, DEF_PCAP_FILTER);
402 : :
403 : : /* Enable SPA packet aging unless we're getting packet data
404 : : * directly from a pcap file
405 : : */
406 [ + + ]: 4403 : if(opts->config[CONF_ENABLE_SPA_PACKET_AGING] == NULL)
407 : : {
408 [ + + ]: 4320 : if(opts->config[CONF_PCAP_FILE] == NULL)
409 : : {
410 : 3875 : set_config_entry(opts, CONF_ENABLE_SPA_PACKET_AGING,
411 : : DEF_ENABLE_SPA_PACKET_AGING);
412 : : }
413 : : else
414 : : {
415 : 445 : set_config_entry(opts, CONF_ENABLE_SPA_PACKET_AGING, "N");
416 : : }
417 : : }
418 : :
419 : : /* SPA packet age.
420 : : */
421 [ + - ]: 4358 : if(opts->config[CONF_MAX_SPA_PACKET_AGE] == NULL)
422 : 4358 : set_config_entry(opts, CONF_MAX_SPA_PACKET_AGE,
423 : : DEF_MAX_SPA_PACKET_AGE);
424 : :
425 : :
426 : : /* Enable digest persistence.
427 : : */
428 [ + - ]: 4318 : if(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE] == NULL)
429 : 4318 : set_config_entry(opts, CONF_ENABLE_DIGEST_PERSISTENCE,
430 : : DEF_ENABLE_DIGEST_PERSISTENCE);
431 : :
432 : : /* Max sniff bytes.
433 : : */
434 [ + - ]: 4279 : if(opts->config[CONF_MAX_SNIFF_BYTES] == NULL)
435 : 4279 : set_config_entry(opts, CONF_MAX_SNIFF_BYTES, DEF_MAX_SNIFF_BYTES);
436 : :
437 : : #if FIREWALL_FIREWALLD
438 : : /* Enable FIREWD forwarding.
439 : : */
440 : : if(opts->config[CONF_ENABLE_FIREWD_FORWARDING] == NULL)
441 : : set_config_entry(opts, CONF_ENABLE_FIREWD_FORWARDING,
442 : : DEF_ENABLE_FIREWD_FORWARDING);
443 : :
444 : : /* Enable FIREWD local NAT.
445 : : */
446 : : if(opts->config[CONF_ENABLE_FIREWD_LOCAL_NAT] == NULL)
447 : : set_config_entry(opts, CONF_ENABLE_FIREWD_LOCAL_NAT,
448 : : DEF_ENABLE_FIREWD_LOCAL_NAT);
449 : :
450 : : /* Enable FIREWD SNAT.
451 : : */
452 : : if(opts->config[CONF_ENABLE_FIREWD_SNAT] == NULL)
453 : : set_config_entry(opts, CONF_ENABLE_FIREWD_SNAT,
454 : : DEF_ENABLE_FIREWD_SNAT);
455 : :
456 : : /* Make sure we have a valid IP if SNAT is enabled
457 : : */
458 : : if(strncasecmp(opts->config[CONF_ENABLE_FIREWD_SNAT], "Y", 1) == 0)
459 : : {
460 : : /* Note that fw_config_init() will set use_masquerade if necessary
461 : : */
462 : : if(opts->config[CONF_SNAT_TRANSLATE_IP] != NULL)
463 : : {
464 : : if(! is_valid_ipv4_addr(opts->config[CONF_SNAT_TRANSLATE_IP]))
465 : : {
466 : : log_msg(LOG_ERR,
467 : : "Invalid IPv4 addr for SNAT_TRANSLATE_IP"
468 : : );
469 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
470 : : }
471 : : }
472 : : }
473 : :
474 : : /* Enable FIREWD OUTPUT.
475 : : */
476 : : if(opts->config[CONF_ENABLE_FIREWD_OUTPUT] == NULL)
477 : : set_config_entry(opts, CONF_ENABLE_FIREWD_OUTPUT,
478 : : DEF_ENABLE_FIREWD_OUTPUT);
479 : :
480 : : /* Flush FIREWD at init.
481 : : */
482 : : if(opts->config[CONF_FLUSH_FIREWD_AT_INIT] == NULL)
483 : : set_config_entry(opts, CONF_FLUSH_FIREWD_AT_INIT, DEF_FLUSH_FIREWD_AT_INIT);
484 : :
485 : : /* Flush FIREWD at exit.
486 : : */
487 : : if(opts->config[CONF_FLUSH_FIREWD_AT_EXIT] == NULL)
488 : : set_config_entry(opts, CONF_FLUSH_FIREWD_AT_EXIT, DEF_FLUSH_FIREWD_AT_EXIT);
489 : :
490 : : /* FIREWD input access.
491 : : */
492 : : if(opts->config[CONF_FIREWD_INPUT_ACCESS] == NULL)
493 : : set_config_entry(opts, CONF_FIREWD_INPUT_ACCESS,
494 : : DEF_FIREWD_INPUT_ACCESS);
495 : :
496 : : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_INPUT_ACCESS]) != 1)
497 : : {
498 : : log_msg(LOG_ERR,
499 : : "Invalid FIREWD_INPUT_ACCESS specification, see fwknopd.conf comments"
500 : : );
501 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
502 : : }
503 : :
504 : : /* FIREWD output access.
505 : : */
506 : : if(opts->config[CONF_FIREWD_OUTPUT_ACCESS] == NULL)
507 : : set_config_entry(opts, CONF_FIREWD_OUTPUT_ACCESS,
508 : : DEF_FIREWD_OUTPUT_ACCESS);
509 : :
510 : : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_OUTPUT_ACCESS]) != 1)
511 : : {
512 : : log_msg(LOG_ERR,
513 : : "Invalid FIREWD_OUTPUT_ACCESS specification, see fwknopd.conf comments"
514 : : );
515 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
516 : : }
517 : :
518 : : /* FIREWD forward access.
519 : : */
520 : : if(opts->config[CONF_FIREWD_FORWARD_ACCESS] == NULL)
521 : : set_config_entry(opts, CONF_FIREWD_FORWARD_ACCESS,
522 : : DEF_FIREWD_FORWARD_ACCESS);
523 : :
524 : : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_FORWARD_ACCESS]) != 1)
525 : : {
526 : : log_msg(LOG_ERR,
527 : : "Invalid FIREWD_FORWARD_ACCESS specification, see fwknopd.conf comments"
528 : : );
529 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
530 : : }
531 : :
532 : : /* FIREWD dnat access.
533 : : */
534 : : if(opts->config[CONF_FIREWD_DNAT_ACCESS] == NULL)
535 : : set_config_entry(opts, CONF_FIREWD_DNAT_ACCESS,
536 : : DEF_FIREWD_DNAT_ACCESS);
537 : :
538 : : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_DNAT_ACCESS]) != 1)
539 : : {
540 : : log_msg(LOG_ERR,
541 : : "Invalid FIREWD_DNAT_ACCESS specification, see fwknopd.conf comments"
542 : : );
543 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
544 : : }
545 : :
546 : : /* FIREWD snat access.
547 : : */
548 : : if(opts->config[CONF_FIREWD_SNAT_ACCESS] == NULL)
549 : : set_config_entry(opts, CONF_FIREWD_SNAT_ACCESS,
550 : : DEF_FIREWD_SNAT_ACCESS);
551 : :
552 : : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_SNAT_ACCESS]) != 1)
553 : : {
554 : : log_msg(LOG_ERR,
555 : : "Invalid FIREWD_SNAT_ACCESS specification, see fwknopd.conf comments"
556 : : );
557 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
558 : : }
559 : :
560 : : /* FIREWD masquerade access.
561 : : */
562 : : if(opts->config[CONF_FIREWD_MASQUERADE_ACCESS] == NULL)
563 : : set_config_entry(opts, CONF_FIREWD_MASQUERADE_ACCESS,
564 : : DEF_FIREWD_MASQUERADE_ACCESS);
565 : :
566 : : if(validate_firewd_chain_conf(opts->config[CONF_FIREWD_MASQUERADE_ACCESS]) != 1)
567 : : {
568 : : log_msg(LOG_ERR,
569 : : "Invalid FIREWD_MASQUERADE_ACCESS specification, see fwknopd.conf comments"
570 : : );
571 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
572 : : }
573 : :
574 : : /* Check for the firewalld 'comment' match at init time
575 : : */
576 : : if(opts->config[CONF_ENABLE_FIREWD_COMMENT_CHECK] == NULL)
577 : : set_config_entry(opts, CONF_ENABLE_FIREWD_COMMENT_CHECK,
578 : : DEF_ENABLE_FIREWD_COMMENT_CHECK);
579 : :
580 : : #elif FIREWALL_IPTABLES
581 : : /* Enable IPT forwarding.
582 : : */
583 [ + + ]: 4244 : if(opts->config[CONF_ENABLE_IPT_FORWARDING] == NULL)
584 : 4126 : set_config_entry(opts, CONF_ENABLE_IPT_FORWARDING,
585 : : DEF_ENABLE_IPT_FORWARDING);
586 : :
587 : : /* Enable IPT local NAT.
588 : : */
589 [ + + ]: 4211 : if(opts->config[CONF_ENABLE_IPT_LOCAL_NAT] == NULL)
590 : 4178 : set_config_entry(opts, CONF_ENABLE_IPT_LOCAL_NAT,
591 : : DEF_ENABLE_IPT_LOCAL_NAT);
592 : :
593 : : /* Enable IPT SNAT.
594 : : */
595 [ + + ]: 4171 : if(opts->config[CONF_ENABLE_IPT_SNAT] == NULL)
596 : 4140 : set_config_entry(opts, CONF_ENABLE_IPT_SNAT,
597 : : DEF_ENABLE_IPT_SNAT);
598 : :
599 : : /* Make sure we have a valid IP if SNAT is enabled
600 : : */
601 [ + + ]: 4131 : if(strncasecmp(opts->config[CONF_ENABLE_IPT_SNAT], "Y", 1) == 0)
602 : : {
603 : : /* Note that fw_config_init() will set use_masquerade if necessary
604 : : */
605 [ + + ]: 31 : if(opts->config[CONF_SNAT_TRANSLATE_IP] != NULL)
606 : : {
607 [ + + ]: 16 : if(! is_valid_ipv4_addr(opts->config[CONF_SNAT_TRANSLATE_IP]))
608 : : {
609 : 1 : log_msg(LOG_ERR,
610 : : "Invalid IPv4 addr for SNAT_TRANSLATE_IP"
611 : : );
612 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
613 : : }
614 : : }
615 : : }
616 : :
617 : : /* Enable IPT OUTPUT.
618 : : */
619 [ + + ]: 4130 : if(opts->config[CONF_ENABLE_IPT_OUTPUT] == NULL)
620 : 4129 : set_config_entry(opts, CONF_ENABLE_IPT_OUTPUT,
621 : : DEF_ENABLE_IPT_OUTPUT);
622 : :
623 : : /* Flush IPT at init.
624 : : */
625 [ + + ]: 4098 : if(opts->config[CONF_FLUSH_IPT_AT_INIT] == NULL)
626 : 4090 : set_config_entry(opts, CONF_FLUSH_IPT_AT_INIT, DEF_FLUSH_IPT_AT_INIT);
627 : :
628 : : /* Flush IPT at exit.
629 : : */
630 [ + + ]: 4074 : if(opts->config[CONF_FLUSH_IPT_AT_EXIT] == NULL)
631 : 4066 : set_config_entry(opts, CONF_FLUSH_IPT_AT_EXIT, DEF_FLUSH_IPT_AT_EXIT);
632 : :
633 : : /* IPT input access.
634 : : */
635 [ + + ]: 4044 : if(opts->config[CONF_IPT_INPUT_ACCESS] == NULL)
636 : 4030 : set_config_entry(opts, CONF_IPT_INPUT_ACCESS,
637 : : DEF_IPT_INPUT_ACCESS);
638 : :
639 [ + + ]: 4004 : if(validate_ipt_chain_conf(opts->config[CONF_IPT_INPUT_ACCESS]) != 1)
640 : : {
641 : 3 : log_msg(LOG_ERR,
642 : : "Invalid IPT_INPUT_ACCESS specification, see fwknopd.conf comments"
643 : : );
644 : 3 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
645 : : }
646 : :
647 : : /* IPT output access.
648 : : */
649 [ + + ]: 4001 : if(opts->config[CONF_IPT_OUTPUT_ACCESS] == NULL)
650 : 3999 : set_config_entry(opts, CONF_IPT_OUTPUT_ACCESS,
651 : : DEF_IPT_OUTPUT_ACCESS);
652 : :
653 [ + + ]: 3975 : if(validate_ipt_chain_conf(opts->config[CONF_IPT_OUTPUT_ACCESS]) != 1)
654 : : {
655 : 1 : log_msg(LOG_ERR,
656 : : "Invalid IPT_OUTPUT_ACCESS specification, see fwknopd.conf comments"
657 : : );
658 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
659 : : }
660 : :
661 : : /* IPT forward access.
662 : : */
663 [ + + ]: 3974 : if(opts->config[CONF_IPT_FORWARD_ACCESS] == NULL)
664 : 3970 : set_config_entry(opts, CONF_IPT_FORWARD_ACCESS,
665 : : DEF_IPT_FORWARD_ACCESS);
666 : :
667 [ + + ]: 3951 : if(validate_ipt_chain_conf(opts->config[CONF_IPT_FORWARD_ACCESS]) != 1)
668 : : {
669 : 1 : log_msg(LOG_ERR,
670 : : "Invalid IPT_FORWARD_ACCESS specification, see fwknopd.conf comments"
671 : : );
672 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
673 : : }
674 : :
675 : : /* IPT dnat access.
676 : : */
677 [ + + ]: 3950 : if(opts->config[CONF_IPT_DNAT_ACCESS] == NULL)
678 : 3946 : set_config_entry(opts, CONF_IPT_DNAT_ACCESS,
679 : : DEF_IPT_DNAT_ACCESS);
680 : :
681 [ + + ]: 3927 : if(validate_ipt_chain_conf(opts->config[CONF_IPT_DNAT_ACCESS]) != 1)
682 : : {
683 : 1 : log_msg(LOG_ERR,
684 : : "Invalid IPT_DNAT_ACCESS specification, see fwknopd.conf comments"
685 : : );
686 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
687 : : }
688 : :
689 : : /* IPT snat access.
690 : : */
691 [ + + ]: 3926 : if(opts->config[CONF_IPT_SNAT_ACCESS] == NULL)
692 : 3925 : set_config_entry(opts, CONF_IPT_SNAT_ACCESS,
693 : : DEF_IPT_SNAT_ACCESS);
694 : :
695 [ + + ]: 3910 : if(validate_ipt_chain_conf(opts->config[CONF_IPT_SNAT_ACCESS]) != 1)
696 : : {
697 : 1 : log_msg(LOG_ERR,
698 : : "Invalid IPT_SNAT_ACCESS specification, see fwknopd.conf comments"
699 : : );
700 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
701 : : }
702 : :
703 : : /* IPT masquerade access.
704 : : */
705 [ + + ]: 3909 : if(opts->config[CONF_IPT_MASQUERADE_ACCESS] == NULL)
706 : 3908 : set_config_entry(opts, CONF_IPT_MASQUERADE_ACCESS,
707 : : DEF_IPT_MASQUERADE_ACCESS);
708 : :
709 [ + + ]: 3880 : if(validate_ipt_chain_conf(opts->config[CONF_IPT_MASQUERADE_ACCESS]) != 1)
710 : : {
711 : 1 : log_msg(LOG_ERR,
712 : : "Invalid IPT_MASQUERADE_ACCESS specification, see fwknopd.conf comments"
713 : : );
714 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
715 : : }
716 : :
717 : : /* Check for the iptables 'comment' match at init time
718 : : */
719 [ + - ]: 3879 : if(opts->config[CONF_ENABLE_IPT_COMMENT_CHECK] == NULL)
720 : 3879 : set_config_entry(opts, CONF_ENABLE_IPT_COMMENT_CHECK,
721 : : DEF_ENABLE_IPT_COMMENT_CHECK);
722 : :
723 : : #elif FIREWALL_IPFW
724 : :
725 : : /* Flush ipfw rules at init.
726 : : */
727 : : if(opts->config[CONF_FLUSH_IPFW_AT_INIT] == NULL)
728 : : set_config_entry(opts, CONF_FLUSH_IPFW_AT_INIT, DEF_FLUSH_IPFW_AT_INIT);
729 : :
730 : : /* Flush ipfw rules at exit.
731 : : */
732 : : if(opts->config[CONF_FLUSH_IPFW_AT_EXIT] == NULL)
733 : : set_config_entry(opts, CONF_FLUSH_IPFW_AT_EXIT, DEF_FLUSH_IPFW_AT_EXIT);
734 : :
735 : : /* Set IPFW start rule number.
736 : : */
737 : : if(opts->config[CONF_IPFW_START_RULE_NUM] == NULL)
738 : : set_config_entry(opts, CONF_IPFW_START_RULE_NUM,
739 : : DEF_IPFW_START_RULE_NUM);
740 : :
741 : : /* Set IPFW max rules.
742 : : */
743 : : if(opts->config[CONF_IPFW_MAX_RULES] == NULL)
744 : : set_config_entry(opts, CONF_IPFW_MAX_RULES,
745 : : DEF_IPFW_MAX_RULES);
746 : :
747 : : /* Set IPFW active set number.
748 : : */
749 : : if(opts->config[CONF_IPFW_ACTIVE_SET_NUM] == NULL)
750 : : set_config_entry(opts, CONF_IPFW_ACTIVE_SET_NUM,
751 : : DEF_IPFW_ACTIVE_SET_NUM);
752 : :
753 : : /* Set IPFW expire set number.
754 : : */
755 : : if(opts->config[CONF_IPFW_EXPIRE_SET_NUM] == NULL)
756 : : set_config_entry(opts, CONF_IPFW_EXPIRE_SET_NUM,
757 : : DEF_IPFW_EXPIRE_SET_NUM);
758 : :
759 : : /* Set IPFW Dynamic rule expiry interval.
760 : : */
761 : : if(opts->config[CONF_IPFW_EXPIRE_PURGE_INTERVAL] == NULL)
762 : : set_config_entry(opts, CONF_IPFW_EXPIRE_PURGE_INTERVAL,
763 : : DEF_IPFW_EXPIRE_PURGE_INTERVAL);
764 : :
765 : : /* Set IPFW Dynamic rule expiry interval.
766 : : */
767 : : if(opts->config[CONF_IPFW_ADD_CHECK_STATE] == NULL)
768 : : set_config_entry(opts, CONF_IPFW_ADD_CHECK_STATE,
769 : : DEF_IPFW_ADD_CHECK_STATE);
770 : :
771 : : #elif FIREWALL_PF
772 : : /* Set PF anchor name
773 : : */
774 : : if(opts->config[CONF_PF_ANCHOR_NAME] == NULL)
775 : : set_config_entry(opts, CONF_PF_ANCHOR_NAME,
776 : : DEF_PF_ANCHOR_NAME);
777 : :
778 : : /* Set PF rule expiry interval.
779 : : */
780 : : if(opts->config[CONF_PF_EXPIRE_INTERVAL] == NULL)
781 : : set_config_entry(opts, CONF_PF_EXPIRE_INTERVAL,
782 : : DEF_PF_EXPIRE_INTERVAL);
783 : :
784 : : #elif FIREWALL_IPF
785 : : /* --DSS Place-holder */
786 : :
787 : : #endif /* FIREWALL type */
788 : :
789 : : /* GPG Home dir.
790 : : */
791 [ + + ]: 3856 : if(opts->config[CONF_GPG_HOME_DIR] == NULL)
792 : 3855 : set_config_entry(opts, CONF_GPG_HOME_DIR, DEF_GPG_HOME_DIR);
793 : :
794 : : /* GPG executable
795 : : */
796 [ + - ]: 3836 : if(opts->config[CONF_GPG_EXE] == NULL)
797 : 3836 : set_config_entry(opts, CONF_GPG_EXE, DEF_GPG_EXE);
798 : :
799 : : /* Enable SPA over HTTP.
800 : : */
801 [ + + ]: 3824 : if(opts->config[CONF_ENABLE_SPA_OVER_HTTP] == NULL)
802 : 3823 : set_config_entry(opts, CONF_ENABLE_SPA_OVER_HTTP,
803 : : DEF_ENABLE_SPA_OVER_HTTP);
804 : :
805 : : /* Enable TCP server.
806 : : */
807 [ + + ]: 3808 : if(opts->config[CONF_ENABLE_TCP_SERVER] == NULL)
808 : 3807 : set_config_entry(opts, CONF_ENABLE_TCP_SERVER, DEF_ENABLE_TCP_SERVER);
809 : :
810 : : /* TCP Server port.
811 : : */
812 [ + + ]: 3792 : if(opts->config[CONF_TCPSERV_PORT] == NULL)
813 : 3790 : set_config_entry(opts, CONF_TCPSERV_PORT, DEF_TCPSERV_PORT);
814 : :
815 : : /* Enable UDP server.
816 : : */
817 [ + + ]: 3780 : if(opts->config[CONF_ENABLE_UDP_SERVER] == NULL)
818 : : {
819 [ - + ][ # # ]: 3778 : if((strncasecmp(DEF_ENABLE_UDP_SERVER, "Y", 1) == 0) &&
820 : 0 : !opts->enable_udp_server)
821 : : {
822 : 0 : log_msg(LOG_ERR, "pcap capture not compiled in, forcing UDP server mode");
823 : 0 : opts->enable_udp_server = 1;
824 : : }
825 : 3778 : set_config_entry(opts, CONF_ENABLE_UDP_SERVER, DEF_ENABLE_UDP_SERVER);
826 : : }
827 : :
828 : : /* UDP Server port.
829 : : */
830 [ + + ]: 3768 : if(opts->config[CONF_UDPSERV_PORT] == NULL)
831 : 3765 : set_config_entry(opts, CONF_UDPSERV_PORT, DEF_UDPSERV_PORT);
832 : :
833 : : /* UDP server select() timeout in microseconds
834 : : */
835 [ + - ]: 3752 : if(opts->config[CONF_UDPSERV_SELECT_TIMEOUT] == NULL)
836 : 3752 : set_config_entry(opts, CONF_UDPSERV_SELECT_TIMEOUT,
837 : : DEF_UDPSERV_SELECT_TIMEOUT);
838 : :
839 : : /* Syslog identity.
840 : : */
841 [ + - ]: 3734 : if(opts->config[CONF_SYSLOG_IDENTITY] == NULL)
842 : 3734 : set_config_entry(opts, CONF_SYSLOG_IDENTITY, DEF_SYSLOG_IDENTITY);
843 : :
844 : : /* Syslog facility.
845 : : */
846 [ + + ]: 3723 : if(opts->config[CONF_SYSLOG_FACILITY] == NULL)
847 : 3713 : set_config_entry(opts, CONF_SYSLOG_FACILITY, DEF_SYSLOG_FACILITY);
848 : :
849 : :
850 : : /* Validate integer variable ranges
851 : : */
852 : 3715 : validate_int_var_ranges(opts);
853 : :
854 : : /* Some options just trigger some output of information, or trigger an
855 : : * external function, but do not actually start fwknopd. If any of those
856 : : * are set, we can return here an skip the validation routines as all
857 : : * other options will be ignored anyway.
858 : : *
859 : : * These are also mutually exclusive (for now).
860 : : */
861 [ + + ]: 3712 : if((opts->dump_config + opts->kill + opts->restart + opts->status) == 1)
862 : : return;
863 : :
864 [ + + ]: 2581 : if((opts->dump_config + opts->kill + opts->restart + opts->status) > 1)
865 : : {
866 : 2 : log_msg(LOG_ERR,
867 : : "The -D, -K, -R, and -S options are mutually exclusive. Pick only one."
868 : : );
869 : 2 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
870 : : }
871 : :
872 [ - + ]: 2579 : if(opts->config[CONF_FIREWALL_EXE] == NULL)
873 : : {
874 : 0 : log_msg(LOG_ERR,
875 : : "[*] No firewall command executable is set. Please check FIREWALL_EXE in fwknopd.conf."
876 : : );
877 : 0 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
878 : : }
879 : :
880 : : return;
881 : : }
882 : :
883 : : void
884 : 5507 : set_preconfig_entries(fko_srv_options_t *opts)
885 : : {
886 : : /* First, set any default or otherwise static settings here. Some may
887 : : * end up being overwritten via config file or command-line.
888 : : */
889 : :
890 : : /* Setup the firewall executable based on build-time info.
891 : : * --DSS Note: We will want to either force external script mode, or
892 : : * error out if we do not have a firewall executable defined.
893 : : */
894 : : #ifdef FIREWALL_EXE
895 : 5507 : set_config_entry(opts, CONF_FIREWALL_EXE, FIREWALL_EXE);
896 : : #endif
897 : :
898 : 5392 : }
899 : :
900 : : /* Initialize program configuration via config file and/or command-line
901 : : * switches.
902 : : */
903 : : void
904 : 5507 : config_init(fko_srv_options_t *opts, int argc, char **argv)
905 : : {
906 : : int cmd_arg, index, is_err;
907 : 5507 : unsigned char got_conf_file = 0, got_override_config = 0;
908 : :
909 : 5507 : char override_file[MAX_LINE_LEN] = {0};
910 : : char *ndx, *cmrk;
911 : :
912 : : /* Zero out options and opts_track.
913 : : */
914 : : memset(opts, 0x00, sizeof(fko_srv_options_t));
915 : :
916 : : /* Set some preconfiguration options (i.e. build-time defaults)
917 : : */
918 : 5507 : set_preconfig_entries(opts);
919 : :
920 : : /* In case this is a re-config.
921 : : */
922 : 5392 : optind = 0;
923 : :
924 : : /* First, scan the command-line args for -h/--help or an alternate
925 : : * configuration file. If we find an alternate config file, use it,
926 : : * otherwise use the default. We also grab any override config files
927 : : * as well.
928 : : */
929 [ + + ]: 50997 : while ((cmd_arg = getopt_long(argc, argv,
930 : : GETOPTS_OPTION_STRING, cmd_opts, &index)) != -1) {
931 : :
932 : : /* If help is wanted, give it and exit.
933 : : */
934 [ + + + + ]: 40380 : switch(cmd_arg) {
935 : : case 'h':
936 : 1 : usage();
937 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS);
938 : :
939 : : /* Look for configuration file arg.
940 : : */
941 : : case 'c':
942 : 5390 : set_config_entry(opts, CONF_CONFIG_FILE, optarg);
943 : 5300 : got_conf_file++;
944 : :
945 : : /* If we already have the config_override option, we are done.
946 : : */
947 [ + - ]: 5300 : if(got_override_config > 0)
948 : : break;
949 : :
950 : : /* Look for override configuration file arg.
951 : : */
952 : : case 'O':
953 : 5302 : set_config_entry(opts, CONF_OVERRIDE_CONFIG, optarg);
954 : 10618 : got_override_config++;
955 : :
956 : : /* If we already have the conf_file option, we are done.
957 : : */
958 : : if(got_conf_file > 0)
959 : : break;
960 : : }
961 : : }
962 : :
963 : : /* If no alternate configuration file was specified, we use the
964 : : * default.
965 : : */
966 [ + + ]: 5225 : if(opts->config[CONF_CONFIG_FILE] == NULL)
967 : 1 : set_config_entry(opts, CONF_CONFIG_FILE, DEF_CONFIG_FILE);
968 : :
969 : : /* Parse configuration file to populate any params not already specified
970 : : * via command-line options.
971 : : */
972 : 5225 : parse_config_file(opts, opts->config[CONF_CONFIG_FILE]);
973 : :
974 : : /* If there are override configuration entries, process them
975 : : * here.
976 : : */
977 [ + - ]: 5125 : if(opts->config[CONF_OVERRIDE_CONFIG] != NULL)
978 : : {
979 : : /* Make a copy of the override_config string so we can munge it.
980 : : */
981 : 5125 : strlcpy(override_file, opts->config[CONF_OVERRIDE_CONFIG], sizeof(override_file));
982 : :
983 : 5125 : ndx = override_file;
984 : 5125 : cmrk = strchr(ndx, ',');
985 : :
986 [ + + ]: 5125 : if(cmrk == NULL)
987 : : {
988 : : /* Only one to process...
989 : : */
990 : 5124 : parse_config_file(opts, ndx);
991 : :
992 : : } else {
993 : : /* Walk the string pulling the next config override
994 : : * at the comma delimiters.
995 : : */
996 [ + + ]: 2 : while(cmrk != NULL) {
997 : 1 : *cmrk = '\0';
998 : 1 : parse_config_file(opts, ndx);
999 : 1 : ndx = cmrk + 1;
1000 : 1 : cmrk = strchr(ndx, ',');
1001 : : }
1002 : :
1003 : : /* Process the last entry
1004 : : */
1005 : 1 : parse_config_file(opts, ndx);
1006 : : }
1007 : : }
1008 : :
1009 : : /* Set up the verbosity level according to the value found in the
1010 : : * config files */
1011 [ + + ]: 5046 : if (opts->config[CONF_VERBOSE] != NULL)
1012 : : {
1013 : 1 : opts->verbose = strtol_wrapper(opts->config[CONF_VERBOSE], 0, -1,
1014 : : NO_EXIT_UPON_ERR, &is_err);
1015 [ + - ]: 1 : if(is_err != FKO_SUCCESS)
1016 : : {
1017 : 1 : log_msg(LOG_ERR, "[*] VERBOSE value '%s' not in the range (>0)",
1018 : : opts->config[CONF_VERBOSE]);
1019 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1020 : : }
1021 : : }
1022 : :
1023 : : /* Reset the options index so we can run through them again.
1024 : : */
1025 : 5045 : optind = 0;
1026 : :
1027 : : /* Last, but not least, we process command-line options (some of which
1028 : : * may override configuration file options.
1029 : : */
1030 [ + + ]: 46446 : while ((cmd_arg = getopt_long(argc, argv,
1031 : : GETOPTS_OPTION_STRING, cmd_opts, &index)) != -1) {
1032 : :
1033 [ + + + + : 36645 : switch(cmd_arg) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + ]
1034 : : case 'A':
1035 : : #if AFL_FUZZING
1036 : : opts->afl_fuzzing = 1;
1037 : : #else
1038 : 1 : log_msg(LOG_ERR, "[*] fwknopd not compiled with AFL fuzzing support");
1039 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1040 : : #endif
1041 : 0 : break;
1042 : : case 'a':
1043 : 5045 : set_config_entry(opts, CONF_ACCESS_FILE, optarg);
1044 : 4965 : break;
1045 : : case 'c':
1046 : : /* This was handled earlier */
1047 : : break;
1048 : : case 'C':
1049 : 744 : opts->packet_ctr_limit = strtol_wrapper(optarg,
1050 : : 0, (2 << 30), NO_EXIT_UPON_ERR, &is_err);
1051 [ + + ]: 744 : if(is_err != FKO_SUCCESS)
1052 : : {
1053 : 1 : log_msg(LOG_ERR,
1054 : : "[*] invalid -C packet count limit '%s'",
1055 : : optarg);
1056 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1057 : : }
1058 : : break;
1059 : : case 'd':
1060 : : #if USE_FILE_CACHE
1061 : 4946 : set_config_entry(opts, CONF_DIGEST_FILE, optarg);
1062 : : #else
1063 : : set_config_entry(opts, CONF_DIGEST_DB_FILE, optarg);
1064 : : #endif
1065 : 4875 : break;
1066 : : case 'D':
1067 : 18 : opts->dump_config = 1;
1068 : 18 : break;
1069 : : case DUMP_SERVER_ERR_CODES:
1070 : 1 : dump_server_errors();
1071 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS);
1072 : : case EXIT_AFTER_PARSE_CONFIG:
1073 : 1649 : opts->exit_after_parse_config = 1;
1074 : 1649 : opts->foreground = 1;
1075 : 1649 : break;
1076 : : case 'f':
1077 : 2721 : opts->foreground = 1;
1078 : 2721 : break;
1079 : : case FAULT_INJECTION_TAG:
1080 : : #if HAVE_LIBFIU
1081 : 35 : set_config_entry(opts, CONF_FAULT_INJECTION_TAG, optarg);
1082 : : #else
1083 : : log_msg(LOG_ERR, "[*] fwknopd not compiled with libfiu support");
1084 : : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1085 : : #endif
1086 : 35 : break;
1087 : : case FW_LIST:
1088 : 890 : opts->fw_list = 1;
1089 : 890 : break;
1090 : : case FW_LIST_ALL:
1091 : 2 : opts->fw_list = 1;
1092 : 2 : opts->fw_list_all = 1;
1093 : 2 : break;
1094 : : case FW_FLUSH:
1095 : 18 : opts->fw_flush = 1;
1096 : 18 : break;
1097 : : case GPG_HOME_DIR:
1098 [ + + ]: 3 : if (is_valid_dir(optarg))
1099 : : {
1100 : 1 : set_config_entry(opts, CONF_GPG_HOME_DIR, optarg);
1101 : : }
1102 : : else
1103 : : {
1104 : 2 : log_msg(LOG_ERR,
1105 : : "[*] Directory '%s' could not stat()/does not exist?",
1106 : : optarg);
1107 : 2 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1108 : : }
1109 : : break;
1110 : : case 'i':
1111 : 2090 : set_config_entry(opts, CONF_PCAP_INTF, optarg);
1112 : 2066 : break;
1113 : : case FIREWD_DISABLE_CHECK_SUPPORT:
1114 : 3 : opts->firewd_disable_check_support = 1;
1115 : 3 : break;
1116 : : case IPT_DISABLE_CHECK_SUPPORT:
1117 : 641 : opts->ipt_disable_check_support = 1;
1118 : 641 : break;
1119 : : case 'K':
1120 : 372 : opts->kill = 1;
1121 : 372 : break;
1122 : : case 'l':
1123 : 2 : set_config_entry(opts, CONF_LOCALE, optarg);
1124 : 2 : break;
1125 : : case 'O':
1126 : : /* This was handled earlier */
1127 : : break;
1128 : : case 'p':
1129 : 4873 : set_config_entry(opts, CONF_FWKNOP_PID_FILE, optarg);
1130 : 4795 : break;
1131 : : case 'P':
1132 : 7 : set_config_entry(opts, CONF_PCAP_FILTER, optarg);
1133 : 7 : break;
1134 : : case PCAP_FILE:
1135 : 671 : set_config_entry(opts, CONF_PCAP_FILE, optarg);
1136 : 642 : break;
1137 : : case ENABLE_PCAP_ANY_DIRECTION:
1138 : 1 : opts->pcap_any_direction = 1;
1139 : 1 : break;
1140 : : case ROTATE_DIGEST_CACHE:
1141 : 2 : opts->rotate_digest_cache = 1;
1142 : 2 : break;
1143 : : case 'R':
1144 : 6 : opts->restart = 1;
1145 : 6 : break;
1146 : : case 'S':
1147 : 739 : opts->status = 1;
1148 : 739 : break;
1149 : : case 't':
1150 : 643 : opts->test = 1;
1151 : 643 : break;
1152 : : case 'U':
1153 : 9 : opts->enable_udp_server = 1;
1154 : 9 : break;
1155 : : /* Verbosity level */
1156 : : case 'v':
1157 : 5462 : opts->verbose++;
1158 : 5462 : break;
1159 : : case SYSLOG_ENABLE:
1160 : 2 : opts->syslog_enable = 1;
1161 : 2 : break;
1162 : : case 'V':
1163 : 1 : fprintf(stdout, "fwknopd server %s\n", MY_VERSION);
1164 : 1 : clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS);
1165 : : default:
1166 : 1 : usage();
1167 : 36355 : clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
1168 : : }
1169 : : }
1170 : :
1171 : : /* Now that we have all of our options set, and we are actually going to
1172 : : * start fwknopd, we can validate them.
1173 : : */
1174 : 4756 : validate_options(opts);
1175 : :
1176 : 3710 : return;
1177 : : }
1178 : :
1179 : : /* Dump the configuration
1180 : : */
1181 : : void
1182 : 1582 : dump_config(const fko_srv_options_t *opts)
1183 : : {
1184 : : int i;
1185 : :
1186 : 1582 : fprintf(stdout, "Current fwknopd config settings:\n");
1187 : :
1188 [ + + ]: 75936 : for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
1189 [ + + ]: 74354 : fprintf(stdout, "%3i. %-28s = '%s'\n",
1190 : : i,
1191 : : config_map[i],
1192 : 74354 : (opts->config[i] == NULL) ? "<not set>" : opts->config[i]
1193 : : );
1194 : :
1195 : 1582 : fprintf(stdout, "\n");
1196 : 1582 : fflush(stdout);
1197 : 1582 : }
1198 : :
1199 : : /* Print usage message...
1200 : : */
1201 : : void
1202 : 2 : usage(void)
1203 : : {
1204 : 2 : fprintf(stdout, "\n%s server version %s\n%s - http://www.cipherdyne.org/fwknop/\n\n",
1205 : : MY_NAME, MY_VERSION, MY_DESC);
1206 : 2 : fprintf(stdout,
1207 : : "Usage: fwknopd [options]\n\n"
1208 : : " -a, --access-file - Specify an alternate access.conf file.\n"
1209 : : " -c, --config-file - Specify an alternate configuration file.\n"
1210 : : " -f, --foreground - Run fwknopd in the foreground (do not become\n"
1211 : : " a background daemon).\n"
1212 : : " -i, --interface - Specify interface to listen for incoming SPA\n"
1213 : : " packets.\n"
1214 : : " -C, --packet-limit - Limit the number of candidate SPA packets to\n"
1215 : : " process and exit when this limit is reached.\n"
1216 : : " -d, --digest-file - Specify an alternate digest.cache file.\n"
1217 : : " -D, --dump-config - Dump the current fwknop configuration values.\n"
1218 : : " -K, --kill - Kill the currently running fwknopd.\n"
1219 : : " -l, --locale - Provide a locale setting other than the system\n"
1220 : : " default.\n"
1221 : : " -O, --override-config - Specify a file with configuration entries that will\n"
1222 : : " overide those in fwknopd.conf\n"
1223 : : " -p, --pid-file - Specify an alternate fwknopd.pid file.\n"
1224 : : " -P, --pcap-filter - Specify a Berkeley packet filter statement to\n"
1225 : : " override the PCAP_FILTER variable in fwknopd.conf.\n"
1226 : : " -R, --restart - Force the currently running fwknopd to restart.\n"
1227 : : " --rotate-digest-cache\n"
1228 : : " - Rotate the digest cache file by renaming it to\n"
1229 : : " '<name>-old', and starting a new one.\n"
1230 : : " -S, --status - Display the status of any running fwknopd process.\n"
1231 : : " -t, --test - Test mode, process SPA packets but do not make any\n"
1232 : : " firewall modifications.\n"
1233 : : " -U, --udp-server - Set UDP server mode.\n"
1234 : : " -v, --verbose - Set verbose mode.\n"
1235 : : " --syslog-enable - Allow messages to be sent to syslog even if the\n"
1236 : : " foreground mode is set.\n"
1237 : : " -V, --version - Print version number.\n"
1238 : : " -A, --afl-fuzzing - Run in American Fuzzy Lop (AFL) fuzzing mode\n"
1239 : : " plaintext SPA packets are accepted via stdin.\n"
1240 : : " -h, --help - Print this usage message and exit.\n"
1241 : : " --dump-serv-err-codes - List all server error codes (only needed by the\n"
1242 : : " test suite).\n"
1243 : : " --exit-parse-config - Parse config files and exit.\n"
1244 : : " --fault-injection-tag - Enable a fault injection tag (only needed by the\n"
1245 : : " test suite).\n"
1246 : : " --pcap-file - Read potential SPA packets from an existing pcap\n"
1247 : : " file.\n"
1248 : : " --pcap-any-direction - By default fwknopd processes packets that are\n"
1249 : : " sent to the sniffing interface, but this option\n"
1250 : : " enables processing of packets that originate from\n"
1251 : : " an interface (such as in a forwarding situation).\n"
1252 : : " --fw-list - List all firewall rules that fwknop has created\n"
1253 : : " and then exit.\n"
1254 : : " --fw-list-all - List all firewall rules in the complete policy,\n"
1255 : : " including those that have nothing to do with\n"
1256 : : " fwknop.\n"
1257 : : " --fw-flush - Flush all firewall rules created by fwknop.\n"
1258 : : " --gpg-home-dir - Specify the GPG home directory (this is normally\n"
1259 : : " done in the access.conf file).\n"
1260 : : " --gpg-exe - Specify the path to GPG (this is normally done in\n"
1261 : : " the access.conf file).\n"
1262 : : " --no-firewd-check-support\n"
1263 : : " - Disable test for 'firewall-cmd ... -C' support.\n"
1264 : : " --no-ipt-check-support - Disable test for 'iptables -C' support.\n"
1265 : : "\n"
1266 : : );
1267 : :
1268 : 2 : return;
1269 : : }
1270 : :
1271 : : /***EOF***/
|