]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
support for name/type bindings
authorRuss Combs <rucombs@cisco.com>
Wed, 1 Oct 2014 13:30:21 +0000 (09:30 -0400)
committerRuss Combs <rucombs@cisco.com>
Wed, 1 Oct 2014 13:30:21 +0000 (09:30 -0400)
ChangeLog
src/main/shell.cc
src/managers/inspector_manager.cc
src/managers/inspector_manager.h
src/managers/module_manager.cc
src/managers/module_manager.h
src/managers/plugin_manager.cc
src/managers/plugin_manager.h
src/managers/snort_config.lua
src/network_inspectors/binder/bind_module.cc
src/network_inspectors/binder/binder.cc

index 0ad70226523af2a080694a3ffc17c29455b070e7..efa3f7ebd1fbf688352012b836f3eea07e7601f4 100644 (file)
--- 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
index 9ba6583cd91d35772d9500accd5e17d79284f1ba..87ed832da603e65ca9106fdd3c8991f8c5ca9825 100644 (file)
@@ -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);
index f4bf16e4fb409c87a72334a8c9a6f786db43afd8..2ccb9a961fe9ab76e522d84a5c1761e2e6b4b63d 100644 (file)
@@ -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);
     }
 }
 
index cc46f847fb7b4d165e291e5cc7af7d05fae63d87..d9ae6d97c3e0ec8f0e538df753b2d4c0e463a1c9 100644 (file)
@@ -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);
 
index e324ef8d23ad40028471282fba1d0adf61438df0..d35ffe9d24412ddcf075c28a6c87aca407ae33da 100644 (file)
@@ -59,6 +59,8 @@ typedef list<ModHook*> 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)
index 1c322d277488384cddb56daaaafff2fcc69eb1e9..7da44e7f430920a50ab779429df9b4fd2bc9f6a0 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef MODULE_MANAGER_H
 #define MODULE_MANAGER_H
 
+#include <string>
+
 //-------------------------------------------------------------------------
 
 struct SnortConfig;
index 2b298da5fa2ab564ab274e7ec20bece19b6acb91..f1ff33ea836bd075fd82d163cac587b78b648ad5 100644 (file)
@@ -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);
+}
+
index 801e2d2d879949df2966432b287e3c78358bcf83..f2f9136ea08bd73e0af64e95f347ccba43d9e973 100644 (file)
@@ -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
index 26e17547fb9b914e7dd7b8d92162a035ea40428a..df49d70103be45240f335eaf14ce57374fe0e8eb 100644 (file)
@@ -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
 
index 6a3bfc90da40a631cba7e5a56b5fa76a70e98c91..a56241ac69815682b5c8ca0ac37eda95f6085819 100644 (file)
@@ -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;
     }
index 929f59ba1670902d785e340fb901395b95adeea8..9d1e4228124bea493349c5c0232f3de068a52d87 100644 (file)
@@ -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;