]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
added act_replace
authorRuss Combs <rucombs@cisco.com>
Mon, 18 Aug 2014 22:01:06 +0000 (18:01 -0400)
committerRuss Combs <rucombs@cisco.com>
Mon, 18 Aug 2014 22:01:06 +0000 (18:01 -0400)
19 files changed:
ChangeLog
src/actions/CMakeLists.txt
src/actions/Makefile.am
src/actions/act_react.cc
src/actions/act_reject.cc
src/actions/act_resp.cc [deleted file]
src/actions/ips_actions.cc
src/detection/detection_options.cc
src/detection/fpdetect.cc
src/file_api/file_resume_block.cc
src/framework/ips_action.h
src/ips_options/ips_replace.cc
src/ips_options/ips_replace.h [deleted file]
src/main/snort.cc
src/managers/action_manager.cc
src/managers/action_manager.h
src/packet_io/active.cc
src/packet_io/active.h
src/parser/parser.cc

index 6f1681e2570a7c008007204a6a9bc674f46a70d0..3d36adb9a05c1fa26813d0106577c6a02b3b0d39 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,7 +5,8 @@
    ips_replace
 -- stream workarounds for new packet / protocol foo and shutdown sequencing
 -- fixed end of rule parsing to not require ; and recognize incomplete rules
--- fixed executing a command wile paused
+-- fixed executing a command while paused
+-- added act_replace
 
 112
 -- initial action plugin - reject
index bc770823d95a3fd43cef46b44995cb3ce60f13ca..8bd7e8c0bd3de6d2fc646a5c4d120dc54d9a51c4 100644 (file)
@@ -12,7 +12,8 @@ set (IPS_ACTION_SOURCES
 set( PLUGIN_LIST
     act_react.cc
     act_reject.cc
-    act_resp.cc
+    act_replace.cc
+    act_replace.h
     )
 
 if (STATIC_IPS_ACTIONS)
@@ -34,7 +35,7 @@ else (STATIC_IPS_ACTIONS)
 
     add_shared_library(act_react actions act_react.cc)
     add_shared_library(act_reject actions act_reject.cc)
-    add_shared_library(act_resp actions act_resp.cc)
+    add_shared_library(act_replace actions act_replace.cc act_replace.h)
 
 endif (STATIC_IPS_ACTIONS)
 
index 7ac113bad4bc534554fcfe698ebb93fce781f5bf..7a4a0bb25878e53ad39d2054c8c968c281c2dd9b 100644 (file)
@@ -10,7 +10,8 @@ actions.h
 plugin_list = \
 act_react.cc \
 act_reject.cc \
-act_resp.cc
+act_replace.cc \
+act_replace.h
 
 libips_actions_a_SOURCES = \
 actions.cc \
@@ -32,10 +33,10 @@ libact_reject_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
 libact_reject_la_LDFLAGS = -export-dynamic -shared
 libact_reject_la_SOURCES = act_reject.cc
 
-actlib_LTLIBRARIES += libact_resp.la
-libact_resp_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
-libact_resp_la_LDFLAGS = -export-dynamic -shared
-libact_resp_la_SOURCES = act_resp.cc
+actlib_LTLIBRARIES += libact_replace.la
+libact_replace_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+libact_replace_la_LDFLAGS = -export-dynamic -shared
+libact_replace_la_SOURCES = act_replace.cc act_replace.h
 endif
 
 AM_CXXFLAGS = @AM_CXXFLAGS@
index 282b9504a66797e7dda4b8646d564a3739021a16..e4aa9d5d043f099fc3ee7df6c5c09ee774147074 100644 (file)
@@ -100,7 +100,6 @@ struct ReactData
     int rule_msg;        // 1=>use rule msg; 0=>use DEFAULT_MSG
     ssize_t buf_len;     // length of response
     char* resp_buf;      // response to send
-
 };
 
 static char* s_page = NULL;
@@ -108,19 +107,20 @@ static char* s_page = NULL;
 class ReactAction : public IpsAction
 {
 public:
-    ReactAction(ReactData* c) : IpsAction(s_name)
+    ReactAction(ReactData* c) : IpsAction(s_name, ACT_PROXY)
     { config = c; };
 
     ~ReactAction();
 
     void exec(Packet*);
 
+private:
+    void send(Packet*);
+
 private:
     ReactData* config;
 };
 
-static void React_Send(Packet*,  void*);
-
 //-------------------------------------------------------------------------
 // class methods
 //-------------------------------------------------------------------------
@@ -144,12 +144,24 @@ void ReactAction::exec(Packet* p)
     MODULE_PROFILE_START(reactPerfStats);
 
     if ( Active_IsRSTCandidate(p) )
-        Active_QueueResponse(React_Send, config);
+        send(p);
 
     Active_DropSession();
     MODULE_PROFILE_END(reactPerfStats);
 }
 
+void ReactAction::send (Packet* p)
+{
+    EncodeFlags df = (p->packet_flags & PKT_FROM_SERVER) ? ENC_FLAG_FWD : 0;
+    EncodeFlags rf = ENC_FLAG_SEQ | (ENC_FLAG_VAL & config->buf_len);
+
+    Active_IgnoreSession(p);
+
+    Active_SendData(p, df, (uint8_t*)config->resp_buf, config->buf_len);
+    Active_SendReset(p, rf);
+    Active_SendReset(p, ENC_FLAG_FWD);
+}
+
 //-------------------------------------------------------------------------
 // implementation foo
 //-------------------------------------------------------------------------
@@ -211,23 +223,6 @@ static bool react_getpage (const char* file)
 
 //--------------------------------------------------------------------
 
-static void React_Send (Packet* p,  void* pv)
-{
-    ReactData* rd = (ReactData*)pv;
-    EncodeFlags df = (p->packet_flags & PKT_FROM_SERVER) ? ENC_FLAG_FWD : 0;
-    EncodeFlags rf = ENC_FLAG_SEQ | (ENC_FLAG_VAL & rd->buf_len);
-    PROFILE_VARS;
-
-    MODULE_PROFILE_START(reactPerfStats);
-    Active_IgnoreSession(p);
-
-    Active_SendData(p, df, (uint8_t*)rd->resp_buf, rd->buf_len);
-    Active_SendReset(p, rf);
-    Active_SendReset(p, ENC_FLAG_FWD);
-
-    MODULE_PROFILE_END(reactPerfStats);
-}
-
 // format response buffer
 static void react_config (ReactData* rd)
 {
index 7db8c104c22e5d16a96fed33e0df8f6f15078b77..d29c7a6c655fb6dc9eb8b40292d0cd3e377c949d 100644 (file)
+/****************************************************************************
+ *
+ * Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+ * Copyright (C) 2005-2013 Sourcefire, Inc.
+ *
+ * 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
+ *
+ ****************************************************************************/
 /*
-** Copyright (C) 2014 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.
-*/
-// act_reject.cc author Russ Combs <rucombs@cisco.com>
+ * Perform flexible response on packets matching conditions specified in Snort
+ * rules.
+ *
+ * Shutdown hostile network connections by injecting TCP resets or ICMP
+ * unreachable packets.
+ *
+ * flexresp3 is derived from flexresp and flexresp2.  It includes all
+ * configuration options from those modules and has these differences:
+ *
+ * - injects packets with correct encapsulations (doesn't assume
+ * eth+ip+icmp/tcp).
+ *
+ * - uses the wire packet as a prototype, not the packet generating the alert
+ * (which may be reassembled or otherwise generated internally with only the
+ * headers required for logging).
+ *
+ * - queues the injection action so that it is taken only once after detection
+ * regardless of multiple resp3 rules firing.
+ *
+ * - uses the same encoding and injection mechanism as active_response and/or
+ * reject actions.
+ *
+ * - bypasses sequence strafing in inline mode.
+ */
+
+// act_rej.cc author Russ Combs <rucombs@cisco.com>
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include "snort_types.h"
-#include "framework/ips_action.h"
-#include "framework/module.h"
+#include "snort_debug.h"
 #include "protocols/packet.h"
+#include "profiler.h"
 #include "packet_io/active.h"
-#include "snort_debug.h"
 #include "snort.h"
+#include "util.h"
+#include "framework/ips_action.h"
+#include "framework/parameter.h"
+#include "framework/module.h"
+
+#define REJ_RST_SND  0x01
+#define REJ_RST_RCV  0x02
+#define REJ_UNR_NET  0x04
+#define REJ_UNR_HOST 0x08
+#define REJ_UNR_PORT 0x10
+
+#define REJ_RST (REJ_RST_SND|REJ_RST_RCV)
+#define REJ_UNR (REJ_UNR_NET|REJ_UNR_HOST|REJ_UNR_PORT)
 
 static const char* s_name = "reject";
 
+static THREAD_LOCAL ProfileStats rejPerfStats;
+
+class RejectAction : public IpsAction
+{
+public:
+    RejectAction(uint32_t f) : IpsAction(s_name, ACT_RESET)
+    { mask = f; };
+
+    void exec(Packet*);
+
+private:
+    void send(Packet*);
+
+private:
+    uint32_t mask;
+};
+
 //-------------------------------------------------------------------------
-// reject module
+// class methods
 //-------------------------------------------------------------------------
 
-static const Parameter reject_params[] =
+void RejectAction::exec(Packet* p)
 {
+    PROFILE_VARS;
+    MODULE_PROFILE_START(rejPerfStats);
+
+    send(p);
+
+    MODULE_PROFILE_END(rejPerfStats);
+}
+
+void RejectAction::send(Packet* p)
+{
+    uint32_t flags = 0;
+
+    if ( Active_IsRSTCandidate(p) )
+        flags |= (mask & REJ_RST);
+
+    if ( Active_IsUNRCandidate(p) )
+        flags |= (mask & REJ_UNR);
+
+    if ( flags & REJ_RST_SND )
+        Active_SendReset(p, 0);
+
+    if ( flags & REJ_RST_RCV )
+        Active_SendReset(p, ENC_FLAG_FWD);
+
+    if ( flags & REJ_UNR_NET )
+        Active_SendUnreach(p, ENC_UNR_NET);
+
+    if ( flags & REJ_UNR_HOST )
+        Active_SendUnreach(p, ENC_UNR_HOST);
+
+    if ( flags & REJ_UNR_PORT )
+        Active_SendUnreach(p, ENC_UNR_PORT);
+
+    Active_IgnoreSession(p);
+}
+
+//-------------------------------------------------------------------------
+// module
+//-------------------------------------------------------------------------
+
+static const Parameter rej_params[] =
+{
+    { "reset_source", Parameter::PT_STRING, nullptr, nullptr,
+      "reset sender" },
+
+    { "rst_snd", Parameter::PT_STRING, nullptr, nullptr,
+      "reset sender" },
+
+    { "reset_dest", Parameter::PT_STRING, nullptr, nullptr,
+      "reset receiver" },
+
+    { "rst_rcv", Parameter::PT_STRING, nullptr, nullptr,
+      "reset receiver" },
+
+    { "reset_both", Parameter::PT_STRING, nullptr, nullptr,
+      "reset both sender and receiver" },
+
+    { "rst_all", Parameter::PT_STRING, nullptr, nullptr,
+      "reset both sender and receiver" },
+
+    { "icmp_net", Parameter::PT_STRING, nullptr, nullptr,
+      "send icmp network unreachable to sender" },
+
+    { "icmp_host", Parameter::PT_STRING, nullptr, nullptr,
+      "send icmp host unreachable to sender" },
+
+    { "icmp_port", Parameter::PT_STRING, nullptr, nullptr,
+      "send icmp port unreachable to sender" },
+
+    { "icmp_all", Parameter::PT_STRING, nullptr, nullptr,
+      "send icmp net, host, and port unreachable to sender" },
+
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
 class RejectModule : public Module
 {
 public:
-    RejectModule() : Module(s_name, reject_params) { };
-    bool set(const char*, Value&, SnortConfig*);
+    RejectModule() : Module(s_name, rej_params) { };
+
     bool begin(const char*, int, SnortConfig*);
-    bool end(const char*, int, SnortConfig*);
+    bool set(const char*, Value&, SnortConfig*);
 
-public:
-};
+    ProfileStats* get_profile() const
+    { return &rejPerfStats; };
 
-bool RejectModule::set(const char*, Value&, SnortConfig*)
-{
-    return false;
-}
+    uint32_t flags;
+};
 
 bool RejectModule::begin(const char*, int, SnortConfig*)
 {
+    flags = 0;
     return true;
 }
 
-bool RejectModule::end(const char*, int, SnortConfig*)
+bool RejectModule::set(const char*, Value& v, SnortConfig*)
 {
-    return true;
-}
+    if ( v.is("reset_source") || v.is("rst_snd") )
+        flags |= REJ_RST_SND;
 
-//-------------------------------------------------------------------------
+    else if ( v.is("reset_dest") || v.is("rst_rcv") )
+        flags |= REJ_RST_RCV;
 
-class RejectAction : public IpsAction
-{
-public:
-    RejectAction(RejectModule*);
+    else if ( v.is("reset_both") || v.is("rst_all") )
+        flags |= (REJ_RST_RCV | REJ_RST_SND);
 
-    void exec(Packet*);
+    else if ( v.is("icmp_net") )
+        flags |= REJ_UNR_NET;
 
-private:
-    unsigned flags;
-};
+    else if ( v.is("icmp_host") )
+        flags |= REJ_UNR_HOST;
 
-RejectAction::RejectAction(RejectModule*) : 
-    IpsAction(s_name)
-{
-    Active_SetEnabled(1);
-}
+    else if ( v.is("icmp_port") )
+        flags |= REJ_UNR_PORT;
 
-void RejectAction::exec(Packet* p)
-{
-    if ( PacketIsRebuilt(p) )
-        return;
+    else if ( v.is("icmp_all") )
+        flags |= (REJ_UNR_NET | REJ_UNR_HOST | REJ_UNR_PORT);
 
-    Active_QueueReject();
+    else
+        return false;
+
+    return true;
 }
 
+//-------------------------------------------------------------------------
+// api methods
 //-------------------------------------------------------------------------
 
 static Module* mod_ctor()
-{ return new RejectModule; }
+{
+    return new RejectModule;
+}
 
 static void mod_dtor(Module* m)
-{ delete m; }
+{
+    delete m;
+}
 
-static IpsAction* rej_ctor(Module* m)
-{ return new RejectAction((RejectModule*)m); }
+static IpsAction* rej_ctor(Module* p)
+{
+    RejectModule* m = (RejectModule*)p;
+    return new RejectAction(m->flags);
+}
 
 static void rej_dtor(IpsAction* p)
-{ delete p; }
+{
+    delete p;
+}
 
-static ActionApi rej_api
+static void rej_ginit()
+{
+    Active_SetEnabled(1);
+}
+
+static const ActionApi rej_api =
 {
     {
         PT_IPS_ACTION,
@@ -119,7 +260,7 @@ static ActionApi rej_api
         mod_dtor
     },
     RULE_TYPE__DROP,
-    nullptr,
+    rej_ginit,
     nullptr,
     nullptr,
     nullptr,
diff --git a/src/actions/act_resp.cc b/src/actions/act_resp.cc
deleted file mode 100644 (file)
index 13be4ac..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/****************************************************************************
- *
- * Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
- * Copyright (C) 2005-2013 Sourcefire, Inc.
- *
- * 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
- *
- ****************************************************************************/
-/*
- * Perform flexible response on packets matching conditions specified in Snort
- * rules.
- *
- * Shutdown hostile network connections by injecting TCP resets or ICMP
- * unreachable packets.
- *
- * flexresp3 is derived from flexresp and flexresp2.  It includes all
- * configuration options from those modules and has these differences:
- *
- * - injects packets with correct encapsulations (doesn't assume
- * eth+ip+icmp/tcp).
- *
- * - uses the wire packet as a prototype, not the packet generating the alert
- * (which may be reassembled or otherwise generated internally with only the
- * headers required for logging).
- *
- * - queues the injection action so that it is taken only once after detection
- * regardless of multiple resp3 rules firing.
- *
- * - uses the same encoding and injection mechanism as active_response and/or
- * reject actions.
- *
- * - bypasses sequence strafing in inline mode.
- */
-
-// act_resp.cc author Russ Combs <rucombs@cisco.com>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "snort_types.h"
-#include "snort_debug.h"
-#include "protocols/packet.h"
-#include "profiler.h"
-#include "packet_io/active.h"
-#include "snort.h"
-#include "util.h"
-#include "framework/ips_action.h"
-#include "framework/parameter.h"
-#include "framework/module.h"
-
-#define RESP_RST_SND  0x01
-#define RESP_RST_RCV  0x02
-#define RESP_UNR_NET  0x04
-#define RESP_UNR_HOST 0x08
-#define RESP_UNR_PORT 0x10
-
-#define RESP_RST (RESP_RST_SND|RESP_RST_RCV)
-#define RESP_UNR (RESP_UNR_NET|RESP_UNR_HOST|RESP_UNR_PORT)
-
-// FIXIT this should merge with or replace reject
-static const char* s_name = "resp";
-
-static THREAD_LOCAL ProfileStats resp3PerfStats;
-
-// instance data
-struct Resp3_Data
-{
-    uint32_t mask;
-};
-
-class RespondAction : public IpsAction
-{
-public:
-    RespondAction(uint32_t f) : IpsAction(s_name)
-    { config.mask = f; };
-
-    void exec(Packet*);
-
-private:
-    Resp3_Data config;
-};
-
-static void Resp3_Send(Packet*, void*);
-
-//-------------------------------------------------------------------------
-// class methods
-//-------------------------------------------------------------------------
-
-void RespondAction::exec(Packet*)
-{
-    PROFILE_VARS;
-    MODULE_PROFILE_START(resp3PerfStats);
-
-    Active_QueueResponse(Resp3_Send, &config);
-
-    MODULE_PROFILE_END(resp3PerfStats);
-}
-
-//--------------------------------------------------------------------
-// core functions
-//--------------------------------------------------------------------
-
-static void Resp3_Send (Packet* p, void* pv)
-{
-    PROFILE_VARS;
-    MODULE_PROFILE_START(resp3PerfStats);
-
-    Resp3_Data* rd = (Resp3_Data*)pv;
-    uint32_t flags = 0;
-
-    if ( Active_IsRSTCandidate(p) )
-        flags |= (rd->mask & RESP_RST);
-
-    if ( Active_IsUNRCandidate(p) )
-        flags |= (rd->mask & RESP_UNR);
-
-    if ( flags & RESP_RST_SND )
-        Active_SendReset(p, 0);
-
-    if ( flags & RESP_RST_RCV )
-        Active_SendReset(p, ENC_FLAG_FWD);
-
-    if ( flags & RESP_UNR_NET )
-        Active_SendUnreach(p, ENC_UNR_NET);
-
-    if ( flags & RESP_UNR_HOST )
-        Active_SendUnreach(p, ENC_UNR_HOST);
-
-    if ( flags & RESP_UNR_PORT )
-        Active_SendUnreach(p, ENC_UNR_PORT);
-
-    Active_IgnoreSession(p);
-    MODULE_PROFILE_END(resp3PerfStats);
-}
-
-//-------------------------------------------------------------------------
-// module
-//-------------------------------------------------------------------------
-
-static const Parameter resp_params[] =
-{
-    { "reset_source", Parameter::PT_STRING, nullptr, nullptr,
-      "reset sender" },
-
-    { "rst_snd", Parameter::PT_STRING, nullptr, nullptr,
-      "reset sender" },
-
-    { "reset_dest", Parameter::PT_STRING, nullptr, nullptr,
-      "reset receiver" },
-
-    { "rst_rcv", Parameter::PT_STRING, nullptr, nullptr,
-      "reset receiver" },
-
-    { "reset_both", Parameter::PT_STRING, nullptr, nullptr,
-      "reset both sender and receiver" },
-
-    { "rst_all", Parameter::PT_STRING, nullptr, nullptr,
-      "reset both sender and receiver" },
-
-    { "icmp_net", Parameter::PT_STRING, nullptr, nullptr,
-      "send icmp network unreachable to sender" },
-
-    { "icmp_host", Parameter::PT_STRING, nullptr, nullptr,
-      "send icmp host unreachable to sender" },
-
-    { "icmp_port", Parameter::PT_STRING, nullptr, nullptr,
-      "send icmp port unreachable to sender" },
-
-    { "icmp_all", Parameter::PT_STRING, nullptr, nullptr,
-      "send icmp net, host, and port unreachable to sender" },
-
-    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-class RespModule : public Module
-{
-public:
-    RespModule() : Module(s_name, resp_params) { };
-
-    bool begin(const char*, int, SnortConfig*);
-    bool set(const char*, Value&, SnortConfig*);
-
-    ProfileStats* get_profile() const
-    { return &resp3PerfStats; };
-
-    uint32_t flags;
-};
-
-bool RespModule::begin(const char*, int, SnortConfig*)
-{
-    flags = 0;
-    return true;
-}
-
-bool RespModule::set(const char*, Value& v, SnortConfig*)
-{
-    if ( v.is("reset_source") || v.is("rst_snd") )
-        flags |= RESP_RST_SND;
-
-    else if ( v.is("reset_dest") || v.is("rst_rcv") )
-        flags |= RESP_RST_RCV;
-
-    else if ( v.is("reset_both") || v.is("rst_all") )
-        flags |= (RESP_RST_RCV | RESP_RST_SND);
-
-    else if ( v.is("icmp_net") )
-        flags |= RESP_UNR_NET;
-
-    else if ( v.is("icmp_host") )
-        flags |= RESP_UNR_HOST;
-
-    else if ( v.is("icmp_port") )
-        flags |= RESP_UNR_PORT;
-
-    else if ( v.is("icmp_all") )
-        flags |= (RESP_UNR_NET | RESP_UNR_HOST | RESP_UNR_PORT);
-
-    else
-        return false;
-
-    return true;
-}
-
-//-------------------------------------------------------------------------
-// api methods
-//-------------------------------------------------------------------------
-
-static Module* mod_ctor()
-{
-    return new RespModule;
-}
-
-static void mod_dtor(Module* m)
-{
-    delete m;
-}
-
-static IpsAction* resp_ctor(Module* p)
-{
-    RespModule* m = (RespModule*)p;
-    return new RespondAction(m->flags);
-}
-
-static void resp_dtor(IpsAction* p)
-{
-    delete p;
-}
-
-static void resp_ginit()
-{
-    Active_SetEnabled(1);
-}
-
-static const ActionApi resp_api =
-{
-    {
-        PT_IPS_ACTION,
-        s_name,
-        ACTAPI_PLUGIN_V0,
-        0,
-        mod_ctor,
-        mod_dtor
-    },
-    RULE_TYPE__DROP,
-    resp_ginit,
-    nullptr,
-    nullptr,
-    nullptr,
-    resp_ctor,
-    resp_dtor
-};
-
-#ifdef BUILDING_SO
-SO_PUBLIC const BaseApi* snort_plugins[] =
-{
-    &resp_api.base,
-    nullptr
-};
-#else
-const BaseApi* act_resp = &resp_api.base;
-#endif
-
index 75d7e5ecfb5556925e4bf9d0be0737c08a1f68f4..7e8e652419d86abe1e866bbf46125270b4a60eb4 100644 (file)
@@ -27,7 +27,7 @@
 #ifdef STATIC_IPS_ACTIONS
 extern const BaseApi* act_react;
 extern const BaseApi* act_reject;
-extern const BaseApi* act_resp;
+extern const BaseApi* act_replace;
 #endif
 
 const BaseApi* ips_actions[] =
@@ -35,7 +35,7 @@ const BaseApi* ips_actions[] =
 #ifdef STATIC_IPS_ACTIONS
     act_react,
     act_reject,
-    act_resp,
+    act_replace,
 #endif
     nullptr,
 };
index 55f7666b79047e2a1b0e858698f97c055d848aba..1d73c7b8ce1baf98892b329361c66b9738ebe413 100644 (file)
@@ -49,7 +49,6 @@
 #include "ips_options/ips_flowbits.h"
 #include "ips_options/ips_content.h"
 #include "ips_options/ips_pcre.h"
-#include "ips_options/ips_replace.h"
 #include "fpdetect.h"
 #include "ppm.h"
 #include "profiler.h"
@@ -383,7 +382,7 @@ int detection_option_node_evaluate(
     detection_option_tree_node_t *node, detection_option_eval_data_t *eval_data,
     Cursor& orig_cursor)
 {
-    int i, result = 0; //, prior_result = 0;
+    int i, result = 0;
     int rval = DETECTION_OPTION_NO_MATCH;
     char tmp_noalert_flag = 0;
     Cursor cursor = orig_cursor;
@@ -723,20 +722,6 @@ int detection_option_node_evaluate(
             //    node->children[i]->result;
         }
 
-#if 0
-        // FIXIT replace is broken now :(
-        if (result - prior_result > 0
-            && node->option_type == RULE_OPTION_TYPE_CONTENT
-            && Replace_OffsetStored(content_data) && ScInlineMode())
-        {
-            // FIXIT queuing replacements here is premature
-            // should be done if / when rule actually fires
-            // and at that point, the change can be applied
-            Replace_QueueChange(content_data);
-            prior_result = result;
-        }
-#endif
-
         NODE_PROFILE_TMPSTART(node);
 
         if (rval == DETECTION_OPTION_NO_ALERT)
index a9e49108d9c72f60fdea09906f89acaa47a0cc6a..60fb9e291fec972778b39de54afe42106706cd08 100644 (file)
@@ -147,15 +147,15 @@ static inline void InitMatchInfo(OTNX_MATCH_DATA *o)
 static inline void fpLogOther (
     Packet* p, RuleTreeNode* rtn, OptTreeNode* otn, int action)
 {
-    // FIXIT some or all of these can be migrated to user defined actions
-    otn_trigger_actions(otn, p);
-
     if ( EventTrace_IsEnabled() )
         EventTrace_Log(p, otn, action);
 
-    // user defined actions are done here
+    // rule option actions are queued here (eg replace)
+    otn_trigger_actions(otn, p);
+
+    // rule actions are queued here (eg reject)
     if ( rtn->listhead->action )
-        rtn->listhead->action->exec(p);
+        ActionManager::queue(rtn->listhead->action);
 }
 
 /*
index 0e5cfc491e4048d6114a0e57be4e577157174641..d233c01b977e5325e5e1a63b52af15856cabb3f5 100644 (file)
@@ -35,6 +35,7 @@
 #include "protocols/packet.h"
 #include "packet_io/active.h"
 #include "libs/file_sha256.h"
+#include "managers/action_manager.h"
 
 /* The hash table of expected files */
 static THREAD_LOCAL_TBD SFXHASH *fileHash = NULL;
@@ -199,7 +200,7 @@ static inline File_Verdict checkVerdict(Packet *p, FileNode *node, SFXHASH_NODE
     {
         Active_ForceDropPacket();
         Active_DropSession();
-        Active_QueueReject();
+        ActionManager::queue_reject();
         if (log_file_action)
         {
             log_file_action(p->flow, FILE_RESUME_BLOCK);
@@ -212,7 +213,7 @@ static inline File_Verdict checkVerdict(Packet *p, FileNode *node, SFXHASH_NODE
         Active_ForceDropPacket();
         Active_DropSession();
         if (FILE_VERDICT_REJECT == node->verdict)
-            Active_QueueReject();
+            ActionManager::queue_reject();
         if (log_file_action)
         {
             log_file_action(p->flow, FILE_RESUME_BLOCK);
index 933cf5663a6313f8668b55efee6b0a8f5fd6e52c..8dc556caa3ff1b3c45f84c0eeff23f6c600a7158 100644 (file)
@@ -38,6 +38,16 @@ struct Packet;
 // api for class
 //-------------------------------------------------------------------------
 
+enum ActionType
+{
+    ACT_LOCAL,
+    ACT_MODIFY,
+    ACT_PROXY,
+    ACT_RESET,
+    ACT_REMOTE,
+    ACT_MAX
+};
+
 struct SnortConfig;
 
 class IpsAction
@@ -48,13 +58,15 @@ public:
     virtual void exec(Packet*) = 0;
 
     const char* get_name() const { return name; };
+    ActionType get_action() { return action; }
 
 protected:
-    IpsAction(const char* s)
-    { name = s; };
+    IpsAction(const char* s, ActionType a)
+    { name = s; action = a; };
 
 private:
     const char* name;
+    ActionType action;
 };
 
 typedef void (*IpsActFunc)();
index de4a57ad10fe18c26644ee8658d97e4746320af8..d1c4c86cdea3b16ae4eb3e3227cd79660d538ea0 100644 (file)
@@ -19,8 +19,6 @@
 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
-#include "ips_replace.h"
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -43,8 +41,7 @@ using namespace std;
 #include "framework/parameter.h"
 #include "framework/module.h"
 #include "detection/detection_defines.h"
-
-#define MAX_PATTERN_SIZE 2048
+#include "actions/act_replace.h"
 
 static void replace_parse(const char* args, string& s)
 {
@@ -78,67 +75,6 @@ static bool replace_ok()
     return true;
 }
 
-//--------------------------------------------------------------------------
-// queue foo
-//--------------------------------------------------------------------------
-
-struct Replacement
-{
-    string data;
-    int offset;
-};
-
-#define MAX_REPLACEMENTS 32
-static THREAD_LOCAL Replacement* rpl;
-static THREAD_LOCAL int num_rpl = 0;
-
-void Replace_ResetQueue(void)
-{
-    num_rpl = 0;
-}
-
-void Replace_QueueChange(string& s, int off)
-{
-    Replacement* r;
-
-    if ( num_rpl == MAX_REPLACEMENTS )
-        return;
-
-    r = rpl + num_rpl++;
-
-    r->data = s;
-    r->offset = off;
-}
-
-static inline void Replace_ApplyChange(Packet *p, Replacement* r)
-{
-    uint8_t* start = (uint8_t*)p->data + r->offset;
-    const uint8_t* end = p->data + p->dsize;
-    unsigned len;
-
-    if ( (start + r->data.size()) >= end )
-        len = p->dsize - r->offset;
-    else
-        len = r->data.size();
-
-    memcpy(start, r->data.c_str(), len);
-}
-
-// FIXIT this could be ContentOption::action()
-// for a more general packet rewriting facility
-void Replace_ModifyPacket(Packet *p)
-{
-    if ( num_rpl == 0 )
-        return;
-
-    for ( int n = 0; n < num_rpl; n++ )
-    {
-        Replace_ApplyChange(p, rpl+n);
-    }
-    p->packet_flags |= PKT_MODIFIED;
-    num_rpl = 0;
-}
-
 //-------------------------------------------------------------------------
 // replace rule option
 //-------------------------------------------------------------------------
@@ -231,25 +167,22 @@ int ReplaceOption::eval(Cursor& c, Packet* p)
     if ( !c.is("pkt_data") )
         return DETECTION_OPTION_NO_MATCH;
 
-    if ( c.length() < repl.size() )
+    if ( c.get_pos() < repl.size() )
         return DETECTION_OPTION_NO_MATCH;
 
-    store(c.get_pos());
+    store(c.get_pos() - repl.size());
 
     MODULE_PROFILE_END(replacePerfStats);
     return DETECTION_OPTION_MATCH;
 }
 
-// FIXIT this may need to be apply change here
-// and queue change from some other point
-// (almost certainly broke)
 void ReplaceOption::action(Packet*)
 {
     PROFILE_VARS;
     MODULE_PROFILE_START(replacePerfStats);
 
     if ( pending() )
-        Replace_QueueChange(repl, pos());
+        Replace_QueueChange(repl, (unsigned)pos());
 
     MODULE_PROFILE_END(replacePerfStats);
 }
@@ -260,8 +193,8 @@ void ReplaceOption::action(Packet*)
 
 static const Parameter repl_params[] =
 {
-    { "~mode", Parameter::PT_ENUM, "printable|binary|all", nullptr,
-      "output format" },
+    { "~", Parameter::PT_STRING, nullptr, nullptr,
+      "byte code to replace with" },
 
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
@@ -288,7 +221,7 @@ bool ReplModule::begin(const char*, int, SnortConfig*)
 
 bool ReplModule::set(const char*, Value& v, SnortConfig*)
 {
-    if ( v.is("~mode") )
+    if ( v.is("~") )
         replace_parse(v.get_string(), data);
 
     else
@@ -333,16 +266,6 @@ static void replace_dtor(IpsOption* p)
     delete p;
 }
 
-static void replace_tinit(SnortConfig*)
-{
-    rpl = new Replacement[MAX_REPLACEMENTS];
-}
-
-static void replace_tterm(SnortConfig*)
-{
-    delete[] rpl;
-}
-
 static const IpsApi replace_api =
 {
     {
@@ -357,8 +280,8 @@ static const IpsApi replace_api =
     0, 0,
     nullptr,
     nullptr,
-    replace_tinit,
-    replace_tterm,
+    nullptr,
+    nullptr,
     replace_ctor,
     replace_dtor,
     nullptr
diff --git a/src/ips_options/ips_replace.h b/src/ips_options/ips_replace.h
deleted file mode 100644 (file)
index 045918d..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
-** Copyright (C) 2002-2013 Sourcefire, Inc.
-** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
-**
-** 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.
-*/
-
-#ifndef REPLACE_H
-#define REPLACE_H
-
-#include <assert.h>
-#include "ips_content.h"
-#include "main/thread.h"
-
-void PayloadReplaceInit(PatternMatchData*, char*, OptTreeNode*);
-
-void Replace_ResetQueue(void);
-void Replace_QueueChange(PatternMatchData*);
-void Replace_ModifyPacket(Packet*);
-
-#endif
-
index 6948a6aeb552f5966e2e06e2bbaf7daeb453a826..462afb641e5fdc023cceb28bc01257372a9472f1 100644 (file)
@@ -55,7 +55,6 @@ using namespace std;
 
 #include "helpers/process.h"
 #include "protocols/packet.h"
-#include "managers/packet_manager.h"
 #include "packet_io/sfdaq.h"
 #include "packet_io/active.h"
 #include "rules.h"
@@ -89,6 +88,7 @@ using namespace std;
 #include "managers/ips_manager.h"
 #include "managers/mpse_manager.h"
 #include "managers/packet_manager.h"
+#include "managers/action_manager.h"
 #include "detection/sfrim.h"
 #include "ppm.h"
 #include "profiler.h"
@@ -107,7 +107,7 @@ using namespace std;
 #include "target_based/sftarget_reader.h"
 #include "stream/stream_api.h"
 #include "stream/stream.h"
-#include "ips_options/ips_replace.h"
+#include "actions/act_replace.h"
 
 #ifdef INTEL_SOFT_CPM
 #include "search/intel_soft_cpm.h"
@@ -285,6 +285,22 @@ static void register_profiles()
 // initialization
 //-------------------------------------------------------------------------
 
+static void init_policy(SnortConfig* sc)
+{
+    PolicyMode pm;
+
+    if ( sc->run_flags & RUN_FLAG__INLINE )
+        pm = POLICY_MODE__INLINE;
+
+    else if ( sc->run_flags & RUN_FLAG__INLINE_TEST )
+        pm =  POLICY_MODE__INLINE_TEST;
+
+    else
+        pm = POLICY_MODE__PASSIVE;
+
+    sc->get_ips_policy()->policy_mode = pm;
+}
+
 static void SnortInit(int argc, char **argv)
 {
     init_signals();
@@ -333,6 +349,7 @@ static void SnortInit(int argc, char **argv)
      * command line overriding config file.
      * Set the global snort_conf that will be used during run time */
     snort_conf = MergeSnortConfs(snort_cmd_line_conf, sc);
+    init_policy(snort_conf);
 
     if ( snort_conf->output )
         EventManager::instantiate(snort_conf->output, sc);
@@ -617,6 +634,7 @@ static SnortConfig * get_reload_config(void)
     SnortConfig *sc = ParseSnortConf(snort_cmd_line_conf);
 
     sc = MergeSnortConfs(snort_cmd_line_conf, sc);
+    init_policy(sc);
 
 #ifdef PERF_PROFILING
     /* Parse profiling here because of file option and potential
@@ -888,16 +906,14 @@ DAQ_Verdict packet_callback(
 
     MODULE_PROFILE_START(eventqPerfStats);
     SnortEventqReset();
-    Replace_ResetQueue();
-    Active_ResetQueue();
     MODULE_PROFILE_END(eventqPerfStats);
 
+    ActionManager::reset_queue();
+
     verdict = ProcessPacket(&s_packet, pkthdr, pkt);
 
-    if ( Active_ResponseQueued() )
-    {
-        Active_SendResponses(&s_packet);
-    }
+    ActionManager::execute(&s_packet);
+
     if ( Active_PacketWasDropped() )
     {
         if ( verdict == DAQ_VERDICT_PASS )
@@ -905,8 +921,6 @@ DAQ_Verdict packet_callback(
     }
     else
     {
-        Replace_ModifyPacket(&s_packet);
-
         if ( s_packet.packet_flags & PKT_MODIFIED )
         {
             // this packet was normalized and/or has replacements
@@ -1003,6 +1017,7 @@ void snort_thread_init(const char* intf)
 
     EventManager::open_outputs();
     IpsManager::setup_options();
+    ActionManager::thread_init(snort_conf);
     InspectorManager::thread_init(snort_conf);
 }
 
@@ -1013,6 +1028,7 @@ void snort_thread_term()
 #endif
     ModuleManager::accumulate(snort_conf);
     InspectorManager::thread_term(snort_conf);
+    ActionManager::thread_term(snort_conf);
     IpsManager::clear_options();
     EventManager::close_outputs();
 
index e7c814b717276098c6b153a4b44be2800429b110..d5f93ea299eb9efbf4a373801ced13a68ec6dffd 100644 (file)
@@ -33,10 +33,14 @@ using namespace std;
 #include "search_engines/search_engines.h"
 #include "parser/parser.h"
 #include "log/messages.h"
+#include "actions/act_replace.h"
 
 typedef list<const ActionApi*> AList;
 static AList s_actors;
 
+static IpsAction* s_reject = nullptr;
+static THREAD_LOCAL IpsAction* s_action = nullptr;
+
 //-------------------------------------------------------------------------
 // engine plugins
 //-------------------------------------------------------------------------
@@ -78,12 +82,29 @@ void ActionManager::instantiate(
 
     if ( act )
     {
+        if ( !s_reject && !strcmp(act->get_name(), "reject") )
+            s_reject = act;
+
         ListHead* lh = CreateRuleType(sc, api->base.name, api->type, 0, nullptr);
         assert(lh);
         lh->action = act;
     }
 }
 
+void ActionManager::thread_init(SnortConfig*)
+{
+    for ( auto* p : s_actors )
+        if ( p->tinit )
+            p->tinit();
+}
+
+void ActionManager::thread_term(SnortConfig*)
+{
+    for ( auto* p : s_actors )
+        if ( p->tterm )
+            p->tterm();
+}
+
 #if 0
 static const ActionApi* get_api(const char* keyword)
 {
@@ -95,6 +116,30 @@ static const ActionApi* get_api(const char* keyword)
 }
 #endif
 
-void ActionManager::execute(Packet*)
-{ }
+void ActionManager::execute(Packet* p)
+{
+    if ( s_action )
+    {
+        s_action->exec(p);
+        s_action = nullptr;
+    }
+}
+
+void ActionManager::queue(IpsAction* a)
+{
+    if ( !s_action || a->get_action() > s_action->get_action() )
+        s_action = a;
+}
+
+void ActionManager::queue_reject()
+{
+    if ( s_reject )
+        queue(s_reject);
+}
+
+void ActionManager::reset_queue()
+{
+    s_action = nullptr;
+    Replace_ResetQueue();
+}
 
index f8974abd23647c344451049ab5c8da794537bc5e..738650bed044615b2216c8da4b50f56534314174 100644 (file)
@@ -45,6 +45,13 @@ public:
     static RuleType get_action_type(const char*);
 
     static void instantiate(const ActionApi*, Module*, SnortConfig*);
+
+    static void thread_init(SnortConfig*);
+    static void thread_term(SnortConfig*);
+
+    static void reset_queue();
+    static void queue_reject();
+    static void queue(IpsAction*);
     static void execute(struct Packet*);
 };
 
index 68d400665e0e073e57a4a6da3e80957adf5a0538..e46cf9df0ab427f1a09f592707008bee55a924fe 100644 (file)
@@ -38,6 +38,7 @@
 #include "stream/stream_api.h"
 #include "snort.h"
 
+#include "managers/action_manager.h"
 #include "managers/packet_manager.h"
 #include "packet_io/sfdaq.h"
 
@@ -56,9 +57,6 @@ THREAD_LOCAL int active_suspend = 0;
 
 THREAD_LOCAL int active_have_rsp = 0;
 
-static THREAD_LOCAL void* s_rejData, *s_rspData;
-static THREAD_LOCAL Active_ResponseFunc s_rejFunc = NULL, s_rspFunc = NULL;
-
 static THREAD_LOCAL uint64_t s_injects = 0;
 
 typedef int (*send_t) (
@@ -83,73 +81,6 @@ static inline PROTO_ID GetInnerProto (const Packet* p)
     return ( p->layers[p->num_layers-1].proto );
 }
 
-//--------------------------------------------------------------------
-// this implementation ensures that flexible responses
-// take precedence over active responses.
-
-int Active_QueueReject (void)
-{
-    if ( Active_Suspended() )
-        return 0;
-
-    if ( !s_rejFunc )
-    {
-        s_rejFunc = (Active_ResponseFunc)Active_KillSession;
-        s_rejData = NULL;
-        active_have_rsp = 1;
-    }
-    return 0;
-}
-
-int Active_QueueResponse (Active_ResponseFunc f, void* pv)
-{
-    if ( Active_Suspended() )
-        return 0;
-
-    if ( !s_rspFunc )
-    {
-        s_rspFunc = f;
-        s_rspData = pv;
-        active_have_rsp = 1;
-    }
-    return 0;
-}
-
-// helper function
-static inline void Active_ClearQueue (void)
-{
-    s_rejFunc = s_rspFunc = NULL;
-    s_rejData = s_rspData = NULL;
-}
-
-int Active_ResetQueue ()
-{
-    Active_ClearQueue();
-    return 0;
-}
-
-int Active_SendResponses (Packet* p)
-{
-    if ( s_rspFunc )
-    {
-        s_rspFunc(p, s_rspData);
-    }
-    else if ( s_rejFunc )
-    {
-        s_rejFunc(p, s_rejData);
-    }
-    else
-    {
-        return 0;
-    }
-    if ( p->flow )
-    {
-        stream.init_active_response(p, p->flow);
-    }
-    Active_ClearQueue();
-    return 1;
-}
-
 //--------------------------------------------------------------------
 
 void Active_KillSession (Packet* p, EncodeFlags* pf)
@@ -435,7 +366,7 @@ static inline int _Active_DoReset(Packet *p)
     {
         case IPPROTO_TCP:
             if ( Active_IsRSTCandidate(p) )
-                Active_QueueReject();
+                ActionManager::queue_reject();
             break;
 
         // FIXIT send unr to udp/icmp4/icmp6 only or for all non-tcp?
@@ -443,7 +374,7 @@ static inline int _Active_DoReset(Packet *p)
         case IPPROTO_ICMP:
         case IPPROTO_ICMPV6:
             if ( Active_IsUNRCandidate(p) )
-                Active_QueueReject();
+                ActionManager::queue_reject();
             break;
     }
 
index 62b448b280678c0c41c6bb7e851e9e808ab51d45..8ba4cb5ec9a9d20b480ddd4dc636b7ea1ff4407d 100644 (file)
 int Active_Init(SnortConfig*);
 int Active_Term(void);
 
-typedef void (*Active_ResponseFunc)(Packet*, void* data);
-
-int Active_QueueReject(void);
-int Active_QueueResponse(Active_ResponseFunc, void*);
-int Active_ResetQueue(void);
-
-// this must be called on the wire packet and not a
-// reassembled packet so that encoding is correct.
-int Active_SendResponses(Packet*);
 uint64_t Active_GetInjects(void);
 
 // NULL flags implies ENC_FLAG_FWD
index 598992b34a22ffcbadc26a8786df1e1ef2eaa5bf..d1ec1909d8ae34499b9f4f785abc5afd4b4767ce 100644 (file)
@@ -619,8 +619,6 @@ SnortConfig * ParseSnortConf(const SnortConfig* boot_conf)
 
     OtnInit(sc);
 
-    InitVarTables(sc->policy_map->ips_policy[0]);
-
     sc->fast_pattern_config = FastPatternConfigNew();
     sc->event_queue_config = EventQueueConfigNew();
     sc->threshold_config = ThresholdConfigNew();