From: Hui Cao (huica) Date: Fri, 20 Jul 2018 15:19:06 +0000 (-0400) Subject: Merge pull request #1309 in SNORT/snort3 from reputation_reload to master X-Git-Tag: 3.0.0-246~19 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=998bb0f75c5c8ca98ac63307658f7eea5160d3f0;p=thirdparty%2Fsnort3.git Merge pull request #1309 in SNORT/snort3 from reputation_reload to master Squashed commit of the following: commit 267ea293ce5e496ead3b4a1161177db6f8aa64f1 Author: huica Date: Fri Jul 13 10:30:35 2018 -0400 reputation: support reload module --- diff --git a/src/main.cc b/src/main.cc index 8b3cf0e7f..a9494df6f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -385,6 +385,47 @@ int main_reload_policy(lua_State* L) return 0; } +int main_reload_module(lua_State* L) +{ + if ( Swapper::get_reload_in_progress() ) + { + current_request->respond("== reload pending; retry\n"); + return 0; + } + const char* fname = nullptr; + + if ( L ) + { + Lua::ManageStack(L, 1); + fname = luaL_checkstring(L, 1); + } + + if ( fname and *fname ) + current_request->respond(".. reloading module\n"); + else + { + current_request->respond("== module name required\n"); + return 0; + } + + SnortConfig* old = SnortConfig::get_conf(); + SnortConfig* sc = Snort::get_updated_module(old, fname); + + if ( !sc ) + { + current_request->respond("== reload failed\n"); + return 0; + } + SnortConfig::set_conf(sc); + proc_stats.policy_reloads++; + + bool from_shell = ( L != nullptr ); + current_request->respond(".. swapping module\n", from_shell); + main_broadcast_command(new ACSwap(new Swapper(old, sc)), from_shell); + + return 0; +} + int main_reload_daq(lua_State* L) { bool from_shell = ( L != nullptr ); diff --git a/src/main.h b/src/main.h index cc4041eb0..82defae28 100644 --- a/src/main.h +++ b/src/main.h @@ -31,6 +31,7 @@ int main_dump_stats(lua_State* = nullptr); int main_rotate_stats(lua_State* = nullptr); int main_reload_config(lua_State* = nullptr); int main_reload_policy(lua_State* = nullptr); +int main_reload_module(lua_State* = nullptr); int main_reload_daq(lua_State* = nullptr); int main_reload_hosts(lua_State* = nullptr); int main_process(lua_State* = nullptr); diff --git a/src/main/snort.cc b/src/main/snort.cc index 8eefc9ee0..11a518d92 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -675,6 +675,43 @@ SnortConfig* Snort::get_updated_policy(SnortConfig* other_conf, const char* fnam return sc; } +SnortConfig* Snort::get_updated_module(SnortConfig* other_conf, const char* name) +{ + reloading = true; + + SnortConfig* sc = new SnortConfig(other_conf); + + if ( name ) + { + ModuleManager::reload_module(name, sc); + if ( ModuleManager::get_errors() || !sc->verify() ) + { + sc->cloned = true; + InspectorManager::update_policy(other_conf); + delete sc; + set_default_policy(other_conf); + reloading = false; + return nullptr; + } + } + + if ( !InspectorManager::configure(sc, true) ) + { + sc->cloned = true; + InspectorManager::update_policy(other_conf); + delete sc; + set_default_policy(other_conf); + reloading = false; + return nullptr; + } + + other_conf->cloned = true; + + InspectorManager::update_policy(sc); + reloading = false; + return sc; +} + void Snort::capture_packet() { if ( snort_main_thread_pid == gettid() ) diff --git a/src/main/snort.h b/src/main/snort.h index abed229fa..e796f4709 100644 --- a/src/main/snort.h +++ b/src/main/snort.h @@ -41,6 +41,7 @@ class Snort public: static SnortConfig* get_reload_config(const char* fname); static SnortConfig* get_updated_policy(SnortConfig*, const char* fname, const char* iname); + static SnortConfig* get_updated_module(SnortConfig*, const char* name); static void setup(int argc, char* argv[]); static bool drop_privileges(); static void do_pidfile(); diff --git a/src/main/snort_module.cc b/src/main/snort_module.cc index be79b27de..daf4fe3df 100644 --- a/src/main/snort_module.cc +++ b/src/main/snort_module.cc @@ -69,6 +69,14 @@ static const Parameter s_delete[] = { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; +static const Parameter s_module[] = +{ + { "module", Parameter::PT_STRING, nullptr, nullptr, + "name of the module to reload" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + static const Command snort_cmds[] = { { "show_plugins", main_dump_plugins, nullptr, "show available plugins" }, @@ -77,6 +85,7 @@ static const Command snort_cmds[] = { "rotate_stats", main_rotate_stats, nullptr, "roll perfmonitor log files" }, { "reload_config", main_reload_config, s_reload, "load new configuration" }, { "reload_policy", main_reload_policy, s_reload, "reload part or all of the default policy" }, + { "reload_module", main_reload_module, s_module, "reload module" }, { "reload_daq", main_reload_daq, nullptr, "reload daq module" }, { "reload_hosts", main_reload_hosts, s_reload, "load a new hosts table" }, diff --git a/src/managers/module_manager.cc b/src/managers/module_manager.cc index 36221fe67..b1612377a 100644 --- a/src/managers/module_manager.cc +++ b/src/managers/module_manager.cc @@ -1068,6 +1068,20 @@ void ModuleManager::show_module(const char* name) cout << "no match" << endl; } +void ModuleManager::reload_module(const char* name, snort::SnortConfig* sc) +{ + if ( ModHook* h = get_hook(name) ) + { + PluginManager::instantiate(h->api, h->mod, sc); + + } + else + { + cout << "Module " << name <<" doesn't exist"; + cout << endl; + } +} + static bool selected(const Module* m, const char* pfx, bool exact) { if ( !pfx ) diff --git a/src/managers/module_manager.h b/src/managers/module_manager.h index 5309ed6a8..6c1d7bf4c 100644 --- a/src/managers/module_manager.h +++ b/src/managers/module_manager.h @@ -71,6 +71,7 @@ public: static void load_commands(Shell*); static void load_rules(snort::SnortConfig*); static void set_config(snort::SnortConfig*); + static void reload_module(const char*, snort::SnortConfig*); static void reset_errors(); static unsigned get_errors(); diff --git a/src/network_inspectors/reputation/reputation_config.h b/src/network_inspectors/reputation/reputation_config.h index afae40e7f..080de0df0 100644 --- a/src/network_inspectors/reputation/reputation_config.h +++ b/src/network_inspectors/reputation/reputation_config.h @@ -79,12 +79,10 @@ struct ReputationConfig IPdecision priority = WHITELISTED_TRUST; NestedIP nested_ip = INNER; WhiteAction white_action = UNBLACK; - MEM_OFFSET local_black_ptr = 0; - MEM_OFFSET local_white_ptr = 0; - uint8_t* reputation_segment = nullptr; - char* blacklist_path = nullptr; - char* whitelist_path = nullptr; + std::string blacklist_path; + std::string whitelist_path; bool memcap_reached = false; + uint8_t* reputation_segment = nullptr; table_flat_t* ip_list = nullptr; ListFiles list_files; std::string list_dir; diff --git a/src/network_inspectors/reputation/reputation_inspect.cc b/src/network_inspectors/reputation/reputation_inspect.cc index 3e0dac9ca..c0dc555f1 100644 --- a/src/network_inspectors/reputation/reputation_inspect.cc +++ b/src/network_inspectors/reputation/reputation_inspect.cc @@ -24,6 +24,7 @@ #endif #include "reputation_inspect.h" +#include "reputation_parse.h" #include "detection/detect.h" #include "detection/detection_engine.h" @@ -145,11 +146,11 @@ static void print_reputation_conf(ReputationConfig* config) LogMessage(" White action: %s %s \n", WhiteActionOption[config->white_action], config->white_action == UNBLACK ? "(Default)" : ""); - if (config->blacklist_path) - LogMessage(" Blacklist File Path: %s\n", config->blacklist_path); + if (config->blacklist_path.size()) + LogMessage(" Blacklist File Path: %s\n", config->blacklist_path.c_str()); - if (config->whitelist_path) - LogMessage(" Whitelist File Path: %s\n", config->whitelist_path); + if (config->whitelist_path.size()) + LogMessage(" Whitelist File Path: %s\n", config->whitelist_path.c_str()); LogMessage("\n"); } @@ -343,32 +344,37 @@ class Reputation : public Inspector { public: Reputation(ReputationConfig*); - ~Reputation() override; void show(SnortConfig*) override; void eval(Packet*) override; private: - ReputationConfig* config; + ReputationConfig config; }; Reputation::Reputation(ReputationConfig* pc) { - config = pc; - reputationstats.memory_allocated = sfrt_flat_usage(config->ip_list); -} - -Reputation::~Reputation() -{ - if ( config ) + config = *pc; + ReputationConfig* conf = &config; + if (!config.list_dir.empty()) + read_manifest(MANIFEST_FILENAME, conf); + + add_black_white_List(conf); + estimate_num_entries(conf); + if (conf->num_entries <= 0) { - delete config; + ParseWarning(WARN_CONF, + "reputation: can't find any whitelist/blacklist entries; disabled."); + return; } + + ip_list_init(conf->num_entries + 1, conf); + reputationstats.memory_allocated = sfrt_flat_usage(conf->ip_list); } void Reputation::show(SnortConfig*) { - print_reputation_conf(config); + print_reputation_conf(&config); } void Reputation::eval(Packet* p) @@ -380,7 +386,7 @@ void Reputation::eval(Packet* p) if (!p->is_rebuilt() && !is_reputation_disabled(p->flow)) { - snort_reputation(config, p); + snort_reputation(&config, p); disable_reputation(p->flow); ++reputationstats.packets; } diff --git a/src/network_inspectors/reputation/reputation_module.cc b/src/network_inspectors/reputation/reputation_module.cc index e7f90e018..524d376f7 100644 --- a/src/network_inspectors/reputation/reputation_module.cc +++ b/src/network_inspectors/reputation/reputation_module.cc @@ -109,10 +109,10 @@ ProfileStats* ReputationModule::get_profile() const bool ReputationModule::set(const char*, Value& v, SnortConfig*) { if ( v.is("blacklist") ) - conf->blacklist_path = snort_strdup(v.get_string()); + conf->blacklist_path = v.get_string(); else if ( v.is("list_dir") ) - conf->list_dir = std::string(v.get_string()); + conf->list_dir = v.get_string(); else if ( v.is("memcap") ) conf->memcap = v.get_long(); @@ -130,7 +130,7 @@ bool ReputationModule::set(const char*, Value& v, SnortConfig*) conf->white_action = (WhiteAction)v.get_long(); else if ( v.is("whitelist") ) - conf->whitelist_path = snort_strdup(v.get_string()); + conf->whitelist_path = v.get_string(); else return false; @@ -140,34 +140,17 @@ bool ReputationModule::set(const char*, Value& v, SnortConfig*) ReputationConfig* ReputationModule::get_data() { - ReputationConfig* tmp = conf; - conf = nullptr; - return tmp; + return conf; } bool ReputationModule::begin(const char*, int, SnortConfig*) { - assert(!conf); conf = new ReputationConfig; return true; } bool ReputationModule::end(const char*, int, SnortConfig*) { - if (!conf->list_dir.empty()) - read_manifest(MANIFEST_FILENAME, conf); - - add_black_white_List(conf); - estimate_num_entries(conf); - if (conf->num_entries <= 0) - { - ParseWarning(WARN_CONF, - "reputation: can't find any whitelist/blacklist entries; disabled."); - return true; - } - - ip_list_init(conf->num_entries + 1, conf); - if ( (conf->priority == WHITELISTED_TRUST) && (conf->white_action == UNBLACK) ) { ParseWarning(WARN_CONF, "Keyword \"whitelist\" for \"priority\" is " diff --git a/src/network_inspectors/reputation/reputation_parse.cc b/src/network_inspectors/reputation/reputation_parse.cc index 0351aa80b..e18de36da 100644 --- a/src/network_inspectors/reputation/reputation_parse.cc +++ b/src/network_inspectors/reputation/reputation_parse.cc @@ -80,12 +80,6 @@ ReputationConfig::~ReputationConfig() if (reputation_segment != nullptr) snort_free(reputation_segment); - if (blacklist_path) - snort_free(blacklist_path); - - if (whitelist_path) - snort_free(whitelist_path); - for (auto& file : list_files) { delete file; @@ -752,7 +746,7 @@ void estimate_num_entries(ReputationConfig* config) void add_black_white_List(ReputationConfig* config) { - if (config->blacklist_path) + if (config->blacklist_path.size()) { ListFile* listItem = new ListFile; listItem->all_zones_enabled = true; @@ -761,7 +755,7 @@ void add_black_white_List(ReputationConfig* config) listItem->list_id = 0; config->list_files.push_back(listItem); } - if (config->whitelist_path) + if (config->whitelist_path.size()) { ListFile* listItem = new ListFile; listItem->all_zones_enabled = true;