]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4798: appid: combined host pattern matchers
authorOleksandr Stepanov -X (ostepano - SOFTSERVE INC at Cisco) <ostepano@cisco.com>
Fri, 25 Jul 2025 14:37:57 +0000 (14:37 +0000)
committerChris Sherwin (chsherwi) <chsherwi@cisco.com>
Fri, 25 Jul 2025 14:37:57 +0000 (14:37 +0000)
Merge in SNORT/snort3 from ~OSTEPANO/snort3:http_ssl_patterns to master

Squashed commit of the following:

commit 64b25c73eff1ebb4f36cd31091ce63ac0343da0a
Author: Oleksandr Stepanov <ostepano@cisco.com>
Date:   Thu Jul 3 06:33:38 2025 -0400

    appid: combined host pattern matchers

22 files changed:
src/network_inspectors/appid/CMakeLists.txt
src/network_inspectors/appid/appid_api.cc
src/network_inspectors/appid/appid_config.cc
src/network_inspectors/appid/appid_config.h
src/network_inspectors/appid/appid_eve_process_event_handler.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/detector_plugins/host_patterns.cc [new file with mode: 0644]
src/network_inspectors/appid/detector_plugins/host_patterns.h [new file with mode: 0644]
src/network_inspectors/appid/detector_plugins/http_url_patterns.cc
src/network_inspectors/appid/detector_plugins/http_url_patterns.h
src/network_inspectors/appid/detector_plugins/ssl_patterns.cc [deleted file]
src/network_inspectors/appid/detector_plugins/ssl_patterns.h [deleted file]
src/network_inspectors/appid/detector_plugins/test/detector_sip_test.cc
src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc
src/network_inspectors/appid/lua_detector_api.cc
src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h
src/network_inspectors/appid/test/appid_api_test.cc
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/appid_eve_process_event_handler_test.cc
src/network_inspectors/appid/test/appid_mock_definitions.h
src/network_inspectors/appid/test/service_state_test.cc
src/network_inspectors/appid/test/tp_lib_handler_test.cc

index fd83fe82e64351a2c65246b9f3726224103de2c7..2d84c193669c88641f581f8f4c55d312bcf9fca8 100644 (file)
@@ -131,8 +131,8 @@ set ( DP_APPID_SOURCES
     detector_plugins/sip_patterns.h
     detector_plugins/ssh_patterns.cc
     detector_plugins/ssh_patterns.h
-    detector_plugins/ssl_patterns.cc
-    detector_plugins/ssl_patterns.h
+    detector_plugins/host_patterns.cc
+    detector_plugins/host_patterns.h
 )
 
 set ( UTIL_APPID_SOURCES
index e27aadbb735b3052e1aff2346347624be6447858..b0d532dfa1b5e154823354a2ed62ff9f448b4bdf 100644 (file)
@@ -138,7 +138,7 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
             return false;
 
         AppidChangeBits change_bits;
-        SslPatternMatchers& ssl_matchers = asd->get_odp_ctxt().get_ssl_matchers();
+        HostPatternMatchers& host_matchers = asd->get_odp_ctxt().get_host_matchers();
         if (!asd->tsession)
             asd->tsession = new TlsSession();
         else if (sni_mismatch)
@@ -155,7 +155,7 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
             asd->tsession->set_tls_org_unit(org_unit, strlen(org_unit));
             if (client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
             {
-                ssl_matchers.scan_cname((const uint8_t*)org_unit, strlen(org_unit),
+                host_matchers.scan_cname((const uint8_t*)org_unit, strlen(org_unit),
                     client_id, payload_id);
                 if (client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
                     asd->tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_ORG_UNIT);
@@ -165,7 +165,7 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
         if (server_name and !sni_mismatch)
         {
             asd->tsession->set_tls_host(server_name, strlen(server_name), change_bits);
-            ssl_matchers.scan_hostname((const uint8_t*)server_name, strlen(server_name),
+            host_matchers.scan_hostname((const uint8_t*)server_name, strlen(server_name),
                 client_id, payload_id);
             if (client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
                 asd->tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_HOST);
@@ -176,7 +176,7 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
             asd->tsession->set_tls_first_alt_name(first_alt_name, strlen(first_alt_name), change_bits);
             if (client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
             {
-                ssl_matchers.scan_hostname((const uint8_t*)first_alt_name, strlen(first_alt_name),
+                host_matchers.scan_hostname((const uint8_t*)first_alt_name, strlen(first_alt_name),
                     client_id, payload_id);
                 if (client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
                     asd->tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_FIRST_SAN);
@@ -188,7 +188,7 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
             asd->tsession->set_tls_cname(common_name, strlen(common_name), change_bits);
             if (client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
             {
-                ssl_matchers.scan_cname((const uint8_t*)common_name, strlen(common_name),
+                host_matchers.scan_cname((const uint8_t*)common_name, strlen(common_name),
                     client_id, payload_id);
                 if (client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
                     asd->tsession->set_matched_tls_type(MatchedTlsType::MATCHED_TLS_CNAME);
@@ -220,19 +220,19 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
     }
     else
     {
-        SslPatternMatchers& ssl_matchers = pkt_thread_odp_ctxt->get_ssl_matchers();
+        HostPatternMatchers& host_matchers = pkt_thread_odp_ctxt->get_host_matchers();
 
         if (server_name and !sni_mismatch)
-            ssl_matchers.scan_hostname((const uint8_t*)server_name, strlen(server_name),
+            host_matchers.scan_hostname((const uint8_t*)server_name, strlen(server_name),
                 client_id, payload_id);
         if (first_alt_name and client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
-            ssl_matchers.scan_hostname((const uint8_t*)first_alt_name, strlen(first_alt_name),
+            host_matchers.scan_hostname((const uint8_t*)first_alt_name, strlen(first_alt_name),
                 client_id, payload_id);
         if (common_name and client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
-            ssl_matchers.scan_cname((const uint8_t*)common_name, strlen(common_name), client_id,
+            host_matchers.scan_cname((const uint8_t*)common_name, strlen(common_name), client_id,
                 payload_id);
         if (org_unit and client_id == APP_ID_NONE and payload_id == APP_ID_NONE)
-            ssl_matchers.scan_cname((const uint8_t*)org_unit, strlen(org_unit), client_id,
+            host_matchers.scan_cname((const uint8_t*)org_unit, strlen(org_unit), client_id,
                 payload_id);
     }
 
index ba7b09a2b7d3cc8070cdc6ee6119ddca02da6a1e..0f7de42840169e6153e965dcbb02714ae68caad2 100644 (file)
@@ -199,7 +199,7 @@ unsigned OdpContext::get_pattern_count()
         eve_ca_matchers.get_pattern_count() +
         alpn_matchers.get_pattern_count() +
         sip_matchers.get_pattern_count() +
-        ssl_matchers.get_pattern_count() +
+        host_matchers.get_pattern_count() +
         ssh_matchers.get_pattern_count() +
         dns_matchers.get_pattern_count();
 }
@@ -257,13 +257,13 @@ void OdpContext::initialize(AppIdInspector& inspector)
     client_pattern_detector->finalize_client_port_patterns(inspector);
     service_disco_mgr.finalize_service_patterns();
     client_disco_mgr.finalize_client_patterns();
-    http_matchers.finalize_patterns();
+    http_matchers.finalize_patterns(*this);
     eve_ca_matchers.finalize_patterns();
     alpn_matchers.finalize_patterns();
     // sip patterns need to be finalized after http patterns because they
     // are dependent on http patterns
     sip_matchers.finalize_patterns(*this);
-    ssl_matchers.finalize_patterns();
+    host_matchers.finalize_patterns();
     dns_matchers.finalize_patterns();
 }
 
@@ -278,7 +278,7 @@ void OdpContext::reload()
     eve_ca_matchers.reload_patterns();
     http_matchers.reload_patterns();
     sip_matchers.reload_patterns();
-    ssl_matchers.reload_patterns();
+    host_matchers.reload_patterns();
     dns_matchers.reload_patterns();
     alpn_matchers.reload_patterns();
 }
index 0bf4788dce3f9037243d7cc33ec0d097a49e6f0e..dfe91df0e8ab3c1fe61a69e7e9099a7cb257c3fb 100644 (file)
@@ -37,7 +37,7 @@
 #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 "detector_plugins/host_patterns.h"
 #include "host_port_app_cache.h"
 #include "length_app_cache.h"
 #include "lua_detector_flow_api.h"
@@ -248,9 +248,9 @@ public:
         return sip_matchers;
     }
 
-    SslPatternMatchers& get_ssl_matchers()
+    HostPatternMatchers& get_host_matchers()
     {
-        return ssl_matchers;
+        return host_matchers;
     }
 
     SshPatternMatchers& get_ssh_matchers()
@@ -315,7 +315,7 @@ private:
     EveCaPatternMatchers eve_ca_matchers;
     ServiceDiscovery service_disco_mgr;
     SipPatternMatchers sip_matchers;
-    SslPatternMatchers ssl_matchers;
+    HostPatternMatchers host_matchers;
     SshPatternMatchers ssh_matchers;
     PatternClientDetector* client_pattern_detector;
     PatternServiceDetector* service_pattern_detector;
index 269f2fa6d45dd7e4f272d5e1bfac50a141780bf1..b9060313543c2f015590f839b6345598f8b3360e 100644 (file)
@@ -122,7 +122,7 @@ void AppIdEveProcessEventHandler::handle(DataEvent& event, Flow* flow)
         asd->tsession->set_tls_host(server_name.c_str(), server_name.length());
         asd->set_tls_host();
 
-        odp_ctxt.get_ssl_matchers().scan_hostname(reinterpret_cast<const uint8_t*>(server_name.c_str()),
+        odp_ctxt.get_host_matchers().scan_hostname(reinterpret_cast<const uint8_t*>(server_name.c_str()),
             server_name.length(), tmp_client_id, tmp_payload_id);
         asd->set_payload_id(tmp_payload_id);
     }
index 03490ccedafb37f8d100313e4bbc2d991b42c06e..9e196b1d9b5908c539808d94857f82b9dc27f221 100644 (file)
@@ -547,7 +547,7 @@ void AppIdSession::examine_ssl_metadata(AppidChangeBits& change_bits)
     if (tls_str)
     {
         size_t size = strlen(tls_str);
-        if (odp_ctxt.get_ssl_matchers().scan_cname((const uint8_t*)tls_str, size,
+        if (odp_ctxt.get_host_matchers().scan_cname((const uint8_t*)tls_str, size,
             client_id, payload_id))
         {
             set_client_appid_data(client_id, change_bits);
@@ -558,7 +558,7 @@ void AppIdSession::examine_ssl_metadata(AppidChangeBits& change_bits)
     if ((scan_flags & SCAN_SSL_HOST_FLAG) and (tls_str = tsession->get_tls_host()))
     {
         size_t size = strlen(tls_str);
-        if (odp_ctxt.get_ssl_matchers().scan_hostname((const uint8_t*)tls_str, size,
+        if (odp_ctxt.get_host_matchers().scan_hostname((const uint8_t*)tls_str, size,
             client_id, payload_id))
         {
             if (api.client.get_id() == APP_ID_NONE or api.client.get_id() == APP_ID_SSL_CLIENT)
@@ -570,7 +570,7 @@ void AppIdSession::examine_ssl_metadata(AppidChangeBits& change_bits)
     if ((scan_flags & SCAN_SSL_CERTIFICATE_FLAG) and (tls_str = tsession->get_tls_cname()))
     {
         size_t size = strlen(tls_str);
-        if (odp_ctxt.get_ssl_matchers().scan_cname((const uint8_t*)tls_str, size,
+        if (odp_ctxt.get_host_matchers().scan_cname((const uint8_t*)tls_str, size,
             client_id, payload_id))
         {
             if (api.client.get_id() == APP_ID_NONE or api.client.get_id() == APP_ID_SSL_CLIENT)
diff --git a/src/network_inspectors/appid/detector_plugins/host_patterns.cc b/src/network_inspectors/appid/detector_plugins/host_patterns.cc
new file mode 100644 (file)
index 0000000..5de5d7f
--- /dev/null
@@ -0,0 +1,304 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2025 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.
+//--------------------------------------------------------------------------
+
+// host_patterns.cc author Shravan Rangaraju <shrarang@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cassert>
+
+#include "host_patterns.h"
+
+#include "utils/util.h"
+
+using namespace snort;
+
+#define HOST_PATTERN_CERT_TYPE_MASK 6 // HostPatternType::HOST_PATTERN_TYPE_SNI | HostPatternType::HOST_PATTERN_TYPE_CNAME
+
+int cert_pattern_match(void* id, void*, int match_end_pos, void* data, void*);
+int cname_pattern_match(void* id, void*, int match_end_pos, void* data, void*);
+int url_pattern_match(void* id, void*, int match_end_pos, void* data, void*);
+
+static void create_matcher(SearchTool& matcher, HostPatternList* list, unsigned& pattern_count)
+{
+    size_t* pattern_index;
+    size_t size = 0;
+    HostPatternList* element = nullptr;
+
+    pattern_index = &size;
+
+    for (element = list; element; element = element->next)
+    {
+        matcher.add(element->dpattern->pattern,
+            element->dpattern->pattern_size, element->dpattern, true, element->dpattern->is_literal);
+        (*pattern_index)++;
+    }
+    pattern_count = size;
+    matcher.prep();
+}
+
+int cert_pattern_match(void* id, void*, int match_end_pos, void* data, void*)
+{
+    HostPattern* target = (HostPattern*)id;
+
+    if ( target->pattern_type & HOST_PATTERN_CERT_TYPE_MASK )
+    {
+        MatchedHostPatterns* cm;
+        MatchedHostPatterns** matches = (MatchedHostPatterns**)data;
+
+        cm = (MatchedHostPatterns*)snort_alloc(sizeof(MatchedHostPatterns));
+        cm->mpattern = target;
+        cm->match_start_pos = match_end_pos - target->pattern_size;
+        cm->next = *matches;
+        *matches = cm;
+    }
+    return 0;
+}
+
+int cname_pattern_match(void* id, void*, int match_end_pos, void* data, void*)
+{
+    HostPattern* target = (HostPattern*)id;
+
+    if ( target->pattern_type & HostPatternType::HOST_PATTERN_TYPE_CNAME )
+    {
+        MatchedHostPatterns* cm;
+        MatchedHostPatterns** matches = (MatchedHostPatterns**)data;
+
+        cm = (MatchedHostPatterns*)snort_alloc(sizeof(MatchedHostPatterns));
+        cm->mpattern = target;
+        cm->match_start_pos = match_end_pos - target->pattern_size;
+        cm->next = *matches;
+        *matches = cm;
+    }
+    return 0;
+}
+
+int url_pattern_match(void* id, void*, int match_end_pos, void* data, void*)
+{
+    HostPattern* target = (HostPattern*)id;
+
+    if ( target->pattern_type & HostPatternType::HOST_PATTERN_TYPE_URL )
+    {
+        MatchedHostPatterns* cm;
+        MatchedHostPatterns** matches = (MatchedHostPatterns**)data;
+        
+        cm = (MatchedHostPatterns*)snort_alloc(sizeof(MatchedHostPatterns));
+        cm->mpattern = target;
+        cm->match_start_pos = match_end_pos - target->pattern_size;
+        cm->next = *matches;
+        *matches = cm;
+    }
+    return 0;
+}
+/*
+Only patterns that match end of the payload AND
+(match the start of the payload
+or match after '.'
+or patterns starting with '.')
+are considered a match. */
+inline bool host_pattern_validate_match(const MatchedHostPatterns * const mp, const uint8_t* data, const size_t& data_size)
+{
+    return mp->match_start_pos + mp->mpattern->pattern_size == data_size and
+            (mp->match_start_pos == 0 or
+            data[mp->match_start_pos-1] == '.' or
+            *mp->mpattern->pattern == '.');
+}
+
+inline bool host_pattern_validate_url_match(const MatchedHostPatterns * const mp, const uint8_t* data)
+{
+        return mp->match_start_pos == 0 or
+                data[mp->match_start_pos-1] == '.';
+}
+
+inline bool is_perfect_literal_match(const MatchedHostPatterns * const mp, const size_t& data_size)
+{
+    return mp->mpattern->is_literal and  mp->match_start_pos == 0 and
+            (mp->match_start_pos + mp->mpattern->pattern_size == data_size);
+
+}
+
+template<HostPatternType T>
+bool scan_patterns(SearchTool& matcher, const uint8_t* data, size_t size,
+    AppId& client_id, AppId& payload_id, bool* is_referred_appid = nullptr)
+{
+    MatchedHostPatterns* mp = nullptr;
+    HostPattern* best_match = nullptr;
+
+    matcher.find_all((const char*)data, size, 
+        T == HostPatternType::HOST_PATTERN_TYPE_CNAME ? cname_pattern_match :
+        T == HostPatternType::HOST_PATTERN_TYPE_URL ? url_pattern_match :
+        cert_pattern_match, false, &mp);
+
+    if ( !mp )
+        return false;
+
+    MatchedHostPatterns* tmp = mp;
+
+    while ( tmp )
+    {
+        auto match = tmp->mpattern;
+        if ( !match->is_literal or ( T == HostPatternType::HOST_PATTERN_TYPE_URL ? host_pattern_validate_url_match(tmp, data) : host_pattern_validate_match(tmp, data, size) ))
+        {
+            if ( T != HostPatternType::HOST_PATTERN_TYPE_URL)
+            {
+                if ( is_perfect_literal_match(tmp, size) )
+                {
+                    best_match = match;
+                    break;
+                }
+            }
+
+            if ( !best_match or match->pattern_size > best_match->pattern_size )
+            {
+                best_match = match;
+            }
+        }
+        tmp = tmp->next;
+    }
+
+    while ( mp )
+    {
+        MatchedHostPatterns* tmpMp = mp;
+        mp = mp->next;
+        snort_free(tmpMp);
+    }
+
+    if ( !best_match )
+        return false;
+
+    if ( T == HostPatternType::HOST_PATTERN_TYPE_URL )
+    {
+        client_id = best_match->client_id;
+        payload_id = best_match->payload_id;
+        if(is_referred_appid)
+        {
+            *is_referred_appid = best_match->is_referred;
+        }
+    }
+    else
+    {
+        if (best_match->type)
+        {
+            client_id = best_match->client_id;
+            payload_id = 0;
+        }
+        else
+        {
+            client_id =  APP_ID_SSL_CLIENT;
+            payload_id = best_match->payload_id;
+        }
+    }
+
+    return true;
+}
+
+static void free_patterns(HostPatternList*& list)
+{
+    HostPatternList* 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(HostPatternList*& list, const uint8_t* pattern_str, size_t
+    pattern_size, uint8_t type, AppId client_id, AppId payload_id, HostPatternType pattern_type, bool is_literal, bool is_referred, HostTmpCache& set)
+{
+
+    HostTmpCacheKey key { pattern_str, pattern_size, client_id, payload_id };
+    auto tmp_lookup_it = set.find(key);
+    if ( tmp_lookup_it != set.end() )
+    {
+        auto cached_list_entry = tmp_lookup_it->second;
+
+        cached_list_entry->pattern_type |= pattern_type;
+        cached_list_entry->is_referred |= is_referred;
+        return;
+    }
+
+    HostPatternList* new_host_pattern;
+
+    new_host_pattern = (HostPatternList*)snort_calloc(sizeof(HostPatternList));
+    new_host_pattern->dpattern = (HostPattern*)snort_calloc(sizeof(HostPattern));
+    new_host_pattern->dpattern->type = type;
+    new_host_pattern->dpattern->client_id = client_id;
+    new_host_pattern->dpattern->payload_id = payload_id;
+    new_host_pattern->dpattern->pattern_size = pattern_size;
+    new_host_pattern->dpattern->pattern_type = pattern_type;
+    new_host_pattern->dpattern->is_literal = is_literal;
+    new_host_pattern->dpattern->is_referred = is_referred;
+    new_host_pattern->dpattern->pattern = (uint8_t*)snort_alloc(pattern_size);
+    memcpy(new_host_pattern->dpattern->pattern, pattern_str, pattern_size);
+
+    new_host_pattern->next = list;
+    list = new_host_pattern;
+
+    key.pattern = new_host_pattern->dpattern->pattern;
+    set[key] = new_host_pattern->dpattern;
+}
+
+HostPatternMatchers::~HostPatternMatchers()
+{
+    free_patterns(host_pattern_list);
+}
+
+void HostPatternMatchers::add_host_pattern(const uint8_t* pattern_str, size_t pattern_size, uint8_t type, AppId client_id, AppId payload_id, HostPatternType pattern_type, bool is_literal, bool is_referred)
+{
+    add_pattern(host_pattern_list, pattern_str, pattern_size, type, client_id, payload_id, pattern_type, is_literal, is_referred, host_pattern_set);
+}
+
+void HostPatternMatchers::finalize_patterns()
+{
+    create_matcher(host_matcher, host_pattern_list, pattern_count);
+    host_pattern_set.clear();
+}
+
+void HostPatternMatchers::reload_patterns()
+{
+    host_matcher.reload();
+}
+
+unsigned HostPatternMatchers::get_pattern_count()
+{
+    return pattern_count;
+}
+
+bool HostPatternMatchers::scan_url(const uint8_t *url, size_t size, AppId &client_id, AppId &payload_id, bool* is_referred_appid)
+{
+    return scan_patterns<HostPatternType::HOST_PATTERN_TYPE_URL>(host_matcher, url, size, client_id, payload_id, is_referred_appid);
+}
+
+bool HostPatternMatchers::scan_hostname(const uint8_t* hostname, size_t size, AppId& client_id, AppId& payload_id)
+{
+    return scan_patterns<HostPatternType::HOST_PATTERN_TYPE_SNI>(host_matcher, hostname, size, client_id, payload_id);
+}
+
+bool HostPatternMatchers::scan_cname(const uint8_t* common_name, size_t size, AppId& client_id, AppId& payload_id)
+{
+    return scan_patterns<HostPatternType::HOST_PATTERN_TYPE_CNAME>(host_matcher, common_name, size, client_id, payload_id);
+}
diff --git a/src/network_inspectors/appid/detector_plugins/host_patterns.h b/src/network_inspectors/appid/detector_plugins/host_patterns.h
new file mode 100644 (file)
index 0000000..ce6eb04
--- /dev/null
@@ -0,0 +1,112 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2025 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.
+//--------------------------------------------------------------------------
+
+// host_patterns.h author Shravan Rangaraju <shrarang@cisco.com>
+
+#ifndef HOST_PATTERNS_H
+#define HOST_PATTERNS_H
+
+#include <cstring>
+#include <unordered_map>
+#include "search_engines/search_tool.h"
+#include "application_ids.h"
+
+enum HostPatternType : uint8_t
+{
+    HOST_PATTERN_TYPE_UNDEFINED = 0,
+    HOST_PATTERN_TYPE_SNI = (1 << 1),
+    HOST_PATTERN_TYPE_CNAME = (1 << 2),
+    HOST_PATTERN_TYPE_URL = (1 << 3)
+};
+
+struct HostPattern
+{
+    uint8_t type;
+    AppId client_id;
+    AppId payload_id;
+    uint8_t* pattern;
+    uint32_t pattern_size;
+    uint8_t pattern_type;
+    bool is_literal; // is not regex pattern
+    bool is_referred;
+
+    bool operator==(const HostPattern& v) const
+    {
+        return this->type == v.type and pattern_size == v.pattern_size and this->pattern_type == v.pattern_type
+            and (memcmp(pattern, v.pattern, (size_t)pattern_size) == 0);
+    }
+};
+
+struct HostTmpCacheKey
+{
+    const uint8_t* pattern;
+    size_t pattern_len;
+    AppId cl_id;
+    AppId pl_id;
+
+    inline bool operator==(const HostTmpCacheKey& rhs) const
+    {
+        return (this->pattern_len == rhs.pattern_len) and (this->cl_id == rhs.cl_id) and 
+               (this->pl_id == rhs.pl_id) and
+               (memcmp(this->pattern, rhs.pattern, this->pattern_len) == 0);
+    }
+};
+
+struct HostTmpCacheKeyHasher
+{
+    size_t operator()(const HostTmpCacheKey& key) const
+    {
+        return std::hash<std::string>()(std::string((const char*)key.pattern, key.pattern_len)) ^ std::hash<AppId>()(key.cl_id) ^ std::hash<AppId>()(key.pl_id);
+    }
+};
+
+typedef std::unordered_map<HostTmpCacheKey, HostPattern*, HostTmpCacheKeyHasher> HostTmpCache;
+
+struct MatchedHostPatterns
+{
+    HostPattern* mpattern;
+    uint32_t match_start_pos;
+    struct MatchedHostPatterns* next;
+};
+
+struct HostPatternList
+{
+    HostPattern* dpattern;
+    HostPatternList* next;
+};
+
+class HostPatternMatchers
+{
+public:
+    ~HostPatternMatchers();
+    void add_host_pattern(const uint8_t*, size_t, uint8_t, AppId, AppId, HostPatternType, bool = true, bool = false);
+    void finalize_patterns();
+    void reload_patterns();
+    unsigned get_pattern_count();
+    bool scan_hostname(const uint8_t*, size_t, AppId&, AppId&);
+    bool scan_cname(const uint8_t*, size_t, AppId&, AppId&);
+    bool scan_url(const uint8_t*, size_t, AppId&, AppId&, bool* = nullptr);
+
+private:
+    HostPatternList* host_pattern_list = nullptr;
+    HostTmpCache host_pattern_set;
+    snort::SearchTool host_matcher = snort::SearchTool();
+    unsigned pattern_count = 0;
+};
+
+#endif
index bb89d5637116a02c434e705c8cafe130bee87561..333a21d3baa528549488b4f4ea8b63c6c004106d 100644 (file)
@@ -471,7 +471,7 @@ void HttpPatternMatchers::insert_app_url_pattern(DetectorAppUrlPattern* pattern)
     HttpPatternMatchers::insert_url_pattern(pattern);
 }
 
-int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorHTTPPattern& pattern)
+int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorHTTPPattern& pattern, OdpContext& odp_ctxt)
 {
     assert(pattern.pattern);
 
@@ -492,6 +492,8 @@ int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorHTTPPatter
     else
         detector->appId = pattern.service_id;
 
+    detector->is_referred = odp_ctxt.get_app_info_mgr().get_app_info_flags(detector->payload_id, APPINFO_FLAG_REFERRED);
+
     tMlmpPattern patterns[PATTERN_PART_MAX];
     int num_patterns = parse_multiple_http_patterns((const char*)pattern.pattern, patterns,
         PATTERN_PART_MAX, 0, true);
@@ -499,7 +501,7 @@ int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorHTTPPatter
     return mlmpAddPattern(matcher, patterns, detector);
 }
 
-int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorAppUrlPattern& pattern)
+int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorAppUrlPattern& pattern, OdpContext& odp_ctxt)
 {
     assert(pattern.patterns.host.pattern);
 
@@ -523,6 +525,7 @@ int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorAppUrlPatt
     detector->service_id = pattern.userData.service_id;
     detector->client_id = pattern.userData.client_id;
     detector->seq = SINGLE;
+    detector->is_referred = odp_ctxt.get_app_info_mgr().get_app_info_flags(detector->payload_id, APPINFO_FLAG_REFERRED);
     if (pattern.userData.appId > APP_ID_NONE)
         detector->appId = pattern.userData.appId;
     else if (pattern.userData.payload_id > APP_ID_NONE)
@@ -543,18 +546,18 @@ int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorAppUrlPatt
     return mlmpAddPattern(matcher, patterns, detector);
 }
 
-int HttpPatternMatchers::process_mlmp_patterns()
+int HttpPatternMatchers::process_mlmp_patterns(OdpContext& ctxt)
 {
     for (auto& pattern: host_payload_patterns)
-        if ( add_mlmp_pattern(host_url_matcher, pattern) < 0 )
+        if ( add_mlmp_pattern(host_url_matcher, pattern, ctxt) < 0 )
             return -1;
 
     if (std::any_of(rtmp_url_patterns.begin(), rtmp_url_patterns.end(),
-        [this](DetectorAppUrlPattern* pattern){ return add_mlmp_pattern(rtmp_host_url_matcher, *pattern) < 0; }))
+        [this, &ctxt](DetectorAppUrlPattern* pattern) mutable { return add_mlmp_pattern(rtmp_host_url_matcher, *pattern, ctxt) < 0; }))
         return -1;
 
     if (std::any_of(app_url_patterns.begin(), app_url_patterns.end(),
-        [this](DetectorAppUrlPattern* pattern){ return add_mlmp_pattern(host_url_matcher, *pattern) < 0; }))
+        [this, &ctxt](DetectorAppUrlPattern* pattern) mutable { return add_mlmp_pattern(host_url_matcher, *pattern, ctxt) < 0; }))
         return -1;
 
     return 0;
@@ -642,7 +645,7 @@ static int http_pattern_match(void* id, void*, int match_end_pos, void* data, vo
         return 0;
 }
 
-int HttpPatternMatchers::process_host_patterns(DetectorHTTPPatterns& patterns)
+int HttpPatternMatchers::process_host_patterns(const DetectorHTTPPatterns& patterns, OdpContext& ctxt)
 {
     if (!host_url_matcher)
         host_url_matcher = mlmpCreate();
@@ -650,13 +653,14 @@ int HttpPatternMatchers::process_host_patterns(DetectorHTTPPatterns& patterns)
     if (!rtmp_host_url_matcher)
         rtmp_host_url_matcher = mlmpCreate();
 
-    for (auto& pat : patterns)
+    for (const auto& pat : patterns)
     {
-        if ( add_mlmp_pattern(host_url_matcher, pat) < 0 )
-            return -1;
+        ctxt.get_host_matchers().add_host_pattern(pat.pattern, pat.pattern_size, 0,
+            pat.client_id, pat.payload_id, HostPatternType::HOST_PATTERN_TYPE_URL, true,
+            ctxt.get_app_info_mgr().get_app_info_flags(pat.payload_id, APPINFO_FLAG_REFERRED));
     }
 
-    if ( HttpPatternMatchers::process_mlmp_patterns() < 0 )
+    if ( HttpPatternMatchers::process_mlmp_patterns(ctxt) < 0 )
         return -1;
 
     mlmpProcessPatterns(host_url_matcher);
@@ -717,14 +721,14 @@ static void process_patterns(SearchTool& matcher, DetectorHTTPPatterns& patterns
         matcher.prep();
 }
 
-int HttpPatternMatchers::finalize_patterns()
+int HttpPatternMatchers::finalize_patterns(OdpContext& ctxt)
 {
     process_patterns(via_matcher, static_via_http_detector_patterns);
     process_patterns(url_matcher, url_patterns);
     process_patterns(client_agent_matcher, static_client_agent_patterns, false);
     process_patterns(client_agent_matcher, client_agent_patterns);
 
-    if (process_host_patterns(static_http_host_payload_patterns) < 0)
+    if (process_host_patterns(static_http_host_payload_patterns, ctxt) < 0)
         return -1;
 
     process_patterns(content_type_matcher, static_content_type_patterns, false);
@@ -1410,50 +1414,36 @@ bool HttpPatternMatchers::get_appid_from_url(const char* host, const char* url,
     const char* referer, AppId* ClientAppId, AppId* serviceAppId, AppId* payloadAppId,
     AppId* referredPayloadAppId, bool from_rtmp, OdpContext& odp_ctxt)
 {
-    char* temp_host = nullptr;
+    if (!host && !url)
+        return false;
+
     tMlmpPattern patterns[3];
     bool payload_found = false;
     tMlmpTree* matcher = from_rtmp ? rtmp_host_url_matcher : host_url_matcher;
-
-    if (!host && !url)
-        return false;
+    auto& host_matcher = odp_ctxt.get_host_matchers();
+    bool is_referred_appid = false;
 
     int url_len = 0;
     if (url)
     {
-        size_t scheme_len = strlen(url);
-        if (scheme_len > URL_SCHEME_MAX_LEN)
-            scheme_len = URL_SCHEME_MAX_LEN;    // only search the first few bytes for scheme
-        const char* url_offset = (const char*)service_strstr((const uint8_t*)url, scheme_len,
-            (const uint8_t*)URL_SCHEME_END_PATTERN, sizeof(URL_SCHEME_END_PATTERN)-1);
+        const char* url_offset = strstr(url, URL_SCHEME_END_PATTERN);
         if (url_offset)
-            url_offset += sizeof(URL_SCHEME_END_PATTERN)-1;
+            url = url_offset + sizeof(URL_SCHEME_END_PATTERN)-1;
         else
             return false;
 
-        url = url_offset;
         url_len = strlen(url);
     }
 
     int host_len;
     if (!host)
     {
-        host = strchr(url, '/');
-        if (host != nullptr)
-            host_len = host - url;
+        host = url;
+        auto path_offset = strchr(url, '/');
+        if (path_offset != nullptr)
+            host_len = path_offset - url;
         else
             host_len = url_len;
-        if (host_len > 0)
-        {
-            temp_host = snort_strndup(url, host_len);
-            if (!temp_host)
-            {
-                host_len = 0;
-                host = nullptr;
-            }
-            else
-                host = temp_host;
-        }
     }
     else
         host_len = strlen(host);
@@ -1464,102 +1454,141 @@ bool HttpPatternMatchers::get_appid_from_url(const char* host, const char* url,
     {
         if (url_len < host_len)
         {
-            snort_free(temp_host);
             return false;
         }
         path = strchr(url, '/');
         if (path)
+        {
             path_len = url + url_len - path;
+            if(path_len == 1)
+                path_len = 0;
+        }
+            
     }
 
-    if (!path_len)
+    if (!path_len and !from_rtmp)
     {
-        path = "/";
-        path_len = 1;
+        payload_found = host_matcher.scan_url((const uint8_t*)host, host_len, *ClientAppId , *payloadAppId);
     }
+    else
+    {
+        if (!path_len)
+        {
+            path = "/";
+            path_len = 1;
+        }
 
-    patterns[0].pattern = (const uint8_t*)host;
-    patterns[0].patternSize = host_len;
-    patterns[1].pattern = (const uint8_t*)path;
-    patterns[1].patternSize = path_len;
-    patterns[2].pattern = nullptr;
+        patterns[0].pattern = (const uint8_t*)host;
+        patterns[0].patternSize = host_len;
+        patterns[1].pattern = (const uint8_t*)path;
+        patterns[1].patternSize = path_len;
+        patterns[2].pattern = nullptr;
 
-    HostUrlDetectorPattern* data = (HostUrlDetectorPattern*)mlmpMatchPatternUrl(matcher, patterns);
-    if ( data )
-    {
-        payload_found = true;
-        if ( url )
+        HostUrlDetectorPattern* data = (HostUrlDetectorPattern*)mlmpMatchPatternUrl(matcher, patterns);
+        if ( data )
         {
-            const char* q = strchr(url, '?');
-            if ( q != nullptr )
+            if ( url )
             {
-                tMlpPattern query;
-                char temp_ver[MAX_VERSION_SIZE];
-                temp_ver[0] = 0;
-                query.pattern = (const uint8_t*)++q;
-                query.patternSize = strlen(q);
+                const char* q = strchr(url, '?');
+                if ( q != nullptr )
+                {
+                    tMlpPattern query;
+                    char temp_ver[MAX_VERSION_SIZE];
+                    temp_ver[0] = 0;
+                    query.pattern = (const uint8_t*)++q;
+                    query.patternSize = strlen(q);
 
-                match_query_elements(&query, &data->query, temp_ver, MAX_VERSION_SIZE);
+                    match_query_elements(&query, &data->query, temp_ver, MAX_VERSION_SIZE);
 
-                if (temp_ver[0] != 0)
-                    replace_optional_string(version, temp_ver);
+                    if (temp_ver[0] != 0)
+                        replace_optional_string(version, temp_ver);
+                }
             }
+
+            *ClientAppId = data->client_id;
+            *serviceAppId = data->service_id;
+            *payloadAppId = data->payload_id;
+            payload_found = data->payload_id;
+            is_referred_appid = data->is_referred;
         }
 
-        *ClientAppId = data->client_id;
-        *serviceAppId = data->service_id;
-        *payloadAppId = data->payload_id;
+        if (!payload_found and !from_rtmp)
+        {
+            payload_found = host_matcher.scan_url((const uint8_t*)host, host_len, *ClientAppId, *payloadAppId, &is_referred_appid);
+        }
     }
 
-    snort_free(temp_host);
-
     /* if referred_id feature id disabled, referer will be null */
-    if ( referer and (referer[0] != '\0') and (!payload_found or
-        odp_ctxt.get_app_info_mgr().get_app_info_flags(data->payload_id,
-        APPINFO_FLAG_REFERRED)) )
+    if ( (!payload_found or is_referred_appid)
+         and ( referer and (referer[0] != '\0') ) )
     {
         const char* referer_start = referer;
-        size_t ref_len = strlen(referer);
 
-        const char* referer_offset = (const char*)service_strstr((const uint8_t*)referer_start, ref_len,
-            (const uint8_t*)URL_SCHEME_END_PATTERN, sizeof(URL_SCHEME_END_PATTERN)-1);
+        const char* referer_offset = strstr(referer_start, URL_SCHEME_END_PATTERN);
 
         if ( !referer_offset )
             return payload_found;
 
-        referer_offset += sizeof(URL_SCHEME_END_PATTERN)-1;
-        referer_start = referer_offset;
+        referer_start = referer_offset + sizeof(URL_SCHEME_END_PATTERN)-1;
         int referer_len = strlen(referer_start);
         const char* referer_path = strchr(referer_start, '/');
-        int referer_path_len = 0;
+        bool referer_found = false;
 
-        if ( referer_path )
-        {
-            referer_path_len = strlen(referer_path);
-            referer_len -= referer_path_len;
-        }
-        else
+        if ( referer_path or from_rtmp)
         {
-            referer_path = "/";
-            referer_path_len = 1;
+            int referer_path_len = 0;
+
+            if(!referer_path)
+            {
+                referer_path = "/";
+                referer_path_len = 1;
+            }
+            else
+            {
+                referer_path_len = strlen(referer_path);
+                referer_len -= referer_path_len;
+            }
+
+            if ( referer_len > 0 )
+            {
+                patterns[0].pattern = (const uint8_t*)referer_start;
+                patterns[0].patternSize = referer_len;
+                patterns[1].pattern = (const uint8_t*)referer_path;
+                patterns[1].patternSize = referer_path_len;
+                patterns[2].pattern = nullptr;
+                HostUrlDetectorPattern* url_pattern_data = (HostUrlDetectorPattern*)mlmpMatchPatternUrl(matcher,
+                    patterns);
+                if ( url_pattern_data != nullptr )
+                {
+                    referer_found = true;
+                    if ( payload_found )
+                        *referredPayloadAppId = *payloadAppId;
+                    else
+                        payload_found = true;
+                    *payloadAppId = url_pattern_data->payload_id;
+                }
+            }
         }
 
-        if ( referer_len > 0 )
+        if ( !referer_found and !from_rtmp)
         {
-            patterns[0].pattern = (const uint8_t*)referer_start;
-            patterns[0].patternSize = referer_len;
-            patterns[1].pattern = (const uint8_t*)referer_path;
-            patterns[1].patternSize = referer_path_len;
-            patterns[2].pattern = nullptr;
-            HostUrlDetectorPattern* url_pattern_data = (HostUrlDetectorPattern*)mlmpMatchPatternUrl(matcher,
-                patterns);
-            if ( url_pattern_data != nullptr )
+            AppId cl_id = 0;
+            AppId pl_id = 0;
+
+            host_matcher.scan_url((const uint8_t*)referer_start, referer_len, cl_id, pl_id);
+
+            if ( pl_id )
             {
                 if ( payload_found )
+                {
                     *referredPayloadAppId = *payloadAppId;
+                }
                 else
+                {
                     payload_found = true;
-                *payloadAppId = url_pattern_data->payload_id;
+                }
+
+                *payloadAppId = pl_id;
             }
         }
     }
index 436ac271d134a41733c33bcb4382200228167119..4ce7061f14b9eea384c485dd5b1722febc7b048e 100644 (file)
@@ -275,6 +275,7 @@ public:
     uint32_t client_id = APP_ID_NONE;
     AppId appId = APP_ID_NONE;
     DHPSequence seq = SINGLE;
+    bool is_referred = false;
 };
 
 class HttpPatternMatchers
@@ -285,7 +286,7 @@ public:
     { }
     ~HttpPatternMatchers();
 
-    int finalize_patterns();
+    int finalize_patterns(OdpContext&);
     void reload_patterns();
     unsigned get_pattern_count();
     void insert_chp_pattern(CHPListElement*);
@@ -296,8 +297,8 @@ public:
     void insert_rtmp_url_pattern(DetectorAppUrlPattern*);
     void insert_app_url_pattern(DetectorAppUrlPattern*);
     int process_chp_list(CHPListElement*);
-    int process_host_patterns(DetectorHTTPPatterns&);
-    int process_mlmp_patterns();
+    int process_host_patterns(const DetectorHTTPPatterns&, OdpContext&);
+    int process_mlmp_patterns(OdpContext&);
     void process_http_field_patterns(FieldPattern*, size_t);
 
     void scan_key_chp(ChpMatchDescriptor&);
@@ -334,8 +335,8 @@ private:
     unsigned chp_pattern_count = 0;
 
     void free_chp_app_elements();
-    int add_mlmp_pattern(tMlmpTree* matcher, DetectorHTTPPattern& pattern );
-    int add_mlmp_pattern(tMlmpTree* matcher, DetectorAppUrlPattern& pattern);
+    int add_mlmp_pattern(tMlmpTree* matcher, DetectorHTTPPattern& pattern, OdpContext& odp_ctxt);
+    int add_mlmp_pattern(tMlmpTree* matcher, DetectorAppUrlPattern& pattern, OdpContext& odp_ctxt);
 
 };
 
diff --git a/src/network_inspectors/appid/detector_plugins/ssl_patterns.cc b/src/network_inspectors/appid/detector_plugins/ssl_patterns.cc
deleted file mode 100644 (file)
index e787cd3..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2020-2025 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 <shrarang@cisco.com>
-
-#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, CnameCache& set, unsigned& pattern_count)
-{
-    size_t* pattern_index;
-    size_t size = 0;
-    SslPatternList* element = nullptr;
-
-    pattern_index = &size;
-
-    for (element = list; element; element = element->next)
-    {
-        if (!element->dpattern->is_cname and set.count(*(element->dpattern)))
-            continue;
-
-        matcher.add(element->dpattern->pattern,
-            element->dpattern->pattern_size, element->dpattern, true, element->dpattern->is_literal);
-        (*pattern_index)++;
-    }
-    pattern_count = size;
-    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 int cname_pattern_match(void* id, void*, int match_end_pos, void* data, void*)
-{
-    MatchedSslPatterns* cm;
-    MatchedSslPatterns** matches = (MatchedSslPatterns**)data;
-    SslPattern* target = (SslPattern*)id;
-
-    /* Only collect the match if it is a cname pattern. */
-    if (target->is_cname)
-    {
-        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;
-}
-/*
-Only patterns that match end of the payload AND
-(match the start of the payload
-or match after '.'
-or patterns starting with '.')
-are considered a match. */
-inline static bool ssl_pattern_validate_match(const MatchedSslPatterns * const mp, const uint8_t* data, int data_size)
-{
-    return mp->match_start_pos + mp->mpattern->pattern_size == data_size and
-            (mp->match_start_pos == 0 or
-            data[mp->match_start_pos-1] == '.' or
-            *mp->mpattern->pattern == '.');
-}
-
-inline static bool is_perfect_literal_match(const MatchedSslPatterns * const mp, int data_size)
-{
-    return mp->mpattern->is_literal and
-            (mp->match_start_pos + mp->mpattern->pattern_size == data_size) and
-            mp->match_start_pos == 0;
-
-}
-
-static bool scan_patterns(SearchTool& matcher, const uint8_t* data, size_t size,
-    AppId& client_id, AppId& payload_id, bool is_cname_search)
-{
-    MatchedSslPatterns* mp = nullptr;
-    SslPattern* best_match = nullptr;
-
-    if (is_cname_search)
-        matcher.find_all((const char*)data, size, cname_pattern_match, false, &mp);
-    else
-        matcher.find_all((const char*)data, size, cert_pattern_match, false, &mp);
-
-    if (!mp)
-        return false;
-
-    MatchedSslPatterns* tmp = mp;
-
-    while (tmp)
-    {
-        if (!tmp->mpattern->is_literal or ssl_pattern_validate_match(tmp, data, (int)size))
-        {
-            if(is_perfect_literal_match(tmp, (int)size))
-            {
-                best_match = tmp->mpattern;
-                break;
-            }
-
-            if (!best_match or
-                    tmp->mpattern->pattern_size > best_match->pattern_size)
-            {
-                best_match = tmp->mpattern;
-            }
-        }
-        tmp = tmp->next;
-    }
-
-    while (mp)
-    {
-        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, bool is_cname, bool is_literal, CnameCache& set)
-{
-    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->dpattern->is_cname = is_cname;
-    new_ssl_pattern->dpattern->is_literal = is_literal;
-
-    new_ssl_pattern->next = list;
-    list = new_ssl_pattern;
-
-    if (is_cname)
-        set.emplace(*(new_ssl_pattern->dpattern));
-}
-
-SslPatternMatchers::~SslPatternMatchers()
-{
-    free_patterns(cert_pattern_list);
-}
-
-void SslPatternMatchers::add_cert_pattern(uint8_t* pattern_str, size_t pattern_size, uint8_t type, AppId app_id, bool is_cname, bool is_literal)
-{
-    add_pattern(cert_pattern_list, pattern_str, pattern_size, type, app_id, is_cname, is_literal, cert_pattern_set);
-}
-
-void SslPatternMatchers::finalize_patterns()
-{
-    create_matcher(ssl_host_matcher, cert_pattern_list, cert_pattern_set, pattern_count);
-    cert_pattern_set.clear();
-}
-
-void SslPatternMatchers::reload_patterns()
-{
-    ssl_host_matcher.reload();
-}
-
-unsigned SslPatternMatchers::get_pattern_count()
-{
-    return pattern_count;
-}
-
-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, false);
-}
-
-bool SslPatternMatchers::scan_cname(const uint8_t* common_name, size_t size, AppId& client_id, AppId& payload_id)
-{
-    return scan_patterns(ssl_host_matcher, common_name, size, client_id, payload_id, true);
-}
diff --git a/src/network_inspectors/appid/detector_plugins/ssl_patterns.h b/src/network_inspectors/appid/detector_plugins/ssl_patterns.h
deleted file mode 100644 (file)
index 59f098b..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2020-2025 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 <shrarang@cisco.com>
-
-#ifndef SSL_PATTERNS_H
-#define SSL_PATTERNS_H
-
-#include <cstring>
-#include <unordered_set>
-#include "search_engines/search_tool.h"
-#include "application_ids.h"
-
-struct SslPattern
-{
-    uint8_t type;
-    AppId app_id;
-    uint8_t* pattern;
-    int pattern_size;
-    bool is_cname;
-    bool is_literal; // is not regex pattern
-
-    bool operator==(const SslPattern& v) const
-    {
-        return this->type == v.type and pattern_size == v.pattern_size
-            and (memcmp(pattern, v.pattern, (size_t)pattern_size) == 0);
-    }
-};
-
-struct SslCacheKeyHasher
-{
-    size_t operator()(const SslPattern& key) const
-    {
-        return std::hash<std::string>{}(std::string((char*)key.pattern, key.pattern_size));
-    }
-};
-
-typedef std::unordered_set<SslPattern, SslCacheKeyHasher> CnameCache;
-
-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, bool, bool = true);
-    void finalize_patterns();
-    void reload_patterns();
-    unsigned get_pattern_count();
-    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;
-    CnameCache cert_pattern_set;
-    snort::SearchTool ssl_host_matcher = snort::SearchTool();
-    unsigned pattern_count = 0;
-};
-
-#endif
index d428bc231007c0cd7c1a33a5550fad50262d6848..ba5ddf3374d36b6bfa3766183a20aa7d9354957a 100644 (file)
@@ -163,7 +163,7 @@ void AppIdModule::reset_stats() { }
 
 DnsPatternMatchers::~DnsPatternMatchers() = default;
 EveCaPatternMatchers::~EveCaPatternMatchers() = default;
-SslPatternMatchers::~SslPatternMatchers() = default;
+HostPatternMatchers::~HostPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
 AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 CipPatternMatchers::~CipPatternMatchers() = default;
index 71674abd222f70334aded7204f6a9d514a4e0384..8f454effb258f24d8bd9f827255785a32cd34f26 100644 (file)
@@ -94,13 +94,15 @@ int AppIdDiscovery::add_service_port(AppIdDetector*, ServiceDetectorPort const&)
 DnsPatternMatchers::~DnsPatternMatchers() = default;
 EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
-SslPatternMatchers::~SslPatternMatchers() = default;
+HostPatternMatchers::~HostPatternMatchers() = default;
 AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 UserDataMap::~UserDataMap() = default;
 CipPatternMatchers::~CipPatternMatchers() = default;
+bool HostPatternMatchers::scan_url(const uint8_t*, size_t, AppId&, AppId&, bool*){ return true; }   
 void AppIdModule::reset_stats() {}
 bool AppIdInspector::configure(snort::SnortConfig*) { return true; }
 void appid_log(const snort::Packet*, unsigned char, char const*, ...) { }
+void HostPatternMatchers::add_host_pattern(unsigned char const*, unsigned long, unsigned char, int, int, HostPatternType, bool, bool) {}
 
 TEST_GROUP(http_url_patterns_tests)
 {
index 900cdd8cf600649882d1c4675d7196e8afa5d626..bc28f9302a0feccf16d27f1c3e9b37e18215fb2f 100644 (file)
@@ -1310,15 +1310,23 @@ static int detector_add_http_pattern(lua_State* L)
     }
 
     uint32_t app_id = lua_tointeger(L, ++index);
-    DetectorHTTPPattern pattern;
-    if (pattern.init(pattern_str, pattern_size, seq, service_id, client_id,
-        payload_id, app_id))
+    if (pat_type != HTTP_USER_AGENT)
     {
-        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);
-        aim.set_app_info_active(app_id);
+        ud->get_odp_ctxt().get_host_matchers().add_host_pattern(pattern_str, pattern_size, 0, client_id,
+            payload_id, HostPatternType::HOST_PATTERN_TYPE_URL, true, ud->get_odp_ctxt().get_app_info_mgr().get_app_info_flags(payload_id, APPINFO_FLAG_REFERRED));
+    }
+    else
+    {
+        DetectorHTTPPattern pattern;
+        if (pattern.init(pattern_str, pattern_size, seq, service_id, client_id,
+            payload_id, app_id))
+        {
+            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);
+            aim.set_app_info_active(app_id);
+        }
     }
 
     return 0;
@@ -1346,9 +1354,8 @@ static int detector_add_ssl_cert_pattern(lua_State* L)
         return 0;
     }
 
-    uint8_t* pattern_str = (uint8_t*)snort_strdup(tmp_string);
-    ud->get_odp_ctxt().get_ssl_matchers().add_cert_pattern(pattern_str, pattern_size, type, app_id,
-        false);
+    ud->get_odp_ctxt().get_host_matchers().add_host_pattern((const uint8_t*)tmp_string, pattern_size, type, type ? app_id : 0, !type ? app_id : 0,
+        HostPatternType::HOST_PATTERN_TYPE_SNI);
     ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(app_id);
 
     return 0;
@@ -1382,9 +1389,8 @@ static int detector_add_ssl_cert_regex_pattern(lua_State* L)
         return 0;
     }
 
-    uint8_t* pattern_str = (uint8_t*)snort_strdup(tmp_string);
-    ud->get_odp_ctxt().get_ssl_matchers().add_cert_pattern(pattern_str, pattern_size, type, app_id,
-        false, false);
+    ud->get_odp_ctxt().get_host_matchers().add_host_pattern((const uint8_t*)tmp_string, pattern_size, type, type ? app_id : 0, !type ? app_id : 0,
+        HostPatternType::HOST_PATTERN_TYPE_SNI, false);
     ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(app_id);
 
     return 0;
@@ -1412,9 +1418,8 @@ static int detector_add_ssl_cname_pattern(lua_State* L)
         return 0;
     }
 
-    uint8_t* pattern_str = (uint8_t*)snort_strdup(tmp_string);
-    ud->get_odp_ctxt().get_ssl_matchers().add_cert_pattern(pattern_str, pattern_size, type, app_id,
-        true);
+    ud->get_odp_ctxt().get_host_matchers().add_host_pattern((const uint8_t*)tmp_string, pattern_size, type, type ? app_id : 0, !type ? app_id : 0,
+        HostPatternType::HOST_PATTERN_TYPE_CNAME);
     ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(app_id);
 
     return 0;
@@ -1449,9 +1454,8 @@ static int detector_add_ssl_cname_regex_pattern(lua_State* L)
         return 0;
     }
 
-    uint8_t* pattern_str = (uint8_t*)snort_strdup(tmp_string);
-    ud->get_odp_ctxt().get_ssl_matchers().add_cert_pattern(pattern_str, pattern_size, type, app_id,
-        true, false);
+    ud->get_odp_ctxt().get_host_matchers().add_host_pattern((const uint8_t*)tmp_string, pattern_size, type, type ? app_id : 0, !type ? app_id : 0,
+        HostPatternType::HOST_PATTERN_TYPE_CNAME, false);
     ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(app_id);
 
     return 0;
@@ -2372,30 +2376,12 @@ static int detector_add_url_application(lua_State* L)
     size_t path_pattern_size = 0;
     uint8_t* path_pattern = nullptr;
     tmp_string = lua_tolstring(L, ++index, &path_pattern_size);
-    if (!tmp_string or !path_pattern_size)
+    if (tmp_string and path_pattern_size)
     {
-        APPID_LOG(nullptr, TRACE_ERROR_LEVEL, "appid: Invalid path pattern string: service_id %u; "
-            "client_id %u; payload %u.\n", service_id, client_id, payload_id);
-        snort_free(host_pattern);
-        return 0;
-    }
-    else
         path_pattern = (uint8_t*)snort_strdup(tmp_string);
-
-    /* Verify that scheme pattern is a valid string */
-    size_t schemePatternSize;
-    uint8_t* schemePattern = nullptr;
-    tmp_string = lua_tolstring(L, ++index, &schemePatternSize);
-    if (!tmp_string or !schemePatternSize)
-    {
-        APPID_LOG(nullptr, TRACE_ERROR_LEVEL, "appid: Invalid scheme pattern string: service_id %u; "
-            "client_id %u; payload %u.\n", service_id, client_id, payload_id);
-        snort_free(path_pattern);
-        snort_free(host_pattern);
-        return 0;
     }
-    else
-        schemePattern = (uint8_t*)snort_strdup(tmp_string);
+    
+    ++index;
 
     /* Verify that query pattern is a valid string */
     size_t query_pattern_size;
@@ -2406,34 +2392,43 @@ static int detector_add_url_application(lua_State* L)
 
     uint32_t appId = lua_tointeger(L, ++index);
     AppInfoManager& app_info_manager = ud->get_odp_ctxt().get_app_info_mgr();
-    DetectorAppUrlPattern* pattern =
-        (DetectorAppUrlPattern*)snort_calloc(sizeof(DetectorAppUrlPattern));
-    pattern->userData.service_id        = app_info_manager.get_appid_by_service_id(service_id);
-    pattern->userData.client_id        = app_info_manager.get_appid_by_client_id(client_id);
-    pattern->userData.payload_id           = app_info_manager.get_appid_by_payload_id(payload_id);
-    pattern->userData.appId             = appId;
-    pattern->userData.query.pattern     = query_pattern;
-    pattern->userData.query.patternSize = query_pattern_size;
-    pattern->patterns.host.pattern      = host_pattern;
-    pattern->patterns.host.patternSize  = (int)host_pattern_size;
-    pattern->patterns.path.pattern      = path_pattern;
-    pattern->patterns.path.patternSize  = (int)path_pattern_size;
-    pattern->patterns.scheme.pattern    = schemePattern;
-    pattern->patterns.scheme.patternSize = (int)schemePatternSize;
-    pattern->is_literal = true;
-    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);
-    app_info_manager.set_app_info_active(pattern->userData.payload_id);
-    app_info_manager.set_app_info_active(appId);
+    if ( query_pattern or ( path_pattern and ( path_pattern_size > 1 )) )
+    {
+        DetectorAppUrlPattern* pattern =
+            (DetectorAppUrlPattern*)snort_calloc(sizeof(DetectorAppUrlPattern));
+        pattern->userData.service_id        = app_info_manager.get_appid_by_service_id(service_id);
+        pattern->userData.client_id        = app_info_manager.get_appid_by_client_id(client_id);
+        pattern->userData.payload_id           = app_info_manager.get_appid_by_payload_id(payload_id);
+        pattern->userData.appId             = appId;
+        pattern->userData.query.pattern     = query_pattern;
+        pattern->userData.query.patternSize = query_pattern_size;
+        pattern->patterns.host.pattern      = host_pattern;
+        pattern->patterns.host.patternSize  = (int)host_pattern_size;
+        pattern->patterns.path.pattern      = path_pattern;
+        pattern->patterns.path.patternSize  = (int)path_pattern_size;
+        pattern->is_literal = true;
+        ud->get_odp_ctxt().get_http_matchers().insert_url_pattern(pattern);
+    }
+    else
+    {
+        AppId linked_payload_id = app_info_manager.get_appid_by_payload_id(payload_id);
+        ud->get_odp_ctxt().get_host_matchers().add_host_pattern((const uint8_t*)host_pattern, host_pattern_size, 0,
+             app_info_manager.get_appid_by_client_id(client_id), linked_payload_id, HostPatternType::HOST_PATTERN_TYPE_URL, true,
+             ud->get_odp_ctxt().get_app_info_mgr().get_app_info_flags(linked_payload_id, APPINFO_FLAG_REFERRED));
+        snort_free(host_pattern);
+        snort_free(path_pattern);
+        snort_free(query_pattern);
+    }
+    
+    ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(appId);
 
     return 0;
 }
 
 static int detector_add_url_application_regex(lua_State* L)
 {
-    // Verify detector user data and that we are NOT in packet context
+     // Verify detector user data and that we are NOT in packet context
     auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     ud->validate_lua_state(false);
     if (!init(L))
@@ -2446,7 +2441,6 @@ static int detector_add_url_application_regex(lua_State* L)
             return 0;
     }
 
-
     int index = 1;
 
     uint32_t service_id      = lua_tointeger(L, ++index);
@@ -2461,7 +2455,7 @@ static int detector_add_url_application_regex(lua_State* L)
     const char* tmp_string = lua_tolstring(L, ++index, &host_pattern_size);
     if (!tmp_string or !host_pattern_size)
     {
-        APPID_LOG(nullptr, TRACE_ERROR_LEVEL, "appid: Invalid host regex pattern string: service_id %u; "
+        APPID_LOG(nullptr, TRACE_ERROR_LEVEL, "appid: Invalid host pattern string: service_id %u; "
             "client_id %u; payload_id %u.\n", service_id, client_id, payload_id);
         return 0;
     }
@@ -2472,30 +2466,12 @@ static int detector_add_url_application_regex(lua_State* L)
     size_t path_pattern_size = 0;
     uint8_t* path_pattern = nullptr;
     tmp_string = lua_tolstring(L, ++index, &path_pattern_size);
-    if (!tmp_string or !path_pattern_size)
+    if (tmp_string and path_pattern_size)
     {
-        APPID_LOG(nullptr, TRACE_ERROR_LEVEL, "appid: Invalid path regex pattern string: service_id %u; "
-            "client_id %u; payload %u.\n", service_id, client_id, payload_id);
-        snort_free(host_pattern);
-        return 0;
-    }
-    else
         path_pattern = (uint8_t*)snort_strdup(tmp_string);
-
-    /* Verify that scheme pattern is a valid string */
-    size_t schemePatternSize;
-    uint8_t* schemePattern = nullptr;
-    tmp_string = lua_tolstring(L, ++index, &schemePatternSize);
-    if (!tmp_string or !schemePatternSize)
-    {
-        APPID_LOG(nullptr, TRACE_ERROR_LEVEL, "appid: Invalid scheme regex pattern string: service_id %u; "
-            "client_id %u; payload %u.\n", service_id, client_id, payload_id);
-        snort_free(path_pattern);
-        snort_free(host_pattern);
-        return 0;
     }
-    else
-        schemePattern = (uint8_t*)snort_strdup(tmp_string);
+    
+    ++index;
 
     /* Verify that query pattern is a valid string */
     size_t query_pattern_size;
@@ -2505,28 +2481,38 @@ static int detector_add_url_application_regex(lua_State* L)
         query_pattern = (uint8_t*)snort_strdup(tmp_string);
 
     uint32_t appId = lua_tointeger(L, ++index);
+
     AppInfoManager& app_info_manager = ud->get_odp_ctxt().get_app_info_mgr();
-    DetectorAppUrlPattern* pattern =
-        (DetectorAppUrlPattern*)snort_calloc(sizeof(DetectorAppUrlPattern));
-    pattern->userData.service_id        = app_info_manager.get_appid_by_service_id(service_id);
-    pattern->userData.client_id        = app_info_manager.get_appid_by_client_id(client_id);
-    pattern->userData.payload_id           = app_info_manager.get_appid_by_payload_id(payload_id);
-    pattern->userData.appId             = appId;
-    pattern->userData.query.pattern     = query_pattern;
-    pattern->userData.query.patternSize = query_pattern_size;
-    pattern->patterns.host.pattern      = host_pattern;
-    pattern->patterns.host.patternSize  = (int)host_pattern_size;
-    pattern->patterns.path.pattern      = path_pattern;
-    pattern->patterns.path.patternSize  = (int)path_pattern_size;
-    pattern->patterns.scheme.pattern    = schemePattern;
-    pattern->patterns.scheme.patternSize = (int)schemePatternSize;
-    pattern->is_literal = false;
-    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);
-    app_info_manager.set_app_info_active(pattern->userData.payload_id);
-    app_info_manager.set_app_info_active(appId);
+    if ( query_pattern or ( path_pattern and ( path_pattern_size > 1 )) )
+    {
+        DetectorAppUrlPattern* pattern =
+            (DetectorAppUrlPattern*)snort_calloc(sizeof(DetectorAppUrlPattern));
+        pattern->userData.service_id        = app_info_manager.get_appid_by_service_id(service_id);
+        pattern->userData.client_id        = app_info_manager.get_appid_by_client_id(client_id);
+        pattern->userData.payload_id           = app_info_manager.get_appid_by_payload_id(payload_id);
+        pattern->userData.appId             = appId;
+        pattern->userData.query.pattern     = query_pattern;
+        pattern->userData.query.patternSize = query_pattern_size;
+        pattern->patterns.host.pattern      = host_pattern;
+        pattern->patterns.host.patternSize  = (int)host_pattern_size;
+        pattern->patterns.path.pattern      = path_pattern;
+        pattern->patterns.path.patternSize  = (int)path_pattern_size;
+        pattern->is_literal = false;
+        ud->get_odp_ctxt().get_http_matchers().insert_url_pattern(pattern);
+    }
+    else
+    {
+        AppId linked_payload_id = app_info_manager.get_appid_by_payload_id(payload_id);
+        ud->get_odp_ctxt().get_host_matchers().add_host_pattern((const uint8_t*)host_pattern, host_pattern_size, 0,
+             app_info_manager.get_appid_by_client_id(client_id), linked_payload_id, HostPatternType::HOST_PATTERN_TYPE_URL, false,
+             ud->get_odp_ctxt().get_app_info_mgr().get_app_info_flags(linked_payload_id, APPINFO_FLAG_REFERRED));
+        snort_free(host_pattern);
+        snort_free(path_pattern);
+        snort_free(query_pattern);
+    }
+    
+    ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(appId);
 
     return 0;
 }
index 58439af14e35fcbad3a4200cc0ed91d1ba9d1932..d4e83c2d2cb904ef5cfbc7d2b024e0c7bfd3f780 100644 (file)
@@ -84,7 +84,7 @@ AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
 
 AlpnPatternMatchers::~AlpnPatternMatchers() {}
 EveCaPatternMatchers::~EveCaPatternMatchers() { }
-SslPatternMatchers::~SslPatternMatchers() { }
+HostPatternMatchers::~HostPatternMatchers() { }
 SipPatternMatchers::~SipPatternMatchers() { }
 HttpPatternMatchers::~HttpPatternMatchers() { }
 DnsPatternMatchers::~DnsPatternMatchers() { }
index 983616eebc259b79711e334eef5cdca755c63346..074ca4edc652676aecd82af0b68f2ea9dedf09e9 100644 (file)
@@ -99,7 +99,7 @@ void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, const Packe
     DataBus::publish(0, AppIdEventIds::ANY_CHANGE, app_event, p.flow);
 }
 
-bool SslPatternMatchers::scan_hostname(const uint8_t* server_name, size_t, AppId& client_id, AppId& payload_id)
+bool HostPatternMatchers::scan_hostname(const uint8_t* server_name, size_t, AppId& client_id, AppId& payload_id)
 {
     if (((const char*)server_name) == APPID_UT_TLS_HOST)
     {
@@ -114,7 +114,7 @@ bool SslPatternMatchers::scan_hostname(const uint8_t* server_name, size_t, AppId
     return true;
 }
 
-bool SslPatternMatchers::scan_cname(const uint8_t* cname, size_t, AppId& client_id, AppId& payload_id)
+bool HostPatternMatchers::scan_cname(const uint8_t* cname, size_t, AppId& client_id, AppId& payload_id)
 {
     if (((const char*)cname) == APPID_UT_TLS_HOST)
     {
index d32534c8d322f120d2ef9152e9cfbb6ef5940efb..531a727e6994e7efef4e66aa32a01fdfc7dac056 100644 (file)
@@ -151,7 +151,7 @@ DnsPatternMatchers::~DnsPatternMatchers() = default;
 EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
-SslPatternMatchers::~SslPatternMatchers() = default;
+HostPatternMatchers::~HostPatternMatchers() = default;
 AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 CipPatternMatchers::~CipPatternMatchers() = default;
 UserDataMap::~UserDataMap() = default;
index 786f72403a139e9f9ee0aa798f315da8ab5374db..47895730a6dc3d6432648dd5fc3bcf7be1d7c52f 100644 (file)
@@ -73,7 +73,7 @@ void AppIdSession::publish_appid_event(AppidChangeBits&, const Packet&, bool, ui
     return;
 }
 
-bool SslPatternMatchers::scan_hostname(const uint8_t*, size_t, AppId&, AppId& payload)
+bool HostPatternMatchers::scan_hostname(const uint8_t*, size_t, AppId&, AppId& payload)
 {
     payload = APPID_UT_ID + 1;
     return true;
index 0b14ad282a4b1c271bee1d6da17b8b8062056ce5..0e375d768a3555bb46cf6d34804375791bf5f6a6 100644 (file)
@@ -90,7 +90,7 @@ DnsPatternMatchers::~DnsPatternMatchers() = default;
 EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
-SslPatternMatchers::~SslPatternMatchers() = default;
+HostPatternMatchers::~HostPatternMatchers() = default;
 AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 CipPatternMatchers::~CipPatternMatchers() = default;
 UserDataMap::~UserDataMap() = default;
index 18d54a53aa533d2817402dce3999df94ee289629..de003862eb3043bdb8be172630aa5a04e815717e 100644 (file)
@@ -149,7 +149,7 @@ DnsPatternMatchers::~DnsPatternMatchers() = default;
 EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
-SslPatternMatchers::~SslPatternMatchers() = default;
+HostPatternMatchers::~HostPatternMatchers() = default;
 AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 CipPatternMatchers::~CipPatternMatchers() = default;
 UserDataMap::~UserDataMap() = default;
index f4c1deaf7fd4a46ca27238939db15c2cabc3e267..6740c81671d83208b3d076af39da53519ae9625d 100644 (file)
@@ -64,7 +64,7 @@ DnsPatternMatchers::~DnsPatternMatchers() = default;
 EveCaPatternMatchers::~EveCaPatternMatchers() = default;
 HttpPatternMatchers::~HttpPatternMatchers() = default;
 SipPatternMatchers::~SipPatternMatchers() = default;
-SslPatternMatchers::~SslPatternMatchers() = default;
+HostPatternMatchers::~HostPatternMatchers() = default;
 AlpnPatternMatchers::~AlpnPatternMatchers() = default;
 CipPatternMatchers::~CipPatternMatchers() = default;
 UserDataMap::~UserDataMap() = default;