]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1309 in SNORT/snort3 from reputation_reload to master
authorHui Cao (huica) <huica@cisco.com>
Fri, 20 Jul 2018 15:19:06 +0000 (11:19 -0400)
committerHui Cao (huica) <huica@cisco.com>
Fri, 20 Jul 2018 15:19:06 +0000 (11:19 -0400)
Squashed commit of the following:

commit 267ea293ce5e496ead3b4a1161177db6f8aa64f1
Author: huica <huica@cisco.com>
Date:   Fri Jul 13 10:30:35 2018 -0400

    reputation: support reload module

src/main.cc
src/main.h
src/main/snort.cc
src/main/snort.h
src/main/snort_module.cc
src/managers/module_manager.cc
src/managers/module_manager.h
src/network_inspectors/reputation/reputation_config.h
src/network_inspectors/reputation/reputation_inspect.cc
src/network_inspectors/reputation/reputation_module.cc
src/network_inspectors/reputation/reputation_parse.cc

index 8b3cf0e7fae93ae5b9e2cb4e4dc17719768c61dd..a9494df6fa2efb0e7adb6b28d7da8fd66584fe0f 100644 (file)
@@ -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 );
index cc4041eb09a0517a9026f53862ed69eff025a9ae..82defae28aae27e82edafa1cc24a9afb4a66c2ec 100644 (file)
@@ -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);
index 8eefc9ee0b87943227e52c6f5b6fecac934626ab..11a518d92407e4abfe7a5a4b67bdecc7b5b17198 100644 (file)
@@ -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() )
index abed229fa1d1fa640e0684d19628744a2fd36ca4..e796f4709b3c7cf644c03b8ce07aa45af72b6e78 100644 (file)
@@ -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();
index be79b27def0cd6f69e38f158fc78688e2fca23bc..daf4fe3dff8d973088fdaaba52b3f5eabeee6a00 100644 (file)
@@ -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" },
 
index 36221fe67675b9bdc7b47081121536de9a97bb03..b1612377a9f3c63ae8ff83f9567bc663ebbe8179 100644 (file)
@@ -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 )
index 5309ed6a888aad4eb75ddb7a78471dccf27bf77c..6c1d7bf4ceb6784916211f4a344afe90322bd8c4 100644 (file)
@@ -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();
index afae40e7f345a4e9ab0cbbc670086707200e5760..080de0df0d16fc3f63e8c2d2af6cdfad8f63d703 100644 (file)
@@ -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;
index 3e0dac9ca61aca74f2580d1a9bb91f9af8b0f021..c0dc555f197461aec9b9831e065e98b4a7b42d9d 100644 (file)
@@ -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;
     }
index e7f90e018367184c6e48df990bce278248338a7d..524d376f7be0ccd6af671807f8fc5b6882c6988a 100644 (file)
@@ -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 "
index 0351aa80b26bd856cd48cf76dadd034b0a4916c6..e18de36da4339c59af8114ac0cc949c8fb8c0b41 100644 (file)
@@ -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;