?? sf_dynamic_plugins.c
字號:
/* $Id: *//* * sf_dynamic_plugins.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation. You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (C) 2005 Sourcefire Inc. * * Author: Steven Sturges * * Dynamic Library Loading for Snort * */#ifdef DYNAMIC_PLUGIN#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifndef WIN32#include <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <limits.h>#include <dirent.h>#include <dlfcn.h>#include <fnmatch.h>#if defined(HPUX)#define EXT "*.sl"#elif defined(MACOS)#define EXT "*.dylib"#elif defined(OPENBSD)#define EXT "*.so"#define EXT2 "*.so.*"#else#define EXT "*.so"#endiftypedef void * PluginHandle;#else /* !WIN32 */#include <windows.h>#define EXT "dll"typedef HANDLE PluginHandle;/* Of course, WIN32 couldn't do things the unix way... * Define a few of these to get around portability issues. */#define getcwd _getcwd #define PATH_MAX MAX_PATH#endif /* !WIN32 */#include <errno.h>#include "config.h"#include "decode.h"#include "debug.h"#include "detect.h"extern u_int8_t DecodeBuffer[DECODE_BLEN]; /* decode.c */extern HttpUri UriBufs[URI_COUNT]; /* detect.c */#include "util.h"#include "snort.h"#include "sf_dynamic_engine.h"#include "sf_dynamic_detection.h"#include "sf_dynamic_preprocessor.h"#include "sp_dynamic.h"#include "sp_preprocopt.h"#include "util.h"#include "event_queue.h"#include "plugbase.h"#include "sfthreshold.h"#include "inline.h"#include "mstring.h"#include "sfsnprintfappend.h"#include "stream_api.h"/* Predeclare this */void VerifySharedLibUniqueness();typedef int (*LoadLibraryFunc)(char *path, int indent);typedef struct _DynamicEnginePlugin{ PluginHandle handle; DynamicPluginMeta metaData; InitEngineLibFunc initFunc; struct _DynamicEnginePlugin *next; struct _DynamicEnginePlugin *prev;} DynamicEnginePlugin;static DynamicEnginePlugin *loadedEngines = NULL;typedef struct _DynamicDetectionPlugin{ PluginHandle handle; DynamicPluginMeta metaData; InitDetectionLibFunc initFunc; struct _DynamicDetectionPlugin *next; struct _DynamicDetectionPlugin *prev;} DynamicDetectionPlugin;static DynamicDetectionPlugin *loadedDetectionPlugins = NULL;typedef struct _DynamicPreprocessorPlugin{ PluginHandle handle; DynamicPluginMeta metaData; InitPreprocessorLibFunc initFunc; struct _DynamicPreprocessorPlugin *next; struct _DynamicPreprocessorPlugin *prev;} DynamicPreprocessorPlugin;static DynamicPreprocessorPlugin *loadedPreprocessorPlugins = NULL;void CloseDynamicLibrary(PluginHandle handle){#ifndef WIN32 dlclose(handle);#else FreeLibrary(handle);#endif}#define NONFATAL 0#define FATAL 1void *getSymbol(PluginHandle handle, char *symbol, DynamicPluginMeta *meta, int fatal){ void *symbolPtr = NULL; if (!handle) return symbolPtr;#ifndef WIN32 symbolPtr = dlsym(handle, symbol);#else symbolPtr = GetProcAddress(handle, symbol);#endif if (!symbolPtr) { if (fatal) {#ifndef WIN32 FatalError("Failed to find %s() function in %s: %s\n", symbol, meta->libraryPath, dlerror());#else FatalError("Failed to find %s() function in %s: %d\n", symbol, meta->libraryPath, GetLastError());#endif } else {#ifndef WIN32 ErrorMessage("Failed to find %s() function in %s: %s\n", symbol, meta->libraryPath, dlerror());#else ErrorMessage("Failed to find %s() function in %s: %d\n", symbol, meta->libraryPath, GetLastError());#endif } } return symbolPtr;}void GetPluginVersion(PluginHandle handle, DynamicPluginMeta* meta){ LibVersionFunc libVersionFunc = NULL; libVersionFunc = (LibVersionFunc)getSymbol(handle, "LibVersion", meta, FATAL); if (libVersionFunc != NULL) { libVersionFunc(meta); }}PluginHandle openDynamicLibrary(char *library_name, int useGlobal){ PluginHandle handle;#ifndef WIN32 handle = dlopen(library_name, RTLD_NOW | (useGlobal ? RTLD_GLOBAL: 0));#else handle = LoadLibrary(library_name);#endif if (handle == NULL) {#ifndef WIN32 FatalError("Failed to load %s: %s\n", library_name, dlerror());#else FatalError("Failed to load %s: %d\n", library_name, GetLastError());#endif } return handle;}void LoadAllLibs(char *path, LoadLibraryFunc loadFunc){#ifndef WIN32 char path_buf[PATH_MAX]; struct dirent *dirEntry; DIR *directory; int count = 0; directory = opendir(path); if (directory) { dirEntry = readdir(directory); while (dirEntry) { if (dirEntry->d_reclen && !fnmatch(EXT, dirEntry->d_name, FNM_PATHNAME | FNM_PERIOD)) { SnortSnprintf(path_buf, PATH_MAX, "%s%s%s", path, "/", dirEntry->d_name); loadFunc(path_buf, 1); count++; } dirEntry = readdir(directory); } closedir(directory);#ifdef OPENBSD directory = opendir(path); if (directory) { dirEntry = readdir(directory); while (dirEntry) { if (dirEntry->d_reclen && !fnmatch(EXT2, dirEntry->d_name, FNM_PATHNAME | FNM_PERIOD)) { SnortSnprintf(path_buf, PATH_MAX, "%s%s%s", path, "/", dirEntry->d_name); loadFunc(path_buf, 1); count++; } dirEntry = readdir(directory); } } closedir(directory);#endif if ( count == 0 ) { LogMessage("Warning: No dynamic libraries found in directory %s!\n", path); } } else { LogMessage("Warning: Directory %s does not exist!\n", path); }#else /* Find all shared library files in path */ char path_buf[PATH_MAX]; char dyn_lib_name[PATH_MAX]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; HANDLE fSearch; WIN32_FIND_DATA FindFileData; int pathLen = 0; char *directory; int useDrive = 0; if (SnortStrncpy(path_buf, path, PATH_MAX) != SNORT_STRNCPY_SUCCESS) FatalError("Path is too long: %s\n", path); pathLen = SnortStrnlen(path_buf, PATH_MAX); if ((path_buf[pathLen - 1] == '\\') || (path_buf[pathLen - 1] == '/')) { /* A directory was specified with trailing dir character */ _splitpath(path_buf, drive, dir, fname, ext); _makepath(path_buf, drive, dir, "*", EXT); directory = &dir[0]; useDrive = 1; } else /* A directory was specified */ { _splitpath(path_buf, drive, dir, fname, ext); if (strcmp(ext, "")) { FatalError("Improperly formatted directory name: %s\n", path); } _makepath(path_buf, "", path_buf, "*", EXT); directory = path; } fSearch = FindFirstFile(path_buf, &FindFileData); while (fSearch != NULL && fSearch != (HANDLE)-1) { if (useDrive) _makepath(dyn_lib_name, drive, directory, FindFileData.cFileName, NULL); else _makepath(dyn_lib_name, NULL, directory, FindFileData.cFileName, NULL); loadFunc(dyn_lib_name, 1); if (!FindNextFile(fSearch, &FindFileData)) { break; } } FindClose(fSearch);#endif}void AddEnginePlugin(PluginHandle handle, InitEngineLibFunc initFunc, DynamicPluginMeta *meta){ DynamicEnginePlugin *newPlugin = NULL; newPlugin = (DynamicEnginePlugin *)SnortAlloc(sizeof(DynamicEnginePlugin)); newPlugin->handle = handle; if (!loadedEngines) { loadedEngines = newPlugin; } else { newPlugin->next = loadedEngines; loadedEngines->prev = newPlugin; loadedEngines = newPlugin; } memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta)); newPlugin->metaData.libraryPath = strdup(meta->libraryPath); newPlugin->initFunc = initFunc;}void RemoveEnginePlugin(DynamicEnginePlugin *plugin){ if (!plugin) return; if (plugin == loadedEngines) { loadedEngines = loadedEngines->next; loadedEngines->prev = NULL; } else { if (plugin->prev) plugin->prev->next = plugin->next; if (plugin->next) plugin->next->prev = plugin->prev; } CloseDynamicLibrary(plugin->handle); free(plugin);}int LoadDynamicEngineLib(char *library_name, int indent){ /* Presume here, that library name is full path */ InitEngineLibFunc engineInit; DynamicPluginMeta metaData; PluginHandle handle;#ifdef SUP_IP6 LogMessage("%sDynamic engine will not be loaded since dynamic detection " "libraries are not yet supported with IPv6.\n", indent?" ":""); return 0;#endif LogMessage("%sLoading dynamic engine %s... ", indent ? " " : "", library_name); handle = openDynamicLibrary(library_name, 1); metaData.libraryPath = library_name; GetPluginVersion(handle, &metaData); /* Just to ensure that the function exists */ engineInit = (InitEngineLibFunc)getSymbol(handle, "InitializeEngine", &metaData, FATAL); if (metaData.type != TYPE_ENGINE) { CloseDynamicLibrary(handle); LogMessage("failed, not an Engine\n"); return 0; } AddEnginePlugin(handle, engineInit, &metaData); LogMessage("done\n"); return 0;}void LoadAllDynamicEngineLibs(char *path){ LogMessage("Loading all dynamic engine libs from %s...\n", path); LoadAllLibs(path, LoadDynamicEngineLib); LogMessage(" Finished Loading all dynamic engine libs from %s\n", path);}void CloseDynamicEngineLibs(){ DynamicEnginePlugin *plugin = loadedEngines; while (plugin) { if (!(plugin->metaData.type & TYPE_DETECTION)) { CloseDynamicLibrary(plugin->handle); } else { /* NOP, handle will be closed when we close the DetectionLib */ ; } plugin = plugin->next; }}void RemovePreprocessorPlugin(DynamicPreprocessorPlugin *plugin){ if (!plugin) return; if (plugin == loadedPreprocessorPlugins) { loadedPreprocessorPlugins = loadedPreprocessorPlugins->next; loadedPreprocessorPlugins->prev = NULL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -