1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 // Copyright (C) 2013-2013 Sourcefire, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License Version 2 as published
7 // by the Free Software Foundation. You may not use, modify or distribute
8 // this program under any other version of the GNU General Public License.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 //--------------------------------------------------------------------------
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "snort_config.h"
25
26 #include <grp.h>
27 #include <pwd.h>
28 #include <syslog.h>
29
30 #include "actions/ips_actions.h"
31 #include "detection/detect.h"
32 #include "detection/detection_engine.h"
33 #include "detection/fp_config.h"
34 #include "detection/fp_create.h"
35 #include "dump_config/json_config_output.h"
36 #include "dump_config/text_config_output.h"
37 #include "file_api/file_service.h"
38 #include "filters/detection_filter.h"
39 #include "filters/rate_filter.h"
40 #include "filters/sfrf.h"
41 #include "filters/sfthreshold.h"
42 #include "flow/ha_module.h"
43 #include "framework/policy_selector.h"
44 #include "hash/xhash.h"
45 #include "helpers/process.h"
46 #include "latency/latency_config.h"
47 #include "log/messages.h"
48 #include "managers/action_manager.h"
49 #include "managers/event_manager.h"
50 #include "managers/inspector_manager.h"
51 #include "managers/ips_manager.h"
52 #include "managers/module_manager.h"
53 #include "managers/mpse_manager.h"
54 #include "managers/plugin_manager.h"
55 #include "managers/so_manager.h"
56 #include "memory/memory_config.h"
57 #include "packet_io/sfdaq.h"
58 #include "packet_io/sfdaq_config.h"
59 #include "parser/parser.h"
60 #include "parser/vars.h"
61 #include "payload_injector/payload_injector_config.h"
62 #include "ports/rule_port_tables.h"
63 #include "profiler/profiler.h"
64 #include "protocols/packet.h"
65 #include "sfip/sf_ip.h"
66 #include "main/snort.h"
67 #include "target_based/host_attributes.h"
68 #include "target_based/snort_protocols.h"
69 #include "trace/trace_config.h"
70 #include "utils/dnet_header.h"
71 #include "utils/util.h"
72 #include "utils/util_cstring.h"
73
74 #include "analyzer.h"
75 #include "thread_config.h"
76
77 using namespace snort;
78
79 #define LOG_NONE "none"
80 #define LOG_DUMP "dump"
81 #define LOG_CODECS "codecs"
82
83 #define ALERT_NONE "none"
84 #define ALERT_CMG "cmg"
85 #define ALERT_JH "jh"
86 #define ALERT_DJR "djr"
87 #define ALERT_U2 "u2"
88 #define ALERT_AJK "ajk"
89
90 #define OUTPUT_U2 "unified2"
91 #define OUTPUT_FAST "alert_fast"
92
93 static THREAD_LOCAL const SnortConfig* snort_conf = nullptr;
94
95 uint32_t SnortConfig::warning_flags = 0;
96 uint32_t SnortConfig::logging_flags = 0;
97
98 static std::vector<ScratchAllocator*> scratch_handlers;
99
100 //-------------------------------------------------------------------------
101 // private implementation
102 //-------------------------------------------------------------------------
103
init_policy_mode(const SnortConfig * sc,PolicyMode mode)104 static PolicyMode init_policy_mode(const SnortConfig* sc, PolicyMode mode)
105 {
106 switch ( mode )
107 {
108 case POLICY_MODE__PASSIVE:
109 if ( sc->adaptor_inline_test_mode() )
110 return POLICY_MODE__INLINE_TEST;
111 break;
112
113 case POLICY_MODE__INLINE:
114 if ( sc->adaptor_inline_test_mode() )
115 return POLICY_MODE__INLINE_TEST;
116
117 else if (!sc->adaptor_inline_mode())
118 {
119 ParseWarning(WARN_DAQ, "adapter is in passive mode; switching policy mode to tap.");
120 return POLICY_MODE__PASSIVE;
121 }
122 break;
123
124 case POLICY_MODE__INLINE_TEST:
125 break;
126
127 case POLICY_MODE__MAX:
128 if ( sc->adaptor_inline_mode() )
129 return POLICY_MODE__INLINE;
130 else
131 return POLICY_MODE__PASSIVE;
132 break;
133 }
134 return mode;
135 }
136
init_policies(SnortConfig * sc)137 static void init_policies(SnortConfig* sc)
138 {
139 IpsPolicy* ips_policy = nullptr;
140 InspectionPolicy* inspection_policy = nullptr;
141
142 for ( unsigned idx = 0; idx < sc->policy_map->ips_policy_count(); ++idx )
143 {
144 ips_policy = sc->policy_map->get_ips_policy(idx);
145 ips_policy->policy_mode = init_policy_mode(sc, ips_policy->policy_mode);
146 }
147
148 for ( unsigned idx = 0; idx < sc->policy_map->inspection_policy_count(); ++idx )
149 {
150 inspection_policy = sc->policy_map->get_inspection_policy(idx);
151 inspection_policy->policy_mode = init_policy_mode(sc, inspection_policy->policy_mode);
152 }
153 }
154
init(const SnortConfig * const other_conf,ProtocolReference * protocol_reference,const char * exclude_name)155 void SnortConfig::init(const SnortConfig* const other_conf, ProtocolReference* protocol_reference,
156 const char* exclude_name)
157 {
158 homenet.clear();
159 obfuscation_net.clear();
160
161 if ( !other_conf )
162 {
163 num_layers = DEFAULT_LAYERMAX;
164
165 max_attribute_hosts = DEFAULT_MAX_ATTRIBUTE_HOSTS;
166 max_attribute_services_per_host = DEFAULT_MAX_ATTRIBUTE_SERVICES_PER_HOST;
167
168 max_metadata_services = DEFAULT_MAX_METADATA_SERVICES;
169
170 daq_config = new SFDAQConfig();
171 ActionManager::new_config(this);
172 InspectorManager::new_config(this);
173
174 num_slots = 0;
175 state = nullptr;
176
177 profiler = new ProfilerConfig;
178 latency = new LatencyConfig();
179 memory = new MemoryConfig();
180 policy_map = new PolicyMap;
181 thread_config = new ThreadConfig();
182
183 proto_ref = new ProtocolReference(protocol_reference);
184 so_rules = new SoRules;
185 trace_config = new TraceConfig;
186 }
187 else
188 {
189 clone(other_conf);
190 policy_map = new PolicyMap(other_conf->policy_map, exclude_name);
191 }
192 }
193
194 //-------------------------------------------------------------------------
195 // public methods
196 //-------------------------------------------------------------------------
197
198 /* A lot of this initialization can be skipped if not running in IDS mode
199 * but the goal is to minimize config checks at run time when running in
200 * IDS mode so we keep things simple and enforce that the only difference
201 * among run_modes is how we handle packets via the log_func. */
SnortConfig(const SnortConfig * const other_conf,const char * exclude_name)202 SnortConfig::SnortConfig(const SnortConfig* const other_conf, const char* exclude_name)
203 {
204 init(other_conf, nullptr, exclude_name);
205 }
206
207 // Copy the ProtocolReference data into the new SnortConfig.
SnortConfig(ProtocolReference * protocol_reference)208 SnortConfig::SnortConfig(ProtocolReference* protocol_reference)
209 {
210 init(nullptr, protocol_reference, nullptr);
211 }
212
~SnortConfig()213 SnortConfig::~SnortConfig()
214 {
215 if ( cloned )
216 {
217 policy_map->set_cloned(true);
218 delete policy_map;
219 return;
220 }
221
222 for ( auto ct : classifications )
223 delete ct.second;
224
225 for ( auto rs : references )
226 delete rs.second;
227
228 for ( auto* s : scratchers )
229 s->cleanup(this);
230
231 FreeRuleLists(this);
232 PortTablesFree(port_tables);
233
234 ThresholdConfigFree(threshold_config);
235 RateFilter_ConfigFree(rate_filter_config);
236 DetectionFilterConfigFree(detection_filter_config);
237
238 if ( event_queue_config )
239 EventQueueConfigFree(event_queue_config);
240
241 fpDeleteFastPacketDetection(this);
242 OtnLookupFree(otn_map);
243
244 delete rtn_hash_table;
245
246 if (eth_dst )
247 snort_free(eth_dst);
248
249 if ( fast_pattern_config &&
250 (!snort_conf || this == snort_conf ||
251 (fast_pattern_config->get_search_api() !=
252 get_conf()->fast_pattern_config->get_search_api())) )
253 {
254 MpseManager::stop_search_engine(fast_pattern_config->get_search_api());
255 }
256 delete fast_pattern_config;
257
258 delete policy_map;
259 InspectorManager::delete_config(this);
260 ActionManager::delete_config(this);
261
262 delete[] state;
263 delete thread_config;
264 delete trace_config;
265 delete overlay_trace_config;
266 delete ha_config;
267
268 delete profiler;
269 delete latency;
270 delete memory;
271 delete daq_config;
272 delete proto_ref;
273 delete[] evalOrder;
274 delete so_rules;
275 if ( plugins )
276 delete plugins;
277 delete payload_injector_config;
278 InspectorManager::free_flow_tracking(flow_tracking);
279 PolicySelector::free_policy_selector(global_selector);
280 clear_reload_resource_tuner_list();
281
282 trim_heap();
283 }
284
setup()285 void SnortConfig::setup()
286 {
287 if ( output_use_utc() )
288 thiszone = 0;
289
290 else
291 thiszone = gmt2local(0);
292
293 init_policies(this);
294 ParseRules(this);
295
296 // Allocate evalOrder before calling the OrderRuleLists
297 evalOrder = new int[Actions::get_max_types()]();
298
299 OrderRuleLists(this);
300
301 if ( rule_states )
302 {
303 rule_states->apply(this);
304 delete rule_states;
305 rule_states = nullptr;
306 }
307
308 ParseRulesFinish(this);
309 ShowPolicyStats(this);
310
311 /* Need to do this after dynamic detection stuff is initialized, too */
312 IpsManager::verify(this);
313 ModuleManager::load_commands(policy_map->get_shell());
314
315 fpCreateFastPacketDetection(this);
316 }
317
post_setup()318 void SnortConfig::post_setup()
319 {
320 unsigned int handler_count = scratch_handlers.size();
321
322 // Ensure we have allocated the scratch space vector for each thread
323 for ( unsigned i = 0; i < num_slots; ++i )
324 state[i].resize(handler_count);
325
326 for ( auto* s : scratch_handlers )
327 {
328 if ( s and s->setup(this) )
329 scratchers.push_back(s);
330 }
331 }
332
clone(const SnortConfig * const conf)333 void SnortConfig::clone(const SnortConfig* const conf)
334 {
335 *this = *conf;
336 if (conf->homenet.get_family() != 0)
337 memcpy(&homenet, &conf->homenet, sizeof(homenet));
338
339 if (conf->obfuscation_net.get_family() != 0)
340 memcpy(&obfuscation_net, &conf->obfuscation_net, sizeof(obfuscation_net));
341 }
342
343 // merge in everything from the command line config
merge(const SnortConfig * cmd_line_conf)344 void SnortConfig::merge(const SnortConfig* cmd_line_conf)
345 {
346 // -D / -H / -Q / -r / -T / -x / --alert-before-pass / --create-pidfile / --enable-inline-test / --mem-check /
347 // --nolock-pidfile / --pause / --pcap-file / --pcap-dir / --pcap-list / --pcap-show / --pedantic / --piglet /
348 // --shell / --show-file-codes
349 run_flags |= cmd_line_conf->run_flags;
350
351 // -A / -C / -d / -e / -f / -O / -U / -X / -y / --nostamps
352 output_flags |= cmd_line_conf->output_flags;
353
354 // -B
355 if (cmd_line_conf->obfuscation_net.get_family() != 0)
356 memcpy(&obfuscation_net, &cmd_line_conf->obfuscation_net, sizeof(obfuscation_net));
357
358 // -g
359 if (cmd_line_conf->group_id != -1)
360 group_id = cmd_line_conf->group_id;
361
362 // -G / --logid
363 event_log_id = cmd_line_conf->event_log_id;
364
365 // -i / -s / --daq / --daq-batch-size / --daq-dir / --daq-list / --daq-mode / --daq-var / --snaplen
366 daq_config->overlay(cmd_line_conf->daq_config);
367
368 // -k (only configures eval, not drop)
369 int cl_chk = cmd_line_conf->policy_map->get_network_policy()->checksum_eval;
370 if (!(cl_chk & CHECKSUM_FLAG__DEF))
371 {
372 for (unsigned idx = 0; idx < policy_map->network_policy_count(); ++idx)
373 {
374 NetworkPolicy* nw_policy = policy_map->get_network_policy(idx);
375 if (!(cl_chk & CHECKSUM_FLAG__DEF))
376 nw_policy->checksum_eval = cl_chk;
377 }
378 }
379
380 // -l
381 if ( !cmd_line_conf->log_dir.empty() )
382 log_dir = cmd_line_conf->log_dir;
383
384 // -L (output is only set by cmd_line_conf to override other conf output settings)
385 output = cmd_line_conf->output;
386
387 // -m
388 if (cmd_line_conf->file_mask != 0)
389 file_mask = cmd_line_conf->file_mask;
390
391 // -n
392 if (cmd_line_conf->pkt_cnt != 0)
393 pkt_cnt = cmd_line_conf->pkt_cnt;
394
395 // -t
396 if (!cmd_line_conf->chroot_dir.empty())
397 chroot_dir = cmd_line_conf->chroot_dir;
398
399 // -u
400 if (cmd_line_conf->user_id != -1)
401 user_id = cmd_line_conf->user_id;
402
403 // --bpf
404 if (!cmd_line_conf->bpf_filter.empty())
405 bpf_filter = cmd_line_conf->bpf_filter;
406
407 // --dirty-pig
408 if (cmd_line_conf->dirty_pig)
409 dirty_pig = cmd_line_conf->dirty_pig;
410
411 // --dump-rule-databases
412 if (!cmd_line_conf->rule_db_dir.empty())
413 rule_db_dir = cmd_line_conf->rule_db_dir;
414
415 // --id-offset
416 id_offset = cmd_line_conf->id_offset;
417 // --id-subdir
418 id_subdir = cmd_line_conf->id_subdir;
419 // --id-zero
420 id_zero = cmd_line_conf->id_zero;
421
422 // --include-path
423 include_path = cmd_line_conf->include_path;
424
425 // --metadata-filter
426 if (!cmd_line_conf->metadata_filter.empty())
427 metadata_filter = cmd_line_conf->metadata_filter;
428
429 // --pause-after-n
430 if (cmd_line_conf->pkt_pause_cnt != 0)
431 pkt_pause_cnt = cmd_line_conf->pkt_pause_cnt;
432
433 // --process-all-events
434 if (cmd_line_conf->run_flags & RUN_FLAG__PROCESS_ALL_EVENTS)
435 event_queue_config->process_all_events = 1;
436
437 // --run-prefix
438 run_prefix = cmd_line_conf->run_prefix;
439
440 // --skip
441 if (cmd_line_conf->pkt_skip != 0)
442 pkt_skip = cmd_line_conf->pkt_skip;
443
444 // --stdin-rules
445 stdin_rules = cmd_line_conf->stdin_rules;
446
447 #ifdef SHELL
448 // -j
449 if (cmd_line_conf->remote_control_port)
450 remote_control_port = cmd_line_conf->remote_control_port;
451 // --control-socket
452 else if (!cmd_line_conf->remote_control_socket.empty())
453 remote_control_socket = cmd_line_conf->remote_control_socket;
454 #endif
455
456 // Finalize the log directory, save a copy in case we need to chroot
457 if ( log_dir.empty() )
458 log_dir = DEFAULT_LOG_DIR;
459 orig_log_dir = log_dir;
460
461 // Initialize the slotted state memory for threads
462 assert(!state);
463 num_slots = offload_threads + ThreadConfig::get_instance_max();
464 state = new std::vector<void*>[num_slots];
465 }
466
verify() const467 bool SnortConfig::verify() const
468 {
469 bool config_ok = false;
470 const SnortConfig* sc = get_conf();
471
472 if ( sc->asn1_mem != asn1_mem )
473 ReloadError("Changing detection.asn1_mem requires a restart.\n");
474
475 else if ( sc->bpf_filter != bpf_filter )
476 ReloadError("Changing packets.bfp_filter requires a restart.\n");
477
478 else if ( sc->respond_attempts != respond_attempts )
479 ReloadError("Changing active.attempts requires a restart.\n");
480
481 else if ( sc->respond_device != respond_device )
482 ReloadError("Changing active.device requires a restart.\n");
483
484 else if (sc->chroot_dir != chroot_dir)
485 ReloadError("Changing process.chroot requires a restart.\n");
486
487 else if ((sc->run_flags & RUN_FLAG__DAEMON) != (run_flags & RUN_FLAG__DAEMON))
488 ReloadError("Changing process.daemon requires a restart.\n");
489
490 else if (sc->orig_log_dir != orig_log_dir)
491 ReloadError("Changing output.logdir requires a restart.\n");
492
493 else if (sc->group_id != group_id)
494 ReloadError("Changing process.setgid requires a restart.\n");
495
496 else if (sc->user_id != user_id)
497 ReloadError("Changing process.setuid requires a restart.\n");
498
499 else if (sc->daq_config->get_mru_size() != daq_config->get_mru_size())
500 ReloadError("Changing daq.snaplen requires a restart.\n");
501
502 else if (sc->threshold_config->memcap != threshold_config->memcap)
503 ReloadError("Changing alerts.event_filter_memcap requires a restart.\n");
504
505 else if (sc->rate_filter_config->memcap != rate_filter_config->memcap)
506 ReloadError("Changing alerts.rate_filter_memcap requires a restart.\n");
507
508 else if (sc->detection_filter_config->memcap != detection_filter_config->memcap)
509 ReloadError("Changing alerts.detection_filter_memcap requires a restart.\n");
510
511 else
512 config_ok = true;
513
514 return config_ok;
515 }
516
set_alert_before_pass(bool enabled)517 void SnortConfig::set_alert_before_pass(bool enabled)
518 {
519 if (enabled)
520 run_flags |= RUN_FLAG__ALERT_BEFORE_PASS;
521 else
522 run_flags &= ~RUN_FLAG__ALERT_BEFORE_PASS;
523 }
524
set_chroot_dir(const char * directory)525 void SnortConfig::set_chroot_dir(const char* directory)
526 {
527 if (directory)
528 chroot_dir = directory;
529 else
530 chroot_dir.clear();
531 }
532
set_create_pid_file(bool enabled)533 void SnortConfig::set_create_pid_file(bool enabled)
534 {
535 if (enabled)
536 run_flags |= RUN_FLAG__CREATE_PID_FILE;
537 else
538 run_flags &= ~RUN_FLAG__CREATE_PID_FILE;
539 }
540
set_daemon(bool enabled)541 void SnortConfig::set_daemon(bool enabled)
542 {
543 if (enabled)
544 {
545 run_flags |= RUN_FLAG__DAEMON;
546 }
547 else
548 run_flags &= ~RUN_FLAG__DAEMON;
549 }
550
set_decode_data_link(bool enabled)551 void SnortConfig::set_decode_data_link(bool enabled)
552 {
553 if (enabled)
554 {
555 output_flags |= OUTPUT_FLAG__SHOW_DATA_LINK;
556 }
557 else
558 output_flags &= ~OUTPUT_FLAG__SHOW_DATA_LINK;
559 }
560
set_dump_chars_only(bool enabled)561 void SnortConfig::set_dump_chars_only(bool enabled)
562 {
563 if (enabled)
564 {
565 /* dump the application layer as text only */
566 output_flags |= OUTPUT_FLAG__CHAR_DATA;
567 }
568 else
569 output_flags &= ~OUTPUT_FLAG__CHAR_DATA;
570 }
571
set_dump_payload(bool enabled)572 void SnortConfig::set_dump_payload(bool enabled)
573 {
574 if (enabled)
575 {
576 /* dump the application layer */
577 output_flags |= OUTPUT_FLAG__APP_DATA;
578 }
579 else
580 output_flags &= ~OUTPUT_FLAG__APP_DATA;
581 }
582
set_dump_payload_verbose(bool enabled)583 void SnortConfig::set_dump_payload_verbose(bool enabled)
584 {
585 if (enabled)
586 {
587 output_flags |= OUTPUT_FLAG__VERBOSE_DUMP;
588 }
589 else
590 output_flags &= ~OUTPUT_FLAG__VERBOSE_DUMP;
591 }
592
set_dst_mac(const char * mac_addr)593 void SnortConfig::set_dst_mac(const char* mac_addr)
594 {
595 if (mac_addr)
596 {
597 eth_addr_t dst;
598
599 if (eth_pton(mac_addr, &dst) < 0)
600 {
601 ParseError("Format check failed: %s, Use format like 12:34:56:78:90:1a", mac_addr);
602 return;
603 }
604 snort_free(eth_dst);
605 eth_dst = (uint8_t*)snort_calloc(sizeof(dst.data));
606 memcpy(eth_dst, dst.data, sizeof(dst.data));
607 }
608 else
609 {
610 snort_free(eth_dst);
611 eth_dst = nullptr;
612 }
613 }
614
set_log_dir(const char * directory)615 void SnortConfig::set_log_dir(const char* directory)
616 {
617 if (directory)
618 log_dir = directory;
619 else
620 log_dir.clear();
621 }
622
set_dirty_pig(bool enabled)623 void SnortConfig::set_dirty_pig(bool enabled)
624 {
625 dirty_pig = enabled;
626 }
627
set_obfuscate(bool enabled)628 void SnortConfig::set_obfuscate(bool enabled)
629 {
630 if (enabled)
631 output_flags |= OUTPUT_FLAG__OBFUSCATE;
632 else
633 output_flags &= ~OUTPUT_FLAG__OBFUSCATE;
634 }
635
set_no_logging_timestamps(bool enabled)636 void SnortConfig::set_no_logging_timestamps(bool enabled)
637 {
638 if (enabled)
639 output_flags |= OUTPUT_FLAG__NO_TIMESTAMP;
640 else
641 output_flags &= ~OUTPUT_FLAG__NO_TIMESTAMP;
642 }
643
set_obfuscation_mask(const char * mask)644 void SnortConfig::set_obfuscation_mask(const char* mask)
645 {
646 if (!mask)
647 return;
648
649 output_flags |= OUTPUT_FLAG__OBFUSCATE;
650
651 obfuscation_net.set(mask);
652 }
653
set_rule_db_dir(const char * directory)654 void SnortConfig::set_rule_db_dir(const char* directory)
655 {
656 assert(directory);
657 rule_db_dir = directory;
658 }
659
set_gid(const char * args)660 void SnortConfig::set_gid(const char* args)
661 {
662 struct group* gr;
663 long target_gid;
664 char* endptr;
665
666 if (!args)
667 return;
668
669 target_gid = SnortStrtol(args, &endptr, 10);
670 if (*endptr != '\0')
671 gr = getgrnam(args); // main thread only
672 else if (errno == ERANGE || target_gid < 0)
673 {
674 ParseError("group id '%s' out of range.", args);
675 return;
676 }
677 else
678 gr = getgrgid((gid_t)target_gid); // main thread only
679
680 if (!gr)
681 {
682 ParseError("group '%s' unknown.", args);
683 return;
684 }
685
686 /* If we're already running as the desired group ID, don't bother to try changing it later. */
687 if (gr->gr_gid != getgid())
688 group_id = (int)gr->gr_gid;
689 }
690
set_uid(const char * args)691 void SnortConfig::set_uid(const char* args)
692 {
693 struct passwd* pw;
694 long target_uid;
695 char* endptr;
696
697 if (!args)
698 return;
699
700 target_uid = SnortStrtol(args, &endptr, 10);
701 if (*endptr != '\0')
702 pw = getpwnam(args); // main thread only
703 else if (errno == ERANGE || target_uid < 0)
704 {
705 ParseError("user id '%s' out of range.", args);
706 return;
707 }
708 else
709 pw = getpwuid((uid_t)target_uid); // main thread only
710
711 if (!pw)
712 {
713 ParseError("user '%s' unknown.", args);
714 return;
715 }
716
717 /* Set group ID to user's default group if not already set.
718 If we're already running as the desired user and/or group ID,
719 don't bother to try changing it later. */
720 if (pw->pw_uid != getuid())
721 user_id = (int)pw->pw_uid;
722
723 if (group_id == -1 && pw->pw_gid != getgid())
724 group_id = (int)pw->pw_gid;
725 }
726
set_show_year(bool enabled)727 void SnortConfig::set_show_year(bool enabled)
728 {
729 if (enabled)
730 {
731 output_flags |= OUTPUT_FLAG__INCLUDE_YEAR;
732 }
733 else
734 output_flags &= ~OUTPUT_FLAG__INCLUDE_YEAR;
735 }
736
set_process_all_events(bool enabled)737 void SnortConfig::set_process_all_events(bool enabled)
738 {
739 if (enabled)
740 run_flags |= RUN_FLAG__PROCESS_ALL_EVENTS;
741 else
742 run_flags &= ~RUN_FLAG__PROCESS_ALL_EVENTS;
743 }
744
745 #ifdef ACCESSPERMS
746 # define FILE_ACCESS_BITS ACCESSPERMS
747 #else
748 # ifdef S_IAMB
749 # define FILE_ACCESS_BITS S_IAMB
750 # else
751 # define FILE_ACCESS_BITS 0x1FF
752 # endif
753 #endif
754
set_umask(uint32_t mask)755 void SnortConfig::set_umask(uint32_t mask)
756 {
757 file_mask = (mode_t)mask;
758 }
759
set_utc(bool enabled)760 void SnortConfig::set_utc(bool enabled)
761 {
762 if (enabled)
763 output_flags |= OUTPUT_FLAG__USE_UTC;
764 else
765 output_flags &= ~OUTPUT_FLAG__USE_UTC;
766 }
767
set_overlay_trace_config(TraceConfig * tc)768 void SnortConfig::set_overlay_trace_config(TraceConfig* tc)
769 {
770 delete overlay_trace_config;
771 overlay_trace_config = tc;
772 }
773
set_latency_enable()774 bool SnortConfig::set_latency_enable()
775 {
776 if (latency)
777 {
778 latency->packet_latency.force_enable = true;
779 return true;
780 }
781 return false;
782 }
783
set_tunnel_verdicts(const char * args)784 void SnortConfig::set_tunnel_verdicts(const char* args)
785 {
786 char* tmp, * tok;
787
788 tmp = snort_strdup(args);
789 char* lasts = nullptr;
790 tok = strtok_r(tmp, " ,", &lasts);
791
792 while (tok)
793 {
794 if (!strcasecmp(tok, "gtp"))
795 tunnel_mask |= TUNNEL_GTP;
796
797 else if (!strcasecmp(tok, "teredo"))
798 tunnel_mask |= TUNNEL_TEREDO;
799
800 else if (!strcasecmp(tok, "vxlan"))
801 tunnel_mask |= TUNNEL_VXLAN;
802
803 else if (!strcasecmp(tok, "6in4"))
804 tunnel_mask |= TUNNEL_6IN4;
805
806 else if (!strcasecmp(tok, "4in6"))
807 tunnel_mask |= TUNNEL_4IN6;
808
809 else if (!strcasecmp(tok, "4in4"))
810 tunnel_mask |= TUNNEL_4IN4;
811
812 else if (!strcasecmp(tok, "6in6"))
813 tunnel_mask |= TUNNEL_6IN6;
814
815 else if (!strcasecmp(tok, "gre"))
816 tunnel_mask |= TUNNEL_GRE;
817
818 else if (!strcasecmp(tok, "mpls"))
819 tunnel_mask |= TUNNEL_MPLS;
820
821 else if (!strcasecmp(tok, "geneve"))
822 tunnel_mask |= TUNNEL_GENEVE;
823
824 else
825 {
826 ParseError("unknown tunnel bypass protocol");
827 return;
828 }
829
830 tok = strtok_r(nullptr, " ,", &lasts);
831 }
832 snort_free(tmp);
833 }
834
set_include_path(const char * path)835 void SnortConfig::set_include_path(const char* path)
836 {
837 if (path)
838 include_path = path;
839 else
840 include_path.clear();
841 }
842
add_plugin_path(const char * path)843 void SnortConfig::add_plugin_path(const char* path)
844 {
845 if (!path)
846 return;
847
848 if (!plugin_path.empty())
849 plugin_path += ":" + std::string(path);
850 else
851 plugin_path = path;
852 }
853
set_tweaks(const char * t)854 void SnortConfig::set_tweaks(const char* t)
855 {
856 if (t)
857 tweaks = t;
858 else
859 tweaks.clear();
860 }
861
add_script_path(const char * path)862 void SnortConfig::add_script_path(const char* path)
863 {
864 if (path)
865 script_paths.emplace_back(path);
866 }
867
set_alert_mode(const char * val)868 void SnortConfig::set_alert_mode(const char* val)
869 {
870 if (strcasecmp(val, ALERT_NONE) == 0)
871 EventManager::enable_alerts(false);
872
873 else if ( !strcasecmp(val, ALERT_CMG) or !strcasecmp(val, ALERT_JH) or
874 !strcasecmp(val, ALERT_DJR) )
875 {
876 output = OUTPUT_FAST;
877 output_flags |= OUTPUT_FLAG__SHOW_DATA_LINK;
878 output_flags |= OUTPUT_FLAG__APP_DATA;
879 }
880 else if ( !strcasecmp(val, ALERT_U2) or !strcasecmp(val, ALERT_AJK) )
881 output = OUTPUT_U2;
882
883 else
884 output = val;
885
886 output_flags |= OUTPUT_FLAG__ALERTS;
887 Analyzer::set_main_hook(DetectionEngine::inspect);
888 }
889
set_log_mode(const char * val)890 void SnortConfig::set_log_mode(const char* val)
891 {
892 if (strcasecmp(val, LOG_NONE) == 0)
893 {
894 Analyzer::set_main_hook(snort_ignore);
895 EventManager::enable_logs(false);
896 }
897 else
898 {
899 if ( !strcmp(val, LOG_DUMP) )
900 val = LOG_CODECS;
901 output = val;
902 Analyzer::set_main_hook(snort_log);
903 }
904 }
905
enable_syslog()906 void SnortConfig::enable_syslog()
907 {
908 static bool syslog_configured = false;
909
910 if (syslog_configured)
911 return;
912
913 openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON);
914
915 enable_log_syslog();
916 syslog_configured = true;
917 }
918
get_default_rule_state() const919 bool SnortConfig::get_default_rule_state() const
920 {
921 switch ( get_ips_policy()->default_rule_state )
922 {
923 case IpsPolicy::INHERIT_ENABLE:
924 return global_default_rule_state;
925
926 case IpsPolicy::ENABLED:
927 return true;
928
929 case IpsPolicy::DISABLED:
930 return false;
931 }
932 return true;
933 }
934
create_config_output() const935 ConfigOutput* SnortConfig::create_config_output() const
936 {
937 ConfigOutput* output = nullptr;
938
939 switch (dump_config_type)
940 {
941 case DUMP_CONFIG_JSON_ALL:
942 output = new JsonAllConfigOutput();
943 break;
944 case DUMP_CONFIG_JSON_TOP:
945 output = new JsonTopConfigOutput();
946 break;
947 case DUMP_CONFIG_TEXT:
948 output = new TextConfigOutput();
949 break;
950 default:
951 break;
952 }
953
954 return output;
955 }
956
tunnel_bypass_enabled(uint16_t proto) const957 bool SnortConfig::tunnel_bypass_enabled(uint16_t proto) const
958 {
959 return !((tunnel_mask & proto) or SFDAQ::get_tunnel_bypass(proto));
960 }
961
request_scratch(ScratchAllocator * s)962 int SnortConfig::request_scratch(ScratchAllocator* s)
963 {
964 scratch_handlers.emplace_back(s);
965
966 // We return an index that the caller uses to reference their per thread
967 // scratch space
968 return scratch_handlers.size() - 1;
969 }
970
release_scratch(int id)971 void SnortConfig::release_scratch(int id)
972 {
973 assert((unsigned)id < scratch_handlers.size());
974 scratch_handlers[id] = nullptr;
975 }
976
get_main_conf()977 SnortConfig* SnortConfig::get_main_conf()
978 { return const_cast<SnortConfig*>(snort_conf); }
979
get_conf()980 const SnortConfig* SnortConfig::get_conf()
981 { return snort_conf; }
982
set_conf(const SnortConfig * sc)983 void SnortConfig::set_conf(const SnortConfig* sc)
984 {
985 snort_conf = sc;
986
987 if ( sc )
988 {
989 Shell* sh = sc->policy_map->get_shell(0);
990 if (sc->policy_map->get_policies(sh))
991 set_policies(sc, sh);
992 }
993 }
994
register_reload_resource_tuner(ReloadResourceTuner * rrt)995 void SnortConfig::register_reload_resource_tuner(ReloadResourceTuner* rrt)
996 {
997 if (Snort::is_reloading())
998 reload_tuners.push_back(rrt);
999 else
1000 delete rrt;
1001 }
1002
clear_reload_resource_tuner_list()1003 void SnortConfig::clear_reload_resource_tuner_list()
1004 {
1005 for (ReloadResourceTuner* rrt : reload_tuners)
1006 delete rrt;
1007 reload_tuners.clear();
1008 }
1009
update_reload_id()1010 void SnortConfig::update_reload_id()
1011 {
1012 static unsigned reload_id_tracker = 0;
1013 reload_id = ++reload_id_tracker;
1014 }
1015
cleanup_fatal_error()1016 void SnortConfig::cleanup_fatal_error()
1017 {
1018 // FIXIT-L need a generic way to manage type other threads
1019 // and preferably not start them too soon
1020 FileService::close();
1021
1022 #ifdef REG_TEST
1023 const SnortConfig* sc = SnortConfig::get_conf();
1024 if ( sc && !sc->dirty_pig )
1025 {
1026 ModuleManager::term();
1027 EventManager::release_plugins();
1028 IpsManager::release_plugins();
1029 InspectorManager::release_plugins();
1030 }
1031 #endif
1032 }
1033
1034