From: Mike Stepanek (mstepane) Date: Wed, 12 Feb 2020 15:09:12 +0000 (+0000) Subject: Merge pull request #1969 in SNORT/snort3 from ~SHRARANG/snort3:appid_odp_ctxt_3 to... X-Git-Tag: 3.0.0-268~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6d462b6b2e603742fd87b2569a78813affb37466;p=thirdparty%2Fsnort3.git Merge pull request #1969 in SNORT/snort3 from ~SHRARANG/snort3:appid_odp_ctxt_3 to master Squashed commit of the following: commit dd1d2a4f13e9f73f8406fa6530b1f9ab5dcc4acc Author: Shravan Rangaraju Date: Tue Jan 28 22:18:16 2020 -0500 appid: move dns, sip, ssl and http pattern matchers to odp context; move client discovery manager to odp context --- diff --git a/src/network_inspectors/appid/CMakeLists.txt b/src/network_inspectors/appid/CMakeLists.txt index 58124aa79..0fa1e1d6e 100644 --- a/src/network_inspectors/appid/CMakeLists.txt +++ b/src/network_inspectors/appid/CMakeLists.txt @@ -130,8 +130,14 @@ set ( DP_APPID_SOURCES detector_plugins/detector_sip.h detector_plugins/detector_smtp.cc detector_plugins/detector_smtp.h + detector_plugins/dns_patterns.cc + detector_plugins/dns_patterns.h detector_plugins/http_url_patterns.cc detector_plugins/http_url_patterns.h + detector_plugins/sip_patterns.cc + detector_plugins/sip_patterns.h + detector_plugins/ssl_patterns.cc + detector_plugins/ssl_patterns.h ) set ( UTIL_APPID_SOURCES diff --git a/src/network_inspectors/appid/appid_api.cc b/src/network_inspectors/appid/appid_api.cc index e801e8c28..03091f0af 100644 --- a/src/network_inspectors/appid/appid_api.cc +++ b/src/network_inspectors/appid/appid_api.cc @@ -28,6 +28,7 @@ #include "managers/inspector_manager.h" #include "utils/util.h" +#include "appid_inspector.h" #include "appid_module.h" #include "appid_session.h" #include "appid_session_api.h" @@ -187,27 +188,49 @@ uint32_t AppIdApi::consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t, IpP return sizeof(*appHA); } -bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name, const char* common_name, AppId& service_id, AppId& client_id, AppId& payload_id) +bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name, const char* common_name, + AppId& service_id, AppId& client_id, AppId& payload_id) { - AppIdSession* asd; + AppIdSession* asd = nullptr; service_id = APP_ID_NONE; client_id = APP_ID_NONE; payload_id = APP_ID_NONE; - if (common_name) - ssl_scan_cname((const uint8_t*)common_name, strlen(common_name), client_id, payload_id); + if (flow) + asd = get_appid_session(*flow); - if (server_name) - ssl_scan_hostname((const uint8_t*)server_name, strlen(server_name), client_id, payload_id); - - if (flow and (asd = get_appid_session(*flow))) + if (asd) { + SslPatternMatchers& ssl_matchers = asd->ctxt.get_odp_ctxt().get_ssl_matchers(); + if (common_name) + ssl_matchers.scan_cname((const uint8_t*)common_name, strlen(common_name), client_id, + payload_id); + + if (server_name) + ssl_matchers.scan_hostname((const uint8_t*)server_name, strlen(server_name), client_id, + payload_id); + service_id = asd->get_application_ids_service(); if (client_id == APP_ID_NONE) client_id = asd->get_application_ids_client(); if (payload_id == APP_ID_NONE) payload_id = asd->get_application_ids_payload(); } + else + { + AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true); + if (inspector) + { + SslPatternMatchers& ssl_matchers = inspector->get_ctxt().get_odp_ctxt().get_ssl_matchers(); + if (common_name) + ssl_matchers.scan_cname((const uint8_t*)common_name, strlen(common_name), client_id, + payload_id); + + if (server_name) + ssl_matchers.scan_hostname((const uint8_t*)server_name, strlen(server_name), + client_id, payload_id); + } + } if (service_id != APP_ID_NONE or client_id != APP_ID_NONE or payload_id != APP_ID_NONE) { diff --git a/src/network_inspectors/appid/appid_config.cc b/src/network_inspectors/appid/appid_config.cc index c8561deff..1a0920b37 100644 --- a/src/network_inspectors/appid/appid_config.cc +++ b/src/network_inspectors/appid/appid_config.cc @@ -74,11 +74,6 @@ AppIdConfig::~AppIdConfig() snort_free((void*)app_detector_dir); } -// FIXIT-M: RELOAD - move initialization back to AppIdContext class constructor -std::array AppIdContext::tcp_port_only = {APP_ID_NONE}; -std::array AppIdContext::udp_port_only = {APP_ID_NONE}; -std::array AppIdContext::ip_protocol = {APP_ID_NONE}; - void AppIdContext::pterm() { assert(odp_ctxt); @@ -97,15 +92,19 @@ bool AppIdContext::init_appid(SnortConfig* sc) static bool once = false; if (!once) { - HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance(); AppIdDiscovery::initialize_plugins(); + odp_ctxt->get_client_disco_mgr().initialize(); LuaDetectorManager::initialize(*this, 1); PatternServiceDetector::finalize_service_port_patterns(); PatternClientDetector::finalize_client_port_patterns(); AppIdDiscovery::finalize_plugins(); - http_matchers->finalize_patterns(); - ssl_detector_process_patterns(); - dns_host_detector_process_patterns(); + odp_ctxt->get_client_disco_mgr().finalize_client_plugins(); + odp_ctxt->get_http_matchers().finalize_patterns(); + // sip patterns need to be finalized after http patterns because they + // are dependent on http patterns + odp_ctxt->get_sip_matchers().finalize_patterns(*odp_ctxt); + odp_ctxt->get_ssl_matchers().finalize_patterns(); + odp_ctxt->get_dns_matchers().finalize_patterns(); once = true; } @@ -122,30 +121,51 @@ void AppIdContext::create_tp_appid_ctxt() tp_appid_ctxt = TPLibHandler::create_tp_appid_ctxt(config, *odp_ctxt); } -AppId AppIdContext::get_port_service_id(IpProtocol proto, uint16_t port) +void AppIdContext::show() +{ + if (!config.tp_appid_path.empty()) + LogMessage(" 3rd Party Dir: %s\n", config.tp_appid_path.c_str()); +} + +OdpContext::OdpContext(AppIdConfig& config, SnortConfig* sc) +{ + app_info_mgr.init_appid_info_table(config, sc, *this); +} + +void OdpContext::add_port_service_id(IpProtocol proto, uint16_t port, AppId appid) +{ + if (proto == IpProtocol::TCP) + tcp_port_only[port] = appid; + else if (proto == IpProtocol::UDP) + udp_port_only[port] = appid; + else + ErrorMessage("appid: invalid port service for proto %d port %d app %d\n", + static_cast(proto), port, appid); +} + +void OdpContext::add_protocol_service_id(IpProtocol proto, AppId appid) +{ + ip_protocol[static_cast(proto)] = appid; +} + +AppId OdpContext::get_port_service_id(IpProtocol proto, uint16_t port) { AppId appId; if (proto == IpProtocol::TCP) - appId = tcp_port_only[port]; + appId = tcp_port_only[port]; else appId = udp_port_only[port]; return appId; } -AppId AppIdContext::get_protocol_service_id(IpProtocol proto) +AppId OdpContext::get_protocol_service_id(IpProtocol proto) { return ip_protocol[(uint16_t)proto]; } -void AppIdContext::show() -{ - if (!config.tp_appid_path.empty()) - LogMessage(" 3rd Party Dir: %s\n", config.tp_appid_path.c_str()); -} - -void AppIdContext::display_port_config() +void OdpContext::display_port_config() { bool first = true; @@ -172,8 +192,3 @@ void AppIdContext::display_port_config() LogMessage(" %5u - %u\n", i, udp_port_only[i]); } } - -OdpContext::OdpContext(AppIdConfig& config, SnortConfig* sc) -{ - app_info_mgr.init_appid_info_table(config, sc, *this); -} diff --git a/src/network_inspectors/appid/appid_config.h b/src/network_inspectors/appid/appid_config.h index 80d92f71c..e15dce880 100644 --- a/src/network_inspectors/appid/appid_config.h +++ b/src/network_inspectors/appid/appid_config.h @@ -36,13 +36,17 @@ #include "application_ids.h" #include "app_info_table.h" +#include "client_plugins/client_discovery.h" +#include "detector_plugins/dns_patterns.h" +#include "detector_plugins/http_url_patterns.h" +#include "detector_plugins/sip_patterns.h" +#include "detector_plugins/ssl_patterns.h" #include "host_port_app_cache.h" #include "length_app_cache.h" #define APP_ID_PORT_ARRAY_SIZE 65536 class AppIdInspector; -class AppInfoManager; extern SnortProtocolId snortId_for_unsynchronized; extern SnortProtocolId snortId_for_ftp_data; @@ -102,6 +106,16 @@ public: OdpContext(AppIdConfig&, snort::SnortConfig*); + AppInfoManager& get_app_info_mgr() + { + return app_info_mgr; + } + + ClientDiscovery& get_client_disco_mgr() + { + return client_disco_mgr; + } + HostPortVal* host_port_cache_find(const snort::SfIp* ip, uint16_t port, IpProtocol proto) { return host_port_cache.find(ip, port, proto, *this); @@ -122,15 +136,45 @@ public: return length_cache.add(key, val); } - AppInfoManager& get_app_info_mgr() + DnsPatternMatchers& get_dns_matchers() { - return app_info_mgr; + return dns_matchers; + } + + HttpPatternMatchers& get_http_matchers() + { + return http_matchers; + } + + SipPatternMatchers& get_sip_matchers() + { + return sip_matchers; } + SslPatternMatchers& get_ssl_matchers() + { + return ssl_matchers; + } + + void add_port_service_id(IpProtocol, uint16_t, AppId); + void add_protocol_service_id(IpProtocol, AppId); + AppId get_port_service_id(IpProtocol, uint16_t); + AppId get_protocol_service_id(IpProtocol); + void display_port_config(); + private: + AppInfoManager app_info_mgr; + ClientDiscovery client_disco_mgr; HostPortCache host_port_cache; LengthCache length_cache; - AppInfoManager app_info_mgr; + DnsPatternMatchers dns_matchers; + HttpPatternMatchers http_matchers; + SipPatternMatchers sip_matchers; + SslPatternMatchers ssl_matchers; + + std::array tcp_port_only = {APP_ID_NONE}; // port-only TCP services + std::array udp_port_only = {APP_ID_NONE}; // port-only UDP services + std::array ip_protocol = {APP_ID_NONE}; // non-TCP / UDP protocol services }; class AppIdContext @@ -157,20 +201,10 @@ public: bool init_appid(snort::SnortConfig*); static void pterm(); void show(); - AppId get_port_service_id(IpProtocol, uint16_t port); - AppId get_protocol_service_id(IpProtocol); - - unsigned max_service_info = 0; - - //FIXIT-L remove static when reload is supported (once flag removed) - static std::array tcp_port_only; // port-only TCP services - static std::array udp_port_only; // port-only UDP services - static std::array ip_protocol; // non-TCP / UDP protocol services AppIdConfig& config; private: - void display_port_config(); static OdpContext* odp_ctxt; static ThirdPartyAppIdContext* tp_appid_ctxt; }; diff --git a/src/network_inspectors/appid/appid_detector.cc b/src/network_inspectors/appid/appid_detector.cc index 5659ad573..465a0a4b7 100644 --- a/src/network_inspectors/appid/appid_detector.cc +++ b/src/network_inspectors/appid/appid_detector.cc @@ -52,7 +52,7 @@ int AppIdDetector::initialize() AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true); AppIdContext& ctxt = inspector->get_ctxt(); for (auto& id : appid_registry) - register_appid(id.appId, id.additionalInfo, ctxt.get_odp_ctxt()); + register_appid(id.appId, id.additionalInfo, ctxt.get_odp_ctxt()); } if (!service_ports.empty()) diff --git a/src/network_inspectors/appid/appid_detector.h b/src/network_inspectors/appid/appid_detector.h index d5e2a0816..617f98492 100644 --- a/src/network_inspectors/appid/appid_detector.h +++ b/src/network_inspectors/appid/appid_detector.h @@ -132,7 +132,6 @@ public: asd.client.set_id(client_id); } virtual void add_app(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppId, const char*, AppidChangeBits&); - virtual void finalize_patterns() {} const char* get_code_string(APPID_STATUS_CODE) const; const std::string& get_name() const diff --git a/src/network_inspectors/appid/appid_discovery.cc b/src/network_inspectors/appid/appid_discovery.cc index c747b8083..e06040af8 100644 --- a/src/network_inspectors/appid/appid_discovery.cc +++ b/src/network_inspectors/appid/appid_discovery.cc @@ -75,24 +75,21 @@ AppIdDiscovery::~AppIdDiscovery() void AppIdDiscovery::initialize_plugins() { ServiceDiscovery::get_instance(); - ClientDiscovery::get_instance(); } void AppIdDiscovery::finalize_plugins() { ServiceDiscovery::get_instance().finalize_service_patterns(); - ClientDiscovery::get_instance().finalize_client_plugins(); } void AppIdDiscovery::release_plugins() { ServiceDiscovery::release_instance(); - ClientDiscovery::release_instance(); } void AppIdDiscovery::tterm() { - ClientDiscovery::get_instance().release_thread_resources(); + ClientDiscovery::release_thread_resources(); ServiceDiscovery::get_instance().release_thread_resources(); } @@ -268,7 +265,7 @@ static bool is_packet_ignored(AppIdSession* asd, Packet* p, AppidSessionDirectio AppIdHttpSession* hsession = asd->get_http_session(); if ( direction == APP_ID_FROM_INITIATOR && hsession && hsession->is_rebuilt_offsets() ) { - HttpPatternMatchers::get_instance()->get_http_offsets(p, hsession); + asd->ctxt.get_odp_ctxt().get_http_matchers().get_http_offsets(p, hsession); if (appidDebug->is_active()) { uint16_t uri_start, uri_end, cookie_start, cookie_end; @@ -648,7 +645,7 @@ void AppIdDiscovery::do_port_based_discovery(Packet* p, AppIdSession& asd, IpPro return; } - AppId id = asd.ctxt.get_port_service_id(protocol, p->ptrs.sp); + AppId id = asd.ctxt.get_odp_ctxt().get_port_service_id(protocol, p->ptrs.sp); if (id > APP_ID_NONE) { asd.service.set_port_service_id(id); @@ -746,7 +743,7 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd, auto ht = host_cache.find(*ip); if (ht) { - AppId appid = ht->get_appid(port, protocol, true, asd.ctxt.get_odp_ctxt().allow_port_wildcard_host_cache); + AppId appid = ht->get_appid(port, protocol, true, asd.ctxt.get_odp_ctxt().allow_port_wildcard_host_cache); if (appid > APP_ID_NONE) { // FIXIT-L: Make this more generic to support service and payload IDs @@ -787,7 +784,7 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, { if ( !asd.get_session_flags(APPID_SESSION_PORT_SERVICE_DONE) ) { - AppId id = asd.ctxt.get_protocol_service_id(protocol); + AppId id = asd.ctxt.get_odp_ctxt().get_protocol_service_id(protocol); if (id > APP_ID_NONE) { asd.service.set_port_service_id(id); @@ -839,8 +836,8 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, is_discovery_done = ServiceDiscovery::get_instance().do_service_discovery(asd, p, direction, change_bits); if (asd.client_disco_state != APPID_DISCO_STATE_FINISHED) - is_discovery_done = ClientDiscovery::get_instance().do_client_discovery(asd, p, - direction, change_bits); + is_discovery_done = asd.ctxt.get_odp_ctxt().get_client_disco_mgr().do_client_discovery( + asd, p, direction, change_bits); asd.set_session_flags(APPID_SESSION_ADDITIONAL_PACKET); } diff --git a/src/network_inspectors/appid/appid_http_event_handler.cc b/src/network_inspectors/appid/appid_http_event_handler.cc index d32859b2d..8d8d3724e 100644 --- a/src/network_inspectors/appid/appid_http_event_handler.cc +++ b/src/network_inspectors/appid/appid_http_event_handler.cc @@ -127,7 +127,8 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow) asd->scan_flags |= SCAN_HTTP_VIA_FLAG; } - hsession->process_http_packet(direction, change_bits); + hsession->process_http_packet(direction, change_bits, + asd->ctxt.get_odp_ctxt().get_http_matchers()); if (asd->service.get_id() == APP_ID_HTTP) { diff --git a/src/network_inspectors/appid/appid_http_session.cc b/src/network_inspectors/appid/appid_http_session.cc index 223952aa3..ce6ba0c8d 100644 --- a/src/network_inspectors/appid/appid_http_session.cc +++ b/src/network_inspectors/appid/appid_http_session.cc @@ -54,8 +54,6 @@ static const char* httpFieldName[ NUM_HTTP_FIELDS ] = // for use in debug messag AppIdHttpSession::AppIdHttpSession(AppIdSession& asd) : asd(asd) { - http_matchers = HttpPatternMatchers::get_instance(); - for ( int i = 0; i < NUM_HTTP_FIELDS; i++) { meta_offset[i].first = 0; @@ -172,7 +170,7 @@ void AppIdHttpSession::set_tun_dest() free(url ); } -int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd) +int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd, HttpPatternMatchers& http_matchers) { CHPApp* cah = nullptr; @@ -181,7 +179,7 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd) if (cmd.buffer[i] && cmd.length[i]) { cmd.cur_ptype = (HttpFieldIds)i; - http_matchers->scan_key_chp(cmd); + http_matchers.scan_key_chp(cmd); } } @@ -271,7 +269,7 @@ void AppIdHttpSession::init_chp_match_descriptor(ChpMatchDescriptor& cmd) } } -void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits) +void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits, HttpPatternMatchers& http_matchers) { ChpMatchDescriptor cmd; @@ -281,7 +279,7 @@ void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits) if ( !chp_candidate ) { - if ( !initial_chp_sweep(cmd) ) + if ( !initial_chp_sweep(cmd, http_matchers) ) chp_finished = true; // this is a failure case. } @@ -299,7 +297,7 @@ void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits) { int num_found = 0; cmd.cur_ptype = (HttpFieldIds)i; - AppId ret = http_matchers->scan_chp(cmd, &version, &user, &num_found, this, + AppId ret = http_matchers.scan_chp(cmd, &version, &user, &num_found, this, asd.ctxt); total_found += num_found; if (!ret || num_found < ptype_req_counts[i]) @@ -438,7 +436,7 @@ void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits) } int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, - AppidChangeBits& change_bits) + AppidChangeBits& change_bits, HttpPatternMatchers& http_matchers) { AppId service_id = APP_ID_NONE; AppId client_id = APP_ID_NONE; @@ -499,7 +497,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, } if (!chp_finished || chp_hold_flow) - process_chp_buffers(change_bits); + process_chp_buffers(change_bits, http_matchers); if (!skip_simple_detect) // true if processCHP found match { @@ -518,7 +516,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, char* vendorVersion = nullptr; char* vendor = nullptr; - http_matchers->get_server_vendor_version(server->c_str(), server->size(), + http_matchers.get_server_vendor_version(server->c_str(), server->size(), &vendorVersion, &vendor, &asd.subtype); if (vendor || vendorVersion) { @@ -557,7 +555,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, { char* version = nullptr; - http_matchers->identify_user_agent(useragent->c_str(), useragent->size(), + http_matchers.identify_user_agent(useragent->c_str(), useragent->size(), service_id, client_id, &version); if (appidDebug->is_active()) { @@ -586,7 +584,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, const std::string* via = meta_data[MISC_VIA_FID]; if ( !asd.is_payload_appid_set() && (asd.scan_flags & SCAN_HTTP_VIA_FLAG) && via ) { - payload_id = http_matchers->get_appid_by_pattern(via->c_str(), via->size(), + payload_id = http_matchers.get_appid_by_pattern(via->c_str(), via->size(), nullptr); if (appidDebug->is_active() && payload_id > APP_ID_NONE && asd.payload.get_id() != payload_id) @@ -611,7 +609,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, AppId appId; char* version = nullptr; - appId = http_matchers->scan_header_x_working_with(x_working_with->c_str(), + appId = http_matchers.scan_header_x_working_with(x_working_with->c_str(), x_working_with->size(), &version); if ( appId ) { @@ -651,7 +649,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, && content_type && !asd.is_payload_appid_set()) || (!have_tp && !asd.is_payload_appid_set() && content_type) ) { - payload_id = http_matchers->get_appid_by_content_type(content_type->c_str(), + payload_id = http_matchers.get_appid_by_content_type(content_type->c_str(), content_type->size()); if (appidDebug->is_active() && payload_id > APP_ID_NONE && asd.payload.get_id() != payload_id) @@ -674,7 +672,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, const char* refStr = referer ? referer->c_str() : nullptr; const std::string* url = meta_data[MISC_URL_FID]; const char* urlStr = url ? url->c_str() : nullptr; - if ( http_matchers->get_appid_from_url(my_host, urlStr, &version, + if ( http_matchers.get_appid_from_url(my_host, urlStr, &version, refStr, &client_id, &service_id, &payload_id, &referredPayloadAppId, false, asd.ctxt.get_odp_ctxt()) ) { diff --git a/src/network_inspectors/appid/appid_http_session.h b/src/network_inspectors/appid/appid_http_session.h index c951443b0..d6ad1f61c 100644 --- a/src/network_inspectors/appid/appid_http_session.h +++ b/src/network_inspectors/appid/appid_http_session.h @@ -99,7 +99,8 @@ public: AppIdHttpSession(AppIdSession&); virtual ~AppIdHttpSession(); - int process_http_packet(AppidSessionDirection direction, AppidChangeBits& change_bits); + int process_http_packet(AppidSessionDirection direction, AppidChangeBits& change_bits, + HttpPatternMatchers& http_matchers); void update_http_xff_address(struct XffFieldValue*, uint32_t, AppidChangeBits&); void update_url(AppidChangeBits& change_bits); @@ -211,13 +212,11 @@ public: protected: void init_chp_match_descriptor(ChpMatchDescriptor& cmd); - int initial_chp_sweep(ChpMatchDescriptor&); - void process_chp_buffers(AppidChangeBits&); + int initial_chp_sweep(ChpMatchDescriptor&, HttpPatternMatchers&); + void process_chp_buffers(AppidChangeBits&, HttpPatternMatchers&); void free_chp_matches(ChpMatchDescriptor& cmd, unsigned max_matches); void set_http_change_bits(AppidChangeBits& change_bits, HttpFieldIds id); - HttpPatternMatchers* http_matchers = nullptr; - AppIdSession& asd; // FIXIT-M the meta data buffers in this array are only set from diff --git a/src/network_inspectors/appid/appid_inspector.cc b/src/network_inspectors/appid/appid_inspector.cc index 248b0f3f9..59252e68e 100644 --- a/src/network_inspectors/appid/appid_inspector.cc +++ b/src/network_inspectors/appid/appid_inspector.cc @@ -42,14 +42,11 @@ #include "appid_session.h" #include "appid_stats.h" #include "client_plugins/client_discovery.h" -#include "detector_plugins/detector_dns.h" #include "detector_plugins/detector_pattern.h" #include "detector_plugins/detector_sip.h" -#include "detector_plugins/http_url_patterns.h" #include "host_port_app_cache.h" #include "lua_detector_module.h" #include "service_plugins/service_discovery.h" -#include "service_plugins/service_ssl.h" #include "tp_appid_module_api.h" #include "tp_lib_handler.h" @@ -229,9 +226,6 @@ static void appid_inspector_pterm() appid_forecast_pterm(); LuaDetectorManager::terminate(); AppIdDiscovery::release_plugins(); - delete HttpPatternMatchers::get_instance(); - service_dns_host_clean(); - service_ssl_clean(); AppIdContext::pterm(); //end of 'FIXIT-M: RELOAD' comment above openssl_cleanup(); diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index ca1caaef1..ca03284e8 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -413,7 +413,7 @@ void AppIdSession::examine_ssl_metadata(Packet* p, AppidChangeBits& change_bits) if ((scan_flags & SCAN_SSL_HOST_FLAG) and tls_str) { size_t size = strlen(tls_str); - if ((ret = ssl_scan_hostname((const uint8_t*)tls_str, size, + if ((ret = ctxt.get_odp_ctxt().get_ssl_matchers().scan_hostname((const uint8_t*)tls_str, size, client_id, payload_id))) { if (client.get_id() == APP_ID_NONE or client.get_id() == APP_ID_SSL_CLIENT) @@ -426,7 +426,7 @@ void AppIdSession::examine_ssl_metadata(Packet* p, AppidChangeBits& change_bits) if ((scan_flags & SCAN_SSL_CERTIFICATE_FLAG) and (tls_str = tsession->get_tls_cname())) { size_t size = strlen(tls_str); - if ((ret = ssl_scan_cname((const uint8_t*)tls_str, size, + if ((ret = ctxt.get_odp_ctxt().get_ssl_matchers().scan_cname((const uint8_t*)tls_str, size, client_id, payload_id))) { if (client.get_id() == APP_ID_NONE or client.get_id() == APP_ID_SSL_CLIENT) @@ -439,7 +439,7 @@ void AppIdSession::examine_ssl_metadata(Packet* p, AppidChangeBits& change_bits) if ((tls_str = tsession->get_tls_org_unit())) { size_t size = strlen(tls_str); - if ((ret = ssl_scan_cname((const uint8_t*)tls_str, size, + if ((ret = ctxt.get_odp_ctxt().get_ssl_matchers().scan_cname((const uint8_t*)tls_str, size, client_id, payload_id))) { set_client_appid_data(client_id, change_bits); @@ -470,12 +470,12 @@ void AppIdSession::examine_rtmp_metadata(AppidChangeBits& change_bits) if (const char* url = hsession->get_cfield(MISC_URL_FID)) { - HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance(); + HttpPatternMatchers& http_matchers = ctxt.get_odp_ctxt().get_http_matchers(); const char* referer = hsession->get_cfield(REQ_REFERER_FID); - if (((http_matchers->get_appid_from_url(nullptr, url, &version, + if (((http_matchers.get_appid_from_url(nullptr, url, &version, referer, &client_id, &service_id, &payload_id, &referred_payload_id, true, ctxt.get_odp_ctxt())) || - (http_matchers->get_appid_from_url(nullptr, url, &version, + (http_matchers.get_appid_from_url(nullptr, url, &version, referer, &client_id, &service_id, &payload_id, &referred_payload_id, false, ctxt.get_odp_ctxt())))) { diff --git a/src/network_inspectors/appid/client_plugins/client_discovery.cc b/src/network_inspectors/appid/client_plugins/client_discovery.cc index dacf8dd7d..3e0d2704d 100644 --- a/src/network_inspectors/appid/client_plugins/client_discovery.cc +++ b/src/network_inspectors/appid/client_plugins/client_discovery.cc @@ -52,14 +52,8 @@ using namespace snort; #define MAX_CANDIDATE_CLIENTS 10 -ClientDiscovery* ClientDiscovery::discovery_manager = nullptr; THREAD_LOCAL ClientAppMatch* match_free_list = nullptr; -ClientDiscovery::ClientDiscovery() -{ - initialize(); -} - ClientDiscovery::~ClientDiscovery() { release_thread_resources(); @@ -75,23 +69,6 @@ void ClientDiscovery::release_thread_resources() } } -ClientDiscovery& ClientDiscovery::get_instance() -{ - if (!discovery_manager) - { - discovery_manager = new ClientDiscovery(); - } - - return *discovery_manager; -} - -void ClientDiscovery::release_instance() -{ - assert(discovery_manager); - delete discovery_manager; - discovery_manager = nullptr; - -} void ClientDiscovery::initialize() { new AimClientDetector(this); @@ -121,12 +98,6 @@ void ClientDiscovery::initialize() void ClientDiscovery::finalize_client_plugins() { - for ( auto kv : tcp_detectors ) - kv.second->finalize_patterns(); - - for ( auto kv : udp_detectors ) - kv.second->finalize_patterns(); - if ( tcp_patterns ) tcp_patterns->prep(); @@ -239,15 +210,15 @@ static void free_matched_list(ClientAppMatch** match_list) *match_list = nullptr; } -ClientAppMatch* ClientDiscovery::find_detector_candidates(const Packet* pkt, IpProtocol protocol) +ClientAppMatch* ClientDiscovery::find_detector_candidates(const Packet* pkt, AppIdSession& asd) { ClientAppMatch* match_list = nullptr; SearchTool* patterns; - if (protocol == IpProtocol::TCP) - patterns = ClientDiscovery::get_instance().tcp_patterns; + if (asd.protocol == IpProtocol::TCP) + patterns = asd.ctxt.get_odp_ctxt().get_client_disco_mgr().tcp_patterns; else - patterns = ClientDiscovery::get_instance().udp_patterns; + patterns = asd.ctxt.get_odp_ctxt().get_client_disco_mgr().udp_patterns; if ( patterns ) patterns->find_all((const char*)pkt->data, pkt->dsize, &pattern_match, false, (void*)&match_list); @@ -262,7 +233,7 @@ void ClientDiscovery::create_detector_candidates_list(AppIdSession& asd, Packet* if ( !p->dsize || asd.client_detector != nullptr || !asd.client_candidates.empty() ) return; - match_list = find_detector_candidates(p, asd.protocol); + match_list = find_detector_candidates(p, asd); while ( asd.client_candidates.size() < MAX_CANDIDATE_CLIENTS ) { ClientDetector* cd = const_cast(get_next_detector(&match_list)); diff --git a/src/network_inspectors/appid/client_plugins/client_discovery.h b/src/network_inspectors/appid/client_plugins/client_discovery.h index 880aae273..6e8198668 100644 --- a/src/network_inspectors/appid/client_plugins/client_discovery.h +++ b/src/network_inspectors/appid/client_plugins/client_discovery.h @@ -45,23 +45,20 @@ class ClientDiscovery : public AppIdDiscovery { public: ~ClientDiscovery() override; - static ClientDiscovery& get_instance(); + void initialize() override; static void release_instance(); void finalize_client_plugins(); - void release_thread_resources(); + static void release_thread_resources(); bool do_client_discovery(AppIdSession&, snort::Packet*, AppidSessionDirection direction, AppidChangeBits& change_bits); private: - ClientDiscovery(); - void initialize() override; void exec_client_detectors(AppIdSession&, snort::Packet*, AppidSessionDirection direction, AppidChangeBits& change_bits); - ClientAppMatch* find_detector_candidates(const snort::Packet* pkt, IpProtocol); + ClientAppMatch* find_detector_candidates(const snort::Packet* pkt, AppIdSession&); void create_detector_candidates_list(AppIdSession&, snort::Packet*); int get_detector_candidates_list(AppIdSession&, snort::Packet*, AppidSessionDirection direction); - static ClientDiscovery* discovery_manager; }; #endif diff --git a/src/network_inspectors/appid/detector_plugins/detector_dns.cc b/src/network_inspectors/appid/detector_plugins/detector_dns.cc index e8f26d81b..7e14aeda8 100644 --- a/src/network_inspectors/appid/detector_plugins/detector_dns.cc +++ b/src/network_inspectors/appid/detector_plugins/detector_dns.cc @@ -139,79 +139,6 @@ struct ServiceDNSData uint16_t id; }; -// DNS host pattern structure -struct DNSHostPattern -{ - uint8_t type; - AppId appId; - uint8_t* pattern; - int pattern_size; -}; - -struct DetectorDNSHostPattern -{ - DNSHostPattern* dpattern; - DetectorDNSHostPattern* next; -}; - -struct MatchedDNSPatterns -{ - DNSHostPattern* mpattern; - MatchedDNSPatterns* next; -}; - -struct ServiceDnsConfig -{ - DetectorDNSHostPattern* DetectorDNSHostPatternList; - SearchTool* dns_host_host_matcher; -}; -static ServiceDnsConfig serviceDnsConfig; // DNS service configuration - -static int dns_host_pattern_match(void* id, void*, int, void* data, void*) -{ - MatchedDNSPatterns* cm; - MatchedDNSPatterns** matches = (MatchedDNSPatterns**)data; - DNSHostPattern* target = (DNSHostPattern*)id; - - cm = (MatchedDNSPatterns*)snort_calloc(sizeof(MatchedDNSPatterns)); - cm->mpattern = target; - cm->next = *matches; - *matches = cm; - - return 0; -} - -static int dns_host_detector_create_matcher(DetectorDNSHostPattern* list) -{ - DetectorDNSHostPattern* element = nullptr; - - if (serviceDnsConfig.dns_host_host_matcher) - delete serviceDnsConfig.dns_host_host_matcher; - - serviceDnsConfig.dns_host_host_matcher = new SearchTool("ac_full", true); - if (!serviceDnsConfig.dns_host_host_matcher) - return 0; - - /* Add patterns from Lua API */ - for (element = list; element; element = element->next) - { - serviceDnsConfig.dns_host_host_matcher->add((char*)element->dpattern->pattern, - element->dpattern->pattern_size, element->dpattern, true); - } - - serviceDnsConfig.dns_host_host_matcher->prep(); - - return 1; -} - -int dns_host_detector_process_patterns() -{ - int retVal = 1; - if (!dns_host_detector_create_matcher(serviceDnsConfig.DetectorDNSHostPatternList)) - retVal = 0; - return retVal; -} - DnsTcpServiceDetector::DnsTcpServiceDetector(ServiceDiscovery* sd) { handler = sd; @@ -760,121 +687,6 @@ inprocess: return APPID_INPROCESS; } -static int dns_host_scan_patterns(SearchTool* matcher, const uint8_t* pattern, size_t size, - AppId* ClientAppId, AppId* payloadId) -{ - MatchedDNSPatterns* mp = nullptr; - MatchedDNSPatterns* tmpMp; - DNSHostPattern* best_match; - - if (!matcher) - return 0; - - matcher->find_all((const char*)pattern, size, dns_host_pattern_match, false, &mp); - - if (!mp) - return 0; - - best_match = mp->mpattern; - tmpMp = mp->next; - snort_free(mp); - - while ((mp = tmpMp)) - { - tmpMp = mp->next; - if (mp->mpattern->pattern_size > best_match->pattern_size) - { - best_match = mp->mpattern; - } - snort_free(mp); - } - - switch (best_match->type) - { - // type 0 means WEB APP - case 0: - *ClientAppId = APP_ID_DNS; - *payloadId = best_match->appId; - break; - // type 1 means CLIENT - case 1: - *ClientAppId = best_match->appId; - *payloadId = 0; - break; - default: - return 0; - } - - return 1; -} - -int dns_host_scan_hostname(const uint8_t* pattern, size_t size, AppId* ClientAppId, - AppId* payloadId) -{ - return dns_host_scan_patterns(serviceDnsConfig.dns_host_host_matcher, pattern, size, - ClientAppId, payloadId); -} - -void service_dns_host_clean() -{ - dns_detector_free_patterns(); - - if (serviceDnsConfig.dns_host_host_matcher ) - { - delete serviceDnsConfig.dns_host_host_matcher; - serviceDnsConfig.dns_host_host_matcher = nullptr; - } -} - -static int dns_add_pattern(DetectorDNSHostPattern** list, uint8_t* pattern_str, size_t - pattern_size, uint8_t type, AppId app_id) -{ - DetectorDNSHostPattern* new_dns_host_pattern; - - new_dns_host_pattern = static_cast(snort_calloc( - sizeof(DetectorDNSHostPattern))); - new_dns_host_pattern->dpattern = static_cast(snort_calloc( - sizeof(DNSHostPattern))); - - new_dns_host_pattern->dpattern->type = type; - new_dns_host_pattern->dpattern->appId = app_id; - new_dns_host_pattern->dpattern->pattern = pattern_str; - new_dns_host_pattern->dpattern->pattern_size = pattern_size; - - new_dns_host_pattern->next = *list; - *list = new_dns_host_pattern; - - return 1; -} - -int dns_add_host_pattern(uint8_t* pattern_str, size_t pattern_size, uint8_t type, AppId app_id) -{ - return dns_add_pattern(&serviceDnsConfig.DetectorDNSHostPatternList, pattern_str, pattern_size, - type, app_id); -} - -static void dns_patterns_free(DetectorDNSHostPattern** list) -{ - DetectorDNSHostPattern* tmp_pattern; - - while ((tmp_pattern = *list)) - { - *list = tmp_pattern->next; - if (tmp_pattern->dpattern) - { - if (tmp_pattern->dpattern->pattern) - snort_free(tmp_pattern->dpattern->pattern); - snort_free (tmp_pattern->dpattern); - } - snort_free(tmp_pattern); - } -} - -void dns_detector_free_patterns() -{ - dns_patterns_free(&serviceDnsConfig.DetectorDNSHostPatternList); -} - char* dns_parse_host(const uint8_t* host, uint8_t host_len) { char* str = static_cast(snort_calloc(host_len + 1)); // plus '\0' at end @@ -905,4 +717,3 @@ char* dns_parse_host(const uint8_t* host, uint8_t host_len) str[host_len] = '\0'; // nullptr term return str; } - diff --git a/src/network_inspectors/appid/detector_plugins/detector_dns.h b/src/network_inspectors/appid/detector_plugins/detector_dns.h index 450d3ae21..c623c71f3 100644 --- a/src/network_inspectors/appid/detector_plugins/detector_dns.h +++ b/src/network_inspectors/appid/detector_plugins/detector_dns.h @@ -24,11 +24,6 @@ #include "service_plugins/service_detector.h" -int dns_host_scan_hostname(const uint8_t*, size_t, AppId*, AppId*); -void service_dns_host_clean(); -int dns_host_detector_process_patterns(); -int dns_add_host_pattern(uint8_t*, size_t, uint8_t, AppId); -void dns_detector_free_patterns(); char* dns_parse_host(const uint8_t* host, uint8_t host_len); struct DNSHeader; diff --git a/src/network_inspectors/appid/detector_plugins/detector_sip.cc b/src/network_inspectors/appid/detector_plugins/detector_sip.cc index 36de1dd50..3f8a6be45 100644 --- a/src/network_inspectors/appid/detector_plugins/detector_sip.cc +++ b/src/network_inspectors/appid/detector_plugins/detector_sip.cc @@ -79,55 +79,6 @@ struct ClientSIPData std::string from; }; -struct DetectorSipConfig -{ - void* sip_ua_matcher; - DetectorAppSipPattern* sip_ua_list; - void* sip_server_matcher; - DetectorAppSipPattern* sip_server_list; -}; - -static DetectorSipConfig detector_sip_config; - -static void clean_sip_ua() -{ - DetectorAppSipPattern* node; - - if ( detector_sip_config.sip_ua_matcher ) - { - mlmpDestroy((tMlmpTree*)detector_sip_config.sip_ua_matcher); - detector_sip_config.sip_ua_matcher = nullptr; - } - - for ( node = detector_sip_config.sip_ua_list; node; node = detector_sip_config.sip_ua_list ) - { - detector_sip_config.sip_ua_list = node->next; - snort_free((void*)node->pattern.pattern); - snort_free(node->userData.clientVersion); - snort_free(node); - } -} - -static void clean_sip_server() -{ - DetectorAppSipPattern* node; - - if ( detector_sip_config.sip_server_matcher ) - { - mlmpDestroy((tMlmpTree*)detector_sip_config.sip_server_matcher); - detector_sip_config.sip_server_matcher = nullptr; - } - - for ( node = detector_sip_config.sip_server_list; node; node = - detector_sip_config.sip_server_list ) - { - detector_sip_config.sip_server_list = node->next; - snort_free((void*)node->pattern.pattern); - snort_free(node->userData.clientVersion); - snort_free(node); - } -} - static void clientDataFree(void* data) { delete (ClientSIPData*)data; @@ -162,15 +113,6 @@ SipUdpClientDetector::SipUdpClientDetector(ClientDiscovery* cdm) handler->register_detector(name, this, proto); } -SipUdpClientDetector::~SipUdpClientDetector() -{ - if (detector_sip_config.sip_ua_matcher) - clean_sip_ua(); - - if (detector_sip_config.sip_server_matcher) - clean_sip_server(); -} - int SipUdpClientDetector::validate(AppIdDiscoveryArgs& args) { ClientSIPData* fd = (ClientSIPData*)data_get(args.asd); @@ -234,100 +176,6 @@ struct ServiceSIPData char vendor[MAX_VENDOR_SIZE]; }; -static int sipAppAddPattern(DetectorAppSipPattern** patternList, AppId ClientAppId, - const char* clientVersion, const char* serverPattern) -{ - /* Allocate memory for data structures */ - DetectorAppSipPattern* pattern = (DetectorAppSipPattern*)snort_calloc( - sizeof(DetectorAppSipPattern)); - pattern->userData.ClientAppId = ClientAppId; - pattern->userData.clientVersion = snort_strdup(clientVersion); - pattern->pattern.pattern = (uint8_t*)snort_strdup(serverPattern); - pattern->pattern.patternSize = (int)strlen(serverPattern); - pattern->next = *patternList; - *patternList = pattern; - - return 0; -} - -int SipUdpClientDetector::sipUaPatternAdd(AppId ClientAppId, const char* clientVersion, const - char* pattern) -{ - return sipAppAddPattern(&detector_sip_config.sip_ua_list, ClientAppId, clientVersion, pattern); -} - -int SipUdpClientDetector::sipServerPatternAdd(AppId ClientAppId, const char* clientVersion, const - char* pattern) -{ - return sipAppAddPattern(&detector_sip_config.sip_server_list, ClientAppId, clientVersion, - pattern); -} - -void SipUdpClientDetector::finalize_patterns() -{ - int num_patterns; - DetectorAppSipPattern* patternNode; - - detector_sip_config.sip_ua_matcher = mlmpCreate(); - if ( !detector_sip_config.sip_ua_matcher ) - return; - - detector_sip_config.sip_server_matcher = mlmpCreate(); - if ( !detector_sip_config.sip_server_matcher ) - { - mlmpDestroy((tMlmpTree*)detector_sip_config.sip_ua_matcher); - detector_sip_config.sip_ua_matcher = nullptr; - return; - } - - for ( patternNode = detector_sip_config.sip_ua_list; patternNode; patternNode = - patternNode->next ) - { - num_patterns = HttpPatternMatchers::get_instance()->parse_multiple_http_patterns( - (const char*)patternNode->pattern.pattern, patterns, PATTERN_PART_MAX, 0); - patterns[num_patterns].pattern = nullptr; - - mlmpAddPattern((tMlmpTree*)detector_sip_config.sip_ua_matcher, patterns, patternNode); - } - - for ( patternNode = detector_sip_config.sip_server_list; patternNode; patternNode = - patternNode->next ) - { - num_patterns = HttpPatternMatchers::get_instance()->parse_multiple_http_patterns( - (const char*)patternNode->pattern.pattern, patterns, PATTERN_PART_MAX, 0); - patterns[num_patterns].pattern = nullptr; - - mlmpAddPattern((tMlmpTree*)detector_sip_config.sip_server_matcher, patterns, patternNode); - } - - mlmpProcessPatterns((tMlmpTree*)detector_sip_config.sip_ua_matcher); - mlmpProcessPatterns((tMlmpTree*)detector_sip_config.sip_server_matcher); -} - -static int get_sip_client_app(void* patternMatcher, const char* pattern, uint32_t patternLen, - AppId* ClientAppId, char** clientVersion) -{ - tMlmpPattern patterns[3]; - DetectorAppSipPattern* data; - - if ( !pattern ) - return 0; - - patterns[0].pattern = (const uint8_t*)pattern; - patterns[0].patternSize = patternLen; - patterns[1].pattern = nullptr; - - data = (DetectorAppSipPattern*)mlmpMatchPatternGeneric((tMlmpTree*)patternMatcher, patterns); - - if ( !data ) - return 0; - - *ClientAppId = data->userData.ClientAppId; - *clientVersion = data->userData.clientVersion; - - return 1; -} - void SipServiceDetector::createRtpFlow(AppIdSession& asd, const Packet* pkt, const SfIp* cliIp, uint16_t cliPort, const SfIp* srvIp, uint16_t srvPort, IpProtocol protocol, int16_t app_id) { @@ -495,8 +343,8 @@ void SipEventHandler::handle(DataEvent& event, Flow* flow) void SipEventHandler::client_handler(SipEvent& sip_event, AppIdSession& asd, AppidChangeBits& change_bits) { - AppId ClientAppId = APP_ID_SIP; - char* clientVersion = nullptr; + AppId client_id = APP_ID_SIP; + char* client_version = nullptr; ClientSIPData* fd = (ClientSIPData*)client->data_get(asd); if ( !fd ) @@ -526,8 +374,8 @@ void SipEventHandler::client_handler(SipEvent& sip_event, AppIdSession& asd, if ( !fd->user_agent.empty() ) { - if ( get_sip_client_app(detector_sip_config.sip_ua_matcher, - fd->user_agent.c_str(), fd->user_agent.size(), &ClientAppId, &clientVersion) ) + if ( asd.ctxt.get_odp_ctxt().get_sip_matchers().get_client_from_ua( + fd->user_agent.c_str(), fd->user_agent.size(), client_id, client_version) ) goto success; } @@ -535,8 +383,8 @@ void SipEventHandler::client_handler(SipEvent& sip_event, AppIdSession& asd, { fd->flags |= SIP_FLAG_SERVER_CHECKED; - if ( get_sip_client_app(detector_sip_config.sip_server_matcher, - fd->from.c_str(), fd->from.size(), &ClientAppId, &clientVersion) ) + if ( asd.ctxt.get_odp_ctxt().get_sip_matchers().get_client_from_server( + fd->from.c_str(), fd->from.size(), client_id, client_version) ) goto success; } @@ -545,7 +393,7 @@ void SipEventHandler::client_handler(SipEvent& sip_event, AppIdSession& asd, success: if( !asd.is_client_detected() ) - client->add_app(asd, APP_ID_SIP, ClientAppId, clientVersion, change_bits); + client->add_app(asd, APP_ID_SIP, client_id, client_version, change_bits); if ( !fd->user_name.empty() ) client->add_user(asd, fd->user_name.c_str(), APP_ID_SIP, true); diff --git a/src/network_inspectors/appid/detector_plugins/detector_sip.h b/src/network_inspectors/appid/detector_plugins/detector_sip.h index 17bc9bb91..d4c081f67 100644 --- a/src/network_inspectors/appid/detector_plugins/detector_sip.h +++ b/src/network_inspectors/appid/detector_plugins/detector_sip.h @@ -34,38 +34,15 @@ namespace snort class Flow; } -struct SipUaUserData -{ - AppId ClientAppId; - char* clientVersion; -}; - -struct DetectorAppSipPattern -{ - tMlpPattern pattern; - SipUaUserData userData; - DetectorAppSipPattern* next; -}; - class SipEventHandler; class SipUdpClientDetector : public ClientDetector { public: SipUdpClientDetector(ClientDiscovery*); - ~SipUdpClientDetector() override; + ~SipUdpClientDetector() override { } int validate(AppIdDiscoveryArgs&) override; - - void finalize_patterns() override; - - // FIXIT-L revisit init so it's not split between static methods and constructor - static int sipUaPatternAdd(AppId, const char* clientVersion, const char* uaPattern); - static int sipServerPatternAdd(AppId, const char* clientVersion, const char* uaPattern); - -private: - static const int PATTERN_PART_MAX = 10; - tMlmpPattern patterns[PATTERN_PART_MAX]; }; class SipTcpClientDetector : public ClientDetector diff --git a/src/network_inspectors/appid/detector_plugins/dns_patterns.cc b/src/network_inspectors/appid/detector_plugins/dns_patterns.cc new file mode 100644 index 000000000..209fcbe3c --- /dev/null +++ b/src/network_inspectors/appid/detector_plugins/dns_patterns.cc @@ -0,0 +1,136 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- + +// dns_patterns.cc author Shravan Rangaraju + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "dns_patterns.h" +#include "utils/util.h" + +using namespace snort; + +void DnsPatternMatchers::add_host_pattern(uint8_t* pattern_str, size_t pattern_size, uint8_t type, AppId app_id) +{ + DnsHostPatternList* new_dns_host_pattern; + + new_dns_host_pattern = static_cast(snort_calloc( + sizeof(DnsHostPatternList))); + new_dns_host_pattern->dpattern = static_cast(snort_calloc( + sizeof(DnsHostPattern))); + + new_dns_host_pattern->dpattern->type = type; + new_dns_host_pattern->dpattern->app_id = app_id; + new_dns_host_pattern->dpattern->pattern = pattern_str; + new_dns_host_pattern->dpattern->pattern_size = pattern_size; + + new_dns_host_pattern->next = dns_host_pattern_list; + dns_host_pattern_list = new_dns_host_pattern; +} + +void DnsPatternMatchers::finalize_patterns() +{ + DnsHostPatternList* element = nullptr; + + /* Add patterns from Lua API */ + for (element = dns_host_pattern_list; element; element = element->next) + { + dns_host_matcher.add((char*)element->dpattern->pattern, + element->dpattern->pattern_size, element->dpattern, true); + } + + dns_host_matcher.prep(); +} + +DnsPatternMatchers::~DnsPatternMatchers() +{ + DnsHostPatternList* tmp_pattern; + + while ((tmp_pattern = dns_host_pattern_list)) + { + dns_host_pattern_list = tmp_pattern->next; + if (tmp_pattern->dpattern) + { + if (tmp_pattern->dpattern->pattern) + snort_free(tmp_pattern->dpattern->pattern); + snort_free (tmp_pattern->dpattern); + } + snort_free(tmp_pattern); + } +} + +static int dns_host_pattern_match(void* id, void*, int, void* data, void*) +{ + MatchedDnsPatterns* cm; + MatchedDnsPatterns** matches = (MatchedDnsPatterns**)data; + DnsHostPattern* target = (DnsHostPattern*)id; + + cm = (MatchedDnsPatterns*)snort_calloc(sizeof(MatchedDnsPatterns)); + cm->mpattern = target; + cm->next = *matches; + *matches = cm; + + return 0; +} + +int DnsPatternMatchers::scan_hostname(const uint8_t* pattern, size_t size, AppId& client_id, + AppId& payload_id) +{ + MatchedDnsPatterns* mp = nullptr; + MatchedDnsPatterns* tmp_mp; + DnsHostPattern* best_match; + + dns_host_matcher.find_all((const char*)pattern, size, dns_host_pattern_match, false, &mp); + + if (!mp) + return 0; + + best_match = mp->mpattern; + tmp_mp = mp->next; + snort_free(mp); + + while ((mp = tmp_mp)) + { + tmp_mp = mp->next; + if (mp->mpattern->pattern_size > best_match->pattern_size) + { + best_match = mp->mpattern; + } + snort_free(mp); + } + + switch (best_match->type) + { + // type 0 means WEB APP + case 0: + client_id = APP_ID_DNS; + payload_id = best_match->app_id; + break; + // type 1 means CLIENT + case 1: + client_id = best_match->app_id; + payload_id = 0; + break; + default: + return 0; + } + + return 1; +} diff --git a/src/network_inspectors/appid/detector_plugins/dns_patterns.h b/src/network_inspectors/appid/detector_plugins/dns_patterns.h new file mode 100644 index 000000000..afa33cf56 --- /dev/null +++ b/src/network_inspectors/appid/detector_plugins/dns_patterns.h @@ -0,0 +1,60 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- + +// dns_patterns.h author Shravan Rangaraju + +#ifndef DNS_PATTERNS_H +#define DNS_PATTERNS_H + +#include "search_engines/search_tool.h" +#include "application_ids.h" + +struct DnsHostPattern +{ + uint8_t type; + AppId app_id; + uint8_t* pattern; + int pattern_size; +}; + +struct DnsHostPatternList +{ + DnsHostPattern* dpattern; + DnsHostPatternList* next; +}; + +struct MatchedDnsPatterns +{ + DnsHostPattern* mpattern; + MatchedDnsPatterns* next; +}; + +class DnsPatternMatchers +{ +public: + ~DnsPatternMatchers(); + void add_host_pattern(uint8_t*, size_t, uint8_t, AppId); + void finalize_patterns(); + int scan_hostname(const uint8_t*, size_t, AppId&, AppId&); + +private: + DnsHostPatternList* dns_host_pattern_list = nullptr; + snort::SearchTool dns_host_matcher = snort::SearchTool("ac_full", true); +}; + +#endif diff --git a/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc b/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc index 16ec5bf2b..46ec18312 100644 --- a/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc +++ b/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc @@ -313,14 +313,6 @@ static int match_query_elements(tMlpPattern* packetData, tMlpPattern* userPatter return copySize; } -HttpPatternMatchers* HttpPatternMatchers::get_instance() -{ - static HttpPatternMatchers* http_matchers; - if (!http_matchers) - http_matchers = new HttpPatternMatchers; - return http_matchers; -} - static void free_app_url_patterns(std::vector& url_patterns) { for (auto* pattern: url_patterns) @@ -1565,7 +1557,7 @@ AppId HttpPatternMatchers::get_appid_by_content_type(const char* data, int size) #define URL_SCHEME_END_PATTERN "://" #define URL_SCHEME_MAX_LEN (sizeof("https://")-1) -bool HttpPatternMatchers::get_appid_from_url(char* host, const char* url, char** version, +bool HttpPatternMatchers::get_appid_from_url(const char* host, const char* url, char** version, const char* referer, AppId* ClientAppId, AppId* serviceAppId, AppId* payloadAppId, AppId* referredPayloadAppId, bool from_rtmp, OdpContext& odp_ctxt) { @@ -1597,7 +1589,7 @@ bool HttpPatternMatchers::get_appid_from_url(char* host, const char* url, char** int host_len; if (!host) { - host = (char*)strchr(url, '/'); + host = strchr(url, '/'); if (host != nullptr) host_len = host - url; else diff --git a/src/network_inspectors/appid/detector_plugins/http_url_patterns.h b/src/network_inspectors/appid/detector_plugins/http_url_patterns.h index fa12c8ec1..98aaabc77 100644 --- a/src/network_inspectors/appid/detector_plugins/http_url_patterns.h +++ b/src/network_inspectors/appid/detector_plugins/http_url_patterns.h @@ -288,7 +288,6 @@ public: { } ~HttpPatternMatchers(); - static HttpPatternMatchers* get_instance(); int finalize_patterns(); void insert_chp_pattern(CHPListElement*); void insert_http_pattern(enum httpPatternType, DetectorHTTPPattern&); @@ -306,7 +305,7 @@ public: const AppIdContext&); AppId scan_header_x_working_with(const char*, uint32_t, char**); int get_appid_by_pattern(const char*, unsigned, char**); - bool get_appid_from_url(char*, const char*, char**, const char*, AppId*, AppId*, + bool get_appid_from_url(const char*, const char*, char**, const char*, AppId*, AppId*, AppId*, AppId*, bool, OdpContext&); AppId get_appid_by_content_type(const char*, int); void get_server_vendor_version(const char*, int, char**, char**, snort::AppIdServiceSubtype**); diff --git a/src/network_inspectors/appid/detector_plugins/sip_patterns.cc b/src/network_inspectors/appid/detector_plugins/sip_patterns.cc new file mode 100644 index 000000000..2a266cc26 --- /dev/null +++ b/src/network_inspectors/appid/detector_plugins/sip_patterns.cc @@ -0,0 +1,157 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- + +// sip_patterns.cc author Shravan Rangaraju + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "sip_patterns.h" + +#include "utils/util.h" + +#include "appid_config.h" + +using namespace snort; + +static int add_pattern(DetectorAppSipPattern** patternList, AppId client_id, + const char* client_version, const char* server_pattern) +{ + /* Allocate memory for data structures */ + DetectorAppSipPattern* pattern = (DetectorAppSipPattern*)snort_calloc( + sizeof(DetectorAppSipPattern)); + pattern->user_data.client_id = client_id; + pattern->user_data.client_version = snort_strdup(client_version); + pattern->pattern.pattern = (uint8_t*)snort_strdup(server_pattern); + pattern->pattern.patternSize = (int)strlen(server_pattern); + pattern->next = *patternList; + *patternList = pattern; + + return 0; +} + +static int get_sip_client_app(void* pattern_matcher, const char* pattern, uint32_t pattern_len, + AppId& client_id, char*& client_version) +{ + tMlmpPattern patterns[3]; + DetectorAppSipPattern* data; + + if ( !pattern ) + return 0; + + patterns[0].pattern = (const uint8_t*)pattern; + patterns[0].patternSize = pattern_len; + patterns[1].pattern = nullptr; + + data = (DetectorAppSipPattern*)mlmpMatchPatternGeneric((tMlmpTree*)pattern_matcher, patterns); + + if ( !data ) + return 0; + + client_id = data->user_data.client_id; + client_version = data->user_data.client_version; + + return 1; +} + +static void free_patterns(DetectorAppSipPattern*& list) +{ + for ( DetectorAppSipPattern* node = list; node; node = list ) + { + list = node->next; + snort_free((void*)node->pattern.pattern); + snort_free(node->user_data.client_version); + snort_free(node); + } +} + +SipPatternMatchers::~SipPatternMatchers() +{ + if ( sip_ua_matcher ) + { + mlmpDestroy((tMlmpTree*)sip_ua_matcher); + } + + free_patterns(sip_ua_list); + + if ( sip_server_matcher ) + { + mlmpDestroy((tMlmpTree*)sip_server_matcher); + } + + free_patterns(sip_server_list); +} + +int SipPatternMatchers::add_ua_pattern(AppId client_id, const char* client_version, const + char* pattern) +{ + return add_pattern(&sip_ua_list, client_id, client_version, pattern); +} + +int SipPatternMatchers::add_server_pattern(AppId client_id, const char* client_version, const + char* pattern) +{ + return add_pattern(&sip_server_list, client_id, client_version, + pattern); +} + +void SipPatternMatchers::finalize_patterns(OdpContext& odp_ctxt) +{ + int num_patterns; + DetectorAppSipPattern* pattern_node; + + sip_ua_matcher = mlmpCreate(); + sip_server_matcher = mlmpCreate(); + + for ( pattern_node = sip_ua_list; pattern_node; pattern_node = + pattern_node->next ) + { + num_patterns = odp_ctxt.get_http_matchers().parse_multiple_http_patterns( + (const char*)pattern_node->pattern.pattern, patterns, PATTERN_PART_MAX, 0); + patterns[num_patterns].pattern = nullptr; + + mlmpAddPattern((tMlmpTree*)sip_ua_matcher, patterns, pattern_node); + } + + for ( pattern_node = sip_server_list; pattern_node; pattern_node = + pattern_node->next ) + { + num_patterns = odp_ctxt.get_http_matchers().parse_multiple_http_patterns( + (const char*)pattern_node->pattern.pattern, patterns, PATTERN_PART_MAX, 0); + patterns[num_patterns].pattern = nullptr; + + mlmpAddPattern((tMlmpTree*)sip_server_matcher, patterns, pattern_node); + } + + mlmpProcessPatterns((tMlmpTree*)sip_ua_matcher); + mlmpProcessPatterns((tMlmpTree*)sip_server_matcher); +} + +int SipPatternMatchers::get_client_from_ua(const char* pattern, uint32_t pattern_len, + AppId& client_id, char*& client_version) +{ + return get_sip_client_app(sip_ua_matcher, pattern, pattern_len, client_id, client_version); +} + +int SipPatternMatchers::get_client_from_server(const char* pattern, uint32_t pattern_len, + AppId& client_id, char*& client_version) +{ + return get_sip_client_app(sip_server_matcher, pattern, pattern_len, client_id, client_version); +} + diff --git a/src/network_inspectors/appid/detector_plugins/sip_patterns.h b/src/network_inspectors/appid/detector_plugins/sip_patterns.h new file mode 100644 index 000000000..ed87e75e0 --- /dev/null +++ b/src/network_inspectors/appid/detector_plugins/sip_patterns.h @@ -0,0 +1,62 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- + +// sip_patterns.h author Shravan Rangaraju + +#ifndef SIP_PATTERNS_H +#define SIP_PATTERNS_H + +#include "appid_utils/sf_mlmp.h" +#include "appid_utils/sf_multi_mpse.h" +#include "application_ids.h" + +class OdpContext; + +struct SipUaUserData +{ + AppId client_id; + char* client_version; +}; + +struct DetectorAppSipPattern +{ + tMlpPattern pattern; + SipUaUserData user_data; + DetectorAppSipPattern* next; +}; + +class SipPatternMatchers +{ +public: + ~SipPatternMatchers(); + int add_ua_pattern(AppId, const char*, const char*); + int add_server_pattern(AppId, const char*, const char*); + int get_client_from_ua(const char*, uint32_t, AppId&, char*&); + int get_client_from_server(const char*, uint32_t, AppId&, char*&); + void finalize_patterns(OdpContext&); + +private: + static const int PATTERN_PART_MAX = 10; + tMlmpPattern patterns[PATTERN_PART_MAX] = { { nullptr, 0, 0 } }; + void* sip_ua_matcher = nullptr; + DetectorAppSipPattern* sip_ua_list = nullptr; + void* sip_server_matcher = nullptr; + DetectorAppSipPattern* sip_server_list = nullptr; +}; + +#endif diff --git a/src/network_inspectors/appid/detector_plugins/ssl_patterns.cc b/src/network_inspectors/appid/detector_plugins/ssl_patterns.cc new file mode 100644 index 000000000..b2980e02e --- /dev/null +++ b/src/network_inspectors/appid/detector_plugins/ssl_patterns.cc @@ -0,0 +1,180 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- + +// ssl_patterns.cc author Shravan Rangaraju + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ssl_patterns.h" + +#include "utils/util.h" + +using namespace snort; + +static void create_matcher(SearchTool& matcher, SslPatternList* list) +{ + size_t* pattern_index; + size_t size = 0; + SslPatternList* element = nullptr; + + pattern_index = &size; + + for (element = list; element; element = element->next) + { + matcher.add(element->dpattern->pattern, + element->dpattern->pattern_size, element->dpattern, true); + (*pattern_index)++; + } + + matcher.prep(); +} + +static int cert_pattern_match(void* id, void*, int match_end_pos, void* data, void*) +{ + MatchedSslPatterns* cm; + MatchedSslPatterns** matches = (MatchedSslPatterns**)data; + SslPattern* target = (SslPattern*)id; + + cm = (MatchedSslPatterns*)snort_alloc(sizeof(MatchedSslPatterns)); + cm->mpattern = target; + cm->match_start_pos = match_end_pos - target->pattern_size; + cm->next = *matches; + *matches = cm; + + return 0; +} + +static bool scan_patterns(SearchTool& matcher, const uint8_t* data, size_t size, + AppId& client_id, AppId& payload_id) +{ + MatchedSslPatterns* mp = nullptr; + SslPattern* best_match; + + matcher.find_all((const char*)data, size, cert_pattern_match, false, &mp); + + if (!mp) + return false; + + best_match = nullptr; + while (mp) + { + /* Only patterns that match start of payload, + or patterns starting with '.' + or patterns following '.' in payload are considered a match. */ + if (mp->match_start_pos == 0 || + *mp->mpattern->pattern == '.' || + data[mp->match_start_pos-1] == '.') + { + if (!best_match || + mp->mpattern->pattern_size > best_match->pattern_size) + { + best_match = mp->mpattern; + } + } + MatchedSslPatterns* tmpMp = mp; + mp = mp->next; + snort_free(tmpMp); + } + if (!best_match) + return false; + + switch (best_match->type) + { + /* type 0 means WEB APP */ + case 0: + client_id = APP_ID_SSL_CLIENT; + payload_id = best_match->app_id; + break; + /* type 1 means CLIENT */ + case 1: + client_id = best_match->app_id; + payload_id = 0; + break; + default: + return false; + } + + return true; +} + +static void free_patterns(SslPatternList*& list) +{ + SslPatternList* tmp_pattern; + + while ((tmp_pattern = list)) + { + list = tmp_pattern->next; + if (tmp_pattern->dpattern) + { + if (tmp_pattern->dpattern->pattern) + snort_free(tmp_pattern->dpattern->pattern); + snort_free(tmp_pattern->dpattern); + } + snort_free(tmp_pattern); + } +} + +static void add_pattern(SslPatternList*& list, uint8_t* pattern_str, size_t + pattern_size, uint8_t type, AppId app_id) +{ + SslPatternList* new_ssl_pattern; + + new_ssl_pattern = (SslPatternList*)snort_calloc(sizeof(SslPatternList)); + new_ssl_pattern->dpattern = (SslPattern*)snort_calloc(sizeof(SslPattern)); + new_ssl_pattern->dpattern->type = type; + new_ssl_pattern->dpattern->app_id = app_id; + new_ssl_pattern->dpattern->pattern = pattern_str; + new_ssl_pattern->dpattern->pattern_size = pattern_size; + + new_ssl_pattern->next = list; + list = new_ssl_pattern; +} + +SslPatternMatchers::~SslPatternMatchers() +{ + free_patterns(cert_pattern_list); + free_patterns(cname_pattern_list); +} + +void SslPatternMatchers::add_cert_pattern(uint8_t* pattern_str, size_t pattern_size, uint8_t type, AppId app_id) +{ + add_pattern(cert_pattern_list, pattern_str, pattern_size, type, app_id); +} + +void SslPatternMatchers::add_cname_pattern(uint8_t* pattern_str, size_t pattern_size, uint8_t type, AppId app_id) +{ + add_pattern(cname_pattern_list, pattern_str, pattern_size, type, app_id); +} + +void SslPatternMatchers::finalize_patterns() +{ + create_matcher(ssl_host_matcher, cert_pattern_list); + create_matcher(ssl_cname_matcher, cname_pattern_list); +} + +bool SslPatternMatchers::scan_hostname(const uint8_t* hostname, size_t size, AppId& client_id, AppId& payload_id) +{ + return scan_patterns(ssl_host_matcher, hostname, size, client_id, payload_id); +} + +bool SslPatternMatchers::scan_cname(const uint8_t* common_name, size_t size, AppId& client_id, AppId& payload_id) +{ + return scan_patterns(ssl_cname_matcher, common_name, size, client_id, payload_id); +} diff --git a/src/network_inspectors/appid/detector_plugins/ssl_patterns.h b/src/network_inspectors/appid/detector_plugins/ssl_patterns.h new file mode 100644 index 000000000..ce33cf3ec --- /dev/null +++ b/src/network_inspectors/appid/detector_plugins/ssl_patterns.h @@ -0,0 +1,65 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- + +// ssl_patterns.h author Shravan Rangaraju + +#ifndef SSL_PATTERNS_H +#define SSL_PATTERNS_H + +#include "search_engines/search_tool.h" +#include "application_ids.h" + +struct SslPattern +{ + uint8_t type; + AppId app_id; + uint8_t* pattern; + int pattern_size; +}; + +struct MatchedSslPatterns +{ + SslPattern* mpattern; + int match_start_pos; + struct MatchedSslPatterns* next; +}; + +struct SslPatternList +{ + SslPattern* dpattern; + SslPatternList* next; +}; + +class SslPatternMatchers +{ +public: + ~SslPatternMatchers(); + void add_cert_pattern(uint8_t*, size_t, uint8_t, AppId); + void add_cname_pattern(uint8_t*, size_t, uint8_t, AppId); + void finalize_patterns(); + bool scan_hostname(const uint8_t*, size_t, AppId&, AppId&); + bool scan_cname(const uint8_t*, size_t, AppId&, AppId&); + +private: + SslPatternList* cert_pattern_list = nullptr; + SslPatternList* cname_pattern_list = nullptr; + snort::SearchTool ssl_host_matcher = snort::SearchTool("ac_full", true); + snort::SearchTool ssl_cname_matcher= snort::SearchTool("ac_full", true); +}; + +#endif 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 04292dadb..7547e0641 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 @@ -148,8 +148,6 @@ AppIdSession::~AppIdSession() = default; AppIdHttpSession::AppIdHttpSession(AppIdSession& asd) : asd(asd) { - http_matchers = HttpPatternMatchers::get_instance(); - for ( int i = 0; i < NUM_METADATA_FIELDS; i++) meta_data[i] = nullptr; } 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 e527c7228..1f3301972 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 @@ -62,6 +62,18 @@ static CHPAction my_match; static void* my_chp_rewritten = nullptr; void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } +AppIdDiscovery::AppIdDiscovery() { } +AppIdDiscovery::~AppIdDiscovery() { } +ClientDiscovery::~ClientDiscovery() { } +void ClientDiscovery::initialize() { } +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; } +DnsPatternMatchers::~DnsPatternMatchers() { } +SipPatternMatchers::~SipPatternMatchers() { } +SslPatternMatchers::~SslPatternMatchers() { } TEST_GROUP(http_url_patterns_tests) { diff --git a/src/network_inspectors/appid/lua_detector_api.cc b/src/network_inspectors/appid/lua_detector_api.cc index a8a111d58..022582514 100644 --- a/src/network_inspectors/appid/lua_detector_api.cc +++ b/src/network_inspectors/appid/lua_detector_api.cc @@ -857,10 +857,10 @@ static int client_register_pattern(lua_State* L) /*mpse library does not hold reference to pattern therefore we don't need to allocate it. */ if ( protocol == IpProtocol::TCP) - ClientDiscovery::get_instance().register_tcp_pattern(ud->cd, (const uint8_t*)pattern, + ud->get_odp_ctxt().get_client_disco_mgr().register_tcp_pattern(ud->cd, (const uint8_t*)pattern, size, position, 0); else - ClientDiscovery::get_instance().register_udp_pattern(ud->cd, (const uint8_t*)pattern, + ud->get_odp_ctxt().get_client_disco_mgr().register_udp_pattern(ud->cd, (const uint8_t*)pattern, size, position, 0); lua_pushnumber(L, 0); @@ -1020,7 +1020,7 @@ static int detector_add_http_pattern(lua_State* L) if ( pattern.init(pattern_str, pattern_size, seq, service_id, client_id, payload_id, app_id) ) { - HttpPatternMatchers::get_instance()->insert_http_pattern(pat_type, pattern); + ud->get_odp_ctxt().get_http_matchers().insert_http_pattern(pat_type, pattern); aim.set_app_info_active(service_id); aim.set_app_info_active(client_id); aim.set_app_info_active(payload_id); @@ -1051,14 +1051,9 @@ static int detector_add_ssl_cert_pattern(lua_State* L) } uint8_t* pattern_str = (uint8_t*)snort_strdup(tmp_string); - if (!ssl_add_cert_pattern(pattern_str, pattern_size, type, app_id)) - { - snort_free(pattern_str); - ErrorMessage("Failed to add an SSL pattern list member"); - return 0; - } - + ud->get_odp_ctxt().get_ssl_matchers().add_cert_pattern(pattern_str, pattern_size, type, app_id); ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(app_id); + return 0; } @@ -1084,11 +1079,7 @@ static int detector_add_dns_host_pattern(lua_State* L) } uint8_t* pattern_str = (uint8_t*)snort_strdup(tmp_string); - if (!dns_add_host_pattern(pattern_str, pattern_size, type, app_id)) - { - snort_free(pattern_str); - ErrorMessage("LuaDetectorApi:Failed to add an SSL pattern list member"); - } + ud->get_odp_ctxt().get_dns_matchers().add_host_pattern(pattern_str, pattern_size, type, app_id); return 0; } @@ -1114,14 +1105,9 @@ static int detector_add_ssl_cname_pattern(lua_State* L) } uint8_t* pattern_str = (uint8_t*)snort_strdup(tmp_string); - if (!ssl_add_cname_pattern(pattern_str, pattern_size, type, app_id)) - { - snort_free(pattern_str); - ErrorMessage("Failed to add an SSL pattern list member"); - return 0; - } - + ud->get_odp_ctxt().get_ssl_matchers().add_cname_pattern(pattern_str, pattern_size, type, app_id); ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(app_id); + return 0; } @@ -1223,7 +1209,7 @@ static int detector_add_content_type_pattern(lua_State* L) detector.pattern = pattern; detector.pattern_size = strlen((char*)pattern); detector.app_id = appId; - HttpPatternMatchers::get_instance()->insert_content_type_pattern(detector); + ud->get_odp_ctxt().get_http_matchers().insert_content_type_pattern(detector); ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(appId); return 0; @@ -1484,7 +1470,7 @@ static inline int get_chp_action_data(lua_State* L, int index, char** action_dat static int add_chp_pattern_action(AppId appIdInstance, int isKeyPattern, HttpFieldIds patternType, size_t patternSize, char* patternData, ActionType actionType, char* optionalActionData, - AppInfoManager& app_info_mgr) + OdpContext& odp_ctxt) { //find the CHP App for this auto chp_entry = CHP_glossary->find(appIdInstance); @@ -1515,7 +1501,7 @@ static int add_chp_pattern_action(AppId appIdInstance, int isKeyPattern, HttpFie // at runtime we'll want to know how many of each type of pattern we are looking for. if (actionType == REWRITE_FIELD || actionType == INSERT_FIELD) { - if (!app_info_mgr.get_app_info_flags(CHP_APPIDINSTANCE_TO_ID(appIdInstance), + if (!odp_ctxt.get_app_info_mgr().get_app_info_flags(CHP_APPIDINSTANCE_TO_ID(appIdInstance), APPINFO_FLAG_SUPPORTED_SEARCH)) { ErrorMessage( @@ -1559,19 +1545,19 @@ static int add_chp_pattern_action(AppId appIdInstance, int isKeyPattern, HttpFie chpa->chp_action.action = actionType; chpa->chp_action.action_data = optionalActionData; chpa->chp_action.chpapp = chpapp; // link this struct to the Glossary entry - HttpPatternMatchers::get_instance()->insert_chp_pattern(chpa); + odp_ctxt.get_http_matchers().insert_chp_pattern(chpa); /* Set the safe-search bits in the appId entry */ if (actionType == GET_OFFSETS_FROM_REBUILT) - app_info_mgr.set_app_info_flags(CHP_APPIDINSTANCE_TO_ID(appIdInstance), + odp_ctxt.get_app_info_mgr().set_app_info_flags(CHP_APPIDINSTANCE_TO_ID(appIdInstance), APPINFO_FLAG_SEARCH_ENGINE | APPINFO_FLAG_SUPPORTED_SEARCH); else if (actionType == SEARCH_UNSUPPORTED) - app_info_mgr.set_app_info_flags(CHP_APPIDINSTANCE_TO_ID(appIdInstance), + odp_ctxt.get_app_info_mgr().set_app_info_flags(CHP_APPIDINSTANCE_TO_ID(appIdInstance), APPINFO_FLAG_SEARCH_ENGINE); else if (actionType == DEFER_TO_SIMPLE_DETECT && strcmp(patternData,"") == 0) - HttpPatternMatchers::get_instance()->remove_http_patterns_for_id(appIdInstance); + odp_ctxt.get_http_matchers().remove_http_patterns_for_id(appIdInstance); return 0; } @@ -1620,7 +1606,7 @@ static int detector_add_chp_action(lua_State* L) } return add_chp_pattern_action(appIdInstance, key_pattern, ptype, psize, pattern, - action, action_data, ud->get_odp_ctxt().get_app_info_mgr()); + action, action_data, ud->get_odp_ctxt()); } static int detector_create_chp_multi_application(lua_State* L) @@ -1710,7 +1696,7 @@ static int detector_add_chp_multi_action(lua_State* L) } return add_chp_pattern_action(appIdInstance, key_pattern, ptype, psize, pattern, - action, action_data, ud->get_odp_ctxt().get_app_info_mgr()); + action, action_data, ud->get_odp_ctxt()); } static int detector_port_only_service(lua_State* L) @@ -1724,14 +1710,12 @@ static int detector_port_only_service(lua_State* L) AppId appId = lua_tointeger(L, ++index); uint16_t port = lua_tointeger(L, ++index); - uint8_t protocol = lua_tointeger(L, ++index); + IpProtocol protocol = static_cast(lua_tointeger(L, ++index)); if (port == 0) - AppIdContext::ip_protocol[protocol] = appId; - else if (protocol == 6) - AppIdContext::tcp_port_only[port] = appId; - else if (protocol == 17) - AppIdContext::udp_port_only[port] = appId; + ud->get_odp_ctxt().add_protocol_service_id(protocol, appId); + else + ud->get_odp_ctxt().add_port_service_id(protocol, port, appId); ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(appId); @@ -1948,7 +1932,7 @@ static int detector_add_url_application(lua_State* L) pattern->patterns.path.patternSize = (int)path_pattern_size; pattern->patterns.scheme.pattern = schemePattern; pattern->patterns.scheme.patternSize = (int)schemePatternSize; - HttpPatternMatchers::get_instance()->insert_url_pattern(pattern); + ud->get_odp_ctxt().get_http_matchers().insert_url_pattern(pattern); app_info_manager.set_app_info_active(pattern->userData.service_id); app_info_manager.set_app_info_active(pattern->userData.client_id); @@ -2033,7 +2017,7 @@ static int detector_add_rtmp_url(lua_State* L) pattern->patterns.path.patternSize = (int)path_pattern_size; pattern->patterns.scheme.pattern = schemePattern; pattern->patterns.scheme.patternSize = (int)schemePatternSize; - HttpPatternMatchers::get_instance()->insert_rtmp_url_pattern(pattern); + ud->get_odp_ctxt().get_http_matchers().insert_rtmp_url_pattern(pattern); AppInfoManager& app_info_manager = ud->get_odp_ctxt().get_app_info_mgr(); app_info_manager.set_app_info_active(pattern->userData.service_id); @@ -2055,22 +2039,22 @@ static int detector_add_sip_user_agent(lua_State* L) int index = 1; uint32_t client_app = lua_tointeger(L, ++index); - const char* clientVersion = lua_tostring(L, ++index); - if (!clientVersion ) + const char* client_version = lua_tostring(L, ++index); + if (!client_version ) { ErrorMessage("Invalid sip client version string."); return 0; } /* Verify that ua pattern is a valid string */ - const char* uaPattern = lua_tostring(L, ++index); - if (!uaPattern) + const char* ua_pattern = lua_tostring(L, ++index); + if (!ua_pattern) { ErrorMessage("Invalid sip ua pattern string."); return 0; } - SipUdpClientDetector::sipUaPatternAdd(client_app, clientVersion, uaPattern); + ud->get_odp_ctxt().get_sip_matchers().add_ua_pattern(client_app, client_version, ua_pattern); ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(client_app); @@ -2193,7 +2177,7 @@ static int add_http_pattern(lua_State* L) if ( pattern.init(pattern_str, pattern_size, seq, service_id, client_id, payload_id, APP_ID_NONE) ) { - HttpPatternMatchers::get_instance()->insert_http_pattern(pat_type, pattern); + ud->get_odp_ctxt().get_http_matchers().insert_http_pattern(pat_type, pattern); AppInfoManager& app_info_manager = ud->get_odp_ctxt().get_app_info_mgr(); app_info_manager.set_app_info_active(service_id); app_info_manager.set_app_info_active(client_id); @@ -2267,7 +2251,7 @@ static int add_url_pattern(lua_State* L) pattern->patterns.path.patternSize = (int)path_pattern_size; pattern->patterns.scheme.pattern = schemePattern; pattern->patterns.scheme.patternSize = (int)schemePatternSize; - HttpPatternMatchers::get_instance()->insert_app_url_pattern(pattern); + ud->get_odp_ctxt().get_http_matchers().insert_app_url_pattern(pattern); AppInfoManager& app_info_manager = ud->get_odp_ctxt().get_app_info_mgr(); app_info_manager.set_app_info_active(service_id); @@ -2383,22 +2367,22 @@ static int detector_add_sip_server(lua_State* L) int index = 1; uint32_t client_app = lua_tointeger(L, ++index); - const char* clientVersion = lua_tostring(L, ++index); - if (!clientVersion ) + const char* client_version = lua_tostring(L, ++index); + if (!client_version ) { ErrorMessage("Invalid sip client version string."); return 0; } - /* Verify that ua pattern is a valid string */ - const char* uaPattern = lua_tostring(L, ++index); - if (!uaPattern) + /* Verify that server pattern is a valid string */ + const char* server_pattern = lua_tostring(L, ++index); + if (!server_pattern) { - ErrorMessage("Invalid sip ua pattern string."); + ErrorMessage("Invalid sip server pattern string."); return 0; } - SipUdpClientDetector::sipServerPatternAdd(client_app, clientVersion, uaPattern); + ud->get_odp_ctxt().get_sip_matchers().add_server_pattern(client_app, client_version, server_pattern); ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(client_app); return 0; @@ -2856,7 +2840,7 @@ LuaClientDetector::LuaClientDetector(AppIdDiscovery* cdm, const std::string& det handler->register_detector(name, this, proto); } -LuaClientObject::LuaClientObject(AppIdDiscovery* cdm, const std::string& detector_name, +LuaClientObject::LuaClientObject(const std::string& detector_name, const std::string& log_name, bool is_custom, IpProtocol protocol, lua_State* L, OdpContext& odp_ctxt) : LuaObject(odp_ctxt) { @@ -2864,7 +2848,7 @@ LuaClientObject::LuaClientObject(AppIdDiscovery* cdm, const std::string& detecto if (init(L)) { - cd = new LuaClientDetector(cdm, detector_name, + cd = new LuaClientDetector(&(odp_ctxt.get_client_disco_mgr()), detector_name, log_name, is_custom, lsd.package_info.minimum_matches, protocol); } else @@ -2874,14 +2858,14 @@ LuaClientObject::LuaClientObject(AppIdDiscovery* cdm, const std::string& detecto if (protocol == IpProtocol::TCP) { - appid_detectors = ClientDiscovery::get_instance().get_tcp_detectors(); + appid_detectors = odp_ctxt.get_client_disco_mgr().get_tcp_detectors(); auto detector = appid_detectors->find(detector_name); if (detector != appid_detectors->end()) ad = detector->second; } else if (protocol == IpProtocol::UDP) { - appid_detectors = ClientDiscovery::get_instance().get_udp_detectors(); + appid_detectors = odp_ctxt.get_client_disco_mgr().get_udp_detectors(); auto detector = appid_detectors->find(detector_name); if (detector != appid_detectors->end()) ad = detector->second; diff --git a/src/network_inspectors/appid/lua_detector_api.h b/src/network_inspectors/appid/lua_detector_api.h index a71448831..e62b793ff 100644 --- a/src/network_inspectors/appid/lua_detector_api.h +++ b/src/network_inspectors/appid/lua_detector_api.h @@ -154,7 +154,7 @@ class LuaClientObject : public LuaObject { public: ClientDetector* cd; - LuaClientObject(AppIdDiscovery* cdm, const std::string& detector_name, + LuaClientObject(const std::string& detector_name, const std::string& log_name, bool is_custom, IpProtocol protocol, lua_State* L, OdpContext& odp_ctxt); ClientDetector* get_detector() diff --git a/src/network_inspectors/appid/lua_detector_module.cc b/src/network_inspectors/appid/lua_detector_module.cc index 717158c24..8c8e78494 100644 --- a/src/network_inspectors/appid/lua_detector_module.cc +++ b/src/network_inspectors/appid/lua_detector_module.cc @@ -362,8 +362,7 @@ LuaObject* LuaDetectorManager::create_lua_detector(const char* detector_name, lua_getfield(L, -1, "client"); if ( lua_istable(L, -1) ) { - return new LuaClientObject(&ClientDiscovery::get_instance(), - detector_name, log_name, is_custom, proto, L, ctxt.get_odp_ctxt()); + return new LuaClientObject(detector_name, log_name, is_custom, proto, L, ctxt.get_odp_ctxt()); } else { diff --git a/src/network_inspectors/appid/service_plugins/service_discovery.cc b/src/network_inspectors/appid/service_plugins/service_discovery.cc index 182fccc15..f09b50240 100644 --- a/src/network_inspectors/appid/service_plugins/service_discovery.cc +++ b/src/network_inspectors/appid/service_plugins/service_discovery.cc @@ -701,8 +701,8 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p, { AppId client_id = APP_ID_NONE; AppId payload_id = APP_ID_NONE; - dns_host_scan_hostname((const uint8_t*)(dsession->get_host()), dsession->get_host_len(), - &client_id, &payload_id); + asd.ctxt.get_odp_ctxt().get_dns_matchers().scan_hostname((const uint8_t*)(dsession->get_host()), + dsession->get_host_len(), client_id, payload_id); asd.set_client_appid_data(client_id, change_bits); } else if (asd.service.get_id() == APP_ID_RTMP) diff --git a/src/network_inspectors/appid/service_plugins/service_ssl.cc b/src/network_inspectors/appid/service_plugins/service_ssl.cc index 00761a1de..42a363593 100644 --- a/src/network_inspectors/appid/service_plugins/service_ssl.cc +++ b/src/network_inspectors/appid/service_plugins/service_ssl.cc @@ -58,27 +58,6 @@ enum SSLContentType /* Extension types. */ #define SSL_EXT_SERVER_NAME 0 -struct SSLCertPattern -{ - uint8_t type; - AppId appId; - uint8_t* pattern; - int pattern_size; -}; - -struct DetectorSSLCertPattern -{ - SSLCertPattern* dpattern; - DetectorSSLCertPattern* next; -}; - -struct MatchedSSLPatterns -{ - SSLCertPattern* mpattern; - int match_start_pos; - struct MatchedSSLPatterns* next; -}; - enum SSLState { SSL_STATE_INITIATE, // Client initiates. @@ -187,16 +166,6 @@ struct ServiceSSLV2Hdr uint16_t conn_len; }; -struct ServiceSslConfig -{ - DetectorSSLCertPattern* DetectorSSLCertPatternList; - DetectorSSLCertPattern* DetectorSSLCnamePatternList; - SearchTool* ssl_host_matcher; - SearchTool* ssl_cname_matcher; -}; - -static ServiceSslConfig service_ssl_config; - #pragma pack() /* Convert 3-byte lengths in TLS headers to integers. */ @@ -205,60 +174,6 @@ static ServiceSslConfig service_ssl_config; + (uint32_t)(((const uint8_t*)(msb_ptr))[1] << 8) \ + (uint32_t)(((const uint8_t*)(msb_ptr))[2]))) -static int ssl_cert_pattern_match(void* id, void*, int match_end_pos, void* data, void*) -{ - MatchedSSLPatterns* cm; - MatchedSSLPatterns** matches = (MatchedSSLPatterns**)data; - SSLCertPattern* target = (SSLCertPattern*)id; - - cm = (MatchedSSLPatterns*)snort_alloc(sizeof(MatchedSSLPatterns)); - cm->mpattern = target; - cm->match_start_pos = match_end_pos - target->pattern_size; - cm->next = *matches; - *matches = cm; - - return 0; -} - -static int ssl_detector_create_matcher(SearchTool** matcher, DetectorSSLCertPattern* list) -{ - size_t* patternIndex; - size_t size = 0; - DetectorSSLCertPattern* element = nullptr; - - if (*matcher) - delete *matcher; - - if (!(*matcher = new SearchTool("ac_full", true))) - return 0; - - patternIndex = &size; - - /* Add patterns from Lua API. */ - for (element = list; element; element = element->next) - { - (*matcher)->add(element->dpattern->pattern, - element->dpattern->pattern_size, element->dpattern, true); - (*patternIndex)++; - } - - (*matcher)->prep(); - - return 1; -} - -int ssl_detector_process_patterns() -{ - int retVal = 1; - if (!ssl_detector_create_matcher(&service_ssl_config.ssl_host_matcher, - service_ssl_config.DetectorSSLCertPatternList)) - retVal = 0; - if (!ssl_detector_create_matcher(&service_ssl_config.ssl_cname_matcher, - service_ssl_config.DetectorSSLCnamePatternList)) - retVal = 0; - return retVal; -} - static const uint8_t SSL_PATTERN_PCT[] = { 0x02, 0x00, 0x80, 0x01 }; static const uint8_t SSL_PATTERN3_0[] = { 0x16, 0x03, 0x00 }; static const uint8_t SSL_PATTERN3_1[] = { 0x16, 0x03, 0x01 }; @@ -319,7 +234,6 @@ SslServiceDetector::SslServiceDetector(ServiceDiscovery* sd) handler->register_detector(name, this, proto); } -/* AppIdFreeFCN */ static void ssl_free(void* ss) { ServiceSSLData* ss_tmp = (ServiceSSLData*)ss; @@ -888,143 +802,6 @@ bool is_service_over_ssl(AppId appId) return false; } -static int ssl_scan_patterns(SearchTool* matcher, const uint8_t* data, size_t size, - AppId& client_id, AppId& payload_id) -{ - MatchedSSLPatterns* mp = nullptr; - SSLCertPattern* best_match; - - if (!matcher) - return 0; - - matcher->find_all((const char*)data, size, ssl_cert_pattern_match, false, &mp); - - if (!mp) - return 0; - - best_match = nullptr; - while (mp) - { - /* Only patterns that match start of payload, - or patterns starting with '.' - or patterns following '.' in payload are considered a match. */ - if (mp->match_start_pos == 0 || - *mp->mpattern->pattern == '.' || - data[mp->match_start_pos-1] == '.') - { - if (!best_match || - mp->mpattern->pattern_size > best_match->pattern_size) - { - best_match = mp->mpattern; - } - } - MatchedSSLPatterns* tmpMp = mp; - mp = mp->next; - snort_free(tmpMp); - } - if (!best_match) - return 0; - - switch (best_match->type) - { - /* type 0 means WEB APP */ - case 0: - client_id = APP_ID_SSL_CLIENT; - payload_id = best_match->appId; - break; - /* type 1 means CLIENT */ - case 1: - client_id = best_match->appId; - payload_id = 0; - break; - default: - return 0; - } - - return 1; -} - -int ssl_scan_hostname(const uint8_t* hostname, size_t size, AppId& client_id, AppId& payload_id) -{ - return ssl_scan_patterns(service_ssl_config.ssl_host_matcher, - hostname, size, client_id, payload_id); -} - -int ssl_scan_cname(const uint8_t* common_name, size_t size, AppId& client_id, AppId& payload_id) -{ - return ssl_scan_patterns(service_ssl_config.ssl_cname_matcher, - common_name, size, client_id, payload_id); -} - -void service_ssl_clean() -{ - ssl_detector_free_patterns(); - - if (service_ssl_config.ssl_host_matcher) - { - delete service_ssl_config.ssl_host_matcher; - service_ssl_config.ssl_host_matcher = nullptr; - } - if (service_ssl_config.ssl_cname_matcher) - { - delete service_ssl_config.ssl_cname_matcher; - service_ssl_config.ssl_cname_matcher = nullptr; - } -} - -static int ssl_add_pattern(DetectorSSLCertPattern** list, uint8_t* pattern_str, size_t - pattern_size, uint8_t type, AppId app_id) -{ - DetectorSSLCertPattern* new_ssl_pattern; - - new_ssl_pattern = (DetectorSSLCertPattern*)snort_calloc(sizeof(DetectorSSLCertPattern)); - new_ssl_pattern->dpattern = (SSLCertPattern*)snort_calloc(sizeof(SSLCertPattern)); - new_ssl_pattern->dpattern->type = type; - new_ssl_pattern->dpattern->appId = app_id; - new_ssl_pattern->dpattern->pattern = pattern_str; - new_ssl_pattern->dpattern->pattern_size = pattern_size; - - new_ssl_pattern->next = *list; - *list = new_ssl_pattern; - - return 1; -} - -int ssl_add_cert_pattern(uint8_t* pattern_str, size_t pattern_size, uint8_t type, AppId app_id) -{ - return ssl_add_pattern(&service_ssl_config.DetectorSSLCertPatternList, - pattern_str, pattern_size, type, app_id); -} - -int ssl_add_cname_pattern(uint8_t* pattern_str, size_t pattern_size, uint8_t type, AppId app_id) -{ - return ssl_add_pattern(&service_ssl_config.DetectorSSLCnamePatternList, - pattern_str, pattern_size, type, app_id); -} - -static void ssl_patterns_free(DetectorSSLCertPattern** list) -{ - DetectorSSLCertPattern* tmp_pattern; - - while ((tmp_pattern = *list)) - { - *list = tmp_pattern->next; - if (tmp_pattern->dpattern) - { - if (tmp_pattern->dpattern->pattern) - snort_free(tmp_pattern->dpattern->pattern); - snort_free(tmp_pattern->dpattern); - } - snort_free(tmp_pattern); - } -} - -void ssl_detector_free_patterns() -{ - ssl_patterns_free(&service_ssl_config.DetectorSSLCertPatternList); - ssl_patterns_free(&service_ssl_config.DetectorSSLCnamePatternList); -} - bool setSSLSquelch(Packet* p, int type, AppId appId, OdpContext& odp_ctxt) { if (!odp_ctxt.get_app_info_mgr().get_app_info_flags(appId, APPINFO_FLAG_SSL_SQUELCH)) diff --git a/src/network_inspectors/appid/service_plugins/service_ssl.h b/src/network_inspectors/appid/service_plugins/service_ssl.h index 7d5af01fb..705e22c64 100644 --- a/src/network_inspectors/appid/service_plugins/service_ssl.h +++ b/src/network_inspectors/appid/service_plugins/service_ssl.h @@ -37,13 +37,6 @@ public: AppId getSslServiceAppId(short srcPort); bool is_service_over_ssl(AppId); -void service_ssl_clean(); -int ssl_detector_process_patterns(); -int ssl_scan_hostname(const uint8_t*, size_t, AppId&, AppId&); -int ssl_scan_cname(const uint8_t*, size_t, AppId&, AppId&); -int ssl_add_cert_pattern(uint8_t*, size_t, uint8_t, AppId); -int ssl_add_cname_pattern(uint8_t*, size_t, uint8_t, AppId); -void ssl_detector_free_patterns(); bool setSSLSquelch(snort::Packet*, int type, AppId, OdpContext&); #endif diff --git a/src/network_inspectors/appid/test/appid_api_test.cc b/src/network_inspectors/appid/test/appid_api_test.cc index b012da341..b40d17ad7 100644 --- a/src/network_inspectors/appid/test/appid_api_test.cc +++ b/src/network_inspectors/appid/test/appid_api_test.cc @@ -50,7 +50,18 @@ namespace snort class Inspector* InspectorManager::get_inspector(char const*, bool, SnortConfig*) { return nullptr; } +} +bool SslPatternMatchers::scan_hostname(unsigned char const*, unsigned long, AppId& client_id, AppId&) +{ + client_id = APPID_UT_ID + 1; + return true; +} + +bool SslPatternMatchers::scan_cname(unsigned char const*, unsigned long, AppId&, AppId& payload_id) +{ + payload_id = APPID_UT_ID + 1; + return true; } void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } diff --git a/src/network_inspectors/appid/test/appid_detector_test.cc b/src/network_inspectors/appid/test/appid_detector_test.cc index 899ac487d..05146c22e 100644 --- a/src/network_inspectors/appid/test/appid_detector_test.cc +++ b/src/network_inspectors/appid/test/appid_detector_test.cc @@ -36,7 +36,7 @@ #include #include -snort::Inspector* snort::InspectorManager::get_inspector(char const*, bool, snort::SnortConfig*) { } +snort::Inspector* snort::InspectorManager::get_inspector(char const*, bool, snort::SnortConfig*) { return nullptr; } void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } void AppIdHttpSession::set_http_change_bits(AppidChangeBits&, HttpFieldIds) {} diff --git a/src/network_inspectors/appid/test/appid_discovery_test.cc b/src/network_inspectors/appid/test/appid_discovery_test.cc index e2479b7e6..64e92fae8 100644 --- a/src/network_inspectors/appid/test/appid_discovery_test.cc +++ b/src/network_inspectors/appid/test/appid_discovery_test.cc @@ -115,12 +115,11 @@ void DataBus::publish(const char*, DataEvent& event, Flow*) // Stubs for matchers static HttpPatternMatchers* http_matchers; +DnsPatternMatchers::~DnsPatternMatchers() { } HttpPatternMatchers::~HttpPatternMatchers() {} void HttpPatternMatchers::get_http_offsets(Packet*, AppIdHttpSession*) {} -HttpPatternMatchers* HttpPatternMatchers::get_instance() -{ - return http_matchers; -} +SipPatternMatchers::~SipPatternMatchers() { } +SslPatternMatchers::~SslPatternMatchers() { } void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } @@ -140,12 +139,12 @@ ProfileStats* AppIdModule::get_profile() const { return nullptr; } // Stubs for config static AppIdConfig app_config; static AppIdContext app_ctxt(app_config); -AppId AppIdContext::get_port_service_id(IpProtocol, uint16_t) +AppId OdpContext::get_port_service_id(IpProtocol, uint16_t) { return APP_ID_NONE; } -AppId AppIdContext::get_protocol_service_id(IpProtocol) +AppId OdpContext::get_protocol_service_id(IpProtocol) { return APP_ID_NONE; } @@ -226,19 +225,12 @@ AppId HostTracker::get_appid(Port, IpProtocol, bool, bool) } // Stubs for ClientDiscovery -ClientDiscovery::ClientDiscovery(){} ClientDiscovery::~ClientDiscovery() {} void ClientDiscovery::initialize() {} void ClientDiscovery::finalize_client_plugins() {} void ClientDiscovery::release_instance() {} void ClientDiscovery::release_thread_resources() {} -static ClientDiscovery* c_discovery_manager = nullptr; -ClientDiscovery& ClientDiscovery::get_instance() -{ - if (!c_discovery_manager) - c_discovery_manager = new ClientDiscovery(); - return *c_discovery_manager; -} +static ClientDiscovery* c_discovery_manager = new ClientDiscovery(); bool ClientDiscovery::do_client_discovery(AppIdSession&, Packet*, AppidSessionDirection, AppidChangeBits&) { diff --git a/src/network_inspectors/appid/test/appid_expected_flags_test.cc b/src/network_inspectors/appid/test/appid_expected_flags_test.cc index 55c85017f..60ad0ce91 100644 --- a/src/network_inspectors/appid/test/appid_expected_flags_test.cc +++ b/src/network_inspectors/appid/test/appid_expected_flags_test.cc @@ -29,7 +29,6 @@ #include snort::Inspector* snort::InspectorManager::get_inspector(char const*, bool, snort::SnortConfig*) { return nullptr; } - void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } void AppIdHttpSession::set_http_change_bits(AppidChangeBits&, HttpFieldIds) {} diff --git a/src/network_inspectors/appid/test/appid_http_event_test.cc b/src/network_inspectors/appid/test/appid_http_event_test.cc index 583f86731..acd5cfb18 100644 --- a/src/network_inspectors/appid/test/appid_http_event_test.cc +++ b/src/network_inspectors/appid/test/appid_http_event_test.cc @@ -43,6 +43,7 @@ THREAD_LOCAL AppIdDebug* appidDebug = nullptr; void AppIdDebug::activate(const Flow*, const AppIdSession*, bool) { active = true; } void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } + using namespace snort; namespace snort diff --git a/src/network_inspectors/appid/test/appid_http_session_test.cc b/src/network_inspectors/appid/test/appid_http_session_test.cc index 6ad53782b..7c1e7424b 100644 --- a/src/network_inspectors/appid/test/appid_http_session_test.cc +++ b/src/network_inspectors/appid/test/appid_http_session_test.cc @@ -52,11 +52,6 @@ const char* AppInfoManager::get_app_name(AppId) } // HttpPatternMatchers mock functions -HttpPatternMatchers* HttpPatternMatchers::get_instance() -{ - return nullptr; -} - void HttpPatternMatchers::scan_key_chp(ChpMatchDescriptor&) { } @@ -91,7 +86,7 @@ AppId HttpPatternMatchers::get_appid_by_content_type(const char*, int) return 0; } -bool HttpPatternMatchers::get_appid_from_url(char*, const char*, char**, +bool HttpPatternMatchers::get_appid_from_url(const char*, const char*, char**, const char*, AppId*, AppId*, AppId*, AppId* referredPayloadAppId, bool, OdpContext&) { *referredPayloadAppId = APP_ID_FACEBOOK; @@ -281,7 +276,7 @@ TEST(appid_http_session, change_bits_for_referred_appid) session.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; hsession.set_skip_simple_detect(false); hsession.set_field( (HttpFieldIds)2, new std::string("referer"), change_bits ); - hsession.process_http_packet(APP_ID_FROM_INITIATOR, change_bits); + hsession.process_http_packet(APP_ID_FROM_INITIATOR, change_bits, odp_ctxt.get_http_matchers()); // Detect changes in referred appid CHECK_EQUAL(change_bits.test(APPID_REFERRED_BIT), true); diff --git a/src/network_inspectors/appid/test/appid_mock_definitions.h b/src/network_inspectors/appid/test/appid_mock_definitions.h index 5e0e7b890..25bde7e2f 100644 --- a/src/network_inspectors/appid/test/appid_mock_definitions.h +++ b/src/network_inspectors/appid/test/appid_mock_definitions.h @@ -50,8 +50,24 @@ void LogMessage(const char*,...) { } void ParseWarning(WarningGroup, const char*, ...) { } void LogLabel(const char*, FILE*) {} +SearchTool::SearchTool(char const*, bool) { } +SearchTool::~SearchTool() { } } +AppIdDiscovery::AppIdDiscovery() { } +AppIdDiscovery::~AppIdDiscovery() { } +ClientDiscovery::~ClientDiscovery() { } +void ClientDiscovery::initialize() { } +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; } +DnsPatternMatchers::~DnsPatternMatchers() { } +HttpPatternMatchers::~HttpPatternMatchers() { } +SipPatternMatchers::~SipPatternMatchers() { } +SslPatternMatchers::~SslPatternMatchers() { } + void Field::set(int32_t length, const uint8_t* start, bool own_the_buffer_) { strt = start; diff --git a/src/network_inspectors/appid/test/appid_mock_http_session.h b/src/network_inspectors/appid/test/appid_mock_http_session.h index 0903dafe9..c4dbe64ea 100644 --- a/src/network_inspectors/appid/test/appid_mock_http_session.h +++ b/src/network_inspectors/appid/test/appid_mock_http_session.h @@ -43,7 +43,7 @@ AppIdHttpSession::~AppIdHttpSession() } } -int AppIdHttpSession::process_http_packet(AppidSessionDirection, AppidChangeBits&) { return 0; } +int AppIdHttpSession::process_http_packet(AppidSessionDirection, AppidChangeBits&, HttpPatternMatchers&) { return 0; } char const* APPID_UT_XFF_IP_ADDR = "192.168.0.1"; char const* CONTENT_TYPE = "html/text"; diff --git a/src/network_inspectors/appid/test/appid_mock_session.h b/src/network_inspectors/appid/test/appid_mock_session.h index 2634cd390..ce21a9bba 100644 --- a/src/network_inspectors/appid/test/appid_mock_session.h +++ b/src/network_inspectors/appid/test/appid_mock_session.h @@ -272,17 +272,5 @@ bool AppIdSession::is_tp_appid_available() const return true; } -int ssl_scan_hostname(const uint8_t*, size_t, AppId& client_id, AppId&) -{ - client_id = APPID_UT_ID + 1; - return 1; -} - -int ssl_scan_cname(const uint8_t*, size_t, AppId&, AppId& payload_id) -{ - payload_id = APPID_UT_ID + 1; - return 1; -} - #endif diff --git a/src/network_inspectors/appid/test/log_message_mock.h b/src/network_inspectors/appid/test/log_message_mock.h index 329c21477..a5646c699 100644 --- a/src/network_inspectors/appid/test/log_message_mock.h +++ b/src/network_inspectors/appid/test/log_message_mock.h @@ -23,7 +23,10 @@ SO_PUBLIC void ErrorMessage(const char* format,...) [[noreturn]] SO_PUBLIC void FatalError(const char* format,...) { - ErrorMessage(format); + va_list ap; + va_start(ap,format); + vfprintf(stderr, format, ap); + va_end(ap); exit(1); } @@ -32,7 +35,7 @@ SO_PUBLIC void WarningMessage(const char* format,...) { va_list ap; va_start(ap, format); - vfprintf(stderr, format, ap); + vfprintf(stderr, format, ap); va_end(ap); } diff --git a/src/network_inspectors/appid/test/tp_lib_handler_test.cc b/src/network_inspectors/appid/test/tp_lib_handler_test.cc index 88071d59f..b634b5e9a 100644 --- a/src/network_inspectors/appid/test/tp_lib_handler_test.cc +++ b/src/network_inspectors/appid/test/tp_lib_handler_test.cc @@ -44,6 +44,22 @@ static OdpContext stub_odp_ctxt(config, nullptr); OdpContext* AppIdContext::odp_ctxt = &stub_odp_ctxt; ThirdPartyAppIdContext* AppIdContext::tp_appid_ctxt = nullptr; +snort::SearchTool::SearchTool(char const*, bool) { } +snort::SearchTool::~SearchTool() { } + +AppIdDiscovery::AppIdDiscovery() { } +AppIdDiscovery::~AppIdDiscovery() { } +ClientDiscovery::~ClientDiscovery() { } +void ClientDiscovery::initialize() { } +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; } +DnsPatternMatchers::~DnsPatternMatchers() { } +HttpPatternMatchers::~HttpPatternMatchers() { } +SipPatternMatchers::~SipPatternMatchers() { } +SslPatternMatchers::~SslPatternMatchers() { } AppIdConfig::~AppIdConfig() { } OdpContext::OdpContext(AppIdConfig&, snort::SnortConfig*) { } diff --git a/src/network_inspectors/appid/tp_appid_utils.cc b/src/network_inspectors/appid/tp_appid_utils.cc index 4791b3b90..1d7eb1952 100644 --- a/src/network_inspectors/appid/tp_appid_utils.cc +++ b/src/network_inspectors/appid/tp_appid_utils.cc @@ -449,9 +449,9 @@ static inline void process_rtmp(AppIdSession& asd, attribute_data.http_request_user_agent_begin() ) > 0 ) { char *version = nullptr; - HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance(); + HttpPatternMatchers& http_matchers = asd.ctxt.get_odp_ctxt().get_http_matchers(); - http_matchers->identify_user_agent(field->c_str(), size, service_id, + http_matchers.identify_user_agent(field->c_str(), size, service_id, client_id, &version); asd.set_client_appid_data(client_id, change_bits, version); @@ -470,13 +470,13 @@ static inline void process_rtmp(AppIdSession& asd, const std::string* url; if ( ( url = hsession->get_field(MISC_URL_FID) ) != nullptr ) { - HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance(); + HttpPatternMatchers& http_matchers = asd.ctxt.get_odp_ctxt().get_http_matchers(); const char* referer = hsession->get_cfield(REQ_REFERER_FID); - if ( ( ( http_matchers->get_appid_from_url(nullptr, url->c_str(), + if ( ( ( http_matchers.get_appid_from_url(nullptr, url->c_str(), nullptr, referer, &client_id, &service_id, &payload_id, &referred_payload_app_id, true, asd.ctxt.get_odp_ctxt()) ) || - ( http_matchers->get_appid_from_url(nullptr, url->c_str(), + ( http_matchers.get_appid_from_url(nullptr, url->c_str(), nullptr, referer, &client_id, &service_id, &payload_id, &referred_payload_app_id, false, asd.ctxt.get_odp_ctxt()) ) ) == 1 ) { @@ -782,7 +782,7 @@ bool do_tp_discovery(ThirdPartyAppIdContext& tp_appid_ctxt, AppIdSession& asd, I } AppIdHttpSession* hsession = asd.get_http_session(); - hsession->process_http_packet(direction, change_bits); + hsession->process_http_packet(direction, change_bits, asd.ctxt.get_odp_ctxt().get_http_matchers()); // If SSL over HTTP tunnel, make sure Snort knows that it's encrypted. if (asd.payload.get_id() == APP_ID_HTTP_SSL_TUNNEL)