From 29d792b09340c85b0887b0e014a7a502bee9e662 Mon Sep 17 00:00:00 2001 From: "Russ Combs (rucombs)" Date: Fri, 11 Aug 2017 12:31:22 -0400 Subject: [PATCH] Merge pull request #975 in SNORT/snort3 from delete_inspector to master Squashed commit of the following: commit bc33c5a6534764063530ab181422f6a0bb6ac9d1 Author: Bhagya Tholpady Date: Wed Jul 26 11:05:30 2017 -0400 control: delete inspector from the default inspection policy --- src/framework/inspector.h | 1 + src/main.cc | 43 ++++++++++++++++++++++++- src/main.h | 1 + src/main/snort.cc | 37 +++++++++++++++------ src/main/snort.h | 2 +- src/main/snort_config.cc | 1 - src/main/snort_module.cc | 9 ++++++ src/managers/inspector_manager.cc | 26 +++++++++++++++ src/managers/inspector_manager.h | 1 + src/network_inspectors/binder/binder.cc | 22 +++++++++++++ src/utils/stats.cc | 1 + src/utils/stats.h | 1 + 12 files changed, 132 insertions(+), 13 deletions(-) diff --git a/src/framework/inspector.h b/src/framework/inspector.h index b90a9ed9e..b12c75f1e 100644 --- a/src/framework/inspector.h +++ b/src/framework/inspector.h @@ -64,6 +64,7 @@ public: // return verification status virtual bool configure(SnortConfig*) { return true; } virtual void show(SnortConfig*) { } + virtual void update(SnortConfig*, const char*) { } // packet thread functions // tinit, tterm called on default policy instance only diff --git a/src/main.cc b/src/main.cc index 52e341d4c..c3a3cf7d0 100644 --- a/src/main.cc +++ b/src/main.cc @@ -353,7 +353,7 @@ int main_reload_policy(lua_State* L) } SnortConfig* old = snort_conf; - SnortConfig* sc = Snort::get_reloaded_policy(old, fname); + SnortConfig* sc = Snort::get_updated_policy(old, fname, nullptr); if ( !sc ) { @@ -417,6 +417,47 @@ int main_reload_hosts(lua_State* L) return 0; } +int main_delete_inspector(lua_State* L) +{ + if ( Swapper::get_reload_in_progress() ) + { + current_request->respond("== delete pending; retry\n"); + return 0; + } + const char* iname = nullptr; + + if ( L ) + { + Lua::ManageStack(L, 1); + iname = luaL_checkstring(L, 1); + } + + if ( iname and *iname ) + current_request->respond(".. deleting inspector\n"); + else + { + current_request->respond("== inspector name required\n"); + return 0; + } + + SnortConfig* old = snort_conf; + SnortConfig* sc = Snort::get_updated_policy(old, nullptr, iname); + + if ( !sc ) + { + current_request->respond("== reload failed\n"); + return 0; + } + snort_conf = sc; + proc_stats.inspector_deletions++; + + bool from_shell = ( L != nullptr ); + current_request->respond(".. deleted inspector\n", from_shell); + broadcast(get_command(new ACSwap(new Swapper(old, sc)), from_shell)); + + return 0; +} + int main_process(lua_State* L) { const char* f = lua_tostring(L, 1); diff --git a/src/main.h b/src/main.h index c9a7e88e3..006b7a917 100644 --- a/src/main.h +++ b/src/main.h @@ -26,6 +26,7 @@ struct lua_State; const char* get_prompt(); // commands provided by the snort module +int main_delete_inspector(lua_State* = nullptr); int main_dump_stats(lua_State* = nullptr); int main_rotate_stats(lua_State* = nullptr); int main_reload_config(lua_State* = nullptr); diff --git a/src/main/snort.cc b/src/main/snort.cc index 485a07eb2..f102bd6c5 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -631,22 +631,39 @@ SnortConfig* Snort::get_reload_config(const char* fname) return sc; } -SnortConfig* Snort::get_reloaded_policy(SnortConfig* other_conf, const char* fname) +SnortConfig* Snort::get_updated_policy(SnortConfig* other_conf, const char* fname, const char* iname) { reloading = true; SnortConfig* sc = new SnortConfig(other_conf); - Shell sh = Shell(fname); - sh.configure(sc); - if ( ModuleManager::get_errors() || !sc->verify() ) + if ( fname ) { - sc->cloned = true; - InspectorManager::update_policy(other_conf); - delete sc; - set_policies(other_conf); - reloading = false; - return nullptr; + Shell sh = Shell(fname); + sh.configure(sc); + + if ( ModuleManager::get_errors() || !sc->verify() ) + { + sc->cloned = true; + InspectorManager::update_policy(other_conf); + delete sc; + set_policies(other_conf); + reloading = false; + return nullptr; + } + } + + if ( iname ) + { + if ( !InspectorManager::delete_inspector(sc, iname) ) + { + sc->cloned = true; + InspectorManager::update_policy(other_conf); + delete sc; + set_policies(other_conf); + reloading = false; + return nullptr; + } } if ( !InspectorManager::configure(sc, true) ) diff --git a/src/main/snort.h b/src/main/snort.h index cb19533ca..0be7708bc 100644 --- a/src/main/snort.h +++ b/src/main/snort.h @@ -38,7 +38,7 @@ class Snort { public: static SnortConfig* get_reload_config(const char* fname); - static SnortConfig* get_reloaded_policy(SnortConfig*, const char* fname); + static SnortConfig* get_updated_policy(SnortConfig*, const char* fname, const char* iname); static void setup(int argc, char* argv[]); static bool drop_privileges(); static void do_pidfile(); diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index b25cf1c96..7fb440422 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -325,7 +325,6 @@ void SnortConfig::clone(SnortConfig* conf) if (conf->obfuscation_net.get_family() != 0) memcpy(&obfuscation_net, &conf->obfuscation_net, sizeof(obfuscation_net)); - } // merge in everything from the command line config diff --git a/src/main/snort_module.cc b/src/main/snort_module.cc index fcb83a1ba..3b6a06926 100644 --- a/src/main/snort_module.cc +++ b/src/main/snort_module.cc @@ -59,9 +59,18 @@ static const Parameter s_reload[] = { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; +static const Parameter s_delete[] = +{ + { "inspector", Parameter::PT_STRING, nullptr, nullptr, + "name of inspector to delete" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + static const Command snort_cmds[] = { { "show_plugins", main_dump_plugins, nullptr, "show available plugins" }, + { "delete_inspector", main_delete_inspector, s_delete, "delete an inspector from the default policy" }, { "dump_stats", main_dump_stats, nullptr, "show summary statistics" }, { "rotate_stats", main_rotate_stats, nullptr, "roll perfmonitor log files" }, { "reload_config", main_reload_config, s_reload, "load new configuration" }, diff --git a/src/managers/inspector_manager.cc b/src/managers/inspector_manager.cc index 61d4cfb1c..bc0878090 100644 --- a/src/managers/inspector_manager.cc +++ b/src/managers/inspector_manager.cc @@ -98,6 +98,7 @@ struct PHClass enum ReloadType { RELOAD_TYPE_NONE = 0, + RELOAD_TYPE_DELETED, RELOAD_TYPE_REENABLED, RELOAD_TYPE_NEW, RELOAD_TYPE_MAX @@ -124,6 +125,7 @@ struct PHInstance bool is_reloaded() { return ((reload_type == RELOAD_TYPE_REENABLED) or + (reload_type == RELOAD_TYPE_DELETED) or (reload_type == RELOAD_TYPE_NEW)); } ReloadType get_reload_type() @@ -513,6 +515,30 @@ InspectorType InspectorManager::get_type(const char* key) return p->get_api()->type; } +bool InspectorManager::delete_inspector(SnortConfig* sc, const char* iname) +{ + bool ok = false; + if ( sc->policy_map->inspection_policy.size() ) + { + FrameworkPolicy* fp = sc->policy_map->inspection_policy[0]->framework_policy; + std::vector::iterator old_it; + + if ( get_instance(fp, iname, false, old_it) ) + { + (*old_it)->set_reloaded(RELOAD_TYPE_DELETED); + fp->ilist.erase(old_it); + ok = true; + std::vector::iterator bind_it; + if ( get_instance(fp, "binder", false, bind_it) ) + { + (*bind_it)->handler->update(sc, iname); + } + } + } + + return ok; +} + void InspectorManager::free_inspector(Inspector* p) { p->get_api()->dtor(p); diff --git a/src/managers/inspector_manager.h b/src/managers/inspector_manager.h index d1fe4f0be..117c27ac5 100644 --- a/src/managers/inspector_manager.h +++ b/src/managers/inspector_manager.h @@ -54,6 +54,7 @@ public: static void instantiate( const InspectApi*, Module*, SnortConfig*, const char* name = nullptr); + static bool delete_inspector(SnortConfig* sc, const char* iname); static void free_inspector(Inspector*); static InspectSsnFunc get_session(uint16_t proto); diff --git a/src/network_inspectors/binder/binder.cc b/src/network_inspectors/binder/binder.cc index 8269b5bd2..cf1b7c908 100644 --- a/src/network_inspectors/binder/binder.cc +++ b/src/network_inspectors/binder/binder.cc @@ -410,6 +410,8 @@ public: void show(SnortConfig*) override { LogMessage("Binder\n"); } + void update(SnortConfig*, const char*) override; + bool configure(SnortConfig*) override; void eval(Packet*) override; @@ -458,6 +460,26 @@ bool Binder::configure(SnortConfig* sc) return true; } +void Binder::update(SnortConfig* sc, const char* name) +{ + vector::iterator it; + for ( it = bindings.begin(); it != bindings.end(); ++it ) + { + const char* key; + Binding *pb = *it; + if ( pb->use.svc.empty() ) + key = pb->use.name.c_str(); + else + key = pb->use.svc.c_str(); + if ( !strcmp(key, name) ) + { + bindings.erase(it); + delete pb; + return; + } + } +} + // FIXIT-M need to consider binding of ips rules / policy // possibly split bindings into these categories void Binder::eval(Packet* p) diff --git a/src/utils/stats.cc b/src/utils/stats.cc index 67c102424..5d6a2f99a 100644 --- a/src/utils/stats.cc +++ b/src/utils/stats.cc @@ -219,6 +219,7 @@ const PegInfo proc_names[] = { "signals", "total signals processed" }, { "conf_reloads", "number of times configuration was reloaded" }, { "policy_reloads", "number of times policies were reloaded" }, + { "inspector_deletions", "number of times inspectors were deleted" }, { "daq_reloads", "number of times daq configuration was reloaded" }, { "attribute_table_reloads", "number of times hosts table was reloaded" }, { "attribute_table_hosts", "total number of hosts in table" }, diff --git a/src/utils/stats.h b/src/utils/stats.h index 7e08423d9..0fd7ec6c1 100644 --- a/src/utils/stats.h +++ b/src/utils/stats.h @@ -62,6 +62,7 @@ struct ProcessCount PegCount signals; PegCount conf_reloads; PegCount policy_reloads; + PegCount inspector_deletions; PegCount daq_reloads; PegCount attribute_table_reloads; PegCount attribute_table_hosts; -- 2.47.3