Added cxtracker like output into file again with -L option.
[prads.git] / src / config.c
blob366dfc462d8509642bdd07cf1adba73049c3aede
1 /*
2 ** This file is a part of PRADS.
3 **
4 ** Copyright (C) 2010, Edward Fjellskål <edward.fjellskaal@redpill-linpro.com>
5 ** Copyright (C) 2010, Kacper Wysocki <kacper.wysocki@redpill-linpro.com>
6 ** Adopted from PADS by Matt Shelton
7 ** Copyright (C) 2004 Matt Shelton <matt@mattshelton.com>
8 **
9 ** This program is free software; you can redistribute it and/or modify
10 ** it under the terms of the GNU General Public License as published by
11 ** the Free Software Foundation; either version 2 of the License, or
12 ** (at your option) any later version.
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ** GNU General Public License for more details.
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 /* I N C L U D E S *********************************************************/
26 #include "common.h"
27 #include "prads.h"
28 #include "sys_func.h"
29 #include "dhcp.h"
30 #include "config.h"
31 #include "mac.h"
32 #include "sig.h"
34 /* G L O B A L E S *********************************************************/
35 extern globalconfig config;
37 /* F U N C T I O N S ********************************************************/
38 void display_config(globalconfig *conf)
40 olog("[*] OS checks enabled:");
41 if (IS_COSET(conf,CO_SYN)) olog (" SYN");
42 if (IS_COSET(conf,CO_SYNACK)) olog (" SYNACK");
43 if (IS_COSET(conf,CO_RST)) olog (" RST");
44 if (IS_COSET(conf,CO_FIN)) olog (" FIN");
45 if (IS_COSET(conf,CO_ACK)) olog (" ACK");
46 olog("\n");
48 olog("[*] Service checks enabled:");
49 if (IS_CSSET(conf,CS_TCP_SERVER)) olog (" TCP-SERVER");
50 if (IS_CSSET(conf,CS_TCP_CLIENT)) olog (" TCP-CLIENT");
51 if (IS_CSSET(conf,CS_UDP_SERVICES)) olog (" UDP-SERVICES");
52 if (IS_CSSET(conf,CS_ICMP)) olog (" ICMP");
53 if (IS_CSSET(conf,CS_ARP)) olog (" ARP");
54 if (IS_CSSET(conf,CS_MAC)) olog (" MAC");
55 olog("\n");
57 return;
60 void free_config()
62 if (config.cfilter.bf_insns != NULL) free (config.cfilter.bf_insns);
63 // Grr - no nice way to tell if the settings comes from configfile or not :/
64 if (config.pidfile != NULL) free(config.pidfile);
65 if (config.user_name != NULL) free(config.user_name);
66 if (config.group_name != NULL) free(config.group_name);
67 if (config.bpff != NULL) free(config.bpff);
70 void set_default_config_options(globalconfig *config)
72 config->file = CONFDIR "prads.conf";
73 config->ctf |= CO_SYN;
74 config->ctf |= CO_RST;
75 config->ctf |= CO_FIN;
76 //config->ctf |= CO_ACK;
77 config->ctf |= CO_SYNACK;
78 //config->ctf |= CO_ICMP;
79 //config->ctf |= CO_UDP;
80 //config->ctf |= CO_DHCP;
81 config->cof |= CS_TCP_SERVER;
82 config->cof |= CS_TCP_CLIENT;
83 config->cof |= CS_UDP_SERVICES;
84 config->cof |= CS_MAC;
85 config->dev = 0x0; // default is to lookup device
86 config->bpff = strdup("");
87 //config->pidfile = strdup("/var/run/prads.pid");
88 config->assetlog= strdup(LOGDIR PRADS_ASSETLOG);
89 config->fifo = NULL;
90 // default source net owns everything
91 config->s_net = DEFAULT_NETS ;
92 config->errbuf[0] = '\0';
93 config->configpath = CONFDIR "";
94 // files should be relative to configpath somehow
95 config->sig_file_syn = CONFDIR "tcp-syn.fp";
96 config->sig_file_synack = CONFDIR "tcp-synack.fp";
97 config->sig_file_ack = CONFDIR "tcp-stray-ack.fp";
98 config->sig_file_fin = CONFDIR "tcp-fin.fp";
99 config->sig_file_rst = CONFDIR "tcp-rst.fp";
100 config->sig_file_mac = CONFDIR "mac.sig";
101 config->sig_file_dhcp = CONFDIR "dhcp.fp";
102 config->sig_file_serv_tcp = CONFDIR "tcp-service.sig";
103 config->sig_file_serv_udp = CONFDIR "udp-service.sig";
104 config->sig_file_cli_tcp = CONFDIR "tcp-clients.sig";
105 config->sig_syn = NULL;
106 config->sig_synack = NULL;
107 config->sig_ack = NULL;
108 config->sig_fin = NULL;
109 config->sig_rst = NULL;
110 config->sig_mac = NULL;
111 config->sig_dhcp = NULL;
112 config->sig_hashsize = SIG_HASHSIZE;
113 config->mac_hashsize = MAC_HASHSIZE;
114 // drop privileges by default
115 config->user_name = strdup("1");
116 config->group_name = strdup("1");
118 config->drop_privs_flag = 1;
119 // don't chroot or daemonize by default
120 config->chroot_dir = NULL;
121 config->daemon_flag = 0;
122 config->cxtlogdir[0] = '\0';
123 config->cxtfname[0] = '\0';
126 void parse_config_file(const char* fname)
128 FILE *fp;
129 bstring filedata;
130 struct bstrList *lines;
131 int i;
132 vlog(0x3, "config - Processing '%s'.", fname);
134 if ((fp = fopen(fname, "r")) == NULL) {
135 elog("Unable to open configuration file - %s\n", fname);
136 return;
139 filedata = bread ((bNread) fread, fp);
140 if ((lines = bsplit(filedata, '\n')) != NULL) {
141 for (i = 0; i < lines->qty; i++) {
142 parse_line(&config, lines->entry[i]);
146 bdestroy(filedata);
147 bstrListDestroy(lines);
148 fclose(fp);
151 void parse_line (globalconfig * conf, bstring line)
153 bstring param, value;
154 struct bstrList *list;
155 int i;
156 /* Check to see if this line has something to read. */
157 if (line->data[0] == '\0' || line->data[0] == '#')
158 return;
160 /* Check to see if this line has a comment in it. */
161 if ((list = bsplit(line, '#')) != NULL) {
162 if ((bassign(line, list->entry[0])) == -1) {
163 elog("warning: 'bassign' in function 'parse_line' failed.\n");
165 if (list != NULL)
166 bstrListDestroy(list);
169 /* Separate line into a parameter and a value. */
170 if ((i = bstrchr(line, '=')) == BSTR_ERR)
171 return;
172 if ((param = bmidstr(line, 0, i)) == NULL)
173 return;
174 if ((value = bmidstr(line, i + 1, line->slen - i)) == NULL)
175 return;
177 /* Normalize Strings */
178 if ((btolower(param)) != 0)
179 elog("warning: 'btolower' in function 'parse_line' failed.\n");
180 if ((bltrim(value)) != 0)
181 elog("warning: 'bltrim' in function 'parse_line' failed.\n");
182 if ((brtrim(value)) != 0)
183 elog("warning: 'brtrim' in function 'parse_line' failed.\n");
185 /* Do something based upon value. */
186 if ((biseqcstr(param, "daemon")) == 1) {
187 /* DAEMON */
188 if (!conf->daemon_flag) {
189 if (value->data[0] == '1')
190 conf->daemon_flag = 1;
191 else
192 conf->daemon_flag = 0;
194 } else if ((biseqcstr(param, "mac")) == 1) {
195 /* MAC CHECK */
196 if (value->data[0] == '1')
197 conf->cof |= CS_MAC;
198 else
199 conf->cof &= ~CS_MAC;
200 } else if ((biseqcstr(param, "arp")) == 1) {
201 /* ARP CHECK */
202 if (value->data[0] == '1')
203 conf->cof |= CS_ARP;
204 else
205 conf->cof &= ~CS_ARP;
206 } else if ((biseqcstr(param, "service_tcp")) == 1) {
207 /* TCP Service check */
208 if (value->data[0] == '1')
209 conf->cof |= CS_TCP_SERVER;
210 else
211 conf->cof &= ~CS_TCP_SERVER;
212 } else if ((biseqcstr(param, "client_tcp")) == 1) {
213 /* TCP Client check */
214 if (value->data[0] == '1')
215 conf->cof |= CS_TCP_CLIENT;
216 else
217 conf->cof &= ~CS_TCP_CLIENT;
218 } else if ((biseqcstr(param, "service_udp")) == 1) {
219 /* UPD service and client checks */
220 if (value->data[0] == '1')
221 conf->cof |= CS_UDP_SERVICES;
222 else
223 conf->cof &= ~CS_UDP_SERVICES;
224 } else if ((biseqcstr(param, "os_icmp")) == 1) {
225 /* ICMP OS Fingerprinting */
226 if (value->data[0] == '1')
227 conf->ctf |= CO_ICMP;
228 else
229 conf->ctf &= ~CO_ICMP;
230 } else if ((biseqcstr(param, "os_udp")) == 1) {
231 /* UDP OS Fingerprinting */
232 if (value->data[0] == '1')
233 conf->ctf |= CO_UDP;
234 else
235 conf->ctf &= ~CO_UDP;
236 } else if ((biseqcstr(param, "service_udp")) == 1) {
237 /* UPD service and client checks */
238 if (value->data[0] == '1')
239 conf->cof |= CS_UDP_SERVICES;
240 else
241 conf->cof &= ~CS_UDP_SERVICES;
242 } else if ((biseqcstr(param, "os_syn_fingerprint")) == 1) {
243 /* TCP SYN OS Fingerprinting */
244 if (value->data[0] == '1')
245 conf->ctf |= CO_SYN;
246 else
247 conf->ctf &= ~CO_SYN;
248 } else if ((biseqcstr(param, "os_synack_fingerprint")) == 1) {
249 /* TCP SYNACK OS Fingerprinting */
250 if (value->data[0] == '1')
251 conf->ctf |= CO_SYNACK;
252 else
253 conf->ctf &= ~CO_SYNACK;
254 } else if ((biseqcstr(param, "os_ack_fingerprint")) == 1) {
255 /* TCP Stray ACK OS Fingerprinting */
256 if (value->data[0] == '1')
257 conf->ctf |= CO_ACK;
258 else
259 conf->ctf &= ~CO_ACK;
260 } else if ((biseqcstr(param, "os_rst_fingerprint")) == 1) {
261 /* TCP RST OS Fingerprinting */
262 if (value->data[0] == '1')
263 conf->ctf |= CO_RST;
264 else
265 conf->ctf &= ~CO_RST;
266 } else if ((biseqcstr(param, "os_fin_fingerprint")) == 1) {
267 /* TCP FIN OS Fingerprinting */
268 if (value->data[0] == '1')
269 conf->ctf |= CO_FIN;
270 else
271 conf->ctf &= ~CO_FIN;
272 } else if ((biseqcstr(param, "chroot_dir")) == 1) {
273 /* CHROOT DIRECTORY */
274 if(conf->chroot_dir) free(conf->chroot_dir);
275 conf->chroot_dir = bstr2cstr(value, '-');
276 } else if ((biseqcstr(param, "pid_file")) == 1) {
277 /* PID FILE */
278 if(conf->pidfile) free(conf->pidfile);
279 conf->pidfile = bstr2cstr(value, '-');
280 } else if ((biseqcstr(param, "asset_log")) == 1) {
281 /* PRADS ASSET LOG */
282 if(conf->assetlog) free(conf->assetlog);
283 conf->assetlog = bstr2cstr(value,'-');
284 } else if ((biseqcstr(param, "fifo")) == 1) {
285 /* FIFO path */
286 conf->fifo = bstr2cstr (value, '-');
287 } else if ((biseqcstr(param, "sig_file_serv_tcp")) == 1) {
288 /* SIGNATURE FILE */
289 conf->sig_file_serv_tcp = bstr2cstr(value, '-');
290 } else if ((biseqcstr(param, "sig_file_cli_tcp")) == 1) {
291 /* SIGNATURE FILE */
292 conf->sig_file_cli_tcp = bstr2cstr(value, '-');
293 } else if ((biseqcstr(param, "sig_file_serv_udp")) == 1) {
294 /* SIGNATURE FILE */
295 conf->sig_file_serv_udp = bstr2cstr(value, '-');
296 } else if ((biseqcstr(param, "sig_file_cli_udp")) == 1) {
297 /* SIGNATURE FILE */
298 conf->sig_file_cli_udp = bstr2cstr(value, '-');
299 } else if ((biseqcstr(param, "mac_file")) == 1) {
300 /* MAC / VENDOR RESOLUTION FILE */
301 conf->sig_file_mac = bstr2cstr(value, '-');
302 } else if ((biseqcstr(param, "output")) == 1) {
303 /* OUTPUT */
304 //conf_module_plugin(value, &activate_output_plugin);
305 } else if ((biseqcstr(param, "user")) == 1) {
306 /* USER */
307 conf->user_name = bstr2cstr(value, '-');
308 conf->drop_privs_flag = 1;
309 } else if ((biseqcstr(param, "group")) == 1) {
310 /* GROUP */
311 conf->group_name = bstr2cstr(value, '-');
312 conf->drop_privs_flag = 1;
313 } else if ((biseqcstr(param, "interface")) == 1) {
314 /* INTERFACE */
315 conf->dev = bstr2cstr(value, '-');
316 } else if ((biseqcstr(param, "bpfilter")) == 1) {
317 /* FILTER */
318 free(conf->bpff);
319 conf->bpff = bstr2cstr(value, '-');
321 // } else if ((biseqcstr(param, "network")) == 1) {
322 // /* NETWORK */
323 // parse_networks((unsigned char *)bdata(value));
324 // } else if ((biseqcstr(param, "hide_unknowns")) == 1) {
325 // /* UNKNOWN */
326 // if (!conf->hide_unknowns) {
327 // if (value->data[0] == '1')
328 // conf->hide_unknowns = 1;
329 // else
330 // conf->hide_unknowns = 0;
331 // }
334 vlog(0x3,"config - PARAM: |%s| / VALUE: |%s|\n", bdata(param), bdata(value));
336 /* Clean Up */
337 if (param != NULL)
338 bdestroy(param);
339 if (value != NULL)
340 bdestroy(value);
343 /* ----------------------------------------------------------
344 * FUNCTION : bltrim
345 * DESCRIPTION : This function will trim the whitespace from
346 * : the left side of a string.
347 * INPUT : 0 - String
348 * ---------------------------------------------------------- */
349 int bltrim (bstring string)
351 int i;
352 int len = 0;
354 /* Find Whitespace */
355 for (i = 0; i < string->slen; i++) {
356 if (string->data[i] == ' ' || string->data[i] == '\t')
357 len++;
358 else
359 break;
362 /* Remove Whitespace */
363 if (len > 0)
364 bdelete(string, 0, len);
366 return 0;
369 /* ----------------------------------------------------------
370 * FUNCTION : brtrim
371 * DESCRIPTION : This function will trim the whitespace from
372 * : the right side of a string.
373 * INPUT : 0 - String
374 * ---------------------------------------------------------- */
375 int brtrim (bstring string)
377 int i;
378 int len = 0;
380 /* Find Whitespace */
381 for (i = (string->slen - 1); i > 0; i--) {
382 if (string->data[i] == ' ' || string->data[i] == '\t')
383 len++;
384 else
385 break;
388 /* Remove Whitespace */
389 if (len > 0)
390 bdelete(string, i + 1, len);
392 return 0;
395 /* Parse commandline and make conf reflect this */
396 int parse_args(globalconfig *conf, int argc, char *argv[], char *args)
398 int ch = 0;
399 while ((ch = getopt(argc, argv, args)) != -1) {
400 switch (ch) {
401 case 'a':
402 if(strlen(optarg) == 0)
403 conf->s_net = DEFAULT_NETS;
404 else
405 conf->s_net = strdup(optarg);
406 break;
407 case 'c':
408 // too late at this point
409 conf->file = optarg;
410 break;
411 case 'C':
412 conf->chroot_dir = strdup(optarg);
413 break;
414 case 'i':
415 conf->dev = optarg;
416 break;
417 case 'r':
418 conf->pcap_file = strdup(optarg);
419 break;
420 case 'b':
421 conf->bpff = strdup(optarg);
422 break;
423 case 'v':
424 conf->verbose++;
425 conf->cflags |= CONFIG_VERBOSE;
426 break;
427 case 'h':
428 return 1; // usage
429 break;
430 case 'D':
431 conf->daemon_flag = 1;
432 conf->cflags |= CONFIG_SYSLOG;
433 break;
434 case 'u':
435 conf->user_name = strdup(optarg);
436 conf->drop_privs_flag = 1;
437 break;
438 case 'g':
439 conf->group_name = strdup(optarg);
440 conf->drop_privs_flag = 1;
441 break;
442 case 'd':
443 conf->drop_privs_flag = 0;
444 break;
445 case 'p':
446 conf->pidfile = strdup(optarg);
447 break;
448 case 'l':
449 conf->assetlog = strdup(optarg);
450 break;
451 case 'f':
452 conf->fifo = strdup(optarg);
453 break;
454 case 's':
455 conf->payload = strtol(optarg, NULL, 0);
456 break;
457 case 'q':
458 conf->cflags |= CONFIG_QUIET;
459 break;
460 case 'O':
461 conf->cflags |= CONFIG_CONNECT;
462 break;
463 case 'Z':
464 conf->cflags |= CONFIG_PDNS;
465 break;
466 case 'x':
467 conf->cflags |= CONFIG_CXWRITE;
468 break;
469 case 'X':
470 conf->ctf = 0;
471 conf->cof = 0;
472 break;
473 case 'F':
474 conf->ctf |= CO_FIN;
475 break;
476 case 'R':
477 conf->ctf |= CO_RST;
478 break;
479 case 'M':
480 conf->cof |= CS_MAC;
481 conf->cof |= CS_ARP;
482 break;
483 case 'S':
484 conf->ctf |= CO_SYN;
485 break;
486 case 'A':
487 conf->ctf |= CO_ACK;
488 break;
489 case 'K':
490 conf->ctf |= CO_SYNACK;
491 break;
492 case 'U':
493 conf->cof |= CS_UDP_SERVICES;
494 break;
495 case 'T':
496 conf->cof |= CS_TCP_SERVER;
497 break;
498 case 'I':
499 conf->cof |= CS_ICMP;
500 break;
501 case 't':
502 conf->cof |= CS_TCP_CLIENT;
503 break;
504 case 'P':
505 case 'H':
506 olog("DHCP!!\n");
507 conf->ctf |= CO_DHCP;
508 break;
509 case 'L':
510 strcpy(conf->cxtlogdir,optarg);
511 break;
512 case '?':
513 elog("unrecognized argument: '%c'\n", optopt);
514 break;
515 default:
516 elog("Did not recognize argument '%c'\n", ch);
519 return 0;