]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1863 in SNORT/snort3 from ~STECHEW/snort3:deferred_whitelist...
authorSteve Chew (stechew) <stechew@cisco.com>
Tue, 3 Dec 2019 20:08:48 +0000 (20:08 +0000)
committerSteve Chew (stechew) <stechew@cisco.com>
Tue, 3 Dec 2019 20:08:48 +0000 (20:08 +0000)
Squashed commit of the following:

commit 5a3d0a1cd928695d52cf798cb92fb55186fe1593
Author: Steve Chew <stechew@cisco.com>
Date:   Fri Nov 22 12:18:20 2019 -0500

    flow: Add ability to defer whitelist verdict.

src/flow/flow.h
src/main/analyzer.cc

index 218dfbb5002bede64d73b341a7011445e3d580d4..43548acd7ffe70e95a99d94d02c569e167306cb5 100644 (file)
@@ -153,6 +153,13 @@ struct LwState
     char ignore_direction;
 };
 
+enum DeferredWhitelist {
+    WHITELIST_DEFER_OFF = 0,
+    WHITELIST_DEFER_ON,
+    WHITELIST_DEFER_STARTED,
+    WHITELIST_DEFER_DONE,
+};
+
 // this struct is organized by member size for compactness
 class SO_PUBLIC Flow
 {
@@ -340,6 +347,16 @@ public:
     bool is_hard_expiration()
     { return (ssn_state.session_flags & SSNFLAG_HARD_EXPIRATION) != 0; }
 
+    void set_deferred_whitelist(DeferredWhitelist defer_state)
+    {
+        deferred_whitelist = defer_state;
+    }
+
+    DeferredWhitelist get_deferred_whitelist_state()
+    {
+        return deferred_whitelist;
+    }
+
 public:  // FIXIT-M privatize if possible
     // fields are organized by initialization and size to minimize
     // void space and allow for memset of tail end of struct
@@ -399,6 +416,8 @@ public:  // FIXIT-M privatize if possible
     bool disable_inspect;
     bool trigger_finalize_event;
 
+    DeferredWhitelist deferred_whitelist = WHITELIST_DEFER_OFF;
+
 private:
     void clean();
 };
index 91c6f4715be3963568b830f12af74dc757f6c8be..5d5eb2be44137dd9f9ae96c772d46841ceca6399 100644 (file)
@@ -208,6 +208,52 @@ static bool process_packet(Packet* p)
     return true;
 }
 
+// If necessary, defer returning a WHITELIST until it's safe to do so.
+// While deferring, keep inspection turned on.
+static void handle_deferred_whitelist(Packet* pkt, DAQ_Verdict& verdict)
+{
+    if ( !pkt->flow or pkt->flow->deferred_whitelist == WHITELIST_DEFER_OFF )
+        return;
+
+    if (verdict == DAQ_VERDICT_BLOCK or verdict == DAQ_VERDICT_BLACKLIST )
+    {
+        // A block/blacklist verdict overrides any earlier whitelist.
+        pkt->flow->deferred_whitelist = WHITELIST_DEFER_OFF;
+        return;
+    }
+
+    if ( pkt->flow->deferred_whitelist == WHITELIST_DEFER_ON )
+    {
+        if ( verdict == DAQ_VERDICT_WHITELIST )
+        {
+            verdict = DAQ_VERDICT_PASS;
+            pkt->flow->deferred_whitelist = WHITELIST_DEFER_STARTED;
+            pkt->flow->set_state(Flow::FlowState::INSPECT);
+            pkt->flow->disable_inspect = false;
+        }
+        return;
+    }
+
+    if ( pkt->flow->deferred_whitelist == WHITELIST_DEFER_STARTED)
+    {
+        verdict = DAQ_VERDICT_PASS;
+        pkt->flow->set_state(Flow::FlowState::INSPECT);
+        pkt->flow->disable_inspect = false;
+        return;
+    }
+
+    if ( pkt->flow->deferred_whitelist == WHITELIST_DEFER_DONE )
+    {
+        // Now that we're done deferring, return the WHITELIST that would
+        // have happened earlier.
+        verdict = DAQ_VERDICT_WHITELIST;
+
+        // Turn inspection back off and allow the flow.
+        pkt->flow->set_state(Flow::FlowState::ALLOW);
+        pkt->flow->disable_inspect = true;
+    }
+}
+
 // Finalize DAQ message verdict
 static DAQ_Verdict distill_verdict(Packet* p)
 {
@@ -273,6 +319,8 @@ static DAQ_Verdict distill_verdict(Packet* p)
     else
         verdict = DAQ_VERDICT_PASS;
 
+    handle_deferred_whitelist(p, verdict);
+
     return verdict;
 }