]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2504 in SNORT/snort3 from ~SVLASIUK/snort3:rule_state_cleanup...
authorBhagya Tholpady (bbantwal) <bbantwal@cisco.com>
Mon, 5 Oct 2020 15:13:35 +0000 (15:13 +0000)
committerBhagya Tholpady (bbantwal) <bbantwal@cisco.com>
Mon, 5 Oct 2020 15:13:35 +0000 (15:13 +0000)
Squashed commit of the following:

commit 1d46cc8fea3a37a18dc4c6dc1dbd882796131760
Author: Serhii Vlasiuk <svlasiuk@cisco.com>
Date:   Thu Oct 1 18:42:11 2020 +0300

    snort2lua: convert rule_state into ips.states

commit 2c87618a426b72b58f52300b3928014e166832e3
Author: Serhii Vlasiuk <svlasiuk@cisco.com>
Date:   Thu Oct 1 18:39:22 2020 +0300

    main: remove deprecated rule_state module

doc/user/params.txt
src/main/modules.cc
src/main/shell.cc
src/managers/coreinit.lua
tools/snort2lua/conversion_state.h
tools/snort2lua/data/CMakeLists.txt
tools/snort2lua/data/dt_state_api.cc [new file with mode: 0644]
tools/snort2lua/data/dt_state_api.h [new file with mode: 0644]
tools/snort2lua/helpers/converter.cc
tools/snort2lua/helpers/converter.h
tools/snort2lua/keyword_states/kws_rule_state.cc

index e3b2b4865e5ee1af24cca20e726b36a87d6c1ef5..d9eb2c8df89c9f52143cccb19155b2c80367a0a5 100644 (file)
@@ -32,8 +32,7 @@ information about the type and use of the parameter:
 * IPS rules may also have a wild card parameter, which is indicated by a
   *.  Used for unquoted, comma-separated lists such as service and metadata.
 * The snort module has command line options starting with a -.
-* $ denotes variable names, eg rule_state.$gid_sid which would be used
-  like rule_state["1:23456"] = { }.
+* $ denotes variable names.
 
 Some additional details to note:
 
index 34d6d5437616b38c8066d7eb22ccc3f28fc0ac09..76428b53bbe26715fafc08bf278ad09443b28a30 100644 (file)
@@ -1818,120 +1818,6 @@ bool RateFilterModule::end(const char*, int idx, SnortConfig* sc)
     return true;
 }
 
-//-------------------------------------------------------------------------
-// rule_state module
-//-------------------------------------------------------------------------
-
-static const Parameter single_rule_state_params[] =
-{
-    { "action", Parameter::PT_ENUM,
-      "log | pass | alert | drop | block | reset", "alert",
-      "apply action if rule matches or inherit from rule definition" },
-
-    { "enable", Parameter::PT_ENUM, "no | yes | inherit", "inherit",
-      "enable or disable rule in current ips policy or use default defined by ips policy" },
-
-    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-static const Parameter rule_state_params[] =
-{
-    { "$gid_sid", Parameter::PT_LIST, single_rule_state_params, nullptr,
-      "defines rule state parameters for gid:sid" },
-
-    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-#define rule_state_help \
-    "enable/disable and set actions for specific IPS rules; " \
-    "deprecated, use rule state stubs with enable instead"
-
-class RuleStateModule : public Module
-{
-public:
-    RuleStateModule() : Module("rule_state", rule_state_help, rule_state_params, false) { }
-
-    bool set(const char*, Value&, SnortConfig*) override;
-    bool begin(const char*, int, SnortConfig*) override;
-    bool end(const char*, int, SnortConfig*) override;
-
-    bool matches(const char*, std::string&) override;
-
-    Usage get_usage() const override
-    { return DETECT; }
-
-private:
-    RuleKey key;
-    RuleState state;
-};
-
-bool RuleStateModule::matches(const char* param, std::string& name)
-{
-    if ( strcmp(param, "$gid_sid") )
-        return false;
-
-    std::stringstream ss(name);
-    char sep;
-
-    ss >> key.gid >> sep >> key.sid;
-
-    if ( key.gid and key.sid and sep == ':' )
-        return true;
-
-    return false;
-}
-
-bool RuleStateModule::set(const char* fqn, Value& v, SnortConfig*)
-{
-    // the name itself is passed as the fqn when declaring rule_state = { }
-    if ( !strcmp(fqn, "$gid_sid") )
-        return true;
-
-    if ( key.gid and key.sid )
-    {
-        if ( v.is("action") )
-        {
-            state.rule_action = v.get_string();
-            state.action = snort::Actions::Type(v.get_uint8() + 1);
-        }
-
-        else if ( v.is("enable") )
-            state.enable = IpsPolicy::Enable(v.get_uint8());
-    }
-    else
-        return false;
-
-    return true;
-}
-
-bool RuleStateModule::begin(const char*, int, SnortConfig* sc)
-{
-    if ( !sc->rule_states )
-        sc->rule_states = new RuleStateMap;
-
-    else
-    {
-        key = { 0, 0, 0 };
-        state.action = snort::Actions::Type::ALERT;
-        state.enable = IpsPolicy::Enable::INHERIT_ENABLE;
-    }
-    return true;
-}
-
-bool RuleStateModule::end(const char* fqn, int, SnortConfig* sc)
-{
-    if ( !strcmp(fqn, "rule_state") )
-        return true;
-
-    if ( !key.gid or !key.sid )
-        return false;
-
-    key.policy_id = snort::get_ips_policy()->policy_id;
-    sc->rule_states->add(key, state);
-
-    return true;
-}
-
 //-------------------------------------------------------------------------
 // hosts module
 //-------------------------------------------------------------------------
@@ -2104,7 +1990,6 @@ void module_init()
     ModuleManager::add_module(new ProcessModule);
     ModuleManager::add_module(new ProfilerModule);
     ModuleManager::add_module(new ReferencesModule);
-    ModuleManager::add_module(new RuleStateModule);
     ModuleManager::add_module(new SearchEngineModule);
     ModuleManager::add_module(new SFDAQModule);
     ModuleManager::add_module(new PayloadInjectorModule);
index 791dd99c7155ccf31e6ef52aea7daeb10b2f4105..3889ebdc9f2ef9a73cbd22f6f27530a4f8108c9c 100644 (file)
@@ -211,19 +211,13 @@ void Shell::set_config_value(const std::string& fqn, const snort::Value& value)
     if ( !s_config_output || !s_current_node )
         return;
 
-    // lua interpreter does not call open_table for simple list items like (string) or
-    // special rule_state list items
-    // We have to add tree node for this item too
+    // lua interpreter does not call open_table for simple list items like (string)
+    // we have to add tree node for this item
     if ( s_current_node->get_type() == Parameter::PT_LIST )
     {
-        auto node = s_current_node->get_node("");
-        if ( !node || s_current_node->get_name().find(":") == std::string::npos )
-        {
-            node = new TreeConfigNode(s_current_node, "", Parameter::PT_TABLE);
-            s_current_node->add_child_node(node);
-        }
-
-        node->add_child_node(new ValueConfigNode(node, value));
+        add_config_child_node("", Parameter::PT_TABLE);
+        s_current_node->add_child_node(new ValueConfigNode(s_current_node, value));
+        s_current_node = s_current_node->get_parent_node();
 
         return;
     }
index bf02b77eae78287a813b3696a9d7e9fb5a2b02b1..b214cb393f60d503fbdeaa7c6ca9758a0024e434 100644 (file)
@@ -61,7 +61,6 @@ port_scan = { }          -- opt in
 profiler = { }           -- don't activate
 rate_filter = { }        -- pure list
 references = { }         -- pure list
-rule_state = { }         -- pure list
 side_channel = { }       -- leaks!
 snort = { }              -- command line only
 suppress = { }           -- pure list
index 80b37b4b482d69f0863025f0d2c3108abacc47b3..60fb9973fef781a625198a828556bd2209a977f9 100644 (file)
@@ -28,6 +28,7 @@
 
 class DataApi;
 class RuleApi;
+class StateApi;
 class TableApi;
 
 class ConversionState
@@ -37,7 +38,8 @@ public:
         // FIXIT-L these should be removed and accessed through cv
         data_api(c.get_data_api()),
         table_api(c.get_table_api()),
-        rule_api(c.get_rule_api())
+        rule_api(c.get_rule_api()),
+        state_api(c.get_state_api())
     { }
     virtual ~ConversionState() = default;
     virtual bool convert(std::istringstream& data)=0;
@@ -47,6 +49,7 @@ protected:
     DataApi& data_api;
     TableApi& table_api;
     RuleApi& rule_api;
+    StateApi& state_api;
 
     inline bool eat_option(std::istringstream& stream)
     {
index 00532b8032f6068e86ab6e1e61ea157b7fdba01d..3c19e3fd1cce0bc9881469668aafc7b90497d3ba 100644 (file)
@@ -4,9 +4,11 @@ add_subdirectory (data_types)
 add_library( conversion_data OBJECT
     dt_data.h
     dt_data.cc
-    dt_table_api.h
-    dt_table_api.cc
     dt_rule_api.h
     dt_rule_api.cc
+    dt_state_api.h
+    dt_state_api.cc
+    dt_table_api.h
+    dt_table_api.cc
 )
 
diff --git a/tools/snort2lua/data/dt_state_api.cc b/tools/snort2lua/data/dt_state_api.cc
new file mode 100644 (file)
index 0000000..ce21c08
--- /dev/null
@@ -0,0 +1,73 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// dt_state_api.cc author Serhii Vlasiuk <svlasiuk@cisco.com>
+
+#include "data/dt_state_api.h"
+
+#include "data/data_types/dt_rule.h"
+
+void StateApi::create_state()
+{
+    curr_state = new Rule();
+    states.push_back(curr_state);
+}
+
+void StateApi::clear()
+{
+    for (auto s : states)
+        delete s;
+
+    states.clear();
+}
+
+bool StateApi::empty() const
+{
+    return states.empty();
+}
+
+void StateApi::set_action(const std::string& action)
+{
+    if ( curr_state )
+        curr_state->add_hdr_data(action);
+}
+
+void StateApi::add_option(const std::string& name, const std::string& val)
+{
+    if ( curr_state )
+        curr_state->add_option(name, val);
+}
+
+void StateApi::add_comment(const std::string& comment)
+{
+    if ( curr_state )
+        curr_state->add_comment(comment);
+}
+
+void StateApi::print_states(std::ostream& out) const
+{
+    if ( states.empty() )
+        return;
+
+    out << "local_states =\n[[\n";
+
+    for (const auto r : states)
+        out << (*r) << "\n";
+
+    out << "]]\n\n";
+}
+
diff --git a/tools/snort2lua/data/dt_state_api.h b/tools/snort2lua/data/dt_state_api.h
new file mode 100644 (file)
index 0000000..831de4a
--- /dev/null
@@ -0,0 +1,48 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// dt_state_api.h author Serhii Vlasiuk <svlasiuk@cisco.com>
+
+#ifndef DATA_DT_STATE_API_H
+#define DATA_DT_STATE_API_H
+
+#include <iostream>
+#include <vector>
+
+class Rule;
+
+class StateApi
+{
+public:
+    StateApi() = default;
+    ~StateApi() = default;
+
+    void create_state();
+    void clear();
+    bool empty() const;
+    void add_option(const std::string& keyword, const std::string& val);
+    void add_comment(const std::string& comment);
+    void set_action(const std::string& action);
+    void print_states(std::ostream& out) const;
+
+private:
+    std::vector<Rule*> states;
+    Rule* curr_state = nullptr;
+};
+
+#endif
+
index 934d441974b9f5d37fc2e649b2765a1828d3e301..717bb9eb2291981351cf8a336c53b767e3c5581d 100644 (file)
@@ -48,7 +48,6 @@ TableDelegation table_delegation =
     { "ips", true },
     { "network", true },
     { "normalizer", true },
-    { "rule_state", true },
     { "stream_tcp", true },
     { "suppress", true },
 };
@@ -489,6 +488,15 @@ int Converter::convert(
         out << "\n";
         data_api.print_data(out);
 
+        if (!state_api.empty())
+        {
+            table_api.open_top_level_table("ips");
+            state_api.print_states(out);
+            state_api.clear();
+            table_api.add_option("states", "$local_states");
+            table_api.close_table();
+        }
+
         if (!rule_api.empty())
         {
             data_api.print_local_variables(out);
index 3edf019a38c691db15e70ff5832b044f4350571b..07798e93550f5423ff38467280d9b987d1e80138 100644 (file)
@@ -23,6 +23,7 @@
 #include "conversion_defines.h"
 #include "data/dt_data.h"
 #include "data/dt_rule_api.h"
+#include "data/dt_state_api.h"
 #include "data/dt_table_api.h"
 #include "helpers/util_binder.h"
 
@@ -122,6 +123,9 @@ public:
     inline RuleApi& get_rule_api()
     { return rule_api; }
 
+    inline StateApi& get_state_api()
+    { return state_api; }
+
     bool added_ftp_data() const
     { return ftp_data_is_added; }
 
@@ -152,6 +156,9 @@ private:
     TableApi table_api;
 
     RuleApi rule_api;
+
+    StateApi state_api;
+
     std::vector<std::shared_ptr<Binder>> binders;
 
     // the current parsing state.
index 3913890a987c7b19614b078af77ac8493ffe2266..d3a8a1c3ae1629641c98ca6484d1fce88fa992e7 100644 (file)
@@ -52,8 +52,6 @@ bool RuleState::convert(std::istringstream& data_stream)
         table_api.open_table("detection");
         table_api.add_option("global_rule_state", true);
         table_api.close_table();
-        table_api.open_table("rule_state");
-        table_api.close_table();
     }
 
     string gid;
@@ -104,13 +102,14 @@ bool RuleState::convert(std::istringstream& data_stream)
 
     if ( retval )
     {
-        string key = gid + ":" + sid;
-        table_api.open_associative_table("rule_state", key.c_str());
+        state_api.create_state();
+        state_api.add_option("gid", gid);
+        state_api.add_option("sid", sid);
 
         if ( !enable.empty() )
         {
-            table_api.add_diff_option_comment("enabled/disabled", "enable");
-            table_api.add_option("enable", enable);
+            state_api.add_option("enable", enable);
+            state_api.add_comment("option change: 'enabled/disabled' --> 'enable'");
         }
 
         if ( !action.empty() )
@@ -118,13 +117,11 @@ bool RuleState::convert(std::istringstream& data_stream)
             if ( action == "sdrop" )
             {
                 action = "drop";
-                table_api.add_diff_option_comment("sdrop", "drop");
+                state_api.add_comment("action change: 'sdrop' --> 'drop'");
             }
 
-            table_api.add_option("action", action);
+            state_api.set_action(action);
         }
-
-        table_api.close_table();
     }
 
     return retval;