ips_actions.cc
ips_actions.h
act_replace.cc
- act_replace.h
)
set( PLUGIN_LIST
"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)
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++;
}
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
//-------------------------------------------------------------------------
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;
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);
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;
};
// 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:
return;
}
- send(p);
-}
-
-void RejectAction::send(Packet* p)
-{
- Active* act = p->active;
uint32_t flags = 0;
if ( act->is_reset_candidate(p) )
#include "config.h"
#endif
-#include "act_replace.h"
-
#include "detection/detection_engine.h"
#include "framework/ips_action.h"
#include "framework/module.h"
// 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;
}
//-------------------------------------------------------------------------
-
-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();
}
{ 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; }
#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"
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;
break;
case Actions::RESET:
- p->active->reset_session(p);
+ p->active->reset_session(p, get_ips_policy()->action[action]);
break;
default:
#include "detection_engine.h"
-#include "actions/act_replace.h"
#include "events/sfeventq.h"
#include "filters/sfthreshold.h"
#include "framework/endianness.h"
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();
SF_EVENTQ* pq = p->context->equeue;
pc.log_limit += sfeventq_reset(pq);
}
+
#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"
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);
+ }
}
/*
{
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.)
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
#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"
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();
fc->process_file_policy_rule(file_rule);
}
+ if ( need_active )
+ Active::set_enabled();
+
return true;
}
{
file_stats_print();
}
+
FileMagicData magic;
FileRule file_rule;
FileConfig *fc = nullptr;
+ bool need_active = false;
};
enum FileSid
#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)
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)();
#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"
RuleProfile profile(replacePerfStats);
if ( pending() )
- Replace_QueueChange(repl, (unsigned)pos());
+ DetectionEngine::add_replacement(repl, (unsigned)pos());
}
//-------------------------------------------------------------------------
*/
void Analyzer::post_process_daq_pkt_msg(Packet* p)
{
- ActionManager::execute(p);
+ Active::execute(p);
DAQ_Verdict verdict = MAX_DAQ_VERDICT;
DetectionEngine::reset();
sfthreshold_reset();
- ActionManager::reset_queue(p);
+ Active::clear_queue(p);
p->daq_msg = msg;
p->daq_instance = daq_instance;
{
DataBus::publish(THREAD_ROTATE_EVENT, nullptr);
}
+
#include "policy.h"
+#include "actions/actions.h"
#include "detection/detection_engine.h"
#include "log/messages.h"
#include "managers/inspector_manager.h"
// detection policy
//-------------------------------------------------------------------------
-IpsPolicy::IpsPolicy(PolicyId id)
+IpsPolicy::IpsPolicy(PolicyId id) : action(Actions::Type::MAX, nullptr)
{
policy_id = id;
user_policy_id = 0;
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); }
bool only_network_policy()
{ return get_network_policy() && !get_ips_policy() && !get_inspection_policy(); }
+
#include <memory>
#include <unordered_map>
+#include <vector>
#include "framework/data_bus.h"
{
class GHash;
struct SnortConfig;
+class ActiveAction;
}
struct PortTable;
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;
};
//-------------------------------------------------------------------------
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);
bool only_network_policy();
#endif
+
#include <vector>
-#include "actions/act_replace.h"
#include "log/messages.h"
#include "main/snort_config.h"
#include "packet_io/active.h"
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;
+
}
}
}
}
-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
//-------------------------------------------------------------------------
return new IpsActionWrapper(api, p);
}
+
#endif
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
add_library (packet_io OBJECT
active.cc
active.h
+ active_action.h
sfdaq.cc
sfdaq.h
sfdaq_config.cc
#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"
#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" },
static THREAD_LOCAL ip_t* s_ipnet = nullptr;
static THREAD_LOCAL send_t s_send = SFDAQ::inject;
+static ResetAction default_reset;
+
//--------------------------------------------------------------------
// helpers
}
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;
if ( enabled )
{
- ActionManager::queue_reject(SnortConfig::get_conf(), p);
+ if (reject)
+ Active::queue(reject, p);
if ( p->flow )
{
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;
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))
delayed_active_action = ACT_PASS;
}
+
//--------------------------------------------------------------------
bool Active::open(const char* dev)
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;
+ }
+}
+
// 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
{
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();
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
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; }
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();
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;
// 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
// 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
* 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;
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++;
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;
sc->evalOrder[node->mode] = evalIndex;
sc->num_rule_types++;
- return node->RuleList;
+ return node;
}
void FreeRuleLists(SnortConfig* sc)
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*);
obfuscator = nullptr;
endianness = nullptr;
- active_inst = new Active;
+ active_inst = new Active();
action_inst = nullptr;
reset();
}
class Active;
class Endianness;
class Flow;
-class IpsAction;
+class ActiveAction;
class IpsContext;
class Obfuscator;
class SFDAQInstance;
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
}
}
#endif
+
{
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;
};
}
#include "smtp_module.h"
#include "log/messages.h"
+#include "packet_io/active.h"
#include "utils/util.h"
using namespace snort;
}
else if ( v.is("xlink2state") )
+ {
config->xlink2state = (XLINK2STATE)v.get_uint8();
+ Active::set_enabled();
+ }
else
return false;