1 /* $Id: */
2 /*
3 * sf_dynamic_plugins.c
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License Version 2 as
7 * published by the Free Software Foundation. You may not use, modify or
8 * distribute this program under any other version of the GNU General
9 * Public License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
21 * Copyright (C) 2005-2013 Sourcefire, Inc.
22 *
23 * Author: Steven Sturges
24 *
25 * Dynamic Library Loading for Snort
26 *
27 */
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #ifndef WIN32
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sys/types.h>
37 #include <limits.h>
38 #include <dirent.h>
39 #include <dlfcn.h>
40 #include <fnmatch.h>
41 #if defined(HPUX)
42 #define MODULE_EXT "*.sl"
43 #else
44 #define MODULE_EXT "*.so*"
45 #endif
46 typedef void * PluginHandle;
47 #else /* !WIN32 */
48 #include <windows.h>
49 #define MODULE_EXT "dll"
50 typedef HANDLE PluginHandle;
51 /* Of course, WIN32 couldn't do things the unix way...
52 * Define a few of these to get around portability issues.
53 */
54 #define getcwd _getcwd
55 #ifndef PATH_MAX
56 #define PATH_MAX MAX_PATH
57 #endif
58 #endif /* !WIN32 */
59
60 #include <errno.h>
61 #include <stdarg.h>
62
63 #if defined(FEAT_OPEN_APPID)
64 #include <pthread.h>
65 #endif
66
67 #include "config.h"
68 #include "decode.h"
69 #include "encode.h"
70 #include "snort_debug.h"
71 #include "detect.h"
72 #include "util.h"
73 #include "snort.h"
74 #include "memory_stats.h"
75 #include "sf_dynamic_engine.h"
76 #include "sf_dynamic_detection.h"
77 #include "sf_dynamic_preprocessor.h"
78 #include "sf_dynamic_decompression.h"
79 #include "sp_dynamic.h"
80 #include "sp_preprocopt.h"
81 #include "sp_pcre.h"
82 #include "util.h"
83 #include "event_queue.h"
84 #include "plugbase.h"
85 #include "sfthreshold.h"
86 #include "active.h"
87 #include "mstring.h"
88 #include "sfsnprintfappend.h"
89 #include "session_api.h"
90 #include "stream_api.h"
91 #include "sf_iph.h"
92 #include "fpdetect.h"
93 #include "sfportobject.h"
94 #include <pcre.h>
95 #include "parser.h"
96 #include "event_wrapper.h"
97 #include "util.h"
98 #include "detection_util.h"
99 #include "sfcontrol_funcs.h"
100 #include "idle_processing_funcs.h"
101 #include "../dynamic-output/plugins/output.h"
102 #include "file_api.h"
103 #include "packet_time.h"
104 #include "perf_indicators.h"
105 #include "reload.h"
106 #include "so_rule_mem_adjust.h"
107
108 #ifdef SNORT_RELOAD
109 #include "appdata_adjuster.h"
110 #endif
111
112 #if defined(FEAT_OPEN_APPID)
113 #include "appIdApi.h"
114 #endif /* defined(FEAT_OPEN_APPID) */
115
116 #ifdef TARGET_BASED
117 #include "target-based/sftarget_protocol_reference.h"
118 #include "target-based/sftarget_reader.h"
119 #endif
120
121 #ifdef SIDE_CHANNEL
122 #include "sidechannel.h"
123 #include "sf_dynamic_side_channel.h"
124 #endif
125
126 #ifndef DEBUG_MSGS
127 char *no_file = "unknown";
128 int no_line = 0;
129 #endif
130
131 #ifdef SNORT_RELOAD
132 static APPDATA_ADJUSTER *ada;
133 #endif
134
135 /* Predeclare this */
136 void VerifySharedLibUniqueness();
137 typedef int (*LoadLibraryFunc)(SnortConfig *sc, const char * const path, int indent);
138
139 typedef struct _DynamicEnginePlugin
140 {
141 PluginHandle handle;
142 DynamicPluginMeta metaData;
143 InitEngineLibFunc initFunc;
144 CompatibilityFunc versCheck;
145 struct _DynamicEnginePlugin *next;
146 struct _DynamicEnginePlugin *prev;
147 } DynamicEnginePlugin;
148
149 static DynamicEnginePlugin *loadedEngines = NULL;
150
151 typedef struct _DynamicPreprocessorPlugin
152 {
153 PluginHandle handle;
154 DynamicPluginMeta metaData;
155 InitPreprocessorLibFunc initFunc;
156 struct _DynamicPreprocessorPlugin *next;
157 struct _DynamicPreprocessorPlugin *prev;
158 } DynamicPreprocessorPlugin;
159
160 static DynamicPreprocessorPlugin *loadedPreprocessorPlugins = NULL;
161
162 typedef struct _LoadableModule
163 {
164 char *prefix;
165 char *name;
166 struct _LoadableModule *next;
167
168 } LoadableModule;
169
CloseDynamicLibrary(PluginHandle handle)170 void CloseDynamicLibrary(PluginHandle handle)
171 {
172 #ifndef WIN32
173 # ifndef DISABLE_DLCLOSE_FOR_VALGRIND_TESTING
174 dlclose(handle);
175 # endif
176 #else
177 FreeLibrary(handle);
178 #endif
179 }
180
181 #define NONFATAL 0
182 #define FATAL 1
183
184 typedef void (*dlsym_func)(void);
185
getSymbol(PluginHandle handle,char * symbol,DynamicPluginMeta * meta,int fatal)186 static dlsym_func getSymbol(
187 PluginHandle handle, char *symbol, DynamicPluginMeta *meta, int fatal)
188 {
189 dlsym_func symbolPtr = NULL;
190
191 if (!handle)
192 return symbolPtr;
193
194 #ifndef WIN32
195 symbolPtr = (dlsym_func)dlsym(handle, symbol);
196 #else
197 symbolPtr = (dlsym_func)GetProcAddress(handle, symbol);
198 #endif
199
200 if (!symbolPtr)
201 {
202 if (fatal)
203 {
204 #ifndef WIN32
205 FatalError("Failed to find %s() function in %s: %s\n",
206 symbol, meta->libraryPath, dlerror());
207 #else
208 FatalError("Failed to find %s() function in %s: %d\n",
209 symbol, meta->libraryPath, GetLastError());
210 #endif
211 }
212 else
213 {
214 #ifndef WIN32
215 ErrorMessage("Failed to find %s() function in %s: %s\n",
216 symbol, meta->libraryPath, dlerror());
217 #else
218 ErrorMessage("Failed to find %s() function in %s: %d\n",
219 symbol, meta->libraryPath, GetLastError());
220 #endif
221 }
222 }
223
224 return symbolPtr;
225 }
226
GetPluginVersion(PluginHandle handle,DynamicPluginMeta * meta)227 void GetPluginVersion(PluginHandle handle, DynamicPluginMeta* meta)
228 {
229 LibVersionFunc libVersionFunc = NULL;
230
231 libVersionFunc = (LibVersionFunc)getSymbol(handle, "LibVersion", meta, FATAL);
232
233 if (libVersionFunc != NULL)
234 {
235 libVersionFunc(meta);
236 }
237 }
238
openDynamicLibrary(const char * const library_name,int useGlobal)239 PluginHandle openDynamicLibrary(const char * const library_name, int useGlobal)
240 {
241 PluginHandle handle;
242 #ifndef WIN32
243 handle = dlopen(library_name, RTLD_NOW | (useGlobal ? RTLD_GLOBAL : RTLD_LOCAL));
244 #else
245 handle = LoadLibrary(library_name);
246 #endif
247 if (handle == NULL)
248 {
249 #ifndef WIN32
250 FatalError("Failed to load %s: %s\n", library_name, dlerror());
251 #else
252 FatalError("Failed to load %s: %d\n", library_name, GetLastError());
253 #endif
254 }
255 return handle;
256 }
257
LoadAllLibs(struct _SnortConfig * sc,const char * const path,LoadLibraryFunc loadFunc)258 void LoadAllLibs(struct _SnortConfig *sc, const char * const path, LoadLibraryFunc loadFunc)
259 {
260 #ifndef WIN32
261 char path_buf[PATH_MAX];
262 struct dirent *dir_entry;
263 DIR *directory;
264 int count = 0;
265 LoadableModule *modules = NULL;
266
267 directory = opendir(path);
268 if (directory != NULL)
269 {
270 dir_entry = readdir(directory);
271 while (dir_entry != NULL)
272 {
273 if (fnmatch(MODULE_EXT, dir_entry->d_name, FNM_PATHNAME | FNM_PERIOD) == 0)
274 {
275 /* Get the string up until the first dot. This will be
276 * considered the file prefix. */
277 char *dot = strchr(dir_entry->d_name, '.');
278
279 if (dot != NULL)
280 {
281 size_t len = (size_t)(dot - dir_entry->d_name); // len >= 0
282 LoadableModule *tmp = modules;
283 LoadableModule *prev = NULL;
284
285 while (tmp != NULL)
286 {
287 /* Make sure the prefix lengths are the same */
288 if (strlen(tmp->prefix) == len)
289 {
290 /* And make sure they are the same string */
291 if (strncmp(tmp->prefix, dir_entry->d_name, len) == 0)
292 {
293 /* Take the shorter, since the longer probably
294 * has version information and the shorter ones
295 * are generally links to the most recent
296 * version, e.g.
297 * libsf_engine.so.0.0.0
298 * libsf_engine.so.0 -> libsf_engine.so.0.0.0
299 * libsf_engine.so -> libsf_engine.so.0.0.0
300 * Mac seems to do
301 * libsf_engine.0.so
302 * libsf_engine.0.0.0.so -> libsf_engine.0.so
303 * libsf_engine.so -> libsf_engine.0.so
304 * We don't want to load the same same thing
305 * more than once. */
306 if (strlen(dir_entry->d_name) < strlen(tmp->name))
307 {
308 /* There will be enough space since at
309 * least the longer of the two will have
310 * been allocated */
311 strcpy(tmp->name, dir_entry->d_name);
312 }
313
314 break;
315 }
316 }
317
318 prev = tmp;
319 tmp = tmp->next;
320 }
321
322 if (tmp == NULL)
323 {
324 tmp = SnortAlloc(sizeof(LoadableModule));
325
326 /* include NULL byte */
327 tmp->prefix = SnortAlloc(len + 1);
328 /* will be NULL terminated because SnortAlloc uses calloc */
329 strncpy(tmp->prefix, dir_entry->d_name, len);
330
331 /* include NULL byte */
332 tmp->name = SnortAlloc(strlen(dir_entry->d_name) + 1);
333 /* will be NULL terminated because SnortAlloc uses calloc */
334 strncpy(tmp->name, dir_entry->d_name, strlen(dir_entry->d_name));
335
336 tmp->next = NULL;
337
338 if (modules == NULL)
339 modules = tmp;
340 else if (prev != NULL)
341 prev->next = tmp;
342 }
343 }
344 }
345
346 dir_entry = readdir(directory);
347 }
348
349 closedir(directory);
350
351 while (modules != NULL)
352 {
353 LoadableModule *tmp = modules;
354
355 SnortSnprintf(path_buf, PATH_MAX, "%s%s%s", path, "/", modules->name);
356 loadFunc(sc, path_buf, 1);
357 count++;
358
359 modules = modules->next;
360
361 /* These will all have been allocated together */
362 free(tmp->prefix);
363 free(tmp->name);
364 free(tmp);
365 }
366
367 if ( count == 0 )
368 {
369 LogMessage("WARNING: No dynamic libraries found in directory %s.\n", path);
370 }
371 }
372 else
373 {
374 LogMessage("WARNING: Directory %s does not exist.\n", path);
375 }
376 #else
377 /* Find all shared library files in path */
378 char path_buf[PATH_MAX];
379 char dyn_lib_name[PATH_MAX];
380 char drive[_MAX_DRIVE];
381 char dir[_MAX_DIR];
382 char fname[_MAX_FNAME];
383 char ext[_MAX_EXT];
384 HANDLE fSearch;
385 WIN32_FIND_DATA FindFileData;
386 int pathLen = 0;
387 const char *directory;
388 int useDrive = 0;
389
390 if (SnortStrncpy(path_buf, path, PATH_MAX) != SNORT_STRNCPY_SUCCESS)
391 FatalError("Path is too long: %s\n", path);
392
393 pathLen = SnortStrnlen(path_buf, PATH_MAX);
394 if ((path_buf[pathLen - 1] == '\\') ||
395 (path_buf[pathLen - 1] == '/'))
396 {
397 /* A directory was specified with trailing dir character */
398 _splitpath(path_buf, drive, dir, fname, ext);
399 _makepath(path_buf, drive, dir, "*", MODULE_EXT);
400 directory = &dir[0];
401 useDrive = 1;
402 }
403 else /* A directory was specified */
404 {
405 _splitpath(path_buf, drive, dir, fname, ext);
406 if (strcmp(ext, ""))
407 {
408 FatalError("Improperly formatted directory name: %s\n", path);
409 }
410 _makepath(path_buf, "", path_buf, "*", MODULE_EXT);
411 directory = path;
412 }
413
414 fSearch = FindFirstFile(path_buf, &FindFileData);
415 while (fSearch != NULL && fSearch != (HANDLE)-1)
416 {
417 if (useDrive)
418 _makepath(dyn_lib_name, drive, directory, FindFileData.cFileName, NULL);
419 else
420 _makepath(dyn_lib_name, NULL, directory, FindFileData.cFileName, NULL);
421
422 loadFunc(dyn_lib_name, 1);
423
424 if (!FindNextFile(fSearch, &FindFileData))
425 {
426 break;
427 }
428 }
429 FindClose(fSearch);
430 #endif
431 }
432
AddEnginePlugin(PluginHandle handle,InitEngineLibFunc initFunc,CompatibilityFunc compatFunc,DynamicPluginMeta * meta)433 void AddEnginePlugin(PluginHandle handle,
434 InitEngineLibFunc initFunc,
435 CompatibilityFunc compatFunc,
436 DynamicPluginMeta *meta)
437 {
438 DynamicEnginePlugin *newPlugin;
439 newPlugin = (DynamicEnginePlugin *)SnortAlloc(sizeof(DynamicEnginePlugin));
440 newPlugin->handle = handle;
441
442 if (!loadedEngines)
443 {
444 loadedEngines = newPlugin;
445 }
446 else
447 {
448 newPlugin->next = loadedEngines;
449 loadedEngines->prev = newPlugin;
450 loadedEngines = newPlugin;
451 }
452
453 memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta));
454 newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath);
455 newPlugin->initFunc = initFunc;
456 newPlugin->versCheck = compatFunc;
457 }
458
RemoveEnginePlugin(DynamicEnginePlugin * plugin)459 void RemoveEnginePlugin(DynamicEnginePlugin *plugin)
460 {
461 if (!plugin)
462 return;
463
464 if (plugin == loadedEngines)
465 {
466 loadedEngines = loadedEngines->next;
467 loadedEngines->prev = NULL;
468 }
469 else
470 {
471 if (plugin->prev)
472 plugin->prev->next = plugin->next;
473 if (plugin->next)
474 plugin->next->prev = plugin->prev;
475 }
476 CloseDynamicLibrary(plugin->handle);
477 if (plugin->metaData.libraryPath != NULL)
478 free(plugin->metaData.libraryPath);
479 free(plugin);
480 }
481
ValidateDynamicEngines(SnortConfig * sc)482 int ValidateDynamicEngines(SnortConfig *sc)
483 {
484 int testNum = 0;
485 DynamicEnginePlugin *curPlugin = loadedEngines;
486 CompatibilityFunc versFunc = NULL;
487
488 while( curPlugin != NULL)
489 {
490 versFunc = (CompatibilityFunc)curPlugin->versCheck;
491 /* if compatibility checking func is absent, skip validating */
492 if( versFunc != NULL)
493 {
494 DynamicDetectionPlugin *lib = sc->loadedDetectionPlugins;
495 while( lib != NULL)
496 {
497 if (lib->metaData.type == TYPE_DETECTION)
498 {
499 RequiredEngineLibFunc engineFunc;
500 DynamicPluginMeta reqEngineMeta;
501
502 engineFunc = (RequiredEngineLibFunc) getSymbol(lib->handle, "EngineVersion", &(lib->metaData), 1);
503 if( engineFunc != NULL)
504 {
505 engineFunc(&reqEngineMeta);
506 }
507 testNum = versFunc(&curPlugin->metaData, &reqEngineMeta);
508 if( testNum )
509 {
510 FatalError("The dynamic detection library \"%s\" version "
511 "%d.%d compiled with dynamic engine library "
512 "version %d.%d isn't compatible with the current "
513 "dynamic engine library \"%s\" version %d.%d.\n",
514 lib->metaData.libraryPath, lib->metaData.major,
515 lib->metaData.minor, reqEngineMeta.major,
516 reqEngineMeta.minor, curPlugin->metaData.libraryPath,
517 curPlugin->metaData.major, curPlugin->metaData.minor);
518 }
519
520 }
521 lib = lib->next;
522 }
523 }
524 if( testNum ) break;
525 curPlugin = curPlugin->next;
526 }
527
528 return(testNum);
529 }
530
LoadDynamicEngineLib(SnortConfig * sc,const char * const library_name,int indent)531 int LoadDynamicEngineLib(SnortConfig *sc, const char * const library_name, int indent)
532 {
533 /* Presume here, that library name is full path */
534 InitEngineLibFunc engineInit;
535 CompatibilityFunc compatFunc;
536 DynamicPluginMeta metaData;
537 PluginHandle handle;
538
539 #if 0
540 LogMessage("%sDynamic engine will not be loaded since dynamic detection "
541 "libraries are not yet supported with IPv6.\n",
542 indent?" ":"");
543 return 0;
544 #endif
545
546 LogMessage("%sLoading dynamic engine %s... ",
547 indent ? " " : "", library_name);
548
549 handle = openDynamicLibrary(library_name, 1);
550 metaData.libraryPath = (char *) library_name;
551
552 GetPluginVersion(handle, &metaData);
553
554 /* Just to ensure that the function exists */
555 engineInit = (InitEngineLibFunc)getSymbol(handle, "InitializeEngine", &metaData, FATAL);
556 compatFunc = (CompatibilityFunc)getSymbol(handle, "CheckCompatibility", &metaData, NONFATAL);
557
558 if (metaData.type != TYPE_ENGINE)
559 {
560 CloseDynamicLibrary(handle);
561 LogMessage("failed, not an Engine\n");
562 return 0;
563 }
564
565 AddEnginePlugin(handle, engineInit, compatFunc, &metaData);
566
567 LogMessage("done\n");
568 return 0;
569 }
570
LoadAllDynamicEngineLibs(SnortConfig * sc,const char * const path)571 void LoadAllDynamicEngineLibs(SnortConfig *sc, const char * const path)
572 {
573 LogMessage("Loading all dynamic engine libs from %s...\n", path);
574 LoadAllLibs(sc, path, LoadDynamicEngineLib);
575 LogMessage(" Finished Loading all dynamic engine libs from %s\n", path);
576 }
577
CloseDynamicEngineLibs(void)578 void CloseDynamicEngineLibs(void)
579 {
580 DynamicEnginePlugin *tmpplugin, *plugin = loadedEngines;
581 while (plugin)
582 {
583 tmpplugin = plugin->next;
584 //if (!(plugin->metaData.type & TYPE_DETECTION))
585 //{
586 CloseDynamicLibrary(plugin->handle);
587 free(plugin->metaData.libraryPath);
588 free(plugin);
589 //}
590 //else
591 //{
592 // HUH?
593 // /* NOP, handle will be closed when we close the DetectionLib */
594 // ;
595 //}
596 plugin = tmpplugin;
597 }
598 loadedEngines = NULL;
599 #ifdef SNORT_RELOAD
600 ada_delete(ada);
601 ada = NULL;
602 #endif
603 }
604
RemovePreprocessorPlugin(DynamicPreprocessorPlugin * plugin)605 void RemovePreprocessorPlugin(DynamicPreprocessorPlugin *plugin)
606 {
607 if (!plugin)
608 return;
609
610 if (plugin == loadedPreprocessorPlugins)
611 {
612 loadedPreprocessorPlugins = loadedPreprocessorPlugins->next;
613 loadedPreprocessorPlugins->prev = NULL;
614 }
615 else
616 {
617 if (plugin->prev)
618 plugin->prev->next = plugin->next;
619 if (plugin->next)
620 plugin->next->prev = plugin->prev;
621 }
622 CloseDynamicLibrary(plugin->handle);
623 if (plugin->metaData.libraryPath != NULL)
624 free(plugin->metaData.libraryPath);
625 free(plugin);
626 }
627
AddPreprocessorPlugin(PluginHandle handle,InitPreprocessorLibFunc initFunc,DynamicPluginMeta * meta)628 void AddPreprocessorPlugin(PluginHandle handle,
629 InitPreprocessorLibFunc initFunc,
630 DynamicPluginMeta *meta)
631 {
632 DynamicPreprocessorPlugin *newPlugin = NULL;
633 newPlugin = (DynamicPreprocessorPlugin *)SnortAlloc(sizeof(DynamicPreprocessorPlugin));
634 newPlugin->handle = handle;
635
636 if (!loadedPreprocessorPlugins)
637 {
638 loadedPreprocessorPlugins = newPlugin;
639 }
640 else
641 {
642 newPlugin->next = loadedPreprocessorPlugins;
643 loadedPreprocessorPlugins->prev = newPlugin;
644 loadedPreprocessorPlugins = newPlugin;
645 }
646
647 memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta));
648 newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath);
649 newPlugin->initFunc = initFunc;
650 }
651
AddDetectionPlugin(SnortConfig * sc,PluginHandle handle,InitDetectionLibFunc initFunc,DynamicPluginMeta * meta)652 void AddDetectionPlugin(SnortConfig *sc, PluginHandle handle,
653 InitDetectionLibFunc initFunc,
654 DynamicPluginMeta *meta)
655 {
656 DynamicDetectionPlugin *newPlugin = NULL;
657 newPlugin = (DynamicDetectionPlugin *)SnortAlloc(sizeof(DynamicDetectionPlugin));
658 newPlugin->handle = handle;
659
660 if (!sc->loadedDetectionPlugins)
661 {
662 sc->loadedDetectionPlugins = newPlugin;
663 }
664 else
665 {
666 newPlugin->next = sc->loadedDetectionPlugins;
667 sc->loadedDetectionPlugins->prev = newPlugin;
668 sc->loadedDetectionPlugins = newPlugin;
669 }
670
671 memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta));
672 newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath);
673 newPlugin->initFunc = initFunc;
674 }
675
RemoveDetectionPlugin(SnortConfig * sc,DynamicDetectionPlugin * plugin)676 void RemoveDetectionPlugin(SnortConfig *sc, DynamicDetectionPlugin *plugin)
677 {
678 if (!plugin)
679 return;
680
681 if (plugin == sc->loadedDetectionPlugins)
682 {
683 sc->loadedDetectionPlugins = sc->loadedDetectionPlugins->next;
684 sc->loadedDetectionPlugins->prev = NULL;
685 }
686 else
687 {
688 if (plugin->prev)
689 plugin->prev->next = plugin->next;
690 if (plugin->next)
691 plugin->next->prev = plugin->prev;
692 }
693 LogMessage("Unloading dynamic detection library %s version %d.%d.%d\n",
694 plugin->metaData.uniqueName,
695 plugin->metaData.major,
696 plugin->metaData.minor,
697 plugin->metaData.build);
698 CloseDynamicLibrary(plugin->handle);
699 if (plugin->metaData.libraryPath != NULL)
700 free(plugin->metaData.libraryPath);
701 free(plugin);
702 }
703
LoadDynamicDetectionLib(SnortConfig * sc,const char * const library_name,int indent)704 int LoadDynamicDetectionLib(SnortConfig *sc, const char * const library_name, int indent)
705 {
706 DynamicPluginMeta metaData;
707 /* Presume here, that library name is full path */
708 InitDetectionLibFunc detectionInit;
709 PluginHandle handle;
710
711 #if 0
712 LogMessage("%sDynamic detection library \"%s\" will not be loaded. Not "
713 "supported with IPv6.\n", indent ? " " : "", library_name);
714 return 0;
715 #endif
716
717 LogMessage("%sLoading dynamic detection library %s... ",
718 indent ? " " : "", library_name);
719
720 handle = openDynamicLibrary(library_name, 0);
721 metaData.libraryPath = (char *) library_name;
722
723 GetPluginVersion(handle, &metaData);
724
725 /* Just to ensure that the function exists */
726 detectionInit = (InitDetectionLibFunc)getSymbol(handle, "InitializeDetection", &metaData, FATAL);
727
728 if (!(metaData.type & TYPE_DETECTION))
729 {
730 CloseDynamicLibrary(handle);
731 LogMessage("failed, not a detection library\n");
732 return 0;
733 }
734
735 if (metaData.type & TYPE_ENGINE)
736 {
737 /* Do the engine initialization as well */
738 InitEngineLibFunc engineInit = (InitEngineLibFunc)getSymbol(handle, "InitializeEngine", &metaData, FATAL);
739 CompatibilityFunc compatFunc = (CompatibilityFunc)getSymbol(handle, "CheckCompatibility", &metaData, NONFATAL);
740
741 AddEnginePlugin(handle, engineInit, compatFunc, &metaData);
742 }
743
744 AddDetectionPlugin(sc, handle, detectionInit, &metaData);
745
746 LogMessage("done\n");
747 return 0;
748 }
749
CloseDynamicDetectionLibs(SnortConfig * sc)750 void CloseDynamicDetectionLibs(SnortConfig *sc)
751 {
752 DynamicDetectionPlugin *tmpplugin, *plugin = sc->loadedDetectionPlugins;
753 while (plugin)
754 {
755 tmpplugin = plugin->next;
756 #ifndef SNORT_RELOAD
757 CloseDynamicLibrary(plugin->handle);
758 #else
759 /*
760 * Even if DISABLE_DLCLOSE_FOR_VALGRIND_TESTING is set
761 * we have to do dlclose() for Dynamic detection libs
762 * during reloading.
763 */
764 #ifndef WIN32
765 dlclose(plugin->handle);
766 #else
767 FreeLibrary(plugin->handle);
768 #endif
769 #endif
770 free(plugin->metaData.libraryPath);
771 free(plugin);
772 plugin = tmpplugin;
773 }
774 sc->loadedDetectionPlugins = NULL;
775 }
776
LoadAllDynamicDetectionLibs(SnortConfig * sc,const char * const path)777 void LoadAllDynamicDetectionLibs(SnortConfig *sc, const char * const path)
778 {
779 LogMessage("Loading all dynamic detection libs from %s...\n", path);
780 LoadAllLibs(sc, path, LoadDynamicDetectionLib);
781 LogMessage(" Finished Loading all dynamic detection libs from %s\n", path);
782 }
783
RemoveDuplicateEngines(void)784 void RemoveDuplicateEngines(void)
785 {
786 int removed = 0;
787 DynamicEnginePlugin *engine1;
788 DynamicEnginePlugin *engine2;
789 DynamicPluginMeta *meta1;
790 DynamicPluginMeta *meta2;
791
792 /* First the Detection Engines */
793 do
794 {
795 removed = 0;
796 engine1 = loadedEngines;
797 while (engine1 != NULL)
798 {
799 engine2 = loadedEngines;
800 while (engine2 != NULL)
801 {
802 /* Obviously, the same ones will be the same */
803 if (engine1 != engine2)
804 {
805 meta1 = &engine1->metaData;
806 meta2 = &engine2->metaData;
807 if (!strcmp(meta1->uniqueName, meta2->uniqueName))
808 {
809 /* Uh, same uniqueName. */
810 if ((meta1->major > meta2->major) ||
811 ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) ||
812 ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) )
813 {
814 /* Lib1 is newer */
815 RemoveEnginePlugin(engine2);
816 removed = 1;
817 }
818 else if ((meta2->major > meta1->major) ||
819 ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) ||
820 ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) )
821 {
822 /* Lib2 is newer */
823 RemoveEnginePlugin(engine1);
824 removed = 1;
825 }
826 else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) )
827 {
828 /* Duplicate */
829 RemoveEnginePlugin(engine2);
830 removed = 1;
831 }
832 }
833 }
834 /* If we removed anything, start back at the beginning */
835 if (removed)
836 break;
837 engine2 = engine2->next;
838 }
839 /* If we removed anything, start back at the beginning */
840 if (removed)
841 break;
842 engine1 = engine1->next;
843 }
844 } while (removed);
845 }
846
RemoveDuplicateDetectionPlugins(SnortConfig * sc)847 void RemoveDuplicateDetectionPlugins(SnortConfig *sc)
848 {
849 int removed = 0;
850 DynamicDetectionPlugin *lib1 = NULL;
851 DynamicDetectionPlugin *lib2 = NULL;
852 DynamicPluginMeta *meta1;
853 DynamicPluginMeta *meta2;
854
855 /* Detection Plugins */
856 do
857 {
858 removed = 0;
859 lib1 = sc->loadedDetectionPlugins;
860 while (lib1 != NULL)
861 {
862 lib2 = sc->loadedDetectionPlugins;
863 while (lib2 != NULL)
864 {
865 /* Obviously, the same ones will be the same */
866 if (lib1 != lib2)
867 {
868 meta1 = &lib1->metaData;
869 meta2 = &lib2->metaData;
870 if (!strcmp(meta1->uniqueName, meta2->uniqueName))
871 {
872 /* Uh, same uniqueName. */
873 if ((meta1->major > meta2->major) ||
874 ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) ||
875 ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) )
876 {
877 /* Lib1 is newer */
878 RemoveDetectionPlugin(sc, lib2);
879 removed = 1;
880 }
881 else if ((meta2->major > meta1->major) ||
882 ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) ||
883 ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) )
884 {
885 /* Lib2 is newer */
886 RemoveDetectionPlugin(sc, lib1);
887 removed = 1;
888 }
889 else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) )
890 {
891 /* Duplicate */
892 RemoveDetectionPlugin(sc, lib2);
893 removed = 1;
894 }
895 }
896 }
897 /* If we removed anything, start back at the beginning */
898 if (removed)
899 break;
900 lib2 = lib2->next;
901 }
902 /* If we removed anything, start back at the beginning */
903 if (removed)
904 break;
905 lib1 = lib1->next;
906 }
907 } while (removed);
908 }
909
RemoveDuplicatePreprocessorPlugins(void)910 void RemoveDuplicatePreprocessorPlugins(void)
911 {
912 int removed = 0;
913 DynamicPreprocessorPlugin *pp1 = NULL;
914 DynamicPreprocessorPlugin *pp2 = NULL;
915 DynamicPluginMeta *meta1;
916 DynamicPluginMeta *meta2;
917
918 /* The Preprocessor Plugins */
919 do
920 {
921 removed = 0;
922 pp1 = loadedPreprocessorPlugins;
923 while (pp1 != NULL)
924 {
925 pp2 = loadedPreprocessorPlugins;
926 while (pp2 != NULL)
927 {
928 /* Obviously, the same ones will be the same */
929 if (pp1 != pp2)
930 {
931 meta1 = &pp1->metaData;
932 meta2 = &pp2->metaData;
933 if (!strcmp(meta1->uniqueName, meta2->uniqueName))
934 {
935 /* Uh, same uniqueName. */
936 if ((meta1->major > meta2->major) ||
937 ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) ||
938 ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) )
939 {
940 /* Lib1 is newer */
941 RemovePreprocessorPlugin(pp2);
942 removed = 1;
943 }
944 else if ((meta2->major > meta1->major) ||
945 ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) ||
946 ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) )
947 {
948 /* Lib2 is newer */
949 RemovePreprocessorPlugin(pp1);
950 removed = 1;
951 }
952 else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) )
953 {
954 /* Duplicate */
955 RemovePreprocessorPlugin(pp2);
956 removed = 1;
957 }
958 }
959 }
960 /* If we removed anything, start back at the beginning */
961 if (removed)
962 break;
963 pp2 = pp2->next;
964 }
965 /* If we removed anything, start back at the beginning */
966 if (removed)
967 break;
968 pp1 = pp1->next;
969 }
970 } while (removed);
971 }
972
VerifyDetectionPluginRequirements(SnortConfig * sc)973 void VerifyDetectionPluginRequirements(SnortConfig *sc)
974 {
975 DynamicDetectionPlugin *lib1 = NULL;
976
977 /* Remove all the duplicates */
978 RemoveDuplicateDetectionPlugins(sc);
979
980 /* Cycle through all of them, and ensure that the required
981 * detection engine is loaded.
982 */
983 lib1 = sc->loadedDetectionPlugins;
984 while (lib1 != NULL)
985 {
986 /* Do this check if this library is a DETECTION plugin only.
987 * If it also has an internal engine, we're fine.
988 */
989 if (lib1->metaData.type == TYPE_DETECTION)
990 {
991 RequiredEngineLibFunc engineFunc;
992 DynamicPluginMeta reqEngineMeta;
993 DynamicEnginePlugin *plugin = loadedEngines;
994 int detectionLibOkay = 0;
995
996 engineFunc = (RequiredEngineLibFunc) getSymbol(lib1->handle, "EngineVersion", &(lib1->metaData), FATAL);
997
998 engineFunc(&reqEngineMeta);
999 while (plugin != NULL)
1000 {
1001 /* Exact match. Yes! */
1002 if (!strcmp(plugin->metaData.uniqueName, reqEngineMeta.uniqueName) &&
1003 plugin->metaData.major == reqEngineMeta.major &&
1004 plugin->metaData.minor == reqEngineMeta.minor)
1005 {
1006 detectionLibOkay = 1;
1007 break;
1008 }
1009
1010 /* Major match, minor must be >= */
1011 if (!strcmp(plugin->metaData.uniqueName, reqEngineMeta.uniqueName) &&
1012 plugin->metaData.major == reqEngineMeta.major &&
1013 plugin->metaData.minor >= reqEngineMeta.minor)
1014 {
1015 detectionLibOkay = 1;
1016 break;
1017 }
1018
1019 /* Major must be >= -- this assumes newer engine is
1020 * bass-ackwards compatabile */
1021 if (!strcmp(plugin->metaData.uniqueName, reqEngineMeta.uniqueName) &&
1022 plugin->metaData.major > reqEngineMeta.major)
1023 {
1024 detectionLibOkay = 1;
1025 break;
1026 }
1027
1028 plugin = plugin->next;
1029 }
1030 if (!detectionLibOkay)
1031 {
1032 FatalError("Loaded dynamic detection plugin %s (version %d:%d:%d) "
1033 "could not find required engine plugin %s(version %d:%d)\n",
1034 lib1->metaData.uniqueName, lib1->metaData.major, lib1->metaData.minor, lib1->metaData.build,
1035 reqEngineMeta.uniqueName, reqEngineMeta.major, reqEngineMeta.minor);
1036 }
1037 }
1038
1039 lib1 = lib1->next;
1040 }
1041 }
1042
InitDynamicEnginePlugins(DynamicEngineData * info)1043 int InitDynamicEnginePlugins(DynamicEngineData *info)
1044 {
1045 DynamicEnginePlugin *plugin;
1046 RemoveDuplicateEngines();
1047
1048 plugin = loadedEngines;
1049 while (plugin)
1050 {
1051 if (plugin->initFunc(info))
1052 {
1053 FatalError("Failed to initialize dynamic engine: %s version %d.%d.%d\n",
1054 plugin->metaData.uniqueName, plugin->metaData.major,
1055 plugin->metaData.minor, plugin->metaData.build);
1056 //return -1;
1057 }
1058
1059 plugin = plugin->next;
1060 }
1061 return 0;
1062 }
1063
1064 typedef struct _DynamicRuleSessionData
1065 {
1066 uint32_t sid;
1067 uint32_t revision;
1068 void *data;
1069 void *compression_data;
1070 struct _DynamicRuleSessionData *next;
1071
1072 } DynamicRuleSessionData;
1073
1074 static uint32_t so_rule_memory = 0;
1075
SoRuleMemInUse()1076 static size_t SoRuleMemInUse()
1077 {
1078 return (size_t) so_rule_memory;
1079 }
1080 /*Only only message will be logged within 60 seconds*/
1081 static ThrottleInfo error_throttleInfo = {0,60,0};
1082
DynamicRuleDataAlloc(size_t size)1083 static void * DynamicRuleDataAlloc(size_t size)
1084 {
1085 size_t alloc_size = size + sizeof(size_t);
1086 size_t *ret;
1087
1088 if ((ScSoRuleMemcap() > 0)
1089 && (so_rule_memory + alloc_size) > ScSoRuleMemcap())
1090 {
1091 ErrorMessageThrottled(&error_throttleInfo,"SO rule memcap exceeded: Wanted to allocate "
1092 "%u bytes (and %d overhead) with memcap: %u and "
1093 "current memory: %u\n", (uint32_t)size,
1094 (int)sizeof(size_t), ScSoRuleMemcap(), so_rule_memory);
1095 return NULL;
1096 }
1097
1098 ret = (size_t *)SnortAlloc(alloc_size);
1099 ret[0] = alloc_size;
1100 so_rule_memory += alloc_size;
1101 return (void *)&ret[1];
1102 }
1103
DynamicRuleDataFree(void * data)1104 static void DynamicRuleDataFree(void *data)
1105 {
1106 if (data != NULL)
1107 {
1108 size_t *alloc_data = (size_t *)data - 1;
1109 size_t size = alloc_data[0];
1110
1111 /* Just in case of an an imbalance of DynamicRuleDataAlloc
1112 * and this function are used */
1113 if (size >= so_rule_memory)
1114 so_rule_memory = 0;
1115 else
1116 so_rule_memory -= size;
1117 free(alloc_data);
1118 }
1119 }
1120
DynamicRuleDataFreeSession(void * data)1121 static void DynamicRuleDataFreeSession(void *data)
1122 {
1123 DynamicRuleSessionData *drsd = (DynamicRuleSessionData *)data;
1124
1125 while (drsd != NULL)
1126 {
1127 DynamicRuleSessionData *tmp = drsd;
1128 drsd = drsd->next;
1129
1130 DynamicRuleDataFree(tmp->data);
1131
1132 #ifdef SNORT_RELOAD
1133 ada_appdata_freed(ada, tmp);
1134 #endif
1135 if (tmp->compression_data)
1136 {
1137 DynamicDecompressDestroy(tmp->compression_data);
1138 }
1139 DynamicRuleDataFree(tmp);
1140 }
1141 }
1142
DynamicSetRuleData(void * p,const RuleInformation * info,void * data,void * compression_data)1143 int DynamicSetRuleData(void *p, const RuleInformation *info, void *data, void *compression_data)
1144 {
1145 Packet *pkt = (Packet *)p;
1146 if (stream_api && pkt && pkt->ssnptr)
1147 {
1148 DynamicRuleSessionData *head =
1149 (DynamicRuleSessionData *)session_api->get_application_data(pkt->ssnptr, PP_SHARED_RULES);
1150 DynamicRuleSessionData *tmp = head;
1151 DynamicRuleSessionData *tail = NULL;
1152
1153 /* Can't reset head without setting application data again which
1154 * will free what's there already, so have to iterate to end of list
1155 * Also need to iterate for duplicates */
1156 while (tmp != NULL)
1157 {
1158 if (tmp->sid == info->sigID)
1159 {
1160 /* Not the same data */
1161 if (tmp->data != data)
1162 {
1163 /* Cleanup the old and replace with the new */
1164 DynamicRuleDataFree(tmp->data);
1165 tmp->data = data;
1166 }
1167 /* Not the same data */
1168 if (tmp->compression_data && tmp->compression_data != compression_data)
1169 {
1170 /* Cleanup the old */
1171 DynamicDecompressDestroy(tmp->compression_data);
1172 }
1173 tmp->compression_data = compression_data;
1174
1175 tmp->revision = info->revision;
1176 return 0;
1177 }
1178
1179 tail = tmp;
1180 tmp = tmp->next;
1181 }
1182
1183 tmp = (DynamicRuleSessionData *)DynamicRuleDataAlloc(sizeof(DynamicRuleSessionData));
1184 if (tmp == NULL)
1185 return -1;
1186
1187 tmp->data = data;
1188 tmp->sid = info->sigID;
1189 tmp->revision = info->revision;
1190
1191 if (head == NULL)
1192 {
1193 if (session_api->set_application_data(pkt->ssnptr, PP_SHARED_RULES,
1194 (void *)tmp, DynamicRuleDataFreeSession) != 0)
1195 {
1196 DynamicRuleDataFree(tmp);
1197 return -1;
1198 }
1199 #ifdef SNORT_RELOAD
1200 ada_add( ada, (void *)tmp, pkt->ssnptr );
1201 #endif
1202 }
1203 else
1204 {
1205 tail->next = tmp;
1206 }
1207
1208 return 0;
1209 }
1210
1211 return -1;
1212 }
1213
DynamicGetRuleData(void * p,const RuleInformation * info,void ** p_data,void ** p_compression_data)1214 void DynamicGetRuleData(void *p, const RuleInformation *info, void **p_data, void **p_compression_data)
1215 {
1216 Packet *pkt = (Packet *)p;
1217 void *compression_data;
1218
1219 if (!p_compression_data)
1220 p_compression_data = &compression_data;
1221 *p_data = NULL;
1222 *p_compression_data = NULL;
1223 if (stream_api && pkt && pkt->ssnptr)
1224 {
1225 DynamicRuleSessionData *head =
1226 (DynamicRuleSessionData *)session_api->get_application_data(pkt->ssnptr, PP_SHARED_RULES);
1227
1228 while (head != NULL)
1229 {
1230 if (head->sid == info->sigID)
1231 {
1232 if (head->revision != info->revision)
1233 {
1234 DynamicRuleDataFree(head->data);
1235 head->data = NULL;
1236 if (head->compression_data)
1237 {
1238 DynamicDecompressDestroy(head->compression_data);
1239 head->compression_data = NULL;
1240 }
1241 }
1242 *p_data = head->data;
1243 *p_compression_data = head->compression_data;
1244 return;
1245 }
1246
1247 head = head->next;
1248 }
1249 }
1250 }
1251
pcreCompile(const char * pattern,int options,const char ** errptr,int * erroffset,const unsigned char * tableptr)1252 void *pcreCompile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr)
1253 {
1254 options &= ~SNORT_PCRE_OVERRIDE_MATCH_LIMIT;
1255 return (void *)pcre_compile(pattern, options, errptr, erroffset, tableptr);
1256 }
1257
pcreStudy(struct _SnortConfig * sc,const void * code,int options,const char ** errptr)1258 void *pcreStudy(struct _SnortConfig *sc, const void *code, int options, const char **errptr)
1259 {
1260 pcre_extra *extra_extra;
1261 int snort_options = options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT;
1262
1263 extra_extra = pcre_study((const pcre*)code, 0, errptr);
1264
1265 if (extra_extra)
1266 {
1267 if ((ScPcreMatchLimitNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT))
1268 {
1269 if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT)
1270 {
1271 extra_extra->match_limit = ScPcreMatchLimitNewConf(sc);
1272 }
1273 else
1274 {
1275 extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
1276 extra_extra->match_limit = ScPcreMatchLimitNewConf(sc);
1277 }
1278 }
1279
1280 #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
1281 if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT))
1282 {
1283 if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION)
1284 {
1285 extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
1286 }
1287 else
1288 {
1289 extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
1290 extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
1291 }
1292 }
1293 #endif
1294 }
1295 else
1296 {
1297 if (!(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT) &&
1298 ((ScPcreMatchLimitNewConf(sc) != -1) || (ScPcreMatchLimitRecursionNewConf(sc) != -1)))
1299 {
1300 extra_extra = (pcre_extra *)SnortAlloc(sizeof(pcre_extra));
1301 if (ScPcreMatchLimitNewConf(sc) != -1)
1302 {
1303 extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
1304 extra_extra->match_limit = ScPcreMatchLimitNewConf(sc);
1305 }
1306
1307 #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
1308 if (ScPcreMatchLimitRecursionNewConf(sc) != -1)
1309 {
1310 extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
1311 extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
1312 }
1313 #endif
1314 }
1315 }
1316
1317 return extra_extra;
1318 }
1319
1320 /* pcreOvectorInfo
1321 *
1322 * Get the Ovector configuration for PCRE from the snort.conf
1323 */
pcreOvectorInfo(int ** ovector,int * ovector_size)1324 void pcreOvectorInfo(int **ovector, int *ovector_size)
1325 {
1326 *ovector = snort_conf->pcre_ovector;
1327 *ovector_size = snort_conf->pcre_ovector_size;
1328 }
1329
pcreExec(const void * code,const void * extra,const char * subj,int len,int start,int options,int * ovec,int ovecsize)1330 int pcreExec(const void *code, const void *extra, const char *subj,
1331 int len, int start, int options, int *ovec, int ovecsize)
1332 {
1333 return pcre_exec((const pcre *)code, (const pcre_extra *)extra, subj, len, start, options, ovec, ovecsize);
1334 }
1335
setFlowId(const void * p,uint32_t id)1336 static int setFlowId(const void* p, uint32_t id)
1337 {
1338 return DAQ_ModifyFlowOpaque(p, id);
1339 }
1340
1341 #ifdef DAQ_MODFLOW_TYPE_PRESERVE_FLOW
setPreserveFlow(const void * p)1342 static int setPreserveFlow(const void* p)
1343 {
1344 DAQ_ModFlow_t mod;
1345 int value = 1;
1346
1347 if ( Active_GetTunnelBypass() )
1348 return -1;
1349
1350 mod.type = DAQ_MODFLOW_TYPE_PRESERVE_FLOW;
1351 mod.length = sizeof(value);
1352 mod.value = (void*)&value;
1353 DAQ_ModifyFlow(p, &mod);
1354
1355 return 0;
1356 }
1357 #endif
1358
getHttpBuffer(HTTP_BUFFER hb_type,unsigned * len)1359 static const uint8_t* getHttpBuffer (HTTP_BUFFER hb_type, unsigned* len)
1360 {
1361 const HttpBuffer* hb = GetHttpBuffer(hb_type);
1362 if ( !hb )
1363 return NULL;
1364
1365 *len = hb->length;
1366 return hb->buf;
1367 }
1368
InitDynamicEngines(char * dynamic_rules_path)1369 int InitDynamicEngines(char *dynamic_rules_path)
1370 {
1371 DynamicEngineData engineData;
1372
1373 engineData.version = ENGINE_DATA_VERSION;
1374 engineData.altBuffer = (SFDataBuffer *)&DecodeBuffer;
1375 engineData.altDetect = (SFDataPointer *)&DetectBuffer;
1376 engineData.fileDataBuf = (SFDataPointer *)&file_data_ptr;
1377
1378 /* This is defined in dynamic-plugins/sp_dynamic.h */
1379 engineData.ruleRegister = &RegisterDynamicRule;
1380 engineData.flowbitRegister = &DynamicFlowbitRegister;
1381 engineData.flowbitCheck = &DynamicFlowbitCheck;
1382 engineData.asn1Detect = &DynamicAsn1Detect;
1383
1384 if (dynamic_rules_path != NULL)
1385 engineData.dataDumpDirectory = SnortStrdup(dynamic_rules_path);
1386 else
1387 engineData.dataDumpDirectory = NULL;
1388
1389 engineData.logMsg = &LogMessage;
1390 engineData.errMsg = &ErrorMessage;
1391 engineData.fatalMsg = &FatalError;
1392
1393 engineData.preprocRuleOptInit = &DynamicPreprocRuleOptInit;
1394
1395 engineData.setRuleData = &DynamicSetRuleData;
1396 engineData.getRuleData = &DynamicGetRuleData;
1397
1398 engineData.sfUnfold = &DynamicsfUnfold;
1399 engineData.sfbase64decode = &Dynamicsfbase64decode;
1400 engineData.GetAltDetect = &DynamicGetAltDetect;
1401 engineData.SetAltDetect = &DynamicSetAltDetect;
1402 engineData.Is_DetectFlag = &DynamicIsDetectFlag;
1403 engineData.DetectFlag_Disable = &DynamicDetectFlagDisable;
1404
1405 engineData.debugMsg = &DebugMessageFunc;
1406 #ifdef SF_WCHAR
1407 engineData.debugWideMsg = &DebugWideMessageFunc;
1408 #endif
1409 #ifdef DEBUG_MSGS
1410 engineData.debugMsgFile = &DebugMessageFile;
1411 engineData.debugMsgLine = &DebugMessageLine;
1412 #else
1413 engineData.debugMsgFile = &no_file;
1414 engineData.debugMsgLine = &no_line;
1415 #endif
1416
1417 engineData.pcreStudy = &pcreStudy;
1418 engineData.pcreCompile = &pcreCompile;
1419 engineData.pcreExec = &pcreExec;
1420
1421 engineData.allocRuleData = &DynamicRuleDataAlloc;
1422 engineData.freeRuleData = &DynamicRuleDataFree;
1423
1424 engineData.flowbitUnregister = &DynamicFlowbitUnregister;
1425
1426 engineData.pcreCapture = &PcreCapture;
1427 engineData.pcreOvectorInfo = &pcreOvectorInfo;
1428 engineData.getHttpBuffer = getHttpBuffer;
1429
1430 engineData.decompressInit = &DynamicDecompressInit;
1431 engineData.decompressDestroy = &DynamicDecompressDestroy;
1432 engineData.decompress = &DynamicDecompress;
1433
1434 return InitDynamicEnginePlugins(&engineData);
1435 }
1436
InitDynamicPreprocessorPlugins(DynamicPreprocessorData * info)1437 int InitDynamicPreprocessorPlugins(DynamicPreprocessorData *info)
1438 {
1439 DynamicPreprocessorPlugin *plugin;
1440 RemoveDuplicatePreprocessorPlugins();
1441
1442 plugin = loadedPreprocessorPlugins;
1443 while (plugin)
1444 {
1445 int i = plugin->initFunc(info);
1446 if (i)
1447 {
1448 FatalError("Failed to initialize dynamic preprocessor: %s version %d.%d.%d (%d)\n",
1449 plugin->metaData.uniqueName, plugin->metaData.major,
1450 plugin->metaData.minor, plugin->metaData.build, i);
1451 //return -1;
1452 }
1453
1454 plugin = plugin->next;
1455 }
1456 #ifdef SNORT_RELOAD
1457 if (!ada) {
1458 ada = ada_init(SoRuleMemInUse, PP_SHARED_RULES, (size_t) ScSoRuleMemcap());
1459 if (!ada) {
1460 FatalError("Failed to initialize so_rule session cache. \n");
1461 }
1462 }
1463 #endif
1464 return 0;
1465 }
1466
1467 /* Do this to avoid exposing Packet & PreprocessFuncNode from
1468 * snort to non-GPL code */
1469 typedef void (*SnortPacketProcessFunc)(Packet *, void *);
AddPreprocessor(struct _SnortConfig * sc,void (* pp_func)(void *,void *),uint16_t priority,uint32_t preproc_id,uint32_t proto_mask)1470 void *AddPreprocessor(struct _SnortConfig *sc, void (*pp_func)(void *, void *), uint16_t priority,
1471 uint32_t preproc_id, uint32_t proto_mask)
1472 {
1473 SnortPacketProcessFunc preprocessorFunc = (SnortPacketProcessFunc)pp_func;
1474 return (void *)AddFuncToPreprocList(sc, preprocessorFunc, priority, preproc_id, proto_mask);
1475 }
1476
AddPreprocessorAllPolicies(struct _SnortConfig * sc,void (* pp_func)(void *,void *),uint16_t priority,uint32_t preproc_id,uint32_t proto_mask)1477 void *AddPreprocessorAllPolicies(struct _SnortConfig *sc, void (*pp_func)(void *, void *),
1478 uint16_t priority, uint32_t preproc_id, uint32_t proto_mask)
1479 {
1480 SnortPacketProcessFunc preprocessorFunc = (SnortPacketProcessFunc)pp_func;
1481 AddFuncToPreprocListAllNapPolicies(sc, preprocessorFunc, priority, preproc_id, proto_mask);
1482 return NULL;
1483 }
1484
1485 typedef void (*MetadataProcessFunc)(int, const uint8_t *);
AddMetaEval(struct _SnortConfig * sc,void (* meta_eval_func)(int,const uint8_t *),uint16_t priority,uint32_t preproc_id)1486 void *AddMetaEval(struct _SnortConfig *sc, void (*meta_eval_func)(int, const uint8_t *), uint16_t priority,
1487 uint32_t preproc_id)
1488 {
1489 MetadataProcessFunc metaEvalFunc = (MetadataProcessFunc)meta_eval_func;
1490 return (void *)AddFuncToPreprocMetaEvalList(sc, metaEvalFunc, priority, preproc_id);
1491 }
1492
AddDetection(struct _SnortConfig * sc,void (* det_func)(void *,void *),uint16_t priority,uint32_t det_id,uint32_t proto_mask)1493 void *AddDetection(struct _SnortConfig *sc, void (*det_func)(void *, void *), uint16_t priority,
1494 uint32_t det_id, uint32_t proto_mask)
1495 {
1496 SnortPacketProcessFunc detectionFunc = (SnortPacketProcessFunc)det_func;
1497 return (void *)AddFuncToDetectionList(sc, detectionFunc, priority, det_id, proto_mask);
1498 }
1499
AddPreprocessorCheck(struct _SnortConfig * sc,int (* pp_chk_func)(struct _SnortConfig * sc))1500 void AddPreprocessorCheck(struct _SnortConfig *sc, int (*pp_chk_func)(struct _SnortConfig *sc))
1501 {
1502 AddFuncToConfigCheckList(sc, pp_chk_func);
1503 }
1504
DynamicDisableDetection(void * p)1505 void DynamicDisableDetection( void *p )
1506 {
1507 DisableDetect( ( Packet * ) p );
1508 }
1509
DynamicDisableAllDetection(void * p)1510 void DynamicDisableAllDetection( void *p )
1511 {
1512 DisableAllDetect( ( Packet * ) p );
1513 }
1514
DynamicEnableContentDetection(void)1515 void DynamicEnableContentDetection( void )
1516 {
1517 EnableContentDetect();
1518 }
1519
DynamicDisablePacketAnalysis(void * p)1520 void DynamicDisablePacketAnalysis( void *p )
1521 {
1522 DisablePacketAnalysis( ( Packet * ) p );
1523 }
1524
DynamicDetect(void * p)1525 int DynamicDetect(void *p)
1526 {
1527 return Detect((Packet *)p);
1528 }
1529
DynamicEnablePreprocessor(void * p,uint32_t preprocId)1530 int DynamicEnablePreprocessor(void *p, uint32_t preprocId)
1531 {
1532 return EnablePreprocessor((Packet *)p, preprocId);
1533 }
1534
1535 #ifdef ACTIVE_RESPONSE
DynamicActiveSetEnabled(int on_off)1536 void DynamicActiveSetEnabled(int on_off)
1537 {
1538 Active_SetEnabled(on_off);
1539 }
1540 #endif
1541
DynamicGetRuleClassByName(char * name)1542 void *DynamicGetRuleClassByName(char *name)
1543 {
1544 return (void *)ClassTypeLookupByType(snort_conf, name);
1545 }
1546
DynamicGetRuleClassById(int id)1547 void *DynamicGetRuleClassById(int id)
1548 {
1549 return (void *)ClassTypeLookupById(snort_conf, id);
1550 }
1551
DynamicRegisterPreprocessorProfile(const char * keyword,void * stats,int layer,void * parent,PreprocStatsNodeFreeFunc freefn)1552 void DynamicRegisterPreprocessorProfile(const char *keyword, void *stats, int layer, void *parent, PreprocStatsNodeFreeFunc freefn)
1553 {
1554 #ifdef PERF_PROFILING
1555 RegisterPreprocessorProfile(keyword, (PreprocStats *)stats, layer, (PreprocStats *)parent, freefn);
1556 #endif
1557 }
1558
DynamicProfilingPreprocs(void)1559 int DynamicProfilingPreprocs(void)
1560 {
1561 #ifdef PERF_PROFILING
1562 return ScProfilePreprocs();
1563 #else
1564 return 0;
1565 #endif
1566 }
1567
DynamicPreprocess(void * packet)1568 int DynamicPreprocess(void *packet)
1569 {
1570 return Preprocess( ( Packet * ) packet );
1571 }
1572
DynamicDisablePreprocessors(void * p)1573 void DynamicDisablePreprocessors(void *p)
1574 {
1575 DisableAppPreprocessors( ( Packet * ) p );
1576 }
1577
DynamicIP6Build(void * p,const void * hdr,int family)1578 void DynamicIP6Build(void *p, const void *hdr, int family)
1579 {
1580 sfiph_build((Packet *)p, hdr, family);
1581 }
1582
DynamicIP6SetCallbacks(void * p,int family,char orig)1583 static inline void DynamicIP6SetCallbacks(void *p, int family, char orig)
1584 {
1585 set_callbacks((Packet *)p, family, orig);
1586 }
1587
DynamicSnortEventqLog(void * p)1588 int DynamicSnortEventqLog(void *p)
1589 {
1590 return SnortEventqLog(snort_conf->event_queue, (Packet *)p);
1591 }
1592
DynamicGetParserPolicy(struct _SnortConfig * sc)1593 tSfPolicyId DynamicGetParserPolicy(struct _SnortConfig *sc)
1594 {
1595 return getParserPolicy(sc);
1596 }
1597
DynamicGetNapRuntimePolicy(void)1598 tSfPolicyId DynamicGetNapRuntimePolicy(void)
1599 {
1600 return getNapRuntimePolicy();
1601 }
1602
DynamicGetIpsRuntimePolicy(void)1603 tSfPolicyId DynamicGetIpsRuntimePolicy(void)
1604 {
1605 return getIpsRuntimePolicy();
1606 }
1607
DynamicGetDefaultPolicy(void)1608 tSfPolicyId DynamicGetDefaultPolicy(void)
1609 {
1610 return getDefaultPolicy();
1611 }
1612
DynamicGetPolicyFromId(uint16_t id)1613 tSfPolicyId DynamicGetPolicyFromId(uint16_t id)
1614 {
1615 return sfPolicyIdGetBinding(snort_conf->policy_config, id);
1616 }
1617
DynamicChangeNapRuntimePolicy(tSfPolicyId new_id,void * scb)1618 void DynamicChangeNapRuntimePolicy(tSfPolicyId new_id, void *scb)
1619 {
1620 session_api->set_runtime_policy( scb, SNORT_NAP_POLICY, new_id );
1621 setNapRuntimePolicy(new_id);
1622 }
1623
DynamicChangeIpsRuntimePolicy(tSfPolicyId new_id,void * p)1624 void DynamicChangeIpsRuntimePolicy(tSfPolicyId new_id, void *p)
1625 {
1626 Packet *pkt = (Packet *) p;
1627
1628 session_api->set_runtime_policy( pkt->ssnptr, SNORT_IPS_POLICY, new_id );
1629 setIpsRuntimePolicy(new_id);
1630 pkt->configPolicyId = snort_conf->targeted_policies[new_id]->configPolicyId;
1631 }
1632
DynamicAddPktTraceData(int module,int strLen)1633 static void DynamicAddPktTraceData(int module, int strLen)
1634 {
1635 addPktTraceData(module, strLen);
1636 }
1637
DynamicGetPktTraceActionMsg()1638 static const char* DynamicGetPktTraceActionMsg()
1639 {
1640 return getPktTraceActMsg();
1641 }
1642
DynamicEncodeNew(void)1643 static void* DynamicEncodeNew (void)
1644 {
1645 return (void*)Encode_New();
1646 }
1647
DynamicEncodeDelete(void * p)1648 static void DynamicEncodeDelete (void *p)
1649 {
1650 Encode_Delete((Packet*)p);
1651 }
1652
DynamicNewGrinderPkt(void * p,void * phdr,uint8_t * pkt)1653 static void *DynamicNewGrinderPkt(void *p, void *phdr, uint8_t *pkt)
1654 {
1655 return (void*)NewGrinderPkt((Packet *)p, (DAQ_PktHdr_t *)phdr, pkt);
1656 }
1657
DynamicDeleteGrinderPkt(void * p)1658 static void DynamicDeleteGrinderPkt(void *p)
1659 {
1660 DeleteGrinderPkt((Packet*)p);
1661 }
1662
DynamicEncodeFormat(uint32_t f,const void * p,void * c,int t)1663 static int DynamicEncodeFormat (uint32_t f, const void* p, void *c, int t)
1664 {
1665 return Encode_Format(f, (Packet*)p, (Packet*)c, (PseudoPacketType)t);
1666 }
1667
DynamicEncodeUpdate(void * p)1668 static void DynamicEncodeUpdate (void* p)
1669 {
1670 Encode_Update((Packet*)p);
1671 }
1672
1673 #ifdef ACTIVE_RESPONSE
DynamicSendBlockResponseMsg(void * p,const uint8_t * buffer,uint32_t buffer_len,unsigned flags)1674 void DynamicSendBlockResponseMsg(void *p, const uint8_t* buffer, uint32_t buffer_len, unsigned flags)
1675 {
1676 Packet *packet = (Packet *)p;
1677 EncodeFlags df = (packet->packet_flags & PKT_FROM_SERVER) ? ENC_FLAG_FWD:0;
1678
1679 if ( !packet->data || packet->dsize == 0 )
1680 return;
1681
1682 if (flags & SND_BLK_RESP_FLAG_DO_CLIENT)
1683 df |= ENC_FLAG_RST_CLNT;
1684 if (flags & SND_BLK_RESP_FLAG_DO_SERVER)
1685 df |= ENC_FLAG_RST_SRVR;
1686 if (packet->packet_flags & PKT_STREAM_EST)
1687 Active_SendData(packet, df, buffer, buffer_len);
1688 }
1689
DynamicActiveResponseMsg(void * p,const uint8_t * buf,uint32_t blen,unsigned flags)1690 void DynamicActiveResponseMsg(void *p, const uint8_t* buf, uint32_t blen, unsigned flags)
1691 {
1692 EncodeFlags df = (SND_BLK_RESP_FLAG_DO_CLIENT) ? 0: ENC_FLAG_FWD;
1693
1694 Active_UDPInjectData((Packet *)p, df , buf, blen);
1695 }
DynamicActiveInjectData(void * p,uint32_t flags,const uint8_t * buf,uint32_t blen)1696 void DynamicActiveInjectData(void *p, uint32_t flags, const uint8_t *buf, uint32_t blen)
1697 {
1698 Active_InjectData((Packet *)p, (EncodeFlags)flags, buf, blen);
1699 }
1700
DynamicActiveSendForwardReset(void * p)1701 void DynamicActiveSendForwardReset(void *p)
1702 {
1703 Active_SendReset((Packet *)p, ENC_FLAG_FWD);
1704 }
1705
DynamicActiveQueueResponse(Active_ResponseFunc cb,void * data)1706 int DynamicActiveQueueResponse( Active_ResponseFunc cb, void *data )
1707 {
1708 return Active_QueueResponse( cb, data );
1709 }
1710
1711 #endif
1712
DynamicDropPacket(void * p)1713 void DynamicDropPacket(void *p)
1714 {
1715 Active_DropPacket((Packet*)p);
1716 }
1717
DynamicRetryPacket(void * p)1718 bool DynamicRetryPacket(void *p)
1719 {
1720 return Active_DAQRetryPacket( ( Packet * ) p );
1721 }
1722
DynamicActivePacketWasDropped(void)1723 bool DynamicActivePacketWasDropped(void)
1724 {
1725 return Active_PacketWasDropped();
1726 }
1727
DynamicForceDropPacket(void * p)1728 void DynamicForceDropPacket(void *p)
1729 {
1730 Active_ForceDropPacket( );
1731 }
1732
DynamicDropSessionAndReset(void * p)1733 void DynamicDropSessionAndReset(void *p)
1734 {
1735 Active_DropSession((Packet*)p);
1736 }
1737
DynamicForceDropSession(void * p)1738 void DynamicForceDropSession(void *p)
1739 {
1740 Active_ForceDropSession();
1741 }
1742
DynamicForceDropSessionAndReset(void * p)1743 void DynamicForceDropSessionAndReset(void *p)
1744 {
1745 Active_ForceDropResetAction((Packet *)p);
1746 }
1747
1748
DynamicSetParserPolicy(SnortConfig * sc,tSfPolicyId id)1749 void DynamicSetParserPolicy(SnortConfig *sc, tSfPolicyId id)
1750 {
1751 setParserPolicy(sc, id);
1752 }
1753
DynamicSetFileDataPtr(uint8_t * ptr,uint16_t decode_size)1754 void DynamicSetFileDataPtr(uint8_t *ptr, uint16_t decode_size)
1755 {
1756 setFileDataPtr((const uint8_t*)ptr, decode_size);
1757 }
1758
DynamicDetectResetPtr(uint8_t * ptr,uint16_t decode_size)1759 void DynamicDetectResetPtr(uint8_t *ptr, uint16_t decode_size)
1760 {
1761 DetectReset(ptr, decode_size);
1762 }
1763
1764
DynamicSetAltDecode(uint16_t altLen)1765 void DynamicSetAltDecode(uint16_t altLen)
1766 {
1767 SetAltDecode(altLen);
1768 }
1769
DynamicGetNapInlineMode(void)1770 int DynamicGetNapInlineMode(void)
1771 {
1772 return ScNapInlineMode();
1773 }
1774
DynamicGetIpsInlineMode(void)1775 int DynamicGetIpsInlineMode(void)
1776 {
1777 return ScIpsInlineMode();
1778 }
1779
DynamicSnortStrtol(const char * nptr,char ** endptr,int base)1780 long DynamicSnortStrtol(const char *nptr, char **endptr, int base)
1781 {
1782 return SnortStrtol(nptr,endptr,base);
1783 }
1784
DynamicSnortStrtoul(const char * nptr,char ** endptr,int base)1785 unsigned long DynamicSnortStrtoul(const char *nptr, char **endptr, int base)
1786 {
1787 return SnortStrtoul(nptr,endptr,base);
1788 }
1789
DynamicSnortStrnStr(const char * s,int slen,const char * accept)1790 const char *DynamicSnortStrnStr(const char *s, int slen, const char *accept)
1791 {
1792 return SnortStrnStr(s, slen, accept);
1793 }
1794
1795
DynamicSnortStrcasestr(const char * s,int slen,const char * accept)1796 const char *DynamicSnortStrcasestr(const char *s, int slen, const char *accept)
1797 {
1798 return SnortStrcasestr(s, slen, accept);
1799 }
1800
DynamicSnortStrncpy(char * dst,const char * src,size_t dst_size)1801 int DynamicSnortStrncpy(char *dst, const char *src, size_t dst_size)
1802 {
1803 return SnortStrncpy(dst, src, dst_size);
1804 }
1805
DynamicSnortStrnPbrk(const char * s,int slen,const char * accept)1806 const char *DynamicSnortStrnPbrk(const char *s, int slen, const char *accept)
1807 {
1808 return SnortStrnPbrk(s, slen, accept);
1809 }
1810
DynamicEvalRTN(void * rtn,void * p,int check_ports)1811 int DynamicEvalRTN(void *rtn, void *p, int check_ports)
1812 {
1813 return fpEvalRTN((RuleTreeNode *)rtn, (Packet *)p, check_ports);
1814 }
1815
DynamicGetLogDirectory(void)1816 char *DynamicGetLogDirectory(void)
1817 {
1818 return SnortStrdup(snort_conf->log_dir);
1819 }
1820
DynamicGetSnortInstance(void)1821 uint32_t DynamicGetSnortInstance(void)
1822 {
1823 return (snort_conf->event_log_id >> 16);
1824 }
1825
DynamicIsPafEnabled(void)1826 bool DynamicIsPafEnabled(void)
1827 {
1828 return ScPafEnabled();
1829 }
1830
DynamicIsReadMode(void)1831 bool DynamicIsReadMode(void)
1832 {
1833 return ScReadMode();
1834 }
1835
DynamicPktTime(void)1836 time_t DynamicPktTime(void)
1837 {
1838 return packet_time();
1839 }
1840
DynamicGetPktTimeOfDay(struct timeval * tv)1841 void DynamicGetPktTimeOfDay(struct timeval *tv)
1842 {
1843 packet_gettimeofday(tv);
1844 }
1845
1846 #ifdef SIDE_CHANNEL
DynamicIsSCEnabled(void)1847 bool DynamicIsSCEnabled(void)
1848 {
1849 return ScSideChannelEnabled();
1850 }
1851
DynamicSCRegisterRXHandler(uint16_t type,SCMProcessMsgFunc processMsgFunc,void * data)1852 int DynamicSCRegisterRXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data)
1853 {
1854 return SideChannelRegisterRXHandler(type, processMsgFunc, data);
1855 }
1856
DynamicSCPreallocMessageTX(uint32_t length,SCMsgHdr ** hdr_ptr,uint8_t ** msg_ptr,void ** msg_handle)1857 int DynamicSCPreallocMessageTX(uint32_t length, SCMsgHdr **hdr_ptr, uint8_t **msg_ptr, void **msg_handle)
1858 {
1859 return SideChannelPreallocMessageTX(length, hdr_ptr, msg_ptr, msg_handle);
1860 }
1861
DynamicSCEnqueueMessageTX(SCMsgHdr * hdr,const uint8_t * msg,uint32_t length,void * msg_handle,SCMQMsgFreeFunc msgFreeFunc)1862 int DynamicSCEnqueueMessageTX(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc)
1863 {
1864 return SideChannelEnqueueMessageTX(hdr, msg, length, msg_handle, msgFreeFunc);
1865 }
1866 #endif
1867
DynamicCanWhitelist(void)1868 int DynamicCanWhitelist(void)
1869 {
1870 return DAQ_CanWhitelist();
1871 }
1872
1873 #if defined(DAQ_CAPA_CST_TIMEOUT)
DynamicCanGetTimeout(void)1874 bool DynamicCanGetTimeout(void)
1875 {
1876 return Daq_Capa_Timeout;
1877 }
1878 #endif
1879
DynamicSnortIsStrEmpty(const char * s)1880 int DynamicSnortIsStrEmpty(const char *s)
1881 {
1882 return IsEmptyStr((char*)s);
1883 }
1884
DynamicDisableAllPolicies(struct _SnortConfig * sc)1885 static void DynamicDisableAllPolicies(struct _SnortConfig *sc)
1886 {
1887 DisableAllPolicies(sc);
1888 }
1889
DynamicReenablePreprocBitFunc(struct _SnortConfig * sc,unsigned int preproc_id)1890 static int DynamicReenablePreprocBitFunc(struct _SnortConfig *sc, unsigned int preproc_id)
1891 {
1892 return ReenablePreprocBit(sc, preproc_id);
1893 }
1894
1895 #ifdef SIDE_CHANNEL
DynamicSnortSignalMask(void)1896 static sigset_t DynamicSnortSignalMask(void)
1897 {
1898 sigset_t mask;
1899
1900 sigemptyset(&mask);
1901 sigaddset(&mask, SIGTERM);
1902 sigaddset(&mask, SIGQUIT);
1903 sigaddset(&mask, SIGPIPE);
1904 sigaddset(&mask, SIGINT);
1905 sigaddset(&mask, SIGNAL_SNORT_RELOAD);
1906 sigaddset(&mask, SIGNAL_SNORT_DUMP_STATS);
1907 sigaddset(&mask, SIGUSR1);
1908 sigaddset(&mask, SIGUSR2);
1909 sigaddset(&mask, SIGNAL_SNORT_ROTATE_STATS);
1910 sigaddset(&mask, SIGNAL_SNORT_CHILD_READY);
1911 #ifdef TARGET_BASED
1912 sigaddset(&mask, SIGNAL_SNORT_READ_ATTR_TBL);
1913 sigaddset(&mask, SIGVTALRM);
1914 #endif
1915 pthread_sigmask(SIG_SETMASK, &mask, NULL);
1916
1917 return mask;
1918 }
1919 #endif
1920
1921 static SslAppIdLookupFunc sslAppIdLookupFnPtr;
1922
registerSslAppIdLookup(SslAppIdLookupFunc fnptr)1923 static void registerSslAppIdLookup(SslAppIdLookupFunc fnptr)
1924 {
1925 sslAppIdLookupFnPtr = fnptr;
1926 }
1927
sslAppIdLookup(void * ssnptr,const char * serverName,const char * commonName,int32_t * serviceAppId,int32_t * clientAppId,int32_t * payloadAppId)1928 static int sslAppIdLookup(void *ssnptr, const char * serverName, const char * commonName, int32_t *serviceAppId, int32_t *clientAppId, int32_t *payloadAppId)
1929 {
1930 if (sslAppIdLookupFnPtr)
1931 return (sslAppIdLookupFnPtr)(ssnptr, serverName, commonName, serviceAppId, clientAppId, payloadAppId);
1932 return 0;
1933 }
1934
1935 static SetTlsHostAppIdFunc setTlsHostAppIdFnPtr;
1936
registerSetTlsHostAppId(SetTlsHostAppIdFunc fnptr)1937 static void registerSetTlsHostAppId(SetTlsHostAppIdFunc fnptr)
1938 {
1939 setTlsHostAppIdFnPtr = fnptr;
1940 }
1941
setTlsHostAppId(void * ssnptr,const char * serverName,const char * commonName,const char * orgName,const char * subjectAltName,bool isSniMismatch,int32_t * serviceAppId,int32_t * clientAppId,int32_t * payloadAppId)1942 static void setTlsHostAppId(void *ssnptr, const char *serverName, const char *commonName,
1943 const char *orgName, const char *subjectAltName, bool isSniMismatch,
1944 int32_t *serviceAppId, int32_t *clientAppId, int32_t *payloadAppId)
1945 {
1946 if (setTlsHostAppIdFnPtr)
1947 (setTlsHostAppIdFnPtr)(ssnptr, serverName, commonName, orgName, subjectAltName, isSniMismatch, serviceAppId, clientAppId, payloadAppId);
1948 }
1949
1950 static GetAppIdFunc getAppIdFnPtr = NULL;
1951
registerGetAppId(GetAppIdFunc fnptr)1952 static void registerGetAppId(GetAppIdFunc fnptr)
1953 {
1954 getAppIdFnPtr = fnptr;
1955 }
1956
getAppId(void * ssnptr)1957 static int32_t getAppId(void *ssnptr)
1958 {
1959 if(getAppIdFnPtr)
1960 return (getAppIdFnPtr)(ssnptr);
1961 return 0;
1962 }
1963
1964
1965 static UrlQueryCreateFunc urlQueryCreateFnPtr;
1966 static UrlQueryDestroyFunc urlQueryDestroyFnPtr;
1967 static UrlQueryMatchFunc urlQueryMatchFnPtr;
1968 static UserGroupIdGetFunc userGroupIdGetFnPtr;
1969 static GeoIpAddressLookupFunc geoIpAddressLookupFnPtr;
1970 static UpdateSSLSSnLogDataFunc updateSSLSSnLogDataFnPtr;
1971 static EndSSLSSnLogDataFunc endSSLSSnLogDataFnPtr;
1972 static GetSSLActualActionFunc getSSLActualActionFnPtr;
1973 static GetIntfDataFunc getIntfDataFnPtr;
1974 static ReputationProcessExternalIpFunc reputationProcessExternalIpFnPtr;
1975 static ReputationGetEntryCountFunc reputatinGetEntryCountFnPtr;
1976
registerReputationGetEntryCount(ReputationGetEntryCountFunc entryCountFn)1977 void registerReputationGetEntryCount(ReputationGetEntryCountFunc entryCountFn)
1978 {
1979 reputatinGetEntryCountFnPtr = entryCountFn;
1980 }
1981
registerReputationProcessExternal(ReputationProcessExternalIpFunc extProcessFn)1982 void registerReputationProcessExternal(ReputationProcessExternalIpFunc extProcessFn)
1983 {
1984 reputationProcessExternalIpFnPtr = extProcessFn;
1985 }
1986
_reputation_get_entry_count(void)1987 static int _reputation_get_entry_count(void)
1988 {
1989 if(reputatinGetEntryCountFnPtr)
1990 return (reputatinGetEntryCountFnPtr());
1991 return 0;
1992 }
1993
_reputation_process_external_ip(void * p,sfaddr_t * ip)1994 static bool _reputation_process_external_ip(void *p, sfaddr_t* ip)
1995 {
1996 if(reputationProcessExternalIpFnPtr)
1997 {
1998 return ((reputationProcessExternalIpFnPtr)(p,ip));
1999 }
2000 return false;
2001 }
2002
registerUrlQuery(UrlQueryCreateFunc createFn,UrlQueryDestroyFunc destroyFn,UrlQueryMatchFunc matchFn)2003 void registerUrlQuery(UrlQueryCreateFunc createFn, UrlQueryDestroyFunc destroyFn, UrlQueryMatchFunc matchFn)
2004 {
2005 urlQueryCreateFnPtr = createFn;
2006 urlQueryDestroyFnPtr = destroyFn;
2007 urlQueryMatchFnPtr = matchFn;
2008 }
urlQueryCreate(const char * url)2009 static struct urlQueryContext* urlQueryCreate(const char *url)
2010 {
2011 if (urlQueryCreateFnPtr)
2012 {
2013 return ((urlQueryCreateFnPtr)(url));
2014 }
2015
2016 return NULL;
2017 }
urlQueryDestroy(struct urlQueryContext * context)2018 static void urlQueryDestroy(struct urlQueryContext *context)
2019 {
2020 if (urlQueryDestroyFnPtr)
2021 (urlQueryDestroyFnPtr)(context);
2022 }
urlQueryMatch(void * ssnptr,struct urlQueryContext * context,uint16_t inUrlCat,uint16_t inUrlMinRep,uint16_t inUrlMaxRep)2023 static int urlQueryMatch(void *ssnptr, struct urlQueryContext *context, uint16_t inUrlCat, uint16_t inUrlMinRep, uint16_t inUrlMaxRep)
2024 {
2025 if (urlQueryMatchFnPtr)
2026 return (urlQueryMatchFnPtr)(ssnptr, context, inUrlCat, inUrlMinRep, inUrlMaxRep);
2027 return -1;
2028 }
2029
2030 #if defined DAQ_CAPA_CST_TIMEOUT
RegisterGetDaqCapaTimeout(GetDaqCapaTimeOutFunc timeoutFn)2031 void RegisterGetDaqCapaTimeout(GetDaqCapaTimeOutFunc timeoutFn)
2032 {
2033 getDaqCapaTimeoutFnPtr = timeoutFn;
2034 }
2035 #endif
2036
registerUserGroupIdGet(UserGroupIdGetFunc userIdFn)2037 static void registerUserGroupIdGet(UserGroupIdGetFunc userIdFn)
2038 {
2039 userGroupIdGetFnPtr = userIdFn;
2040 }
2041
userGroupIdGet(void * ssnptr,uint32_t * userId,uint32_t * realmId,unsigned * groupIdArray,unsigned groupIdArrayLen)2042 static int userGroupIdGet(void *ssnptr, uint32_t *userId, uint32_t *realmId, unsigned *groupIdArray, unsigned groupIdArrayLen)
2043 {
2044 if (userGroupIdGetFnPtr)
2045 return (userGroupIdGetFnPtr)(ssnptr, userId, realmId, groupIdArray, groupIdArrayLen);
2046 return -1;
2047 }
2048
registerGeoIpAddressLookup(GeoIpAddressLookupFunc fn)2049 static void registerGeoIpAddressLookup(GeoIpAddressLookupFunc fn)
2050 {
2051 geoIpAddressLookupFnPtr = fn;
2052 }
geoIpAddressLookup(const sfaddr_t * snortIp,uint16_t * geo)2053 static int geoIpAddressLookup(const sfaddr_t *snortIp, uint16_t* geo)
2054 {
2055 if (geoIpAddressLookupFnPtr)
2056 return (geoIpAddressLookupFnPtr)(snortIp, geo);
2057 return -1;
2058 }
2059
registerGetIntfData(GetIntfDataFunc fn)2060 static void registerGetIntfData(GetIntfDataFunc fn)
2061 {
2062 getIntfDataFnPtr = fn;
2063 }
2064
getIntfData(void * ssnptr,int32_t * ingressIntfIndex,int32_t * egressIntfIndex,int32_t * ingressZoneIndex,int32_t * egressZoneIndex)2065 static void getIntfData(void *ssnptr, int32_t *ingressIntfIndex, int32_t *egressIntfIndex,
2066 int32_t *ingressZoneIndex, int32_t *egressZoneIndex)
2067 {
2068 if (getIntfDataFnPtr)
2069 {
2070 (getIntfDataFnPtr)(ssnptr, ingressIntfIndex, egressIntfIndex, ingressZoneIndex, egressZoneIndex);
2071 }
2072 }
2073
registerUpdateSSLSSnLogData(UpdateSSLSSnLogDataFunc fn)2074 static void registerUpdateSSLSSnLogData(UpdateSSLSSnLogDataFunc fn)
2075 {
2076 updateSSLSSnLogDataFnPtr = fn;
2077 }
2078
updateSSLSSnLogData(void * ssnptr,uint8_t logging_on,uint8_t action_is_block,const char * ssl_cert_fingerprint,uint32_t ssl_cert_fingerprint_len,uint32_t ssl_cert_status,uint8_t * ssl_policy_id,uint32_t ssl_policy_id_len,uint32_t ssl_rule_id,uint16_t ssl_cipher_suite,uint8_t ssl_version,uint16_t ssl_actual_action,uint16_t ssl_expected_action,uint32_t ssl_url_category,uint16_t ssl_flow_status,uint32_t ssl_flow_error,uint32_t ssl_flow_messages,uint64_t ssl_flow_flags,char * ssl_server_name,uint8_t * ssl_session_id,uint8_t session_id_len,uint8_t * ssl_ticket_id,uint8_t ticket_id_len)2079 static void updateSSLSSnLogData(void *ssnptr, uint8_t logging_on, uint8_t action_is_block, const char *ssl_cert_fingerprint,
2080 uint32_t ssl_cert_fingerprint_len, uint32_t ssl_cert_status, uint8_t *ssl_policy_id,
2081 uint32_t ssl_policy_id_len, uint32_t ssl_rule_id, uint16_t ssl_cipher_suite, uint8_t ssl_version,
2082 uint16_t ssl_actual_action, uint16_t ssl_expected_action, uint32_t ssl_url_category,
2083 uint16_t ssl_flow_status, uint32_t ssl_flow_error, uint32_t ssl_flow_messages,
2084 uint64_t ssl_flow_flags, char *ssl_server_name, uint8_t *ssl_session_id, uint8_t session_id_len,
2085 uint8_t *ssl_ticket_id, uint8_t ticket_id_len)
2086 {
2087 if (updateSSLSSnLogDataFnPtr)
2088 {
2089 (updateSSLSSnLogDataFnPtr)(ssnptr, logging_on, action_is_block, ssl_cert_fingerprint,
2090 ssl_cert_fingerprint_len, ssl_cert_status, ssl_policy_id,
2091 ssl_policy_id_len, ssl_rule_id, ssl_cipher_suite, ssl_version,
2092 ssl_actual_action, ssl_expected_action, ssl_url_category,
2093 ssl_flow_status, ssl_flow_error, ssl_flow_messages,
2094 ssl_flow_flags, ssl_server_name, ssl_session_id, session_id_len, ssl_ticket_id, ticket_id_len);
2095 }
2096 }
2097
registerGetSSLActualAction(GetSSLActualActionFunc fn)2098 static void registerGetSSLActualAction(GetSSLActualActionFunc fn)
2099 {
2100 getSSLActualActionFnPtr = fn;
2101 }
2102
getSSLActualAction(void * ssnptr,uint16_t * action)2103 static int getSSLActualAction(void *ssnptr, uint16_t *action)
2104 {
2105 if (getSSLActualActionFnPtr)
2106 {
2107 return (getSSLActualActionFnPtr)(ssnptr, action);
2108 }
2109
2110 return -1;
2111 }
2112
2113
registerEndSSLSSnLogData(EndSSLSSnLogDataFunc fn)2114 static void registerEndSSLSSnLogData(EndSSLSSnLogDataFunc fn)
2115 {
2116 endSSLSSnLogDataFnPtr = fn;
2117 }
2118
endSSLSSnLogData(void * ssnptr,uint32_t ssl_flow_messages,uint64_t ssl_flow_flags)2119 static void endSSLSSnLogData(void *ssnptr, uint32_t ssl_flow_messages, uint64_t ssl_flow_flags)
2120 {
2121 if (endSSLSSnLogDataFnPtr)
2122 {
2123 (endSSLSSnLogDataFnPtr)(ssnptr, ssl_flow_messages, ssl_flow_flags);
2124 }
2125 }
DynamicReadyForProcess(void * pkt)2126 static inline bool DynamicReadyForProcess (void* pkt)
2127 {
2128 Packet *p = (Packet *)pkt;
2129
2130 if ( ScPafEnabled() )
2131 return PacketHasPAFPayload(p);
2132
2133 return !(p->packet_flags & PKT_STREAM_INSERT);
2134 }
2135
DynamicSetSSLCallback(void * p)2136 void DynamicSetSSLCallback(void *p)
2137 {
2138 SetSSLCallback(p);
2139 }
2140
DynamicGetSSLCallback(void)2141 void *DynamicGetSSLCallback(void)
2142 {
2143 return GetSSLCallback();
2144 }
2145
2146 /*
2147 DynamicIsSSLPolicyEnabled( struct _SnortConfig * )
2148
2149 Notes: Durring reload/init SnortConfig MUST be provided.
2150 Durring runtime/packet processing, NULL MUST be provided.
2151
2152 Arguments: (struct _SnortConfig*) sc
2153 Returns: (bool) true || false
2154 */
DynamicIsSSLPolicyEnabled(struct _SnortConfig * sc)2155 bool DynamicIsSSLPolicyEnabled( struct _SnortConfig *sc )
2156 {
2157 tSfPolicyId policy;
2158 if (sc)
2159 {
2160 policy = getParserPolicy(sc);
2161 return (sc->targeted_policies[ policy ]->ssl_policy_enabled);
2162 }
2163
2164 policy = getNapRuntimePolicy();
2165 return (snort_conf->targeted_policies[ policy ]->ssl_policy_enabled );
2166 }
2167
DynamicSetSSLPolicyEnabled(struct _SnortConfig * sc,tSfPolicyId policy,bool value)2168 void DynamicSetSSLPolicyEnabled(struct _SnortConfig *sc, tSfPolicyId policy, bool value)
2169 {
2170 sc->targeted_policies[policy]->ssl_policy_enabled = value;
2171 }
2172
2173 static ftpGetModefunc ftpGetDataModefnptr;
registerFtpModeQuery(ftpGetModefunc fnptr)2174 void registerFtpModeQuery(ftpGetModefunc fnptr)
2175 {
2176 if (!ftpGetDataModefnptr)
2177 ftpGetDataModefnptr = fnptr;
2178 }
2179
ftpGetDataSessionMode(void * ssnptr)2180 static bool ftpGetDataSessionMode(void *ssnptr)
2181 {
2182 if (ftpGetDataModefnptr)
2183 {
2184 return ((ftpGetDataModefnptr)(ssnptr));
2185 }
2186 return 0;
2187 }
2188
2189 #ifdef SNORT_RELOAD
DynamicReloadAdjustRegister(SnortConfig * sc,const char * raName,tSfPolicyId raPolicyId,ReloadAdjustFunc raFunc,void * raUserData,ReloadAdjustUserFreeFunc raUserFreeFunc)2190 int DynamicReloadAdjustRegister(SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId,
2191 ReloadAdjustFunc raFunc, void* raUserData,
2192 ReloadAdjustUserFreeFunc raUserFreeFunc)
2193 {
2194 return ReloadAdjustRegister(sc, raName, raPolicyId, raFunc, raUserData, raUserFreeFunc);
2195 }
2196 #endif
2197
2198 #if defined(FEAT_OPEN_APPID)
2199 typedef struct _IsAppIdRequiredFuncNode
2200 {
2201 IsAppIdRequiredFunc fn;
2202 struct _IsAppIdRequiredFuncNode * next;
2203 }
2204 IsAppIdRequiredFuncNode;
2205
2206 static IsAppIdRequiredFuncNode * isAppIdRequiredFuncList = NULL;
2207 static pthread_mutex_t isAppIdRequiredFuncListMutex = PTHREAD_MUTEX_INITIALIZER;
2208
registerIsAppIdRequired(IsAppIdRequiredFunc fn)2209 static void registerIsAppIdRequired(IsAppIdRequiredFunc fn)
2210 {
2211 IsAppIdRequiredFuncNode * curr;
2212
2213 if (fn == NULL)
2214 return;
2215
2216 pthread_mutex_lock(&isAppIdRequiredFuncListMutex);
2217
2218 curr = isAppIdRequiredFuncList;
2219 while (curr != NULL)
2220 {
2221 if (curr->fn == fn)
2222 {
2223 pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
2224 return; /* function is already registered */
2225 }
2226 curr = curr->next;
2227 }
2228
2229 curr = malloc(sizeof(IsAppIdRequiredFuncNode));
2230 if (curr == NULL)
2231 {
2232 pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
2233 return;
2234 }
2235
2236 curr->fn = fn;
2237 curr->next = isAppIdRequiredFuncList;
2238 isAppIdRequiredFuncList = curr;
2239
2240 pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
2241 }
2242
unregisterIsAppIdRequired(IsAppIdRequiredFunc fn)2243 static void unregisterIsAppIdRequired(IsAppIdRequiredFunc fn)
2244 {
2245 IsAppIdRequiredFuncNode * tmp;
2246 IsAppIdRequiredFuncNode ** curr;
2247
2248 if (fn == NULL)
2249 return;
2250
2251 pthread_mutex_lock(&isAppIdRequiredFuncListMutex);
2252
2253 curr = &isAppIdRequiredFuncList;
2254 while (*curr != NULL)
2255 {
2256 if ((*curr)->fn == fn)
2257 break;
2258 curr = &((*curr)->next);
2259 }
2260
2261 if (*curr == NULL)
2262 {
2263 pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
2264 return; /* function is not currently registered */
2265 }
2266
2267 tmp = *curr;
2268 *curr = (*curr)->next;
2269
2270 pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
2271
2272 free(tmp);
2273 }
2274
isAppIdRequired(void)2275 static bool isAppIdRequired(void)
2276 {
2277 IsAppIdRequiredFuncNode * curr;
2278
2279 pthread_mutex_lock(&isAppIdRequiredFuncListMutex);
2280
2281 curr = isAppIdRequiredFuncList;
2282 while (curr != NULL)
2283 {
2284 if ((curr->fn != NULL) && curr->fn())
2285 {
2286 pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
2287 return true;
2288 }
2289 curr = curr->next;
2290 }
2291
2292 pthread_mutex_unlock(&isAppIdRequiredFuncListMutex);
2293
2294 return false;
2295 }
2296
dummyGetApplicationName(int32_t appId)2297 static const char *dummyGetApplicationName(int32_t appId)
2298 {
2299 return NULL;
2300 }
2301
dummyGetApplicationId(const char * appName)2302 static tAppId dummyGetApplicationId(const char *appName)
2303 {
2304 return 0;
2305 }
2306
dummyAppIdFFromAppIdData(struct AppIdData * session)2307 static tAppId dummyAppIdFFromAppIdData(struct AppIdData *session)
2308 {
2309 return 0;
2310 }
2311
dummyAppIdMultiPayload(struct AppIdData * session)2312 static SFGHASH* dummyAppIdMultiPayload(struct AppIdData *session)
2313 {
2314 return NULL;
2315 }
2316
dummyCheckAppIdData(struct AppIdData * session)2317 static bool dummyCheckAppIdData(struct AppIdData *session)
2318 {
2319 return false;
2320 }
2321
dummyGetUserName(struct AppIdData * session,tAppId * service,bool * isLoginSuccessful)2322 static char *dummyGetUserName(struct AppIdData *session, tAppId *service, bool *isLoginSuccessful)
2323 {
2324 return NULL;
2325 }
2326
dummyGetClientVersion(struct AppIdData * session)2327 static char *dummyGetClientVersion(struct AppIdData *session)
2328 {
2329 return NULL;
2330 }
2331
dummyGetAppIdSessionAttribute(struct AppIdData * session,uint64_t flag)2332 static uint64_t dummyGetAppIdSessionAttribute(struct AppIdData *session, uint64_t flag)
2333 {
2334 return 0;
2335 }
2336
dummyGetFlowType(struct AppIdData * appIdData)2337 static APPID_FLOW_TYPE dummyGetFlowType(struct AppIdData *appIdData)
2338 {
2339 return APPID_FLOW_TYPE_IGNORE;
2340 }
2341
dummyGetServiceInfo(struct AppIdData * appIdData,char ** serviceVendor,char ** serviceVersion,RNAServiceSubtype ** serviceSubtype)2342 static void dummyGetServiceInfo(struct AppIdData *appIdData, char **serviceVendor, char **serviceVersion, RNAServiceSubtype **serviceSubtype)
2343 {
2344 }
2345
dummyGetServicePort(struct AppIdData * appIdData)2346 static short dummyGetServicePort(struct AppIdData *appIdData)
2347 {
2348 return 0;
2349 }
2350
dummyIpFromAppIdData(struct AppIdData * appIdData)2351 static sfaddr_t *dummyIpFromAppIdData(struct AppIdData *appIdData)
2352 {
2353 return NULL;
2354 }
2355
dummyGetInitiatorIp(struct AppIdData * appIdData)2356 static struct in6_addr *dummyGetInitiatorIp(struct AppIdData *appIdData)
2357 {
2358 return NULL;
2359 }
2360
dummyStringFromAppIdData(struct AppIdData * appIdData)2361 static char *dummyStringFromAppIdData(struct AppIdData *appIdData)
2362 {
2363 return NULL;
2364 }
2365
dummyIndexedStringFromAppIdData(struct AppIdData * appIdData,HTTP_FIELD_ID fieldId)2366 static char *dummyIndexedStringFromAppIdData(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId)
2367 {
2368 return NULL;
2369 }
2370
dummyFreeIndexedStringFromAppIdData(struct AppIdData * appIdData,HTTP_FIELD_ID fieldId)2371 static void dummyFreeIndexedStringFromAppIdData(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId)
2372 {
2373 return;
2374 }
2375
dummyGetHttpFieldOffset(struct AppIdData * appIdData,HTTP_FIELD_ID fieldId)2376 static uint16_t dummyGetHttpFieldOffset(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId)
2377 {
2378 return 0;
2379 }
2380
dummySearchTypeFromAppIdData(struct AppIdData * appIdData)2381 static SEARCH_SUPPORT_TYPE dummySearchTypeFromAppIdData(struct AppIdData *appIdData)
2382 {
2383 return NOT_A_SEARCH_ENGINE;
2384 }
2385
dummyOffsetFromAppIdData(struct AppIdData * appIdData)2386 static uint16_t dummyOffsetFromAppIdData(struct AppIdData *appIdData)
2387 {
2388 return 0;
2389 }
2390
dummyGetDhcpFpData(struct AppIdData * appIdData)2391 static DhcpFPData *dummyGetDhcpFpData(struct AppIdData *appIdData)
2392 {
2393 return NULL;
2394 }
2395
dummyFreeDhcpFpData(struct AppIdData * session,DhcpFPData * data)2396 static void dummyFreeDhcpFpData(struct AppIdData *session, DhcpFPData *data)
2397 {
2398 }
2399
dummyGetDhcpInfo(struct AppIdData * session)2400 static DHCPInfo *dummyGetDhcpInfo(struct AppIdData *session)
2401 {
2402 return NULL;
2403 }
2404
dummyFreeDhcpInfo(struct AppIdData * session,DHCPInfo * data)2405 static void dummyFreeDhcpInfo(struct AppIdData *session, DHCPInfo *data)
2406 {
2407 }
2408
dummyGetSmbFpData(struct AppIdData * session)2409 static FpSMBData *dummyGetSmbFpData(struct AppIdData *session)
2410 {
2411 return NULL;
2412 }
2413
dummyFreeSmbFpData(struct AppIdData * session,FpSMBData * data)2414 static void dummyFreeSmbFpData(struct AppIdData *session, FpSMBData *data)
2415 {
2416 }
2417
dummyGetNetbiosName(struct AppIdData * session)2418 static char *dummyGetNetbiosName(struct AppIdData *session)
2419 {
2420 return NULL;
2421 }
2422
dummyProduceHAState(void * lwssn,uint8_t * buf)2423 static uint32_t dummyProduceHAState(void *lwssn, uint8_t *buf)
2424 {
2425 return 0;
2426 }
2427
dummyConsumeHAState(void * lwssn,const uint8_t * buf,uint8_t length,uint8_t proto,const struct in6_addr * ip,uint16_t initiatorPort)2428 static uint32_t dummyConsumeHAState(void *lwssn, const uint8_t *buf, uint8_t length, uint8_t proto, const struct in6_addr* ip, uint16_t initiatorPort)
2429 {
2430 return 0;
2431 }
2432
dummyGetAppIdData(void * lwssn)2433 static struct AppIdData *dummyGetAppIdData(void *lwssn)
2434 {
2435 return NULL;
2436 }
2437
dummyGetAppIdSessionPacketCount(struct AppIdData * appIdData)2438 static int dummyGetAppIdSessionPacketCount(struct AppIdData * appIdData)
2439 {
2440 return 0;
2441 }
2442
dummyGetDNSQuery(struct AppIdData * session,uint8_t * query_len,bool * got_response)2443 static char *dummyGetDNSQuery(struct AppIdData *session, uint8_t *query_len, bool *got_response)
2444 {
2445 if (query_len)
2446 *query_len = 0;
2447 if (got_response)
2448 *got_response = false;
2449 return NULL;
2450 }
dummyGetDNSOffset(struct AppIdData * session)2451 static uint16_t dummyGetDNSOffset(struct AppIdData *session)
2452 {
2453 return 0;
2454 }
dummyGetDNSRecordType(struct AppIdData * session)2455 static uint16_t dummyGetDNSRecordType(struct AppIdData *session)
2456 {
2457 return 0;
2458 }
dummyGetDNSResponseType(struct AppIdData * session)2459 static uint8_t dummyGetDNSResponseType(struct AppIdData *session)
2460 {
2461 return 0;
2462 }
dummyGetDNSTTL(struct AppIdData * session)2463 static uint32_t dummyGetDNSTTL(struct AppIdData *session)
2464 {
2465 return 0;
2466 }
2467
dummyRemoveExpectedAppIdData(struct AppIdData * appIdData)2468 struct AppIdData* dummyRemoveExpectedAppIdData(struct AppIdData *appIdData)
2469 {
2470 return NULL;
2471 }
2472
dummyDumpDebugHostInfo(void)2473 static void dummyDumpDebugHostInfo(void)
2474 {
2475 }
2476
2477 struct AppIdApi appIdApi = {
2478 dummyGetApplicationName, /* getApplicationName */
2479 dummyGetApplicationId, /* getApplicationId */
2480
2481 dummyAppIdFFromAppIdData, /* getServiceAppId */
2482 dummyAppIdFFromAppIdData, /* getPortServiceAppId */
2483 dummyAppIdFFromAppIdData, /* getOnlyServiceAppId */
2484 dummyAppIdFFromAppIdData, /* getMiscAppId */
2485 dummyAppIdFFromAppIdData, /* getClientAppId */
2486 dummyAppIdFFromAppIdData, /* getPayloadAppId */
2487 dummyAppIdFFromAppIdData, /* getReferredAppId */
2488 dummyAppIdFFromAppIdData, /* getFwServiceAppId */
2489 dummyAppIdFFromAppIdData, /* getFwMiscAppId */
2490 dummyAppIdFFromAppIdData, /* getFwClientAppId */
2491 dummyAppIdFFromAppIdData, /* getFwPayloadAppId */
2492 dummyAppIdFFromAppIdData, /* getFwReferredAppId */
2493 dummyAppIdMultiPayload, /* getFwMultiPayloadList */
2494
2495 dummyCheckAppIdData, /* isSessionSslDecrypted */
2496 dummyCheckAppIdData, /* isAppIdInspectingSession */
2497 dummyCheckAppIdData, /* isAppIdAvailable */
2498
2499 dummyGetUserName, /* getUserName */
2500 dummyGetClientVersion, /* getClientVersion */
2501
2502 dummyGetAppIdSessionAttribute, /* getAppIdSessionAttribute */
2503
2504 dummyGetFlowType, /* getFlowType */
2505 dummyGetServiceInfo, /* getServiceInfo */
2506 dummyGetServicePort, /* getServicePort */
2507 dummyIpFromAppIdData, /* getServiceIp */
2508 dummyGetInitiatorIp, /* getInitiatorIp */
2509
2510 dummyStringFromAppIdData, /* getHttpUserAgent */
2511 dummyStringFromAppIdData, /* getHttpHost */
2512 dummyStringFromAppIdData, /* getHttpUrl */
2513 dummyStringFromAppIdData, /* getHttpReferer */
2514 dummyStringFromAppIdData, /* getHttpNewUrl */
2515 dummyStringFromAppIdData, /* getHttpUri */
2516 dummyStringFromAppIdData, /* getHttpResponseCode */
2517 dummyStringFromAppIdData, /* getHttpCookie */
2518 dummyStringFromAppIdData, /* getHttpNewCookie */
2519 dummyStringFromAppIdData, /* getHttpContentType */
2520 dummyStringFromAppIdData, /* getHttpLocation */
2521 dummyStringFromAppIdData, /* getHttpBody */
2522 dummyStringFromAppIdData, /* getHttpReqBody */
2523 dummyOffsetFromAppIdData, /* getHttpUriOffset */
2524 dummyOffsetFromAppIdData, /* getHttpUriEndOffset */
2525 dummyOffsetFromAppIdData, /* getHttpCookieOffset */
2526 dummyOffsetFromAppIdData, /* getHttpCookieEndOffset */
2527 dummySearchTypeFromAppIdData, /* getHttpSearch */
2528 dummyIpFromAppIdData, /* getHttpXffAddr */
2529
2530
2531 dummyStringFromAppIdData, /* getTlsHost */
2532
2533 dummyGetDhcpFpData, /* getDhcpFpData */
2534 dummyFreeDhcpFpData, /* freeDhcpFpData */
2535 dummyGetDhcpInfo, /* getDhcpInfo */
2536 dummyFreeDhcpInfo, /* freeDhcpInfo */
2537 dummyGetSmbFpData, /* getSmbFpData */
2538 dummyFreeSmbFpData, /* freeSmbFpData */
2539 dummyGetNetbiosName, /* getNetbiosName */
2540 dummyProduceHAState, /* produceHAState */
2541 dummyConsumeHAState, /* consumeHAState */
2542
2543 dummyGetAppIdData, /* getAppIdData */
2544 dummyGetAppIdSessionPacketCount, /* getAppIdSessionPacketCount */
2545
2546 dummyGetDNSQuery, /* getDNSQuery */
2547 dummyGetDNSOffset, /* getDNSQueryoffset */
2548 dummyGetDNSRecordType, /* getDNSQueryType */
2549 dummyGetDNSResponseType, /* getDNSQueryResponseType */
2550 dummyGetDNSTTL, /* getDNSTTL */
2551 dummyGetDNSOffset, /* getDNSOptionsOffset */
2552
2553 dummyIndexedStringFromAppIdData, /* getHttpNewField */
2554 dummyFreeIndexedStringFromAppIdData, /* freeHttpNewField */
2555 dummyGetHttpFieldOffset, /* getHttpFieldOffset */
2556 dummyGetHttpFieldOffset, /* getHttpFieldEndOffset */
2557 dummyCheckAppIdData, /* isHttpInspectionDone */
2558 dummyDumpDebugHostInfo /* dumpDebugHostInfo */
2559 };
2560 #endif /* defined(FEAT_OPEN_APPID) */
2561
GetSnortPerfIndicators(void * p)2562 static int GetSnortPerfIndicators( void *p )
2563 {
2564 return( PerfIndicator_GetIndicators( (Perf_Indicator_Descriptor_p_t)p ) );
2565 }
2566
GetSnortPacketLatency()2567 static uint32_t GetSnortPacketLatency()
2568 {
2569 #ifdef PI_PACKET_LATENCY_SUPPORT
2570 return ( GetPacketLatency() );
2571 #else
2572 return 0;
2573 #endif
2574 }
2575
GetSnortPacketDropPortion()2576 static double GetSnortPacketDropPortion()
2577 {
2578 #ifdef PI_PACKET_DROPS_SUPPORT
2579 return ( GetPacketDropPortion() );
2580 #else
2581 return 0;
2582 #endif
2583 }
2584
DynamicIsTestMode(void)2585 static bool DynamicIsTestMode(void)
2586 {
2587 return (ScTestMode()!= 0);
2588 }
2589
GetCurrentSnortConfig(void)2590 static SnortConfig* GetCurrentSnortConfig(void)
2591 {
2592 return snort_conf;
2593 }
2594
DynamicSetIPRepUpdateCount(uint8_t count)2595 static void DynamicSetIPRepUpdateCount(uint8_t count)
2596 {
2597 return setIPRepUpdateCount(count);
2598 }
2599
ErrorMsgThrottled(void * tinfo,const char * format,...)2600 static void ErrorMsgThrottled(void* tinfo, const char *format, ...)
2601 {
2602 char buf[STD_BUF+1];
2603 va_list ap;
2604 ThrottleInfo *throttleInfo = (ThrottleInfo *)tinfo;
2605
2606 va_start(ap, format);
2607 vsnprintf(buf, STD_BUF, format, ap);
2608 va_end(ap);
2609
2610 ErrorMessageThrottled(throttleInfo, "%s", buf);
2611 }
2612
InitDynamicPreprocessors(void)2613 int InitDynamicPreprocessors(void)
2614 {
2615 DynamicPreprocessorData preprocData;
2616
2617 preprocData.version = PREPROCESSOR_DATA_VERSION;
2618 preprocData.size = sizeof(DynamicPreprocessorData);
2619
2620 preprocData.altBuffer = (SFDataBuffer *)&DecodeBuffer;
2621 preprocData.altDetect = (SFDataPointer *)&DetectBuffer;
2622 preprocData.fileDataBuf = (SFDataPointer *)&file_data_ptr;
2623
2624 preprocData.logMsg = &LogMessage;
2625 preprocData.errMsg = &ErrorMessage;
2626 preprocData.fatalMsg = &FatalError;
2627 preprocData.debugMsg = &DebugMessageFunc;
2628 preprocData.errMsgThrottled = &ErrorMsgThrottled;
2629 #ifdef SF_WCHAR
2630 preprocData.debugWideMsg = &DebugWideMessageFunc;
2631 #endif
2632
2633 preprocData.registerPreproc = &RegisterPreprocessor;
2634 #ifdef SNORT_RELOAD
2635 preprocData.getRelatedReloadData = GetRelatedReloadData;
2636 #endif
2637 #ifdef DUMP_BUFFER
2638 preprocData.registerBufferTracer = &RegisterBufferTracer;
2639 #endif
2640 preprocData.addPreproc = &AddPreprocessor;
2641 preprocData.addPreprocAllPolicies = &AddPreprocessorAllPolicies;
2642 preprocData.addMetaEval = &AddMetaEval;
2643 preprocData.getSnortInstance = DynamicGetSnortInstance;
2644 preprocData.addPreprocExit = &AddFuncToPreprocCleanExitList;
2645 preprocData.addPreprocConfCheck = &AddPreprocessorCheck;
2646 preprocData.preprocOptRegister = &RegisterPreprocessorRuleOption;
2647 preprocData.addPreprocProfileFunc = &DynamicRegisterPreprocessorProfile;
2648 preprocData.profilingPreprocsFunc = &DynamicProfilingPreprocs;
2649 #ifdef PERF_PROFILING
2650 preprocData.totalPerfStats = &totalPerfStats;
2651 #else
2652 preprocData.totalPerfStats = NULL;
2653 #endif
2654
2655 preprocData.alertAdd = &SnortEventqAdd;
2656 preprocData.genSnortEvent = &GenerateSnortEvent;
2657 preprocData.thresholdCheck = &sfthreshold_test;
2658 preprocData.detect = &DynamicDetect;
2659 preprocData.disableDetect = &DynamicDisableDetection;
2660 preprocData.disableAllDetect = &DynamicDisableAllDetection;
2661 preprocData.enableContentDetect = &DynamicEnableContentDetection;
2662 preprocData.disablePacketAnalysis = &DynamicDisablePacketAnalysis;
2663 preprocData.enablePreprocessor = &DynamicEnablePreprocessor;
2664 preprocData.sessionAPI = session_api;
2665 preprocData.streamAPI = stream_api;
2666 preprocData.searchAPI = search_api;
2667
2668 preprocData.config_file = &file_name;
2669 preprocData.config_line = &file_line;
2670 preprocData.printfappend = &sfsnprintfappend;
2671 preprocData.tokenSplit = &mSplit;
2672 preprocData.tokenFree = &mSplitFree;
2673
2674 preprocData.getRuleInfoByName = &DynamicGetRuleClassByName;
2675 preprocData.getRuleInfoById = &DynamicGetRuleClassById;
2676
2677 preprocData.preprocess = &DynamicPreprocess;
2678
2679 #ifdef DEBUG_MSGS
2680 preprocData.debugMsgFile = &DebugMessageFile;
2681 preprocData.debugMsgLine = &DebugMessageLine;
2682 #else
2683 preprocData.debugMsgFile = &no_file;
2684 preprocData.debugMsgLine = &no_line;
2685 #endif
2686
2687 preprocData.registerPreprocStats = &RegisterPreprocStats;
2688 preprocData.addPreprocReset = &AddFuncToPreprocResetList;
2689 preprocData.addPreprocResetStats = &AddFuncToPreprocResetStatsList;
2690 preprocData.disablePreprocessors = &DynamicDisablePreprocessors;
2691
2692 preprocData.ip6Build = &DynamicIP6Build;
2693 preprocData.ip6SetCallbacks = &DynamicIP6SetCallbacks;
2694
2695 preprocData.logAlerts = &DynamicSnortEventqLog;
2696 preprocData.resetAlerts = &SnortEventqReset;
2697 preprocData.pushAlerts = SnortEventqPush;
2698 preprocData.popAlerts = SnortEventqPop;
2699
2700 #ifdef TARGET_BASED
2701 preprocData.findProtocolReference = &FindProtocolReference;
2702 preprocData.addProtocolReference = &AddProtocolReference;
2703 preprocData.isAdaptiveConfigured = &IsAdaptiveConfigured;
2704 preprocData.isAdaptiveConfiguredForSnortConfig = &IsAdaptiveConfiguredForSnortConfig;
2705 #endif
2706
2707 preprocData.preprocOptOverrideKeyword = &RegisterPreprocessorRuleOptionOverride;
2708 preprocData.preprocOptByteOrderKeyword = &RegisterPreprocessorRuleOptionByteOrder;
2709 preprocData.isPreprocEnabled = &IsPreprocEnabled;
2710
2711 preprocData.getNapRuntimePolicy = DynamicGetNapRuntimePolicy;
2712 preprocData.getIpsRuntimePolicy = DynamicGetIpsRuntimePolicy;
2713 preprocData.getParserPolicy = DynamicGetParserPolicy;
2714 preprocData.getDefaultPolicy = DynamicGetDefaultPolicy;
2715 preprocData.setParserPolicy = DynamicSetParserPolicy;
2716 preprocData.setFileDataPtr = DynamicSetFileDataPtr;
2717 preprocData.DetectReset = DynamicDetectResetPtr;
2718 preprocData.SetAltDecode = &DynamicSetAltDecode;
2719 preprocData.GetAltDetect = &DynamicGetAltDetect;
2720 preprocData.SetAltDetect = &DynamicSetAltDetect;
2721 preprocData.Is_DetectFlag = &DynamicIsDetectFlag;
2722 preprocData.DetectFlag_Disable = &DynamicDetectFlagDisable;
2723 preprocData.SnortStrtol = DynamicSnortStrtol;
2724 preprocData.SnortStrtoul = DynamicSnortStrtoul;
2725 preprocData.SnortStrnStr = DynamicSnortStrnStr;
2726 preprocData.SnortStrncpy = DynamicSnortStrncpy;
2727 preprocData.SnortStrnPbrk = DynamicSnortStrnPbrk;
2728 preprocData.SnortStrcasestr = DynamicSnortStrcasestr;
2729
2730 preprocData.portObjectCharPortArray = PortObjectCharPortArray;
2731 preprocData.fpEvalRTN = DynamicEvalRTN;
2732
2733 preprocData.obApi = obApi;
2734
2735 preprocData.encodeNew = DynamicEncodeNew;
2736 preprocData.encodeDelete = DynamicEncodeDelete;
2737 preprocData.encodeFormat = DynamicEncodeFormat;
2738 preprocData.encodeUpdate = DynamicEncodeUpdate;
2739
2740 preprocData.newGrinderPkt = DynamicNewGrinderPkt;
2741 preprocData.deleteGrinderPkt = DynamicDeleteGrinderPkt;
2742
2743 preprocData.portObjectCharPortArray = PortObjectCharPortArray;
2744
2745 preprocData.addDetect = &AddDetection;
2746
2747 preprocData.getLogDirectory = DynamicGetLogDirectory;
2748
2749 preprocData.controlSocketRegisterHandler = &ControlSocketRegisterHandler;
2750
2751 preprocData.registerIdleHandler = &IdleProcessingRegisterHandler;
2752
2753 preprocData.isPafEnabled = DynamicIsPafEnabled;
2754
2755 preprocData.pktTime = DynamicPktTime;
2756 preprocData.getPktTimeOfDay = DynamicGetPktTimeOfDay;
2757 #ifdef SIDE_CHANNEL
2758 preprocData.isSCEnabled = DynamicIsSCEnabled;
2759 preprocData.scRegisterRXHandler = &DynamicSCRegisterRXHandler;
2760 preprocData.scAllocMessageTX = &DynamicSCPreallocMessageTX;
2761 preprocData.scEnqueueMessageTX = &DynamicSCEnqueueMessageTX;
2762 #endif
2763
2764 preprocData.getPolicyFromId = &DynamicGetPolicyFromId;
2765 preprocData.changeNapRuntimePolicy = &DynamicChangeNapRuntimePolicy;
2766 preprocData.changeIpsRuntimePolicy = &DynamicChangeIpsRuntimePolicy;
2767
2768 preprocData.inlineDropPacket = &DynamicDropPacket;
2769 preprocData.inlineRetryPacket = &DynamicRetryPacket;
2770 preprocData.inlineForceDropPacket =&DynamicForceDropPacket;
2771 preprocData.inlineDropSessionAndReset = &DynamicDropSessionAndReset;
2772 preprocData.inlineForceDropSession = &DynamicForceDropSession;
2773 preprocData.inlineForceDropSessionAndReset = &DynamicForceDropSessionAndReset;
2774 preprocData.active_PacketWasDropped = &DynamicActivePacketWasDropped;
2775 #ifdef ACTIVE_RESPONSE
2776 preprocData.activeSetEnabled = &DynamicActiveSetEnabled;
2777 #endif
2778 preprocData.SnortIsStrEmpty = DynamicSnortIsStrEmpty;
2779 #ifdef ACTIVE_RESPONSE
2780 preprocData.dynamicSendBlockResponse = &DynamicSendBlockResponseMsg;
2781 #endif
2782 preprocData.dynamicSetFlowId = &setFlowId;
2783 #ifdef HAVE_DAQ_EXT_MODFLOW
2784 preprocData.dynamicModifyFlow = &DAQ_ModifyFlow;
2785 #endif
2786 #ifdef HAVE_DAQ_QUERYFLOW
2787 preprocData.dynamicQueryFlow = &DAQ_QueryFlow;
2788 #endif
2789
2790 #if defined(DAQ_VERSION) && DAQ_VERSION > 8
2791 preprocData.dynamicDebugPkt = &DAQ_DebugPkt;
2792 #endif
2793
2794 #if defined(DAQ_VERSION) && DAQ_VERSION > 9
2795 preprocData.dynamicIoctl = &DAQ_Ioctl;
2796 #endif
2797 preprocData.addPeriodicCheck = &AddFuncToPeriodicCheckList;
2798 preprocData.addPostConfigFunc = &AddFuncToPreprocPostConfigList;
2799 preprocData.addFuncToPostConfigList = &AddFuncToPostConfigList;
2800 preprocData.snort_conf_dir = &snort_conf_dir;
2801 preprocData.addOutputModule = &output_load_module;
2802 preprocData.canWhitelist = DynamicCanWhitelist;
2803 preprocData.fileAPI = file_api;
2804 preprocData.disableAllPolicies = &DynamicDisableAllPolicies;
2805 preprocData.reenablePreprocBit = &DynamicReenablePreprocBitFunc;
2806 preprocData.checkValueInRange = &CheckValueInRange;
2807
2808 preprocData.setHttpBuffer = SetHttpBuffer;
2809 preprocData.getHttpBuffer = getHttpBuffer;
2810
2811 #ifdef ACTIVE_RESPONSE
2812 preprocData.activeInjectData = &DynamicActiveInjectData;
2813 preprocData.activeSendResponse = &DynamicActiveResponseMsg;
2814 preprocData.activeSendForwardReset = &DynamicActiveSendForwardReset;
2815 preprocData.activeQueueResponse = &DynamicActiveQueueResponse;
2816 #endif
2817 preprocData.readyForProcess = &DynamicReadyForProcess;
2818
2819 preprocData.getSSLCallback = &DynamicGetSSLCallback;
2820 preprocData.setSSLCallback = &DynamicSetSSLCallback;
2821
2822 preprocData.sslAppIdLookup = &sslAppIdLookup;
2823 preprocData.registerSslAppIdLookup = ®isterSslAppIdLookup;
2824
2825 preprocData.getAppId = &getAppId;
2826 preprocData.registerGetAppId = ®isterGetAppId;
2827
2828 preprocData.urlQueryCreate = &urlQueryCreate;
2829 preprocData.urlQueryDestroy = &urlQueryDestroy;
2830 preprocData.urlQueryMatch = &urlQueryMatch;
2831 preprocData.registerUrlQuery = ®isterUrlQuery;
2832
2833 preprocData.userGroupIdGet = &userGroupIdGet;
2834 preprocData.registerUserGroupIdGet = ®isterUserGroupIdGet;
2835
2836 preprocData.geoIpAddressLookup = &geoIpAddressLookup;
2837 preprocData.registerGeoIpAddressLookup = ®isterGeoIpAddressLookup;
2838 preprocData.updateSSLSSnLogData = &updateSSLSSnLogData;
2839 preprocData.registerUpdateSSLSSnLogData = ®isterUpdateSSLSSnLogData;
2840 preprocData.endSSLSSnLogData = &endSSLSSnLogData;
2841 preprocData.registerEndSSLSSnLogData = ®isterEndSSLSSnLogData;
2842 preprocData.registerGetSSLActualAction = ®isterGetSSLActualAction;
2843 preprocData.getSSLActualAction = &getSSLActualAction;
2844 preprocData.getIntfData = &getIntfData;
2845 preprocData.registerGetIntfData = ®isterGetIntfData;
2846 preprocData.isSSLPolicyEnabled = &DynamicIsSSLPolicyEnabled;
2847 preprocData.setSSLPolicyEnabled = &DynamicSetSSLPolicyEnabled;
2848 preprocData.getPerfIndicators = &GetSnortPerfIndicators;
2849 preprocData.getPacketLatency = &GetSnortPacketLatency;
2850 preprocData.getPacketDropPortion = &GetSnortPacketDropPortion;
2851
2852 preprocData.loadAllLibs = &LoadAllLibs;
2853 preprocData.openDynamicLibrary = &openDynamicLibrary;
2854 preprocData.getSymbol = &getSymbol;
2855 preprocData.closeDynamicLibrary = &CloseDynamicLibrary;
2856
2857 preprocData.getHttpXffFields = &GetHttpXffFields;
2858
2859 #if defined(FEAT_OPEN_APPID)
2860 preprocData.appIdApi = &appIdApi;
2861 preprocData.registerIsAppIdRequired = ®isterIsAppIdRequired;
2862 preprocData.unregisterIsAppIdRequired = &unregisterIsAppIdRequired;
2863 preprocData.isAppIdRequired = &isAppIdRequired;
2864 #endif /* defined(FEAT_OPEN_APPID) */
2865 preprocData.isReadMode = DynamicIsReadMode;
2866 preprocData.isTestMode = &DynamicIsTestMode;
2867
2868 preprocData.getCurrentSnortConfig = GetCurrentSnortConfig;
2869 preprocData.pkt_tracer_enabled = &pkt_trace_enabled;
2870 preprocData.trace = trace_line;
2871 preprocData.traceMax = MAX_TRACE_LINE;
2872 preprocData.addPktTrace = DynamicAddPktTraceData;
2873 preprocData.getPktTraceActionMsg = DynamicGetPktTraceActionMsg;
2874 preprocData.setIPRepUpdateCount = DynamicSetIPRepUpdateCount;
2875
2876 preprocData.getCapability = &DAQ_GetCapabilities;
2877 #if defined(DAQ_CAPA_CST_TIMEOUT)
2878 preprocData.canGetTimeout = DynamicCanGetTimeout;
2879 preprocData.registerGetDaqCapaTimeout = RegisterGetDaqCapaTimeout;
2880 #endif
2881
2882 #ifdef SNORT_RELOAD
2883 preprocData.reloadAdjustRegister = DynamicReloadAdjustRegister;
2884 #endif
2885
2886 #ifdef DAQ_MODFLOW_TYPE_PRESERVE_FLOW
2887 preprocData.setPreserveFlow = setPreserveFlow;
2888 #endif
2889
2890 preprocData.registerMemoryStatsFunc = RegisterMemoryStatsFunction;
2891 preprocData.snortAlloc = SnortPreprocAlloc;
2892 preprocData.snortFree = SnortPreprocFree;
2893 preprocData.registerReputationProcessExternal = ®isterReputationProcessExternal;
2894 preprocData.reputation_process_external_ip = &_reputation_process_external_ip;
2895 preprocData.registerReputationGetEntryCount = ®isterReputationGetEntryCount;
2896 preprocData.reputation_get_entry_count = &_reputation_get_entry_count;
2897 preprocData.registerFtpmodeQuery = ®isterFtpModeQuery;
2898 preprocData.ftpGetMode = &ftpGetDataSessionMode;
2899
2900 preprocData.setTlsHostAppId = &setTlsHostAppId;
2901 preprocData.registerSetTlsHostAppId = ®isterSetTlsHostAppId;
2902 return InitDynamicPreprocessorPlugins(&preprocData);
2903 }
2904
InitDynamicDetectionPlugins(SnortConfig * sc)2905 int InitDynamicDetectionPlugins(SnortConfig *sc)
2906 {
2907 DynamicDetectionPlugin *plugin;
2908
2909 if (sc == NULL)
2910 return -1;
2911
2912 VerifyDetectionPluginRequirements(sc);
2913
2914 plugin = sc->loadedDetectionPlugins;
2915 while (plugin)
2916 {
2917 if (plugin->initFunc(sc))
2918 {
2919 ErrorMessage("Failed to initialize dynamic detection library: "
2920 "%s version %d.%d.%d\n",
2921 plugin->metaData.uniqueName,
2922 plugin->metaData.major,
2923 plugin->metaData.minor,
2924 plugin->metaData.build);
2925
2926 return -1;
2927 }
2928
2929 plugin = plugin->next;
2930 }
2931
2932 return 0;
2933 }
2934
DumpDetectionLibRules(SnortConfig * sc)2935 int DumpDetectionLibRules(SnortConfig *sc)
2936 {
2937 DynamicDetectionPlugin *plugin = sc->loadedDetectionPlugins;
2938 DumpDetectionRules ruleDumpFunc = NULL;
2939 int retVal = 0;
2940 int dumped = 0;
2941
2942 LogMessage("Dumping dynamic rules...\n");
2943 while (plugin)
2944 {
2945 ruleDumpFunc = (DumpDetectionRules) getSymbol(plugin->handle, "DumpSkeletonRules", &(plugin->metaData), NONFATAL);
2946
2947 LogMessage("Dumping dynamic rules for Library %s %d.%d.%d\n",
2948 plugin->metaData.uniqueName,
2949 plugin->metaData.major,
2950 plugin->metaData.minor,
2951 plugin->metaData.build);
2952 if (ruleDumpFunc != NULL)
2953 {
2954 if (ruleDumpFunc())
2955 {
2956 LogMessage("Failed to dump the rules for Library %s %d.%d.%d\n",
2957 plugin->metaData.uniqueName,
2958 plugin->metaData.major,
2959 plugin->metaData.minor,
2960 plugin->metaData.build);
2961 dumped = 1;
2962 }
2963 }
2964 plugin = plugin->next;
2965 }
2966 if( dumped == 0)
2967 {
2968 LogMessage(" Finished dumping dynamic rules.\n");
2969 }
2970 return retVal;
2971 }
2972
LoadDynamicPreprocessor(SnortConfig * sc,const char * const library_name,int indent)2973 int LoadDynamicPreprocessor(SnortConfig *sc, const char * const library_name, int indent)
2974 {
2975 DynamicPluginMeta metaData;
2976 /* Presume here, that library name is full path */
2977 InitPreprocessorLibFunc preprocInit;
2978 PluginHandle handle;
2979
2980 LogMessage("%sLoading dynamic preprocessor library %s... ",
2981 indent ? " " : "", library_name);
2982
2983 handle = openDynamicLibrary(library_name, 0);
2984 metaData.libraryPath = (char *) library_name;
2985
2986 GetPluginVersion(handle, &metaData);
2987
2988 /* Just to ensure that the function exists */
2989 preprocInit = (InitPreprocessorLibFunc) getSymbol(handle, "InitializePreprocessor", &metaData, FATAL);
2990
2991 if (metaData.type != TYPE_PREPROCESSOR)
2992 {
2993 CloseDynamicLibrary(handle);
2994 LogMessage("failed, not a preprocessor library\n");
2995 return 0;
2996 }
2997
2998 AddPreprocessorPlugin(handle, preprocInit, &metaData);
2999
3000 LogMessage("done\n");
3001 return 0;
3002 }
3003
LoadAllDynamicPreprocessors(SnortConfig * sc,const char * const path)3004 void LoadAllDynamicPreprocessors(SnortConfig *sc, const char * const path)
3005 {
3006 LogMessage("Loading all dynamic preprocessor libs from %s...\n", path);
3007 LoadAllLibs(sc, path, LoadDynamicPreprocessor);
3008 LogMessage(" Finished Loading all dynamic preprocessor libs from %s\n", path);
3009 }
3010
CloseDynamicPreprocessorLibs(void)3011 void CloseDynamicPreprocessorLibs(void)
3012 {
3013 DynamicPreprocessorPlugin *tmpplugin, *plugin = loadedPreprocessorPlugins;
3014 while (plugin)
3015 {
3016 tmpplugin = plugin->next;
3017 CloseDynamicLibrary(plugin->handle);
3018 free(plugin->metaData.libraryPath);
3019 free(plugin);
3020 plugin = tmpplugin;
3021 }
3022 loadedPreprocessorPlugins = NULL;
3023 }
3024
GetNextEnginePluginVersion(void * p)3025 void *GetNextEnginePluginVersion(void *p)
3026 {
3027 DynamicEnginePlugin *lib = (DynamicEnginePlugin *) p;
3028
3029 if ( lib != NULL )
3030 {
3031 lib = lib->next;
3032 }
3033 else
3034 {
3035 lib = loadedEngines;
3036 }
3037
3038 if ( lib == NULL )
3039 {
3040 return lib;
3041 }
3042
3043 return (void *) lib;
3044 }
3045
GetNextDetectionPluginVersion(SnortConfig * sc,void * p)3046 void *GetNextDetectionPluginVersion(SnortConfig *sc, void *p)
3047 {
3048 DynamicDetectionPlugin *lib = (DynamicDetectionPlugin *) p;
3049
3050 if ( lib != NULL )
3051 {
3052 lib = lib->next;
3053 }
3054 else
3055 {
3056 lib = sc->loadedDetectionPlugins;
3057 }
3058
3059 if ( lib == NULL )
3060 {
3061 return lib;
3062 }
3063
3064 return (void *) lib;
3065 }
3066
GetNextPreprocessorPluginVersion(void * p)3067 void *GetNextPreprocessorPluginVersion(void *p)
3068 {
3069 DynamicPreprocessorPlugin *lib = (DynamicPreprocessorPlugin *) p;
3070
3071 if ( lib != NULL )
3072 {
3073 lib = lib->next;
3074 }
3075 else
3076 {
3077 lib = loadedPreprocessorPlugins;
3078 }
3079
3080 if ( lib == NULL )
3081 {
3082 return lib;
3083 }
3084
3085 return (void *) lib;
3086 }
3087
GetDetectionPluginMetaData(void * p)3088 DynamicPluginMeta *GetDetectionPluginMetaData(void *p)
3089 {
3090 DynamicDetectionPlugin *lib = (DynamicDetectionPlugin *) p;
3091 DynamicPluginMeta *meta;
3092
3093 meta = &(lib->metaData);
3094
3095 return meta;
3096 }
3097
GetEnginePluginMetaData(void * p)3098 DynamicPluginMeta *GetEnginePluginMetaData(void *p)
3099 {
3100 DynamicEnginePlugin *lib = (DynamicEnginePlugin *) p;
3101 DynamicPluginMeta *meta;
3102
3103 meta = &(lib->metaData);
3104
3105 return meta;
3106 }
3107
GetPreprocessorPluginMetaData(void * p)3108 DynamicPluginMeta *GetPreprocessorPluginMetaData(void *p)
3109 {
3110 DynamicPreprocessorPlugin *lib = (DynamicPreprocessorPlugin *) p;
3111 DynamicPluginMeta *meta;
3112
3113 meta = &(lib->metaData);
3114
3115 return meta;
3116 }
3117
3118 #ifdef SIDE_CHANNEL
3119
3120 /*
3121 * Dynamic Side Channel Plugin Support
3122 */
3123 typedef struct _DynamicSideChannelPlugin
3124 {
3125 PluginHandle handle;
3126 DynamicPluginMeta metaData;
3127 InitSideChannelLibFunc initFunc;
3128 struct _DynamicSideChannelPlugin *next;
3129 struct _DynamicSideChannelPlugin *prev;
3130 } DynamicSideChannelPlugin;
3131
3132 static DynamicSideChannelPlugin *loadedSideChannelPlugins = NULL;
3133
AddSideChannelPlugin(PluginHandle handle,InitSideChannelLibFunc initFunc,DynamicPluginMeta * meta)3134 void AddSideChannelPlugin(PluginHandle handle,
3135 InitSideChannelLibFunc initFunc,
3136 DynamicPluginMeta *meta)
3137 {
3138 DynamicSideChannelPlugin *newPlugin = NULL;
3139 newPlugin = (DynamicSideChannelPlugin *)SnortAlloc(sizeof(DynamicSideChannelPlugin));
3140 newPlugin->handle = handle;
3141
3142 if (!loadedSideChannelPlugins)
3143 {
3144 loadedSideChannelPlugins = newPlugin;
3145 }
3146 else
3147 {
3148 newPlugin->next = loadedSideChannelPlugins;
3149 loadedSideChannelPlugins->prev = newPlugin;
3150 loadedSideChannelPlugins = newPlugin;
3151 }
3152
3153 memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta));
3154 newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath);
3155 newPlugin->initFunc = initFunc;
3156 }
3157
RemoveSideChannelPlugin(DynamicSideChannelPlugin * plugin)3158 void RemoveSideChannelPlugin(DynamicSideChannelPlugin *plugin)
3159 {
3160 if (!plugin)
3161 return;
3162
3163 if (plugin == loadedSideChannelPlugins)
3164 {
3165 loadedSideChannelPlugins = loadedSideChannelPlugins->next;
3166 loadedSideChannelPlugins->prev = NULL;
3167 }
3168 else
3169 {
3170 if (plugin->prev)
3171 plugin->prev->next = plugin->next;
3172 if (plugin->next)
3173 plugin->next->prev = plugin->prev;
3174 }
3175 LogMessage("Unloading dynamic side channel library %s version %d.%d.%d\n",
3176 plugin->metaData.uniqueName,
3177 plugin->metaData.major,
3178 plugin->metaData.minor,
3179 plugin->metaData.build);
3180 CloseDynamicLibrary(plugin->handle);
3181 if (plugin->metaData.libraryPath != NULL)
3182 free(plugin->metaData.libraryPath);
3183 free(plugin);
3184 }
3185
LoadDynamicSideChannelLib(SnortConfig * sc,const char * const library_name,int indent)3186 int LoadDynamicSideChannelLib(SnortConfig *sc, const char * const library_name, int indent)
3187 {
3188 DynamicPluginMeta metaData;
3189 /* Presume here, that library name is full path */
3190 InitSideChannelLibFunc sideChannelInit;
3191 PluginHandle handle;
3192
3193 LogMessage("%sLoading dynamic side channel library %s... ",
3194 indent ? " " : "", library_name);
3195
3196 handle = openDynamicLibrary(library_name, 0);
3197 metaData.libraryPath = (char *) library_name;
3198
3199 GetPluginVersion(handle, &metaData);
3200
3201 /* Just to ensure that the function exists */
3202 sideChannelInit = (InitSideChannelLibFunc)getSymbol(handle, "InitializeSideChannel", &metaData, FATAL);
3203
3204 if (!(metaData.type & TYPE_SIDE_CHANNEL))
3205 {
3206 CloseDynamicLibrary(handle);
3207 LogMessage("failed, not a side channel library\n");
3208 return 0;
3209 }
3210
3211 AddSideChannelPlugin(handle, sideChannelInit, &metaData);
3212
3213 LogMessage("done\n");
3214 return 0;
3215 }
3216
CloseDynamicSideChannelLibs(void)3217 void CloseDynamicSideChannelLibs(void)
3218 {
3219 DynamicSideChannelPlugin *tmpplugin, *plugin = loadedSideChannelPlugins;
3220 while (plugin)
3221 {
3222 tmpplugin = plugin->next;
3223 CloseDynamicLibrary(plugin->handle);
3224 free(plugin->metaData.libraryPath);
3225 free(plugin);
3226 plugin = tmpplugin;
3227 }
3228 loadedSideChannelPlugins = NULL;
3229 }
3230
LoadAllDynamicSideChannelLibs(SnortConfig * sc,const char * const path)3231 void LoadAllDynamicSideChannelLibs(SnortConfig *sc, const char * const path)
3232 {
3233 LogMessage("Loading all dynamic side channel libs from %s...\n", path);
3234 LoadAllLibs(sc, path, LoadDynamicSideChannelLib);
3235 LogMessage(" Finished Loading all dynamic side channel libs from %s\n", path);
3236 }
3237
InitDynamicSideChannelPlugins(void)3238 int InitDynamicSideChannelPlugins(void)
3239 {
3240 DynamicSideChannelPlugin *plugin;
3241 DynamicSideChannelData sideChannelData;
3242
3243 RemoveDuplicateSideChannelPlugins();
3244
3245 sideChannelData.version = SIDE_CHANNEL_DATA_VERSION;
3246 sideChannelData.size = sizeof(DynamicSideChannelData);
3247 sideChannelData.registerModule = &RegisterSideChannelModule;
3248 sideChannelData.registerRXHandler = &SideChannelRegisterRXHandler;
3249 sideChannelData.registerTXHandler = &SideChannelRegisterTXHandler;
3250 sideChannelData.unregisterRXHandler = &SideChannelUnregisterRXHandler;
3251 sideChannelData.unregisterTXHandler = &SideChannelUnregisterTXHandler;
3252 sideChannelData.allocMessageRX = &SideChannelPreallocMessageRX;
3253 sideChannelData.allocMessageTX = &SideChannelPreallocMessageTX;
3254 sideChannelData.discardMessageRX = &SideChannelDiscardMessageRX;
3255 sideChannelData.discardMessageTX = &SideChannelDiscardMessageTX;
3256 sideChannelData.enqueueMessageRX = &SideChannelEnqueueMessageRX;
3257 sideChannelData.enqueueMessageTX = &SideChannelEnqueueMessageTX;
3258 sideChannelData.enqueueDataRX = &SideChannelEnqueueDataRX;
3259 sideChannelData.enqueueDataTX = &SideChannelEnqueueDataTX;
3260
3261 sideChannelData.getSnortInstance = &DynamicGetSnortInstance;
3262 sideChannelData.snortSignalMask = &DynamicSnortSignalMask;
3263
3264 sideChannelData.logMsg = &LogMessage;
3265 sideChannelData.errMsg = &ErrorMessage;
3266 sideChannelData.fatalMsg = &FatalError;
3267 sideChannelData.debugMsg = &DebugMessageFunc;
3268
3269 plugin = loadedSideChannelPlugins;
3270 while (plugin)
3271 {
3272 if (plugin->initFunc(&sideChannelData))
3273 {
3274 ErrorMessage("Failed to initialize dynamic side channel library: %s version %d.%d.%d\n",
3275 plugin->metaData.uniqueName,
3276 plugin->metaData.major,
3277 plugin->metaData.minor,
3278 plugin->metaData.build);
3279
3280 return -1;
3281 }
3282
3283 plugin = plugin->next;
3284 }
3285
3286 return 0;
3287 }
3288
GetNextSideChannelPluginVersion(void * p)3289 void *GetNextSideChannelPluginVersion(void *p)
3290 {
3291 DynamicSideChannelPlugin *lib = (DynamicSideChannelPlugin *) p;
3292
3293 if (lib != NULL)
3294 lib = lib->next;
3295 else
3296 lib = loadedSideChannelPlugins;
3297
3298 if (lib == NULL)
3299 return lib;
3300
3301 return (void *) lib;
3302 }
3303
GetSideChannelPluginMetaData(void * p)3304 DynamicPluginMeta *GetSideChannelPluginMetaData(void *p)
3305 {
3306 DynamicSideChannelPlugin *lib = (DynamicSideChannelPlugin *) p;
3307 DynamicPluginMeta *meta;
3308
3309 meta = &(lib->metaData);
3310
3311 return meta;
3312 }
3313
RemoveDuplicateSideChannelPlugins(void)3314 void RemoveDuplicateSideChannelPlugins(void)
3315 {
3316 int removed = 0;
3317 DynamicSideChannelPlugin *lib1 = NULL;
3318 DynamicSideChannelPlugin *lib2 = NULL;
3319 DynamicPluginMeta *meta1;
3320 DynamicPluginMeta *meta2;
3321
3322 /* Side Channel Plugins */
3323 do
3324 {
3325 removed = 0;
3326 lib1 = loadedSideChannelPlugins;
3327 while (lib1 != NULL)
3328 {
3329 lib2 = loadedSideChannelPlugins;
3330 while (lib2 != NULL)
3331 {
3332 /* Obviously, the same ones will be the same */
3333 if (lib1 != lib2)
3334 {
3335 meta1 = &lib1->metaData;
3336 meta2 = &lib2->metaData;
3337 if (!strcmp(meta1->uniqueName, meta2->uniqueName))
3338 {
3339 /* Uh, same uniqueName. */
3340 if ((meta1->major > meta2->major) ||
3341 ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) ||
3342 ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) )
3343 {
3344 /* Lib1 is newer */
3345 RemoveSideChannelPlugin(lib2);
3346 removed = 1;
3347 break;
3348 }
3349 else if ((meta2->major > meta1->major) ||
3350 ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) ||
3351 ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) )
3352 {
3353 /* Lib2 is newer */
3354 RemoveSideChannelPlugin(lib1);
3355 removed = 1;
3356 break;
3357 }
3358 else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) )
3359 {
3360 /* Duplicate */
3361 RemoveSideChannelPlugin(lib2);
3362 removed = 1;
3363 break;
3364 }
3365 }
3366 }
3367 /* If we removed anything, start back at the beginning */
3368 if (removed)
3369 break;
3370 lib2 = lib2->next;
3371 }
3372 /* If we removed anything, start back at the beginning */
3373 if (removed)
3374 break;
3375 lib1 = lib1->next;
3376 }
3377 } while (removed);
3378 }
3379
3380 #endif /* SIDE_CHANNEL */
3381
3382 #ifdef SNORT_RELOAD
AdjustSoRuleMemory(SnortConfig * new_config,SnortConfig * old_config)3383 void AdjustSoRuleMemory(SnortConfig *new_config, SnortConfig *old_config) {
3384 tSfPolicyId policy_id = getParserPolicy(new_config);
3385 ada_reload_adjust_register(ada, policy_id, (void *) new_config, "so_rule", (size_t) new_config->so_rule_memcap);
3386 }
3387
ReloadDynamicDetectionLibs(SnortConfig * sc)3388 void ReloadDynamicDetectionLibs(SnortConfig *sc)
3389 {
3390 uint32_t i;
3391
3392 if (sc->dyn_rules != NULL)
3393 {
3394 /* Load the dynamic detection libs */
3395 for (i = 0; i < sc->dyn_rules->count; i++)
3396 {
3397 switch (sc->dyn_rules->lib_paths[i]->ptype)
3398 {
3399 case PATH_TYPE__FILE:
3400 LoadDynamicDetectionLib(sc, sc->dyn_rules->lib_paths[i]->path, 0);
3401 break;
3402
3403 case PATH_TYPE__DIRECTORY:
3404 LoadAllDynamicDetectionLibs(sc, sc->dyn_rules->lib_paths[i]->path);
3405 break;
3406 }
3407 }
3408 }
3409 }
3410 #endif
3411
3412