]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1961 in SNORT/snort3 from ~SMINUT/snort3:multiple_reject_take5...
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 18 Feb 2020 21:21:07 +0000 (21:21 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 18 Feb 2020 21:21:07 +0000 (21:21 +0000)
Squashed commit of the following:

commit d2f17bbd38c252525c3a36822d2e19c872dc4868
Author: Silviu Minut <sminut@cisco.com>
Date:   Fri Jan 3 18:01:36 2020 -0500

    main: make ips actions (reject, react, replace) configurable by ips policy and provide default reject to everything else that needs one.

    managers: take IpsAction out of ActionManager.

    actions: change ReactData from struct to class with proper constructor and destructor and enable default_react in active.cc.

    packet_io: introduce the BaseAction class for Active to work with, and take IpsAction out of Active.

    packet_io: allow ips reject to put both an RST and ICMP dest unreachable on the wire, if so configured, and make the active default reset action put a RST for tcp and ICMP for icmp.

    packet_io: add a version of Active::reset_session()that does not take a BaseAction as an input argument, but rather queues the default reset; similarly for set_delayed_action.

    actions: remove act_react.h, act_reject.h and act_replace.h.

    actions: get rid of Replace_ResetQueue() and Replace_QueueChange().

    packet_io: rename ActiveAction to ActiveActionType and BaseAction to ActiveAction.

28 files changed:
src/actions/CMakeLists.txt
src/actions/act_react.cc
src/actions/act_reject.cc
src/actions/act_replace.cc
src/actions/actions.cc
src/detection/detection_engine.cc
src/detection/fp_detect.cc
src/detection/rules.h
src/file_api/file_cache.cc
src/file_api/file_module.cc
src/file_api/file_module.h
src/framework/ips_action.h
src/ips_options/ips_replace.cc
src/main/analyzer.cc
src/main/policy.cc
src/main/policy.h
src/managers/action_manager.cc
src/managers/action_manager.h
src/packet_io/CMakeLists.txt
src/packet_io/active.cc
src/packet_io/active.h
src/packet_io/active_action.h [moved from src/actions/act_replace.h with 53% similarity]
src/parser/parser.cc
src/parser/parser.h
src/protocols/packet.cc
src/protocols/packet.h
src/pub_sub/active_events.h
src/service_inspectors/smtp/smtp_module.cc

index 9d805a580d4815f89823bbad48beb01fe5e118bc..f12a5a84ead1dde6b6c04564865f6768e575b78e 100644 (file)
@@ -8,7 +8,6 @@ set (IPS_ACTION_SOURCES
     ips_actions.cc
     ips_actions.h
     act_replace.cc
-    act_replace.h
 )
 
 set( PLUGIN_LIST
index 909f528aa5d122f5b6e63bf143006b7abf09df53..9605227ef7f72a6875b0c1a24c546d59be94f453 100644 (file)
@@ -92,41 +92,81 @@ static THREAD_LOCAL ProfileStats reactPerfStats;
     "You are attempting to access a forbidden site.<br />" \
     "Consult your system administrator for details."
 
-struct ReactData
+
+class ReactData
 {
-    int rule_msg;        // 1=>use rule msg; 0=>use DEFAULT_MSG
+public:
+
+    ReactData(bool rmsg, const char* page);
+    ~ReactData();
+
+    ssize_t get_buf_len() const { return buf_len; }
+    const char* get_resp_buf() const { return resp_buf; }
+
+private:
+    // FIXIT-M: make it do what it says, or delete it.
+    // int rule_msg;        // 1=>use rule msg; 0=>use DEFAULT_MSG
     ssize_t buf_len;     // length of response
     char* resp_buf;      // response to send
-    char* resp_page;
+    const char* resp_page;
 };
 
-class ReactAction : public IpsAction
+
+class ReactAction : public snort::IpsAction
 {
 public:
-    ReactAction(ReactData* c) : IpsAction(s_name, ACT_PROXY)
-    { config = c; }
-
+    ReactAction(ReactData* c);
     ~ReactAction() override;
 
-    void exec(Packet*) override;
+    void exec(snort::Packet*) override;
 
 private:
-    void send(Packet*);
+    void send(snort::Packet*);
 
 private:
     ReactData* config;
 };
 
+ReactData::ReactData(bool rmsg, const char* page)
+    : buf_len(0), resp_buf(nullptr), resp_page(page)
+{
+    int body_len, head_len, total_len;
+    char dummy;
+
+    const char* head = DEFAULT_HTTP;
+    const char* body = resp_page ? resp_page : DEFAULT_HTML;
+    const char* msg = DEFAULT_MSG;
+    UNUSED(rmsg);
+
+    body_len = snprintf(&dummy, 1, body, msg);
+    head_len = snprintf(&dummy, 1, head, body_len);
+    total_len = head_len + body_len + 1;
+
+    resp_buf = (char*)snort_calloc(total_len);
+
+    SnortSnprintf((char*)resp_buf, head_len+1, head, body_len);
+    SnortSnprintf((char*)resp_buf+head_len, body_len+1, body, msg);
+
+    // set actual length
+    resp_buf[total_len-1] = '\0';
+    buf_len = strlen(resp_buf);
+}
+
+ReactData::~ReactData()
+{
+    if ( resp_buf )
+        snort_free(resp_buf);
+}
+
 //-------------------------------------------------------------------------
 // class methods
 //-------------------------------------------------------------------------
 
+ReactAction::ReactAction(ReactData* c) : IpsAction(s_name, ActionType::ACT_PROXY), config(c) {}
+
 ReactAction::~ReactAction()
 {
-    if (config->resp_buf)
-        snort_free(config->resp_buf);
-
-    snort_free(config);
+    delete config;
 }
 
 void ReactAction::exec(Packet* p)
@@ -140,13 +180,13 @@ void ReactAction::exec(Packet* p)
 void ReactAction::send(Packet* p)
 {
     EncodeFlags df = (p->is_from_server()) ? ENC_FLAG_FWD : 0;
-    EncodeFlags sent = config->buf_len;
+    EncodeFlags sent = config->get_buf_len();
 
     Active* act = p->active;
 
     if ( p->packet_flags & PKT_STREAM_EST )
     {
-        act->send_data(p, df, (uint8_t*)config->resp_buf, config->buf_len);
+        act->send_data(p, df, (const uint8_t*)config->get_resp_buf(), sent);
         // act->send_data() sends a FIN, so need to bump seq by 1.
         sent++;
     }
@@ -155,37 +195,6 @@ void ReactAction::send(Packet* p)
     act->send_reset(p, rf);
 }
 
-//-------------------------------------------------------------------------
-// implementation foo
-//-------------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-
-// format response buffer
-static void react_config(ReactData* rd)
-{
-    int body_len, head_len, total_len;
-    char dummy;
-
-    const char* head = DEFAULT_HTTP;
-    const char* body = rd->resp_page ? rd->resp_page : DEFAULT_HTML;
-    const char* msg = DEFAULT_MSG;
-
-    body_len = snprintf(&dummy, 1, body, msg);
-    head_len = snprintf(&dummy, 1, head, body_len);
-    total_len = head_len + body_len + 1;
-
-    rd->resp_buf = (char*)snort_calloc(total_len);
-
-    SnortSnprintf((char*)rd->resp_buf, head_len+1, head, body_len);
-    SnortSnprintf((char*)rd->resp_buf+head_len, body_len+1, body, msg);
-
-    // set actual length
-    rd->resp_buf[total_len-1] = '\0';
-    rd->buf_len = strlen(rd->resp_buf);
-}
-
 //-------------------------------------------------------------------------
 // module
 //-------------------------------------------------------------------------
@@ -204,8 +213,11 @@ static const Parameter s_params[] =
 class ReactModule : public Module
 {
 public:
-    ReactModule() : Module(s_name, s_help, s_params) { page = nullptr; }
-    ~ReactModule() override { if (page) snort_free(page); }
+    ReactModule() : Module(s_name, s_help, s_params), msg(false), page(nullptr) {}
+    ~ReactModule() override {
+        if (page)
+            snort_free(page);
+    }
 
     bool begin(const char*, int, SnortConfig*) override;
     bool set(const char*, Value&, SnortConfig*) override;
@@ -314,12 +326,8 @@ static void mod_dtor(Module* m)
 
 static IpsAction* react_ctor(Module* p)
 {
-    ReactData* rd = (ReactData*)snort_calloc(sizeof(*rd));
-
     ReactModule* m = (ReactModule*)p;
-    rd->rule_msg = m->msg;
-    rd->resp_page = m->page;
-    react_config(rd); // FIXIT-L this must be done per response
+    ReactData* rd = new ReactData(m->msg, m->page);
     Active::set_enabled();
 
     return new ReactAction(rd);
index 0160291fcfd4f5980a12a4d63f3badffcf46853b..082c166dbe8413b0e8652e489c2bdc56241eb32f 100644 (file)
 
 using namespace snort;
 
-#define REJ_NONE     0x00
-#define REJ_RST_SRC  0x01
-#define REJ_RST_DST  0x02
-#define REJ_UNR_NET  0x04
-#define REJ_UNR_HOST 0x08
-#define REJ_UNR_PORT 0x10
-#define REJ_UNR_FWD  0x20
-
-#define REJ_RST_BOTH (REJ_RST_SRC|REJ_RST_DST)
-#define REJ_UNR_ALL  (REJ_UNR_NET|REJ_UNR_HOST|REJ_UNR_PORT|REJ_UNR_FWD)
-
 #define s_name "reject"
 
 #define s_help \
     "terminate session with TCP reset or ICMP unreachable"
 
-static THREAD_LOCAL ProfileStats rejPerfStats;
+enum
+{
+    REJ_NONE     = 0x00,
+    REJ_RST_SRC  = 0x01,
+    REJ_RST_DST  = 0x02,
+    REJ_UNR_NET  = 0x04,
+    REJ_UNR_HOST = 0x08,
+    REJ_UNR_PORT = 0x10,
+    REJ_UNR_FWD  = 0x20,
+    REJ_RST_BOTH = (REJ_RST_SRC | REJ_RST_DST),
+    REJ_UNR_ALL  = (REJ_UNR_NET | REJ_UNR_HOST | REJ_UNR_PORT | REJ_UNR_FWD)
+};
+
+THREAD_LOCAL ProfileStats rejPerfStats;
 
-class RejectAction : public IpsAction
+class RejectAction : public snort::IpsAction
 {
 public:
-    RejectAction(uint32_t f) : IpsAction(s_name, ACT_RESET), mask(f) { }
-
-    void exec(Packet*) override;
+    RejectAction(uint32_t f);
+    void exec(snort::Packet*) override;
 
 private:
-    void send(Packet*);
-
     uint32_t mask;
 };
 
@@ -90,15 +89,19 @@ private:
 // class methods
 //-------------------------------------------------------------------------
 
+RejectAction::RejectAction(uint32_t f) : IpsAction(s_name, ActionType::ACT_RESET), mask(f)
+{ }
+
+
 void RejectAction::exec(Packet* p)
 {
-    Profile profile(rejPerfStats);
-
     if ( !p->ptrs.ip_api.is_ip() )
         return;
 
     Active* act = p->active;
 
+    Profile profile(rejPerfStats);
+
     switch ( p->type() )
     {
     case PktType::TCP:
@@ -117,12 +120,6 @@ void RejectAction::exec(Packet* p)
         return;
     }
 
-    send(p);
-}
-
-void RejectAction::send(Packet* p)
-{
-    Active* act = p->active;
     uint32_t flags = 0;
 
     if ( act->is_reset_candidate(p) )
index 5068d6a51c21748c8cdb1025ff5372bed25eb439..388ab381b956136eca30e478c720f781d978713c 100644 (file)
@@ -21,8 +21,6 @@
 #include "config.h"
 #endif
 
-#include "act_replace.h"
-
 #include "detection/detection_engine.h"
 #include "framework/ips_action.h"
 #include "framework/module.h"
@@ -40,16 +38,6 @@ using namespace snort;
 // queue foo
 //--------------------------------------------------------------------------
 
-void Replace_ResetQueue()
-{
-    DetectionEngine::clear_replacement();
-}
-
-void Replace_QueueChange(const std::string& s, unsigned off)
-{
-    DetectionEngine::add_replacement(s, off);
-}
-
 static inline void Replace_ApplyChange(Packet* p, std::string& data, unsigned offset)
 {
     uint8_t* start = const_cast<uint8_t*>(p->data) + offset;
@@ -131,21 +119,20 @@ bool ReplaceModule::end(const char*, int, SnortConfig*)
 }
 
 //-------------------------------------------------------------------------
-
-class ReplaceAction : public IpsAction
+class ReplaceAction : public snort::IpsAction
 {
 public:
-    ReplaceAction(ReplaceModule*);
+    ReplaceAction(bool disable_replace);
 
-    void exec(Packet*) override;
+    void exec(snort::Packet*) override;
 private:
     bool disable_replace = false;
 };
 
-ReplaceAction::ReplaceAction(ReplaceModule* m) :
+ReplaceAction::ReplaceAction(bool dr) :
     IpsAction(s_name, ACT_RESET)
 {
-    disable_replace = m->disable_replace;
+    disable_replace = dr;
     Active::set_enabled();
 }
 
@@ -166,7 +153,7 @@ static void mod_dtor(Module* m)
 { delete m; }
 
 static IpsAction* rep_ctor(Module* m)
-{ return new ReplaceAction((ReplaceModule*)m); }
+{ return new ReplaceAction( ((ReplaceModule*)m)->disable_replace); }
 
 static void rep_dtor(IpsAction* p)
 { delete p; }
index 8250bad1647323748d7483965ca79e1678d387ef..3578908907ef0ef7d483ef596174f90f9e0bece9 100644 (file)
@@ -25,6 +25,7 @@
 #include "detection/detect.h"
 #include "detection/tag.h"
 #include "packet_io/active.h"
+#include "packet_io/active_action.h"
 #include "parser/parser.h"
 #include "utils/stats.h"
 
@@ -131,7 +132,7 @@ void Actions::execute(Actions::Type action, Packet* p, const OptTreeNode* otn,
         break;
 
     case Actions::RESET:
-        p->active->reset_session(p);
+        p->active->reset_session(p, get_ips_policy()->action[action]);
         alert(p, otn);
         SetTags(p, otn, event_id);
         break;
@@ -154,7 +155,7 @@ void Actions::apply(Actions::Type action, Packet* p)
         break;
 
     case Actions::RESET:
-        p->active->reset_session(p);
+        p->active->reset_session(p, get_ips_policy()->action[action]);
         break;
 
     default:
index 18dd43897ae06a9f3ddedfebb1d9388d764fe55a..cb688e7fc1f01b2996e9bc7c2ba42efd0c310c38 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "detection_engine.h"
 
-#include "actions/act_replace.h"
 #include "events/sfeventq.h"
 #include "filters/sfthreshold.h"
 #include "framework/endianness.h"
@@ -146,7 +145,7 @@ Packet* DetectionEngine::get_encode_packet()
 Packet* DetectionEngine::set_next_packet(Packet* parent)
 {
     static THREAD_LOCAL Active shutdown_active;
-    static THREAD_LOCAL IpsAction* shutdown_action = nullptr;
+    static THREAD_LOCAL ActiveAction* shutdown_action = nullptr;
 
     wait_for_context();
     IpsContext* c = Analyzer::get_switcher()->get_next();
@@ -698,3 +697,4 @@ void DetectionEngine::clear_events(Packet* p)
     SF_EVENTQ* pq = p->context->equeue;
     pc.log_limit += sfeventq_reset(pq);
 }
+
index 05cd9bf62e7bcaa6fcfb1953ab0464a71aee2b54..967ed95e6e184f9089492aba56e013c04c6e41c4 100644 (file)
@@ -54,6 +54,7 @@
 #include "managers/action_manager.h"
 #include "packet_tracer/packet_tracer.h"
 #include "parser/parser.h"
+#include "packet_io/active.h"
 #include "profiler/profiler_defs.h"
 #include "protocols/icmp4.h"
 #include "protocols/packet_manager.h"
@@ -120,8 +121,13 @@ static inline void fpLogOther(
     otn_trigger_actions(otn, p);
 
     // rule actions are queued here (eg reject)
-    if ( rtn->listhead->action )
-        ActionManager::queue(rtn->listhead->action, p);
+    if ( rtn->listhead->is_plugin_action )
+    {
+        snort::Actions::Type idx = rtn->listhead->ruleListNode->mode;
+        ActiveAction * act = get_ips_policy()->action[idx];
+        if ( act )
+            Active::queue(act, p);
+    }
 }
 
 /*
index c6659567a0f8a0fc62a6066962eb717a6afbb749..b31436bf3da02423be4bb88289f6b896812c50ea 100644 (file)
@@ -56,8 +56,8 @@ struct ListHead
 {
     OutputSet* LogList;
     OutputSet* AlertList;
-    snort::IpsAction* action;
     struct RuleListNode* ruleListNode;
+    bool is_plugin_action = false;
 };
 
 // for top-level rule lists by type (alert, drop, etc.)
index 48019fde5658bd4eac52740d234e0572558bd7a3..1f435900a8bbab035e2c8ed871096a5182bacbe6 100644 (file)
@@ -271,9 +271,9 @@ bool FileCache::apply_verdict(Packet* p, FileContext* file_ctx, FileVerdict verd
             policy->log_file_action(flow, file_ctx, FILE_RESUME_LOG);
         return false;
     case FILE_VERDICT_BLOCK:
-         // can't block session inside a session
-         act->set_delayed_action(Active::ACT_BLOCK, true);
-         break;
+        // can't block session inside a session
+        act->set_delayed_action(Active::ACT_BLOCK, true);
+        break;
 
     case FILE_VERDICT_REJECT:
         // can't reset session inside a session
index 8cf0296cbb581ae78ff5ae80ad1bc9738212e50f..4910e819b8953807805bfa02fbef475effb5ba0e 100644 (file)
@@ -32,6 +32,7 @@
 #include "log/messages.h"
 #include "main/snort.h"
 #include "main/snort_config.h"
+#include "packet_io/active.h"
 
 #include "file_service.h"
 #include "file_stats.h"
@@ -369,7 +370,11 @@ bool FileIdModule::set(const char*, Value& v, SnortConfig*)
         return true;
 
     else if ( v.is("verdict") )
+    {
         file_rule.use.verdict = (FileVerdict)v.get_uint8();
+        if (file_rule.use.verdict == FileVerdict::FILE_VERDICT_REJECT)
+            need_active = true;
+    }
 
     else if ( v.is("enable_file_type") )
         file_rule.use.type_enabled = v.get_bool();
@@ -433,6 +438,9 @@ bool FileIdModule::end(const char* fqn, int idx, SnortConfig*)
         fc->process_file_policy_rule(file_rule);
     }
 
+    if ( need_active )
+        Active::set_enabled();
+
     return true;
 }
 
@@ -451,3 +459,4 @@ void FileIdModule::show_dynamic_stats()
 {
     file_stats_print();
 }
+
index 301d695a39accf8ac6a53455180936d2a71d5b8d..7f7bc48d94465be1550912602493ee6988376c1b 100644 (file)
@@ -66,6 +66,7 @@ private:
     FileMagicData magic;
     FileRule file_rule;
     FileConfig *fc = nullptr;
+    bool need_active = false;
 };
 
 enum FileSid
index c976db805e70137c148fdb3b00fc3f0559791147..b9be2d6d1994c7b6cb8e9f812a31b045b5f5fcae 100644 (file)
@@ -28,6 +28,7 @@
 #include "actions/actions.h"
 #include "framework/base_api.h"
 #include "main/snort_types.h"
+#include "packet_io/active_action.h"
 
 // this is the current version of the api
 #define ACTAPI_VERSION ((BASE_API_VERSION << 16) | 0)
@@ -41,33 +42,18 @@ namespace snort
 struct Packet;
 struct SnortConfig;
 
-enum ActionType
-{
-    ACT_LOCAL,
-    ACT_MODIFY,
-    ACT_PROXY,
-    ACT_RESET,
-    ACT_REMOTE,
-    ACT_MAX
-};
-
-class SO_PUBLIC IpsAction
+class SO_PUBLIC IpsAction : public ActiveAction
 {
 public:
-    virtual ~IpsAction() = default;
-
-    virtual void exec(Packet*) = 0;
-
+    virtual void exec(Packet*) override = 0;
     const char* get_name() const { return name; }
-    ActionType get_action() { return action; }
 
 protected:
-    IpsAction(const char* s, ActionType a)
-    { name = s; action = a; }
+    IpsAction(const char* s, ActionType a) : ActiveAction(a)
+    { name = s; }
 
 private:
     const char* name;
-    ActionType action;
 };
 
 typedef void (* IpsActFunc)();
index 28861213d64e05b9019b7dc617e8b0850fe75c76..8c10b64d9f9f91d96124a2c188299e62a4dc66bc 100644 (file)
@@ -22,7 +22,7 @@
 #include "config.h"
 #endif
 
-#include "actions/act_replace.h"
+#include "detection/detection_engine.h"
 #include "detection/treenodes.h"
 #include "framework/cursor.h"
 #include "framework/ips_option.h"
@@ -178,7 +178,7 @@ void ReplaceOption::action(Packet*)
     RuleProfile profile(replacePerfStats);
 
     if ( pending() )
-        Replace_QueueChange(repl, (unsigned)pos());
+        DetectionEngine::add_replacement(repl, (unsigned)pos());
 }
 
 //-------------------------------------------------------------------------
index 52c9343497d45a63f77346aac4f19fbc5b87f015..26eb50b8592bbca89e2814ab29d45a8fac284cb2 100644 (file)
@@ -329,7 +329,7 @@ static DAQ_Verdict distill_verdict(Packet* p)
  */
 void Analyzer::post_process_daq_pkt_msg(Packet* p)
 {
-    ActionManager::execute(p);
+    Active::execute(p);
 
     DAQ_Verdict verdict = MAX_DAQ_VERDICT;
 
@@ -397,7 +397,7 @@ void Analyzer::process_daq_pkt_msg(DAQ_Msg_h msg, bool retry)
     DetectionEngine::reset();
 
     sfthreshold_reset();
-    ActionManager::reset_queue(p);
+    Active::clear_queue(p);
 
     p->daq_msg = msg;
     p->daq_instance = daq_instance;
@@ -964,3 +964,4 @@ void Analyzer::rotate()
 {
     DataBus::publish(THREAD_ROTATE_EVENT, nullptr);
 }
+
index a8aecbe5cc39f29b9508dd33703fe42351793472..cc65d39ebab0329184b9a99f61de643dc01b97c3 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "policy.h"
 
+#include "actions/actions.h"
 #include "detection/detection_engine.h"
 #include "log/messages.h"
 #include "managers/inspector_manager.h"
@@ -106,7 +107,7 @@ void InspectionPolicy::clone_dbus(SnortConfig* from, const char* exclude_module)
 // detection policy
 //-------------------------------------------------------------------------
 
-IpsPolicy::IpsPolicy(PolicyId id)
+IpsPolicy::IpsPolicy(PolicyId id) : action(Actions::Type::MAX, nullptr)
 {
     policy_id = id;
     user_policy_id = 0;
@@ -296,6 +297,12 @@ InspectionPolicy* get_inspection_policy()
 IpsPolicy* get_ips_policy()
 { return s_detection_policy; }
 
+IpsPolicy* get_ips_policy(SnortConfig* sc, unsigned i)
+{
+    return sc && i < sc->policy_map->ips_policy_count() ?
+        sc->policy_map->get_ips_policy(0) : nullptr;
+}
+
 InspectionPolicy* get_default_inspection_policy(SnortConfig* sc)
 { return sc->policy_map->get_inspection_policy(0); }
 
@@ -391,3 +398,4 @@ bool only_ips_policy()
 
 bool only_network_policy()
 { return get_network_policy() && !get_ips_policy() && !get_inspection_policy(); }
+
index de51b437c251d882b233a6ad5b4e7f3b8958640c..4821aa67496fe27461568f428e8446e2158da4c1 100644 (file)
@@ -34,6 +34,7 @@ typedef unsigned char uuid_t[16];
 
 #include <memory>
 #include <unordered_map>
+#include <vector>
 
 #include "framework/data_bus.h"
 
@@ -41,6 +42,7 @@ namespace snort
 {
 class GHash;
 struct SnortConfig;
+class ActiveAction;
 }
 
 struct PortTable;
@@ -166,6 +168,10 @@ public:
     Enable default_rule_state = INHERIT_ENABLE;
 
     bool obfuscate_pii;
+
+    // Holds plugin actions associated with this policy (e.g. reject, react, etc.)
+    // Indexed by Actions::Type.
+    std::vector<snort::ActiveAction*> action;
 };
 
 //-------------------------------------------------------------------------
@@ -272,6 +278,7 @@ namespace snort
 SO_PUBLIC NetworkPolicy* get_network_policy();
 SO_PUBLIC InspectionPolicy* get_inspection_policy();
 SO_PUBLIC IpsPolicy* get_ips_policy();
+SO_PUBLIC IpsPolicy* get_ips_policy(snort::SnortConfig*, unsigned i = 0);
 SO_PUBLIC InspectionPolicy* get_default_inspection_policy(snort::SnortConfig*);
 SO_PUBLIC void set_ips_policy(IpsPolicy* p);
 SO_PUBLIC void set_network_policy(NetworkPolicy* p);
@@ -297,3 +304,4 @@ bool only_ips_policy();
 bool only_network_policy();
 
 #endif
+
index 78180bd9f5376698375f338ba51ecd085f330332..10d2e0e3a6c52272c7b73e6e4949f9e5102c7dfa 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <vector>
 
-#include "actions/act_replace.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
 #include "packet_io/active.h"
@@ -163,9 +162,15 @@ void ActionManager::instantiate(const ActionApi* api, Module* mod, SnortConfig*
         if ( !sc->ips_actions_config->reject && !strcmp(act->get_name(), "reject") )
             sc->ips_actions_config->reject = act;
 
-        ListHead* lh = CreateRuleType(sc, api->base.name, api->type);
-        assert(lh);
-        lh->action = act;
+        RuleListNode* rln = CreateRuleType(sc, api->base.name, api->type, true);
+
+        // The plugin actions (e.g. reject, react, etc.) are per policy, per mode.
+        // At logging time, they have to be retrieved the way we store them here.
+        IpsPolicy* ips = get_ips_policy();
+        snort::Actions::Type idx = rln->mode;
+        assert(ips->action[idx] == nullptr);
+        ips->action[idx] = act;
+
     }
 }
 
@@ -227,33 +232,6 @@ void ActionManager::thread_term(SnortConfig*)
     }
 }
 
-void ActionManager::execute(Packet* p)
-{
-    if ( *p->action )
-    {
-        (*p->action)->exec(p);
-        *p->action = nullptr;
-    }
-}
-
-void ActionManager::queue(IpsAction* a, Packet* p)
-{
-    if ( !(*p->action) || a->get_action() > (*p->action)->get_action() )
-        *p->action = a;
-}
-
-void ActionManager::queue_reject(SnortConfig* sc, Packet* p)
-{
-    if ( sc->ips_actions_config->reject )
-        queue(sc->ips_actions_config->reject, p);
-}
-
-void ActionManager::reset_queue(Packet* p)
-{
-    *p->action = nullptr;
-    Replace_ResetQueue();
-}
-
 #ifdef PIGLET
 
 //-------------------------------------------------------------------------
@@ -282,5 +260,6 @@ IpsActionWrapper* ActionManager::instantiate(const char* name, Module* m)
     return new IpsActionWrapper(api, p);
 }
 
+
 #endif
 
index 1cea257f3906524a31941f2339d7d59c5b0361c0..21ebce884977e289bc06a99126e379011521a085 100644 (file)
@@ -72,11 +72,6 @@ public:
     static void thread_reinit(snort::SnortConfig*);
     static void thread_term(snort::SnortConfig*);
 
-    static void reset_queue(snort::Packet*);
-    static void queue_reject(snort::SnortConfig*, snort::Packet*);
-    static void queue(snort::IpsAction*, snort::Packet*);
-    static void execute(snort::Packet*);
-
 #ifdef PIGLET
     static IpsActionWrapper* instantiate(const char*, snort::Module*);
 #endif
index 4c2807d9b54f16d4171b954e1606348b95102b47..13689e82b0549bd3a3dba7a03653a107cd90531a 100644 (file)
@@ -28,6 +28,7 @@ endif ()
 add_library (packet_io OBJECT
     active.cc
     active.h
+    active_action.h
     sfdaq.cc
     sfdaq.h
     sfdaq_config.cc
index 63922a104674d1f1f3a84f77eb4a3d949bebeb63..0df08bdd6f52d16b742ecf6f968cd676682f3581 100644 (file)
 #endif
 
 #include "active.h"
+#include "active_action.h"
 
+#include "detection/detection_engine.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
 #include "managers/action_manager.h"
+#include "profiler/profiler.h"
 #include "protocols/tcp.h"
 #include "pub_sub/active_events.h"
 #include "stream/stream.h"
@@ -41,6 +44,17 @@ using namespace snort;
 
 #define MAX_ATTEMPTS 20
 
+class ResetAction : public snort::ActiveAction
+{
+public:
+    ResetAction() : ActiveAction(ActionType::ACT_RESET) {}
+
+    void exec(snort::Packet* p) override
+    {
+        p->active->kill_session(p, ENC_FLAG_FWD);
+    }
+};
+
 const char* Active::act_str[Active::ACT_MAX][Active::AST_MAX] =
 {
     { "allow", "error", "error", "error" },
@@ -63,6 +77,8 @@ static THREAD_LOCAL eth_t* s_link = nullptr;
 static THREAD_LOCAL ip_t* s_ipnet = nullptr;
 static THREAD_LOCAL send_t s_send = SFDAQ::inject;
 
+static ResetAction default_reset;
+
 //--------------------------------------------------------------------
 // helpers
 
@@ -482,6 +498,11 @@ void Active::block_session(Packet* p, bool force)
 }
 
 void Active::reset_session(Packet* p, bool force)
+{
+    reset_session(p, &default_reset, force);
+}
+
+void Active::reset_session(Packet* p, ActiveAction* reject, bool force)
 {
     update_status(p, force);
     active_action = ACT_RESET;
@@ -491,7 +512,8 @@ void Active::reset_session(Packet* p, bool force)
 
     if ( enabled )
     {
-        ActionManager::queue_reject(SnortConfig::get_conf(), p);
+        if (reject)
+            Active::queue(reject, p);
 
         if ( p->flow )
         {
@@ -503,9 +525,22 @@ void Active::reset_session(Packet* p, bool force)
     p->disable_inspect = true;
 }
 
-void Active::set_delayed_action(ActiveAction action, bool force)
+void Active::queue(ActiveAction* a, Packet* p)
+{
+    if ( !(*p->action) || a->get_action() > (*p->action)->get_action() )
+        *p->action = a;
+}
+
+void Active::set_delayed_action(ActiveActionType action, bool force)
+{
+    set_delayed_action(action, action == ACT_RESET ? &default_reset : nullptr, force);
+}
+
+void Active::set_delayed_action(ActiveActionType action, ActiveAction* act, bool force)
 {
     delayed_active_action = action;
+    assert(delayed_reject == nullptr);
+    delayed_reject = act;
 
     if ( force )
         active_status = AST_FORCE;
@@ -526,7 +561,8 @@ void Active::apply_delayed_action(Packet* p)
         block_session(p, force);
         break;
     case ACT_RESET:
-        reset_session(p, force);
+        assert(delayed_reject);   // resets must have been told which reject to use
+        reset_session(p, delayed_reject, force);
         break;
     case ACT_RETRY:
         if(!retry_packet(p))
@@ -539,6 +575,7 @@ void Active::apply_delayed_action(Packet* p)
     delayed_active_action = ACT_PASS;
 }
 
+
 //--------------------------------------------------------------------
 
 bool Active::open(const char* dev)
@@ -582,4 +619,21 @@ void Active::reset()
     active_status = AST_ALLOW;
     active_action = ACT_PASS;
     delayed_active_action = ACT_PASS;
+    delayed_reject = nullptr;
+}
+
+void Active::clear_queue(Packet* p)
+{
+    *p->action = nullptr;
+    DetectionEngine::clear_replacement();
 }
+
+void Active::execute(Packet* p)
+{
+    if ( *p->action )
+    {
+        (*p->action)->exec(p);
+        *p->action = nullptr;
+    }
+}
+
index 89f2a70309faa339731e30567d1fac391ea5e73b..387b595f81ac4da38652b60dbd41a66b345aa549 100644 (file)
 
 // manages packet processing verdicts returned to the DAQ.  action (what to
 // do) is separate from status (whether we can actually do it or not).
-
 #include "protocols/packet_manager.h"
 
 namespace snort
 {
 struct Packet;
 struct SnortConfig;
+class ActiveAction;
 
 class SO_PUBLIC Active
 {
@@ -44,10 +44,14 @@ public:
     enum ActiveStatus : uint8_t
     { AST_ALLOW, AST_CANT, AST_WOULD, AST_FORCE, AST_MAX };
 
-    enum ActiveAction : uint8_t
+    // FIXIT-M: these are only used in set_delayed_action and
+    // apply_delayed_action, in a big switch(action). Do away with these and
+    // use the actual (Base)Action objects.
+    enum ActiveActionType : uint8_t
     { ACT_PASS, ACT_HOLD, ACT_RETRY, ACT_DROP, ACT_BLOCK, ACT_RESET, ACT_MAX };
 
 public:
+
     static void init(SnortConfig*);
     static bool thread_init(SnortConfig*);
     static void thread_term();
@@ -69,7 +73,7 @@ public:
     bool is_reset_candidate(const Packet*);
     bool is_unreachable_candidate(const Packet*);
 
-    ActiveAction get_action() const
+    ActiveActionType get_action() const
     { return active_action; }
 
     ActiveStatus get_status() const
@@ -91,6 +95,11 @@ public:
     void allow_session(Packet*);
     void block_session(Packet*, bool force = false);
     void reset_session(Packet*, bool force = false);
+    void reset_session(Packet*, snort::ActiveAction* r, bool force = false);
+
+    static void queue(snort::ActiveAction* a, snort::Packet* p);
+    static void clear_queue(snort::Packet*);
+    static void execute(Packet* p);
 
     void block_again()
     { active_action = ACT_BLOCK; }
@@ -125,7 +134,8 @@ public:
     bool get_tunnel_bypass() const
     { return active_tunnel_bypass > 0; }
 
-    void set_delayed_action(ActiveAction, bool force = false);
+    void set_delayed_action(ActiveActionType, bool force = false);
+    void set_delayed_action(ActiveActionType, ActiveAction* act, bool force = false);
     void apply_delayed_action(Packet*);
 
     void reset();
@@ -139,11 +149,10 @@ private:
     void update_status(const Packet*, bool force = false);
     void daq_update_status(const Packet*);
 
-    void block_session(const Packet*, ActiveAction, bool force = false);
+    void block_session(const Packet*, ActiveActionType, bool force = false);
 
     void cant_drop();
 
-
 private:
     static const char* act_str[ACT_MAX][AST_MAX];
     static bool enabled;
@@ -156,8 +165,9 @@ private:
     // of these flags following all processing and the drop
     // or response may have been produced by a pseudopacket.
     ActiveStatus active_status;
-    ActiveAction active_action;
-    ActiveAction delayed_active_action;
+    ActiveActionType active_action;
+    ActiveActionType delayed_active_action;
+    ActiveAction* delayed_reject;    // set with set_delayed_action()
 };
 
 struct ActiveSuspendContext
similarity index 53%
rename from src/actions/act_replace.h
rename to src/packet_io/active_action.h
index 6f739b4fc61b2c267a54916ef8089d8143f22cc0..1c2dc0955b61c1ff3b1d88170c69d64696b3a7a1 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-#ifndef ACT_REPLACE_H
-#define ACT_REPLACE_H
+// active_action.h author Silviu Minut <sminut@cisco.com>
 
-#include <string>
+#ifndef ACTIVE_ACTION_H
+#define ACTIVE_ACTION_H
 
-// FIXIT-M these prevent dynamic ips replace option and action
-void Replace_ResetQueue();
-void Replace_QueueChange(const std::string&, unsigned);
+#include "main/snort_types.h"
+
+namespace snort
+{
+struct Packet;
+
+enum ActionType
+{
+    ACT_LOCAL,
+    ACT_MODIFY,
+    ACT_PROXY,
+    ACT_RESET,
+    ACT_REMOTE,
+    ACT_MAX
+};
+
+// These are injection actions (e.g. send a RST packet, or respond to a query
+// with an "Access denied" message). Instances of this class are queued into
+// the packet at inspection / detection time and executed at the end by
+// Analyzer. The pure virtual exec() method can call into Active methods for
+// the low-level stuff.
+class SO_PUBLIC ActiveAction
+{
+public:
+    ActiveAction(ActionType a = ActionType::ACT_MAX) : action(a) {}
+    virtual ~ActiveAction() = default;
+
+    virtual void exec(Packet*) = 0;
+
+    ActionType get_action() const { return action; }
+
+protected:
+    ActionType action;
+
+};
+
+}
 
 #endif
 
index fe5860b6197a4b24017d64e15370852ce0a08743..8dd5ef27e0b155d4f6f69c560209d105074ca3e0 100644 (file)
@@ -410,7 +410,7 @@ void ParseRules(SnortConfig* sc)
  * Returns: the ListHead for the rule type
  *
  ***************************************************************************/
-ListHead* CreateRuleType(SnortConfig* sc, const char* name, Actions::Type mode)
+RuleListNode* CreateRuleType(SnortConfig* sc, const char* name, Actions::Type mode, bool is_plugin_action)
 {
     RuleListNode* node;
     unsigned evalIndex = 0;
@@ -433,11 +433,10 @@ ListHead* CreateRuleType(SnortConfig* sc, const char* name, Actions::Type mode)
 
         do
         {
-            /* We do not allow multiple rules types with the same name. */
             if (strcasecmp(tmp->name, name) == 0)
             {
                 snort_free(node);
-                return nullptr;
+                return tmp;
             }
 
             evalIndex++;
@@ -451,6 +450,7 @@ ListHead* CreateRuleType(SnortConfig* sc, const char* name, Actions::Type mode)
 
     node->RuleList = (ListHead*)snort_calloc(sizeof(ListHead));
     node->RuleList->ruleListNode = node;
+    node->RuleList->is_plugin_action = is_plugin_action;
     node->mode = mode;
     node->name = snort_strdup(name);
     node->evalIndex = evalIndex;
@@ -458,7 +458,7 @@ ListHead* CreateRuleType(SnortConfig* sc, const char* name, Actions::Type mode)
     sc->evalOrder[node->mode] =  evalIndex;
     sc->num_rule_types++;
 
-    return node->RuleList;
+    return node;
 }
 
 void FreeRuleLists(SnortConfig* sc)
index 6bd96c8b4d02de2a91aeb0aa36eb9d555ee481ba..0978b884c83bb8ca0bd36d27ff9bc9e3d16f60a0 100644 (file)
@@ -84,7 +84,8 @@ inline RuleTreeNode* getRuntimeRtnFromOtn(const struct OptTreeNode* otn)
     return getRtnFromOtn(otn);
 }
 
-ListHead* CreateRuleType(snort::SnortConfig* sc, const char* name, snort::Actions::Type);
+RuleListNode* CreateRuleType(snort::SnortConfig* sc, const char* name,
+    snort::Actions::Type, bool is_plugin_action = false);
 
 void FreeRuleTreeNode(RuleTreeNode*);
 void DestroyRuleTreeNode(RuleTreeNode*);
index 546bf9ebee45268f08d744f04ab9ec74fd870edb..1acc69da347a97a6dc6a8281bb3eea963b6476d1 100644 (file)
@@ -53,7 +53,7 @@ Packet::Packet(bool packet_data)
 
     obfuscator = nullptr;
     endianness = nullptr;
-    active_inst = new Active;
+    active_inst = new Active();
     action_inst = nullptr;
     reset();
 }
index 12741ca467d1c4d10a3ffb47e3ef9a9fc1dda03c..e6c0265cfbedf85d5e91df50809ab08c32959346 100644 (file)
@@ -33,7 +33,7 @@ namespace snort
 class Active;
 class Endianness;
 class Flow;
-class IpsAction;
+class ActiveAction;
 class IpsContext;
 class Obfuscator;
 class SFDAQInstance;
@@ -137,8 +137,8 @@ struct SO_PUBLIC Packet
     IpsContext* context;
     Active* active;
     Active* active_inst;
-    IpsAction** action;
-    IpsAction* action_inst;
+    ActiveAction** action;
+    ActiveAction* action_inst;
 
     DAQ_Msg_h daq_msg;              // DAQ message this packet came from
     SFDAQInstance* daq_instance;    // DAQ instance the message came from
@@ -385,3 +385,4 @@ inline uint64_t alignedNtohq(const uint64_t* ptr)
 }
 }
 #endif
+
index b09150632290853018eacce7249f81378a7ca550..425916393179063e1cded7651d670e3fc5d020d1 100644 (file)
@@ -34,22 +34,22 @@ class SO_PUBLIC ActiveEvent : public DataEvent
 {
 public:
     ActiveEvent
-        (const Active::ActiveAction current, const Active::ActiveAction previous, const Packet* p)
+        (const Active::ActiveActionType current, const Active::ActiveActionType previous, const Packet* p)
         : current_action(current), previous_action(previous), pkt(p)
     { }
 
-    Active::ActiveAction get_current_action() const
+    Active::ActiveActionType get_current_action() const
     { return current_action; }
 
-    Active::ActiveAction get_previous_action() const
+    Active::ActiveActionType get_previous_action() const
     { return previous_action; }
 
     const Packet* get_pkt() const
     { return pkt; }
 
 private:
-    const Active::ActiveAction current_action;
-    const Active::ActiveAction previous_action;
+    const Active::ActiveActionType current_action;
+    const Active::ActiveActionType previous_action;
     const Packet* pkt;
 };
 }
index af5416759f4917ab99d5d1ec1b329027cef265f6..b9a5adce4d3948bc951ed3a7ea1eaea5d41aa0ef 100644 (file)
@@ -25,6 +25,7 @@
 #include "smtp_module.h"
 
 #include "log/messages.h"
+#include "packet_io/active.h"
 #include "utils/util.h"
 
 using namespace snort;
@@ -329,7 +330,10 @@ bool SmtpModule::set(const char*, Value& v, SnortConfig*)
     }
 
     else if ( v.is("xlink2state") )
+    {
         config->xlink2state = (XLINK2STATE)v.get_uint8();
+        Active::set_enabled();
+    }
 
     else
         return false;