From: Russ Combs Date: Wed, 1 Oct 2014 13:30:21 +0000 (-0400) Subject: support for name/type bindings X-Git-Tag: 3.0.0-233~1397^2~41 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4de3dd3ec9a5fdb511f8fd8829947f28598efb6e;p=thirdparty%2Fsnort3.git support for name/type bindings --- diff --git a/ChangeLog b/ChangeLog index 0ad702265..efa3f7ebd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ -- always change both directions to atom splitter -- fixed byte_extract leak, session flow data leak -- changed pcre JIT to be optional by #define; need autofoo +-- added support for name / type bindings 121 -- valgrind fixes diff --git a/src/main/shell.cc b/src/main/shell.cc index 9ba6583cd..87ed832da 100644 --- a/src/main/shell.cc +++ b/src/main/shell.cc @@ -78,14 +78,15 @@ static void load_overrides(lua_State* L, string& s) } } -static void run_config(lua_State* L) +static void run_config(lua_State* L, const char* t) { lua_getglobal(L, "snort_config"); + lua_getglobal(L, t); - if ( !lua_isfunction(L, -1) ) + if ( !lua_isfunction(L, -2) ) FatalError("%s\n", "snort_config is required"); - else if ( lua_pcall(L, 0, 1, 0) ) + else if ( lua_pcall(L, 1, 1, 0) ) { const char* err = lua_tostring(L, -1); FatalError("%s\n", err); @@ -95,14 +96,13 @@ static void run_config(lua_State* L) static void config_lua( lua_State* L, const char* file, string& s) { - if ( file && *file ) load_config(L, file); if ( s.size() ) load_overrides(L, s); - run_config(L); + run_config(L, "_G"); if ( int k = ModuleManager::get_errors() ) { @@ -147,7 +147,7 @@ void Shell::set_overrides(const char* s) void Shell::configure(SnortConfig* sc) { - assert(file.size()); // FIXIT-M -- provide detailed error message. Will be confusing for an end user + assert(file.size()); ModuleManager::set_config(sc); config_lua(lua, file.c_str(), overrides); ModuleManager::set_config(nullptr); diff --git a/src/managers/inspector_manager.cc b/src/managers/inspector_manager.cc index f4bf16e4f..2ccb9a961 100644 --- a/src/managers/inspector_manager.cc +++ b/src/managers/inspector_manager.cc @@ -82,12 +82,16 @@ struct PHInstance { PHClass& pp_class; Inspector* handler; + string name; PHInstance(PHClass&); ~PHInstance(); static bool comp (PHInstance* a, PHInstance* b) { return ( a->pp_class.api.type < b->pp_class.api.type ); }; + + void set_name(const char* s) + { name = s; }; }; PHInstance::PHInstance(PHClass& p) : pp_class(p) @@ -304,8 +308,13 @@ static PHInstance* get_instance( FrameworkPolicy* fp, const char* keyword) { for ( auto* p : fp->ilist ) - if ( !strcmp(p->pp_class.api.base.name, keyword) ) + { + if ( p->name.size() && p->name == keyword ) + return p; + + else if ( !strcmp(p->pp_class.api.base.name, keyword) ) return p; + } return nullptr; } @@ -461,7 +470,7 @@ void InspectorManager::thread_term(SnortConfig* sc) // new configuration void InspectorManager::instantiate( - const InspectApi* api, Module*, SnortConfig* sc) + const InspectApi* api, Module*, SnortConfig* sc, const char* name) { FrameworkConfig* fc = sc->framework_config; FrameworkPolicy* fp = get_inspection_policy()->framework_policy; @@ -481,6 +490,9 @@ void InspectorManager::instantiate( if ( !ppi ) ParseError("can't instantiate inspector: '%s'.", keyword); + + else if ( name ) + ppi->set_name(name); } } diff --git a/src/managers/inspector_manager.h b/src/managers/inspector_manager.h index cc46f847f..d9ae6d97c 100644 --- a/src/managers/inspector_manager.h +++ b/src/managers/inspector_manager.h @@ -46,7 +46,9 @@ public: static void new_config(SnortConfig*); static void delete_config(SnortConfig*); - static void instantiate(const InspectApi*, Module*, SnortConfig*); + static void instantiate( + const InspectApi*, Module*, SnortConfig*, const char* name = nullptr); + static void free_inspector(Inspector*); static InspectSsnFunc get_session(const char* key); diff --git a/src/managers/module_manager.cc b/src/managers/module_manager.cc index e324ef8d2..d35ffe9d2 100644 --- a/src/managers/module_manager.cc +++ b/src/managers/module_manager.cc @@ -59,6 +59,8 @@ typedef list ModuleList; static ModuleList s_modules; static unsigned s_errors = 0; static string s_current; +static string s_name; +static string s_type; // for callbacks from Lua static SnortConfig* s_config = nullptr; @@ -116,6 +118,19 @@ void ModHook::init() // helper functions //------------------------------------------------------------------------- +static void set_type(string& fqn) +{ + if ( s_type.empty() ) + return; + + size_t pos = fqn.find_first_of('.'); + + if ( pos == fqn.npos ) + pos = fqn.size(); + + fqn.replace(0, pos, s_type); +} + static void set_top(string& fqn) { size_t pos = fqn.find_first_of('.'); @@ -294,10 +309,14 @@ static bool set_param(Module* mod, const char* fqn, Value& val) static bool set_value(const char* fqn, Value& v) { - string mod_name = fqn; - set_top(mod_name); + string t = fqn; + set_type(t); + fqn = t.c_str(); + + string key = t; + set_top(key); - Module* mod = ModuleManager::get_module(mod_name.c_str()); + Module* mod = ModuleManager::get_module(key.c_str()); if ( !mod ) return set_var(fqn, v); @@ -343,11 +362,24 @@ extern "C" bool set_bool(const char* fqn, bool val); bool set_number(const char* fqn, double val); bool set_string(const char* fqn, const char* val); + bool set_alias(const char* from, const char* to); +} + +SO_PUBLIC bool set_alias(const char* from, const char* to) +{ + s_name = from; + s_type = to; + return true; } SO_PUBLIC bool open_table(const char* s, int idx) { - string key = s; + const char* orig = s; + string fqn = s; + set_type(fqn); + s = fqn.c_str(); + + string key = fqn; set_top(key); // ips option parameters only using in rules which @@ -362,7 +394,10 @@ SO_PUBLIC bool open_table(const char* s, int idx) if ( s_current != key ) { - LogMessage("\t %s\n", key.c_str()); + if ( fqn != orig ) + LogMessage("\t%s (%s)\n", key.c_str(), orig); + else + LogMessage("\t%s\n", key.c_str()); s_current = key; } @@ -376,20 +411,26 @@ SO_PUBLIC bool open_table(const char* s, int idx) SO_PUBLIC void close_table(const char* s, int idx) { - string key = s; + string fqn = s; + set_type(fqn); + s = fqn.c_str(); + + string key = fqn; set_top(key); if ( ModHook* h = get_hook(key.c_str()) ) { if ( !h->mod->end(s, idx, s_config) ) - { ParseError("can't close %s", h->mod->get_name()); - return; - } - if ( !idx && h->api && (key == s) ) + else if ( !s_name.empty() ) + PluginManager::instantiate(h->api, h->mod, s_config, s_name.c_str()); + + else if ( !idx && h->api && (key == s) ) PluginManager::instantiate(h->api, h->mod, s_config); } + s_name.clear(); + s_type.clear(); } SO_PUBLIC bool set_bool(const char* fqn, bool b) diff --git a/src/managers/module_manager.h b/src/managers/module_manager.h index 1c322d277..7da44e7f4 100644 --- a/src/managers/module_manager.h +++ b/src/managers/module_manager.h @@ -21,6 +21,8 @@ #ifndef MODULE_MANAGER_H #define MODULE_MANAGER_H +#include + //------------------------------------------------------------------------- struct SnortConfig; diff --git a/src/managers/plugin_manager.cc b/src/managers/plugin_manager.cc index 2b298da5f..f1ff33ea8 100644 --- a/src/managers/plugin_manager.cc +++ b/src/managers/plugin_manager.cc @@ -468,3 +468,10 @@ void PluginManager::instantiate( } } +void PluginManager::instantiate( + const BaseApi* api, Module* mod, SnortConfig* sc, const char* name) +{ + assert(api->type == PT_INSPECTOR); + InspectorManager::instantiate((InspectApi*)api, mod, sc, name); +} + diff --git a/src/managers/plugin_manager.h b/src/managers/plugin_manager.h index 801e2d2d8..f2f9136ea 100644 --- a/src/managers/plugin_manager.h +++ b/src/managers/plugin_manager.h @@ -50,10 +50,13 @@ public: static void show_plugins(); static void dump_plugins(); static void release_plugins(); + static const BaseApi* get_api(PlugType, const char* name); - static void instantiate(const BaseApi*, Module*, SnortConfig*); static const char* get_type_name(PlugType); static const char* get_current_plugin(); + + static void instantiate(const BaseApi*, Module*, SnortConfig*); + static void instantiate(const BaseApi*, Module*, SnortConfig*, const char* name); }; #endif diff --git a/src/managers/snort_config.lua b/src/managers/snort_config.lua index 26e17547f..df49d7010 100644 --- a/src/managers/snort_config.lua +++ b/src/managers/snort_config.lua @@ -30,6 +30,7 @@ void close_table(const char*, int); bool set_bool(const char*, bool); bool set_number(const char*, double); bool set_string(const char*, const char*); +bool set_alias(const char*, const char*); ]] function include(file) @@ -80,7 +81,26 @@ function snort_set(fqn, key, val) end end -function snort_config() - snort_traverse(_G) +function load_aliases() + for i,v in ipairs(binder) do + if ( v.use and type(v.use) == "table" ) then + if ( v.use.name and v.use.type ) then + ffi.C.set_alias(v.use.name, v.use.type) + tab = _G[v.use.name] + + if ( tab ) then + snort_set(nil, v.use.name, _G[v.use.name]) + end + end + end + end +end + +function snort_config(tab) + snort_traverse(tab) + + if ( binder and type(binder) == 'table' ) then + load_aliases() + end end diff --git a/src/network_inspectors/binder/bind_module.cc b/src/network_inspectors/binder/bind_module.cc index 6a3bfc90d..a56241ac6 100644 --- a/src/network_inspectors/binder/bind_module.cc +++ b/src/network_inspectors/binder/bind_module.cc @@ -33,6 +33,8 @@ using namespace std; #include "main/policy.h" #include "main/snort_config.h" #include "main/shell.h" +#include "managers/module_manager.h" +#include "parser/parser.h" THREAD_LOCAL BindStats bstats; @@ -123,7 +125,7 @@ BinderModule::~BinderModule() ProfileStats* BinderModule::get_profile() const { return &bindPerfStats; } -bool BinderModule::set(const char* fqn, Value& v, SnortConfig* sc) +bool BinderModule::set(const char* fqn, Value& v, SnortConfig*) { // both if ( !strcmp(fqn, "binder.when.service") ) @@ -165,15 +167,26 @@ bool BinderModule::set(const char* fqn, Value& v, SnortConfig* sc) else if ( v.is("file") ) { - Shell* sh = new Shell(v.get_string()); - work->use.index = sc->policy_map->add_shell(sh) + 1; + if ( !work->use.name.empty() || !work->use.type.empty() ) + ParseError("you can't set binder.use.file with type or name"); + + work->use.name = v.get_string(); + work->use.type = ".file"; } else if ( v.is("name") ) - work->use.name = v.get_string(); + { + if ( !work->use.name.empty() ) + ParseError("you can't set binder.use.file with type or name"); + work->use.name = v.get_string(); + } else if ( v.is("type") ) - work->use.type = v.get_string(); + { + if ( !work->use.type.empty() ) + ParseError("you can't set binder.use.file with type or name"); + work->use.type = v.get_string(); + } else return false; @@ -188,10 +201,18 @@ bool BinderModule::begin(const char* fqn, int idx, SnortConfig*) return true; } -bool BinderModule::end(const char* fqn, int idx, SnortConfig*) +bool BinderModule::end(const char* fqn, int idx, SnortConfig* sc) { if ( idx && !strcmp(fqn, BIND_NAME) ) { + if ( work->use.type == ".file" ) + { + Shell* sh = new Shell(work->use.name.c_str()); + work->use.index = sc->policy_map->add_shell(sh) + 1; + } + if ( !work->use.name.size() ) + work->use.name = work->use.type; + bindings.push_back(work); work = nullptr; } diff --git a/src/network_inspectors/binder/binder.cc b/src/network_inspectors/binder/binder.cc index 929f59ba1..9d1e42281 100644 --- a/src/network_inspectors/binder/binder.cc +++ b/src/network_inspectors/binder/binder.cc @@ -227,7 +227,7 @@ Inspector* Binder::find_inspector(Flow* flow) if ( !pb ) return nullptr; - Inspector* ins = InspectorManager::get_inspector(pb->use.type.c_str()); + Inspector* ins = InspectorManager::get_inspector(pb->use.name.c_str()); return ins; } @@ -323,14 +323,14 @@ BindAction Binder::apply(Flow* flow, Binding* pb) init_flow(flow); Inspector* ins; - if ( !pb->use.type.size() || pb->use.type == "wizard" ) + if ( !pb->use.name.size() || pb->use.name == "wizard" ) { ins = InspectorManager::get_wizard(); flow->set_clouseau(ins); } else { - ins = InspectorManager::get_inspector(pb->use.type.c_str()); + ins = InspectorManager::get_inspector(pb->use.name.c_str()); flow->set_gadget(ins); } return BA_INSPECT;