]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3606: appid: service, client and payload detection by lua detectors...
authorSreeja Athirkandathil Narayanan (sathirka) <sathirka@cisco.com>
Wed, 9 Nov 2022 18:00:40 +0000 (18:00 +0000)
committerSreeja Athirkandathil Narayanan (sathirka) <sathirka@cisco.com>
Wed, 9 Nov 2022 18:00:40 +0000 (18:00 +0000)
Merge in SNORT/snort3 from ~UMASHARM/snort3:navl_fix to master

Squashed commit of the following:

commit 94a51e06a4c12f0732d200e9f26a97e485dfe60c
Author: Umang Sharma <umasharm@cisco.com>
Date:   Wed Sep 28 08:34:11 2022 -0400

    appid: service, client and payload detection by lua detectors and third-party when first packet re-inspection is enabled

src/network_inspectors/appid/appid_config.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_discovery.h
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/service_plugins/service_discovery.cc

index b61f596cef2cf0218ebc8f13d28c516cd25c396c..7403db99c4bf198aae31bf00e2ecbf114dca95e3 100644 (file)
@@ -115,6 +115,9 @@ public:
     bool ftp_userid_disabled = false;
     bool chp_body_collection_disabled = false;
     bool need_reinspection = false;
+    AppId first_pkt_service_id = 0;
+    AppId first_pkt_payload_id = 0;
+    AppId first_pkt_client_id = 0;
     uint32_t chp_body_collection_max = 0;
     uint32_t rtmp_max_packets = 15;
     uint32_t max_tp_flow_depth = 5;
@@ -126,6 +129,7 @@ public:
     uint64_t max_bytes_before_service_fail = MIN_MAX_BYTES_BEFORE_SERVICE_FAIL;
     uint16_t max_packet_before_service_fail = MIN_MAX_PKTS_BEFORE_SERVICE_FAIL;
     uint16_t max_packet_service_fail_ignore_bytes = MIN_MAX_PKT_BEFORE_SERVICE_FAIL_IGNORE_BYTES;
+    FirstPktAppIdDiscovered first_pkt_appid_prefix = NO_APPID_FOUND;
 
     OdpContext(const AppIdConfig&, snort::SnortConfig*);
     void initialize(AppIdInspector& inspector);
index 247a6ccf8fc34362c962dfb19bde8234a7f66bd7..7b03355b3adbc6ab882929c19291545a3ed54bac 100644 (file)
@@ -567,70 +567,85 @@ bool AppIdDiscovery::detect_on_first_pkt(Packet* p, AppIdSession& asd,
     hv = asd.get_odp_ctxt().host_first_pkt_find(ip, port, protocol);
     if (hv)
     {
-        uint32_t appids_found = 0;
         const char *service_app_name = nullptr, *client_app_name = nullptr, *payload_app_name = nullptr;
-        FirstPktAppIdDiscovered appid_prefix = NO_APPID_FOUND;
+        asd.get_odp_ctxt().first_pkt_appid_prefix = NO_APPID_FOUND;
 
         if (hv->client_appId)
         {
             client_id = hv->client_appId;
-            asd.set_client_id(client_id);
             client_app_name = asd.get_odp_ctxt().get_app_info_mgr().get_app_name(client_id);
-            appids_found++;
-            appid_prefix = CLIENT_APPID_FOUND;
+            asd.get_odp_ctxt().first_pkt_client_id = client_id;
+            asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_CLIENT_APPID_FOUND;
         } 
         if (hv->protocol_appId) 
         {
             service_id = hv->protocol_appId;
-            asd.set_service_id(service_id, asd.get_odp_ctxt());
-            asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED);
             service_app_name = asd.get_odp_ctxt().get_app_info_mgr().get_app_name(service_id);
-            appids_found++;
-            appid_prefix = SERVICE_APPID_FOUND;
+            asd.get_odp_ctxt().first_pkt_service_id = service_id;
+
+            if (asd.get_odp_ctxt().first_pkt_appid_prefix == FIRST_CLIENT_APPID_FOUND)
+            {
+                asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_SERVICE_CLIENT_APPID_FOUND;
+            } 
+            else 
+            {
+                asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_SERVICE_APPID_FOUND;
+            }
         }
         if (hv->web_appId) 
         {
             payload_id = hv->web_appId;
-            asd.set_payload_id(payload_id);
             payload_app_name = asd.get_odp_ctxt().get_app_info_mgr().get_app_name(payload_id);
-            appids_found++;
-            if (appid_prefix == CLIENT_APPID_FOUND)
+            asd.get_odp_ctxt().first_pkt_payload_id = payload_id;
+
+            if (asd.get_odp_ctxt().first_pkt_appid_prefix == FIRST_CLIENT_APPID_FOUND)
             {
-                appid_prefix = CLIENT_PAYLOAD_APPID_FOUND;
+                asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_CLIENT_PAYLOAD_APPID_FOUND;
             } 
+            else if (asd.get_odp_ctxt().first_pkt_appid_prefix == FIRST_SERVICE_APPID_FOUND)
+            {
+                asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_SERVICE_PAYLOAD_APPID_FOUND;
+            }   
+            else if (asd.get_odp_ctxt().first_pkt_appid_prefix == FIRST_SERVICE_CLIENT_APPID_FOUND)
+            {
+                asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_ALL_APPID_FOUND;
+            }
             else 
             {
-                appid_prefix = PAYLOAD_APPID_FOUND;
+                asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_PAYLOAD_APPID_FOUND;
             }
         }
         asd.get_odp_ctxt().need_reinspection = hv->reinspect;  
 
-        switch (appids_found
+        switch (asd.get_odp_ctxt().first_pkt_appid_prefix
         {
-        case FIRST_PKT_CACHE_ONE_APPID_FOUND :
-            if (appid_prefix == PAYLOAD_APPID_FOUND) 
-            {
-                service_id = payload_id;
-                asd.set_service_id(service_id, asd.get_odp_ctxt());
-                asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED);
-                service_app_name = asd.get_odp_ctxt().get_app_info_mgr().get_app_name(service_id);
-            } 
-            else if (appid_prefix == CLIENT_APPID_FOUND) 
-            {    
-                service_id = client_id;
-                asd.set_service_id(service_id, asd.get_odp_ctxt());
-                asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED);
-                service_app_name = asd.get_odp_ctxt().get_app_info_mgr().get_app_name(service_id);
-            } 
+        case FIRST_PAYLOAD_APPID_FOUND :
+            service_id = payload_id;
+            service_app_name = asd.get_odp_ctxt().get_app_info_mgr().get_app_name(service_id);
+            asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_SERVICE_PAYLOAD_APPID_FOUND;
+            asd.get_odp_ctxt().first_pkt_service_id = service_id;
             break;
-        case FIRST_PKT_CACHE_TWO_APPIDS_FOUND :
-            if (appid_prefix == CLIENT_PAYLOAD_APPID_FOUND) 
-            {
-                service_id = client_id;
-                asd.set_service_id(service_id, asd.get_odp_ctxt());
-                asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED);
-                service_app_name = asd.get_odp_ctxt().get_app_info_mgr().get_app_name(service_id);
-            } 
+
+        case FIRST_CLIENT_APPID_FOUND :
+            service_id = client_id;
+            service_app_name = asd.get_odp_ctxt().get_app_info_mgr().get_app_name(service_id);
+            asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_SERVICE_CLIENT_APPID_FOUND;
+            asd.get_odp_ctxt().first_pkt_service_id = service_id;
+            break;
+
+        case FIRST_CLIENT_PAYLOAD_APPID_FOUND :
+            service_id = client_id;
+            service_app_name = asd.get_odp_ctxt().get_app_info_mgr().get_app_name(service_id);
+            asd.get_odp_ctxt().first_pkt_appid_prefix = FIRST_ALL_APPID_FOUND;
+            asd.get_odp_ctxt().first_pkt_service_id = service_id;
+            break;
+
+        case NO_APPID_FOUND :
+        case FIRST_SERVICE_APPID_FOUND :
+        case FIRST_SERVICE_PAYLOAD_APPID_FOUND :
+        case FIRST_SERVICE_CLIENT_APPID_FOUND :
+        case FIRST_ALL_APPID_FOUND :
+        default:
             break;
         }
         asd.set_session_flags(APPID_SESSION_FIRST_PKT_CACHE_MATCHED);
@@ -662,11 +677,13 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
     if (asd.get_session_flags(APPID_SESSION_FIRST_PKT_CACHE_MATCHED) and !asd.get_odp_ctxt().need_reinspection) 
     {
        is_discovery_done = true;
+       asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED);
+       asd.client_disco_state = APPID_DISCO_STATE_FINISHED; 
+       asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
        service_id = asd.pick_service_app_id();
        client_id = asd.pick_ss_client_app_id();
        payload_id = asd.pick_ss_payload_app_id(service_id);
-       asd.client_disco_state = APPID_DISCO_STATE_FINISHED; 
-       asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
+       
        return is_discovery_done;
     }  
 
index 7bec32905e9fdb13803790e2cb37d791f6488fec..016f0eb3cb2e458f35c94067d22214bbf5be167f 100644 (file)
@@ -60,17 +60,17 @@ struct Packet;
 #define SCAN_HTTP_URI_FLAG          (1<<9)
 #define SCAN_CERTVIZ_ENABLED_FLAG   (1<<10)
 #define SCAN_SPOOFED_SNI_FLAG       (1<<11)
-#define FIRST_PKT_CACHE_ONE_APPID_FOUND 1
-#define FIRST_PKT_CACHE_TWO_APPIDS_FOUND 2
-#define FIRST_PKT_CACHE_ALL_APPIDS_FOUND 3
 
 enum FirstPktAppIdDiscovered
 {
     NO_APPID_FOUND = 0,
-    CLIENT_APPID_FOUND,
-    SERVICE_APPID_FOUND,
-    PAYLOAD_APPID_FOUND,
-    CLIENT_PAYLOAD_APPID_FOUND
+    FIRST_CLIENT_APPID_FOUND,
+    FIRST_SERVICE_APPID_FOUND,
+    FIRST_PAYLOAD_APPID_FOUND,
+    FIRST_CLIENT_PAYLOAD_APPID_FOUND,
+    FIRST_SERVICE_PAYLOAD_APPID_FOUND,
+    FIRST_SERVICE_CLIENT_APPID_FOUND,
+    FIRST_ALL_APPID_FOUND
 };
 
 class AppIdPatternMatchNode
index fbe7055954571790af63c208a024b795e0bfe18a..4e52d897a266a475b4283d2f3b225e517ac31f3d 100644 (file)
@@ -778,9 +778,13 @@ AppId AppIdSession::pick_service_app_id() const
         {
             if ((rval = api.service.get_id()) > APP_ID_NONE)
                 return rval;
+            else if (odp_ctxt.first_pkt_service_id > APP_ID_NONE)
+                return odp_ctxt.first_pkt_service_id;
             else
                 rval = APP_ID_UNKNOWN;
         }
+        else if (odp_ctxt.first_pkt_service_id > APP_ID_NONE)
+            return odp_ctxt.first_pkt_service_id;
     }
     else
     {
@@ -790,6 +794,9 @@ AppId AppIdSession::pick_service_app_id() const
 
             if (api.service.get_id() > APP_ID_NONE and !deferred)
                 return api.service.get_id();
+            if (odp_ctxt.first_pkt_service_id > APP_ID_NONE)
+                return odp_ctxt.first_pkt_service_id;
+
             if (is_tp_appid_available())
             {
                 if (tp_app_id > APP_ID_NONE)
@@ -804,7 +811,9 @@ AppId AppIdSession::pick_service_app_id() const
         }
         else if (tp_app_id > APP_ID_NONE)
             return tp_app_id;
-    }
+        else if (odp_ctxt.first_pkt_service_id > APP_ID_NONE)
+            return odp_ctxt.first_pkt_service_id;
+    }   
 
     if (client_inferred_service_id > APP_ID_NONE)
         return client_inferred_service_id;
@@ -864,10 +873,29 @@ AppId AppIdSession::pick_ss_client_app_id() const
         return api.client.get_id();
     }
 
+    if (odp_ctxt.first_pkt_client_id > APP_ID_NONE)
+    {
+        api.client.set_eve_client_app_detect_type(CLIENT_APP_DETECT_APPID);
+        return odp_ctxt.first_pkt_client_id;
+    }
+
     api.client.set_eve_client_app_detect_type(CLIENT_APP_DETECT_APPID);
     return encrypted.client_id;
 }
 
+AppId AppIdSession::check_first_pkt_tp_payload_app_id() const
+{
+    if (get_session_flags(APPID_SESSION_FIRST_PKT_CACHE_MATCHED) and 
+        (api.payload.get_id() <= APP_ID_NONE))    
+    {
+        if ((odp_ctxt.first_pkt_payload_id > APP_ID_NONE) and (tp_payload_app_id > APP_ID_NONE))
+        {
+            return tp_payload_app_id;
+        }
+    }
+    return APP_ID_NONE;
+}
+
 AppId AppIdSession::pick_ss_payload_app_id(AppId service_id) const
 {
     if (service_id == APP_ID_HTTP2 or
@@ -884,15 +912,24 @@ AppId AppIdSession::pick_ss_payload_app_id(AppId service_id) const
     {
         if (tmp_id == APP_ID_HTTP_TUNNEL)
         {
-            if (api.payload.get_id() > APP_ID_NONE)
+            AppId first_pkt_payload_appid = check_first_pkt_tp_payload_app_id();
+            if (first_pkt_payload_appid > APP_ID_NONE)
+                return first_pkt_payload_appid;
+            else if (api.payload.get_id() > APP_ID_NONE)
                 return api.payload.get_id();
             else if (tp_payload_app_id > APP_ID_NONE)
                 return tp_payload_app_id;
+            else if (odp_ctxt.first_pkt_payload_id > APP_ID_NONE)
+                return odp_ctxt.first_pkt_payload_id;
         }
         else
             return tmp_id;
     }
 
+    AppId first_pkt_payload_appid = check_first_pkt_tp_payload_app_id();
+    if (first_pkt_payload_appid > APP_ID_NONE)
+        return first_pkt_payload_appid;
+    
     if (api.payload.get_id() > APP_ID_NONE)
         return api.payload.get_id();
 
@@ -902,6 +939,9 @@ AppId AppIdSession::pick_ss_payload_app_id(AppId service_id) const
     if (encrypted.payload_id > APP_ID_NONE)
         return encrypted.payload_id;
 
+    if (odp_ctxt.first_pkt_payload_id > APP_ID_NONE)
+        return odp_ctxt.first_pkt_payload_id;
+
     // APP_ID_UNKNOWN is valid only for HTTP type services
     if (tmp_id == APP_ID_UNKNOWN)
         return tmp_id;
index 6f21da5908a9a0e3dd447621dc6000c37615b9cc..b873ac04ad37a84599357fb721bbfb3ae0064330 100644 (file)
@@ -328,6 +328,7 @@ public:
     AppId pick_ss_misc_app_id() const;
     AppId pick_ss_client_app_id() const;
     AppId pick_ss_payload_app_id() const;
+    AppId check_first_pkt_tp_payload_app_id() const;
     AppId pick_ss_payload_app_id(AppId service_id) const;
     AppId pick_ss_referred_payload_app_id() const;
 
index e3e270077d3ca4ea3ea0963bd6c84473ce319e46..31d3c34775eeb001e2e422679ca285e92e26132f 100644 (file)
@@ -788,7 +788,7 @@ int ServiceDiscovery::fail_service(AppIdSession& asd, const Packet* pkt, AppidSe
 
     /* If we're still working on a port/pattern list of detectors, then ignore
      * individual fails until we're done looking at everything. */
-    if ( !asd.service_detector && !asd.service_candidates.empty() )
+    if ((asd.get_odp_ctxt().first_pkt_service_id > APP_ID_NONE) or (!asd.service_detector && !asd.service_candidates.empty()))
         return APPID_SUCCESS;
 
     asd.set_service_id(APP_ID_NONE, asd.get_odp_ctxt());