]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2156 in SNORT/snort3 from ~KAMURTHI/snort3:http2_multi_stream...
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Mon, 20 Apr 2020 22:29:04 +0000 (22:29 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Mon, 20 Apr 2020 22:29:04 +0000 (22:29 +0000)
Squashed commit of the following:

commit af68aa5f7982ddeaa6d628dd21f9df6fd05192d6
Author: Kanimozhi Murthi <kamurthi@cisco.com>
Date:   Mon Apr 20 00:14:50 2020 -0400

    appid: Changing sessionAPI to accomodate stream_index

27 files changed:
src/network_inspectors/appid/CMakeLists.txt
src/network_inspectors/appid/appid_app_descriptor.cc
src/network_inspectors/appid/appid_app_descriptor.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_http_event_handler.cc
src/network_inspectors/appid/appid_http_session.h
src/network_inspectors/appid/appid_inspector.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/appid_session_api.cc
src/network_inspectors/appid/appid_session_api.h
src/network_inspectors/appid/appid_types.h
src/network_inspectors/appid/client_plugins/test/client_plugin_mock.h
src/network_inspectors/appid/detector_plugins/http_url_patterns.h
src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h
src/network_inspectors/appid/lua_detector_api.cc
src/network_inspectors/appid/service_plugins/service_rtmp.cc
src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h
src/network_inspectors/appid/test/appid_detector_test.cc
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/appid_http_event_test.cc
src/network_inspectors/appid/test/appid_http_session_test.cc
src/network_inspectors/appid/test/appid_mock_definitions.h
src/network_inspectors/appid/test/appid_mock_session.h
src/network_inspectors/appid/test/appid_session_api_test.cc
src/network_inspectors/appid/test/service_state_test.cc
src/network_inspectors/appid/tp_appid_utils.cc

index d333b2262aa2c2f1c070876b6ceafdfbf79e3b4f..e0246f137d7329d1dbfc83e3dcfc1dd2f0af9560 100644 (file)
@@ -1,5 +1,6 @@
 set (APPID_INCLUDES
     appid_api.h
+    appid_app_descriptor.h
     appid_dns_session.h
     appid_http_session.h
     appid_session_api.h
index c749bae09d2274286a97f2e68abc53fc613233fa..17fb65159c718819b23facd98512999281d53707 100644 (file)
@@ -9,10 +9,27 @@
 #endif
 
 #include "appid_app_descriptor.h"
+#include "app_info_table.h"
+#include "appid_config.h"
+#include "appid_module.h"
+#include "appid_peg_counts.h"
+#include "appid_types.h"
 #include "lua_detector_api.h"
 
 using namespace snort;
 
+void ApplicationDescriptor::set_id(AppId app_id)
+{
+    if ( my_id != app_id )
+    {
+        my_id = app_id;
+        if ( app_id > APP_ID_NONE )
+            update_stats(app_id);
+        else if ( app_id == APP_ID_UNKNOWN )
+            appid_stats.appid_unknown++;
+    }
+}
+
 void ApplicationDescriptor::set_id(const Packet& p, AppIdSession& asd,
     AppidSessionDirection dir, AppId app_id, AppidChangeBits& change_bits)
 {
@@ -23,3 +40,48 @@ void ApplicationDescriptor::set_id(const Packet& p, AppIdSession& asd,
     }
 }
 
+void ServiceAppDescriptor::update_stats(AppId id)
+{
+    AppIdPegCounts::inc_service_count(id);
+}
+
+void ServiceAppDescriptor::set_port_service_id(AppId id)
+{
+    if ( id != port_service_id )
+    {
+        port_service_id = id;
+        if ( id > APP_ID_NONE )
+            AppIdPegCounts::inc_service_count(id);
+    }
+}
+
+void ServiceAppDescriptor::set_id(AppId app_id, OdpContext& odp_ctxt)
+{
+    if (get_id() != app_id)
+    {
+        ApplicationDescriptor::set_id(app_id);
+        deferred = odp_ctxt.get_app_info_mgr().get_app_info_flags(app_id, APPINFO_FLAG_DEFER);
+    }
+}
+
+void ClientAppDescriptor::update_user(AppId app_id, const char* username)
+{
+    my_username = username;
+
+    if ( my_user_id != app_id )
+    {
+        my_user_id = app_id;
+        if ( app_id > APP_ID_NONE )
+            AppIdPegCounts::inc_user_count(app_id);
+    }
+}
+
+void ClientAppDescriptor::update_stats(AppId id)
+{
+    AppIdPegCounts::inc_client_count(id);
+}
+
+void PayloadAppDescriptor::update_stats(AppId id)
+{
+    AppIdPegCounts::inc_payload_count(id);
+}
index 7ae0803664488ea0402005cf34fac373e23802a7..05097e119ce3223c57095b25b14206aea41dee99 100644 (file)
 #include "protocols/packet.h"
 #include "pub_sub/appid_events.h"
 
-#include "app_info_table.h"
-#include "appid_config.h"
-#include "appid_module.h"
-#include "appid_peg_counts.h"
 #include "appid_types.h"
+#include "application_ids.h"
 
 class AppIdDetector;
 class AppIdSession;
+class OdpContext;
 
 class ApplicationDescriptor
 {
@@ -68,17 +66,7 @@ public:
         return my_id;
     }
 
-    virtual void set_id(AppId app_id)
-    {
-        if ( my_id != app_id )
-        {
-            my_id = app_id;
-            if ( app_id > APP_ID_NONE )
-                update_stats(app_id);
-            else if ( app_id == APP_ID_UNKNOWN )
-                appid_stats.appid_unknown++;
-        }
-    }
+    virtual void set_id(AppId app_id);
 
     virtual void set_id(const snort::Packet& p, AppIdSession& asd, AppidSessionDirection dir, AppId app_id, AppidChangeBits& change_bits);
 
@@ -118,14 +106,7 @@ class ServiceAppDescriptor : public ApplicationDescriptor
 public:
     ServiceAppDescriptor() = default;
 
-    void set_id(AppId app_id, OdpContext& odp_ctxt)
-    {
-        if (get_id() != app_id)
-        {
-            ApplicationDescriptor::set_id(app_id);
-            deferred = odp_ctxt.get_app_info_mgr().get_app_info_flags(app_id, APPINFO_FLAG_DEFER);
-        }
-    }
+    void set_id(AppId app_id, OdpContext& odp_ctxt);
 
     void reset() override
     {
@@ -133,25 +114,14 @@ public:
         port_service_id = APP_ID_NONE;
     }
 
-    void update_stats(AppId id) override
-    {
-        AppIdPegCounts::inc_service_count(id);
-    }
+    void update_stats(AppId id) override;
 
     AppId get_port_service_id() const
     {
         return port_service_id;
     }
 
-    void set_port_service_id(AppId id)
-    {
-        if ( id != port_service_id )
-        {
-            port_service_id = id;
-            if ( id > APP_ID_NONE )
-                AppIdPegCounts::inc_service_count(id);
-        }
-    }
+    void set_port_service_id(AppId id);
 
     bool get_deferred()
     {
@@ -176,18 +146,7 @@ public:
         my_user_id = APP_ID_NONE;
     }
 
-    void update_user(AppId app_id, const char* username)
-    {
-        if ( my_username != username )
-            my_username = username;
-
-        if ( my_user_id != app_id )
-        {
-            my_user_id = app_id;
-            if ( app_id > APP_ID_NONE )
-                AppIdPegCounts::inc_user_count(app_id);
-        }
-    }
+    void update_user(AppId app_id, const char* username);
 
     AppId get_user_id() const
     {
@@ -199,10 +158,7 @@ public:
         return my_username.empty() ? nullptr : my_username.c_str();
     }
 
-    void update_stats(AppId id) override
-    {
-        AppIdPegCounts::inc_client_count(id);
-    }
+    void update_stats(AppId id) override;
 
 private:
     std::string my_username;
@@ -219,10 +175,7 @@ public:
         ApplicationDescriptor::reset();
     }
 
-    void update_stats(AppId id) override
-    {
-        AppIdPegCounts::inc_payload_count(id);
-    }
+    void update_stats(AppId id) override;
 };
 
 #endif
index 36378e902d1378461e3032887ac3cf049feec2c7..f008f96b0d0183b8519f300fa10f75e6c382571c 100644 (file)
@@ -672,7 +672,9 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd,
     const SfIp* ip;
     AppIdHttpSession* hsession = asd.get_http_session();
 
-    const TunnelDest* tun_dest = hsession->get_tun_dest();
+    const TunnelDest* tun_dest = nullptr;
+    if (hsession)
+        tun_dest  = hsession->get_tun_dest();
     if (tun_dest)
     {
         ip = &(tun_dest->ip);
index e2b7576251611956d4a985eacd97dae0ef91dcfb..7d00314e0eb69985b630f15a29d8d951c0290c78 100644 (file)
@@ -60,7 +60,10 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow)
 
     direction = event_type == REQUEST_EVENT ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
 
-    AppIdHttpSession* hsession = asd->get_http_session();
+    AppIdHttpSession* hsession = asd->get_http_session(0);
+
+    if (!hsession)
+        hsession = asd->create_http_session();
 
     if (direction == APP_ID_FROM_INITIATOR)
     {
index 5ede3da0efe0683b6d6fc1922c31371b024c6cdb..bb118c3af32ab2ae29f0362e536c67579b2a5077 100644 (file)
@@ -29,6 +29,7 @@
 #include "pub_sub/appid_events.h"
 #include "sfip/sf_ip.h"
 
+#include "appid_app_descriptor.h"
 #include "appid_types.h"
 #include "application_ids.h"
 
@@ -36,42 +37,6 @@ class AppIdSession;
 class ChpMatchDescriptor;
 class HttpPatternMatchers;
 
-// These values are used in Lua code as raw numbers. Do NOT reassign new values.
-// 0 - 8 (inclusive)       : used heavily in CHP code. DO NOT CHANGE.
-// 9 - NUM_METADATA_FIELDS : extra metadata buffers, beyond CHP.
-// NUM_METADATA_FIELDS     : must always follow the last metadata FID.
-// NUM_HTTP_FIELDS         : number of CHP fields, so always RSP_BODY_FID + 1
-enum HttpFieldIds : uint8_t
-{
-    // 0-8: CHP fields. DO NOT CHANGE
-
-    // Request-side headers
-    REQ_AGENT_FID,          // 0
-    REQ_HOST_FID,           // 1
-    REQ_REFERER_FID,        // 2
-    REQ_URI_FID,            // 3
-    REQ_COOKIE_FID,         // 4
-    REQ_BODY_FID,           // 5
-    // Response-side headers
-    RSP_CONTENT_TYPE_FID,   // 6
-    RSP_LOCATION_FID,       // 7
-    RSP_BODY_FID,           // 8
-
-    // extra (non-CHP) metadata fields.
-    MISC_VIA_FID,           // 9
-    MISC_RESP_CODE_FID,     // 10
-    MISC_SERVER_FID,        // 11
-    MISC_XWW_FID,           // 12
-    MISC_URL_FID,           // 13
-
-    // Total number of metadata fields, always first after actual FIDs.
-    NUM_METADATA_FIELDS,    // 14
-
-    // Number of CHP fields, always 1 past RSP_BODY_FIELD
-    NUM_HTTP_FIELDS = MISC_VIA_FID,
-    MAX_KEY_PATTERN = REQ_URI_FID,     // DO NOT CHANGE, used in CHP
-};
-
 #define RESPONSE_CODE_PACKET_THRESHHOLD 0
 
 // These values are used in Lua code as raw numbers. Do NOT reassign new values.
@@ -97,6 +62,10 @@ public:
 
     AppIdHttpSession(AppIdSession&);
     virtual ~AppIdHttpSession();
+    ClientAppDescriptor client;
+    PayloadAppDescriptor payload;
+    AppId referred_payload_app_id = APP_ID_NONE;
+    AppId misc_app_id = APP_ID_NONE;
 
     int process_http_packet(AppidSessionDirection direction, AppidChangeBits& change_bits,
         HttpPatternMatchers& http_matchers);
index 1e8e614dd3a56bb382de49650113a38a8b055ed7..5a9b5881236bfd8f83071ebd52932953cab7a37e 100644 (file)
@@ -38,6 +38,7 @@
 #include "appid_debug.h"
 #include "appid_discovery.h"
 #include "appid_http_event_handler.h"
+#include "appid_peg_counts.h"
 #include "appid_session.h"
 #include "appid_stats.h"
 #include "client_plugins/client_discovery.h"
index 29d7c7e8d3b6d81a386e686e723f8e15f9f9181f..a60f9fcae0f13b34b214a092d3a51868555930e2 100644 (file)
@@ -227,8 +227,8 @@ void AppIdSession::reinit_session_data(AppidChangeBits& change_bits)
         payload.reset();
         referred_payload_app_id = tp_payload_app_id = APP_ID_NONE;
         clear_session_flags(APPID_SESSION_CONTINUE);
-        if (hsession)
-            hsession->set_field(MISC_URL_FID, nullptr, change_bits);
+        if (!hsessions.empty())
+            hsessions[0]->set_field(MISC_URL_FID, nullptr, change_bits);
     }
 
     //service
@@ -471,13 +471,13 @@ void AppIdSession::examine_rtmp_metadata(AppidChangeBits& change_bits)
     AppId referred_payload_id = APP_ID_NONE;
     char* version = nullptr;
 
-    if (!hsession)
-        hsession = new AppIdHttpSession(*this);
+    if (hsessions.empty())
+        return;
 
-    if (const char* url = hsession->get_cfield(MISC_URL_FID))
+    if (const char* url = hsessions[0]->get_cfield(MISC_URL_FID))
     {
         HttpPatternMatchers& http_matchers = ctxt.get_odp_ctxt().get_http_matchers();
-        const char* referer = hsession->get_cfield(REQ_REFERER_FID);
+        const char* referer = hsessions[0]->get_cfield(REQ_REFERER_FID);
         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())) ||
@@ -591,7 +591,8 @@ void AppIdSession::delete_session_data()
         rna_ss = subtype;
     }
 
-    delete hsession;
+    for (auto* hsession: hsessions)
+        delete hsession;
     free_tls_session_data();
     delete dsession;
 }
@@ -880,7 +881,7 @@ void AppIdSession::reset_session_data()
     delete_session_data();
     netbios_name = nullptr;
     netbios_domain = nullptr;
-    hsession = nullptr;
+    hsessions.clear();
 
     tp_payload_app_id = APP_ID_UNKNOWN;
     tp_app_id = APP_ID_UNKNOWN;
@@ -906,17 +907,24 @@ void AppIdSession::clear_http_flags()
 
 void AppIdSession::clear_http_data()
 {
-    if (!hsession)
+    if (hsessions.empty())
         return;
-    hsession->clear_all_fields();
+    hsessions[0]->clear_all_fields();
 }
 
-AppIdHttpSession* AppIdSession::get_http_session()
+AppIdHttpSession* AppIdSession::create_http_session()
 {
-    if (!hsession)
-        hsession = new AppIdHttpSession(*this);
+    AppIdHttpSession* hsession = new AppIdHttpSession(*this);
+    hsessions.push_back(hsession);
     return hsession;
 }
+AppIdHttpSession* AppIdSession::get_http_session(uint32_t stream_index)
+{
+    if (stream_index < hsessions.size())
+        return hsessions[stream_index];
+    else
+        return nullptr;
+}
 
 AppIdDnsSession* AppIdSession::get_dns_session()
 {
index d83dd7fb03fa4a193a6abbc6ec8c5f1877973842..e057d99b53d0df09b1e2a4a735406bc430f40400 100644 (file)
@@ -32,6 +32,8 @@
 #include "app_info_table.h"
 #include "appid_api.h"
 #include "appid_app_descriptor.h"
+#include "appid_config.h"
+#include "appid_http_session.h"
 #include "appid_types.h"
 #include "application_ids.h"
 #include "detector_plugins/http_url_patterns.h"
@@ -328,6 +330,10 @@ public:
     AppId get_application_ids_client();
     AppId get_application_ids_payload();
     AppId get_application_ids_misc();
+    uint32_t get_hsessions_size()
+    {
+        return hsessions.size();
+    }
 
     bool is_ssl_session_decrypted();
     void examine_ssl_metadata(snort::Packet*, AppidChangeBits& change_bits);
@@ -346,7 +352,8 @@ public:
     void clear_http_data();
     void reset_session_data();
 
-    AppIdHttpSession* get_http_session();
+    AppIdHttpSession* create_http_session();
+    AppIdHttpSession* get_http_session(uint32_t stream_index = 0);
     AppIdDnsSession* get_dns_session();
 
     bool is_tp_appid_done() const;
@@ -400,7 +407,7 @@ public:
     }
 
 private:
-    AppIdHttpSession* hsession = nullptr;
+    std::vector<AppIdHttpSession*> hsessions;
     AppIdDnsSession* dsession = nullptr;
 
     void reinit_session_data(AppidChangeBits& change_bits);
index 340be1745cf12dc08de0d36055d4c824c4e734d0..b2c86f5fcdedd41a348af54bae6164be92339fc9 100644 (file)
@@ -60,36 +60,110 @@ AppId AppIdSessionApi::get_only_service_app_id()
     return asd->pick_only_service_app_id();
 }
 
-AppId AppIdSessionApi::get_misc_app_id()
+AppId AppIdSessionApi::get_misc_app_id(uint32_t stream_index)
 {
-    return asd->get_application_ids_misc();
+    if (asd->is_http2)
+    {
+        if (stream_index >= asd->get_hsessions_size())
+            return APP_ID_UNKNOWN;
+        return asd->get_http_session(stream_index)->misc_app_id;
+    }
+    else
+        return asd->get_application_ids_misc();
 }
 
-AppId AppIdSessionApi::get_client_app_id()
+AppId AppIdSessionApi::get_client_app_id(uint32_t stream_index)
 {
-    return asd->get_application_ids_client();
+    if (asd->is_http2)
+    {
+        if (stream_index >= asd->get_hsessions_size())
+            return APP_ID_UNKNOWN;
+        return asd->get_http_session(stream_index)->client.get_id();
+    }
+    else
+        return asd->get_application_ids_client();
 }
 
-AppId AppIdSessionApi::get_payload_app_id()
+AppId AppIdSessionApi::get_payload_app_id(uint32_t stream_index)
 {
-    return asd->get_application_ids_payload();
+    if (asd->is_http2)
+    {
+        if (stream_index >= asd->get_hsessions_size())
+            return APP_ID_UNKNOWN;
+        return asd->get_http_session(stream_index)->payload.get_id();
+    }
+    else
+        return asd->get_application_ids_payload();
 }
 
-AppId AppIdSessionApi::get_referred_app_id()
+AppId AppIdSessionApi::get_referred_app_id(uint32_t stream_index)
 {
-    return asd->pick_referred_payload_app_id();
+    if (asd->is_http2)
+    {
+        if (stream_index >= asd->get_hsessions_size())
+            return APP_ID_UNKNOWN;
+        return asd->get_http_session(stream_index)->referred_payload_app_id;
+    }
+    else
+        return asd->pick_referred_payload_app_id();
 }
 
 void AppIdSessionApi::get_app_id(AppId& service, AppId& client,
-    AppId& payload, AppId& misc, AppId& referred)
+    AppId& payload, AppId& misc, AppId& referred, uint32_t stream_index)
 {
-    asd->get_application_ids(service, client, payload, misc);
-    referred = asd->pick_referred_payload_app_id();
+    if (asd->is_http2)
+    {
+        if (stream_index >= asd->get_hsessions_size())
+            service = client = payload = misc = referred = APP_ID_UNKNOWN;
+        else
+        {
+            service = asd->get_application_ids_service();
+            client = asd->get_http_session(stream_index)->client.get_id();
+            payload = asd->get_http_session(stream_index)->payload.get_id();
+            misc = asd->get_http_session(stream_index)->misc_app_id;
+            referred = asd->get_http_session(stream_index)->referred_payload_app_id;
+        }
+    }
+    else
+    {
+        asd->get_application_ids(service, client, payload, misc);
+        referred = asd->pick_referred_payload_app_id();
+    }
 }
 
 void AppIdSessionApi::get_app_id(AppId* service, AppId* client,
-    AppId* payload, AppId* misc, AppId* referred)
+    AppId* payload, AppId* misc, AppId* referred, uint32_t stream_index)
 {
+    if (asd->is_http2)
+    {
+        if (stream_index >= asd->get_hsessions_size())
+        {
+            if(service)
+                *service = APP_ID_UNKNOWN;
+            if(client)
+                *client = APP_ID_UNKNOWN;
+            if(payload)
+                *payload = APP_ID_UNKNOWN;
+            if(misc)
+                *misc = APP_ID_UNKNOWN;
+            if(referred)
+                *referred = APP_ID_UNKNOWN;
+        }
+        else
+        {
+            AppIdHttpSession* hsession = asd->get_http_session(stream_index);
+            if (service)
+                *service = asd->get_application_ids_service();
+            if (client)
+                *client = hsession->client.get_id();
+            if (payload)
+                *payload = hsession->payload.get_id();
+            if (misc)
+                *misc = hsession->misc_app_id;
+            if (referred)
+                *referred = hsession->referred_payload_app_id;
+        }
+    }
     if (service)
         *service = asd->get_application_ids_service();
     if (client)
@@ -154,9 +228,16 @@ bool AppIdSessionApi::is_appid_available()
         asd->get_session_flags(APPID_SESSION_NO_TPI)) );
 }
 
-const char* AppIdSessionApi::get_client_version()
+const char* AppIdSessionApi::get_client_version(uint32_t stream_index)
 {
-    return asd->client.get_version();
+    if (asd->is_http2)
+    {
+        if (stream_index >= asd->get_hsessions_size())
+            return nullptr;
+        return asd->get_http_session(stream_index)->client.get_version();
+    }
+    else
+        return asd->client.get_version();
 }
 
 uint64_t AppIdSessionApi::get_appid_session_attribute(uint64_t flags)
@@ -247,9 +328,9 @@ AppIdDnsSession* AppIdSessionApi::get_dns_session()
     return asd->get_dns_session();
 }
 
-AppIdHttpSession* AppIdSessionApi::get_http_session()
+AppIdHttpSession* AppIdSessionApi::get_http_session(uint32_t stream_index)
 {
-    return asd->get_http_session();
+    return asd->get_http_session(stream_index);
 }
 
 bool AppIdSessionApi::is_http_inspection_done()
index cc38c51fd02e8ff886513644f7257968d82d5c22..e9f978c49d317eb157471792a7b2bbd2f279c650 100644 (file)
@@ -151,17 +151,17 @@ public:
     AppId get_service_app_id();
     AppId get_port_service_app_id();
     AppId get_only_service_app_id();
-    AppId get_misc_app_id();
-    AppId get_client_app_id();
-    AppId get_payload_app_id();
-    AppId get_referred_app_id();
-    void get_app_id(AppId& service, AppId& client, AppId& payload, AppId& misc, AppId& referred);
-    void get_app_id(AppId* service, AppId* client, AppId* payload, AppId* misc, AppId* referred);
+    AppId get_misc_app_id(uint32_t stream_index = 0);
+    AppId get_client_app_id(uint32_t stream_index = 0);
+    AppId get_payload_app_id(uint32_t stream_index = 0);
+    AppId get_referred_app_id(uint32_t stream_index = 0);
+    void get_app_id(AppId& service, AppId& client, AppId& payload, AppId& misc, AppId& referred, uint32_t stream_index = 0);
+    void get_app_id(AppId* service, AppId* client, AppId* payload, AppId* misc, AppId* referred, uint32_t stream_index = 0);
     bool is_ssl_session_decrypted();
     bool is_appid_inspecting_session();
     bool is_appid_available();
     const char* get_user_name(AppId* service, bool* isLoginSuccessful);
-    const char* get_client_version();
+    const char* get_client_version(uint32_t stream_index = 0);
     uint64_t get_appid_session_attribute(uint64_t flag);
     APPID_FLOW_TYPE get_flow_type();
     void get_service_info(const char** vendor, const char** version,
@@ -170,7 +170,7 @@ public:
     SfIp* get_service_ip();
     SfIp* get_initiator_ip();
     AppIdDnsSession* get_dns_session();
-    AppIdHttpSession* get_http_session();
+    AppIdHttpSession* get_http_session(uint32_t stream_index = 0);
     char* get_tls_host();
     DHCPData* get_dhcp_fp_data();
     void free_dhcp_fp_data(DHCPData*);
index 42c71a7f743c06557940678fb00b898ca021758d..2e1590413d56439e9d3d280d1a8ddb2a21dbd891 100644 (file)
 
 #ifndef APPID_TYPES_H
 #define APPID_TYPES_H
+#include <cstdint>
+// These values are used in Lua code as raw numbers. Do NOT reassign new values.
+// 0 - 8 (inclusive)       : used heavily in CHP code. DO NOT CHANGE.
+// 9 - NUM_METADATA_FIELDS : extra metadata buffers, beyond CHP.
+// NUM_METADATA_FIELDS     : must always follow the last metadata FID.
+// NUM_HTTP_FIELDS         : number of CHP fields, so always RSP_BODY_FID + 1
+enum HttpFieldIds : uint8_t
+{
+    // 0-8: CHP fields. DO NOT CHANGE
+
+    // Request-side headers
+    REQ_AGENT_FID,          // 0
+    REQ_HOST_FID,           // 1
+    REQ_REFERER_FID,        // 2
+    REQ_URI_FID,            // 3
+    REQ_COOKIE_FID,         // 4
+    REQ_BODY_FID,           // 5
+    // Response-side headers
+    RSP_CONTENT_TYPE_FID,   // 6
+    RSP_LOCATION_FID,       // 7
+    RSP_BODY_FID,           // 8
+
+    // extra (non-CHP) metadata fields.
+    MISC_VIA_FID,           // 9
+    MISC_RESP_CODE_FID,     // 10
+    MISC_SERVER_FID,        // 11
+    MISC_XWW_FID,           // 12
+    MISC_URL_FID,           // 13
+
+    // Total number of metadata fields, always first after actual FIDs.
+    NUM_METADATA_FIELDS,    // 14
+
+    // Number of CHP fields, always 1 past RSP_BODY_FIELD
+    NUM_HTTP_FIELDS = MISC_VIA_FID,
+    MAX_KEY_PATTERN = REQ_URI_FID,     // DO NOT CHANGE, used in CHP
+};
 
 enum AppidSessionDirection
 {
@@ -28,5 +64,4 @@ enum AppidSessionDirection
     APP_ID_FROM_RESPONDER,
     APP_ID_APPID_SESSION_DIRECTION_MAX
 };
-
 #endif
index e01a97e4a3d5897b624c0773cbea0dd127630a6d..34189df392771c5c64c8784f95dff1387fd098f8 100644 (file)
 #ifndef CLIENT_PLUGIN_MOCK_H
 #define CLIENT_PLUGIN_MOCK_H
 
+#include "appid_detector.h"
+#include "appid_module.h"
+#include "appid_peg_counts.h"
+#include "utils/stats.h"
 namespace snort
 {
 // Stubs for messages
@@ -89,6 +93,7 @@ void AppIdDiscovery::register_udp_pattern(AppIdDetector*, const uint8_t* const,
     int, unsigned){}
 int AppIdDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&){return 0;}
 void ApplicationDescriptor::set_id(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&){}
+void ApplicationDescriptor::set_id(AppId){}
 AppIdDiscovery::AppIdDiscovery() { }
 AppIdDiscovery::~AppIdDiscovery() { }
 void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }
index d1e5243736c399be609817bad69394af8d65b0a3..c9d4dda5422ab531ee2c53db0a9864ad501b8ae1 100644 (file)
@@ -30,7 +30,7 @@
 #include "search_engines/search_tool.h"
 #include "utils/util.h"
 
-#include "appid_http_session.h"
+#include "appid_types.h"
 #include "appid_utils/sf_mlmp.h"
 #include "application_ids.h"
 
index 5a03142efca502f95b22f6bd856e3de80b6587d7..5842342e40420d7ab2a8a5a481042cf1a9fdbb19 100644 (file)
 
 #ifndef DETECTOR_PLUGINS_MOCK_H
 #define DETECTOR_PLUGINS_MOCK_H
+#include "appid_detector.h"
+#include "appid_module.h"
+#include "appid_peg_counts.h"
+#include "utils/stats.h"
 
 namespace snort
 {
@@ -201,7 +205,12 @@ bool AppIdReloadTuner::tune_resources(unsigned int)
 {
     return true;
 }
-
+void ApplicationDescriptor::set_id(AppId){}
+void ServiceAppDescriptor::set_id(AppId, OdpContext&){}
+void ServiceAppDescriptor::update_stats(AppId){}
+void ClientAppDescriptor::update_user(AppId, const char*){}
+void ClientAppDescriptor::update_stats(AppId) {}
+void PayloadAppDescriptor::update_stats(AppId) {}
 void ServiceDiscovery::initialize()
 { }
 
index 7eabfc5321004b5df9bdc6e777dc58252c571d30..9ea39e67d238d5daa458bcb2fd6a1035ad58122c 100644 (file)
@@ -37,6 +37,7 @@
 #include "app_info_table.h"
 #include "appid_debug.h"
 #include "appid_inspector.h"
+#include "appid_peg_counts.h"
 #include "client_plugins/client_discovery.h"
 #include "detector_plugins/detector_dns.h"
 #include "detector_plugins/detector_pattern.h"
index d1a459752e039939b6e601223757c1daefe3de25..0c677c0daa9b5aeb787cac3681c4d1bc781aec44 100644 (file)
@@ -633,6 +633,9 @@ fail:
 
 success:
     AppIdHttpSession* hsession = args.asd.get_http_session();
+    if (!hsession)
+        hsession = args.asd.create_http_session();
+
     if ( ss->swfUrl )
     {
         if ( !hsession->get_field(MISC_URL_FID) )
index b9d428538ae1e2a3fad186d57d328e20ee721e2f..c0c7b81488e0356b29a980be26eb3186a6036327 100644 (file)
 
 #ifndef SERVICE_PLUGIN_MOCK_H
 #define SERVICE_PLUGIN_MOCK_H
+#include "appid_detector.h"
+#include "appid_module.h"
+#include "appid_peg_counts.h"
+#include "utils/stats.h"
 
 namespace snort
 {
@@ -88,6 +92,12 @@ void AppIdDetector::add_info(AppIdSession&, const char*, AppidChangeBits&){}
 void AppIdDetector::add_user(AppIdSession&, const char*, AppId, bool){}
 void AppIdDetector::add_payload(AppIdSession&, AppId){}
 void AppIdDetector::add_app(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppId, const char*, AppidChangeBits&){}
+void ApplicationDescriptor::set_id(AppId){}
+void ServiceAppDescriptor::set_id(AppId, OdpContext&){}
+void ServiceAppDescriptor::update_stats(AppId){}
+void ClientAppDescriptor::update_user(AppId, const char*){}
+void ClientAppDescriptor::update_stats(AppId) {}
+void PayloadAppDescriptor::update_stats(AppId) {}
 void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool*, int,
         const uint8_t* const, unsigned, unsigned){}
 void AppIdDiscovery::register_detector(const std::string&, AppIdDetector*,  IpProtocol){}
index eb4fc6d26d67c3fe0bef286e7379da201e8cc132..fa864cd15c8ebc9d1e9b0ec76a4e19a1a8fb3273 100644 (file)
@@ -72,20 +72,6 @@ TEST_GROUP(appid_detector_tests)
     }
 };
 
-TEST(appid_detector_tests, add_info)
-{
-    const char* info_url = "https://tools.ietf.org/html/rfc793";
-    AppidChangeBits change_bits;
-    AppIdDetector* ad = new TestDetector;
-    MockAppIdHttpSession* hsession = (MockAppIdHttpSession*)mock_session->get_http_session();
-    ad->add_info(*mock_session, info_url, change_bits);
-    STRCMP_EQUAL(hsession->get_cfield(MISC_URL_FID), URL);
-    hsession->reset();
-    ad->add_info(*mock_session, info_url, change_bits);
-    STRCMP_EQUAL(mock_session->get_http_session()->get_cfield(MISC_URL_FID), info_url);
-    delete ad;
-}
-
 TEST(appid_detector_tests, add_user)
 {
     const char* username = "snorty";
index d832a7a32555265a62eb4a76ff351f69c2fa975b..42a3aa44168ee415e1b1310b80b90a98911465ee 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "host_tracker/host_cache.h"
 #include "network_inspectors/appid/appid_discovery.cc"
+#include "network_inspectors/appid/appid_peg_counts.h"
 
 #include "search_engines/search_tool.h"
 #include "utils/sflsq.cc"
@@ -123,6 +124,17 @@ SipPatternMatchers::~SipPatternMatchers() { }
 SslPatternMatchers::~SslPatternMatchers() { }
 
 void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
+void ApplicationDescriptor::set_id(AppId app_id){my_id = app_id;}
+void ServiceAppDescriptor::set_id(AppId app_id, OdpContext& odp_ctxt)
+{
+    set_id(app_id);
+    deferred = odp_ctxt.get_app_info_mgr().get_app_info_flags(app_id, APPINFO_FLAG_DEFER);
+}
+void ServiceAppDescriptor::update_stats(AppId){}
+void ServiceAppDescriptor::set_port_service_id(AppId){}
+void ClientAppDescriptor::update_user(AppId, const char*){}
+void ClientAppDescriptor::update_stats(AppId) {}
+void PayloadAppDescriptor::update_stats(AppId) {}
 
 // Stubs for AppIdModule
 AppIdModule::AppIdModule(): Module("appid_mock", "appid_mock_help") {}
index 95d3415f9ae8b3fc975a7ac46a5b7f521ef13ce1..0981aea9ceec2eec0692a208a9900871ba409a28 100644 (file)
@@ -199,6 +199,7 @@ TEST_GROUP(appid_http_event)
         MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
         flow = new Flow;
         mock_session = new AppIdSession(IpProtocol::TCP, nullptr, 1492, appid_inspector);
+        mock_session->create_http_session();
         flow->set_flow_data(mock_session);
         appidDebug = new AppIdDebug();
         appidDebug->activate(nullptr, nullptr, 0);
index 2011dce88a70a262b385d2b477f755568d2b3152..cf1270cba4091829af1b6d006367d40663d6dbd5 100644 (file)
@@ -38,6 +38,7 @@
 #include "appid_mock_definitions.h"
 #include "appid_mock_inspector.h"
 #include "appid_mock_flow.h"
+#include "appid_peg_counts.h"
 
 #include "detector_plugins/http_url_patterns.h"
 
@@ -101,12 +102,10 @@ OdpContext* AppIdContext::odp_ctxt = &stub_odp_ctxt;
 // AppIdSession mock functions
 AppIdSession::AppIdSession(IpProtocol, const SfIp*, uint16_t, AppIdInspector& inspector)
     : FlowData(inspector_id, &inspector), ctxt(stub_ctxt)
-{
-}
+{}
 
 AppIdSession::~AppIdSession()
-{
-}
+{}
 
 void AppIdSession::set_client_appid_data(AppId, AppidChangeBits&, char*)
 {
index b26eec09d4e3357ae266cd271ef5c79f9695f85b..d41b20ed8e0337747d7169af64903829b6dc48f9 100644 (file)
 #ifndef APPID_MOCK_DEFINITIONS_H
 #define APPID_MOCK_DEFINITIONS_H
 
+#include "appid_detector.h"
+#include "appid_module.h"
+#include "appid_peg_counts.h"
 #include "service_inspectors/http_inspect/http_msg_header.h"
+#include "utils/stats.h"
 
 class Inspector;
 class ThirdPartyAppIdContext;
@@ -54,6 +58,18 @@ SearchTool::SearchTool(char const*, bool) { }
 SearchTool::~SearchTool() { }
 }
 
+void ApplicationDescriptor::set_id(AppId app_id){ my_id = app_id;}
+void ServiceAppDescriptor::set_id(AppId app_id, OdpContext&){ set_id(app_id); }
+void ServiceAppDescriptor::update_stats(AppId){}
+void ServiceAppDescriptor::set_port_service_id(AppId app_id){ port_service_id = app_id;}
+void ClientAppDescriptor::update_user(AppId app_id, const char* username)
+{
+    my_username = username;
+    my_user_id = app_id;
+}
+void ClientAppDescriptor::update_stats(AppId) {}
+void PayloadAppDescriptor::update_stats(AppId) {}
+
 AppIdDiscovery::AppIdDiscovery() { }
 AppIdDiscovery::~AppIdDiscovery() { }
 void ClientDiscovery::initialize() { }
index 96fa00a4736cc88a86ebb382938974141581899f..dcb79d297758217343d2e7783cef941e31e1a3d4 100644 (file)
@@ -112,7 +112,8 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp*, uint16_t, AppIdInspect
 
 AppIdSession::~AppIdSession()
 {
-    delete hsession;
+    for (auto* hsession: hsessions)
+        delete hsession;
     delete tsession;
     delete dsession;
     if (netbios_name)
@@ -245,14 +246,26 @@ bool AppIdSession::is_ssl_session_decrypted()
 {
     return is_session_decrypted;
 }
-
-AppIdHttpSession* AppIdSession::get_http_session()
+AppIdHttpSession* AppIdSession::create_http_session()
 {
-    if ( !hsession )
-        hsession = new MockAppIdHttpSession(*this);
+    AppIdHttpSession* hsession = new MockAppIdHttpSession(*this);
+    hsession->client.set_id(APPID_UT_ID);
+    hsession->payload.set_id(APPID_UT_ID);
+    hsession->misc_app_id = APPID_UT_ID;
+    hsession->referred_payload_app_id = APPID_UT_ID;
+    hsessions.push_back(hsession);
     return hsession;
 }
 
+AppIdHttpSession* AppIdSession::get_http_session(uint32_t stream_index)
+{
+    if (stream_index < hsessions.size())
+    {
+        return hsessions[stream_index];
+    }
+    return nullptr;
+}
+
 AppIdDnsSession* AppIdSession::get_dns_session()
 {
     if ( !dsession )
index 599e2f1d94516abac688f93e947e6dfd1e03b310..abddc139665a7750b4312dc4f50d2b7209c4c9db 100644 (file)
@@ -87,26 +87,50 @@ TEST(appid_session_api, get_only_service_app_id)
 
 TEST(appid_session_api, get_misc_app_id)
 {
+    mock_session->is_http2 = false;
     AppId id = appid_session_api->get_misc_app_id();
     CHECK_EQUAL(id, APPID_UT_ID);
+    mock_session->is_http2 = true;
+    id = appid_session_api->get_client_app_id(0);
+    CHECK_EQUAL(APPID_UT_ID, id);
+    id = appid_session_api->get_client_app_id(3);
+    CHECK_EQUAL(APP_ID_UNKNOWN, id);
 }
 
 TEST(appid_session_api, get_client_app_id)
 {
+    mock_session->is_http2 = false;
     AppId id = appid_session_api->get_client_app_id();
     CHECK_EQUAL(id, APPID_UT_ID);
+    mock_session->is_http2 = true;
+    id = appid_session_api->get_client_app_id(0);
+    CHECK_EQUAL(APPID_UT_ID, id);
+    id = appid_session_api->get_client_app_id(3);
+    CHECK_EQUAL(APP_ID_UNKNOWN, id);
 }
 
 TEST(appid_session_api, get_payload_app_id)
 {
+    mock_session->is_http2 = false;
     AppId id = appid_session_api->get_payload_app_id();
     CHECK_EQUAL(id, APPID_UT_ID);
+    mock_session->is_http2 = true;
+    id = appid_session_api->get_payload_app_id(0);
+    CHECK_EQUAL(APPID_UT_ID, id);
+    id = appid_session_api->get_payload_app_id(2);
+    CHECK_EQUAL(APP_ID_UNKNOWN, id);
 }
 
 TEST(appid_session_api, get_referred_app_id)
 {
+    mock_session->is_http2 = false;
     AppId id = appid_session_api->get_referred_app_id();
     CHECK_EQUAL(id, APPID_UT_ID);
+    mock_session->is_http2 = true;
+    id = appid_session_api->get_payload_app_id(0);
+    CHECK_EQUAL(APPID_UT_ID, id);
+    id = appid_session_api->get_payload_app_id(2);
+    CHECK_EQUAL(APP_ID_UNKNOWN, id);
 }
 
 TEST(appid_session_api, get_service_port)
@@ -243,8 +267,20 @@ TEST(appid_session_api, get_client_version)
     const char* val;
     val = appid_session_api->get_client_version();
     STRCMP_EQUAL(val, APPID_UT_CLIENT_VERSION);
+    val = appid_session_api->get_client_version(0);
+    STRCMP_EQUAL(APPID_UT_CLIENT_VERSION, val);
+    mock_session->is_http2 = true;
+    val = appid_session_api->get_client_version(2);
+    STRCMP_EQUAL(nullptr, val);
+}
+TEST(appid_session_api, get_http_session)
+{
+    AppIdHttpSession* val;
+    val = appid_session_api->get_http_session();
+    CHECK_TRUE(val != nullptr);
+    val = appid_session_api->get_http_session(2);
+    CHECK_TRUE(val == nullptr);
 }
-
 TEST(appid_session_api, get_appid_session_attribute)
 {
     uint64_t flags = 0x0000000000000001;
@@ -372,6 +408,7 @@ int main(int argc, char** argv)
 {
     mock_init_appid_pegs();
     mock_session = new AppIdSession(IpProtocol::TCP, nullptr, 1492, appid_inspector);
+    mock_session->create_http_session();
     int rc = CommandLineTestRunner::RunAllTests(argc, argv);
     mock_cleanup_appid_pegs();
     return rc;
index 672f88bf08d3d776fbca34b1d96b8f64588efae0..158b00320120caac88332bcf6f36a103098c1f8d 100644 (file)
@@ -72,6 +72,13 @@ THREAD_LOCAL AppIdStats appid_stats;
 void AppIdDebug::activate(const Flow*, const AppIdSession*, bool) { active = true; }
 
 void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
+void ApplicationDescriptor::set_id(AppId){}
+void ServiceAppDescriptor::set_id(AppId, OdpContext&){}
+void ServiceAppDescriptor::update_stats(AppId){}
+void ServiceAppDescriptor::set_port_service_id(AppId){}
+void ClientAppDescriptor::update_user(AppId, const char*){}
+void ClientAppDescriptor::update_stats(AppId) {}
+void PayloadAppDescriptor::update_stats(AppId) {}
 AppIdConfig::~AppIdConfig() { }
 AppIdConfig stub_config;
 AppIdContext stub_ctxt(stub_config);
index 923635b489b5bac9be4d08a2d67c8d73a3ae73b8..f26d66eaa188d077a3458c844e47444d8bdef6df 100644 (file)
@@ -86,7 +86,9 @@ static inline int check_ssl_appid_for_reinspect(AppId app_id, OdpContext& odp_ct
 static inline void process_http_session(AppIdSession& asd,
     ThirdPartyAppIDAttributeData& attribute_data, AppidChangeBits& change_bits)
 {
-    AppIdHttpSession* hsession = asd.get_http_session();
+    AppIdHttpSession* hsession = asd.get_http_session(0);
+    if (!hsession)
+        hsession = asd.create_http_session();
     string* field=0;
     bool own=true;
 
@@ -398,6 +400,8 @@ static inline void process_rtmp(AppIdSession& asd,
     ThirdPartyAppIDAttributeData& attribute_data, int confidence, AppidChangeBits& change_bits)
 {
     AppIdHttpSession* hsession = asd.get_http_session();
+    if (!hsession)
+        hsession = asd.create_http_session();
     AppId service_id = 0;
     AppId client_id = 0;
     AppId payload_id = 0;
@@ -799,6 +803,8 @@ bool do_tp_discovery(ThirdPartyAppIdContext& tp_appid_ctxt, AppIdSession& asd, I
                     }
 
                     AppIdHttpSession* hsession = asd.get_http_session();
+                    if (!hsession)
+                        hsession = asd.create_http_session();
                     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.