]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2296 in SNORT/snort3 from ~SHRARANG/snort3:appid_stash3 to master
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Mon, 20 Jul 2020 21:37:55 +0000 (21:37 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Mon, 20 Jul 2020 21:37:55 +0000 (21:37 +0000)
Squashed commit of the following:

commit cea2b438cc8c294199adb26c56d14e005ff16c80
Author: Shravan Rangaraju <shrarang@cisco.com>
Date:   Tue Jun 23 23:54:14 2020 -0400

    appid: move appid data needed by external components to stash

45 files changed:
src/flow/flow_stash.cc
src/flow/flow_stash.h
src/flow/stash_item.h
src/network_inspectors/appid/app_forecast.cc
src/network_inspectors/appid/appid_api.cc
src/network_inspectors/appid/appid_api.h
src/network_inspectors/appid/appid_dcerpc_event_handler.h
src/network_inspectors/appid/appid_debug.cc
src/network_inspectors/appid/appid_detector.cc
src/network_inspectors/appid/appid_detector.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_http_event_handler.cc
src/network_inspectors/appid/appid_http_session.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_stats.cc
src/network_inspectors/appid/application_ids.h
src/network_inspectors/appid/client_plugins/client_discovery.cc
src/network_inspectors/appid/detector_plugins/detector_sip.cc
src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h
src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc
src/network_inspectors/appid/ips_appid_option.cc
src/network_inspectors/appid/lua_detector_api.cc
src/network_inspectors/appid/service_plugins/service_detector.cc
src/network_inspectors/appid/service_plugins/service_discovery.cc
src/network_inspectors/appid/service_plugins/service_ftp.cc
src/network_inspectors/appid/service_plugins/service_snmp.cc
src/network_inspectors/appid/service_plugins/service_tftp.cc
src/network_inspectors/appid/service_plugins/test/service_netbios_test.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_debug_test.cc
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_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
src/pub_sub/appid_events.h

index 2bc44eff575c5562519f759b4da51c6022f7fa2f..7bed26373d7ee9b68c1191452002aa5b2a906a5b 100644 (file)
@@ -80,12 +80,12 @@ void FlowStash::store(const string& key, const string& val)
     store(key, val, STASH_ITEM_TYPE_STRING);
 }
 
-void FlowStash::store(const std::string& key, StashGenericObject* val)
+void FlowStash::store(const std::string& key, StashGenericObject* val, bool publish)
 {
-    store(key, val, STASH_ITEM_TYPE_GENERIC_OBJECT);
+    store(key, val, STASH_ITEM_TYPE_GENERIC_OBJECT, publish);
 }
 
-void FlowStash::store(const string& key, StashGenericObject* &val, StashItemType type)
+void FlowStash::store(const string& key, StashGenericObject* &val, StashItemType type, bool publish)
 {
 #ifdef NDEBUG
     UNUSED(type);
@@ -103,8 +103,11 @@ void FlowStash::store(const string& key, StashGenericObject* &val, StashItemType
         it_and_status.first->second = item;
     }
 
-    StashEvent e(item);
-    DataBus::publish(key.c_str(), e);
+    if (publish)
+    {
+        StashEvent e(item);
+        DataBus::publish(key.c_str(), e);
+    }
 }
 
 void FlowStash::store(const std::string& key, std::string* val)
index 1f57168a533800b9790625331d22b347f9cc5f22..bc7894aefcd1c5cb9d648649933ae67ff3c5afa2 100644 (file)
@@ -44,7 +44,7 @@ public:
     void store(const std::string& key, uint32_t val);
     void store(const std::string& key, const std::string& val);
     void store(const std::string& key, std::string* val);
-    void store(const std::string& key, StashGenericObject* val);
+    void store(const std::string& key, StashGenericObject* val, bool publish = true);
 
 private:
     std::map<std::string, StashItem*> container;
@@ -53,7 +53,8 @@ private:
     bool get(const std::string& key, T& val, StashItemType type);
     template<typename T>
     void store(const std::string& key, T& val, StashItemType type);
-    void store(const std::string& key, StashGenericObject* &val, StashItemType type);
+    void store(const std::string& key, StashGenericObject* &val, StashItemType type,
+        bool publish = true);
 };
 
 }
index baf4aa85d6d18de3f6401718dfe0e064fe02062b..a66007bc563aecaa605174fed53e7e1d49752ff8 100644 (file)
 #include <cstdint>
 #include <string>
 
+#define STASH_APPID_DATA "appid_data"
+
+#define STASH_GENERIC_OBJECT_APPID 1
+
 namespace snort
 {
 
index af295799571e9ae2e7e86aa6b5ad1b90219e5abb..4e18472378f3fddcc7a3029965c4c6900900738f 100644 (file)
@@ -66,7 +66,7 @@ AppId check_session_for_AF_forecast(AppIdSession& asd, Packet* p, AppidSessionDi
         odp_thread_ctxt->erase_af_actives(master_key);
         return APP_ID_UNKNOWN;
     }
-    asd.payload.set_id(check_act_val->second.target);
+    asd.set_payload_id(check_act_val->second.target);
     return forecast;
 }
 
index 1fcd8141f0a03a3b85dc64c45ac57c8ff531fe25..4f072d5f9106e88b76a2c211d326287c018a65d2 100644 (file)
@@ -110,19 +110,19 @@ uint32_t AppIdApi::produce_ha_state(const Flow& flow, uint8_t* buf)
         if (asd->get_session_flags(APPID_SESSION_HTTP_SESSION))
             appHA->flags |= APPID_HA_FLAGS_HTTP;
         appHA->appId[0] = asd->get_tp_app_id();
-        appHA->appId[1] = asd->service.get_id();
+        appHA->appId[1] = asd->get_service_id();
         appHA->appId[2] = asd->client_inferred_service_id;
-        appHA->appId[3] = asd->service.get_port_service_id();
-        AppIdHttpSession* hsession = asd->get_http_session();
+        appHA->appId[3] = asd->get_port_service_id();
+        const AppIdHttpSession* hsession = asd->get_http_session();
         if (hsession)
             appHA->appId[4] = hsession->payload.get_id();
         else
-            appHA->appId[4] = asd->payload.get_id();
+            appHA->appId[4] = asd->get_payload_id();
         appHA->appId[5] = asd->get_tp_payload_app_id();
         if (hsession)
             appHA->appId[6] = hsession->client.get_id();
         else
-            appHA->appId[6] = asd->client.get_id();
+            appHA->appId[6] = asd->get_client_id();
         appHA->appId[7] = asd->misc_app_id;
     }
     else
@@ -147,8 +147,8 @@ uint32_t AppIdApi::consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t, IpP
             {
                 asd = new AppIdSession(proto, ip, port, *inspector);
                 flow.set_flow_data(asd);
-                asd->service.set_id(appHA->appId[1], asd->ctxt.get_odp_ctxt());
-                if (asd->service.get_id() == APP_ID_FTP_CONTROL)
+                asd->set_service_id(appHA->appId[1], asd->ctxt.get_odp_ctxt());
+                if (asd->get_service_id() == APP_ID_FTP_CONTROL)
                 {
                     asd->set_session_flags(APPID_SESSION_CLIENT_DETECTED |
                             APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED);
@@ -184,21 +184,21 @@ uint32_t AppIdApi::consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t, IpP
             asd->set_session_flags(APPID_SESSION_HTTP_SESSION);
 
         asd->set_tp_app_id(appHA->appId[0]);
-        asd->service.set_id(appHA->appId[1], asd->ctxt.get_odp_ctxt());
+        asd->set_service_id(appHA->appId[1], asd->ctxt.get_odp_ctxt());
         asd->client_inferred_service_id = appHA->appId[2];
-        asd->service.set_port_service_id(appHA->appId[3]);
+        asd->set_port_service_id(appHA->appId[3]);
         AppIdHttpSession* hsession = nullptr;
         if (appHA->appId[1] == APP_ID_HTTP or appHA->appId[1] == APP_ID_RTMP)
             hsession = asd->create_http_session();
         if (hsession)
             hsession->payload.set_id(appHA->appId[4]);
         else
-            asd->payload.set_id(appHA->appId[4]);
+            asd->set_payload_id(appHA->appId[4]);
         asd->set_tp_payload_app_id(appHA->appId[5]);
         if (hsession)
             hsession->client.set_id(appHA->appId[6]);
         else
-            asd->client.set_id(appHA->appId[6]);
+            asd->set_client_id(appHA->appId[6]);
         asd->misc_app_id = appHA->appId[7];
     }
     return sizeof(*appHA);
@@ -275,20 +275,20 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
 
         asd->scan_flags |= SCAN_CERTVIZ_ENABLED_FLAG;
 
-        service_id = asd->get_application_ids_service();
-        AppId misc_id = asd->get_application_ids_misc();
+        service_id = asd->get_api().get_service_app_id();
 
         if (client_id == APP_ID_NONE)
-            client_id = asd->get_application_ids_client();
+            client_id = asd->get_api().get_client_app_id();
         else
-            asd->client.set_id(client_id);
+            asd->set_client_id(client_id);
 
         if (payload_id == APP_ID_NONE)
-            payload_id = asd->get_application_ids_payload();
+            payload_id = asd->get_api().get_payload_app_id();
         else
-            asd->payload.set_id(payload_id);
+            asd->set_payload_id(payload_id);
 
-        asd->set_ss_application_ids(service_id, client_id, payload_id, misc_id, change_bits);
+        asd->set_ss_application_ids(client_id, payload_id, change_bits);
+        asd->set_tls_host(change_bits);
 
         asd->publish_appid_event(change_bits, flow);
     }
@@ -314,7 +314,7 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
         }
     }
 
-    if (service_id != APP_ID_NONE or client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
+    if (client_id != APP_ID_NONE or payload_id != APP_ID_NONE)
     {
         return true;
     }
index 1291f528081e1578187e3408554c6153e95a320f..26ba1542674b7afed121b77230a0fade03deacf0 100644 (file)
@@ -63,6 +63,29 @@ public:
         const char*, bool, AppId& service_id, AppId& client_id, AppId& payload_id);
     const AppIdSessionApi* get_appid_session_api(const Flow& flow) const;
     bool is_inspection_needed(const Inspector& g) const;
+
+    bool is_service_http_type(AppId service_id) const
+    {
+        switch (service_id)
+        {
+            case APP_ID_HTTP:
+            case APP_ID_HTTPS:
+            case APP_ID_HTTP2:
+            case APP_ID_FTPS:
+            case APP_ID_IMAPS:
+            case APP_ID_IRCS:
+            case APP_ID_LDAPS:
+            case APP_ID_NNTPS:
+            case APP_ID_POP3S:
+            case APP_ID_SMTPS:
+            case APP_ID_SSHELL:
+            case APP_ID_SSL:
+            case APP_ID_QUIC:
+                return true;
+        }
+
+        return false;
+    }
 };
 
 SO_PUBLIC extern AppIdApi appid_api;
index 3e2aed796444ae0afcb2d08215aaec9d0e277285..985d34ddb9053400af215029f96583a2315a6d33 100644 (file)
@@ -54,7 +54,7 @@ public:
 
         if (fp) // initialize data session
         {
-            fp->service.set_id(APP_ID_DCE_RPC, asd->ctxt.get_odp_ctxt());
+            fp->set_service_id(APP_ID_DCE_RPC, asd->ctxt.get_odp_ctxt());
             asd->initialize_future_session(*fp, APPID_SESSION_IGNORE_ID_FLAGS,
                 APP_ID_FROM_RESPONDER);
         }
index c30ccd4216f4e36bbe5ced3bab72e8f2e8bcbb58..da2f31b4ad84248e3545dfc8329c03404687ba51 100644 (file)
@@ -79,7 +79,7 @@ void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t por
             dport = port1;
         }
     }
-    else if (memcmp(session->initiator_ip.get_ip6_ptr(),
+    else if (memcmp(session->get_initiator_ip().get_ip6_ptr(),
                 ip1, sizeof(ip::snort_in6_addr)) == 0)
     {
         sip = (const ip::snort_in6_addr*)ip1;
index ad4483a9bdba7a8c13178ae2586cdd08c0d3d0ae..a342832a7f40dacde5d8baf2231e34f8e3eb578c 100644 (file)
@@ -76,7 +76,7 @@ int AppIdDetector::data_add(AppIdSession& asd, void* data, AppIdFreeFCN fcn)
 
 void AppIdDetector::add_user(AppIdSession& asd, const char* username, AppId appId, bool success)
 {
-    asd.client.update_user(appId, username);
+    asd.set_client_user(appId, username);
     if ( success )
         asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED);
     else
@@ -85,18 +85,18 @@ void AppIdDetector::add_user(AppIdSession& asd, const char* username, AppId appI
 
 void AppIdDetector::add_payload(AppIdSession& asd, AppId payload_id)
 {
-    asd.payload.set_id(payload_id);
+    asd.set_payload_id(payload_id);
 }
 
 void AppIdDetector::add_app(const Packet& p, AppIdSession& asd, AppidSessionDirection dir, AppId service_id,
     AppId client_id, const char* version, AppidChangeBits& change_bits)
 {
     if ( version )
-        asd.client.set_version(version, change_bits);
+        asd.set_client_version(version, change_bits);
 
     asd.set_client_detected();
     asd.client_inferred_service_id = service_id;
-    asd.client.set_id(p, asd, dir, client_id, change_bits);
+    asd.set_client_id(p, dir, client_id, change_bits);
 }
 
 const char* AppIdDetector::get_code_string(APPID_STATUS_CODE code) const
index 3846e3198217bbf5f1351439582f4fb4d1fc0be5..bde7edc1be9f538e26fc2e7068b541e7c7b6db69 100644 (file)
@@ -123,11 +123,11 @@ public:
     virtual void add_app(AppIdSession& asd, AppId service_id, AppId client_id, const char* version, AppidChangeBits& change_bits)
     {
         if ( version )
-            asd.client.set_version(version, change_bits);
+            asd.set_client_version(version, change_bits);
 
         asd.set_client_detected();
         asd.client_inferred_service_id = service_id;
-        asd.client.set_id(client_id);
+        asd.set_client_id(client_id);
     }
     virtual void add_app(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppId, const char*, AppidChangeBits&);
     const char* get_code_string(APPID_STATUS_CODE) const;
index 36d4e99fc467a77f0a9117417461129f9ae13d6b..8e45b4b6c7c01e9d1ee9534fdb8dbf82c959140d 100644 (file)
@@ -188,7 +188,7 @@ static bool set_network_attributes(AppIdSession* asd, Packet* p, IpProtocol& pro
         else
         {
             const SfIp* ip = p->ptrs.ip_api.get_src();
-            direction = ip->fast_equals_raw(asd->initiator_ip) ?
+            direction = ip->fast_equals_raw(asd->get_initiator_ip()) ?
                 APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
         }
 
@@ -437,17 +437,18 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession*& asd, AppIdInspec
         AppidChangeBits change_bits;
 
         asd->set_ss_application_ids(asd->pick_service_app_id(), asd->pick_ss_client_app_id(),
-            asd->pick_ss_payload_app_id(), asd->pick_ss_misc_app_id(), change_bits);
+            asd->pick_ss_payload_app_id(), asd->pick_ss_misc_app_id(),
+            asd->pick_ss_referred_payload_app_id(), change_bits);
         asd->publish_appid_event(change_bits, p->flow);
         asd->set_session_flags(APPID_SESSION_FUTURE_FLOW_IDED);
 
         if (appidDebug->is_active())
         {
             const char *app_name =
-                asd->ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(asd->service.get_id());
+                asd->ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(asd->get_service_id());
             LogMessage("AppIdDbg %s Ignoring connection with service %s (%d)\n",
                 appidDebug->get_debug_session(), app_name ? app_name : "unknown",
-                asd->service.get_id());
+                asd->get_service_id());
         }
 
         return false;
@@ -505,6 +506,7 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession*& asd, AppIdInspec
                     port = p->ptrs.sp;
                 }
                 AppIdServiceState::check_reset(*asd, ip, port);
+                return false;
             }
             asd->previous_tcp_flags = p->ptrs.tcph->th_flags;
         }
@@ -550,14 +552,14 @@ void AppIdDiscovery::do_port_based_discovery(Packet* p, AppIdSession& asd, IpPro
     AppId id = asd.ctxt.get_odp_ctxt().get_port_service_id(protocol, p->ptrs.sp);
     if (id > APP_ID_NONE)
     {
-        asd.service.set_port_service_id(id);
+        asd.set_port_service_id(id);
         if (appidDebug->is_active())
         {
-            AppId ps_id = asd.service.get_port_service_id();
+            AppId ps_id = asd.get_port_service_id();
             const char *app_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(ps_id);
             LogMessage("AppIdDbg %s Port service %s (%d) from port\n",
                 appidDebug->get_debug_session(), app_name ? app_name : "unknown",
-                asd.service.get_port_service_id());
+                asd.get_port_service_id());
         }
     }
     asd.set_session_flags(APPID_SESSION_PORT_SERVICE_DONE);
@@ -619,22 +621,22 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd,
         switch (hv->type)
         {
         case APP_ID_TYPE_CLIENT:
-            asd.client.set_id(hv->appId);
+            asd.set_client_id(hv->appId);
             asd.client_disco_state = APPID_DISCO_STATE_FINISHED;
             break;
         case APP_ID_TYPE_PAYLOAD:
-            asd.payload.set_id(hv->appId);
+            asd.set_payload_id(hv->appId);
             break;
         default:
-            asd.service.set_id(hv->appId, asd.ctxt.get_odp_ctxt());
+            asd.set_service_id(hv->appId, asd.ctxt.get_odp_ctxt());
             asd.sync_with_snort_protocol_id(hv->appId, p);
             asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
             asd.client_disco_state = APPID_DISCO_STATE_FINISHED;
             asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED);
             if (asd.tpsession)
                 asd.tpsession->reset();
-            if ( asd.payload.get_id() == APP_ID_NONE)
-                asd.payload.set_id(APP_ID_UNKNOWN);
+            if ( asd.get_payload_id() == APP_ID_NONE)
+                asd.set_payload_id(APP_ID_UNKNOWN);
         }
         asd.set_session_flags(APPID_SESSION_HOST_CACHE_MATCHED);
         return true;
@@ -654,7 +656,7 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd,
             if (appid > APP_ID_NONE)
             {
                 // FIXIT-L: Make this more generic to support service and payload IDs
-                asd.client.set_id(appid);
+                asd.set_client_id(appid);
                 asd.client_disco_state = APPID_DISCO_STATE_FINISHED;
                 asd.set_session_flags(APPID_SESSION_HOST_CACHE_MATCHED);
             }
@@ -670,9 +672,8 @@ static inline bool is_check_host_cache_valid(AppIdSession& asd, AppId service_id
     bool is_payload_client_misc_none = (payload_id <= APP_ID_NONE and client_id <= APP_ID_NONE and
         misc_id <= APP_ID_NONE);
     bool is_appid_none = is_payload_client_misc_none and (service_id <= APP_ID_NONE or
-        service_id == APP_ID_UNKNOWN_UI or
         (asd.ctxt.get_odp_ctxt().recheck_for_portservice_appid and
-        service_id == asd.service.get_port_service_id()));
+        service_id == asd.get_port_service_id()));
     bool is_ssl_none = asd.ctxt.get_odp_ctxt().check_host_cache_unknown_ssl and
         asd.get_session_flags(APPID_SESSION_SSL_SESSION) and
         (not(asd.tsession and asd.tsession->get_tls_host() and asd.tsession->get_tls_cname()));
@@ -714,12 +715,12 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
             AppId id = asd.ctxt.get_odp_ctxt().get_protocol_service_id(protocol);
             if (id > APP_ID_NONE)
             {
-                asd.service.set_port_service_id(id);
+                asd.set_port_service_id(id);
                 service_id = id;
                 asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
                 if (appidDebug->is_active())
                 {
-                    AppId ps_id = asd.service.get_port_service_id();
+                    AppId ps_id = asd.get_port_service_id();
                     const char *app_name =
                         asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(ps_id);
                     LogMessage("AppIdDbg %s Protocol service %s (%d) from protocol\n",
@@ -768,8 +769,8 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
             APPID_SESSION_CONTINUE) == APPID_SESSION_SERVICE_DETECTED)
         {
             asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
-            if ( asd.payload.get_id() == APP_ID_NONE)
-                asd.payload.set_id(APP_ID_UNKNOWN);
+            if ( asd.get_payload_id() == APP_ID_NONE)
+                asd.set_payload_id(APP_ID_UNKNOWN);
         }
     }
     // FIXIT-M - snort 2.x has added a check for midstream pickup to this, do we need that?
@@ -789,7 +790,7 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
     service_id = asd.pick_service_app_id();
 
     // Length-based service detection if no service is found yet
-    if ((service_id <= APP_ID_NONE or service_id == APP_ID_UNKNOWN_UI) and (p->dsize > 0) and
+    if ((service_id <= APP_ID_NONE) and (p->dsize > 0) and
          (asd.length_sequence.sequence_cnt < LENGTH_SEQUENCE_CNT_MAX) and
          !asd.get_session_flags(APPID_SESSION_OOO))
     {
@@ -802,7 +803,7 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
         if (id > APP_ID_NONE)
         {
             service_id = id;
-            asd.service.set_port_service_id(id);
+            asd.set_port_service_id(id);
             if (appidDebug->is_active())
             {
                 const char *app_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(id);
@@ -813,7 +814,7 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
         }
     }
 
-    payload_id = asd.pick_ss_payload_app_id();
+    payload_id = asd.pick_ss_payload_app_id(service_id);
     client_id = asd.pick_ss_client_app_id();
     misc_id =  asd.pick_ss_misc_app_id();
 
@@ -837,10 +838,10 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
 
         if (do_host_port_based_discovery(p, asd, protocol, direction))
         {
-            asd.service.set_port_service_id(APP_ID_NONE);
+            asd.set_port_service_id(APP_ID_NONE);
             service_id = asd.pick_service_app_id();
             client_id = asd.pick_ss_client_app_id();
-            payload_id = asd.pick_ss_payload_app_id();
+            payload_id = asd.pick_ss_payload_app_id(service_id);
         }
     }
 
@@ -874,11 +875,11 @@ void AppIdDiscovery::do_post_discovery(Packet* p, AppIdSession& asd,
         }
 
         if (asd.past_forecast != service_id and asd.past_forecast != APP_ID_UNKNOWN and
-             asd.payload.get_id() == APP_ID_NONE)
+             asd.get_payload_id() == APP_ID_NONE)
         {
             asd.past_forecast = check_session_for_AF_forecast(asd, p, direction, service_id);
             if (asd.past_forecast != APP_ID_UNKNOWN)
-                payload_id = asd.pick_ss_payload_app_id();
+                payload_id = asd.pick_ss_payload_app_id(service_id);
         }
     }
 
@@ -895,6 +896,9 @@ void AppIdDiscovery::do_post_discovery(Packet* p, AppIdSession& asd,
         }
     }
 
-    asd.set_ss_application_ids(service_id, client_id, payload_id, misc_id, change_bits);
+    asd.set_ss_application_ids(service_id, client_id, payload_id, misc_id,
+        asd.pick_ss_referred_payload_app_id(), change_bits);
+    asd.set_tls_host(change_bits);
+
     asd.publish_appid_event(change_bits, p->flow);
 }
index 0561153e4455fb30a4fbc73ce9394c8d0ad608f5..87b5b60b97a5eaac35710b6d557d848864e6d423 100644 (file)
@@ -171,19 +171,20 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow)
 
     if (http_event->get_is_http2())
     {
-        asd->service.set_id(APP_ID_HTTP2, asd->ctxt.get_odp_ctxt());
+        asd->set_service_id(APP_ID_HTTP2, asd->ctxt.get_odp_ctxt());
     }
 
     hsession->process_http_packet(direction, change_bits,
         asd->ctxt.get_odp_ctxt().get_http_matchers());
 
-    if (asd->service.get_id() != APP_ID_HTTP2)
+    if (asd->get_service_id() != APP_ID_HTTP2)
         asd->set_ss_application_ids(asd->pick_service_app_id(), asd->pick_ss_client_app_id(),
-            asd->pick_ss_payload_app_id(), asd->pick_ss_misc_app_id(), change_bits);
+            asd->pick_ss_payload_app_id(), asd->pick_ss_misc_app_id(),
+            asd->pick_ss_referred_payload_app_id(), change_bits);
     else
-          asd->set_application_ids_service(APP_ID_HTTP2, change_bits);      
+        asd->set_application_ids_service(APP_ID_HTTP2, change_bits);
 
     asd->publish_appid_event(change_bits, flow, http_event->get_is_http2(),
-        asd->get_hsessions_size() - 1);
+        asd->get_api().get_hsessions_size() - 1);
 }
 
index 67d0327f4b068a8d1fdafeaf1cf2fcc3ff9413b7..05c8dcf47d023f3ce4ca2329b6f22efc6c18b410 100644 (file)
@@ -379,7 +379,7 @@ void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits, HttpPat
             if (app_type_flags & APP_TYPE_SERVICE)
                 client.update_user(chp_final, user);
             else
-                client.update_user(asd.service.get_id(), user);
+                client.update_user(asd.get_service_id(), user);
             user = nullptr;
             asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED);
         }
@@ -488,7 +488,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
                 if (appidDebug->is_active())
                     LogMessage("AppIdDbg %s Bad http response code.\n",
                         appidDebug->get_debug_session());
-                asd.reset_session_data();
+                asd.reset_session_data(change_bits);
                 return 0;
             }
         }
@@ -497,7 +497,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
         {
             set_session_flags(APPID_SESSION_RESPONSE_CODE_CHECKED);
             /* didn't receive response code in first X packets. Stop processing this session */
-            asd.reset_session_data();
+            asd.reset_session_data(change_bits);
             if (appidDebug->is_active())
                 LogMessage("AppIdDbg %s No response code received\n",
                     appidDebug->get_debug_session());
@@ -506,10 +506,10 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
 #endif
     }
 
-    if (asd.service.get_id() == APP_ID_NONE or asd.service.get_id() == APP_ID_HTTP2)
+    if (asd.get_service_id() == APP_ID_NONE or asd.get_service_id() == APP_ID_HTTP2)
     {
-        if (asd.service.get_id() == APP_ID_NONE)
-            asd.service.set_id(APP_ID_HTTP, asd.ctxt.get_odp_ctxt());
+        if (asd.get_service_id() == APP_ID_NONE)
+            asd.set_service_id(APP_ID_HTTP, asd.ctxt.get_odp_ctxt());
         asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED);
         asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
     }
@@ -526,8 +526,8 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
         const std::string* server = meta_data[MISC_SERVER_FID];
         if ( (asd.scan_flags & SCAN_HTTP_VENDOR_FLAG) and server)
         {
-            if ( asd.service.get_id() == APP_ID_NONE or asd.service.get_id() == APP_ID_HTTP  or
-                asd.service.get_id() == APP_ID_HTTP2)
+            if ( asd.get_service_id() == APP_ID_NONE or asd.get_service_id() == APP_ID_HTTP  or
+                asd.get_service_id() == APP_ID_HTTP2)
                 {
                     char* vendorVersion = nullptr;
                     char* vendor = nullptr;
@@ -537,8 +537,8 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
                         &vendorVersion, &vendor, &subtype);
                     if (vendor || vendorVersion)
                     {
-                        asd.service.set_vendor(vendor);
-                        asd.service.set_version(vendorVersion, change_bits);
+                        asd.set_service_vendor(vendor);
+                        asd.set_service_version(vendorVersion, change_bits);
                         asd.scan_flags &= ~SCAN_HTTP_VENDOR_FLAG;
 
                         snort_free(vendor);
@@ -573,7 +573,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
             if (appidDebug->is_active())
             {
                 if (service_id > APP_ID_NONE and service_id != APP_ID_HTTP and
-                    asd.service.get_id() != service_id)
+                    asd.get_service_id() != service_id)
                 {
                     const char *app_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(service_id);
                     LogMessage("AppIdDbg %s User Agent is service %s (%d)\n",
@@ -614,7 +614,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
             set_client(app_id, change_bits, "X-working-with", version);
         else
         {
-            if (app_id and asd.service.get_id() != app_id)
+            if (app_id and asd.get_service_id() != app_id)
             {
                 asd.set_service_appid_data(app_id, change_bits, version);
                 if (appidDebug->is_active())
@@ -662,10 +662,10 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
             if (client.get_id() <= APP_ID_NONE and client_id != APP_ID_HTTP)
                 set_client(client_id, change_bits, "URL", version);
 
-            if (asd.service.get_id() <= APP_ID_NONE)
+            if (asd.get_service_id() <= APP_ID_NONE)
             {
                 if (appidDebug->is_active() && service_id > APP_ID_NONE && service_id !=
-                    APP_ID_HTTP && asd.service.get_id() != service_id)
+                    APP_ID_HTTP && asd.get_service_id() != service_id)
                 {
                     const char *app_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(service_id);
                     LogMessage("AppIdDbg %s URL is service %s (%d)\n",
@@ -714,9 +714,9 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
             }
         }
     }
-    if (payload.get_id() <=APP_ID_NONE and is_payload_processed and
-        (asd.service.get_id()== APP_ID_HTTP2 or (asd.service.get_id()== APP_ID_HTTP and
-        asd.is_tp_appid_available())))
+    if (payload.get_id() <= APP_ID_NONE and is_payload_processed and
+        (asd.get_service_id() == APP_ID_HTTP2 or (asd.get_service_id() == APP_ID_HTTP and
+            asd.is_tp_appid_available())))
         set_payload(APP_ID_UNKNOWN, change_bits);
 
     asd.clear_http_flags();
index e51c03ba7406646b6da5b9614abe59ac3291aaba..ef5333cc32c41fde537cdbee113b1b4aed4ba2c4 100644 (file)
@@ -148,8 +148,6 @@ public:
     int get_ptype_scan_count(enum HttpFieldIds type) const
     { return ptype_scan_counts[type]; }
 
-    virtual void custom_init() { }
-
     void clear_all_fields();
     void set_client(AppId, AppidChangeBits&, const char*, const char* version = nullptr);
     void set_payload(AppId, AppidChangeBits&, const char* type = nullptr, const char* version = nullptr);
index 157effb26ca2ef8db785c63ce2eed7a1a10bb128..67ff4c4c1669e230cdc7a13608807199cd4d9946 100644 (file)
@@ -71,7 +71,7 @@ static void add_appid_to_packet_trace(Flow& flow)
     {
         AppId service_id, client_id, payload_id, misc_id;
         const char* service_app_name, * client_app_name, * payload_app_name, * misc_name;
-        session->get_first_stream_app_ids(service_id, client_id, payload_id, misc_id);
+        session->get_api().get_first_stream_app_ids(service_id, client_id, payload_id, misc_id);
         service_app_name = appid_api.get_application_name(service_id, session->ctxt);
         client_app_name = appid_api.get_application_name(client_id, session->ctxt);
         payload_app_name = appid_api.get_application_name(payload_id, session->ctxt);
@@ -80,11 +80,11 @@ static void add_appid_to_packet_trace(Flow& flow)
         if (PacketTracer::is_active())
         {
             PacketTracer::log(appid_mute,
-                    "AppID: service: %s(%d), client: %s(%d), payload: %s(%d), misc: %s(%d)\n",
-                    (service_app_name ? service_app_name : ""), service_id,
-                    (client_app_name ? client_app_name : ""), client_id,
-                    (payload_app_name ? payload_app_name : ""), payload_id,
-                    (misc_name ? misc_name : ""), misc_id);
+                "AppID: service: %s(%d), client: %s(%d), payload: %s(%d), misc: %s(%d)\n",
+                (service_app_name ? service_app_name : ""), service_id,
+                (client_app_name ? client_app_name : ""), client_id,
+                (payload_app_name ? payload_app_name : ""), payload_id,
+                (misc_name ? misc_name : ""), misc_id);
         }
     }
 }
index e880aa53929e55c1c4f963e581f6a733d5311a88..a73567f5aa43f70701fc38622a62727ca2d101c5 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <cstring>
 
+#include "flow/flow_stash.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
 #include "managers/inspector_manager.h"
@@ -95,11 +96,10 @@ AppIdSession* AppIdSession::allocate_session(const Packet* p, IpProtocol proto,
 AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t port,
     AppIdInspector& inspector)
     : FlowData(inspector_id, &inspector), ctxt(inspector.get_ctxt()),
-    protocol(proto)
+        protocol(proto), api(*(new AppIdSessionApi(this, *ip)))
 {
     service_ip.clear();
     session_id = ++appid_flow_data_id;
-    initiator_ip = *ip;
     initiator_port = port;
 
     appid_stats.total_sessions++;
@@ -139,10 +139,18 @@ AppIdSession::~AppIdSession()
             delete tpsession;
     }
 
-    delete_session_data();
+    delete_session_data(false);
     free_flow_data();
     service_candidates.clear();
     client_candidates.clear();
+
+    // If api was not stored in the stash, delete it. An example would be when an appid future
+    // session is created, but it doesn't get attached to a snort flow (because the packets for the
+    // future session were never received by snort), api object is not stored in the stash.
+    if (!api.stored_in_stash)
+        delete &api;
+    else
+        api.asd = nullptr;
 }
 
 // FIXIT-RC X Move this to somewhere more generally available/appropriate (decode_data.h).
@@ -248,6 +256,7 @@ void AppIdSession::initialize_future_session(AppIdSession& expected, uint64_t fl
     expected.service_disco_state = APPID_DISCO_STATE_FINISHED;
     expected.client_disco_state = APPID_DISCO_STATE_FINISHED;
 }
+
 void AppIdSession::reinit_session_data(AppidChangeBits& change_bits)
 {
     misc_app_id = APP_ID_NONE;
@@ -255,17 +264,17 @@ void AppIdSession::reinit_session_data(AppidChangeBits& change_bits)
     //data
     if (is_service_over_ssl(tp_app_id))
     {
-        payload.reset();
+        api.payload.reset();
         tp_payload_app_id = APP_ID_NONE;
         clear_session_flags(APPID_SESSION_CONTINUE);
-        if (!hsessions.empty())
-            hsessions[0]->set_field(MISC_URL_FID, nullptr, change_bits);
+        if (!api.hsessions.empty())
+            api.hsessions[0]->set_field(MISC_URL_FID, nullptr, change_bits);
     }
 
     //service
     if (!get_session_flags(APPID_SESSION_STICKY_SERVICE))
     {
-        service.reset();
+        api.service.reset();
         tp_app_id = APP_ID_NONE;
         service_ip.clear();
         service_port = 0;
@@ -276,7 +285,7 @@ void AppIdSession::reinit_session_data(AppidChangeBits& change_bits)
     }
 
     //client
-    client.reset();
+    api.client.reset();
     client_inferred_service_id = APP_ID_NONE;
     client_disco_state = APPID_DISCO_STATE_NONE;
     free_flow_data_by_mask(APPID_SESSION_DATA_CLIENT_MODSTATE_BIT);
@@ -385,10 +394,10 @@ void AppIdSession::check_tunnel_detection_restart()
             appidDebug->get_debug_session());
 
     // service
-    if (service.get_id() == service.get_port_service_id())
-        service.set_id(APP_ID_NONE, ctxt.get_odp_ctxt());
-    service.set_port_service_id(APP_ID_NONE);
-    service.reset();
+    if (api.service.get_id() == api.service.get_port_service_id())
+        api.service.set_id(APP_ID_NONE, ctxt.get_odp_ctxt());
+    api.service.set_port_service_id(APP_ID_NONE);
+    api.service.reset();
     service_ip.clear();
     service_port = 0;
     service_disco_state = APPID_DISCO_STATE_NONE;
@@ -396,7 +405,7 @@ void AppIdSession::check_tunnel_detection_restart()
     free_flow_data_by_mask(APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
 
     // client
-    client.reset();
+    api.client.reset();
     client_inferred_service_id = APP_ID_NONE;
     client_disco_state = APPID_DISCO_STATE_NONE;
     free_flow_data_by_mask(APPID_SESSION_DATA_CLIENT_MODSTATE_BIT);
@@ -482,7 +491,7 @@ void AppIdSession::examine_ssl_metadata(AppidChangeBits& change_bits)
         if (ctxt.get_odp_ctxt().get_ssl_matchers().scan_hostname((const uint8_t*)tls_str, size,
             client_id, payload_id))
         {
-            if (client.get_id() == APP_ID_NONE or client.get_id() == APP_ID_SSL_CLIENT)
+            if (api.client.get_id() == APP_ID_NONE or api.client.get_id() == APP_ID_SSL_CLIENT)
                 set_client_appid_data(client_id, change_bits);
             set_payload_appid_data(payload_id, change_bits);
         }
@@ -494,7 +503,7 @@ void AppIdSession::examine_ssl_metadata(AppidChangeBits& change_bits)
         if (ctxt.get_odp_ctxt().get_ssl_matchers().scan_cname((const uint8_t*)tls_str, size,
             client_id, payload_id))
         {
-            if (client.get_id() == APP_ID_NONE or client.get_id() == APP_ID_SSL_CLIENT)
+            if (api.client.get_id() == APP_ID_NONE or api.client.get_id() == APP_ID_SSL_CLIENT)
                 set_client_appid_data(client_id, change_bits);
             set_payload_appid_data(payload_id, change_bits);
         }
@@ -512,12 +521,12 @@ void AppIdSession::examine_ssl_metadata(AppidChangeBits& change_bits)
         tsession->set_tls_org_unit(nullptr, 0);
     }
     if (tsession->get_tls_handshake_done() and
-        payload.get_id() == APP_ID_NONE)
+        api.payload.get_id() == APP_ID_NONE)
     {
         if (appidDebug->is_active())
             LogMessage("AppIdDbg %s End of SSL/TLS handshake detected with no payloadAppId, "
                 "so setting to unknown\n", appidDebug->get_debug_session());
-        payload.set_id(APP_ID_UNKNOWN);
+        api.payload.set_id(APP_ID_UNKNOWN);
     }
 }
 
@@ -547,7 +556,7 @@ void AppIdSession::examine_rtmp_metadata(AppidChangeBits& change_bits)
             // do not overwrite a previously-set client or service
             if (hsession->client.get_id() <= APP_ID_NONE)
                 hsession->set_client(client_id, change_bits, "URL");
-            if (service.get_id() <= APP_ID_NONE)
+            if (api.service.get_id() <= APP_ID_NONE)
                 set_service_appid_data(service_id, change_bits);
 
             // DO overwrite a previously-set payload
@@ -562,16 +571,16 @@ void AppIdSession::set_client_appid_data(AppId id, AppidChangeBits& change_bits,
     if (id <= APP_ID_NONE || id == APP_ID_HTTP)
         return;
 
-    AppId cur_id = client.get_id();
+    AppId cur_id = api.client.get_id();
     if (id != cur_id)
     {
         if (cur_id)
             if (ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(cur_id) >
                 ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(id))
                 return;
-        client.set_id(id);
+        api.client.set_id(id);
     }
-    client.set_version(version, change_bits);
+    api.client.set_version(version, change_bits);
 }
 
 void AppIdSession::set_payload_appid_data(AppId id, AppidChangeBits& change_bits, char* version)
@@ -579,11 +588,11 @@ void AppIdSession::set_payload_appid_data(AppId id, AppidChangeBits& change_bits
     if (id <= APP_ID_NONE)
         return;
 
-    if (ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(payload.get_id()) >
+    if (ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(api.payload.get_id()) >
         ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(id))
         return;
-    payload.set_id(id);
-    payload.set_version(version, change_bits);
+    api.payload.set_id(id);
+    api.payload.set_version(version, change_bits);
 }
 
 void AppIdSession::set_service_appid_data(AppId id, AppidChangeBits& change_bits, char* version)
@@ -599,7 +608,7 @@ void AppIdSession::set_service_appid_data(AppId id, AppidChangeBits& change_bits
         return;
     }
 
-    service.update(id, change_bits, version);
+    api.service.update(id, change_bits, version);
 }
 
 bool AppIdSession::is_svc_taking_too_much_time() const
@@ -609,11 +618,12 @@ bool AppIdSession::is_svc_taking_too_much_time() const
         init_bytes_without_reply > ctxt.get_odp_ctxt().max_bytes_before_service_fail));
 }
 
-void AppIdSession::delete_session_data()
+void AppIdSession::delete_session_data(bool free_api)
 {
-    service.reset();
-    client.reset();
-    payload.reset();
+    api.service.reset();
+    api.client.reset();
+    api.payload.reset();
+
     snort_free(netbios_name);
     snort_free(netbios_domain);
 
@@ -628,10 +638,12 @@ void AppIdSession::delete_session_data()
         rna_ss = subtype;
     }
 
-    delete_all_http_sessions();
     if (tsession)
         delete tsession;
-    delete dsession;
+
+    // delete api data only when appid session is getting reset
+    if (free_api)
+        api.delete_session_data();
 }
 
 int AppIdSession::add_flow_data(void* data, unsigned id, AppIdFreeFCN fcn)
@@ -724,9 +736,9 @@ void AppIdSession::stop_service_inspection(Packet* p, AppidSessionDirection dire
 
     service_disco_state = APPID_DISCO_STATE_FINISHED;
 
-    if (payload.get_id() == APP_ID_NONE and
+    if (api.payload.get_id() == APP_ID_NONE and
         (is_tp_appid_available() or get_session_flags(APPID_SESSION_NO_TPI)))
-        payload.set_id(APP_ID_UNKNOWN);
+        api.payload.set_id(APP_ID_UNKNOWN);
 
     set_session_flags(APPID_SESSION_SERVICE_DETECTED);
     clear_session_flags(APPID_SESSION_CONTINUE);
@@ -736,35 +748,48 @@ AppId AppIdSession::pick_service_app_id() const
 {
     AppId rval = APP_ID_NONE;
 
-    if (is_service_detected())
+    if (!ctxt.get_tp_appid_ctxt())
     {
-        bool deferred = service.get_deferred() || tp_app_id_deferred;
-
-        if (service.get_id() > APP_ID_NONE && !deferred)
-            return service.get_id();
-        if (is_tp_appid_available())
+        if (is_service_detected())
         {
-            if (tp_app_id > APP_ID_NONE)
-                return tp_app_id;
-            else if (deferred)
-                return service.get_id();
+            if ((rval = api.service.get_id()) > APP_ID_NONE)
+                return rval;
             else
-                rval = APP_ID_UNKNOWN_UI;
+                rval = APP_ID_UNKNOWN;
         }
-        else
-            rval = tp_app_id;
     }
-    else if (tp_app_id > APP_ID_NONE)
-        return tp_app_id;
+    else
+    {
+        if (is_service_detected())
+        {
+            bool deferred = api.service.get_deferred() || tp_app_id_deferred;
+
+            if (api.service.get_id() > APP_ID_NONE && !deferred)
+                return api.service.get_id();
+            if (is_tp_appid_available())
+            {
+                if (tp_app_id > APP_ID_NONE)
+                    return tp_app_id;
+                else if (deferred)
+                    return api.service.get_id();
+                else
+                    rval = APP_ID_UNKNOWN;
+            }
+            else
+                rval = tp_app_id;
+        }
+        else if (tp_app_id > APP_ID_NONE)
+            return tp_app_id;
+    }
 
     if (client_inferred_service_id > APP_ID_NONE)
         return client_inferred_service_id;
 
-    if (service.get_port_service_id() > APP_ID_NONE)
-        return service.get_port_service_id();
+    if (api.service.get_port_service_id() > APP_ID_NONE)
+        return api.service.get_port_service_id();
 
     if (rval == APP_ID_NONE or
-        (rval == APP_ID_UNKNOWN_UI and encrypted.service_id > APP_ID_NONE))
+        (rval == APP_ID_UNKNOWN and encrypted.service_id > APP_ID_NONE))
         return encrypted.service_id;
 
     return rval;
@@ -772,15 +797,15 @@ AppId AppIdSession::pick_service_app_id() const
 
 AppId AppIdSession::pick_ss_misc_app_id() const
 {
-    if (service.get_id() == APP_ID_HTTP2)
+    if (api.service.get_id() == APP_ID_HTTP2)
         return APP_ID_NONE;
 
     if (misc_app_id > APP_ID_NONE)
         return misc_app_id;
 
     AppId tmp_id = APP_ID_NONE;
-    if (!hsessions.empty())
-        tmp_id = hsessions[0]->misc_app_id;
+    if (!api.hsessions.empty())
+        tmp_id = api.hsessions[0]->misc_app_id;
     if (tmp_id > APP_ID_NONE)
         return tmp_id;
 
@@ -789,37 +814,37 @@ AppId AppIdSession::pick_ss_misc_app_id() const
 
 AppId AppIdSession::pick_ss_client_app_id() const
 {
-    if (service.get_id() == APP_ID_HTTP2)
+    if (api.service.get_id() == APP_ID_HTTP2)
         return APP_ID_NONE;
 
     AppId tmp_id = APP_ID_NONE;
-    if (!hsessions.empty())
-        tmp_id = hsessions[0]->client.get_id();
+    if (!api.hsessions.empty())
+        tmp_id = api.hsessions[0]->client.get_id();
     if (tmp_id > APP_ID_NONE)
         return tmp_id;
 
-    if (client.get_id() > APP_ID_NONE)
-        return client.get_id();
+    if (api.client.get_id() > APP_ID_NONE)
+        return api.client.get_id();
 
     return encrypted.client_id;
 }
 
-AppId AppIdSession::pick_ss_payload_app_id() const
+AppId AppIdSession::pick_ss_payload_app_id(AppId service_id) const
 {
-    if (service.get_id() == APP_ID_HTTP2)
+    if (service_id == APP_ID_HTTP2)
         return APP_ID_NONE;
 
     if (tp_payload_app_id_deferred)
         return tp_payload_app_id;
 
     AppId tmp_id = APP_ID_NONE;
-    if (!hsessions.empty())
-        tmp_id = hsessions[0]->payload.get_id();
+    if (!api.hsessions.empty())
+        tmp_id = api.hsessions[0]->payload.get_id();
     if (tmp_id > APP_ID_NONE)
         return tmp_id;
 
-    if (payload.get_id() > APP_ID_NONE)
-        return payload.get_id();
+    if (api.payload.get_id() > APP_ID_NONE)
+        return api.payload.get_id();
 
     if (tp_payload_app_id > APP_ID_NONE)
         return tp_payload_app_id;
@@ -831,155 +856,49 @@ AppId AppIdSession::pick_ss_payload_app_id() const
     if (tmp_id == APP_ID_UNKNOWN)
         return tmp_id;
 
-    AppId service_id = pick_service_app_id();
-    if (payload.get_id() == APP_ID_UNKNOWN and
-        is_svc_http_type(service_id))
+    if (api.payload.get_id() == APP_ID_UNKNOWN and
+        appid_api.is_service_http_type(service_id))
         return APP_ID_UNKNOWN;
 
     return APP_ID_NONE;
 }
 
+AppId AppIdSession::pick_ss_payload_app_id() const
+{
+    AppId service_id = pick_service_app_id();
+
+    return pick_ss_payload_app_id(service_id);
+}
+
 AppId AppIdSession::pick_ss_referred_payload_app_id() const
 {
-    if (service.get_id() == APP_ID_HTTP2)
+    if (api.service.get_id() == APP_ID_HTTP2)
         return APP_ID_NONE;
 
     AppId tmp_id = APP_ID_NONE;
-    if (!hsessions.empty())
-        tmp_id = hsessions[0]->referred_payload_app_id;
+    if (!api.hsessions.empty())
+        tmp_id = api.hsessions[0]->referred_payload_app_id;
     if (tmp_id > APP_ID_NONE)
         return tmp_id;
 
     return encrypted.referred_id;
 }
 
-void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id,
-    AppId payload_id, AppId misc_id, AppidChangeBits& change_bits)
-{
-    if (application_ids[APP_PROTOID_SERVICE] != service_id)
-    {
-        application_ids[APP_PROTOID_SERVICE] = service_id;
-        change_bits.set(APPID_SERVICE_BIT);
-    }
-    if (application_ids[APP_PROTOID_CLIENT] != client_id)
-    {
-        application_ids[APP_PROTOID_CLIENT] = client_id;
-        change_bits.set(APPID_CLIENT_BIT);
-    }
-    if (application_ids[APP_PROTOID_PAYLOAD] != payload_id)
-    {
-        application_ids[APP_PROTOID_PAYLOAD] = payload_id;
-        change_bits.set(APPID_PAYLOAD_BIT);
-    }
-    if (application_ids[APP_PROTOID_MISC] != misc_id)
-    {
-        application_ids[APP_PROTOID_MISC] = misc_id;
-        change_bits.set(APPID_MISC_BIT);
-    }
-}
-
-void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits)
+void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id,
+    AppId misc_id, AppId referred_id, AppidChangeBits& change_bits)
 {
-    if (application_ids[APP_PROTOID_SERVICE] != service_id)
-    {
-        application_ids[APP_PROTOID_SERVICE] = service_id;
-        change_bits.set(APPID_SERVICE_BIT);
-    }
-}
-
-void AppIdSession::get_first_stream_app_ids(AppId& service_id, AppId& client_id,
-    AppId& payload_id, AppId& misc_id) const
-{
-    service_id = application_ids[APP_PROTOID_SERVICE];
-    if (service_id != APP_ID_HTTP2)
-    {
-        client_id  = application_ids[APP_PROTOID_CLIENT];
-        payload_id = application_ids[APP_PROTOID_PAYLOAD];
-        misc_id    = application_ids[APP_PROTOID_MISC];
-    }
-    else if (AppIdHttpSession* hsession = get_http_session(0))
-    {
-        client_id = hsession->client.get_id();
-        payload_id = hsession->payload.get_id();
-        misc_id = hsession->misc_app_id;
-    }
-    else
-    {
-        client_id = APP_ID_NONE;
-        payload_id = APP_ID_NONE;
-        misc_id = APP_ID_NONE;
-    }
+    api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits);
 }
 
-void AppIdSession::get_first_stream_app_ids(AppId& service_id, AppId& client_id,
-    AppId& payload_id) const
-{
-    service_id = application_ids[APP_PROTOID_SERVICE];
-    if (service_id != APP_ID_HTTP2)
-    {
-        client_id  = application_ids[APP_PROTOID_CLIENT];
-        payload_id = application_ids[APP_PROTOID_PAYLOAD];
-    }
-    else if (AppIdHttpSession* hsession = get_http_session(0))
-    {
-        client_id = hsession->client.get_id();
-        payload_id = hsession->payload.get_id();
-    }
-    else
-    {
-        client_id = APP_ID_NONE;
-        payload_id = APP_ID_NONE;
-    }
-}
-
-AppId AppIdSession::get_application_ids_service() const
-{
-    return application_ids[APP_PROTOID_SERVICE];
-}
-
-AppId AppIdSession::get_application_ids_client(uint32_t stream_index) const
-{
-    if (get_application_ids_service() == APP_ID_HTTP2)
-    {
-        if (stream_index >= get_hsessions_size())
-            return APP_ID_NONE;
-        else if (AppIdHttpSession* hsession = get_http_session(stream_index))
-            return hsession->client.get_id();
-    }
-    else if (stream_index == 0)
-        return application_ids[APP_PROTOID_CLIENT];
-
-    return APP_ID_NONE;
-}
-
-AppId AppIdSession::get_application_ids_payload(uint32_t stream_index) const
+void AppIdSession::set_ss_application_ids(AppId client_id, AppId payload_id,
+    AppidChangeBits& change_bits)
 {
-    if (get_application_ids_service() == APP_ID_HTTP2)
-    {
-        if (stream_index >= get_hsessions_size())
-            return APP_ID_NONE;
-        else if (AppIdHttpSession* hsession = get_http_session(stream_index))
-            return hsession->payload.get_id();
-    }
-    else if (stream_index == 0)
-        return application_ids[APP_PROTOID_PAYLOAD];
-
-    return APP_ID_NONE;
+    api.set_ss_application_ids(client_id, payload_id, change_bits);
 }
 
-AppId AppIdSession::get_application_ids_misc(uint32_t stream_index) const
+void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits)
 {
-    if (service.get_id() == APP_ID_HTTP2)
-    {
-        if (stream_index >= get_hsessions_size())
-            return APP_ID_NONE;
-        else if (AppIdHttpSession* hsession = get_http_session(stream_index))
-            return hsession->misc_app_id;
-    }
-    else if (stream_index == 0)
-        return application_ids[APP_PROTOID_MISC];
-
-    return APP_ID_NONE;
+    api.set_application_ids_service(service_id, change_bits);
 }
 
 bool AppIdSession::is_ssl_session_decrypted() const
@@ -987,23 +906,26 @@ bool AppIdSession::is_ssl_session_decrypted() const
     return get_session_flags(APPID_SESSION_DECRYPTED);
 }
 
-void AppIdSession::reset_session_data()
+void AppIdSession::reset_session_data(AppidChangeBits& change_bits)
 {
     delete_session_data();
     netbios_name = nullptr;
     netbios_domain = nullptr;
-    hsessions.clear();
+    api.hsessions.clear();
 
     tp_payload_app_id = APP_ID_UNKNOWN;
     tp_app_id = APP_ID_UNKNOWN;
 
     if (this->tpsession)
         this->tpsession->reset();
+
+    change_bits.reset();
+    change_bits.set(APPID_RESET_BIT);
 }
 
 bool AppIdSession::is_payload_appid_set() const
 {
-    return (payload.get_id() || tp_payload_app_id);
+    return (api.payload.get_id() || tp_payload_app_id);
 }
 
 void AppIdSession::clear_http_flags()
@@ -1018,47 +940,52 @@ void AppIdSession::clear_http_flags()
 
 void AppIdSession::clear_http_data()
 {
-    if (hsessions.empty())
+    if (api.hsessions.empty())
         return;
-    hsessions[0]->clear_all_fields();
-}
-
-AppIdHttpSession* AppIdSession::create_http_session(uint32_t stream_id)
-{
-    AppIdHttpSession* hsession = new AppIdHttpSession(*this, stream_id);
-    hsessions.push_back(hsession);
-    return hsession;
+    api.hsessions[0]->clear_all_fields();
 }
 
 AppIdHttpSession* AppIdSession::get_http_session(uint32_t stream_index) const
 {
-    if (stream_index < hsessions.size())
-        return hsessions[stream_index];
+    if (stream_index < api.hsessions.size())
+        return api.hsessions[stream_index];
     else
         return nullptr;
 }
 
+AppIdHttpSession* AppIdSession::create_http_session(uint32_t stream_id)
+{
+    AppIdHttpSession* hsession = new AppIdHttpSession(*this, stream_id);
+    api.hsessions.push_back(hsession);
+    return hsession;
+}
+
 AppIdHttpSession* AppIdSession::get_matching_http_session(uint32_t stream_id) const
 {
-    for (uint32_t stream_index=0; stream_index < hsessions.size(); stream_index++)
+    for (uint32_t stream_index=0; stream_index < api.hsessions.size(); stream_index++)
     {
-        if(stream_id == hsessions[stream_index]->get_http2_stream_id())
-            return hsessions[stream_index];
+        if(stream_id == api.hsessions[stream_index]->get_http2_stream_id())
+            return api.hsessions[stream_index];
     }
     return nullptr;
 }
 
+void AppIdSession::delete_all_http_sessions()
+{
+    api.delete_all_http_sessions();
+}
+
 AppIdDnsSession* AppIdSession::create_dns_session()
 {
-    if (dsession)
-        delete dsession;
-    dsession = new AppIdDnsSession();
-    return dsession;
+    if (api.dsession)
+        delete api.dsession;
+    api.dsession = new AppIdDnsSession();
+    return api.dsession;
 }
 
 AppIdDnsSession* AppIdSession::get_dns_session() const
 {
-    return dsession;
+    return api.dsession;
 }
 
 bool AppIdSession::is_tp_appid_done() const
@@ -1140,10 +1067,17 @@ void AppIdSession::set_tp_payload_app_id(Packet& p, AppidSessionDirection dir, A
 void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, Flow* flow,
     bool is_http2, uint32_t http2_stream_index)
 {
-    if (!api.get_published())
+    if (!api.stored_in_stash and change_bits.any())
+    {
+        assert(flow and flow->stash);
+        flow->stash->store(STASH_APPID_DATA, &api, false);
+        api.stored_in_stash = true;
+    }
+
+    if (!api.published)
     {
         change_bits.set(APPID_CREATED_BIT);
-        api.set_published(true);
+        api.published = true;
     }
 
     if (change_bits.none())
index 7d3833cd056675957b1313eeb49b3a7cbeb0d7bc..afd566c759226a5fafb19d8fa4d80b28dc51de9a 100644 (file)
@@ -250,7 +250,6 @@ public:
     AppIdContext& ctxt;
     std::unordered_map<unsigned, AppIdFlowData*> flow_data;
     uint64_t flags = 0;
-    snort::SfIp initiator_ip;
     uint16_t initiator_port = 0;
 
     uint16_t session_packet_count = 0;
@@ -268,13 +267,9 @@ public:
     ServiceDetector* service_detector = nullptr;
     AppIdServiceSubtype* subtype = nullptr;
     std::vector<ServiceDetector*> service_candidates;
-    ServiceAppDescriptor service;
 
-    // Following three fields are used only for non-http sessions. For HTTP traffic,
-    // these fields are maintained inside AppIdHttpSession.
-    // Note: RTMP traffic is treated like HTTP in AppId
-    ClientAppDescriptor client;
-    PayloadAppDescriptor payload;
+    // Following field is used only for non-http sessions. For HTTP traffic,
+    // this field is maintained inside AppIdHttpSession.
     AppId misc_app_id = APP_ID_NONE;
 
     // AppId matching client side
@@ -353,26 +348,14 @@ public:
     AppId pick_ss_misc_app_id() const;
     AppId pick_ss_client_app_id() const;
     AppId pick_ss_payload_app_id() const;
+    AppId pick_ss_payload_app_id(AppId service_id) const;
     AppId pick_ss_referred_payload_app_id() const;
 
     void set_ss_application_ids(AppId service, AppId client, AppId payload, AppId misc,
-        AppidChangeBits& change_bits);
+        AppId referred, AppidChangeBits& change_bits);
+    void set_ss_application_ids(AppId client, AppId payload, AppidChangeBits& change_bits);
     void set_application_ids_service(AppId service_id, AppidChangeBits& change_bits);
 
-    // For protocols such as HTTP2 which can have multiple streams within a single flow, get_first_stream_*
-    // methods return the appids in the first stream seen in a packet.
-    void get_first_stream_app_ids(AppId& service, AppId& client, AppId& payload, AppId& misc) const;
-    void get_first_stream_app_ids(AppId& service, AppId& client, AppId& payload) const;
-    AppId get_application_ids_service() const;
-    AppId get_application_ids_client(uint32_t stream_index = 0) const;
-    AppId get_application_ids_payload(uint32_t stream_index = 0) const;
-    AppId get_application_ids_misc(uint32_t stream_index = 0) const;
-
-    uint32_t get_hsessions_size() const
-    {
-        return hsessions.size();
-    }
-
     bool is_ssl_session_decrypted() const;
     void examine_ssl_metadata(AppidChangeBits& change_bits);
     void set_client_appid_data(AppId, AppidChangeBits& change_bits, char* version = nullptr);
@@ -389,17 +372,12 @@ public:
     bool is_payload_appid_set() const;
     void clear_http_flags();
     void clear_http_data();
-    void reset_session_data();
+    void reset_session_data(AppidChangeBits& change_bits);
 
-    AppIdHttpSession* create_http_session(uint32_t stream_id = 0);
     AppIdHttpSession* get_http_session(uint32_t stream_index = 0) const;
+    AppIdHttpSession* create_http_session(uint32_t stream_id = 0);
     AppIdHttpSession* get_matching_http_session(uint32_t stream_id) const;
-    void delete_all_http_sessions()
-    {
-        for (auto hsession : hsessions)
-            delete hsession;
-        hsessions.clear();
-    }
+    void delete_all_http_sessions();
 
     AppIdDnsSession* create_dns_session();
     AppIdDnsSession* get_dns_session() const;
@@ -475,17 +453,104 @@ public:
         return api;
     }
 
+    AppId get_service_id() const
+    {
+        return api.service.get_id();
+    }
+
+    void set_service_id(AppId id, OdpContext &ctxt)
+    {
+        api.service.set_id(id, ctxt);
+    }
+
+    AppId get_port_service_id() const
+    {
+        return api.service.get_port_service_id();
+    }
+
+    void set_port_service_id(AppId id)
+    {
+        api.service.set_port_service_id(id);
+    }
+
+    void set_service_version(const char* version, AppidChangeBits& change_bits)
+    {
+        api.service.set_version(version, change_bits);
+    }
+
+    void set_service_vendor(const char* vendor)
+    {
+        api.service.set_vendor(vendor);
+    }
+
+    AppId get_client_id() const
+    {
+        return api.client.get_id();
+    }
+
+    void set_client_id(AppId id)
+    {
+        api.client.set_id(id);
+    }
+
+    void set_client_id(const snort::Packet& p, AppidSessionDirection dir, AppId id, AppidChangeBits& change_bits)
+    {
+        api.client.set_id(p, *this, dir, id, change_bits);
+    }
+
+    void set_client_version(const char* version, AppidChangeBits& change_bits)
+    {
+        api.client.set_version(version, change_bits);
+    }
+
+    const char* get_client_user() const
+    {
+        return api.client.get_username();
+    }
+
+    AppId get_client_user_id() const
+    {
+        return api.client.get_user_id();
+    }
+
+    void set_client_user(AppId id, const char* username)
+    {
+        api.client.update_user(id, username);
+    }
+
+    AppId get_payload_id() const
+    {
+        return api.payload.get_id();
+    }
+
+    void set_payload_id(AppId id)
+    {
+        api.payload.set_id(id);
+    }
+
+    const snort::SfIp& get_initiator_ip() const
+    {
+        return api.initiator_ip;
+    }
+
+    void set_initiator_ip(const snort::SfIp& ip)
+    {
+        api.initiator_ip = ip;
+    }
+
+    void set_tls_host(const AppidChangeBits& change_bits)
+    {
+        if (tsession and change_bits[APPID_TLSHOST_BIT])
+            api.set_tls_host(tsession->get_tls_host());
+    }
+
 private:
-    std::vector<AppIdHttpSession*> hsessions;
-    AppIdDnsSession* dsession = nullptr;
     uint16_t prev_http2_raw_packet = 0;
 
     void reinit_session_data(AppidChangeBits& change_bits);
-    void delete_session_data();
+    void delete_session_data(bool free_api = true);
 
     static THREAD_LOCAL uint32_t appid_flow_data_id;
-    AppId application_ids[APP_PROTOID_MAX] =
-        { APP_ID_NONE, APP_ID_NONE, APP_ID_NONE, APP_ID_NONE };
     bool tp_app_id_deferred = false;
     bool tp_payload_app_id_deferred = false;
 
@@ -494,28 +559,8 @@ private:
     AppId tp_payload_app_id = APP_ID_NONE;
 
     uint16_t my_inferred_svcs_ver = 0;
-    snort::AppIdSessionApi api{*this};
+    snort::AppIdSessionApi& api;
     static uint16_t inferred_svcs_ver;
 };
 
-static inline bool is_svc_http_type(AppId serviceId)
-{
-    switch(serviceId)
-    {
-        case APP_ID_HTTP:
-        case APP_ID_HTTPS:
-        case APP_ID_FTPS:
-        case APP_ID_IMAPS:
-        case APP_ID_IRCS:
-        case APP_ID_LDAPS:
-        case APP_ID_NNTPS:
-        case APP_ID_POP3S:
-        case APP_ID_SMTPS:
-        case APP_ID_SSHELL:
-        case APP_ID_SSL:
-        case APP_ID_QUIC:
-            return true;
-    }
-    return false;
-}
 #endif
index 888d6cf9a62470064509c969a3ddb1a12f8fb177..121231da2882d6bee3ebaa3bb8a7aa79d160dd74 100644 (file)
@@ -35,49 +35,79 @@ using namespace snort;
 
 AppId AppIdSessionApi::get_service_app_id() const
 {
-    return asd.get_application_ids_service();
+    return application_ids[APP_PROTOID_SERVICE];
 }
 
 AppId AppIdSessionApi::get_misc_app_id(uint32_t stream_index) const
 {
-    return asd.get_application_ids_misc(stream_index);
+    if (get_service_app_id() == APP_ID_HTTP2)
+    {
+        if (stream_index >= get_hsessions_size())
+            return APP_ID_NONE;
+        else if (AppIdHttpSession* hsession = get_hsession(stream_index))
+            return hsession->misc_app_id;
+    }
+    else if (stream_index == 0)
+        return application_ids[APP_PROTOID_MISC];
+
+    return APP_ID_NONE;
 }
 
 AppId AppIdSessionApi::get_client_app_id(uint32_t stream_index) const
 {
-    return asd.get_application_ids_client(stream_index);
+    if (get_service_app_id() == APP_ID_HTTP2)
+    {
+        if (stream_index >= get_hsessions_size())
+            return APP_ID_NONE;
+        else if (AppIdHttpSession* hsession = get_hsession(stream_index))
+            return hsession->client.get_id();
+    }
+    else if (stream_index == 0)
+        return application_ids[APP_PROTOID_CLIENT];
+
+    return APP_ID_NONE;
 }
 
 AppId AppIdSessionApi::get_payload_app_id(uint32_t stream_index) const
 {
-    return asd.get_application_ids_payload(stream_index);
+    if (get_service_app_id() == APP_ID_HTTP2)
+    {
+        if (stream_index >= get_hsessions_size())
+            return APP_ID_NONE;
+        else if (AppIdHttpSession* hsession = get_hsession(stream_index))
+            return hsession->payload.get_id();
+    }
+    else if (stream_index == 0)
+        return application_ids[APP_PROTOID_PAYLOAD];
+
+    return APP_ID_NONE;
 }
 
 AppId AppIdSessionApi::get_referred_app_id(uint32_t stream_index) const
 {
-    if (asd.get_application_ids_service() == APP_ID_HTTP2)
+    if (get_service_app_id() == APP_ID_HTTP2)
     {
-        if ((stream_index != 0) and (stream_index >= asd.get_hsessions_size()))
+        if ((stream_index != 0) and (stream_index >= get_hsessions_size()))
             return APP_ID_UNKNOWN;
-        else if (AppIdHttpSession* hsession = asd.get_http_session(stream_index))
+        else if (AppIdHttpSession* hsession = get_hsession(stream_index))
             return hsession->referred_payload_app_id;
     }
     else if (stream_index == 0)
-        return asd.pick_ss_referred_payload_app_id();
+        return application_ids[APP_PROTOID_REFERRED];
 
-    return APP_ID_UNKNOWN;
+    return APP_ID_NONE;
 }
 
 void AppIdSessionApi::get_app_id(AppId& service, AppId& client,
     AppId& payload, AppId& misc, AppId& referred, uint32_t stream_index) const
 {
-    if (asd.get_application_ids_service() == APP_ID_HTTP2)
+    if (get_service_app_id() == APP_ID_HTTP2)
     {
-        if ((stream_index != 0) and (stream_index >= asd.get_hsessions_size()))
+        if ((stream_index != 0) and (stream_index >= get_hsessions_size()))
             service = client = payload = misc = referred = APP_ID_UNKNOWN;
-        else if (AppIdHttpSession* hsession = asd.get_http_session(stream_index))
+        else if (AppIdHttpSession* hsession = get_hsession(stream_index))
         {
-            service = asd.get_application_ids_service();
+            service = get_service_app_id();
             client = hsession->client.get_id();
             payload = hsession->payload.get_id();
             misc = hsession->misc_app_id;
@@ -86,17 +116,17 @@ void AppIdSessionApi::get_app_id(AppId& service, AppId& client,
     }
     else
     {
-        asd.get_first_stream_app_ids(service, client, payload, misc);
-        referred = asd.pick_ss_referred_payload_app_id();
+        get_first_stream_app_ids(service, client, payload, misc);
+        referred = get_referred_app_id();
     }
 }
 
 void AppIdSessionApi::get_app_id(AppId* service, AppId* client,
     AppId* payload, AppId* misc, AppId* referred, uint32_t stream_index) const
 {
-    if (asd.get_application_ids_service() == APP_ID_HTTP2)
+    if (get_service_app_id() == APP_ID_HTTP2)
     {
-        if ((stream_index != 0) and (stream_index >= asd.get_hsessions_size()))
+        if ((stream_index != 0) and (stream_index >= get_hsessions_size()))
         {
             if (service)
                 *service = APP_ID_UNKNOWN;
@@ -110,10 +140,10 @@ void AppIdSessionApi::get_app_id(AppId* service, AppId* client,
                 *referred = APP_ID_UNKNOWN;
             return;
         }
-        else if (AppIdHttpSession* hsession = asd.get_http_session(stream_index))
+        else if (AppIdHttpSession* hsession = get_hsession(stream_index))
         {
             if (service)
-                *service = asd.get_application_ids_service();
+                *service = get_service_app_id();
             if (client)
                 *client = hsession->client.get_id();
             if (payload)
@@ -126,44 +156,47 @@ void AppIdSessionApi::get_app_id(AppId* service, AppId* client,
         }
     }
     if (service)
-        *service = asd.get_application_ids_service();
+        *service = get_service_app_id();
     if (client)
-        *client = asd.get_application_ids_client();
+        *client = get_client_app_id();
     if (payload)
-        *payload = asd.get_application_ids_payload();
+        *payload = get_payload_app_id();
     if (misc)
-        *misc = asd.get_application_ids_misc();
+        *misc = get_misc_app_id();
     if (referred)
-        *referred = asd.pick_ss_referred_payload_app_id();
+        *referred = get_referred_app_id();
 }
 
 bool AppIdSessionApi::is_appid_inspecting_session() const
 {
-    if ( asd.service_disco_state != APPID_DISCO_STATE_FINISHED or
-        !asd.is_tp_appid_done() or
-        asd.get_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_CONTINUE) or
-        (asd.get_session_flags(APPID_SESSION_ENCRYPTED) and
-            (asd.get_session_flags(APPID_SESSION_DECRYPTED) or
-            asd.session_packet_count < SSL_WHITELIST_PKT_LIMIT)) )
+    if (!asd)
+        return false;
+
+    if ( asd->service_disco_state != APPID_DISCO_STATE_FINISHED or
+        !asd->is_tp_appid_done() or
+        asd->get_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_CONTINUE) or
+        (asd->get_session_flags(APPID_SESSION_ENCRYPTED) and
+            (asd->get_session_flags(APPID_SESSION_DECRYPTED) or
+            asd->session_packet_count < SSL_WHITELIST_PKT_LIMIT)) )
     {
         return true;
     }
 
-    if ( asd.client_disco_state != APPID_DISCO_STATE_FINISHED and
-        (!asd.is_client_detected() or
-            (asd.service_disco_state != APPID_DISCO_STATE_STATEFUL
-                and asd.get_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))) )
+    if ( asd->client_disco_state != APPID_DISCO_STATE_FINISHED and
+        (!asd->is_client_detected() or
+            (asd->service_disco_state != APPID_DISCO_STATE_STATEFUL
+                and asd->get_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))) )
     {
         return true;
     }
 
-    if ( asd.get_tp_app_id() == APP_ID_SSH and asd.payload.get_id() != APP_ID_SFTP and
-        asd.session_packet_count < MAX_SFTP_PACKET_COUNT )
+    if ( get_service_app_id() == APP_ID_SSH and get_payload_app_id() != APP_ID_SFTP and
+        asd->session_packet_count < MAX_SFTP_PACKET_COUNT )
     {
         return true;
     }
 
-    if (asd.ctxt.get_odp_ctxt().check_host_port_app_cache)
+    if (asd->ctxt.get_odp_ctxt().check_host_port_app_cache)
         return true;
 
     return false;
@@ -171,57 +204,171 @@ bool AppIdSessionApi::is_appid_inspecting_session() const
 
 bool AppIdSessionApi::is_appid_available() const
 {
-    return ( (asd.service.get_id() != APP_ID_NONE ||
-        asd.payload.get_id() != APP_ID_NONE) &&
-        (asd.is_tp_appid_available() ||
-        asd.get_session_flags(APPID_SESSION_NO_TPI)) );
+    if (!asd)
+        return false;
+
+    return ( (service.get_id() != APP_ID_NONE ||
+        payload.get_id() != APP_ID_NONE) &&
+        (asd->is_tp_appid_available() ||
+        asd->get_session_flags(APPID_SESSION_NO_TPI)) );
 }
 
 const char* AppIdSessionApi::get_client_version(uint32_t stream_index) const
 {
-    if (uint32_t num_hsessions = asd.get_hsessions_size())
+    if (uint32_t num_hsessions = get_hsessions_size())
     {
         if (stream_index >= num_hsessions)
             return nullptr;
-        else if (AppIdHttpSession* hsession = asd.get_http_session(stream_index))
+        else if (AppIdHttpSession* hsession = get_hsession(stream_index))
             return hsession->client.get_version();
     }
     else if (stream_index == 0)
-        return asd.client.get_version();
+        return client.get_version();
 
     return nullptr;
 }
 
 uint64_t AppIdSessionApi::get_appid_session_attribute(uint64_t flags) const
 {
-    return asd.get_session_flags(flags);
+    if (!asd)
+        return 0;
+
+    return asd->get_session_flags(flags);
 }
 
 const char* AppIdSessionApi::get_tls_host() const
 {
-    if (asd.tsession)
-        return asd.tsession->get_tls_host();
-    return nullptr;
+    return tls_host;
 }
 
 const SfIp* AppIdSessionApi::get_initiator_ip() const
 {
-    return &asd.initiator_ip;
+    return &initiator_ip;
 }
 
 const AppIdDnsSession* AppIdSessionApi::get_dns_session() const
 {
-    return asd.get_dns_session();
+    return dsession;
+}
+
+bool AppIdSessionApi::is_http_inspection_done() const
+{
+    if (!asd)
+        return true;
+
+    return (asd->is_tp_appid_done() and
+        !(asd->get_session_flags(APPID_SESSION_SSL_SESSION) and !get_tls_host() and
+            (asd->service_disco_state!= APPID_DISCO_STATE_FINISHED)));
+}
+
+void AppIdSessionApi::set_ss_application_ids(AppId service_id, AppId client_id,
+    AppId payload_id, AppId misc_id, AppId referred_id, AppidChangeBits& change_bits)
+{
+    if (application_ids[APP_PROTOID_SERVICE] != service_id)
+    {
+        application_ids[APP_PROTOID_SERVICE] = service_id;
+        change_bits.set(APPID_SERVICE_BIT);
+    }
+    if (application_ids[APP_PROTOID_CLIENT] != client_id)
+    {
+        application_ids[APP_PROTOID_CLIENT] = client_id;
+        change_bits.set(APPID_CLIENT_BIT);
+    }
+    if (application_ids[APP_PROTOID_PAYLOAD] != payload_id)
+    {
+        application_ids[APP_PROTOID_PAYLOAD] = payload_id;
+        change_bits.set(APPID_PAYLOAD_BIT);
+    }
+    if (application_ids[APP_PROTOID_MISC] != misc_id)
+    {
+        application_ids[APP_PROTOID_MISC] = misc_id;
+        change_bits.set(APPID_MISC_BIT);
+    }
+    if (application_ids[APP_PROTOID_REFERRED] != referred_id)
+    {
+        application_ids[APP_PROTOID_REFERRED] = referred_id;
+        change_bits.set(APPID_REFERRED_BIT);
+    }
+}
+
+void AppIdSessionApi::set_ss_application_ids(AppId client_id, AppId payload_id,
+    AppidChangeBits& change_bits)
+{
+    if (application_ids[APP_PROTOID_CLIENT] != client_id)
+    {
+        application_ids[APP_PROTOID_CLIENT] = client_id;
+        change_bits.set(APPID_CLIENT_BIT);
+    }
+    if (application_ids[APP_PROTOID_PAYLOAD] != payload_id)
+    {
+        application_ids[APP_PROTOID_PAYLOAD] = payload_id;
+        change_bits.set(APPID_PAYLOAD_BIT);
+    }
+}
+
+void AppIdSessionApi::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits)
+{
+    if (application_ids[APP_PROTOID_SERVICE] != service_id)
+    {
+        application_ids[APP_PROTOID_SERVICE] = service_id;
+        change_bits.set(APPID_SERVICE_BIT);
+    }
+}
+
+void AppIdSessionApi::get_first_stream_app_ids(AppId& service_id, AppId& client_id,
+    AppId& payload_id, AppId& misc_id) const
+{
+    service_id = application_ids[APP_PROTOID_SERVICE];
+    if (service_id != APP_ID_HTTP2)
+    {
+        client_id  = application_ids[APP_PROTOID_CLIENT];
+        payload_id = application_ids[APP_PROTOID_PAYLOAD];
+        misc_id    = application_ids[APP_PROTOID_MISC];
+    }
+    else if (AppIdHttpSession* hsession = get_hsession(0))
+    {
+        client_id = hsession->client.get_id();
+        payload_id = hsession->payload.get_id();
+        misc_id = hsession->misc_app_id;
+    }
+    else
+    {
+        client_id = APP_ID_NONE;
+        payload_id = APP_ID_NONE;
+        misc_id = APP_ID_NONE;
+    }
+}
+
+void AppIdSessionApi::get_first_stream_app_ids(AppId& service_id, AppId& client_id,
+    AppId& payload_id) const
+{
+    service_id = application_ids[APP_PROTOID_SERVICE];
+    if (service_id != APP_ID_HTTP2)
+    {
+        client_id  = application_ids[APP_PROTOID_CLIENT];
+        payload_id = application_ids[APP_PROTOID_PAYLOAD];
+    }
+    else if (AppIdHttpSession* hsession = get_hsession(0))
+    {
+        client_id = hsession->client.get_id();
+        payload_id = hsession->payload.get_id();
+    }
+    else
+    {
+        client_id = APP_ID_NONE;
+        payload_id = APP_ID_NONE;
+    }
 }
 
 const AppIdHttpSession* AppIdSessionApi::get_http_session(uint32_t stream_index) const
 {
-    return asd.get_http_session(stream_index);
+    return get_hsession(stream_index);
 }
 
-bool AppIdSessionApi::is_http_inspection_done() const
+AppIdHttpSession* AppIdSessionApi::get_hsession(uint32_t stream_index) const
 {
-    return (asd.is_tp_appid_done() and
-        !(asd.get_session_flags(APPID_SESSION_SSL_SESSION) and !get_tls_host() and
-            (asd.service_disco_state!= APPID_DISCO_STATE_FINISHED)));
+    if (stream_index < hsessions.size())
+        return hsessions[stream_index];
+    else
+        return nullptr;
 }
index f540b0464cc887755cf2700dc7024ba0b3a8afb8..d5b0e0b3cb5e5db48fef944a04d9870e9034a1a4 100644 (file)
 #define APPID_SESSION_API_H
 
 #include "flow/flow.h"
+#include "flow/stash_item.h"
 #include "main/snort_types.h"
+#include "pub_sub/appid_events.h"
 #include "sfip/sf_ip.h"
+#include "utils/util.h"
+#include "appid_dns_session.h"
+#include "appid_http_session.h"
 #include "application_ids.h"
 
 class AppIdDnsSession;
-class AppIdHttpSession;
 class AppIdSession;
 
 namespace snort
@@ -97,10 +101,9 @@ namespace snort
     APPID_SESSION_PORT_SERVICE_DONE)
 const uint64_t APPID_SESSION_ALL_FLAGS = 0xFFFFFFFFFFFFFFFFULL;
 
-class SO_PUBLIC AppIdSessionApi
+class SO_PUBLIC AppIdSessionApi : public StashGenericObject
 {
 public:
-    AppIdSessionApi(const AppIdSession& asd) : asd(asd) {}
     AppId get_service_app_id() const;
     AppId get_misc_app_id(uint32_t stream_index = 0) const;
     AppId get_client_app_id(uint32_t stream_index = 0) const;
@@ -118,15 +121,72 @@ public:
     const char* get_tls_host() const;
     bool is_http_inspection_done() const;
 
-    bool get_published() const
-    { return published; }
+    // For protocols such as HTTP2 which can have multiple streams within a single flow, get_first_stream_*
+    // methods return the appids in the first stream seen in a packet.
+    void get_first_stream_app_ids(AppId& service, AppId& client, AppId& payload, AppId& misc) const;
+    void get_first_stream_app_ids(AppId& service, AppId& client, AppId& payload) const;
 
-    void set_published(bool val)
-    { published = val; }
+    ~AppIdSessionApi()
+    {
+        delete_session_data();
+    }
+
+    uint32_t get_hsessions_size() const
+    {
+        return hsessions.size();
+    }
+
+protected:
+    AppIdSessionApi(const AppIdSession* asd, const SfIp& ip) :
+        StashGenericObject(STASH_GENERIC_OBJECT_APPID), asd(asd), initiator_ip(ip) {}
 
 private:
-    const AppIdSession& asd;
+    const AppIdSession* asd = nullptr;
+    AppId application_ids[APP_PROTOID_MAX] =
+        { APP_ID_NONE, APP_ID_NONE, APP_ID_NONE, APP_ID_NONE, APP_ID_NONE };
     bool published = false;
+    bool stored_in_stash = false;
+    std::vector<AppIdHttpSession*> hsessions;
+    AppIdDnsSession* dsession = nullptr;
+    snort::SfIp initiator_ip;
+    ServiceAppDescriptor service;
+    char* tls_host = nullptr;
+
+    // Following two fields are used only for non-http sessions. For HTTP traffic,
+    // these fields are maintained inside AppIdHttpSession.
+    // Note: RTMP traffic is treated like HTTP in AppId
+    ClientAppDescriptor client;
+    PayloadAppDescriptor payload;
+
+    void set_ss_application_ids(AppId service, AppId client, AppId payload, AppId misc,
+        AppId referred, AppidChangeBits& change_bits);
+    void set_ss_application_ids(AppId client, AppId payload, AppidChangeBits& change_bits);
+    void set_application_ids_service(AppId service_id, AppidChangeBits& change_bits);
+
+    AppIdHttpSession* get_hsession(uint32_t stream_index = 0) const;
+
+    void delete_session_data()
+    {
+        delete_all_http_sessions();
+        snort_free(tls_host);
+        delete dsession;
+    }
+
+    void delete_all_http_sessions()
+    {
+        for (auto hsession : hsessions)
+            delete hsession;
+        hsessions.clear();
+    }
+
+    void set_tls_host(const char* host)
+    {
+        if (tls_host)
+            snort_free(tls_host);
+        tls_host = snort_strdup(host);
+    }
+
+    friend AppIdSession;
 };
 
 }
index 5d3bdbd2257def29873829a0a4eedeb165948487..6241053b556ec997854714deebf3c1ddba7cba80 100644 (file)
@@ -217,7 +217,7 @@ static void update_stats(const AppIdSession& asd, AppId app_id, StatsBucket* buc
             else
                 record->app_name = snort_strdup(entry->app_name);
         }
-        else if ( app_id == APP_ID_UNKNOWN || app_id == APP_ID_UNKNOWN_UI )
+        else if ( app_id == APP_ID_UNKNOWN )
             record->app_name = snort_strdup("__unknown");
         else if ( app_id == APP_ID_NONE )
             record->app_name = snort_strdup("__none");
@@ -273,7 +273,7 @@ void AppIdStatistics::update(const AppIdSession& asd)
     bucket->totalStats.rxByteCnt += asd.stats.responder_bytes;
 
     AppId web_app_id, service_id, client_id;
-    asd.get_first_stream_app_ids(service_id, client_id, web_app_id);
+    asd.get_api().get_first_stream_app_ids(service_id, client_id, web_app_id);
 
     if ( web_app_id > APP_ID_NONE )
         update_stats(asd, web_app_id, bucket);
index 2e80f56dd498379b420801d55721535419f98075..fedca093b67415b8d71ae4bd7228dbb7bc0c6d55 100644 (file)
@@ -30,6 +30,7 @@ enum AppProtoIdIndex
     APP_PROTOID_CLIENT,
     APP_PROTOID_PAYLOAD,
     APP_PROTOID_MISC,
+    APP_PROTOID_REFERRED,
     APP_PROTOID_MAX
 };
 
@@ -1004,7 +1005,7 @@ enum ApplicationIds : AppId
     APP_ID_LYCOS                          = 2775,
     APP_ID_DOGPILE                        = 2804,
     APP_ID_SPDY                           = 2886,
-    APP_ID_HTTP2                          = 2889,   // only used for bookkeeping -- treat as HTTP
+    APP_ID_HTTP2                          = 2889,
     APP_ID_ANYCONNECT                     = 2921,
     APP_ID_ANYCONNECT_SSL_CLIENT          = 2922,
     APP_ID_ANYCONNECT_IPSEC_CLIENT        = 2923,
@@ -1015,13 +1016,14 @@ enum ApplicationIds : AppId
     APP_ID_FTP_PASSIVE                    = 4003,
     APP_ID_QUIC                           = 4023,
     APP_ID_PSIPHON                        = 4075,
-    APP_ID_DNS_OVER_TLS                   = 4615,
 #ifdef REG_TEST
+    APP_ID_DNS_OVER_TLS                   = 4615,
     APP_ID_REGTEST                        = 10000,
     APP_ID_REGTEST1                       = 10001,
-    APP_ID_REGTEST2                       = 10002,
+    APP_ID_REGTEST2                       = 10002
+#else
+    APP_ID_DNS_OVER_TLS                   = 4615
 #endif
-    APP_ID_UNKNOWN_UI                     = 65535   // UI renders this value as 'Unknown'
 };
 
 enum AppIdType
index c7a2ee66543020ee4a97156454d955bb261af40a..db345b8f2aea5faff85db872d12671b7768ecd4a 100644 (file)
@@ -384,7 +384,7 @@ bool ClientDiscovery::do_client_discovery(AppIdSession& asd, Packet* p,
     }
 
     if ( !was_service && asd.is_service_detected() )
-        asd.sync_with_snort_protocol_id(asd.service.get_id(), p);
+        asd.sync_with_snort_protocol_id(asd.get_service_id(), p);
 
     return isTpAppidDiscoveryDone;
 }
index 56960e38d7141b53786d9348c9c008f769983661..63433e415740f2ff32012fff0943c002c5689984 100644 (file)
@@ -188,9 +188,9 @@ void SipServiceDetector::createRtpFlow(AppIdSession& asd, const Packet* pkt, con
 
     if ( fp )
     {
-        fp->client.set_id(asd.client.get_id());
-        fp->payload.set_id(asd.payload.get_id());
-        fp->service.set_id(APP_ID_RTP, asd.ctxt.get_odp_ctxt());
+        fp->set_client_id(asd.get_client_id());
+        fp->set_payload_id(asd.get_payload_id());
+        fp->set_service_id(APP_ID_RTP, asd.ctxt.get_odp_ctxt());
 
         // FIXIT-M : snort 2.9.x updated the flag to APPID_SESSION_EXPECTED_EVALUATE.
         // Check if it is needed here as well.
@@ -207,9 +207,9 @@ void SipServiceDetector::createRtpFlow(AppIdSession& asd, const Packet* pkt, con
 
     if ( fp2 )
     {
-        fp2->client.set_id(asd.client.get_id());
-        fp2->payload.set_id(asd.payload.get_id());
-        fp2->service.set_id(APP_ID_RTCP, asd.ctxt.get_odp_ctxt());
+        fp2->set_client_id(asd.get_client_id());
+        fp2->set_payload_id(asd.get_payload_id());
+        fp2->set_service_id(APP_ID_RTCP, asd.ctxt.get_odp_ctxt());
 
         // FIXIT-M : same comment as above
         // asd.initialize_future_session(*fp2, APPID_SESSION_EXPECTED_EVALUATE, APP_ID_APPID_SESSION_DIRECTION_MAX);
index a0e8cb152b4b36d0aa4986ccd059c6966a1fd21e..a7f1c26897250a53c82e3942b8a8546af564499f 100644 (file)
@@ -149,8 +149,9 @@ const TraceOption* AppIdModule::get_trace_options() const { return nullptr; }
 unsigned AppIdSession::inspector_id = 0;
 AppIdConfig stub_config;
 AppIdContext stub_ctxt(stub_config);
-AppIdSession::AppIdSession(IpProtocol, const SfIp*, uint16_t, AppIdInspector& inspector)
-    : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), ctxt(stub_ctxt) { }
+AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector)
+    : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), ctxt(stub_ctxt),
+        api(*(new AppIdSessionApi(this, *ip)))  { }
 AppIdSession::~AppIdSession() = default;
 AppIdHttpSession::AppIdHttpSession(AppIdSession& asd, uint32_t http2_stream_id)
   : asd(asd), http2_stream_id(http2_stream_id)
index 1705c02d45522333e5b0468e788e66d228149467..79e2d952ec1d60c34afe4d55b2bd8b131d24001a 100644 (file)
 
 static HttpPatternMatchers* hm = nullptr;
 static Packet pkt;
-static const SfIp* sfip = nullptr;
+static SfIp sfip;
 static AppIdModule appid_mod;
 static AppIdInspector appid_inspector(appid_mod);
-static AppIdSession session(IpProtocol::IP, sfip, 0, appid_inspector);
+static AppIdSession session(IpProtocol::IP, &sfip, 0, appid_inspector);
 static AppIdHttpSession mock_hsession(session, 0);
 static ChpMatchDescriptor cmd_test;
 static MatchedCHPAction mchp;
@@ -79,7 +79,6 @@ TEST_GROUP(http_url_patterns_tests)
     void teardown() override
     {
         delete hm;
-        delete sfip;
     }
 };
 
index 9f5606384a49d68e17332ab8bc16774a0ea0d17d..58f5c9d64b95862c329b26acde1a80cd4e37493c 100644 (file)
@@ -123,13 +123,13 @@ IpsOption::EvalStatus AppIdIpsOption::eval(Cursor&, Packet* p)
         return NO_MATCH;
 
     AppId app_ids[APP_PROTOID_MAX];
-    AppId service_id = session->get_application_ids_service();
+    AppId service_id = session->get_api().get_service_app_id();
     OdpContext& odp_ctxt = session->ctxt.get_odp_ctxt();
 
     if (service_id != APP_ID_HTTP2)
     {
         // id order on stream api call is: service, client, payload, misc
-        session->get_first_stream_app_ids(app_ids[APP_PROTOID_SERVICE], app_ids[APP_PROTOID_CLIENT],
+        session->get_api().get_first_stream_app_ids(app_ids[APP_PROTOID_SERVICE], app_ids[APP_PROTOID_CLIENT],
             app_ids[APP_PROTOID_PAYLOAD], app_ids[APP_PROTOID_MISC]);
 
         for ( unsigned i = 0; i < APP_PROTOID_MAX; i++ )
@@ -141,9 +141,9 @@ IpsOption::EvalStatus AppIdIpsOption::eval(Cursor&, Packet* p)
         if (match_id_against_rule(odp_ctxt, service_id))
             return MATCH;
 
-        for (uint32_t i = 0; i < session->get_hsessions_size(); i++)
+        for (uint32_t i = 0; i < session->get_api().get_hsessions_size(); i++)
         {
-            AppIdHttpSession* hsession = session->get_http_session(i);
+            const AppIdHttpSession* hsession = session->get_http_session(i);
             if (!hsession)
                 return NO_MATCH;
             if (match_id_against_rule(odp_ctxt, hsession->client.get_id()))
index 15cc07cb2fcff52cdc9a0ec6a1702b38bf9e2e40..0f9d0c4a7fc296a4bd2e7fbfb60b13a53123f4cb 100644 (file)
@@ -338,7 +338,7 @@ static int service_analyze_payload(lua_State* L)
     // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
-    lsd->ldp.asd->payload.set_id(lua_tonumber(L, 2));
+    lsd->ldp.asd->set_payload_id(lua_tonumber(L, 2));
     return 0;
 }
 
@@ -2459,9 +2459,9 @@ static int create_future_flow(lua_State* L)
         client_port, &server_addr, server_port, proto, snort_protocol_id);
     if (fp)
     {
-        fp->service.set_id(service_id, ud->get_odp_ctxt());
-        fp->client.set_id(client_id);
-        fp->payload.set_id(payload_id);
+        fp->set_service_id(service_id, ud->get_odp_ctxt());
+        fp->set_client_id(client_id);
+        fp->set_payload_id(payload_id);
         fp->set_session_flags(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_NOT_A_SERVICE |
             APPID_SESSION_PORT_SERVICE_DONE);
         fp->service_disco_state = APPID_DISCO_STATE_FINISHED;
@@ -2505,7 +2505,7 @@ static int is_http_tunnel(lua_State* L)
     if (!lua_checkstack(L, 1))
         return 0;
 
-    AppIdHttpSession* hsession = lsd->ldp.asd->get_http_session();
+    const AppIdHttpSession* hsession = lsd->ldp.asd->get_http_session();
 
     if (hsession)
     {
@@ -2537,7 +2537,7 @@ static int get_http_tunneled_ip(lua_State* L)
     if (!lua_checkstack(L, 1))
         return 0;
 
-    AppIdHttpSession* hsession = lsd->ldp.asd->get_http_session();
+    const AppIdHttpSession* hsession = lsd->ldp.asd->get_http_session();
     if (hsession)
     {
         const TunnelDest* tunnel_dest = hsession->get_tun_dest();
@@ -2569,7 +2569,7 @@ static int get_http_tunneled_port(lua_State* L)
     if (!lua_checkstack(L, 1))
         return 0;
 
-    AppIdHttpSession* hsession = lsd->ldp.asd->get_http_session();
+    const AppIdHttpSession* hsession = lsd->ldp.asd->get_http_session();
     if (hsession)
     {
         const TunnelDest* tunnel_dest = hsession->get_tun_dest();
index 20837389fda4ccb7a4513adffc36a5bbb0c49762..fd318b3ed43edd4cef7059f965354dccf8f9f320 100644 (file)
@@ -87,10 +87,10 @@ int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, A
     const SfIp* ip = nullptr;
 
     asd.service_detector = this;
-    asd.service.set_vendor(vendor);
-    asd.service.set_version(version, change_bits);
+    asd.set_service_vendor(vendor);
+    asd.set_service_version(version, change_bits);
     asd.set_service_detected();
-    asd.service.set_id(appId, asd.ctxt.get_odp_ctxt());
+    asd.set_service_id(appId, asd.ctxt.get_odp_ctxt());
 
     if (asd.get_session_flags(APPID_SESSION_IGNORE_HOST))
         return APPID_SUCCESS;
index 0d0b3425bead1c9b2aecd298626d12f5f32c11d2..7d331e5dff0e81648b8e8e02e0b74fbea5824ef8 100644 (file)
@@ -579,9 +579,9 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p,
                 asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED);
                 asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
 
-                if (asd.payload.get_id() == APP_ID_NONE and
+                if (asd.get_payload_id() == APP_ID_NONE and
                     (asd.is_tp_appid_available() or asd.get_session_flags(APPID_SESSION_NO_TPI)))
-                    asd.payload.set_id(APP_ID_UNKNOWN);
+                    asd.set_payload_id(APP_ID_UNKNOWN);
             }
         }
         else if (tp_app_id > APP_ID_NONE and asd.is_tp_appid_available())
@@ -633,7 +633,7 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p,
             // job of it than we do, so stay out of its way, and don't
             // waste time (but we will still get the Snort callbacks
             // for any of our own future flows). Shut down our detectors.
-            asd.service.set_id(APP_ID_SIP, asd.ctxt.get_odp_ctxt());
+            asd.set_service_id(APP_ID_SIP, asd.ctxt.get_odp_ctxt());
             asd.stop_service_inspection(p, direction);
             asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
         }
@@ -642,7 +642,7 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p,
         {
             // No need for anybody to keep wasting time once we've
             // found RTP - Shut down our detectors.
-            asd.service.set_id(tp_app_id, asd.ctxt.get_odp_ctxt());
+            asd.set_service_id(tp_app_id, asd.ctxt.get_odp_ctxt());
             asd.stop_service_inspection(p, direction);
             asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
             //  - Shut down TP.
@@ -662,26 +662,26 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p,
             APPID_SESSION_CONTINUE) == APPID_SESSION_SERVICE_DETECTED)
         {
             asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
-            if ( asd.payload.get_id() == APP_ID_NONE and
+            if ( asd.get_payload_id() == APP_ID_NONE and
                  ( asd.is_tp_appid_available() or
                    asd.get_session_flags(APPID_SESSION_NO_TPI) ) )
             {
-                asd.payload.set_id(APP_ID_UNKNOWN);
+                asd.set_payload_id(APP_ID_UNKNOWN);
             }
         }
 
         /* If the session appears to only have the client sending data then
            we must mark the service unknown to prevent pending forever. */
         if (asd.service_disco_state == APPID_DISCO_STATE_STATEFUL &&
-            asd.service.get_id() == APP_ID_NONE && asd.is_svc_taking_too_much_time())
+            asd.get_service_id() == APP_ID_NONE && asd.is_svc_taking_too_much_time())
         {
                 asd.stop_service_inspection(p, direction);
-                asd.service.set_id(APP_ID_UNKNOWN, asd.ctxt.get_odp_ctxt());
+                asd.set_service_id(APP_ID_UNKNOWN, asd.ctxt.get_odp_ctxt());
                 return isTpAppidDiscoveryDone;
         }
 
         AppIdDnsSession* dsession = asd.get_dns_session();
-        if (dsession and asd.service.get_id() == APP_ID_DNS
+        if (dsession and asd.get_service_id() == APP_ID_DNS
             and asd.ctxt.get_odp_ctxt().dns_host_reporting and dsession->get_host())
         {
             AppId client_id = APP_ID_NONE;
@@ -690,7 +690,7 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p,
                 dsession->get_host_len(), client_id, payload_id);
             asd.set_client_appid_data(client_id, change_bits);
         }
-        else if (asd.service.get_id() == APP_ID_RTMP)
+        else if (asd.get_service_id() == APP_ID_RTMP)
             asd.examine_rtmp_metadata(change_bits);
         else if (asd.get_session_flags(APPID_SESSION_SSL_SESSION) && asd.tsession)
             asd.examine_ssl_metadata(change_bits);
@@ -699,7 +699,7 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p,
             APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_NOT_A_SERVICE |
             APPID_SESSION_IGNORE_HOST) == APPID_SESSION_SERVICE_DETECTED)
         {
-            asd.sync_with_snort_protocol_id(asd.service.get_id(), p);
+            asd.sync_with_snort_protocol_id(asd.get_service_id(), p);
         }
     }
 
@@ -724,7 +724,7 @@ int ServiceDiscovery::incompatible_data(AppIdSession& asd, const Packet* pkt, Ap
 
     asd.set_service_detected();
     asd.clear_session_flags(APPID_SESSION_CONTINUE);
-    asd.service.set_id(APP_ID_NONE, asd.ctxt.get_odp_ctxt());
+    asd.set_service_id(APP_ID_NONE, asd.ctxt.get_odp_ctxt());
 
     if ( asd.get_session_flags(APPID_SESSION_IGNORE_HOST | APPID_SESSION_UDP_REVERSED) )
         return APPID_SUCCESS;
@@ -760,7 +760,7 @@ int ServiceDiscovery::fail_service(AppIdSession& asd, const Packet* pkt, AppidSe
     if ( !asd.service_detector && !asd.service_candidates.empty() )
         return APPID_SUCCESS;
 
-    asd.service.set_id(APP_ID_NONE, asd.ctxt.get_odp_ctxt());
+    asd.set_service_id(APP_ID_NONE, asd.ctxt.get_odp_ctxt());
     asd.set_service_detected();
     asd.clear_session_flags(APPID_SESSION_CONTINUE);
 
index 08321e6f68cc14e6390c4c289c25569a9659236c..43a42b3cd52474f63c909ce1df15772f3e629898 100644 (file)
@@ -897,12 +897,12 @@ void FtpServiceDetector::create_expected_session(AppIdSession& asd, const Packet
         uint64_t encrypted_flags = asd.get_session_flags(APPID_SESSION_ENCRYPTED | APPID_SESSION_DECRYPTED);
         if (encrypted_flags == APPID_SESSION_ENCRYPTED)
         {
-            fp->service.set_id(APP_ID_FTPSDATA, asd.ctxt.get_odp_ctxt());
+            fp->set_service_id(APP_ID_FTPSDATA, asd.ctxt.get_odp_ctxt());
         }
         else
         {
             encrypted_flags = 0; // reset (APPID_SESSION_ENCRYPTED | APPID_SESSION_DECRYPTED) bits
-            fp->service.set_id(APP_ID_FTP_DATA, asd.ctxt.get_odp_ctxt());
+            fp->set_service_id(APP_ID_FTP_DATA, asd.ctxt.get_odp_ctxt());
         }
 
         asd.initialize_future_session(*fp, APPID_SESSION_IGNORE_ID_FLAGS | encrypted_flags, dir);
index 78450a524e3af68814d79468f37582a74f7c1579..913bb091848bb8fa0e9f020b72a468bba6c22afb 100644 (file)
@@ -459,7 +459,7 @@ int SnmpServiceDetector::validate(AppIdDiscoveryArgs& args)
         {
             args.asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_NOT_A_SERVICE);
             args.asd.clear_session_flags(APPID_SESSION_CONTINUE);
-            args.asd.service.set_id(APP_ID_SNMP, args.asd.ctxt.get_odp_ctxt());
+            args.asd.set_service_id(APP_ID_SNMP, args.asd.ctxt.get_odp_ctxt());
             break;
         }
         sd->state = SNMP_STATE_RESPONSE;
@@ -487,7 +487,7 @@ int SnmpServiceDetector::validate(AppIdDiscoveryArgs& args)
             args.asd.initialize_future_session(*pf, APPID_SESSION_EXPECTED_EVALUATE, APP_ID_APPID_SESSION_DIRECTION_MAX);
             pf->service_disco_state = APPID_DISCO_STATE_STATEFUL;
             pf->scan_flags |= SCAN_HOST_PORT_FLAG;
-            pf->initiator_ip = *sip;
+            pf->set_initiator_ip(*sip);
         }
     }
     break;
index ea5ff32d16c875861894fd91a91381996af4f146..a886999129e2713fd91c35ee260b402b90055686 100644 (file)
@@ -204,7 +204,7 @@ int TftpServiceDetector::validate(AppIdDiscoveryArgs& args)
                 return APPID_ENOMEM;
             }
             args.asd.initialize_future_session(*pf, APPID_SESSION_EXPECTED_EVALUATE, APP_ID_FROM_RESPONDER);
-            pf->initiator_ip = *sip;
+            pf->set_initiator_ip(*sip);
             pf->service_disco_state = APPID_DISCO_STATE_STATEFUL;
             pf->scan_flags |= SCAN_HOST_PORT_FLAG;
         }
index 319a298230aaa68375e0236d83c6fe4adb690517..1bded84bc38c45f58611a368fd49c93153d67a44 100644 (file)
@@ -73,7 +73,8 @@ TEST(service_netbios_test, check_add_smb_info_pointer )
     AppIdInspector ins;
     snort::Packet pkt;
     AppidChangeBits cb;
-    AppIdSession asd(IpProtocol::TCP, nullptr, 21, ins);
+    SfIp ip;
+    AppIdSession asd(IpProtocol::TCP, &ip, 21, ins);
     AppIdDiscoveryArgs args(data, size, dir, asd, &pkt,cb);
     ServiceDiscovery& s_discovery_manager = asd.ctxt.get_odp_ctxt().get_service_disco_mgr();
     args.pkt->ptrs.sp = args.pkt->ptrs.dp = 138;
@@ -84,6 +85,7 @@ TEST(service_netbios_test, check_add_smb_info_pointer )
     FpSMBData *smb_ptr2 = (FpSMBData*)(asd.get_flow_data(APPID_SESSION_DATA_SMB_DATA));
     CHECK(smb_ptr1 == smb_ptr2);
     asd.free_flow_data();
+    delete &asd.get_api();
 }
 
 int main(int argc, char** argv)
index 69cccb5a82e82169a4b22a9fef5d8290a5728bdd..aaecbb0a6a777a93f9c405bf0aedae54d4e26b08 100644 (file)
@@ -169,8 +169,9 @@ const TraceOption* AppIdModule::get_trace_options() const { return nullptr; }
 unsigned AppIdSession::inspector_id = 0;
 AppIdConfig stub_config;
 AppIdContext stub_ctxt(stub_config);
-AppIdSession::AppIdSession(IpProtocol, const SfIp*, uint16_t, AppIdInspector& inspector)
-    : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), ctxt(stub_ctxt) { }
+AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector)
+    : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), ctxt(stub_ctxt),
+        api(*(new AppIdSessionApi(this, *ip))) { }
 AppIdSession::~AppIdSession() = default;
 void AppIdSession::free_flow_data()
 {
index cdaef8c1aa75479be9bd3adce6318fe2ad5e8418..f0368ef7de7cddb0296efa20737e536d2b30ab8f 100644 (file)
@@ -73,8 +73,7 @@ void DataBus::publish(const char*, DataEvent& event, Flow*)
 
 void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, Flow* flow, bool, uint32_t)
 {
-    static AppIdSessionApi api(*this);
-    AppidEvent app_event(change_bits, false, 0, api);
+    AppidEvent app_event(change_bits, false, 0, this->get_api());
     DataBus::publish(APPID_EVENT_ANY_CHANGE, app_event, flow);
 }
 
@@ -120,6 +119,68 @@ AppId AppInfoManager::get_appid_by_name(const char*)
     return APPID_UT_ID;
 }
 
+AppId AppIdSessionApi::get_service_app_id() const
+{
+    return application_ids[APP_PROTOID_SERVICE];
+}
+
+AppId AppIdSessionApi::get_client_app_id(uint32_t) const
+{
+    return application_ids[APP_PROTOID_CLIENT];
+}
+
+AppId AppIdSessionApi::get_payload_app_id(uint32_t) const
+{
+    return application_ids[APP_PROTOID_PAYLOAD];
+}
+
+void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id,
+    AppId misc_id, AppId referred_id, AppidChangeBits& change_bits)
+{
+    if (api.application_ids[APP_PROTOID_SERVICE] != service_id)
+    {
+        api.application_ids[APP_PROTOID_SERVICE] = service_id;
+        change_bits.set(APPID_SERVICE_BIT);
+    }
+    if (api.application_ids[APP_PROTOID_CLIENT] != client_id)
+    {
+        api.application_ids[APP_PROTOID_CLIENT] = client_id;
+        change_bits.set(APPID_CLIENT_BIT);
+    }
+    if (api.application_ids[APP_PROTOID_PAYLOAD] != payload_id)
+    {
+        api.application_ids[APP_PROTOID_PAYLOAD] = payload_id;
+        change_bits.set(APPID_PAYLOAD_BIT);
+    }
+    if (api.application_ids[APP_PROTOID_MISC] != misc_id)
+    {
+        api.application_ids[APP_PROTOID_MISC] = misc_id;
+        change_bits.set(APPID_MISC_BIT);
+    }
+    if (api.application_ids[APP_PROTOID_REFERRED] != referred_id)
+    {
+        api.application_ids[APP_PROTOID_REFERRED] = referred_id;
+        change_bits.set(APPID_REFERRED_BIT);
+    }
+}
+
+void AppIdSession::set_ss_application_ids(AppId client_id, AppId payload_id,
+    AppidChangeBits& change_bits)
+{
+    if (api.application_ids[APP_PROTOID_CLIENT] != client_id)
+    {
+        api.application_ids[APP_PROTOID_CLIENT] = client_id;
+        change_bits.set(APPID_CLIENT_BIT);
+    }
+    if (api.application_ids[APP_PROTOID_PAYLOAD] != payload_id)
+    {
+        api.application_ids[APP_PROTOID_PAYLOAD] = payload_id;
+        change_bits.set(APPID_PAYLOAD_BIT);
+    }
+}
+
+AppIdHttpSession* AppIdSession::get_http_session(uint32_t) const { return nullptr; }
+
 Flow* flow = nullptr;
 AppIdSession* mock_session = nullptr;
 
@@ -167,12 +228,12 @@ TEST(appid_api, produce_ha_state)
     mock_session->flags |= APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_HTTP_SESSION;
 
     mock_session->set_tp_app_id(APPID_UT_ID);
-    mock_session->service.set_id(APPID_UT_ID + 1, stub_odp_ctxt);
+    mock_session->set_service_id(APPID_UT_ID + 1, stub_odp_ctxt);
     mock_session->client_inferred_service_id = APPID_UT_ID + 2;
-    mock_session->service.set_port_service_id(APPID_UT_ID + 3);
-    mock_session->payload.set_id(APPID_UT_ID + 4);
+    mock_session->set_port_service_id(APPID_UT_ID + 3);
+    mock_session->set_payload_id(APPID_UT_ID + 4);
     mock_session->set_tp_payload_app_id(APPID_UT_ID + 5);
-    mock_session->client.set_id(APPID_UT_ID + 6);
+    mock_session->set_client_id(APPID_UT_ID + 6);
     mock_session->misc_app_id = APPID_UT_ID + 7;
 
     uint32_t val = appid_api.produce_ha_state(*flow, (uint8_t*)&appHA);
@@ -197,15 +258,16 @@ TEST(appid_api, produce_ha_state)
     AppIdSession* session = (AppIdSession*)flow->get_flow_data(AppIdSession::inspector_id);
     CHECK_TRUE(session);
     CHECK_TRUE(session->get_tp_app_id() == appHA.appId[0]);
-    CHECK_TRUE(session->service.get_id() == appHA.appId[1]);
+    CHECK_TRUE(session->get_service_id() == appHA.appId[1]);
     CHECK_TRUE(session->client_inferred_service_id == appHA.appId[2]);
-    CHECK_TRUE(session->service.get_port_service_id() == appHA.appId[3]);
-    CHECK_TRUE(session->payload.get_id() == appHA.appId[4]);
+    CHECK_TRUE(session->get_port_service_id() == appHA.appId[3]);
+    CHECK_TRUE(session->get_payload_id() == appHA.appId[4]);
     CHECK_TRUE(session->get_tp_payload_app_id() == appHA.appId[5]);
-    CHECK_TRUE(session->client.get_id() == appHA.appId[6]);
+    CHECK_TRUE(session->get_client_id() == appHA.appId[6]);
     CHECK_TRUE(session->misc_app_id == appHA.appId[7]);
     CHECK_TRUE(session->service_disco_state == APPID_DISCO_STATE_FINISHED);
     CHECK_TRUE(session->client_disco_state == APPID_DISCO_STATE_FINISHED);
+    delete &session->get_api();
     delete session;
 
     // test logic when service app is ftp control
@@ -220,9 +282,10 @@ TEST(appid_api, produce_ha_state)
         APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED);
     CHECK_TRUE(flags == (APPID_SESSION_CLIENT_DETECTED | APPID_SESSION_NOT_A_SERVICE
         | APPID_SESSION_SERVICE_DETECTED));
-    CHECK_TRUE(session->service.get_id() == APP_ID_FTP_CONTROL);
+    CHECK_TRUE(session->get_service_id() == APP_ID_FTP_CONTROL);
     CHECK_TRUE(session->service_disco_state == APPID_DISCO_STATE_STATEFUL);
     CHECK_TRUE(session->client_disco_state == APPID_DISCO_STATE_FINISHED);
+    delete &session->get_api();
     delete session;
 }
 
@@ -232,13 +295,16 @@ TEST(appid_api, ssl_app_group_id_lookup)
     AppId service, client, payload = APP_ID_NONE;
     bool val = false;
 
+    AppidChangeBits change_bits;
+    mock_session->set_ss_application_ids(APPID_UT_ID, APPID_UT_ID, APPID_UT_ID,
+        APPID_UT_ID, APPID_UT_ID, change_bits);
     val = appid_api.ssl_app_group_id_lookup(flow, nullptr, nullptr, nullptr, nullptr,
         false, service, client, payload);
     CHECK_TRUE(val);
     CHECK_EQUAL(service, APPID_UT_ID);
     CHECK_EQUAL(client, APPID_UT_ID);
     CHECK_EQUAL(payload, APPID_UT_ID);
-    STRCMP_EQUAL("Published change_bits == 0000000011110", test_log);
+    STRCMP_EQUAL("Published change_bits == 00000000000000", test_log);
 
     service = APP_ID_NONE;
     client = APP_ID_NONE;
@@ -251,9 +317,8 @@ TEST(appid_api, ssl_app_group_id_lookup)
     STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
-    STRCMP_EQUAL("Published change_bits == 0000010001100", test_log);
+    STRCMP_EQUAL("Published change_bits == 00000100011000", test_log);
 
-    AppidChangeBits change_bits;
     mock_session->tsession->set_tls_host("www.cisco.com", 13, change_bits);
     mock_session->tsession->set_tls_cname("www.cisco.com", 13, change_bits);
     mock_session->tsession->set_tls_org_unit("Cisco", 5);
@@ -268,7 +333,7 @@ TEST(appid_api, ssl_app_group_id_lookup)
     STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Cisco");
-    STRCMP_EQUAL("Published change_bits == 0000010001100", test_log);
+    STRCMP_EQUAL("Published change_bits == 00000100011000", test_log);
 
     string host = "";
     val = appid_api.ssl_app_group_id_lookup(flow, (const char*)(host.c_str()), nullptr,
@@ -279,7 +344,7 @@ TEST(appid_api, ssl_app_group_id_lookup)
     STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST);
     STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Google");
-    STRCMP_EQUAL("Published change_bits == 0000010000000", test_log);
+    STRCMP_EQUAL("Published change_bits == 00000100000000", test_log);
     mock().checkExpectations();
 }
 
@@ -294,11 +359,22 @@ TEST(appid_api, is_inspection_needed)
     CHECK_FALSE(appid_api.is_inspection_needed(inspector));
 }
 
+TEST(appid_api, is_service_http_type)
+{
+    CHECK_TRUE(appid_api.is_service_http_type(APP_ID_HTTP));
+    CHECK_TRUE(appid_api.is_service_http_type(APP_ID_HTTPS));
+    CHECK_TRUE(appid_api.is_service_http_type(APP_ID_SMTPS));
+    CHECK_FALSE(appid_api.is_service_http_type(APP_ID_SMTP));
+}
+
 int main(int argc, char** argv)
 {
     mock_init_appid_pegs();
-    mock_session = new AppIdSession(IpProtocol::TCP, nullptr, 1492, dummy_appid_inspector);
+    SfIp ip;
+    mock_session = new AppIdSession(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector);
     int rc = CommandLineTestRunner::RunAllTests(argc, argv);
     mock_cleanup_appid_pegs();
+    delete &mock_session->get_api();
+    delete mock_session;
     return rc;
 }
index d91003913b59ecf3d10623245a369379121818ec..10ba40a3c8ea8c1e0dcfe5e077c0e12dfc381b88 100644 (file)
@@ -56,8 +56,8 @@ AppIdConfig::~AppIdConfig() { }
 
 AppIdConfig stub_config;
 AppIdContext stub_ctxt(stub_config);
-AppIdSession::AppIdSession(IpProtocol, const SfIp*, uint16_t, AppIdInspector&)
-    : FlowData(0), ctxt(stub_ctxt) { }
+AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector&)
+    : FlowData(0), ctxt(stub_ctxt), api(*(new AppIdSessionApi(this, *ip))) { }
 AppIdSession::~AppIdSession() = default;
 
 // Utility functions
@@ -109,11 +109,11 @@ TEST(appid_debug, basic_test)
     CHECK_EQUAL(appidDebug->is_enabled(), true);
 
     SfIp sip;
+    sip.set("10.1.2.3");
     SfIp dip;
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &sip, 0, inspector);
     // This packet...
-    sip.set("10.1.2.3");
     dip.set("10.9.8.7");
     uint16_t sport = 48620;
     uint16_t dport = 80;
@@ -121,7 +121,6 @@ TEST(appid_debug, basic_test)
     uint16_t address_space_id = 0;
     // The session...
     session.initiator_port = sport;
-    session.initiator_ip = sip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 4, address_space_id, &session, false);
@@ -130,6 +129,8 @@ TEST(appid_debug, basic_test)
     // get_debug_session()
     const char* str = "10.1.2.3 48620 -> 10.9.8.7 80 6 AS=0 ID=3";
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
+
+    delete &session.get_api();
 }
 
 // Test matching a packet in reverse direction (from constraints).
@@ -143,18 +144,17 @@ TEST(appid_debug, reverse_direction_activate_test)
 
     SfIp sip;
     SfIp dip;
+    dip.set("10.1.2.3");
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &dip, 0, inspector);
     // This packet...
     sip.set("10.9.8.7");    // this would be a reply back
-    dip.set("10.1.2.3");
     uint16_t sport = 80;
     uint16_t dport = 48620;
     IpProtocol protocol = IpProtocol::TCP;
     uint16_t address_space_id = 0;
     // The session...
     session.initiator_port = dport;    // session initiator is now dst
-    session.initiator_ip = dip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 4, address_space_id, &session, false);
@@ -163,6 +163,8 @@ TEST(appid_debug, reverse_direction_activate_test)
     // get_debug_session()
     const char* str = "10.1.2.3 48620 -> 10.9.8.7 80 6 AS=0 ID=3";
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
+
+    delete &session.get_api();
 }
 
 // Test IPv6 matches.
@@ -176,11 +178,11 @@ TEST(appid_debug, ipv6_test)
     CHECK_EQUAL(appidDebug->is_enabled(), true);
 
     SfIp sip;
+    sip.set("2001:db8:85a3::8a2e:370:7334");    // IPv6
     SfIp dip;
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &sip, 0, inspector);
     // This packet...
-    sip.set("2001:db8:85a3::8a2e:370:7334");    // IPv6
     dip.set("2001:db8:85a3::8a2e:370:7335");
     uint16_t sport = 1234;
     uint16_t dport = 443;
@@ -188,7 +190,6 @@ TEST(appid_debug, ipv6_test)
     uint16_t address_space_id = 100;
     // The session...
     session.initiator_port = sport;
-    session.initiator_ip = sip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 6, address_space_id, &session, false);
@@ -203,6 +204,8 @@ TEST(appid_debug, ipv6_test)
             "2001:db8:85a3::8a2e:370:7335 443 17 AS=100 ID=3";
 #endif
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
+
+    delete &session.get_api();
 }
 
 // Test matching on session initiator IP (rather than port).
@@ -215,11 +218,11 @@ TEST(appid_debug, no_initiator_port_test)
     CHECK_EQUAL(appidDebug->is_enabled(), true);
 
     SfIp sip;
+    sip.set("10.1.2.3");
     SfIp dip;
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &sip, 0, inspector);
     // This packet...
-    sip.set("10.1.2.3");
     dip.set("10.9.8.7");
     uint16_t sport = 48620;
     uint16_t dport = 80;
@@ -227,7 +230,6 @@ TEST(appid_debug, no_initiator_port_test)
     uint16_t address_space_id = 0;
     // The session...
     session.initiator_port = 0;    // no initiator port yet (uses IPs)
-    session.initiator_ip = sip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 4, address_space_id, &session, false);
@@ -236,6 +238,8 @@ TEST(appid_debug, no_initiator_port_test)
     // get_debug_session()
     const char* str = "10.1.2.3 48620 -> 10.9.8.7 80 6 AS=0 ID=3";
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
+
+    delete &session.get_api();
 }
 
 // Test matching on session initiator IP (reverse direction packet).
@@ -249,18 +253,17 @@ TEST(appid_debug, no_initiator_port_reversed_test)
 
     SfIp sip;
     SfIp dip;
+    dip.set("10.1.2.3");
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &dip, 0, inspector);
     // This packet...
     sip.set("10.9.8.7");
-    dip.set("10.1.2.3");
     uint16_t sport = 80;
     uint16_t dport = 48620;
     IpProtocol protocol = IpProtocol::TCP;
     uint16_t address_space_id = 0;
     // The session...
     session.initiator_port = 0;    // no initiator port yet (uses IPs)... and reversed packet dir from above
-    session.initiator_ip = dip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 4, address_space_id, &session, false);
@@ -269,6 +272,8 @@ TEST(appid_debug, no_initiator_port_reversed_test)
     // get_debug_session()
     const char* str = "10.1.2.3 48620 -> 10.9.8.7 80 6 AS=0 ID=3";
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
+
+    delete &session.get_api();
 }
 
 // Check for null session pointer (won't activate).
@@ -316,11 +321,11 @@ TEST(appid_debug, no_match_test)
     CHECK_EQUAL(appidDebug->is_enabled(), true);
 
     SfIp sip;
+    sip.set("10.1.2.3");
     SfIp dip;
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &sip, 0, inspector);
     // This packet...
-    sip.set("10.1.2.3");
     dip.set("10.9.8.7");
     uint16_t sport = 48620;
     uint16_t dport = 80;
@@ -328,11 +333,12 @@ TEST(appid_debug, no_match_test)
     uint16_t address_space_id = 0;
     // The session...
     session.initiator_port = sport;
-    session.initiator_ip = sip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 4, address_space_id, &session, false);
     CHECK_EQUAL(appidDebug->is_active(), false);    // not active (no match)
+
+    delete &session.get_api();
 }
 
 // Set all constraints (must match all).
@@ -345,11 +351,11 @@ TEST(appid_debug, all_constraints_test)
     CHECK_EQUAL(appidDebug->is_enabled(), true);
 
     SfIp sip;
+    sip.set("10.1.2.3");
     SfIp dip;
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &sip, 0, inspector);
     // This packet...
-    sip.set("10.1.2.3");
     dip.set("10.9.8.7");
     uint16_t sport = 48620;
     uint16_t dport = 80;
@@ -357,7 +363,6 @@ TEST(appid_debug, all_constraints_test)
     uint16_t address_space_id = 0;
     // The session...
     session.initiator_port = sport;
-    session.initiator_ip = sip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 4, address_space_id, &session, false);
@@ -366,6 +371,8 @@ TEST(appid_debug, all_constraints_test)
     // get_debug_session()
     const char* str = "10.1.2.3 48620 -> 10.9.8.7 80 6 AS=0 ID=3";
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
+
+    delete &session.get_api();
 }
 
 // Only set protocol in constraints.
@@ -378,11 +385,11 @@ TEST(appid_debug, just_proto_test)
     CHECK_EQUAL(appidDebug->is_enabled(), true);
 
     SfIp sip;
+    sip.set("10.1.2.3");
     SfIp dip;
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &sip, 0, inspector);
     // This packet...
-    sip.set("10.1.2.3");
     dip.set("10.9.8.7");
     uint16_t sport = 48620;
     uint16_t dport = 80;
@@ -390,7 +397,6 @@ TEST(appid_debug, just_proto_test)
     uint16_t address_space_id = 0;
     // The session...
     session.initiator_port = sport;
-    session.initiator_ip = sip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 4, address_space_id, &session, false);
@@ -399,6 +405,8 @@ TEST(appid_debug, just_proto_test)
     // get_debug_session()
     const char* str = "10.1.2.3 48620 -> 10.9.8.7 80 6 AS=0 ID=3";
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
+
+    delete &session.get_api();
 }
 
 // Only set IP in constraints.
@@ -411,11 +419,11 @@ TEST(appid_debug, just_ip_test)
     CHECK_EQUAL(appidDebug->is_enabled(), true);
 
     SfIp sip;
+    sip.set("10.1.2.3");
     SfIp dip;
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &sip, 0, inspector);
     // This packet...
-    sip.set("10.1.2.3");
     dip.set("10.9.8.7");
     uint16_t sport = 48620;
     uint16_t dport = 80;
@@ -423,7 +431,6 @@ TEST(appid_debug, just_ip_test)
     uint16_t address_space_id = 0;
     // The session...
     session.initiator_port = sport;
-    session.initiator_ip = sip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 4, address_space_id, &session, false);
@@ -432,6 +439,8 @@ TEST(appid_debug, just_ip_test)
     // get_debug_session()
     const char* str = "10.1.2.3 48620 -> 10.9.8.7 80 6 AS=0 ID=3";
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
+
+    delete &session.get_api();
 }
 
 // Only set port in constraints.
@@ -444,11 +453,11 @@ TEST(appid_debug, just_port_test)
     CHECK_EQUAL(appidDebug->is_enabled(), true);
 
     SfIp sip;
+    sip.set("10.1.2.3");
     SfIp dip;
     AppIdInspector inspector;
-    AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
+    AppIdSession session(IpProtocol::PROTO_NOT_SET, &sip, 0, inspector);
     // This packet...
-    sip.set("10.1.2.3");
     dip.set("10.9.8.7");
     uint16_t sport = 48620;
     uint16_t dport = 80;
@@ -456,7 +465,6 @@ TEST(appid_debug, just_port_test)
     uint16_t address_space_id = 0;
     // The session...
     session.initiator_port = sport;
-    session.initiator_ip = sip;
     // activate()
     appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
         protocol, 4, address_space_id, &session, false);
@@ -465,6 +473,8 @@ TEST(appid_debug, just_port_test)
     // get_debug_session()
     const char* str = "10.1.2.3 48620 -> 10.9.8.7 80 6 AS=0 ID=3";
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
+
+    delete &session.get_api();
 }
 
 int main(int argc, char** argv)
index 1bd157065685fb6d6cbf61364db6f7d774caff9c..a751237f64089df719433d29d5a596cf6d2909cf 100644 (file)
 #include <CppUTest/CommandLineTestRunner.h>
 #include <CppUTest/TestHarness.h>
 
-snort::Inspector* snort::InspectorManager::get_inspector(
+namespace snort
+{
+Inspector* InspectorManager::get_inspector(
     char const*, bool, const snort::SnortConfig*) { return nullptr; }
+}
 
 void ApplicationDescriptor::set_id(
     const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
@@ -62,8 +65,8 @@ TEST_GROUP(appid_detector_tests)
     void setup() override
     {
         MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
-        mock_session = new AppIdSession(IpProtocol::TCP, nullptr, 1492, dummy_appid_inspector);
-        mock_session->get_http_session();
+        SfIp ip;
+        mock_session = new AppIdSession(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector);
         flow = new Flow;
         flow->set_flow_data(mock_session);
     }
@@ -71,6 +74,7 @@ TEST_GROUP(appid_detector_tests)
     void teardown() override
     {
         delete flow;
+        delete &mock_session->get_api();
         delete mock_session;
         MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
     }
@@ -81,8 +85,8 @@ TEST(appid_detector_tests, add_user)
     const char* username = "snorty";
     AppIdDetector* ad = new TestDetector;
     ad->add_user(*mock_session, username, APPID_UT_ID, true);
-    STRCMP_EQUAL(mock_session->client.get_username(), username);
-    CHECK_TRUE((mock_session->client.get_user_id() == APPID_UT_ID));
+    STRCMP_EQUAL(mock_session->get_client_user(), username);
+    CHECK_TRUE((mock_session->get_client_user_id() == APPID_UT_ID));
     CHECK_TRUE((mock_session->get_session_flags(APPID_SESSION_LOGIN_SUCCEEDED)
         & APPID_SESSION_LOGIN_SUCCEEDED));
     delete ad;
index 3a4ccd5cfc0d6906df41157a93f36e976dfab878..5c366a74e00d28fc8f2a38614bd6670c2f18a7f4 100644 (file)
@@ -197,6 +197,7 @@ void AppIdSession::examine_rtmp_metadata(AppidChangeBits&) {}
 void AppIdSession::examine_ssl_metadata(AppidChangeBits&) {}
 void AppIdSession::update_encrypted_app_id(AppId) {}
 bool AppIdSession::is_tp_processing_done() const {return 0;}
+AppId AppIdSession::pick_ss_payload_app_id(AppId) const { return get_payload_id(); }
 AppIdSession* AppIdSession::allocate_session(const Packet*, IpProtocol,
     AppidSessionDirection, AppIdInspector*)
 {
@@ -205,8 +206,7 @@ AppIdSession* AppIdSession::allocate_session(const Packet*, IpProtocol,
 
 void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, Flow* flow, bool, uint32_t)
 {
-    static AppIdSessionApi api(*this);
-    AppidEvent app_event(change_bits, false, 0, api);
+    AppidEvent app_event(change_bits, false, 0, this->get_api());
     DataBus::publish(APPID_EVENT_ANY_CHANGE, app_event, flow);
 }
 
@@ -285,6 +285,38 @@ bool AppIdReloadTuner::tune_resources(unsigned int)
     return true;
 }
 
+void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id,
+    AppId misc_id, AppId referred_id, AppidChangeBits& change_bits)
+{
+    if (api.application_ids[APP_PROTOID_SERVICE] != service_id)
+    {
+        api.application_ids[APP_PROTOID_SERVICE] = service_id;
+        change_bits.set(APPID_SERVICE_BIT);
+    }
+    if (api.application_ids[APP_PROTOID_CLIENT] != client_id)
+    {
+        api.application_ids[APP_PROTOID_CLIENT] = client_id;
+        change_bits.set(APPID_CLIENT_BIT);
+    }
+    if (api.application_ids[APP_PROTOID_PAYLOAD] != payload_id)
+    {
+        api.application_ids[APP_PROTOID_PAYLOAD] = payload_id;
+        change_bits.set(APPID_PAYLOAD_BIT);
+    }
+    if (api.application_ids[APP_PROTOID_MISC] != misc_id)
+    {
+        api.application_ids[APP_PROTOID_MISC] = misc_id;
+        change_bits.set(APPID_MISC_BIT);
+    }
+    if (api.application_ids[APP_PROTOID_REFERRED] != referred_id)
+    {
+        api.application_ids[APP_PROTOID_REFERRED] = referred_id;
+        change_bits.set(APPID_REFERRED_BIT);
+    }
+}
+
+AppIdHttpSession* AppIdSession::get_http_session(uint32_t) const { return nullptr; }
+
 TEST_GROUP(appid_discovery_tests)
 {
     char test_log[256];
@@ -330,22 +362,24 @@ TEST(appid_discovery_tests, event_published_when_ignoring_flow)
     DAQ_PktHdr_t pkth;
     p.pkth = &pkth;
     SfIp ip;
+    ip.set("1.2.3.4");
     p.ptrs.ip_api.set(ip, ip);
     AppIdModule app_module;
     AppIdInspector ins(app_module);
-    AppIdSession* asd = new AppIdSession(IpProtocol::TCP, nullptr, 21, ins);
+    AppIdSession* asd = new AppIdSession(IpProtocol::TCP, &ip, 21, ins);
     Flow* flow = new Flow;
     flow->set_flow_data(asd);
     p.flow = flow;
     asd->initiator_port = 21;
-    asd->initiator_ip.set("1.2.3.4");
     asd->set_session_flags(APPID_SESSION_FUTURE_FLOW);
 
     AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
 
     // Detect changes in service, client, payload, and misc appid
     mock().checkExpectations();
-    STRCMP_EQUAL(test_log, "Published change_bits == 0000000011110");
+    STRCMP_EQUAL(test_log, "Published change_bits == 00000001111100");
+
+    delete &asd->get_api();
     delete asd;
     delete flow;
 }
@@ -360,22 +394,23 @@ TEST(appid_discovery_tests, event_published_when_processing_flow)
     DAQ_PktHdr_t pkth;
     p.pkth = &pkth;
     SfIp ip;
+    ip.set("1.2.3.4");
     p.ptrs.ip_api.set(ip, ip);
     p.ptrs.tcph = nullptr;
     AppIdModule app_module;
     AppIdInspector ins(app_module);
-    AppIdSession* asd = new AppIdSession(IpProtocol::TCP, nullptr, 21, ins);
+    AppIdSession* asd = new AppIdSession(IpProtocol::TCP, &ip, 21, ins);
     Flow* flow = new Flow;
     flow->set_flow_data(asd);
     p.flow = flow;
     asd->initiator_port = 21;
-    asd->initiator_ip.set("1.2.3.4");
 
     AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
 
     // Detect changes in service, client, payload, and misc appid
     mock().checkExpectations();
-    STRCMP_EQUAL(test_log, "Published change_bits == 0000000011110");
+    STRCMP_EQUAL(test_log, "Published change_bits == 00000001111100");
+    delete &asd->get_api();
     delete asd;
     delete flow;
 }
@@ -386,12 +421,14 @@ TEST(appid_discovery_tests, change_bits_for_client_version)
     AppidChangeBits change_bits;
     AppIdModule app_module;
     AppIdInspector ins(app_module);
-    AppIdSession* asd = new AppIdSession(IpProtocol::TCP, nullptr, 21, ins);
+    SfIp ip;
+    AppIdSession* asd = new AppIdSession(IpProtocol::TCP, &ip, 21, ins);
     const char* version = "3.0";
-    asd->client.set_version(version, change_bits);
+    asd->set_client_version(version, change_bits);
 
     // Detect changes in client version
     CHECK_EQUAL(change_bits.test(APPID_VERSION_BIT), true);
+    delete &asd->get_api();
     delete asd;
 }
 
@@ -416,38 +453,39 @@ TEST(appid_discovery_tests, change_bits_for_non_http_appid)
     DAQ_PktHdr_t pkth;
     p.pkth = &pkth;
     SfIp ip;
+    ip.set("1.2.3.4");
     p.ptrs.ip_api.set(ip, ip);
     AppIdModule app_module;
     AppIdInspector ins(app_module);
-    AppIdSession* asd = new AppIdSession(IpProtocol::TCP, nullptr, 21, ins);
+    AppIdSession* asd = new AppIdSession(IpProtocol::TCP, &ip, 21, ins);
     Flow* flow = new Flow;
     flow->set_flow_data(asd);
     p.flow = flow;
     p.ptrs.tcph = nullptr;
     asd->initiator_port = 21;
-    asd->initiator_ip.set("1.2.3.4");
     asd->misc_app_id = APP_ID_NONE;
-    asd->payload.set_id(APP_ID_NONE);
-    asd->client.set_id(APP_ID_CURL);
-    asd->service.set_id(APP_ID_FTP, app_ctxt.get_odp_ctxt());
+    asd->set_payload_id(APP_ID_NONE);
+    asd->set_client_id(APP_ID_CURL);
+    asd->set_service_id(APP_ID_FTP, app_ctxt.get_odp_ctxt());
 
     AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
 
     // Detect event for FTP service and CURL client
-    CHECK_EQUAL(asd->client.get_id(), APP_ID_CURL);
-    CHECK_EQUAL(asd->service.get_id(), APP_ID_FTP);
+    CHECK_EQUAL(asd->get_client_id(), APP_ID_CURL);
+    CHECK_EQUAL(asd->get_service_id(), APP_ID_FTP);
 
     // Testing DNS appid
     asd->misc_app_id = APP_ID_NONE;
-    asd->payload.set_id(APP_ID_NONE);
-    asd->client.set_id(APP_ID_NONE);
-    asd->service.set_id(APP_ID_DNS, app_ctxt.get_odp_ctxt());
+    asd->set_payload_id(APP_ID_NONE);
+    asd->set_client_id(APP_ID_NONE);
+    asd->set_service_id(APP_ID_DNS, app_ctxt.get_odp_ctxt());
     AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
 
     // Detect event for DNS service
     mock().checkExpectations();
-    CHECK_EQUAL(asd->service.get_id(), APP_ID_DNS);
+    CHECK_EQUAL(asd->get_service_id(), APP_ID_DNS);
 
+    delete &asd->get_api();
     delete asd;
     delete flow;
 }
@@ -465,11 +503,11 @@ TEST(appid_discovery_tests, change_bits_to_string)
     // Detect all; failure of this test means some bits from enum are missed in translation
     change_bits.set();
     change_bits_to_string(change_bits, str);
-    STRCMP_EQUAL(str.c_str(), "created, service, client, payload, misc, referred, host,"
+    STRCMP_EQUAL(str.c_str(), "created, reset, service, client, payload, misc, referred, host,"
         " tls-host, url, user-agent, response, referrer, version");
 
     // Failure of this test is a reminder that enum is changed, hence translator needs update
-    CHECK_EQUAL(APPID_MAX_BIT, 13);
+    CHECK_EQUAL(APPID_MAX_BIT, 14);
 }
 
 int main(int argc, char** argv)
index 80186dfb26222cca6e08e84856bb2efbc954c87f..8cc88e24a1f9a081b72f6f9c49614d4e41c8bd9b 100644 (file)
@@ -69,6 +69,24 @@ class FakeHttpMsgHeader
 };
 FakeHttpMsgHeader* fake_msg_header = nullptr;
 
+void AppIdSession::set_application_ids_service(AppId, AppidChangeBits&) {}
+void AppIdSession::set_ss_application_ids(AppId, AppId, AppId, AppId, AppId, AppidChangeBits&) {}
+AppIdHttpSession* AppIdSession::get_http_session(uint32_t stream_index) const
+{
+    if (stream_index < api.hsessions.size())
+    {
+        return api.hsessions[stream_index];
+    }
+    return nullptr;
+}
+
+void AppIdSession::delete_all_http_sessions()
+{
+    for (auto hsession : api.hsessions)
+        delete hsession;
+    api.hsessions.clear();
+}
+
 void AppIdHttpSession::set_http_change_bits(AppidChangeBits&, HttpFieldIds) {}
 void AppIdHttpSession::set_field(HttpFieldIds id, const std::string* str,
     AppidChangeBits&)
@@ -215,7 +233,8 @@ TEST_GROUP(appid_http_event)
     {
         MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
         flow = new Flow;
-        mock_session = new AppIdSession(IpProtocol::TCP, nullptr, 1492, dummy_appid_inspector);
+        SfIp ip;
+        mock_session = new AppIdSession(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector);
         mock_session->create_http_session();
         flow->set_flow_data(mock_session);
         appidDebug = new AppIdDebug();
@@ -225,6 +244,7 @@ TEST_GROUP(appid_http_event)
     void teardown() override
     {
         fake_msg_header = nullptr;
+        delete &mock_session->get_api();
         delete mock_session;
         delete flow;
         mock().clear();
index 3ee5faa0b5e9346b86969765aa196414f62ded07..ed3838035d1c0f726034258047fc572090612bbc 100644 (file)
@@ -101,8 +101,9 @@ static OdpContext stub_odp_ctxt(stub_config, nullptr);
 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(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector)
+    : FlowData(inspector_id, &inspector), ctxt(stub_ctxt),
+        api(*(new AppIdSessionApi(this, *ip)))
 {}
 
 AppIdSession::~AppIdSession()
@@ -124,7 +125,7 @@ void AppIdSession::clear_http_flags()
 {
 }
 
-void AppIdSession::reset_session_data()
+void AppIdSession::reset_session_data(AppidChangeBits&)
 {
 }
 
@@ -168,8 +169,8 @@ AppIdConfig::~AppIdConfig() { }
 unsigned AppIdSession::inspector_id = 0;
 THREAD_LOCAL AppIdDebug* appidDebug = nullptr;
 
-const SfIp* sfip = nullptr;
-AppIdSession session(IpProtocol::IP, sfip, 0, dummy_appid_inspector);
+SfIp sfip;
+AppIdSession session(IpProtocol::IP, &sfip, 0, dummy_appid_inspector);
 AppIdHttpSession mock_hsession(session, 0);
 
 TEST_GROUP(appid_http_session)
@@ -286,7 +287,7 @@ TEST(appid_http_session, change_bits_for_referred_appid)
     AppIdPegCounts::init_pegs();
     AppIdConfig config;
     OdpContext odp_ctxt(config, nullptr);
-    session.service.set_id(APP_ID_HTTP, odp_ctxt);
+    session.set_service_id(APP_ID_HTTP, odp_ctxt);
     session.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
     mock_hsession.set_skip_simple_detect(false);
     mock_hsession.set_field( (HttpFieldIds)2, new std::string("referer"), change_bits );
index 4b9916c26d262796b90e002c3b25b6c0a1159c2b..ada2480d546a443072a0b20b8c57cb3926586ad5 100644 (file)
@@ -78,44 +78,41 @@ static AppIdConfig stub_config;
 static AppIdContext stub_ctxt(stub_config);
 static OdpContext stub_odp_ctxt(stub_config, nullptr);
 OdpContext* AppIdContext::odp_ctxt = &stub_odp_ctxt;
-AppIdSession::AppIdSession(IpProtocol proto, const SfIp*, uint16_t, AppIdInspector& inspector)
-    : FlowData(inspector_id, &inspector), ctxt(stub_ctxt), protocol(proto)
+AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInspector& inspector)
+    : FlowData(inspector_id, &inspector), ctxt(stub_ctxt), protocol(proto),
+        api(*(new AppIdSessionApi(this, *ip)))
 {
     service_port = APPID_UT_SERVICE_PORT;
     AppidChangeBits change_bits;
 
-    memset(application_ids, 0, sizeof(application_ids));
-    client.update_user(APPID_UT_ID, APPID_UT_USERNAME);
-    client.set_version(APPID_UT_CLIENT_VERSION, change_bits);
+    set_client_user(APPID_UT_ID, APPID_UT_USERNAME);
+    set_client_version(APPID_UT_CLIENT_VERSION, change_bits);
 
-    service.set_vendor(APPID_UT_SERVICE_VENDOR);
-    service.set_version(APPID_UT_SERVICE_VERSION, change_bits);
+    set_service_vendor(APPID_UT_SERVICE_VENDOR);
+    set_service_version(APPID_UT_SERVICE_VERSION, change_bits);
     subtype = &APPID_UT_SERVICE_SUBTYPE;
 
     tsession = new TlsSession;
 
     service_ip.pton(AF_INET, APPID_UT_SERVICE_IP_ADDR);
-    initiator_ip.pton(AF_INET, APPID_UT_INITIATOR_IP_ADDR);
+    api.initiator_ip.pton(AF_INET, APPID_UT_INITIATOR_IP_ADDR);
 
     netbios_name = snort_strdup(APPID_UT_NETBIOS_NAME);
 
-    dsession = new MockAppIdDnsSession;
+    api.dsession = new MockAppIdDnsSession;
     tp_app_id = APPID_UT_ID;
-    service.set_id(APPID_UT_ID + 1, ctxt.get_odp_ctxt());
+    set_service_id(APPID_UT_ID + 1, ctxt.get_odp_ctxt());
     client_inferred_service_id = APPID_UT_ID + 2;
-    service.set_port_service_id(APPID_UT_ID + 3);
-    payload.set_id(APPID_UT_ID + 4);
+    set_port_service_id(APPID_UT_ID + 3);
+    set_payload_id(APPID_UT_ID + 4);
     tp_payload_app_id = APPID_UT_ID + 5;
-    client.set_id(APPID_UT_ID + 6);
+    set_client_id(APPID_UT_ID + 6);
     misc_app_id = APPID_UT_ID + 7;
 }
 
 AppIdSession::~AppIdSession()
 {
-    for (auto* hsession: hsessions)
-        delete hsession;
     delete tsession;
-    delete dsession;
     if (netbios_name)
         snort_free(netbios_name);
 }
@@ -130,34 +127,9 @@ int AppIdSession::add_flow_data(void*, unsigned, AppIdFreeFCN)
     return 0;
 }
 
-void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id,
-    AppId payload_id, AppId misc_id, AppidChangeBits& change_bits)
-{
-    if (application_ids[APP_PROTOID_SERVICE] != service_id)
-    {
-        application_ids[APP_PROTOID_SERVICE] = service_id;
-        change_bits.set(APPID_SERVICE_BIT);
-    }
-    if (application_ids[APP_PROTOID_CLIENT] != client_id)
-    {
-        application_ids[APP_PROTOID_CLIENT] = client_id;
-        change_bits.set(APPID_CLIENT_BIT);
-    }
-    if (application_ids[APP_PROTOID_PAYLOAD] != payload_id)
-    {
-        application_ids[APP_PROTOID_PAYLOAD] = payload_id;
-        change_bits.set(APPID_PAYLOAD_BIT);
-    }
-    if (application_ids[APP_PROTOID_MISC] != misc_id)
-    {
-        application_ids[APP_PROTOID_MISC] = misc_id;
-        change_bits.set(APPID_MISC_BIT);
-    }
-}
-
 AppId AppIdSession::pick_service_app_id() const
 {
-    return service.get_id();
+    return get_service_id();
 }
 
 AppId AppIdSession::pick_ss_misc_app_id() const
@@ -167,12 +139,12 @@ AppId AppIdSession::pick_ss_misc_app_id() const
 
 AppId AppIdSession::pick_ss_client_app_id() const
 {
-    return client.get_id();
+    return get_client_id();
 }
 
 AppId AppIdSession::pick_ss_payload_app_id() const
 {
-    return payload.get_id();
+    return get_payload_id();
 }
 
 AppId AppIdSession::pick_ss_referred_payload_app_id() const
@@ -180,36 +152,6 @@ AppId AppIdSession::pick_ss_referred_payload_app_id() const
     return APPID_UT_ID;
 }
 
-void AppIdSession::get_first_stream_app_ids(AppId&, AppId&, AppId&, AppId&) const { }
-
-void AppIdSession::get_first_stream_app_ids(AppId&, AppId&, AppId&) const { }
-
-AppId AppIdSession::get_application_ids_service() const { return APPID_UT_ID; }
-
-AppId AppIdSession::get_application_ids_client(uint32_t stream_index) const
-{
-    if (stream_index < hsessions.size() or stream_index == 0)
-      return APPID_UT_ID;
-
-    return APP_ID_NONE;      
-}
-
-AppId AppIdSession::get_application_ids_payload(uint32_t stream_index) const
-{
-    if (stream_index < hsessions.size() or stream_index == 0)
-      return APPID_UT_ID;
-
-    return APP_ID_NONE;      
-}
-
-AppId AppIdSession::get_application_ids_misc(uint32_t stream_index) const
-{
-    if (stream_index < hsessions.size() or stream_index == 0)
-      return APPID_UT_ID;
-
-    return APP_ID_NONE;      
-}
-
 bool AppIdSession::is_ssl_session_decrypted() const
 {
     return is_session_decrypted;
@@ -225,39 +167,30 @@ AppIdHttpSession* AppIdSession::create_http_session(uint32_t)
     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);
+    api.hsessions.push_back(hsession);
     return hsession;
 }
 
-AppIdHttpSession* AppIdSession::get_http_session(uint32_t stream_index) const
-{
-    if (stream_index < hsessions.size())
-    {
-        return hsessions[stream_index];
-    }
-    return nullptr;
-}
-
 AppIdHttpSession* AppIdSession::get_matching_http_session(uint32_t stream_id) const
 {
-    for (uint32_t stream_index=0; stream_index < hsessions.size(); stream_index++)
+    for (uint32_t stream_index=0; stream_index < api.hsessions.size(); stream_index++)
     {
-        if (stream_id == hsessions[stream_index]->get_http2_stream_id())
-            return hsessions[stream_index];
+        if (stream_id == api.hsessions[stream_index]->get_http2_stream_id())
+            return api.hsessions[stream_index];
     }
     return nullptr;
 }
 
 AppIdDnsSession* AppIdSession::create_dns_session()
 {
-    if ( !dsession )
-        dsession = new MockAppIdDnsSession();
-    return dsession;
+    if ( !api.dsession )
+        api.dsession = new MockAppIdDnsSession();
+    return api.dsession;
 }
 
 AppIdDnsSession* AppIdSession::get_dns_session() const
 {
-    return dsession;
+    return api.dsession;
 }
 
 bool AppIdSession::is_tp_appid_done() const
@@ -270,7 +203,5 @@ bool AppIdSession::is_tp_appid_available() const
     return true;
 }
 
-void AppIdSession::set_application_ids_service(int, AppidChangeBits&) { }
-
 #endif
 
index 0343296447bb2f45369aa9526aa4c06b0374fb12..74366565438e2a059d0cc6f38d47191550cff512 100644 (file)
@@ -37,18 +37,33 @@ AppIdSessionApi* appid_session_api = nullptr;
 static AppIdConfig config;
 static OdpContext odpctxt(config, nullptr);
 
+void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id,
+    AppId misc_id, AppId referred_id, AppidChangeBits& change_bits)
+{
+    api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits);
+}
+
+void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits)
+{
+    api.set_application_ids_service(service_id, change_bits);
+}
+
 TEST_GROUP(appid_session_api)
 {
     void setup() override
     {
+        AppidChangeBits change_bits;
+
         MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
-        mock_session = new AppIdSession(IpProtocol::TCP, nullptr, 1492, dummy_appid_inspector);
-        appid_session_api = new AppIdSessionApi(*mock_session);
+        SfIp ip;
+        mock_session = new AppIdSession(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector);
+        mock_session->set_ss_application_ids(APPID_UT_ID, APPID_UT_ID, APPID_UT_ID,
+            APPID_UT_ID, APPID_UT_ID, change_bits);
     }
 
     void teardown() override
     {
-        delete appid_session_api;
+        delete &mock_session->get_api();
         delete mock_session;
         MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
     }
@@ -56,56 +71,58 @@ TEST_GROUP(appid_session_api)
 
 TEST(appid_session_api, get_service_app_id)
 {
-    AppId id = appid_session_api->get_service_app_id();
+    AppId id = mock_session->get_api().get_service_app_id();
     CHECK_EQUAL(id, APPID_UT_ID);
 }
 
 TEST(appid_session_api, get_misc_app_id)
 {
-    AppId id = appid_session_api->get_misc_app_id();
+    AppId id = mock_session->get_api().get_misc_app_id();
     CHECK_EQUAL(id, APPID_UT_ID);
-    id = appid_session_api->get_misc_app_id(0);
+    id = mock_session->get_api().get_misc_app_id(0);
     CHECK_EQUAL(APPID_UT_ID, id);
-    id = appid_session_api->get_misc_app_id(3);
+    id = mock_session->get_api().get_misc_app_id(3);
     CHECK_EQUAL(APP_ID_NONE, id);
 }
 
 TEST(appid_session_api, get_client_app_id)
 {
-    AppId id = appid_session_api->get_client_app_id();
+    AppId id = mock_session->get_api().get_client_app_id();
     CHECK_EQUAL(id, APPID_UT_ID);
-    id = appid_session_api->get_client_app_id(0);
+    id = mock_session->get_api().get_client_app_id(0);
     CHECK_EQUAL(APPID_UT_ID, id);
-    id = appid_session_api->get_client_app_id(3);
+    id = mock_session->get_api().get_client_app_id(3);
     CHECK_EQUAL(APP_ID_NONE, id);
 }
 
 TEST(appid_session_api, get_payload_app_id)
 {
-    AppId id = appid_session_api->get_payload_app_id();
+    AppId id = mock_session->get_api().get_payload_app_id();
     CHECK_EQUAL(id, APPID_UT_ID);
-    id = appid_session_api->get_payload_app_id(0);
+    id = mock_session->get_api().get_payload_app_id(0);
     CHECK_EQUAL(APPID_UT_ID, id);
-    id = appid_session_api->get_payload_app_id(2);
+    id = mock_session->get_api().get_payload_app_id(2);
     CHECK_EQUAL(APP_ID_NONE, id);
 }
 
 TEST(appid_session_api, get_referred_app_id)
 {
-    AppId id = appid_session_api->get_referred_app_id();
+    AppId id = mock_session->get_api().get_referred_app_id();
     CHECK_EQUAL(id, APPID_UT_ID);
-    id = appid_session_api->get_payload_app_id(0);
+    id = mock_session->get_api().get_referred_app_id(0);
     CHECK_EQUAL(APPID_UT_ID, id);
-    id = appid_session_api->get_payload_app_id(2);
+    id = mock_session->get_api().get_referred_app_id(2);
     CHECK_EQUAL(APP_ID_NONE, id);
 }
 
 TEST(appid_session_api, get_tls_host)
 {
     AppidChangeBits change_bits;
+    change_bits.set(APPID_TLSHOST_BIT);
     char* host = snort_strdup(APPID_UT_TLS_HOST);
     mock_session->tsession->set_tls_host(host, 0, change_bits);
-    const char* val = appid_session_api->get_tls_host();
+    mock_session->set_tls_host(change_bits);
+    const char* val = mock_session->get_api().get_tls_host();
     STRCMP_EQUAL(val, APPID_UT_TLS_HOST);
 }
 
@@ -115,90 +132,91 @@ TEST(appid_session_api, get_initiator_ip)
 
     expected_ip.pton(AF_INET, APPID_UT_INITIATOR_IP_ADDR);
 
-    const SfIp* val = appid_session_api->get_initiator_ip();
+    const SfIp* val = mock_session->get_api().get_initiator_ip();
     CHECK_TRUE(val->fast_eq4(expected_ip));
 }
 
 TEST(appid_session_api, is_appid_inspecting_session)
 {
     mock_session->service_disco_state = APPID_DISCO_STATE_STATEFUL;
-    bool val = appid_session_api->is_appid_inspecting_session();
+    bool val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(val);
     mock_session->service_disco_state = APPID_DISCO_STATE_FINISHED;
     mock_session->set_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_CONTINUE);
-    val = appid_session_api->is_appid_inspecting_session();
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(val);
     mock_session->clear_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_CONTINUE);
     mock_session->set_session_flags(APPID_SESSION_ENCRYPTED);
-    val = appid_session_api->is_appid_inspecting_session();
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(val);
     mock_session->set_session_flags(APPID_SESSION_DECRYPTED);
     mock_session->session_packet_count = SSL_WHITELIST_PKT_LIMIT;
-    val = appid_session_api->is_appid_inspecting_session();
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(val);
 
     // 2nd if in is_appid_inspecting_session
     mock_session->clear_session_flags(APPID_SESSION_DECRYPTED);
     mock_session->set_session_flags(APPID_SESSION_CLIENT_DETECTED);
-    val = appid_session_api->is_appid_inspecting_session();
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(!val);
     mock_session->set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
-    val = appid_session_api->is_appid_inspecting_session();
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(val);
     mock_session->client_disco_state = APPID_DISCO_STATE_FINISHED;
-    val = appid_session_api->is_appid_inspecting_session();
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(!val);
 
     // 3rd if in is_appid_inspecting_session
     mock_session->session_packet_count = MAX_SFTP_PACKET_COUNT;
-    val = appid_session_api->is_appid_inspecting_session();
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(!val);
-    mock_session->payload.set_id(APP_ID_SFTP);
-    val = appid_session_api->is_appid_inspecting_session();
+    mock_session->set_payload_id(APP_ID_SFTP);
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(!val);
     mock_session->session_packet_count = MAX_SFTP_PACKET_COUNT - 1;
-    val = appid_session_api->is_appid_inspecting_session();
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(!val);
-    mock_session->payload.set_id(APP_ID_NONE);
-    mock_session->set_tp_app_id(APP_ID_SSH);
-    val = appid_session_api->is_appid_inspecting_session();
+    mock_session->set_payload_id(APP_ID_NONE);
+    AppidChangeBits change_bits;
+    mock_session->set_application_ids_service(APP_ID_SSH, change_bits);
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(val);
 
     // 4th if in is_appid_inspecting_session
-    mock_session->set_tp_app_id(APP_ID_NONE);
+    mock_session->set_application_ids_service(APP_ID_NONE, change_bits);
     mock_session->ctxt.get_odp_ctxt().check_host_port_app_cache = true;
-    val = appid_session_api->is_appid_inspecting_session();
+    val = mock_session->get_api().is_appid_inspecting_session();
     CHECK_TRUE(val);
 }
 
 TEST(appid_session_api, is_appid_available)
 {
     bool val;
-    val = appid_session_api->is_appid_available();
+    val = mock_session->get_api().is_appid_available();
     CHECK_TRUE(val);
     mock_session->set_session_flags(APPID_SESSION_NO_TPI);
-    val = appid_session_api->is_appid_available();
+    val = mock_session->get_api().is_appid_available();
     CHECK_TRUE(val);
 }
 
 TEST(appid_session_api, get_client_version)
 {
     const char* val;
-    val = appid_session_api->get_client_version();
+    val = mock_session->get_api().get_client_version();
     STRCMP_EQUAL(val, APPID_UT_CLIENT_VERSION);
     mock_session->create_http_session();
-    val = appid_session_api->get_client_version(0);
+    val = mock_session->get_api().get_client_version(0);
     STRCMP_EQUAL(APPID_UT_CLIENT_VERSION, val);
-    val = appid_session_api->get_client_version(2);
+    val = mock_session->get_api().get_client_version(2);
     STRCMP_EQUAL(nullptr, val);
 }
 TEST(appid_session_api, get_http_session)
 {
     const AppIdHttpSession* val;
     mock_session->create_http_session();
-    val = appid_session_api->get_http_session();
+    val = mock_session->get_api().get_http_session();
     CHECK_TRUE(val != nullptr);
-    val = appid_session_api->get_http_session(2);
+    val = mock_session->get_api().get_http_session(2);
     CHECK_TRUE(val == nullptr);
 }
 TEST(appid_session_api, get_appid_session_attribute)
@@ -209,17 +227,17 @@ TEST(appid_session_api, get_appid_session_attribute)
     {
         flags <<= i;
         mock_session->set_session_flags(flags);
-        uint64_t fv = appid_session_api->get_appid_session_attribute(flags);
+        uint64_t fv = mock_session->get_api().get_appid_session_attribute(flags);
         CHECK_TRUE((fv & flags) == flags);
         mock_session->clear_session_flags(flags);
-        fv = appid_session_api->get_appid_session_attribute(flags);
+        fv = mock_session->get_api().get_appid_session_attribute(flags);
         CHECK_TRUE((fv & flags) == 0);
     }
 }
 
 TEST(appid_session_api, appid_dns_api)
 {
-    const AppIdDnsSession* dsession = appid_session_api->get_dns_session();
+    const AppIdDnsSession* dsession = mock_session->get_api().get_dns_session();
 
     const char* val = dsession->get_host();
     STRCMP_EQUAL(val, APPID_ID_UT_DNS_HOST);
@@ -246,26 +264,28 @@ TEST(appid_session_api, appid_dns_api)
 TEST(appid_session_api, is_http_inspection_done)
 {
     bool val;
-    val = appid_session_api->is_http_inspection_done();
+    val = mock_session->get_api().is_http_inspection_done();
     CHECK_TRUE(val);
     mock_session->service_disco_state = APPID_DISCO_STATE_FINISHED;
     mock_session->set_session_flags(APPID_SESSION_SSL_SESSION);
-    val = appid_session_api->is_http_inspection_done();
+    val = mock_session->get_api().is_http_inspection_done();
     CHECK_TRUE(val);
     AppidChangeBits change_bits;
     mock_session->service_disco_state = APPID_DISCO_STATE_STATEFUL;
     mock_session->set_session_flags(APPID_SESSION_SSL_SESSION);
-    val = appid_session_api->is_http_inspection_done();
+    val = mock_session->get_api().is_http_inspection_done();
     CHECK_FALSE(val);
     mock_session->service_disco_state = APPID_DISCO_STATE_STATEFUL;
     mock_session->set_session_flags(APPID_SESSION_SSL_SESSION);
     char* host = snort_strdup(APPID_UT_TLS_HOST);
     mock_session->tsession->set_tls_host(host, 0, change_bits);
-    val = appid_session_api->is_http_inspection_done();
+    change_bits.set(APPID_TLSHOST_BIT);
+    mock_session->set_tls_host(change_bits);
+    val = mock_session->get_api().is_http_inspection_done();
     CHECK_TRUE(val);
     mock_session->service_disco_state = APPID_DISCO_STATE_FINISHED;
     mock_session->set_session_flags(APPID_SESSION_SSL_SESSION);
-    val = appid_session_api->is_http_inspection_done();
+    val = mock_session->get_api().is_http_inspection_done();
     CHECK_TRUE(val);
 }
 
index d0848d87e6f01783a68efa9656e27ace42b0b316..df18b09fc52d4bb6f17c5f31689234e10b47212c 100644 (file)
@@ -82,8 +82,8 @@ void PayloadAppDescriptor::update_stats(AppId) {}
 AppIdConfig::~AppIdConfig() { }
 AppIdConfig stub_config;
 AppIdContext stub_ctxt(stub_config);
-AppIdSession::AppIdSession(IpProtocol, const SfIp*, uint16_t, AppIdInspector&)
-    : FlowData(0), ctxt(stub_ctxt) {}
+AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector&)
+    : FlowData(0), ctxt(stub_ctxt), api(*(new AppIdSessionApi(this, *ip)))  { }
 AppIdSession::~AppIdSession() = default;
 AppIdDiscovery::AppIdDiscovery() {}
 AppIdDiscovery::~AppIdDiscovery() {}
@@ -150,17 +150,19 @@ TEST(service_state_tests, set_service_id_failed)
 {
     ServiceDiscoveryState sds;
     AppIdInspector inspector;
-    AppIdSession asd(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
     SfIp client_ip;
+    client_ip.set("1.2.3.4");
+    AppIdSession asd(IpProtocol::PROTO_NOT_SET, &client_ip, 0, inspector);
 
     // Testing 3+ failures to exceed STATE_ID_NEEDED_DUPE_DETRACT_COUNT with valid_count = 0
-    client_ip.set("1.2.3.4");
     sds.set_state(ServiceState::VALID);
     sds.set_service_id_failed(asd, &client_ip, 0);
     sds.set_service_id_failed(asd, &client_ip, 0);
     sds.set_service_id_failed(asd, &client_ip, 0);
     sds.set_service_id_failed(asd, &client_ip, 0);
     CHECK_TRUE(sds.get_state() == ServiceState::SEARCHING_PORT_PATTERN);
+
+    delete &asd.get_api();
 }
 
 
@@ -168,11 +170,11 @@ TEST(service_state_tests, set_service_id_failed_with_valid)
 {
     ServiceDiscoveryState sds;
     AppIdInspector inspector;
-    AppIdSession asd(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
     SfIp client_ip;
+    client_ip.set("1.2.3.4");
+    AppIdSession asd(IpProtocol::PROTO_NOT_SET, &client_ip, 0, inspector);
 
     // Testing 3+ failures to exceed STATE_ID_NEEDED_DUPE_DETRACT_COUNT with valid_count > 1
-    client_ip.set("1.2.3.4");
     sds.set_state(ServiceState::VALID);
     sds.set_service_id_valid(0);
     sds.set_service_id_valid(0);
@@ -181,6 +183,8 @@ TEST(service_state_tests, set_service_id_failed_with_valid)
     sds.set_service_id_failed(asd, &client_ip, 0);
     sds.set_service_id_failed(asd, &client_ip, 0);
     CHECK_TRUE(sds.get_state() == ServiceState::VALID);
+
+    delete &asd.get_api();
 }
 
 TEST(service_state_tests, appid_service_state_key_comparison_test)
index 7b485a95f049b99711b702709d3874e06eb30983..650b908ec5452481f994cdff1e7d36b478ea6f35 100644 (file)
@@ -362,7 +362,7 @@ static inline void process_rtmp(AppIdSession& asd,
     }
 
     if ( ( asd.scan_flags & SCAN_HTTP_USER_AGENT_FLAG ) and
-         asd.client.get_id() <= APP_ID_NONE and
+         asd.get_client_id() <= APP_ID_NONE and
          ( field = hsession->get_field(REQ_AGENT_FID) ) and
          ( size = attribute_data.http_request_user_agent_end() -
            attribute_data.http_request_user_agent_begin() ) > 0 )
@@ -376,7 +376,7 @@ static inline void process_rtmp(AppIdSession& asd,
         hsession->set_client(client_id, change_bits, "User Agent", version);
 
         // do not overwrite a previously-set service
-        if ( asd.service.get_id() <= APP_ID_NONE )
+        if ( asd.get_service_id() <= APP_ID_NONE )
             asd.set_service_appid_data(service_id, change_bits);
 
         asd.scan_flags |= ~SCAN_HTTP_USER_AGENT_FLAG;
@@ -402,7 +402,7 @@ static inline void process_rtmp(AppIdSession& asd,
                 // do not overwrite a previously-set client or service
                 if ( hsession->client.get_id() <= APP_ID_NONE )
                     hsession->set_client(client_id, change_bits, "URL");
-                if ( asd.service.get_id() <= APP_ID_NONE )
+                if ( asd.get_service_id() <= APP_ID_NONE )
                     asd.set_service_appid_data(service_id, change_bits);
 
                 // DO overwrite a previously-set payload
@@ -449,7 +449,7 @@ static inline void process_ssl(AppIdSession& asd,
     if (!asd.tsession)
         asd.tsession = new TlsSession();
 
-    if (!asd.client.get_id())
+    if (!asd.get_client_id())
         asd.set_client_appid_data(APP_ID_SSL_CLIENT, change_bits);
 
     reinspect_ssl_appid = check_ssl_appid_for_reinspect(tmpAppId, asd.ctxt.get_odp_ctxt());
@@ -490,7 +490,7 @@ static inline void process_ftp_control(AppIdSession& asd,
     if (!asd.ctxt.get_odp_ctxt().ftp_userid_disabled &&
         (field=attribute_data.ftp_command_user()) != nullptr)
     {
-        asd.client.update_user(APP_ID_FTP_CONTROL, field->c_str());
+        asd.set_client_user(APP_ID_FTP_CONTROL, field->c_str());
         asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED);
         // attribute_data.ftpCommandUser = nullptr;
     }
@@ -508,7 +508,7 @@ static inline void process_quic(AppIdSession& asd,
         if ( appidDebug->is_active() )
             LogMessage("AppIdDbg %s Flow is QUIC\n", appidDebug->get_debug_session());
         asd.tsession->set_tls_host(field->c_str(), field->size(), change_bits);
-        if ( asd.service.get_id() <= APP_ID_NONE )
+        if ( asd.get_service_id() <= APP_ID_NONE )
             asd.set_service_appid_data(APP_ID_QUIC, change_bits);
     }
 }
@@ -517,8 +517,8 @@ static inline void process_third_party_results(AppIdSession& asd, int confidence
     const vector<AppId>& proto_list, ThirdPartyAppIDAttributeData& attribute_data,
     AppidChangeBits& change_bits)
 {
-    if ( asd.payload.get_id() == APP_ID_NONE and contains(proto_list, APP_ID_EXCHANGE) )
-        asd.payload.set_id(APP_ID_EXCHANGE);
+    if ( asd.get_payload_id() == APP_ID_NONE and contains(proto_list, APP_ID_EXCHANGE) )
+        asd.set_payload_id(APP_ID_EXCHANGE);
 
     if ( contains(proto_list, APP_ID_HTTP) )
     {
@@ -558,7 +558,7 @@ static inline void check_terminate_tp_module(AppIdSession& asd, uint16_t tpPktCo
 
     if ((tpPktCount >= asd.ctxt.get_odp_ctxt().max_tp_flow_depth) ||
         (asd.get_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) ==
-        (APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) &&
+        (APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) && hsession &&
         hsession->get_field(REQ_URI_FID) &&
         (!hsession->get_chp_candidate() || hsession->is_chp_finished())))
     {
@@ -566,8 +566,8 @@ static inline void check_terminate_tp_module(AppIdSession& asd, uint16_t tpPktCo
             asd.set_tp_app_id(APP_ID_UNKNOWN);
 
         if ( !hsession and asd.service_disco_state == APPID_DISCO_STATE_FINISHED and
-            asd.payload.get_id() == APP_ID_NONE )
-            asd.payload.set_id(APP_ID_UNKNOWN);
+            asd.get_payload_id() == APP_ID_NONE )
+            asd.set_payload_id(APP_ID_UNKNOWN);
 
         if ( hsession and asd.service_disco_state == APPID_DISCO_STATE_FINISHED and
             hsession->payload.get_id() == APP_ID_NONE )
@@ -610,13 +610,13 @@ bool do_tp_discovery(ThirdPartyAppIdContext& tp_appid_ctxt, AppIdSession& asd, I
 {
     AppId tp_app_id = asd.get_tp_app_id();
 
-    if (tp_app_id == APP_ID_SSH && asd.payload.get_id() != APP_ID_SFTP &&
+    if (tp_app_id == APP_ID_SSH && asd.get_payload_id() != APP_ID_SFTP &&
         asd.session_packet_count >= MIN_SFTP_PACKET_COUNT &&
         asd.session_packet_count < MAX_SFTP_PACKET_COUNT)
     {
         if ( p->ptrs.ip_api.tos() == 8 )
         {
-            asd.payload.set_id(APP_ID_SFTP);
+            asd.set_payload_id(APP_ID_SFTP);
             if (appidDebug->is_active())
                 LogMessage("AppIdDbg %s Payload is SFTP\n", appidDebug->get_debug_session());
         }
@@ -698,7 +698,7 @@ bool do_tp_discovery(ThirdPartyAppIdContext& tp_appid_ctxt, AppIdSession& asd, I
         if (hsession)
             hsession->set_client(tp_app_id, change_bits, "Third Party");
         else
-            asd.client.set_id(*p, asd, direction, tp_app_id, change_bits);
+            asd.set_client_id(*p, direction, tp_app_id, change_bits);
     }
 
     if ( app_info_flags & APPINFO_FLAG_IGNORE )
@@ -777,15 +777,15 @@ bool do_tp_discovery(ThirdPartyAppIdContext& tp_appid_ctxt, AppIdSession& asd, I
                 tp_app_id = portAppId;
                 //SSL policy determines IMAPS/POP3S etc before appId sees first server
                 // packet
-                asd.service.set_port_service_id(portAppId);
+                asd.set_port_service_id(portAppId);
                 if (appidDebug->is_active())
                 {
                     const char *service_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(tp_app_id);
-                    const char *port_service_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(asd.service.get_port_service_id());
+                    const char *port_service_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(asd.get_port_service_id());
                     LogMessage("AppIdDbg %s SSL is service %s (%d), portServiceAppId %s (%d)\n",
                         appidDebug->get_debug_session(),
                         service_name ? service_name : "unknown", tp_app_id,
-                        port_service_name ? port_service_name : "unknown", asd.service.get_port_service_id());
+                        port_service_name ? port_service_name : "unknown", asd.get_port_service_id());
                 }
             }
             else
@@ -802,7 +802,7 @@ bool do_tp_discovery(ThirdPartyAppIdContext& tp_appid_ctxt, AppIdSession& asd, I
             }
             snort_app_id = APP_ID_SSL;
         }
-        else if (asd.service.get_id() == APP_ID_QUIC)
+        else if (asd.get_service_id() == APP_ID_QUIC)
             asd.set_tp_payload_app_id(*p, direction, tp_app_id, change_bits);
         else
         {
index 9d661aee35abb95ee27a36ae3964e6f227aedaf6..2f0d7659fe508988b326f5ac583caa8fcfb824d8 100644 (file)
@@ -38,6 +38,7 @@ namespace snort
 enum AppidChangeBit
 {
     APPID_CREATED_BIT = 0,
+    APPID_RESET_BIT,
 
     // id
     APPID_SERVICE_BIT,
@@ -68,6 +69,8 @@ inline void change_bits_to_string(AppidChangeBits& change_bits, std::string& str
 
     if (change_bits.test(APPID_CREATED_BIT))
         --n? str.append("created, ") : str.append("created");
+    if (change_bits.test(APPID_RESET_BIT))
+        --n? str.append("reset, ") : str.append("reset");
     if (change_bits.test(APPID_SERVICE_BIT))
         --n? str.append("service, ") : str.append("service");
     if (change_bits.test(APPID_CLIENT_BIT))