1 /* $Id$ */
2 /*
3 ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
4 ** Copyright (C) 2002-2013 Sourcefire, Inc.
5 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License Version 2 as
9 ** published by the Free Software Foundation.  You may not use, modify or
10 ** distribute this program under any other version of the GNU General
11 ** Public License.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; if not, write to the Free Software
20 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <sys/types.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #ifdef HAVE_STRINGS_H
33 #include <strings.h>
34 #endif
35 
36 #ifndef WIN32
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #endif /* !WIN32 */
41 #include <time.h>
42 #include <errno.h>
43 
44 #include "sf_types.h"
45 #include "plugbase.h"
46 #include "spo_plugbase.h"
47 #include "snort.h"
48 #include "snort_debug.h"
49 #include "util.h"
50 #include "log.h"
51 #include "detect.h"
52 
53 /* built-in preprocessors */
54 #include "preprocessors/spp_rpc_decode.h"
55 #include "preprocessors/spp_bo.h"
56 #include "preprocessors/spp_session.h"
57 #include "preprocessors/spp_stream6.h"
58 #include "preprocessors/spp_arpspoof.h"
59 #include "preprocessors/spp_perfmonitor.h"
60 #include "preprocessors/spp_httpinspect.h"
61 #include "preprocessors/spp_sfportscan.h"
62 #include "preprocessors/spp_frag3.h"
63 #include "preprocessors/spp_normalize.h"
64 
65 /* built-in detection plugins */
66 #include "detection-plugins/sp_pattern_match.h"
67 #include "detection-plugins/sp_tcp_flag_check.h"
68 #include "detection-plugins/sp_icmp_type_check.h"
69 #include "detection-plugins/sp_icmp_code_check.h"
70 #include "detection-plugins/sp_ttl_check.h"
71 #include "detection-plugins/sp_ip_id_check.h"
72 #include "detection-plugins/sp_tcp_ack_check.h"
73 #include "detection-plugins/sp_tcp_seq_check.h"
74 #include "detection-plugins/sp_dsize_check.h"
75 #include "detection-plugins/sp_ipoption_check.h"
76 #include "detection-plugins/sp_rpc_check.h"
77 #include "detection-plugins/sp_icmp_id_check.h"
78 #include "detection-plugins/sp_icmp_seq_check.h"
79 #include "detection-plugins/sp_session.h"
80 #include "detection-plugins/sp_ip_tos_check.h"
81 #include "detection-plugins/sp_ip_fragbits.h"
82 #include "detection-plugins/sp_tcp_win_check.h"
83 #include "detection-plugins/sp_ip_same_check.h"
84 #include "detection-plugins/sp_ip_proto.h"
85 #include "detection-plugins/sp_ip_same_check.h"
86 #include "detection-plugins/sp_clientserver.h"
87 #include "detection-plugins/sp_byte_check.h"
88 #include "detection-plugins/sp_byte_jump.h"
89 #include "detection-plugins/sp_byte_extract.h"
90 #include "detection-plugins/sp_byte_math.h"
91 #include "detection-plugins/sp_isdataat.h"
92 #include "detection-plugins/sp_pcre.h"
93 #include "detection-plugins/sp_flowbits.h"
94 #include "detection-plugins/sp_file_data.h"
95 #include "detection-plugins/sp_base64_decode.h"
96 #include "detection-plugins/sp_base64_data.h"
97 #include "detection-plugins/sp_pkt_data.h"
98 #include "detection-plugins/sp_asn1.h"
99 
100 #ifdef ENABLE_REACT
101 #include "detection-plugins/sp_react.h"
102 #endif
103 
104 #ifdef ENABLE_RESPOND
105 #include "detection-plugins/sp_respond.h"
106 #endif
107 
108 #include "detection-plugins/sp_ftpbounce.h"
109 #include "detection-plugins/sp_urilen_check.h"
110 #include "detection-plugins/sp_cvs.h"
111 #include "detection-plugins/sp_file_type.h"
112 
113 #if defined(FEAT_OPEN_APPID)
114 #include "detection-plugins/sp_appid.h"
115 #endif /* defined(FEAT_OPEN_APPID) */
116 
117 /* built-in output plugins */
118 #include "output-plugins/spo_alert_syslog.h"
119 #include "output-plugins/spo_log_tcpdump.h"
120 #include "output-plugins/spo_alert_fast.h"
121 #include "output-plugins/spo_alert_full.h"
122 #include "output-plugins/spo_alert_unixsock.h"
123 #include "output-plugins/spo_csv.h"
124 #include "output-plugins/spo_log_null.h"
125 #include "output-plugins/spo_log_ascii.h"
126 #include "output-plugins/spo_unified2.h"
127 
128 #ifdef DUMP_BUFFER
129 #include "output-plugins/spo_log_buffer_dump.h"
130 #endif
131 
132 #ifdef LINUX
133 #include "output-plugins/spo_alert_sf_socket.h"
134 #endif
135 
136 #include "output-plugins/spo_alert_test.h"
137 
138 extern ListHead *head_tmp;
139 extern PreprocConfigFuncNode *preproc_config_funcs;
140 extern OutputConfigFuncNode *output_config_funcs;
141 extern RuleOptConfigFuncNode *rule_opt_config_funcs;
142 extern RuleOptOverrideInitFuncNode *rule_opt_override_init_funcs;
143 extern RuleOptParseCleanupNode *rule_opt_parse_cleanup_list;
144 extern RuleOptByteOrderFuncNode *rule_opt_byte_order_funcs;
145 extern PreprocSignalFuncNode *preproc_clean_exit_funcs;
146 extern PreprocSignalFuncNode *preproc_shutdown_funcs;
147 extern PreprocSignalFuncNode *preproc_reset_funcs;
148 extern PreprocSignalFuncNode *preproc_reset_stats_funcs;
149 extern PreprocStatsFuncNode *preproc_stats_funcs;
150 extern PluginSignalFuncNode *plugin_shutdown_funcs;
151 extern PluginSignalFuncNode *plugin_clean_exit_funcs;
152 extern OutputFuncNode *AlertList;
153 extern OutputFuncNode *LogList;
154 
155 /**************************** Detection Plugin API ****************************/
156 /* For translation from enum to char* */
157 #ifdef DEBUG_MSGS
158 static const char *optTypeMap[OPT_TYPE_MAX] =
159 {
160     "action",
161     "logging",
162     "detection"
163 };
164 
165 #define ENUM2STR(num, map) \
166     ((num < sizeof(map)/sizeof(map[0])) ? map[num] : "undefined")
167 #endif
168 
169 static GetHttpXffFieldsFunc getHttpXffFieldsFunc = NULL;
170 
RegisterRuleOptions(void)171 void RegisterRuleOptions(void)
172 {
173     LogMessage("Initializing Plug-ins!\n");
174 
175     SetupPatternMatch();
176     SetupTCPFlagCheck();
177     SetupIcmpTypeCheck();
178     SetupIcmpCodeCheck();
179     SetupTtlCheck();
180     SetupIpIdCheck();
181     SetupTcpAckCheck();
182     SetupTcpSeqCheck();
183     SetupDsizeCheck();
184     SetupIpOptionCheck();
185     SetupRpcCheck();
186     SetupIcmpIdCheck();
187     SetupIcmpSeqCheck();
188     SetupSession();
189     SetupIpTosCheck();
190     SetupFragBits();
191     SetupFragOffset();
192     SetupTcpWinCheck();
193     SetupIpProto();
194     SetupIpSameCheck();
195     SetupClientServer();
196     SetupPktData();
197     SetupByteTest();
198     SetupByteJump();
199     SetupByteExtract();
200     SetupByteMath();
201     SetupIsDataAt();
202     SetupFileData();
203     SetupBase64Decode();
204     SetupBase64Data();
205     SetupPcre();
206     SetupFlowBits();
207     SetupAsn1();
208 #ifdef ENABLE_REACT
209     SetupReact();
210 #endif
211 #ifdef ENABLE_RESPOND
212     SetupRespond();
213 #endif
214     SetupFTPBounce();
215     SetupUriLenCheck();
216     SetupCvs();
217     SetupFileType();
218 #if defined(FEAT_OPEN_APPID)
219     SetupAppId();
220 #endif /* defined(FEAT_OPEN_APPID) */
221 }
222 
223 /****************************************************************************
224  *
225  * Function: RegisterRuleOption(char *, void (*func)(), enum OptionType)
226  *
227  * Purpose:  Associates a rule option keyword with an option setup/linking
228  *           function.
229  *
230  * Arguments: keyword => The option keyword to associate with the option
231  *                       handler
232  *            *func => function pointer to the handler
233  *            type => used to determine where keyword is allowed
234  *
235  * Returns: void function
236  *
237  ***************************************************************************/
RegisterRuleOption(char * opt_name,RuleOptConfigFunc ro_config_func,RuleOptOverrideInitFunc override_init_func,RuleOptType opt_type,RuleOptOtnHandler otn_handler)238 void RegisterRuleOption(char *opt_name, RuleOptConfigFunc ro_config_func,
239                         RuleOptOverrideInitFunc override_init_func,
240                         RuleOptType opt_type,
241                         RuleOptOtnHandler otn_handler)
242 {
243     RuleOptConfigFuncNode *node;
244 
245     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Registering keyword:func => %s/%s:%p\n",
246                             ENUM2STR(opt_type, optTypeMap), opt_name, ro_config_func););
247 
248     node = (RuleOptConfigFuncNode *)SnortAlloc(sizeof(RuleOptConfigFuncNode));
249 
250     if (rule_opt_config_funcs == NULL)
251     {
252         rule_opt_config_funcs = node;
253     }
254     else
255     {
256         RuleOptConfigFuncNode *tmp = rule_opt_config_funcs;
257         RuleOptConfigFuncNode *last;
258 
259         do
260         {
261             if (strcasecmp(tmp->keyword, opt_name) == 0)
262             {
263                 free(node);
264                 FatalError("%s(%d) Duplicate detection plugin keyword: %s.\n",
265                            file_name, file_line, opt_name);
266             }
267 
268             last = tmp;
269             tmp = tmp->next;
270 
271         } while (tmp != NULL);
272 
273         last->next = node;
274     }
275 
276     node->keyword = SnortStrdup(opt_name);
277     node->type = opt_type;
278     node->func = ro_config_func;
279     node->otn_handler = otn_handler;
280 
281     if (override_init_func != NULL)
282     {
283         RuleOptOverrideInitFuncNode *node_override =
284             (RuleOptOverrideInitFuncNode *)SnortAlloc(sizeof(RuleOptOverrideInitFuncNode));
285 
286         if (rule_opt_override_init_funcs == NULL)
287         {
288             rule_opt_override_init_funcs = node_override;
289         }
290         else
291         {
292             RuleOptOverrideInitFuncNode *tmp = rule_opt_override_init_funcs;
293             RuleOptOverrideInitFuncNode *last;
294 
295             do
296             {
297                 if (strcasecmp(tmp->keyword, opt_name) == 0)
298                 {
299                     free(node_override);
300                     FatalError("RegisterRuleOption: Duplicate detection plugin keyword:"
301                             " (%s) (%s)!\n", tmp->keyword, opt_name);
302                 }
303 
304                 last = tmp;
305                 tmp = tmp->next;
306 
307             } while (tmp != NULL);
308 
309             last->next = node_override;
310         }
311 
312         node_override->keyword = SnortStrdup(opt_name);
313         node_override->type = opt_type;
314         node_override->func = override_init_func;
315         node_override->otn_handler = otn_handler;
316     }
317 }
318 
RegisterOverrideKeyword(char * keyword,char * option,RuleOptOverrideFunc roo_func)319 void RegisterOverrideKeyword(char *keyword, char *option, RuleOptOverrideFunc roo_func)
320 {
321     RuleOptOverrideInitFuncNode *node = rule_opt_override_init_funcs;
322 
323     while (node != NULL)
324     {
325         if (strcasecmp(node->keyword, keyword) == 0)
326         {
327             node->func(keyword, option, roo_func);
328             break;
329         }
330 
331         node = node->next;
332     }
333 }
334 
RegisterByteOrderKeyword(char * keyword,RuleOptByteOrderFunc roo_func)335 void RegisterByteOrderKeyword(char *keyword, RuleOptByteOrderFunc roo_func)
336 {
337     RuleOptByteOrderFuncNode *node = (RuleOptByteOrderFuncNode *)SnortAlloc(sizeof(RuleOptByteOrderFuncNode));
338     RuleOptByteOrderFuncNode *list = rule_opt_byte_order_funcs;
339     RuleOptByteOrderFuncNode *last;
340 
341     node->keyword = SnortStrdup(keyword);
342     node->func = roo_func;
343     node->next = NULL;
344 
345     if (list == NULL)
346         rule_opt_byte_order_funcs = node;
347     else
348     {
349         while (list != NULL)
350         {
351             if (strcasecmp(node->keyword, list->keyword) == 0)
352             {
353                 free(node->keyword);
354                 free(node);
355                 return;
356             }
357 
358             last = list;
359             list = list->next;
360         }
361 
362         last->next = node;
363     }
364 }
365 
GetByteOrderFunc(char * keyword)366 RuleOptByteOrderFunc GetByteOrderFunc(char *keyword)
367 {
368     RuleOptByteOrderFuncNode *node = rule_opt_byte_order_funcs;
369 
370     while (node != NULL)
371     {
372         if (strcasecmp(keyword, node->keyword) == 0)
373             return node->func;
374 
375         node = node->next;
376     }
377 
378     return NULL;
379 }
380 
381 /****************************************************************************
382  *
383  * Function: DumpPlugIns()
384  *
385  * Purpose:  Prints the keyword->function list
386  *
387  * Arguments: None.
388  *
389  * Returns: void function
390  *
391  ***************************************************************************/
DumpRuleOptions(void)392 void DumpRuleOptions(void)
393 {
394     RuleOptConfigFuncNode *node;
395 
396     node = rule_opt_config_funcs;
397 
398     LogMessage("-------------------------------------------------\n");
399     LogMessage(" Keyword     |      Plugin Registered @\n");
400     LogMessage("-------------------------------------------------\n");
401 
402     while (node != NULL)
403     {
404         LogMessage("%-13s:      %p\n", node->keyword, (void *)node->vfunc);
405         node = node->next;
406     }
407 
408     LogMessage("-------------------------------------------------\n");
409     LogMessage("\n");
410 }
411 
412 
413 /****************************************************************************
414  *
415  * Function: AddOptFuncToList(int (*func)(), OptTreeNode *)
416  *
417  * Purpose: Links the option detection module to the OTN
418  *
419  * Arguments: (*func)() => function pointer to the detection module
420  *            otn =>  pointer to the current OptTreeNode
421  *
422  * Returns: void function
423  *
424  ***************************************************************************/
AddOptFuncToList(RuleOptEvalFunc ro_eval_func,OptTreeNode * otn)425 OptFpList * AddOptFuncToList(RuleOptEvalFunc ro_eval_func, OptTreeNode *otn)
426 {
427     OptFpList *ofp = (OptFpList *)SnortAlloc(sizeof(OptFpList));
428 
429     DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding new rule to list\n"););
430 
431     /* if there are no nodes on the function list... */
432     if (otn->opt_func == NULL)
433     {
434         otn->opt_func = ofp;
435     }
436     else
437     {
438         OptFpList *tmp = otn->opt_func;
439 
440         /* walk to the end of the list */
441         while (tmp->next != NULL)
442             tmp = tmp->next;
443 
444         tmp->next = ofp;
445     }
446 
447     DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set OptTestFunc to %p\n", ro_eval_func););
448 
449     ofp->OptTestFunc = ro_eval_func;
450 
451     return ofp;
452 }
453 
454 /****************************************************************************
455  *
456  * Function: AddRspFuncToList(int (*func)(), OptTreeNode *)
457  *
458  * Purpose: Adds Response function to OTN
459  *
460  * Arguments: (*func)() => function pointer to the response module
461  *            otn =>  pointer to the current OptTreeNode
462  *
463  * Returns: void function
464  *
465  ***************************************************************************/
466 // TBD this can prolly be replaced with a single item
467 // because we allow at most one response per packet
AddRspFuncToList(ResponseFunc resp_func,OptTreeNode * otn,void * params)468 void AddRspFuncToList(ResponseFunc resp_func, OptTreeNode *otn, void *params)
469 {
470     RspFpList *rsp = (RspFpList *)SnortAlloc(sizeof(RspFpList));
471 
472     DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding response to list\n"););
473 
474     /* if there are no nodes on the function list... */
475     if (otn->rsp_func == NULL)
476     {
477         otn->rsp_func = rsp;
478     }
479     else
480     {
481         RspFpList *tmp = otn->rsp_func;
482 
483         /* walk to the end of the list */
484         while (tmp->next != NULL)
485             tmp = tmp->next;
486 
487         tmp->next = rsp;
488     }
489 
490     DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set ResponseFunc to %p\n", resp_func););
491 
492     rsp->func = resp_func;
493     rsp->params = params;
494 }
495 
PostConfigInitPlugins(struct _SnortConfig * sc,PostConfigFuncNode * post_config_funcs)496 void PostConfigInitPlugins(struct _SnortConfig *sc, PostConfigFuncNode *post_config_funcs)
497 {
498     while (post_config_funcs != NULL)
499     {
500         post_config_funcs->func(sc, 0, post_config_funcs->arg);
501         post_config_funcs = post_config_funcs->next;
502     }
503 }
504 
FreeRuleOptConfigFuncs(RuleOptConfigFuncNode * head)505 void FreeRuleOptConfigFuncs(RuleOptConfigFuncNode *head)
506 {
507 
508     while (head != NULL)
509     {
510         RuleOptConfigFuncNode *tmp = head;
511 
512         head = head->next;
513 
514         if (tmp->keyword != NULL)
515             free(tmp->keyword);
516 
517         free(tmp);
518     }
519 }
520 
FreeRuleOptOverrideInitFuncs(RuleOptOverrideInitFuncNode * head)521 void FreeRuleOptOverrideInitFuncs(RuleOptOverrideInitFuncNode *head)
522 {
523 
524     while (head != NULL)
525     {
526         RuleOptOverrideInitFuncNode *tmp = head;
527 
528         head = head->next;
529 
530         if (tmp->keyword != NULL)
531             free(tmp->keyword);
532 
533         free(tmp);
534     }
535 }
536 
FreeRuleOptByteOrderFuncs(RuleOptByteOrderFuncNode * head)537 void FreeRuleOptByteOrderFuncs(RuleOptByteOrderFuncNode *head)
538 {
539     while (head != NULL)
540     {
541         RuleOptByteOrderFuncNode *tmp = head;
542 
543         head = head->next;
544 
545         if (tmp->keyword != NULL)
546             free(tmp->keyword);
547 
548         free(tmp);
549     }
550 }
551 
FreePluginSigFuncs(PluginSignalFuncNode * head)552 void FreePluginSigFuncs(PluginSignalFuncNode *head)
553 {
554     while (head != NULL)
555     {
556         PluginSignalFuncNode *tmp = head;
557 
558         head = head->next;
559 
560         /* don't free sig->arg, that's free'd by the CleanExit func */
561         free(tmp);
562     }
563 }
564 
FreePluginPostConfigFuncs(PostConfigFuncNode * head)565 void FreePluginPostConfigFuncs(PostConfigFuncNode *head)
566 {
567     while (head != NULL)
568     {
569         PostConfigFuncNode *tmp = head;
570 
571         head = head->next;
572 
573         /* don't free sig->arg, that's free'd by the CleanExit func */
574         free(tmp);
575     }
576 }
577 
578 /************************** Non Rule Detection Plugin API *********************/
AddFuncToDetectionList(SnortConfig * sc,DetectionEvalFunc detect_eval_func,uint16_t priority,uint32_t detect_id,uint32_t proto_mask)579 DetectionEvalFuncNode * AddFuncToDetectionList(SnortConfig *sc,
580                                             DetectionEvalFunc detect_eval_func,
581                                             uint16_t priority, uint32_t detect_id,
582                                             uint32_t proto_mask)
583 {
584     DetectionEvalFuncNode *node;
585     tSfPolicyId policy_id = getParserPolicy(sc);
586     SnortPolicy *p;
587 
588     if (sc == NULL)
589     {
590         FatalError("%s(%d) Snort config for parsing is NULL.\n",
591                    __FILE__, __LINE__);
592     }
593 
594     p = sc->targeted_policies[policy_id];
595     if (p == NULL)
596         return NULL;
597 
598     DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,
599                             "Adding detection function ID %d/bit %d/pri %d to list\n",
600                             detect_id, p->num_detects, priority););
601 
602     node = (DetectionEvalFuncNode *)SnortAlloc(sizeof(DetectionEvalFuncNode));
603 
604     if (p->detect_eval_funcs == NULL)
605     {
606         p->detect_eval_funcs = node;
607     }
608     else
609     {
610         DetectionEvalFuncNode *tmp = p->detect_eval_funcs;
611         DetectionEvalFuncNode *last = NULL;
612 
613         do
614         {
615             if (tmp->detect_id == detect_id)
616             {
617                 free(node);
618                 FatalError("Detection function already registered with ID %d\n",
619                            detect_id);
620             }
621 
622             /* Insert higher priority preprocessors first.  Lower priority
623              * number means higher priority */
624             if (priority < tmp->priority)
625                 break;
626 
627             last = tmp;
628             tmp = tmp->next;
629 
630         } while (tmp != NULL);
631 
632         /* Priority higher than first item in list */
633         if (last == NULL)
634         {
635             node->next = tmp;
636             p->detect_eval_funcs = node;
637         }
638         else
639         {
640             node->next = tmp;
641             last->next = node;
642         }
643     }
644 
645     node->func = detect_eval_func;
646     node->priority = priority;
647     node->detect_id = detect_id;
648     //node->detect_bit = (1 << detect_id);
649     node->proto_mask = proto_mask;
650 
651     p->num_detects++;
652     p->detect_proto_mask |= proto_mask;
653     //p->detect_bit_mask |= node->detect_bit;
654 
655     return node;
656 }
657 
FreeDetectionEvalFuncs(DetectionEvalFuncNode * head)658 void FreeDetectionEvalFuncs(DetectionEvalFuncNode *head)
659 {
660     DetectionEvalFuncNode *tmp;
661 
662     while (head != NULL)
663     {
664         tmp = head->next;
665         //if (head->context)
666         //    free(head->context);
667         free(head);
668         head = tmp;
669     }
670 }
671 
672 /************************** Buffer Dump Plugin API ***************************/
673 #ifdef DUMP_BUFFER
RegisterBufferTracer(TraceBuffer * (* bdfunc)(),BUFFER_DUMP_FUNC type)674 void RegisterBufferTracer(TraceBuffer *(*bdfunc)(), BUFFER_DUMP_FUNC type)
675 {
676     getBuffers[type] = bdfunc;
677     bdmask |= (UINT64_C(1) << type);
678 }
679 #endif
680 
681 /************************** Preprocessor Plugin API ***************************/
682 static void AddFuncToPreprocSignalList(PreprocSignalFunc, void *,
683                                        PreprocSignalFuncNode **, uint16_t, uint32_t);
684 
685 
RegisterPreprocessors(void)686 void RegisterPreprocessors(void)
687 {
688     LogMessage("Initializing Preprocessors!\n");
689 
690     SetupARPspoof();
691 #ifdef NORMALIZER
692     SetupNormalizer();
693 #endif
694     SetupFrag3();
695     SetupSessionManager();
696     SetupStream6();
697     SetupRpcDecode();
698     SetupBo();
699     SetupHttpInspect();
700     SetupPerfMonitor();
701     SetupSfPortscan();
702 }
703 
704 /****************************************************************************
705  *
706  * Function: RegisterPreprocessor(char *, void (*)(char *))
707  *
708  * Purpose:  Associates a preprocessor statement with its function.
709  *
710  * Arguments: keyword => The option keyword to associate with the
711  *                       preprocessor
712  *            *func => function pointer to the handler
713  *
714  * Returns: void function
715  *
716  ***************************************************************************/
717 #ifndef SNORT_RELOAD
RegisterPreprocessor(const char * keyword,PreprocConfigFunc pp_config_func)718 void RegisterPreprocessor(const char *keyword, PreprocConfigFunc pp_config_func)
719 #else
720 void RegisterPreprocessor(const char *keyword, PreprocConfigFunc pp_config_func,
721                           PreprocReloadFunc rfunc, PreprocReloadVerifyFunc rvfunc,
722                           PreprocReloadSwapFunc sfunc, PreprocReloadSwapFreeFunc ffunc)
723 #endif
724 {
725     PreprocConfigFuncNode *node =
726         (PreprocConfigFuncNode *)SnortAlloc(sizeof(PreprocConfigFuncNode));
727 
728     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:preproc => %s:%p\n", keyword, pp_config_func););
729 
730     if (preproc_config_funcs == NULL)
731     {
732         preproc_config_funcs = node;
733     }
734     else
735     {
736         PreprocConfigFuncNode *tmp = preproc_config_funcs;
737         PreprocConfigFuncNode *last;
738 
739         do
740         {
741             if (strcasecmp(tmp->keyword, keyword) == 0)
742             {
743                 free(node);
744                 FatalError("Duplicate preprocessor keyword: %s.\n", keyword);
745             }
746 
747             last = tmp;
748             tmp = tmp->next;
749 
750         } while (tmp != NULL);
751 
752         last->next = node;
753     }
754 
755     node->keyword = SnortStrdup(keyword);
756     node->config_func = pp_config_func;
757 
758 #ifdef SNORT_RELOAD
759     node->reload_func = rfunc;
760     node->reload_verify_func = rvfunc;
761     node->reload_swap_func = sfunc;
762     node->reload_swap_free_func = ffunc;
763 #endif
764 }
765 
766 #ifdef SNORT_RELOAD
GetRelatedReloadData(SnortConfig * sc,const char * keyword)767 void *GetRelatedReloadData(SnortConfig *sc, const char *keyword)
768 {
769     PreprocessorSwapData *swapData;
770     for (swapData = sc->preprocSwapData; swapData; swapData = swapData->next)
771     {
772         if (swapData->preprocNode && swapData->preprocNode->keyword &&
773             strcasecmp(swapData->preprocNode->keyword, keyword) == 0)
774         {
775             return swapData->data;
776         }
777     }
778     return NULL;
779 }
780 
GetReloadStreamConfig(SnortConfig * sc)781 void *GetReloadStreamConfig(SnortConfig *sc)
782 {
783     return sc->streamReloadConfig;
784 }
785 #endif
786 
GetPreprocConfig(char * keyword)787 PreprocConfigFuncNode * GetPreprocConfig(char *keyword)
788 {
789     PreprocConfigFuncNode *head = preproc_config_funcs;
790 
791     if (keyword == NULL)
792         return NULL;
793 
794     while (head != NULL)
795     {
796         if (strcasecmp(head->keyword, keyword) == 0)
797            return head;
798 
799         head = head->next;
800     }
801 
802     return NULL;
803 }
804 
GetPreprocConfigFunc(char * keyword)805 PreprocConfigFunc GetPreprocConfigFunc(char *keyword)
806 {
807     PreprocConfigFuncNode *head = preproc_config_funcs;
808 
809     if (keyword == NULL)
810         return NULL;
811 
812     while (head != NULL)
813     {
814         if (strcasecmp(head->keyword, keyword) == 0)
815            return head->config_func;
816 
817         head = head->next;
818     }
819 
820     return NULL;
821 }
822 
823 /****************************************************************************
824  *
825  * Function: RegisterPreprocStats(char *keyword, void (*func)(int))
826  *
827  * Purpose: Registers a function for printing preprocessor final stats
828  *          (or other if it has a use for printing final stats)
829  *
830  * Arguments: keyword => keyword (preprocessor) whose stats will print
831  *            func => function pointer to the handler
832  *
833  * Returns: void function
834  *
835  ***************************************************************************/
RegisterPreprocStats(const char * keyword,PreprocStatsFunc pp_stats_func)836 void RegisterPreprocStats(const char *keyword, PreprocStatsFunc pp_stats_func)
837 {
838     PreprocStatsFuncNode *node;
839 
840     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering final stats function: "
841                             "preproc => %s:%p\n", keyword, pp_stats_func););
842 
843     node = (PreprocStatsFuncNode *)SnortAlloc(sizeof(PreprocStatsFuncNode));
844 
845     if (preproc_stats_funcs == NULL)
846     {
847         preproc_stats_funcs = node;
848     }
849     else
850     {
851         PreprocStatsFuncNode *tmp = preproc_stats_funcs;
852         PreprocStatsFuncNode *last;
853 
854         do
855         {
856             if (strcasecmp(tmp->keyword, keyword) == 0)
857             {
858                 free(node);
859                 FatalError("Duplicate preprocessor keyword: %s.\n", keyword);
860             }
861 
862             last = tmp;
863             tmp = tmp->next;
864 
865         } while (tmp != NULL);
866 
867         last->next = node;
868     }
869 
870     node->keyword = SnortStrdup(keyword);
871     node->func = pp_stats_func;
872 }
873 
874 /****************************************************************************
875  *
876  * Function: DumpPreprocessors()
877  *
878  * Purpose:  Prints the keyword->preprocess list
879  *
880  * Arguments: None.
881  *
882  * Returns: void function
883  *
884  ***************************************************************************/
DumpPreprocessors(void)885 void DumpPreprocessors(void)
886 {
887     PreprocConfigFuncNode *node = preproc_config_funcs;
888 
889     LogMessage("-------------------------------------------------\n");
890     LogMessage(" Keyword     |       Preprocessor @ \n");
891     LogMessage("-------------------------------------------------\n");
892 
893     while (node != NULL)
894     {
895         LogMessage("%-13s:       %p\n", node->keyword, node->config_vfunc);
896         node = node->next;
897     }
898 
899     LogMessage("-------------------------------------------------\n\n");
900 }
901 
IsPreprocEnabled(SnortConfig * sc,uint32_t preproc_id)902 int IsPreprocEnabled(SnortConfig *sc, uint32_t preproc_id)
903 {
904     PreprocEvalFuncNode *node;
905     tSfPolicyId policy_id = getParserPolicy(sc);
906     SnortPolicy *p;
907 
908     if (sc == NULL)
909     {
910         FatalError("%s(%d) Snort config for parsing is NULL.\n",
911                    __FILE__, __LINE__);
912     }
913 
914     p = sc->targeted_policies[policy_id];
915     if (p == NULL)
916         return 0;
917 
918     for (node = p->preproc_eval_funcs; node != NULL; node = node->next)
919     {
920         if (node->preproc_id == preproc_id)
921             return 1;
922     }
923 
924     return 0;
925 }
926 
AddFuncToPreprocList(SnortConfig * sc,PreprocEvalFunc pp_eval_func,uint16_t priority,uint32_t preproc_id,uint32_t proto_mask)927 PreprocEvalFuncNode * AddFuncToPreprocList(SnortConfig *sc, PreprocEvalFunc pp_eval_func, uint16_t priority,
928                                            uint32_t preproc_id, uint32_t proto_mask)
929 {
930     PreprocEvalFuncNode *node;
931     tSfPolicyId policy_id = getParserPolicy(sc);
932     SnortPolicy *p;
933 
934     if (sc == NULL)
935     {
936         FatalError("%s(%d) Snort config for parsing is NULL.\n",
937                    __FILE__, __LINE__);
938     }
939 
940     p = sc->targeted_policies[policy_id];
941     if (p == NULL)
942         return NULL;
943 
944     DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,
945                             "Adding preprocessor function ID %d/bit %d/pri %d to list\n",
946                             preproc_id, p->num_preprocs, priority););
947 
948     node = (PreprocEvalFuncNode *)SnortAlloc(sizeof(PreprocEvalFuncNode));
949 
950     if (p->preproc_eval_funcs == NULL)
951     {
952         p->preproc_eval_funcs = node;
953     }
954     else
955     {
956         PreprocEvalFuncNode *tmp = p->preproc_eval_funcs;
957         PreprocEvalFuncNode *last = NULL;
958 
959         do
960         {
961             if (tmp->preproc_id == preproc_id)
962             {
963                 free(node);
964                 FatalError("Preprocessor already registered with ID %d\n",
965                            preproc_id);
966             }
967 
968             /* Insert higher priority preprocessors first.  Lower priority
969              * number means higher priority */
970             if (priority < tmp->priority)
971                 break;
972 
973             last = tmp;
974             tmp = tmp->next;
975 
976         } while (tmp != NULL);
977 
978         /* Priority higher than first item in list */
979         if (last == NULL)
980         {
981             node->next = tmp;
982             p->preproc_eval_funcs = node;
983         }
984         else
985         {
986             node->next = tmp;
987             last->next = node;
988         }
989     }
990 
991     node->func = pp_eval_func;
992     node->priority = priority;
993     node->preproc_id = preproc_id;
994     node->preproc_bit = (UINT64_C(1) << preproc_id);
995     node->proto_mask = proto_mask;
996 
997     p->num_preprocs++;
998     p->preproc_proto_mask |= proto_mask;
999     p->preproc_bit_mask |= node->preproc_bit;
1000 
1001     return node;
1002 }
1003 
AddFuncToPreprocListAllNapPolicies(struct _SnortConfig * sc,PreprocEvalFunc pp_eval_func,uint16_t priority,uint32_t preproc_id,uint32_t proto_mask)1004 void AddFuncToPreprocListAllNapPolicies(struct _SnortConfig *sc, PreprocEvalFunc pp_eval_func, uint16_t priority,
1005                                         uint32_t preproc_id, uint32_t proto_mask)
1006 {
1007     tSfPolicyId save_policy_id = getParserPolicy( sc );
1008     uint32_t i;
1009 
1010     if (sc == NULL)
1011         FatalError("%s(%d) Snort config for parsing is NULL.\n", __FILE__, __LINE__);
1012 
1013     // preprocs are only registered in NAP policies so if num_prerocs > 0 then policy is NAP, this works here
1014     //  because this func is always called after all policies have been parsed and preprocs configured per policy
1015     //  have already registered...
1016     for( i = 0; i < sc->num_policies_allocated; i++ )
1017         if( ( sc->targeted_policies[ i ] != NULL ) && ( sc->targeted_policies[ i ]->num_preprocs > 0 ) )
1018         {
1019             setParserPolicy( sc, i );
1020             AddFuncToPreprocList( sc, pp_eval_func, priority, preproc_id, proto_mask );
1021         }
1022 
1023     setParserPolicy( sc, save_policy_id );
1024  }
1025 
1026 
AddFuncToPreprocMetaEvalList(SnortConfig * sc,PreprocMetaEvalFunc pp_meta_eval_func,uint16_t priority,uint32_t preproc_id)1027 PreprocMetaEvalFuncNode * AddFuncToPreprocMetaEvalList(
1028     SnortConfig *sc,
1029     PreprocMetaEvalFunc pp_meta_eval_func,
1030     uint16_t priority,
1031     uint32_t preproc_id)
1032 {
1033     PreprocMetaEvalFuncNode *node;
1034     tSfPolicyId policy_id = getDefaultPolicy( );
1035     SnortPolicy *p;
1036 
1037     if (sc == NULL)
1038     {
1039         FatalError("%s(%d) Snort config for parsing is NULL.\n",
1040                    __FILE__, __LINE__);
1041     }
1042 
1043 #ifndef HAVE_DAQ_ACQUIRE_WITH_META
1044     WarningMessage("Metadata not available for processing.  Not registering Preprocessor Meta Eval id %d\n", preproc_id);
1045     return NULL; // Not supported
1046 #endif
1047 
1048     p = sc->targeted_policies[policy_id];
1049     if (p == NULL)
1050         return NULL;
1051 
1052     DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,
1053                             "Adding preprocessor function ID %d/bit %d/pri %d to list\n",
1054                             preproc_id, p->num_preprocs, priority););
1055 
1056     node = (PreprocMetaEvalFuncNode *)SnortAlloc(sizeof(PreprocMetaEvalFuncNode));
1057 
1058     if (p->preproc_meta_eval_funcs == NULL)
1059     {
1060         p->preproc_meta_eval_funcs = node;
1061         SetupMetadataCallback();
1062     }
1063     else
1064     {
1065         PreprocMetaEvalFuncNode *tmp = p->preproc_meta_eval_funcs;
1066         PreprocMetaEvalFuncNode *last = NULL;
1067 
1068         do
1069         {
1070             if (tmp->preproc_id == preproc_id)
1071             {
1072                 free(node);
1073                 FatalError("Preprocessor Meta Eval already registered with ID %d\n",
1074                            preproc_id);
1075             }
1076 
1077             /* Insert higher priority preprocessors first.  Lower priority
1078              * number means higher priority */
1079             if (priority < tmp->priority)
1080                 break;
1081 
1082             last = tmp;
1083             tmp = tmp->next;
1084 
1085         } while (tmp != NULL);
1086 
1087         /* Priority higher than first item in list */
1088         if (last == NULL)
1089         {
1090             node->next = tmp;
1091             p->preproc_meta_eval_funcs = node;
1092         }
1093         else
1094         {
1095             node->next = tmp;
1096             last->next = node;
1097         }
1098     }
1099 
1100     node->func = pp_meta_eval_func;
1101     node->priority = priority;
1102     node->preproc_id = preproc_id;
1103     node->preproc_bit = (UINT64_C(1) << preproc_id);
1104 
1105     p->num_meta_preprocs++;
1106     p->preproc_meta_bit_mask |= node->preproc_bit;
1107 
1108     return node;
1109 }
1110 
AddFuncToPreprocPostConfigList(SnortConfig * sc,PreprocPostConfigFunc pp_post_config_func,void * data)1111 void AddFuncToPreprocPostConfigList(SnortConfig *sc, PreprocPostConfigFunc pp_post_config_func,
1112                                     void *data)
1113 {
1114     PreprocPostConfigFuncNode *node;
1115 
1116     if (sc == NULL)
1117     {
1118         FatalError("%s(%d) Snort config for parsing is NULL.\n",
1119                    __FILE__, __LINE__);
1120     }
1121 
1122     node = (PreprocPostConfigFuncNode *)SnortAlloc(sizeof(PreprocPostConfigFuncNode));
1123 
1124     if (sc->preproc_post_config_funcs == NULL)
1125     {
1126         sc->preproc_post_config_funcs = node;
1127     }
1128     else
1129     {
1130         PreprocPostConfigFuncNode *tmp = sc->preproc_post_config_funcs;
1131 
1132         while (tmp->next != NULL)
1133             tmp = tmp->next;
1134 
1135         tmp->next = node;
1136     }
1137 
1138     node->data = data;
1139     node->func = pp_post_config_func;
1140 }
1141 
PostConfigPreprocessors(SnortConfig * sc)1142 void PostConfigPreprocessors(SnortConfig *sc)
1143 {
1144     PreprocPostConfigFuncNode *list;
1145 
1146     if (sc == NULL)
1147     {
1148         FatalError("%s(%d) Snort config is NULL.\n",
1149                    __FILE__, __LINE__);
1150     }
1151 
1152     list = sc->preproc_post_config_funcs;
1153 
1154     for (; list != NULL; list = list->next)
1155     {
1156         if (list->func != NULL)
1157             list->func(sc, list->data);
1158     }
1159 }
1160 
FilterConfigPreprocessors(SnortConfig * sc)1161 void FilterConfigPreprocessors(SnortConfig *sc)
1162 {
1163     tSfPolicyId policy_id;
1164     SnortPolicy *p;
1165     PreprocEvalFuncNode *node;
1166     PreprocEvalFuncNode **list;
1167     PreprocEvalFuncNode **free_list;
1168 
1169     if (sc == NULL)
1170     {
1171         ParseError("%s(%d) Snort config is NULL.\n",
1172                    __FILE__, __LINE__);
1173     }
1174 
1175     if (!sc->disable_all_policies)
1176         return;
1177 
1178     policy_id = getParserPolicy(sc);
1179     p = sc->targeted_policies[policy_id];
1180     if (p == NULL)
1181         return;
1182 
1183     list = &p->preproc_eval_funcs;
1184     free_list = &p->unused_preproc_eval_funcs;
1185 
1186     while ((node = *list) != NULL)
1187     {
1188         if (node->preproc_bit & sc->reenabled_preprocessor_bits)
1189         {
1190             list = &node->next;
1191         }
1192         else
1193         {
1194             *list = node->next;
1195             node->next = NULL;
1196             *free_list = node;
1197             free_list = &node->next;
1198         }
1199     }
1200 }
1201 
1202 #ifdef SNORT_RELOAD
SwapPreprocConfigurations(SnortConfig * sc)1203 void SwapPreprocConfigurations(SnortConfig *sc)
1204 {
1205     PreprocessorSwapData *node;
1206     PreprocConfigFuncNode *preproc;
1207 
1208     for (node = sc->preprocSwapData; node != NULL; node = node->next)
1209     {
1210         if ((preproc = node->preprocNode) && preproc->reload_swap_func)
1211             node->data = preproc->reload_swap_func(sc, node->data);
1212     }
1213 }
1214 
FreeSwappedPreprocConfigurations(struct _SnortConfig * sc)1215 void FreeSwappedPreprocConfigurations(struct _SnortConfig *sc)
1216 {
1217     PreprocessorSwapData *node;
1218     PreprocConfigFuncNode *preproc;
1219 
1220     for (node = sc->preprocSwapData; node != NULL; node = node->next)
1221     {
1222         if (node->data && (preproc = node->preprocNode) && preproc->reload_swap_free_func)
1223         {
1224             preproc->reload_swap_free_func(node->data);
1225             node->data = NULL;
1226         }
1227     }
1228 }
1229 #endif
1230 
AddFuncToConfigCheckList(SnortConfig * sc,PreprocCheckConfigFunc pp_chk_config_func)1231 void AddFuncToConfigCheckList(SnortConfig *sc, PreprocCheckConfigFunc pp_chk_config_func)
1232 {
1233     PreprocCheckConfigFuncNode *node;
1234 
1235     if (sc == NULL)
1236     {
1237         FatalError("%s(%d) Snort config for parsing is NULL.\n",
1238                    __FILE__, __LINE__);
1239     }
1240 
1241     node = (PreprocCheckConfigFuncNode *)SnortAlloc(sizeof(PreprocCheckConfigFuncNode));
1242 
1243     if (sc->preproc_config_check_funcs == NULL)
1244     {
1245         sc->preproc_config_check_funcs = node;
1246     }
1247     else
1248     {
1249         PreprocCheckConfigFuncNode *tmp = sc->preproc_config_check_funcs;
1250 
1251         while (tmp->next != NULL)
1252             tmp = tmp->next;
1253 
1254         tmp->next = node;
1255     }
1256 
1257     node->func = pp_chk_config_func;
1258 }
1259 
1260 /* functions to aid in cleaning up after plugins */
AddFuncToPreprocCleanExitList(PreprocSignalFunc pp_sig_func,void * arg,uint16_t priority,uint32_t preproc_id)1261 void AddFuncToPreprocCleanExitList(PreprocSignalFunc pp_sig_func, void *arg,
1262                                    uint16_t priority, uint32_t preproc_id)
1263 {
1264     AddFuncToPreprocSignalList(pp_sig_func, arg, &preproc_clean_exit_funcs, priority, preproc_id);
1265 }
1266 
AddFuncToPreprocShutdownList(PreprocSignalFunc pp_shutdown_func,void * arg,uint16_t priority,uint32_t preproc_id)1267 void AddFuncToPreprocShutdownList(PreprocSignalFunc pp_shutdown_func, void *arg,
1268                                   uint16_t priority, uint32_t preproc_id)
1269 {
1270     AddFuncToPreprocSignalList(pp_shutdown_func, arg, &preproc_shutdown_funcs, priority, preproc_id);
1271 }
1272 
AddFuncToPreprocResetList(PreprocSignalFunc pp_sig_func,void * arg,uint16_t priority,uint32_t preproc_id)1273 void AddFuncToPreprocResetList(PreprocSignalFunc pp_sig_func, void *arg,
1274                                uint16_t priority, uint32_t preproc_id)
1275 {
1276     AddFuncToPreprocSignalList(pp_sig_func, arg, &preproc_reset_funcs, priority, preproc_id);
1277 }
1278 
AddFuncToPreprocResetStatsList(PreprocSignalFunc pp_sig_func,void * arg,uint16_t priority,uint32_t preproc_id)1279 void AddFuncToPreprocResetStatsList(PreprocSignalFunc pp_sig_func, void *arg,
1280                                     uint16_t priority, uint32_t preproc_id)
1281 {
1282     AddFuncToPreprocSignalList(pp_sig_func, arg, &preproc_reset_stats_funcs, priority, preproc_id);
1283 }
1284 
AddFuncToPreprocSignalList(PreprocSignalFunc pp_sig_func,void * arg,PreprocSignalFuncNode ** list,uint16_t priority,uint32_t preproc_id)1285 static void AddFuncToPreprocSignalList(PreprocSignalFunc pp_sig_func, void *arg,
1286                                        PreprocSignalFuncNode **list,
1287                                        uint16_t priority, uint32_t preproc_id)
1288 {
1289     PreprocSignalFuncNode *node;
1290 
1291     if (list == NULL)
1292         return;
1293 
1294     node = (PreprocSignalFuncNode *)SnortAlloc(sizeof(PreprocSignalFuncNode));
1295 
1296     if (*list == NULL)
1297     {
1298         *list = node;
1299     }
1300     else
1301     {
1302         PreprocSignalFuncNode *tmp = *list;
1303         PreprocSignalFuncNode *last = NULL;
1304 
1305         do
1306         {
1307             /* Insert higher priority stuff first.  Lower priority
1308              * number means higher priority */
1309             if (priority < tmp->priority)
1310                 break;
1311 
1312             last = tmp;
1313             tmp = tmp->next;
1314 
1315         } while (tmp != NULL);
1316 
1317         /* Priority higher than first item in list */
1318         if (last == NULL)
1319         {
1320             node->next = tmp;
1321             *list = node;
1322         }
1323         else
1324         {
1325             node->next = tmp;
1326             last->next = node;
1327         }
1328     }
1329 
1330     node->func = pp_sig_func;
1331     node->arg = arg;
1332     node->preproc_id = preproc_id;
1333     node->priority = priority;
1334 }
1335 
AddFuncToPeriodicCheckList(PeriodicFunc periodic_func,void * arg,uint16_t priority,uint32_t preproc_id,uint32_t period)1336 void AddFuncToPeriodicCheckList(PeriodicFunc periodic_func, void *arg,
1337         uint16_t priority, uint32_t preproc_id, uint32_t period )
1338 {
1339     PeriodicCheckFuncNode **list= &periodic_check_funcs;
1340     PeriodicCheckFuncNode *node;
1341 
1342 
1343     node = (PeriodicCheckFuncNode *)SnortAlloc(sizeof(PeriodicCheckFuncNode));
1344 
1345     if (*list == NULL)
1346     {
1347         *list = node;
1348     }
1349     else
1350     {
1351         PeriodicCheckFuncNode *tmp = *list;
1352         PeriodicCheckFuncNode *last = NULL;
1353 
1354         do
1355         {
1356             /* Insert higher priority stuff first.  Lower priority
1357              * number means higher priority */
1358             if (priority < tmp->priority)
1359                 break;
1360 
1361             last = tmp;
1362             tmp = tmp->next;
1363 
1364         } while (tmp != NULL);
1365 
1366         /* Priority higher than first item in list */
1367         if (last == NULL)
1368         {
1369             node->next = tmp;
1370             *list = node;
1371         }
1372         else
1373         {
1374             node->next = tmp;
1375             last->next = node;
1376         }
1377     }
1378 
1379     node->func = periodic_func;
1380     node->arg = arg;
1381     node->preproc_id = preproc_id;
1382     node->priority = priority;
1383     node->period = period;
1384     node->time_left = period;
1385 }
1386 
FreePreprocConfigFuncs(void)1387 void FreePreprocConfigFuncs(void)
1388 {
1389     PreprocConfigFuncNode *head = preproc_config_funcs;
1390     PreprocConfigFuncNode *tmp;
1391 
1392     while (head != NULL)
1393     {
1394         tmp = head->next;
1395         if (head->keyword != NULL)
1396             free(head->keyword);
1397         free(head);
1398         head = tmp;
1399     }
1400 }
1401 
FreePreprocCheckConfigFuncs(PreprocCheckConfigFuncNode * head)1402 void FreePreprocCheckConfigFuncs(PreprocCheckConfigFuncNode *head)
1403 {
1404     PreprocCheckConfigFuncNode *tmp;
1405 
1406     while (head != NULL)
1407     {
1408         tmp = head->next;
1409         free(head);
1410         head = tmp;
1411     }
1412 }
1413 
FreePreprocPostConfigFuncs(PreprocPostConfigFuncNode * head)1414 void FreePreprocPostConfigFuncs(PreprocPostConfigFuncNode *head)
1415 {
1416     PreprocPostConfigFuncNode *tmp;
1417 
1418     while (head != NULL)
1419     {
1420         tmp = head->next;
1421         free(head);
1422         head = tmp;
1423     }
1424 }
1425 
FreePreprocStatsFuncs(PreprocStatsFuncNode * head)1426 void FreePreprocStatsFuncs(PreprocStatsFuncNode *head)
1427 {
1428     PreprocStatsFuncNode *tmp;
1429 
1430     while (head != NULL)
1431     {
1432         tmp = head->next;
1433         if (head->keyword != NULL)
1434             free(head->keyword);
1435         free(head);
1436         head = tmp;
1437     }
1438 }
1439 
FreePreprocEvalFuncs(PreprocEvalFuncNode * head)1440 void FreePreprocEvalFuncs(PreprocEvalFuncNode *head)
1441 {
1442     PreprocEvalFuncNode *tmp;
1443 
1444     while (head != NULL)
1445     {
1446         tmp = head->next;
1447         //if (head->context)
1448         //    free(head->context);
1449         free(head);
1450         head = tmp;
1451     }
1452 }
1453 
FreePreprocMetaEvalFuncs(PreprocMetaEvalFuncNode * head)1454 void FreePreprocMetaEvalFuncs(PreprocMetaEvalFuncNode *head)
1455 {
1456     PreprocMetaEvalFuncNode *tmp;
1457 
1458     while (head != NULL)
1459     {
1460         tmp = head->next;
1461         //if (head->context)
1462         //    free(head->context);
1463         free(head);
1464         head = tmp;
1465     }
1466 }
1467 
FreePreprocSigFuncs(PreprocSignalFuncNode * head)1468 void FreePreprocSigFuncs(PreprocSignalFuncNode *head)
1469 {
1470     PreprocSignalFuncNode *tmp;
1471 
1472     while (head != NULL)
1473     {
1474         tmp = head->next;
1475         /* don't free sig->arg, that's free'd by the CleanExit func */
1476         free(head);
1477         head = tmp;
1478     }
1479 }
1480 
FreePeriodicFuncs(PeriodicCheckFuncNode * head)1481 void FreePeriodicFuncs(PeriodicCheckFuncNode *head)
1482 {
1483     PeriodicCheckFuncNode *tmp;
1484 
1485     while (head != NULL)
1486     {
1487         tmp = head->next;
1488         /* don't free sig->arg, that's free'd by the CleanExit func */
1489         free(head);
1490         head = tmp;
1491     }
1492 }
1493 
CheckPreprocessorsConfig(SnortConfig * sc)1494 int CheckPreprocessorsConfig(SnortConfig *sc)
1495 {
1496     PreprocCheckConfigFuncNode *idx;
1497     int rval;
1498 
1499     if (sc == NULL)
1500     {
1501         FatalError("%s(%d) Snort config is NULL.\n",
1502                    __FILE__, __LINE__);
1503     }
1504 
1505     idx = sc->preproc_config_check_funcs;
1506 
1507     LogMessage("Verifying Preprocessor Configurations!\n");
1508 
1509     while(idx != NULL)
1510     {
1511         if ((rval = idx->func(sc)))
1512             return rval;
1513         idx = idx->next;
1514     }
1515     return 0;
1516 }
1517 
1518 #ifdef SNORT_RELOAD
VerifyReloadedPreprocessors(SnortConfig * sc)1519 int VerifyReloadedPreprocessors(SnortConfig *sc)
1520 {
1521     int rval;
1522     PreprocessorSwapData *node;
1523     PreprocConfigFuncNode *preproc;
1524 
1525     for (node = sc->preprocSwapData; node != NULL; node = node->next)
1526     {
1527         if (node->data && (preproc = node->preprocNode) && preproc->reload_verify_func &&
1528             (rval = preproc->reload_verify_func(sc, node->data)))
1529         {
1530             return rval;
1531         }
1532     }
1533 
1534     return 0;
1535 }
1536 
FreePreprocessorReloadData(SnortConfig * sc)1537 void FreePreprocessorReloadData(SnortConfig *sc)
1538 {
1539     PreprocessorSwapData *node;
1540     PreprocConfigFuncNode *preproc;
1541 
1542     while ((node = sc->preprocSwapData))
1543     {
1544         sc->preprocSwapData = node->next;
1545         if (node->data && (preproc = node->preprocNode) && preproc->reload_swap_free_func)
1546             preproc->reload_swap_free_func(node->data);
1547         free(node);
1548     }
1549 }
1550 #endif
1551 
DisableAllPolicies(SnortConfig * sc)1552 void DisableAllPolicies(SnortConfig *sc)
1553 {
1554     if (!sc->disable_all_policies)
1555     {
1556         sc->disable_all_policies = 1;
1557         sc->reenabled_preprocessor_bits = (UINT64_C(1) << PP_FRAG3);
1558         sc->reenabled_preprocessor_bits |= (UINT64_C(1) << PP_STREAM);
1559         sc->reenabled_preprocessor_bits |= (UINT64_C(1) << PP_PERFMONITOR);
1560     }
1561 }
1562 
ReenablePreprocBit(SnortConfig * sc,unsigned int preproc_id)1563 int ReenablePreprocBit(SnortConfig *sc, unsigned int preproc_id)
1564 {
1565     sc->reenabled_preprocessor_bits |= (UINT64_C(1) << preproc_id);
1566     return 0;
1567 }
1568 
1569 /***************************** Output Plugin API  *****************************/
1570 extern OutputConfigFuncNode *output_config_funcs;
1571 
1572 static void AppendOutputFuncList(OutputFunc, void *, OutputFuncNode **);
1573 
RegisterOutputPlugins(void)1574 void RegisterOutputPlugins(void)
1575 {
1576     LogMessage("Initializing Output Plugins!\n");
1577 
1578     AlertSyslogSetup();
1579     LogTcpdumpSetup();
1580     AlertFastSetup();
1581     AlertFullSetup();
1582 #ifndef WIN32
1583     /* Win32 doesn't support AF_UNIX sockets */
1584     AlertUnixSockSetup();
1585 #endif /* !WIN32 */
1586     AlertCSVSetup();
1587     LogNullSetup();
1588     Unified2Setup();
1589     LogAsciiSetup();
1590 
1591 #ifdef DUMP_BUFFER
1592     LogBufferDumpSetup();
1593 #endif
1594 
1595 #ifdef LINUX
1596     /* This uses linux only capabilities */
1597     AlertSFSocket_Setup();
1598 #endif
1599 
1600     AlertTestSetup();
1601 }
1602 
1603 /****************************************************************************
1604  *
1605  * Function: RegisterOutputPlugin(char *, void (*func)(Packet *, u_char *))
1606  *
1607  * Purpose:  Associates an output statement with its function.
1608  *
1609  * Arguments: keyword => The output keyword to associate with the
1610  *                       output processor
1611  *            type => alert or log types
1612  *            *func => function pointer to the handler
1613  *
1614  * Returns: void function
1615  *
1616  ***************************************************************************/
RegisterOutputPlugin(char * keyword,int type_flags,OutputConfigFunc oc_func)1617 void RegisterOutputPlugin(char *keyword, int type_flags, OutputConfigFunc oc_func)
1618 {
1619     OutputConfigFuncNode *node = (OutputConfigFuncNode *)SnortAlloc(sizeof(OutputConfigFuncNode));
1620 
1621 
1622     DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:output => %s:%p\n",
1623                             keyword, oc_func););
1624 
1625     if (output_config_funcs == NULL)
1626     {
1627         output_config_funcs = node;
1628     }
1629     else
1630     {
1631         OutputConfigFuncNode *tmp = output_config_funcs;
1632         OutputConfigFuncNode *last;
1633 
1634         do
1635         {
1636             if (strcasecmp(tmp->keyword, keyword) == 0)
1637             {
1638                 free(node);
1639                 FatalError("Duplicate output keyword: %s\n", keyword);
1640             }
1641 
1642             last = tmp;
1643             tmp = tmp->next;
1644 
1645         } while (tmp != NULL);
1646 
1647         last->next = node;
1648     }
1649 
1650     node->keyword = SnortStrdup(keyword);
1651     node->config_func = oc_func;
1652     node->output_type_flags = type_flags;
1653 }
1654 
RemoveOutputPlugin(char * keyword)1655 void RemoveOutputPlugin(char *keyword)
1656 {
1657     OutputConfigFuncNode *head = output_config_funcs;
1658 
1659     if (!head ||(keyword == NULL))
1660         return;
1661 
1662     /*If head node, remove head*/
1663     if(head->keyword != NULL)
1664     {
1665         if (strcasecmp(head->keyword, keyword) == 0)
1666         {
1667             output_config_funcs = head->next;
1668             free(head->keyword);
1669             free(head);
1670             return;
1671         }
1672     }
1673 
1674     while (head->next != NULL)
1675     {
1676         OutputConfigFuncNode *next;
1677         next = head->next;
1678         if(next->keyword != NULL )
1679         {
1680             if (strcasecmp(next->keyword, keyword) == 0)
1681             {
1682                 head->next = next->next;
1683                 free(next->keyword);
1684                 free(next);
1685                 break;
1686             }
1687         }
1688         head = head->next;
1689     }
1690 
1691     return;
1692 }
1693 
GetOutputConfigFunc(char * keyword)1694 OutputConfigFunc GetOutputConfigFunc(char *keyword)
1695 {
1696     OutputConfigFuncNode *head = output_config_funcs;
1697 
1698     if (keyword == NULL)
1699         return NULL;
1700 
1701     while (head != NULL)
1702     {
1703         if (strcasecmp(head->keyword, keyword) == 0)
1704            return head->config_func;
1705 
1706         head = head->next;
1707     }
1708 
1709     return NULL;
1710 }
1711 
1712 
GetOutputTypeFlags(char * keyword)1713 int GetOutputTypeFlags(char *keyword)
1714 {
1715     OutputConfigFuncNode *head = output_config_funcs;
1716 
1717     if (keyword == NULL)
1718         return 0;
1719 
1720     while (head != NULL)
1721     {
1722         if (strcasecmp(head->keyword, keyword) == 0)
1723            return head->output_type_flags;
1724 
1725         head = head->next;
1726     }
1727 
1728     return 0;
1729 }
1730 
FreeOutputConfigFuncs(void)1731 void FreeOutputConfigFuncs(void)
1732 {
1733     OutputConfigFuncNode *head = output_config_funcs;
1734     OutputConfigFuncNode *tmp;
1735 
1736     while (head != NULL)
1737     {
1738         tmp = head->next;
1739         if (head->keyword != NULL)
1740             free(head->keyword);
1741         free(head);
1742         head = tmp;
1743     }
1744 }
1745 
FreeOutputList(OutputFuncNode * list)1746 void FreeOutputList(OutputFuncNode *list)
1747 {
1748     while (list != NULL)
1749     {
1750         OutputFuncNode *tmp = list;
1751 
1752         list = list->next;
1753         free(tmp);
1754     }
1755 }
1756 
1757 /****************************************************************************
1758  *
1759  * Function: DumpOutputPlugins()
1760  *
1761  * Purpose:  Prints the keyword->preprocess list
1762  *
1763  * Arguments: None.
1764  *
1765  * Returns: void function
1766  *
1767  ***************************************************************************/
DumpOutputPlugins(void)1768 void DumpOutputPlugins(void)
1769 {
1770     OutputConfigFuncNode *idx = output_config_funcs;
1771 
1772     LogMessage("-------------------------------------------------\n");
1773     LogMessage(" Keyword     |          Output @ \n");
1774     LogMessage("-------------------------------------------------\n");
1775     while(idx != NULL)
1776     {
1777         LogMessage("%-13s:       %p\n", idx->keyword, idx->config_vfunc);
1778         idx = idx->next;
1779     }
1780     LogMessage("-------------------------------------------------\n\n");
1781 }
1782 
AddFuncToOutputList(SnortConfig * sc,OutputFunc o_func,OutputType type,void * arg)1783 void AddFuncToOutputList(SnortConfig *sc, OutputFunc o_func, OutputType type, void *arg)
1784 {
1785     switch (type)
1786     {
1787         case OUTPUT_TYPE__ALERT:
1788             if (sc->head_tmp != NULL)
1789                 AppendOutputFuncList(o_func, arg, &sc->head_tmp->AlertList);
1790             else
1791                 AppendOutputFuncList(o_func, arg, &AlertList);
1792 
1793             break;
1794 
1795         case OUTPUT_TYPE__LOG:
1796             if (sc->head_tmp != NULL)
1797                 AppendOutputFuncList(o_func, arg, &sc->head_tmp->LogList);
1798             else
1799                 AppendOutputFuncList(o_func, arg, &LogList);
1800 
1801             break;
1802 
1803         default:
1804             /* just to be error-prone */
1805             FatalError("Unknown output type: %i. Possible bug, please "
1806                        "report.\n", type);
1807     }
1808 }
1809 
1810 #ifdef DUMP_BUFFER
1811 /****************************************************************************
1812  *
1813  * Function: AddBDFuncToOutputList()
1814  *
1815  * Purpose: This function is called only when buffer dump is enabled. For
1816  * BufferDump output plugin, bdfptr points to LogBufferDump function. For all
1817  * other output plugins, bdfptr points to NULL.
1818  *
1819  * Arguments: sc => snort config
1820  *            o_func => output plugin function
1821  *            type => alert or log types
1822  *            arg => pointer to output stream to which buffers will be dumped
1823  *
1824  * Returns: void function
1825  *
1826  ***************************************************************************/
1827 
AddBDFuncToOutputList(SnortConfig * sc,OutputFunc o_func,OutputType type,void * arg)1828 void AddBDFuncToOutputList(SnortConfig *sc, OutputFunc o_func, OutputType type, void *arg)
1829 {
1830 
1831     OutputFuncNode *node;
1832 
1833     if (sc->head_tmp != NULL)
1834         node = sc->head_tmp->LogList;
1835 
1836     else
1837         node = LogList;
1838 
1839     while (node->next != NULL)
1840         node = node->next;
1841 
1842     node->bdfptr = o_func;
1843 }
1844 #endif
1845 
AppendOutputFuncList(OutputFunc o_func,void * arg,OutputFuncNode ** list)1846 void AppendOutputFuncList(OutputFunc o_func, void *arg, OutputFuncNode **list)
1847 {
1848     OutputFuncNode *node;
1849 
1850     if (list == NULL)
1851         return;
1852 
1853     node = (OutputFuncNode *)SnortAlloc(sizeof(OutputFuncNode));
1854 
1855     if (*list == NULL)
1856     {
1857         *list = node;
1858     }
1859     else
1860     {
1861         OutputFuncNode *tmp = *list;
1862 
1863         while (tmp->next != NULL)
1864             tmp = tmp->next;
1865 
1866         tmp->next = node;
1867     }
1868 
1869     node->func = o_func;
1870     node->arg = arg;
1871 
1872 #ifdef DUMP_BUFFER
1873     node->bdfptr = NULL;
1874 #endif
1875 
1876 }
1877 
1878 
1879 /************************** Miscellaneous Functions  **************************/
1880 
1881 /* functions to aid in cleaning up after plugins
1882  * Used for both rule options and output.  Preprocessors have their own */
_AddFuncToPostConfigList(PostConfigFunc pl_post_func,void * arg,PostConfigFuncNode ** list)1883 static inline void _AddFuncToPostConfigList(PostConfigFunc pl_post_func, void *arg, PostConfigFuncNode **list)
1884 {
1885     PostConfigFuncNode *node;
1886 
1887     node = (PostConfigFuncNode *)SnortAlloc(sizeof(PostConfigFuncNode));
1888 
1889     if (*list == NULL)
1890     {
1891         *list = node;
1892     }
1893     else
1894     {
1895         PostConfigFuncNode *tmp = *list;
1896 
1897         while (tmp->next != NULL)
1898             tmp = tmp->next;
1899 
1900         tmp->next = node;
1901     }
1902 
1903     node->func = pl_post_func;
1904     node->arg = arg;
1905 }
1906 
1907 #ifdef SNORT_RELOAD
AddFuncToReloadList(PostConfigFunc pl_post_func,void * arg)1908 void AddFuncToReloadList(PostConfigFunc pl_post_func, void *arg)
1909 {
1910     _AddFuncToPostConfigList(pl_post_func, arg, &plugin_reload_funcs);
1911 }
1912 #endif
1913 
AddFuncToCleanExitList(PluginSignalFunc pl_sig_func,void * arg)1914 void AddFuncToCleanExitList(PluginSignalFunc pl_sig_func, void *arg)
1915 {
1916     AddFuncToSignalList(pl_sig_func, arg, &plugin_clean_exit_funcs);
1917 }
1918 
AddFuncToShutdownList(PluginSignalFunc pl_sig_func,void * arg)1919 void AddFuncToShutdownList(PluginSignalFunc pl_sig_func, void *arg)
1920 {
1921     AddFuncToSignalList(pl_sig_func, arg, &plugin_shutdown_funcs);
1922 }
1923 
AddFuncToPostConfigList(SnortConfig * sc,PostConfigFunc pl_post_func,void * arg)1924 void AddFuncToPostConfigList(SnortConfig *sc, PostConfigFunc pl_post_func, void *arg)
1925 {
1926     _AddFuncToPostConfigList(pl_post_func, arg, &sc->plugin_post_config_funcs);
1927 }
1928 
AddFuncToSignalList(PluginSignalFunc pl_sig_func,void * arg,PluginSignalFuncNode ** list)1929 void AddFuncToSignalList(PluginSignalFunc pl_sig_func, void *arg, PluginSignalFuncNode **list)
1930 {
1931     PluginSignalFuncNode *node;
1932 
1933     if (list == NULL)
1934         return;
1935 
1936     node = (PluginSignalFuncNode *)SnortAlloc(sizeof(PluginSignalFuncNode));
1937 
1938     if (*list == NULL)
1939     {
1940         *list = node;
1941     }
1942     else
1943     {
1944         PluginSignalFuncNode *tmp = *list;
1945 
1946         while (tmp->next != NULL)
1947             tmp = tmp->next;
1948 
1949         tmp->next = node;
1950     }
1951 
1952     node->func = pl_sig_func;
1953     node->arg = arg;
1954 }
1955 
AddFuncToRuleOptParseCleanupList(RuleOptParseCleanupFunc ro_parse_clean_func)1956 void AddFuncToRuleOptParseCleanupList(RuleOptParseCleanupFunc ro_parse_clean_func)
1957 {
1958     RuleOptParseCleanupNode *node =
1959         (RuleOptParseCleanupNode *)SnortAlloc(sizeof(RuleOptParseCleanupNode));
1960 
1961     if (rule_opt_parse_cleanup_list == NULL)
1962     {
1963         rule_opt_parse_cleanup_list = node;
1964     }
1965     else
1966     {
1967         RuleOptParseCleanupNode *tmp = rule_opt_parse_cleanup_list;
1968 
1969         while (tmp->next != NULL)
1970             tmp = tmp->next;
1971 
1972         tmp->next = node;
1973     }
1974 
1975     node->func = ro_parse_clean_func;
1976 }
1977 
RuleOptParseCleanup(void)1978 void RuleOptParseCleanup(void)
1979 {
1980     RuleOptParseCleanupNode *list = rule_opt_parse_cleanup_list;
1981 
1982     for (; list != NULL; list = list->next)
1983     {
1984         if (list->func != NULL)
1985             list->func();
1986     }
1987 }
1988 
FreeRuleOptParseCleanupList(RuleOptParseCleanupNode * head)1989 void FreeRuleOptParseCleanupList(RuleOptParseCleanupNode *head)
1990 {
1991     while (head != NULL)
1992     {
1993         RuleOptParseCleanupNode *tmp = head;
1994 
1995         head = head->next;
1996         free(tmp);
1997     }
1998 }
1999 
RegisterGetHttpXffFields(GetHttpXffFieldsFunc fn)2000 void RegisterGetHttpXffFields(GetHttpXffFieldsFunc fn)
2001 {
2002     if (!getHttpXffFieldsFunc) getHttpXffFieldsFunc = fn;
2003 }
2004 
GetHttpXffFields(int * nFields)2005 char** GetHttpXffFields(int* nFields)
2006 {
2007     if (getHttpXffFieldsFunc) return getHttpXffFieldsFunc(nFields);
2008     else return NULL;
2009 }
2010