]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2607 in SNORT/snort3 from ~MASHASAN/snort3:user_logins to master
authorMasud Hasan (mashasan) <mashasan@cisco.com>
Thu, 12 Nov 2020 00:14:22 +0000 (00:14 +0000)
committerMasud Hasan (mashasan) <mashasan@cisco.com>
Thu, 12 Nov 2020 00:14:22 +0000 (00:14 +0000)
Squashed commit of the following:

commit 3010559b529e126340058c30dec48457493ddb4a
Author: Masud Hasan <mashasan@cisco.com>
Date:   Sun Nov 8 21:13:23 2020 -0500

    rna: Support user login failure discovery

src/host_tracker/host_tracker.cc
src/host_tracker/host_tracker.h
src/host_tracker/test/host_tracker_test.cc
src/network_inspectors/rna/rna_app_discovery.cc
src/network_inspectors/rna/rna_app_discovery.h
src/network_inspectors/rna/rna_logger.cc
src/network_inspectors/rna/rna_logger_common.h

index 7d5f1662f9ea4f45a89c0da25cb793188bc8bbeb..8a3322ee24d2a64e43c065f1527b67a131cb7f91 100644 (file)
@@ -32,6 +32,9 @@
 using namespace snort;
 using namespace std;
 
+#define USER_LOGIN_SUCCESS 1
+#define USER_LOGIN_FAILURE 2
+
 THREAD_LOCAL struct HostTrackerStats host_tracker_stats;
 
 const uint8_t snort::zero_mac[MAC_SIZE] = {0, 0, 0, 0, 0, 0};
@@ -564,6 +567,8 @@ HostApplication* HostTracker::find_and_add_service_no_lock(Port port, IpProtocol
         available->last_seen = lseen;
         available->inferred_appid = false;
         available->user[0] = '\0';
+        available->user_login = 0;
+        available->banner_updated = false;
         available->visibility = true;
         return available;
     }
@@ -709,7 +714,7 @@ bool HostTracker::update_service_banner(Port port, IpProtocol proto)
 }
 
 bool HostTracker::update_service_user(Port port, IpProtocol proto, const char* user,
-    uint32_t lseen, uint16_t max_services)
+    uint32_t lseen, uint16_t max_services, bool success)
 {
     host_tracker_stats.service_finds++;
     bool is_new = false;
@@ -725,9 +730,24 @@ bool HostTracker::update_service_user(Port port, IpProtocol proto, const char* u
     {
         strncpy(ha->user, user, INFO_SIZE);
         ha->user[INFO_SIZE-1] = '\0';
+        ha->user_login = success ? USER_LOGIN_SUCCESS : USER_LOGIN_FAILURE;
+        return true;
+    }
+
+    if ( success )
+    {
+        if ( ha->user_login & USER_LOGIN_SUCCESS )
+            return false;
+        ha->user_login |= USER_LOGIN_SUCCESS;
+        return true;
+    }
+    else
+    {
+        if ( ha->user_login & USER_LOGIN_FAILURE )
+            return false;
+        ha->user_login |= USER_LOGIN_FAILURE;
         return true;
     }
-    return false;
 }
 
 void HostTracker::remove_inferred_services()
index deb4fe2438a52c8b70757259420271ff3f9844da..e8c59329737e0429886d7a93ce7e280b8a8c6606 100644 (file)
@@ -118,6 +118,7 @@ struct HostApplication
     uint32_t hits = 0;
     uint32_t last_seen = 0;
     char user[INFO_SIZE] = { '\0' };
+    uint8_t user_login = 0;
     bool banner_updated = false;
     size_t num_visible_payloads = 0;
 
@@ -325,7 +326,7 @@ public:
         uint16_t max_info);
     bool update_service_banner(Port, IpProtocol);
     bool update_service_user(Port, IpProtocol, const char* username, uint32_t lseen,
-        uint16_t max_services);
+        uint16_t max_services, bool success);
     void remove_inferred_services();
 
     size_t get_client_count();
index cacc64faa9c99b3d7836257b8cb2a391241abc0a..b852084938402db12f0f14d470f4694ed35541bc 100644 (file)
@@ -288,6 +288,26 @@ TEST(host_tracker, client_payload_max_payloads_test)
     CHECK(clients.size() == 1);
 }
 
+// Test user login information updates for service
+TEST(host_tracker, update_service_user_test)
+{
+    HostTracker ht;
+
+    CHECK(ht.add_service(110, IpProtocol::TCP, 788, false) == true);
+
+    // The first discoveries of both login success and login failure are updated
+    CHECK(ht.update_service_user(110, IpProtocol::TCP, "user1", 1, 1, true) == true);
+    CHECK(ht.update_service_user(110, IpProtocol::TCP, "user1", 1, 1, false) == true);
+
+    // Subsequent discoveries for login success and login failure are not updated
+    CHECK(ht.update_service_user(110, IpProtocol::TCP, "user1", 1, 1, true) == false);
+    CHECK(ht.update_service_user(110, IpProtocol::TCP, "user1", 1, 1, false) == false);
+
+    // Discoveries for a new user name are updated
+    CHECK(ht.update_service_user(110, IpProtocol::TCP, "user2", 1, 1, false) == true);
+    CHECK(ht.update_service_user(110, IpProtocol::TCP, "user2", 1, 1, true) == true);
+}
+
 //  Test copying data and deleting copied list
 TEST(host_tracker, copy_data_test)
 {
index c50fe73fa43751f74d1ffae6dbe842a709e20b65..fd8a17a7e741a48334243d30439fa61669a0adc2 100644 (file)
@@ -126,15 +126,14 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
         discover_banner(p, proto, ht, &p->flow->server_ip, src_mac, logger, service);
     }
 
-    // Appid supports only login success event. Change checks once login failure and
-    // logoff is supported
+    // Appid supports login success/failure events, but not logoff event.
     if ( appid_change_bits[APPID_USER_INFO_BIT] and filter.is_user_monitored(p) )
     {
-        bool login;
-        const char* username = appid_session_api.get_user_info(service, login);
-        if ( login and service > APP_ID_NONE and username and *username )
+        bool login_success;
+        const char* username = appid_session_api.get_user_info(service, login_success);
+        if ( service > APP_ID_NONE and username and *username )
             discover_user(p, ht, (const struct in6_addr*) p->ptrs.ip_api.get_dst()->get_ip6_ptr(),
-                logger, username, service, proto, conf);
+                logger, username, service, proto, conf, login_success);
     }
 
     if ( p->is_from_client() and ( appid_change_bits[APPID_HOST_BIT] or
@@ -318,13 +317,13 @@ void RnaAppDiscovery::discover_client(const Packet* p, RnaTracker& rt,
 
 void RnaAppDiscovery::discover_user(const Packet* p, RnaTracker& rt,
     const struct in6_addr* ip, RnaLogger& logger, const char* username,
-    AppId service, IpProtocol proto, RnaConfig* conf)
+    AppId service, IpProtocol proto, RnaConfig* conf, bool login_success)
 {
     if ( rt->update_service_user(p->flow->server_port, proto, username,
-        (uint32_t) packet_time(), conf ? conf->max_host_services : 0) )
+        (uint32_t) packet_time(), conf ? conf->max_host_services : 0, login_success) )
     {
-        logger.log(RUA_EVENT, CHANGE_USER_LOGIN, p, &rt, ip, username,
-            service, (uint32_t) packet_time());
+        logger.log(RUA_EVENT, login_success ? CHANGE_USER_LOGIN : FAILED_USER_LOGIN,
+            p, &rt, ip, username, service, (uint32_t) packet_time());
     }
 }
 
index dbbefac35f9a3d8b4d7dc48c4103083be09e6c8c..02a3d7020b1bdd3916a5b22bb1d4ae62035583be 100644 (file)
@@ -41,7 +41,7 @@ public:
         RnaLogger&, const char*, AppId client, AppId service);
 
     static void discover_user(const snort::Packet*, RnaTracker&, const struct in6_addr*,
-        RnaLogger&, const char* username, AppId, IpProtocol, RnaConfig*);
+        RnaLogger&, const char* username, AppId, IpProtocol, RnaConfig*, bool);
 
     static void discover_banner(const snort::Packet*, IpProtocol, RnaTracker&,
         const snort::SfIp*, const uint8_t* mac, RnaLogger&, AppId);
index 46fc35939abb16b6ad04027759caf59014b3e135..e8ce65b4bd68903ab81c51b0e38bf0c6ae9fe06f 100644 (file)
@@ -44,6 +44,7 @@
 #endif
 
 using namespace snort;
+using namespace std;
 
 #ifdef DEBUG_MSGS
 static inline void rna_logger_message(const RnaLoggerEvent& rle, const Packet* p)
@@ -95,11 +96,18 @@ static inline void rna_logger_message(const RnaLoggerEvent& rle, const Packet* p
                 debug_logf(rna_trace, p, "RNA Banner log: true\n");
         }
 
-        if ( rle.user )
+        if ( rle.user and *rle.user )
         {
-            if ( rle.user and *rle.user )
-                debug_logf(rna_trace, p,
-                    "RNA user login: service %u, user name %s\n", rle.appid, rle.user);
+            string login_str;
+            if ( rle.type == RUA_EVENT )
+            {
+                if ( rle.subtype == CHANGE_USER_LOGIN )
+                    login_str = " login success";
+                else if ( rle.subtype == FAILED_USER_LOGIN )
+                    login_str = " login failure";
+            }
+            debug_logf(rna_trace, nullptr, "RNA user%s: service %u, user name %s\n",
+                login_str.c_str(), rle.appid, rle.user);
         }
     }
     else
index 38bdfbfd5010fa1e372a6bbc452504e5cf98c44b..aee6625f803d2ea62573200cee25ad7b5d17173f 100644 (file)
@@ -44,5 +44,6 @@
 
 #define RUA_EVENT         1004
     #define CHANGE_USER_LOGIN    2
+    #define FAILED_USER_LOGIN    5
 
 #endif