From: Shravan Rangarajuvenkata (shrarang) Date: Thu, 5 Aug 2021 18:43:24 +0000 (+0000) Subject: Merge pull request #3001 in SNORT/snort3 from ~SATHIRKA/snort3:sip_odp_reload to... X-Git-Tag: 3.1.10.0~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0ed157f519d9e3a77272232b390e9585e321445;p=thirdparty%2Fsnort3.git Merge pull request #3001 in SNORT/snort3 from ~SATHIRKA/snort3:sip_odp_reload to master Squashed commit of the following: commit 2b6790982998f014959301f7665f05dc388e6996 Author: Sreeja Athirkandathil Narayanan Date: Fri Jul 16 16:34:12 2021 -0400 appid: use packet thread odp context while creating SIP session --- diff --git a/src/network_inspectors/appid/detector_plugins/detector_sip.cc b/src/network_inspectors/appid/detector_plugins/detector_sip.cc index d58afbf4a..714597ae6 100644 --- a/src/network_inspectors/appid/detector_plugins/detector_sip.cc +++ b/src/network_inspectors/appid/detector_plugins/detector_sip.cc @@ -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 diff --git a/src/network_inspectors/appid/detector_plugins/sip_patterns.cc b/src/network_inspectors/appid/detector_plugins/sip_patterns.cc index 3f102e7ba..e990f6669 100644 --- a/src/network_inspectors/appid/detector_plugins/sip_patterns.cc +++ b/src/network_inspectors/appid/detector_plugins/sip_patterns.cc @@ -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) diff --git a/src/network_inspectors/appid/detector_plugins/test/CMakeLists.txt b/src/network_inspectors/appid/detector_plugins/test/CMakeLists.txt index 85b7f325c..5b63a4ff5 100644 --- a/src/network_inspectors/appid/detector_plugins/test/CMakeLists.txt +++ b/src/network_inspectors/appid/detector_plugins/test/CMakeLists.txt @@ -5,3 +5,4 @@ add_cpputest( detector_smtp_test ) add_cpputest( http_url_patterns_test ) +add_cpputest( detector_sip_test ) diff --git a/src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h b/src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h index 8784677d7..cf2cd4551 100644 --- a/src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h +++ b/src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h @@ -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 index 000000000..655acdcfa --- /dev/null +++ b/src/network_inspectors/appid/detector_plugins/test/detector_sip_test.cc @@ -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 + +#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 +#include +#include + +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 = ""; + 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; +} diff --git a/src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc b/src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc index 1fd904032..488b3d7fe 100644 --- a/src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc +++ b/src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc @@ -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) {