-- 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
}
}
-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);
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() )
{
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);
{
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)
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;
}
// 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;
if ( !ppi )
ParseError("can't instantiate inspector: '%s'.", keyword);
+
+ else if ( name )
+ ppi->set_name(name);
}
}
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);
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;
// 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('.');
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);
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
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;
}
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)
#ifndef MODULE_MANAGER_H
#define MODULE_MANAGER_H
+#include <string>
+
//-------------------------------------------------------------------------
struct SnortConfig;
}
}
+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);
+}
+
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
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)
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
#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;
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") )
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;
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;
}
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;
}
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;