]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #3001 in SNORT/snort3 from ~SATHIRKA/snort3:sip_odp_reload to...
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Thu, 5 Aug 2021 18:43:24 +0000 (18:43 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Thu, 5 Aug 2021 18:43:24 +0000 (18:43 +0000)
Squashed commit of the following:

commit 2b6790982998f014959301f7665f05dc388e6996
Author: Sreeja Athirkandathil Narayanan <sathirka@cisco.com>
Date:   Fri Jul 16 16:34:12 2021 -0400

    appid: use packet thread odp context while creating SIP session

src/network_inspectors/appid/detector_plugins/detector_sip.cc
src/network_inspectors/appid/detector_plugins/sip_patterns.cc
src/network_inspectors/appid/detector_plugins/test/CMakeLists.txt
src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h
src/network_inspectors/appid/detector_plugins/test/detector_sip_test.cc [new file with mode: 0644]
src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc

index d58afbf4ab0723b43a407c83e38527e2bf72c02d..714597ae6342d18d908ca7fdd1f2fc2770e6b5c6 100644 (file)
@@ -126,6 +126,7 @@ int SipUdpClientDetector::validate(AppIdDiscoveryArgs& args)
     return APPID_INPROCESS;
 }
 
+#ifndef SIP_UNIT_TEST
 SipTcpClientDetector::SipTcpClientDetector(ClientDiscovery* cdm)
 {
     handler = cdm;
@@ -308,6 +309,7 @@ int SipServiceDetector::validate(AppIdDiscoveryArgs& args)
 }
 
 SipUdpClientDetector* SipEventHandler::client = nullptr;
+#endif
 SipServiceDetector* SipEventHandler::service = nullptr;
 
 void SipEventHandler::handle(DataEvent& event, Flow* flow)
@@ -330,7 +332,7 @@ void SipEventHandler::handle(DataEvent& event, Flow* flow)
         IpProtocol protocol = p->is_tcp() ? IpProtocol::TCP : IpProtocol::UDP;
         AppidSessionDirection direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
         asd = AppIdSession::allocate_session(p, protocol, direction, inspector,
-            inspector.get_ctxt().get_odp_ctxt());
+            *pkt_thread_odp_ctxt);
     }
     if (!asd->get_session_flags(APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED))
         return;
@@ -400,6 +402,7 @@ success:
         client->add_user(asd, fd->user_name.c_str(), APP_ID_SIP, true, change_bits);
 }
 
+#ifndef SIP_UNIT_TEST
 void SipEventHandler::service_handler(SipEvent& sip_event, AppIdSession& asd,
     AppidChangeBits& change_bits)
 {
@@ -449,4 +452,5 @@ void SipEventHandler::service_handler(SipEvent& sip_event, AppIdSession& asd,
         }
     }
 }
+#endif
 
index 3f102e7ba80d90386f461557634fb3d97140320c..e990f6669efcce52d1aaa849f504dfbceb37ba21 100644 (file)
@@ -111,6 +111,7 @@ int SipPatternMatchers::add_server_pattern(AppId client_id, const char* client_v
         pattern);
 }
 
+#ifndef SIP_UNIT_TEST
 void SipPatternMatchers::finalize_patterns(OdpContext& odp_ctxt)
 {
     int num_patterns;
@@ -156,6 +157,7 @@ int SipPatternMatchers::get_client_from_ua(const char* pattern, uint32_t pattern
 {
     return get_sip_client_app(sip_ua_matcher, pattern, pattern_len, client_id, client_version);
 }
+#endif
 
 int SipPatternMatchers::get_client_from_server(const char* pattern, uint32_t pattern_len,
     AppId& client_id, char*& client_version)
index 85b7f325c89c685bd1e4496c18ab285fa2190c5f..5b63a4ff583c087aa5d30e4b09098c71fa5f795a 100644 (file)
@@ -5,3 +5,4 @@ add_cpputest( detector_smtp_test )
 
 add_cpputest( http_url_patterns_test )
 
+add_cpputest( detector_sip_test )
index 8784677d746a32801b459571470f66e754a2a2a9..cf2cd45515ba0d378f4eeb8eb408a441d3b77491 100644 (file)
@@ -47,23 +47,12 @@ bool Inspector::get_buf(const char*, Packet*, InspectionBuffer&) { return true;
 class StreamSplitter* Inspector::get_splitter(bool) { return nullptr; }
 
 // Stubs for search_tool.cc
-SearchTool::SearchTool(const char*, bool) { }
 SearchTool::~SearchTool() = default;
 void SearchTool::add(const char*, unsigned, int, bool) { }
 void SearchTool::add(const char*, unsigned, void*, bool) { }
 void SearchTool::add(const uint8_t*, unsigned, int, bool) { }
 void SearchTool::add(const uint8_t*, unsigned, void*, bool) { }
 void SearchTool::prep() { }
-static bool test_find_all_done = false;
-static bool test_find_all_enabled = false;
-static MatchedPatterns* mock_mp = nullptr;
-int SearchTool::find_all(const char*, unsigned, MpseMatch, bool, void* mp_arg)
-{
-    test_find_all_done = true;
-    if (test_find_all_enabled)
-        memcpy(mp_arg, &mock_mp, sizeof(MatchedPatterns*));
-    return 0;
-}
 
 // Stubs for util.cc
 char* snort_strndup(const char* src, size_t dst_size)
@@ -90,17 +79,21 @@ DiscoveryFilter::~DiscoveryFilter(){}
 void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }
 void show_stats(PegCount*, const PegInfo*, const IndexVec&, const char*, FILE*) { }
 
+#ifndef SIP_UNIT_TEST
 class AppIdInspector : public snort::Inspector
 {
 public:
     AppIdInspector(AppIdModule&) { }
     ~AppIdInspector() override = default;
     void eval(Packet*) override { }
-    bool configure(snort::SnortConfig*) override { return true; }
+    bool configure(snort::SnortConfig*) override;
     void show(const SnortConfig*) const override { }
     void tinit() override { }
     void tterm() override { }
+private:
+    AppIdContext* ctxt = nullptr;
 };
+#endif
 
 // Stubs for modules, config
 AppIdConfig::~AppIdConfig() = default;
@@ -151,9 +144,12 @@ AppIdConfig stub_config;
 AppIdContext stub_ctxt(stub_config);
 OdpContext stub_odp_ctxt(stub_config, nullptr);
 AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector,
-    OdpContext&, uint16_t) : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), config(stub_config),
-        api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt) { }
-AppIdSession::~AppIdSession() = default;
+    OdpContext& odpctxt, uint16_t) : snort::FlowData(inspector_id, (snort::Inspector*)&inspector),
+        config(stub_config), api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(odpctxt)
+{
+    this->set_session_flags(APPID_SESSION_DISCOVER_APP);
+}
+AppIdSession::~AppIdSession() { delete &api; }
 AppIdHttpSession::AppIdHttpSession(AppIdSession& asd, uint32_t http2_stream_id)
   : asd(asd), http2_stream_id(http2_stream_id)
 {
@@ -222,4 +218,5 @@ int ServiceDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort
 OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*)
 { }
 
+THREAD_LOCAL OdpContext* pkt_thread_odp_ctxt = nullptr;
 #endif
diff --git a/src/network_inspectors/appid/detector_plugins/test/detector_sip_test.cc b/src/network_inspectors/appid/detector_plugins/test/detector_sip_test.cc
new file mode 100644 (file)
index 0000000..655acdc
--- /dev/null
@@ -0,0 +1,214 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2021-2021 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.
+//--------------------------------------------------------------------------
+
+// detector_sip_test.cc author Sreeja Athirkandathil Narayanan <sathirka@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define SIP_UNIT_TEST
+
+#include "detector_plugins/detector_sip.cc"
+#include "detector_plugins/sip_patterns.cc"
+
+#include "framework/data_bus.h"
+#include "framework/module.cc"
+#include "framework/mpse_batch.h"
+#include "network_inspectors/appid/appid_utils/sf_mlmp.cc"
+#include "protocols/protocol_ids.h"
+#include "utils/util_cstring.cc"
+
+#include "appid_inspector.h"
+#include "detector_plugins_mock.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+
+static AppIdConfig config;
+static AppIdContext context(config);
+OdpContext* AppIdContext::odp_ctxt = nullptr;
+static AppIdModule appid_mod;
+static AppIdInspector appid_inspector(appid_mod);
+static Packet pkt;
+static SfIp sfip;
+AppIdSession *session = nullptr;
+THREAD_LOCAL AppIdDebug* appidDebug;
+ClientDiscovery cdm;
+SipUdpClientDetector cd(&cdm);
+ClientSIPData* sip_data = nullptr;
+MpseGroup mpse_group;
+static bool prep_patterns = true;
+
+namespace snort
+{
+AppIdApi appid_api;
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
+    StashGenericObject(STASH_GENERIC_OBJECT_APPID) { }
+Flow::Flow() = default;
+Flow::~Flow() = default;
+AppIdSession* AppIdApi::get_appid_session(snort::Flow const&) { return nullptr; }
+
+MpseGroup::~MpseGroup() = default;
+SearchTool::SearchTool(const char*, bool)
+{
+    mpsegrp = &mpse_group;
+}
+void SearchTool::reload() { }
+int SearchTool::find_all(const char*, unsigned, MpseMatch, bool, void*)
+{
+    // Seg-fault will be observed if this is called without initializing pattern matchers
+    assert(mpsegrp);
+    return 0;
+}
+}
+
+AppIdInspector::AppIdInspector(AppIdModule&) { }
+
+bool AppIdInspector::configure(snort::SnortConfig*)
+{
+    ctxt = &context;
+    return true;
+}
+void AppIdInspector::eval(Packet*) { }
+void AppIdInspector::show(const SnortConfig*) const { }
+void AppIdInspector::tinit() { }
+void AppIdInspector::tterm() { }
+void AppIdInspector::tear_down(SnortConfig*) { }
+AppIdContext& AppIdInspector::get_ctxt() const { return *ctxt; }
+AppIdInspector::~AppIdInspector() = default;
+
+void AppIdContext::create_odp_ctxt()
+{
+    odp_ctxt = new OdpContext(config, nullptr);
+}
+
+void AppIdContext::pterm() { delete odp_ctxt; }
+
+void OdpContext::initialize(AppIdInspector&)
+{
+    sip_matchers.finalize_patterns(*this);
+}
+
+void SipPatternMatchers::finalize_patterns(OdpContext&)
+{
+    sip_ua_matcher = mlmpCreate();
+    sip_server_matcher = mlmpCreate();
+
+    if (prep_patterns)
+    {
+        mlmpProcessPatterns(sip_ua_matcher);
+        mlmpProcessPatterns(sip_server_matcher);
+    }
+}
+
+AppIdSession* AppIdSession::allocate_session(snort::Packet const*, IpProtocol,
+    AppidSessionDirection, AppIdInspector&, OdpContext& odp_ctxt)
+{
+    session = new AppIdSession(IpProtocol::IP, &sfip, 0, appid_inspector, odp_ctxt);
+    return session;
+}
+
+void AppIdSession::publish_appid_event(AppidChangeBits&, const Packet&, bool, uint32_t) { }
+AppIdDiscovery::~AppIdDiscovery() = default;
+void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection,
+    AppId, AppidChangeBits&) { }
+void ClientDiscovery::initialize(AppIdInspector&) { }
+void ClientDiscovery::reload() { }
+void AppIdDiscovery::register_detector(const string&, AppIdDetector*, IpProtocol) { }
+void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool&, int,
+    unsigned char const*, unsigned int, unsigned int) { }
+void AppIdDiscovery::register_tcp_pattern(AppIdDetector*, unsigned char const*, unsigned int,
+    int, unsigned int) { }
+void AppIdDiscovery::register_udp_pattern(AppIdDetector*, unsigned char const*, unsigned int,
+    int, unsigned int) { }
+int AppIdDiscovery::add_service_port(AppIdDetector*, ServiceDetectorPort const&) { return 0; }
+void AppIdModule::reset_stats() {}
+DnsPatternMatchers::~DnsPatternMatchers() = default;
+SslPatternMatchers::~SslPatternMatchers() = default;
+HttpPatternMatchers::~HttpPatternMatchers() = default;
+
+ClientDetector::ClientDetector() { }
+void ClientDetector::register_appid(int, unsigned int, OdpContext&) { }
+int AppIdDetector::initialize(AppIdInspector&) { return 1; }
+void AppIdDetector::reload() { }
+int AppIdDetector::data_add(AppIdSession&, void*, void (*)(void*)) { return 1; }
+void AppIdDetector::add_user(AppIdSession&, char const*, int, bool, AppidChangeBits&) { }
+void AppIdDetector::add_payload(AppIdSession&, int) { }
+void AppIdDetector::add_app(snort::Packet const&, AppIdSession&, AppidSessionDirection, int,
+    int, char const*, AppidChangeBits&) { }
+void memory::MemoryCap::update_deallocations(size_t) { }
+
+SipEvent::SipEvent(snort::Packet const* p, SIPMsg const*, SIP_DialogData const*) { this->p = p; }
+SipEvent::~SipEvent() = default;
+bool SipEvent::is_invite() const { return false; }
+bool SipEvent::is_dialog_established() const { return false; }
+int SipPatternMatchers::get_client_from_ua(char const*, unsigned int, int&, char*&) { return 0; }
+void SipEventHandler::service_handler(SipEvent&, AppIdSession&, AppidChangeBits&) { }
+SipUdpClientDetector* SipEventHandler::client = &cd;
+
+void* AppIdDetector::data_get(AppIdSession&)
+{
+    sip_data = new ClientSIPData();
+    sip_data->from = "<sip:1001@51.1.1.130:11810>";
+    return (void*)sip_data;
+}
+
+TEST_GROUP(detector_sip_tests)
+{
+    void setup() override
+    {
+        appid_inspector.configure(nullptr);
+    }
+    void teardown() override
+    {
+        delete session;
+        delete sip_data;
+        context.pterm();
+    }
+};
+
+TEST(detector_sip_tests, sip_event_handler)
+{
+    context.create_odp_ctxt();
+    OdpContext* odpctxt = pkt_thread_odp_ctxt = &context.get_odp_ctxt();
+
+    odpctxt->initialize(appid_inspector);
+    SipEvent event(&pkt, nullptr, nullptr);
+    SipEventHandler event_handler(appid_inspector);
+    Flow* flow = new Flow();
+    event_handler.handle(event, flow);
+    delete sip_data;
+    delete session;
+
+    // Create and assign new ODP context to appid inspector without finalizing SIP patterns
+    context.create_odp_ctxt();
+    prep_patterns = false;
+    context.get_odp_ctxt().initialize(appid_inspector);
+    event_handler.handle(event, flow);
+    delete flow;
+    delete odpctxt;
+    prep_patterns = true;
+}
+
+int main(int argc, char** argv)
+{
+    int return_value = CommandLineTestRunner::RunAllTests(argc, argv);
+    return return_value;
+}
index 1fd904032fd788cfc4a400748de9149773554001..488b3d7fe1eb99670e3121c0297ce62eee24dc0c 100644 (file)
@@ -63,7 +63,18 @@ namespace snort
 {
 AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
     StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+SearchTool::SearchTool(const char*, bool) { }
 void SearchTool::reload() { }
+static bool test_find_all_done = false;
+static bool test_find_all_enabled = false;
+static MatchedPatterns* mock_mp = nullptr;
+int SearchTool::find_all(const char*, unsigned, MpseMatch, bool, void* mp_arg)
+{
+    test_find_all_done = true;
+    if (test_find_all_enabled)
+        memcpy(mp_arg, &mock_mp, sizeof(MatchedPatterns*));
+    return 0;
+}
 }
 
 void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
@@ -79,6 +90,7 @@ DnsPatternMatchers::~DnsPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
 SslPatternMatchers::~SslPatternMatchers() = default;
 void AppIdModule::reset_stats() {}
+bool AppIdInspector::configure(snort::SnortConfig*) { return true; }
 
 TEST_GROUP(http_url_patterns_tests)
 {