From: Russ Combs (rucombs) Date: Wed, 25 Aug 2021 22:08:24 +0000 (+0000) Subject: Merge pull request #3023 in SNORT/snort3 from ~RUCOMBS/snort3:pub_order to master X-Git-Tag: 3.1.11.0~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bc8539f8fac92c1b5161e4e6e74da8d632aef0d7;p=thirdparty%2Fsnort3.git Merge pull request #3023 in SNORT/snort3 from ~RUCOMBS/snort3:pub_order to master Squashed commit of the following: commit e1f7f82009202b4dd5f3f2f8a72b82b95decc0e6 Author: russ Date: Wed Aug 25 16:29:47 2021 -0400 framework: update base API version to 7 commit f465cfcbfeace58569b37b00b62db54daa766ca2 Author: russ Date: Fri Aug 6 11:40:46 2021 -0400 policy: reorganize for sanity commit 86df6f2bf31b78cc5251c42df5dbfaa6943b8cc7 Author: russ Date: Fri Aug 6 11:32:37 2021 -0400 policy: put inspection policy accessors in public space commit 56a76559b84bff6437f5e412f807ba27c8e3bf98 Author: russ Date: Sat Jul 31 09:51:31 2021 -0400 data_bus: support ordered call of handlers Each handler can set a desired order which defaults to zero meaning last. One would be first, and so on. The sequence in which handlers with the same order are called is unspecified. binder sets order 100 for flow setup events to apply policy. (That makes it effectively first since by default everything else is zero / last.) plugins which want to predictably set policy on flow setup can run before or after binder by setting an appropriate order. --- diff --git a/src/framework/base_api.h b/src/framework/base_api.h index e416771be..6de163f5c 100644 --- a/src/framework/base_api.h +++ b/src/framework/base_api.h @@ -29,7 +29,7 @@ // this is the current version of the base api // must be prefixed to subtype version -#define BASE_API_VERSION 6 +#define BASE_API_VERSION 7 // set options to API_OPTIONS to ensure compatibility #ifndef API_OPTIONS diff --git a/src/framework/data_bus.cc b/src/framework/data_bus.cc index d85d5ccfb..3e41b9033 100644 --- a/src/framework/data_bus.cc +++ b/src/framework/data_bus.cc @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include "data_bus.h" #include "main/policy.h" @@ -142,10 +144,22 @@ void DataBus::publish(const char* key, Packet* p, Flow* f) // private methods //-------------------------------------------------------------------------- +static bool compare(DataHandler* a, DataHandler* b) +{ + if ( a->order and b->order ) + return a->order < b->order; + + if ( a->order ) + return true; + + return false; +} + void DataBus::_subscribe(const char* key, DataHandler* h) { DataList& v = map[key]; v.emplace_back(h); + std::sort(v.begin(), v.end(), compare); } void DataBus::_unsubscribe(const char* key, DataHandler* h) diff --git a/src/framework/data_bus.h b/src/framework/data_bus.h index 109ebc703..259324405 100644 --- a/src/framework/data_bus.h +++ b/src/framework/data_bus.h @@ -77,6 +77,10 @@ public: const char* module_name; bool cloned; + // order is desired position in the call sequence of handlers: 1 = first, 0 = last + // the sequence among subscribers with the same order is not specified + unsigned order = 0; + protected: DataHandler(std::nullptr_t) = delete; DataHandler(const char* mod_name) : module_name(mod_name), cloned(false) { } diff --git a/src/framework/test/data_bus_test.cc b/src/framework/test/data_bus_test.cc index 752f2e16b..fb97af2c9 100644 --- a/src/framework/test/data_bus_test.cc +++ b/src/framework/test/data_bus_test.cc @@ -72,19 +72,24 @@ private: class UTestHandler : public DataHandler { public: - UTestHandler() : DataHandler("unit_test") - { } + UTestHandler(unsigned u = 0) : DataHandler("unit_test") + { if ( u ) order = u; } void handle(DataEvent&, Flow*) override; int evt_msg = 0; + unsigned seq = 99; }; +static unsigned s_next = 0; + void UTestHandler::handle(DataEvent& event, Flow*) { UTestEvent* evt = (UTestEvent*)&event; evt_msg = evt->get_message(); + seq = ++s_next; } + #define DB_UTEST_EVENT "unit.test.event" //-------------------------------------------------------------------------- @@ -151,6 +156,62 @@ TEST(data_bus, subscribe) delete h; } +TEST(data_bus, order1) +{ + UTestHandler* h0 = new UTestHandler(); + DataBus::subscribe(DB_UTEST_EVENT, h0); + + UTestHandler* h1 = new UTestHandler(1); + DataBus::subscribe(DB_UTEST_EVENT, h1); + + UTestHandler* h9 = new UTestHandler(9); + DataBus::subscribe(DB_UTEST_EVENT, h9); + + s_next = 0; + UTestEvent event(100); + DataBus::publish(DB_UTEST_EVENT, event); + + CHECK(1 == h1->seq); + CHECK(2 == h9->seq); + CHECK(3 == h0->seq); + + DataBus::unsubscribe(DB_UTEST_EVENT, h0); + DataBus::unsubscribe(DB_UTEST_EVENT, h1); + DataBus::unsubscribe(DB_UTEST_EVENT, h9); + + delete h0; + delete h1; + delete h9; +} + +TEST(data_bus, order2) +{ + UTestHandler* h0 = new UTestHandler(0); + DataBus::subscribe(DB_UTEST_EVENT, h0); + + UTestHandler* h9 = new UTestHandler(9); + DataBus::subscribe(DB_UTEST_EVENT, h9); + + UTestHandler* h1 = new UTestHandler(1); + DataBus::subscribe(DB_UTEST_EVENT, h1); + + s_next = 0; + UTestEvent event(100); + DataBus::publish(DB_UTEST_EVENT, event); + + CHECK(1 == h1->seq); + CHECK(2 == h9->seq); + CHECK(3 == h0->seq); + + DataBus::unsubscribe(DB_UTEST_EVENT, h0); + DataBus::unsubscribe(DB_UTEST_EVENT, h1); + DataBus::unsubscribe(DB_UTEST_EVENT, h9); + + delete h0; + delete h1; + delete h9; +} + //------------------------------------------------------------------------- // main //------------------------------------------------------------------------- diff --git a/src/main/policy.cc b/src/main/policy.cc index 666722587..1c0a30864 100644 --- a/src/main/policy.cc +++ b/src/main/policy.cc @@ -293,20 +293,33 @@ InspectionPolicy* get_inspection_policy() IpsPolicy* get_ips_policy() { return s_detection_policy; } -IpsPolicy* get_ips_policy(const SnortConfig* sc, unsigned i) +void set_network_policy(NetworkPolicy* p) +{ s_traffic_policy = p; } + +void set_inspection_policy(InspectionPolicy* p) +{ s_inspection_policy = p; } + +void set_ips_policy(IpsPolicy* p) +{ s_detection_policy = p; } + +NetworkPolicy* get_user_network_policy(const SnortConfig* sc, unsigned policy_id) { - return sc && i < sc->policy_map->ips_policy_count() ? - sc->policy_map->get_ips_policy(i) : nullptr; + return sc->policy_map->get_user_network(policy_id); +} + +InspectionPolicy* get_user_inspection_policy(const SnortConfig* sc, unsigned policy_id) +{ + return sc->policy_map->get_user_inspection(policy_id); } InspectionPolicy* get_default_inspection_policy(const SnortConfig* sc) { return sc->policy_map->get_inspection_policy(0); } -void set_ips_policy(IpsPolicy* p) -{ s_detection_policy = p; } - -void set_network_policy(NetworkPolicy* p) -{ s_traffic_policy = p; } +IpsPolicy* get_ips_policy(const SnortConfig* sc, unsigned i) +{ + return sc && i < sc->policy_map->ips_policy_count() ? + sc->policy_map->get_ips_policy(i) : nullptr; +} IpsPolicy* get_user_ips_policy(const SnortConfig* sc, unsigned policy_id) { @@ -317,11 +330,6 @@ IpsPolicy* get_empty_ips_policy(const SnortConfig* sc) { return sc->policy_map->get_empty_ips(); } - -NetworkPolicy* get_user_network_policy(const SnortConfig* sc, unsigned policy_id) -{ - return sc->policy_map->get_user_network(policy_id); -} } // namespace snort void set_network_policy(const SnortConfig* sc, unsigned i) @@ -332,9 +340,6 @@ void set_network_policy(const SnortConfig* sc, unsigned i) set_network_policy(pm->get_network_policy(i)); } -void set_inspection_policy(InspectionPolicy* p) -{ s_inspection_policy = p; } - void set_inspection_policy(const SnortConfig* sc, unsigned i) { PolicyMap* pm = sc->policy_map; @@ -372,6 +377,15 @@ void set_default_policy(const SnortConfig* sc) set_ips_policy(sc->policy_map->get_ips_policy(0)); } +bool only_network_policy() +{ return get_network_policy() && !get_ips_policy() && !get_inspection_policy(); } + +bool only_inspection_policy() +{ return get_inspection_policy() && !get_ips_policy() && !get_network_policy(); } + +bool only_ips_policy() +{ return get_ips_policy() && !get_inspection_policy() && !get_network_policy(); } + bool default_inspection_policy() { if ( !get_inspection_policy() ) @@ -383,12 +397,3 @@ bool default_inspection_policy() return true; } -bool only_inspection_policy() -{ return get_inspection_policy() && !get_ips_policy() && !get_network_policy(); } - -bool only_ips_policy() -{ return get_ips_policy() && !get_inspection_policy() && !get_network_policy(); } - -bool only_network_policy() -{ return get_network_policy() && !get_ips_policy() && !get_inspection_policy(); } - diff --git a/src/main/policy.h b/src/main/policy.h index 5cc7025fe..bb32a0614 100644 --- a/src/main/policy.h +++ b/src/main/policy.h @@ -219,14 +219,26 @@ public: Shell* get_shell(unsigned i = 0) { return i < shells.size() ? shells[i] : nullptr; } + void set_user_network(NetworkPolicy* p) + { user_network[p->user_policy_id] = p; } + void set_user_inspection(InspectionPolicy* p) { user_inspection[p->user_policy_id] = p; } void set_user_ips(IpsPolicy* p) { user_ips[p->user_policy_id] = p; } - void set_user_network(NetworkPolicy* p) - { user_network[p->user_policy_id] = p; } + NetworkPolicy* get_user_network(unsigned user_id) + { + auto it = user_network.find(user_id); + return it == user_network.end() ? nullptr : it->second; + } + + InspectionPolicy* get_user_inspection(unsigned user_id) + { + auto it = user_inspection.find(user_id); + return it == user_inspection.end() ? nullptr : it->second; + } IpsPolicy* get_user_ips(unsigned user_id) { @@ -234,11 +246,8 @@ public: return it == user_ips.end() ? nullptr : it->second; } - NetworkPolicy* get_user_network(unsigned user_id) - { - auto it = user_network.find(user_id); - return it == user_network.end() ? nullptr : it->second; - } + NetworkPolicy* get_network_policy(unsigned i = 0) + { return i < network_policy.size() ? network_policy[i] : nullptr; } InspectionPolicy* get_inspection_policy(unsigned i = 0) { return i < inspection_policy.size() ? inspection_policy[i] : nullptr; } @@ -249,8 +258,8 @@ public: IpsPolicy* get_empty_ips() { return empty_ips_policy; } - NetworkPolicy* get_network_policy(unsigned i = 0) - { return i < network_policy.size() ? network_policy[i] : nullptr; } + unsigned network_policy_count() + { return network_policy.size(); } unsigned inspection_policy_count() { return inspection_policy.size(); } @@ -258,9 +267,6 @@ public: unsigned ips_policy_count() { return ips_policy.size(); } - unsigned network_policy_count() - { return network_policy.size(); } - unsigned shells_count() { return shells.size(); } @@ -280,21 +286,21 @@ private: std::vector inspection_policy; std::vector ips_policy; std::vector network_policy; + IpsPolicy* empty_ips_policy; + std::unordered_map> shell_map; + std::unordered_map user_network; std::unordered_map user_inspection; std::unordered_map user_ips; - std::unordered_map user_network; bool cloned = false; - }; //------------------------------------------------------------------------- // navigator stuff //------------------------------------------------------------------------- - // FIXIT-L may be inlined at some point; on lockdown for now // FIXIT-L SO_PUBLIC required because SnortConfig::inline_mode(), etc. uses the function namespace snort @@ -302,29 +308,31 @@ 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(const snort::SnortConfig*, unsigned i = 0); -SO_PUBLIC InspectionPolicy* get_default_inspection_policy(const snort::SnortConfig*); -SO_PUBLIC void set_ips_policy(IpsPolicy*); + SO_PUBLIC void set_network_policy(NetworkPolicy*); +SO_PUBLIC void set_inspection_policy(InspectionPolicy*); +SO_PUBLIC void set_ips_policy(IpsPolicy*); + +SO_PUBLIC NetworkPolicy* get_user_network_policy(const snort::SnortConfig*, unsigned policy_id); +SO_PUBLIC InspectionPolicy* get_user_inspection_policy(const snort::SnortConfig*, unsigned policy_id); +SO_PUBLIC InspectionPolicy* get_default_inspection_policy(const snort::SnortConfig*); + +SO_PUBLIC IpsPolicy* get_ips_policy(const snort::SnortConfig*, unsigned i = 0); SO_PUBLIC IpsPolicy* get_user_ips_policy(const snort::SnortConfig*, unsigned policy_id); SO_PUBLIC IpsPolicy* get_empty_ips_policy(const snort::SnortConfig*); -SO_PUBLIC NetworkPolicy* get_user_network_policy(const snort::SnortConfig*, unsigned policy_id); } void set_network_policy(const snort::SnortConfig*, unsigned = 0); - -void set_inspection_policy(InspectionPolicy*); void set_inspection_policy(const snort::SnortConfig*, unsigned = 0); - void set_ips_policy(const snort::SnortConfig*, unsigned = 0); void set_policies(const snort::SnortConfig*, Shell*); void set_default_policy(const snort::SnortConfig*); -bool default_inspection_policy(); +bool only_network_policy(); bool only_inspection_policy(); bool only_ips_policy(); -bool only_network_policy(); +bool default_inspection_policy(); #endif diff --git a/src/managers/inspector_manager.cc b/src/managers/inspector_manager.cc index 44c0cd90d..c02a2586e 100644 --- a/src/managers/inspector_manager.cc +++ b/src/managers/inspector_manager.cc @@ -1036,13 +1036,13 @@ bool InspectorManager::configure(SnortConfig* sc, bool cloned) if ( cloned and idx ) break; - set_inspection_policy(sc, idx); + ::set_inspection_policy(sc, idx); InspectionPolicy* p = sc->policy_map->get_inspection_policy(idx); p->configure(); ok = ::configure(sc, p->framework_policy, cloned) && ok; } - set_inspection_policy(sc); + ::set_inspection_policy(sc); SearchTool::set_conf(nullptr); return ok; diff --git a/src/network_inspectors/binder/binder.cc b/src/network_inspectors/binder/binder.cc index 7cdb12197..c66569c12 100644 --- a/src/network_inspectors/binder/binder.cc +++ b/src/network_inspectors/binder/binder.cc @@ -468,7 +468,8 @@ private: class FlowStateSetupHandler : public DataHandler { public: - FlowStateSetupHandler() : DataHandler(BIND_NAME) { } + FlowStateSetupHandler() : DataHandler(BIND_NAME) + { order = 100; } void handle(DataEvent&, Flow* flow) override {