]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2223 in SNORT/snort3 from ~RDEMPSTE/snort3:direction_prevent_whit...
authorRon Dempster (rdempste) <rdempste@cisco.com>
Tue, 2 Jun 2020 17:57:50 +0000 (17:57 +0000)
committerRon Dempster (rdempste) <rdempste@cisco.com>
Tue, 2 Jun 2020 17:57:50 +0000 (17:57 +0000)
Squashed commit of the following:

commit 8b95f26e28f56d5815c75c6cd42f163e3f3f85ef
Author: rdempste <rdempste@cisco.com>
Date:   Mon Jun 1 16:32:28 2020 -0400

    active: add a facility to prevent a DAQ whitelist verdict

commit 63fb0a693a3cea1ff45f1931d01e3b120dc4ab7a
Author: rdempste <rdempste@cisco.com>
Date:   Wed May 6 15:46:48 2020 -0400

    packet: add client and server direction methods that use the client initiator flow flag

commit 86bfdc7f46edd0f359e0196b951eb404fafd22b8
Author: rdempste <rdempste@cisco.com>
Date:   Thu May 7 17:36:36 2020 -0400

    flow: make client_initiated flag depend on the DAQ reverse flow flag

src/flow/flow.h
src/flow/flow_control.cc
src/main/analyzer.cc
src/main/test/CMakeLists.txt
src/main/test/distill_verdict_test.cc [new file with mode: 0644]
src/main/test/stubs.h [new file with mode: 0644]
src/network_inspectors/reputation/reputation_inspect.cc
src/packet_io/active.cc
src/packet_io/active.h
src/protocols/packet.h
tools/u2spewfoo/u2spewfoo.cc

index b0a7c11ee32aba678e6bfa5de1d77e7fcffb9a8d..f093d79787b403093702af5e20b227d93e1ed959 100644 (file)
@@ -441,7 +441,8 @@ public:  // FIXIT-M privatize if possible
 
     struct
     {
-        bool client_initiated : 1;
+        bool client_initiated : 1; // Set if the first packet on the flow was from the side that is currently
+                                   // considered to be the client
         bool disable_inspect : 1;
         bool reputation_src_dest : 1;
         bool reputation_blacklist : 1;
index d32204d17ba08029a55e14303802d836308c8b96..3735a7519480b94bace450b828841d543e49cd82 100644 (file)
@@ -403,8 +403,14 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
     last_pkt_type = p->type();
     preemptive_cleanup();
 
-    flow->set_direction(p);
-    flow->session->precheck(p);
+    // If this code is executed on a flow in SETUP state, it will result in a packet from both
+    // client and server on packets from 0.0.0.0 or ::
+    if ( flow->flow_state != Flow::FlowState::SETUP )
+    {
+        flow->set_direction(p);
+        // This call can reset the flow state to SETUP in lazy flow timeout cases
+        flow->session->precheck(p);
+    }
 
     if ( flow->flow_state != Flow::FlowState::SETUP )
     {
@@ -430,7 +436,10 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
 
         ++news;
         flow->flowstats.start_time = p->pkth->ts;
-        flow->flags.client_initiated = p->is_from_client();
+        // Set the flag if the flow direction matches the DAQ direction
+        flow->flags.client_initiated =
+            (p->is_from_server() ==
+                (DAQ_PKT_FLAG_REV_FLOW == (p->packet_flags & DAQ_PKT_FLAG_REV_FLOW)));
     }
 
     // This requires the packet direction to be set
@@ -453,8 +462,6 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
             Stream::stop_inspection(flow, p, SSN_DIR_BOTH, -1, 0);
         else
             DetectionEngine::disable_all(p);
-
-        p->ptrs.decode_flags |= DECODE_PKT_TRUST;
         break;
 
     case Flow::FlowState::BLOCK:
index fa6be4d21f2dd33fe973dbe596760055e75a8a71..37105a1ece5d2987bb66e4973b2c06c3e7f224ba 100644 (file)
@@ -299,10 +299,27 @@ static DAQ_Verdict distill_verdict(Packet* p)
         PacketManager::encode_update(p);
         verdict = DAQ_VERDICT_REPLACE;
     }
+    else if ( act->session_was_trusted() )
+    {
+        if ( p->flow && !act->get_prevent_trust_action() )
+            p->flow->disable_inspection();
+
+        if ( !(act->get_tunnel_bypass() || act->get_prevent_trust_action()) )
+        {
+            verdict = DAQ_VERDICT_WHITELIST;
+        }
+        else
+        {
+            verdict = DAQ_VERDICT_PASS;
+            daq_stats.internal_whitelist++;
+        }
+    }
     else if ( (p->packet_flags & PKT_IGNORE) ||
-        (p->flow && p->flow->get_ignore_direction() == SSN_DIR_BOTH) )
+        (p->flow &&
+            (p->flow->get_ignore_direction() == SSN_DIR_BOTH ||
+                p->flow->flow_state == Flow::FlowState::ALLOW)) )
     {
-        if ( !act->get_tunnel_bypass() )
+        if ( !(act->get_tunnel_bypass() || act->get_prevent_trust_action()) )
         {
             verdict = DAQ_VERDICT_WHITELIST;
         }
index fe5aff786a83ead7dcd2fc0acc937b62ae24c88b..4edae52277085b2bed75df8266ef47c96adf4aa3 100644 (file)
@@ -3,4 +3,11 @@ if ( ENABLE_SHELL )
         SOURCES
             ../request.cc
     )
+
+    add_cpputest(distill_verdict_test
+        SOURCES
+            stubs.h
+            ../analyzer.cc
+            ../../packet_io/active.cc
+    )
 endif ( ENABLE_SHELL )
diff --git a/src/main/test/distill_verdict_test.cc b/src/main/test/distill_verdict_test.cc
new file mode 100644 (file)
index 0000000..3e16dad
--- /dev/null
@@ -0,0 +1,185 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// distill_verdict.cc author Ron Dempster <rdempste@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+
+#include "stubs.h"
+
+#include "main/analyzer.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+
+namespace snort
+{
+int SFDAQInstance::finalize_message(DAQ_Msg_h, DAQ_Verdict verdict)
+{
+    mock().actualCall("finalize_message").onObject(this).withParameter("verdict", verdict);
+    return -1;
+}
+}
+
+using namespace snort;
+
+//--------------------------------------------------------------------------
+// Distill verdict tests
+//--------------------------------------------------------------------------
+TEST_GROUP(distill_verdict_tests)
+{
+    Packet pkt;
+    Flow flow{};
+    Active act;
+    SFDAQInstance* di;
+    Analyzer* analyzer;
+    ActiveAction* active_action;
+
+    void setup() override
+    {
+        pkt.active = &act;
+        active_action = nullptr;
+        pkt.action = &active_action;
+        di = new SFDAQInstance(nullptr, 0, nullptr);
+        pkt.daq_instance = di;
+        analyzer = new Analyzer(di, 0, nullptr);
+    }
+
+    void teardown() override
+    {
+        delete analyzer;
+        mock().clear();
+    }
+};
+
+TEST(distill_verdict_tests, normal_pass)
+{
+    // Normal pass verdict
+    pkt.packet_flags = PKT_FROM_CLIENT;
+    act.reset();
+    mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_PASS);
+    analyzer->post_process_packet(&pkt);
+    mock().checkExpectations();
+}
+
+TEST(distill_verdict_tests, trust_session_whitelist)
+{
+    // Trust session whitelist verdict
+    pkt.flow = &flow;
+    pkt.packet_flags = PKT_FROM_CLIENT;
+    flow.flags.disable_inspect = false;
+    flow.ssn_state.ignore_direction = SSN_DIR_NONE;
+    flow.flow_state = Flow::FlowState::INSPECT;
+    act.reset();
+    act.trust_session(&pkt);
+    mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_WHITELIST);
+    analyzer->post_process_packet(&pkt);
+    mock().checkExpectations();
+    CHECK_TEXT(flow.flags.disable_inspect, "Disable inspection should have been called");
+}
+
+TEST(distill_verdict_tests, prevent_trust_session_whitelist)
+{
+    // Prevent trust_session whitelist verdict
+    pkt.flow = &flow;
+    pkt.packet_flags = PKT_FROM_CLIENT;
+    flow.flags.disable_inspect = false;
+    flow.ssn_state.ignore_direction = SSN_DIR_NONE;
+    flow.flow_state = Flow::FlowState::INSPECT;
+    act.reset();
+    act.trust_session(&pkt);
+    act.set_prevent_trust_action();
+    mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_PASS);
+    analyzer->post_process_packet(&pkt);
+    mock().checkExpectations();
+    CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+TEST(distill_verdict_tests, flow_state_whitelist)
+{
+    // Normal flow state whitelist verdict
+    pkt.flow = &flow;
+    pkt.packet_flags = PKT_FROM_CLIENT;
+    flow.flags.disable_inspect = false;
+    flow.ssn_state.ignore_direction = SSN_DIR_NONE;
+    flow.flow_state = Flow::FlowState::ALLOW;
+    act.reset();
+    mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_WHITELIST);
+    analyzer->post_process_packet(&pkt);
+    mock().checkExpectations();
+    CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+TEST(distill_verdict_tests, prevent_flow_state_whitelist)
+{
+    // Prevent flow state whitelist verdict
+    pkt.flow = &flow;
+    pkt.packet_flags = PKT_FROM_CLIENT;
+    flow.flags.disable_inspect = false;
+    flow.ssn_state.ignore_direction = SSN_DIR_NONE;
+    flow.flow_state = Flow::FlowState::ALLOW;
+    act.reset();
+    act.set_prevent_trust_action();
+    mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_PASS);
+    analyzer->post_process_packet(&pkt);
+    mock().checkExpectations();
+    CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+TEST(distill_verdict_tests, ignore_both_whitelist)
+{
+    // Normal ignore both directions whitelist verdict
+    pkt.flow = &flow;
+    pkt.packet_flags = PKT_FROM_CLIENT;
+    flow.flags.disable_inspect = false;
+    flow.ssn_state.ignore_direction = SSN_DIR_BOTH;
+    flow.flow_state = Flow::FlowState::INSPECT;
+    act.reset();
+    mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_WHITELIST);
+    analyzer->post_process_packet(&pkt);
+    mock().checkExpectations();
+    CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+TEST(distill_verdict_tests, prevent_ignore_both_whitelist)
+{
+    // Prevent ignore both directions whitelist verdict
+    pkt.flow = &flow;
+    pkt.packet_flags = PKT_FROM_CLIENT;
+    flow.flags.disable_inspect = false;
+    flow.ssn_state.ignore_direction = SSN_DIR_BOTH;
+    flow.flow_state = Flow::FlowState::INSPECT;
+    act.reset();
+    act.set_prevent_trust_action();
+    mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_PASS);
+    analyzer->post_process_packet(&pkt);
+    mock().checkExpectations();
+    CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
+}
+
+//-------------------------------------------------------------------------
+// main
+//-------------------------------------------------------------------------
+int main(int argc, char** argv)
+{
+    return CommandLineTestRunner::RunAllTests(argc, argv);
+}
diff --git a/src/main/test/stubs.h b/src/main/test/stubs.h
new file mode 100644 (file)
index 0000000..75f564d
--- /dev/null
@@ -0,0 +1,213 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// stubs.h author Ron Dempster <rdempste@cisco.com>
+
+#include "detection/context_switcher.h"
+#include "detection/detection_engine.h"
+#include "detection/detection_util.h"
+#include "detection/ips_context.h"
+#include "detection/tag.h"
+#include "file_api/file_service.h"
+#include "filters/detection_filter.h"
+#include "filters/rate_filter.h"
+#include "filters/sfrf.h"
+#include "filters/sfthreshold.h"
+#include "flow/ha.h"
+#include "framework/data_bus.h"
+#include "latency/packet_latency.h"
+#include "latency/rule_latency.h"
+#include "log/messages.h"
+#include "managers/action_manager.h"
+#include "managers/codec_manager.h"
+#include "managers/event_manager.h"
+#include "managers/inspector_manager.h"
+#include "managers/ips_manager.h"
+#include "managers/module_manager.h"
+#include "main.h"
+#include "main/analyzer.h"
+#include "main/oops_handler.h"
+#include "main/policy.h"
+#include "main/snort_config.h"
+#include "main/swapper.h"
+#include "main/thread_config.h"
+#include "network_inspectors/packet_tracer/packet_tracer.h"
+#include "packet_io/active.h"
+#include "packet_io/sfdaq.h"
+#include "packet_io/sfdaq_instance.h"
+#include "packet_io/sfdaq_module.h"
+#include "profiler/profiler.h"
+#include "profiler/profiler_defs.h"
+#include "protocols/packet.h"
+#include "protocols/packet_manager.h"
+#include "side_channel/side_channel.h"
+#include "stream/stream.h"
+#include "time/packet_time.h"
+#include "trace/trace_api.h"
+#include "utils/dnet_header.h"
+#include "utils/stats.h"
+
+THREAD_LOCAL DAQStats daq_stats;
+
+void Profiler::start() { }
+void Profiler::stop(uint64_t) { }
+void Profiler::consolidate_stats() { }
+void ThreadConfig::implement_thread_affinity(SThreadType, unsigned) { }
+void Swapper::apply(Analyzer&) { }
+Swapper::~Swapper() { }
+OopsHandler::OopsHandler() { }
+OopsHandler::~OopsHandler() { }
+uint16_t get_run_num() { return 0; }
+void set_run_num(uint16_t) { }
+void set_instance_id(unsigned) { }
+void set_thread_type(SThreadType) { }
+void ContextSwitcher::push(snort::IpsContext*) { }
+void ContextSwitcher::stop() { }
+ContextSwitcher::~ContextSwitcher() { }
+snort::IpsContext* ContextSwitcher::get_context() const { return nullptr; }
+void ContextSwitcher::start() { }
+void InitTag() { }
+void CleanupTag() { }
+void RateFilter_Cleanup() { }
+int sfthreshold_alloc(unsigned int, unsigned int) { return -1; }
+void sfthreshold_reset() { }
+void sfthreshold_free() { }
+void EventTrace_Init() { }
+void EventTrace_Term() { }
+void detection_filter_init(DetectionFilterConfig*) { }
+void detection_filter_term() { }
+void RuleLatency::tterm() { }
+void PacketLatency::tterm() { }
+void SideChannelManager::thread_init() { }
+void SideChannelManager::thread_term() { }
+void CodecManager::thread_init(const snort::SnortConfig*) { }
+void CodecManager::thread_term() { }
+void EventManager::open_outputs() { }
+void EventManager::close_outputs() { }
+void IpsManager::setup_options(const snort::SnortConfig*) { }
+void IpsManager::clear_options(const snort::SnortConfig*) { }
+void ActionManager::thread_init(const snort::SnortConfig*) { }
+void ActionManager::thread_term() { }
+void ActionManager::thread_reinit(const snort::SnortConfig*) { }
+int SFRF_Alloc(unsigned int) { return -1; }
+void packet_time_update(const struct timeval*) { }
+void main_poke(unsigned) { }
+void set_default_policy(const snort::SnortConfig*) { }
+bool snort_ignore(snort::Packet*) { return false; }
+ip_t* ip_open() { return nullptr; }
+ip_t* ip_close(ip_t*) { return nullptr; }
+ssize_t ip_send(ip_t*, const void*, size_t) { return -1; }
+eth_t* eth_open(const char*) { return nullptr; }
+eth_t* eth_close(eth_t*) { return nullptr; }
+ssize_t eth_send(eth_t*, const void*, size_t) { return -1; }
+
+namespace snort
+{
+static struct timeval s_packet_time = { 0, 0 };
+THREAD_LOCAL PacketTracer* s_pkt_trace;
+THREAD_LOCAL TimeContext* ProfileContext::curr_time = nullptr;
+bool TimeProfilerStats::enabled = false;
+THREAD_LOCAL PacketCount pc;
+
+void packet_gettimeofday(struct timeval* tv) { *tv = s_packet_time; }
+MemoryContext::MemoryContext(MemoryTracker&) : saved(nullptr) { }
+MemoryContext::~MemoryContext() { }
+Packet::Packet(bool)
+{
+    memset(this , 0, sizeof(*this));
+    ip_proto_next = IpProtocol::PROTO_NOT_SET;
+    packet_flags = PKT_FROM_CLIENT;
+}
+Packet::~Packet()  = default;
+IpsPolicy* get_ips_policy() { return nullptr; }
+void DataBus::publish(const char*, Packet*, Flow*) { }
+void DataBus::publish(const char*, DataEvent&, Flow*) { }
+SFDAQInstance::SFDAQInstance(const char*, unsigned, const SFDAQConfig*) { }
+SFDAQInstance::~SFDAQInstance() { }
+void SFDAQInstance::reload() { }
+bool SFDAQInstance::start() { return false; }
+bool SFDAQInstance::stop() { return false; }
+const char* SFDAQInstance::get_error() { return nullptr; }
+bool SFDAQInstance::interrupt() { return false; }
+int SFDAQInstance::inject(DAQ_Msg_h, int, const uint8_t*, uint32_t) { return -1; }
+DAQ_RecvStatus SFDAQInstance::receive_messages(unsigned) { return DAQ_RSTAT_ERROR; }
+int SFDAQInstance::ioctl(DAQ_IoctlCmd, void*, size_t) { return -4; }
+void SFDAQ::set_local_instance(SFDAQInstance*) { }
+const char* SFDAQ::verdict_to_string(DAQ_Verdict) { return nullptr; }
+bool SFDAQ::forwarding_packet(const DAQ_PktHdr_t*) { return false; }
+int SFDAQ::inject(DAQ_Msg_h, int, const uint8_t*, uint32_t) { return -1; }
+bool SFDAQ::can_inject() { return false; }
+bool SFDAQ::can_inject_raw() { return false; }
+DetectionEngine::DetectionEngine() { }
+DetectionEngine::~DetectionEngine() { }
+void DetectionEngine::onload() { }
+void DetectionEngine::thread_init() { }
+void DetectionEngine::thread_term() { }
+void DetectionEngine::idle() { }
+void DetectionEngine::reset() { }
+void DetectionEngine::wait_for_context() { }
+void DetectionEngine::set_file_data(const DataPointer&) { }
+void DetectionEngine::clear_replacement() { }
+void DetectionEngine::disable_all(Packet*) { }
+unsigned get_instance_id() { return 0; }
+const SnortConfig* SnortConfig::get_conf() { return nullptr; }
+void PacketTracer::thread_init() { }
+void PacketTracer::thread_term() { }
+void PacketTracer::log(const char*, ...) { }
+void PacketTracer::dump(Packet*) { }
+void PacketTracer::activate(const Packet&) { }
+void TraceApi::thread_init(const TraceConfig*) { }
+void TraceApi::thread_term() { }
+void TraceApi::thread_reinit(const TraceConfig*) { }
+void PacketManager::thread_init() { }
+void PacketManager::decode(
+    Packet*, const DAQ_PktHdr_t*, const uint8_t*, uint32_t, bool, bool) { }
+void PacketManager::encode_update(Packet*) { }
+void PacketManager::thread_term() { }
+const uint8_t* PacketManager::encode_response(TcpResponse, EncodeFlags, const Packet*, uint32_t&,
+    const uint8_t* const, uint32_t) { return nullptr; }
+uint16_t PacketManager::encode_get_max_payload(const Packet*) { return 0; }
+const uint8_t* PacketManager::encode_reject(UnreachResponse, EncodeFlags, const Packet*, uint32_t&)
+{ return nullptr; }
+void FileService::thread_init() { }
+void FileService::thread_term() { }
+void ErrorMessage(const char*,...) { }
+void LogMessage(const char*,...) { }
+[[noreturn]] void FatalError(const char*,...) { exit(-1); }
+void ParseWarning(WarningGroup, const char*, ...) { }
+void HighAvailabilityManager::thread_init() { }
+void HighAvailabilityManager::process_receive() { }
+void HighAvailabilityManager::thread_term() { }
+void HighAvailabilityManager::thread_term_beginning() { }
+void HighAvailabilityManager::process_update(Flow*, Packet*) { }
+void InspectorManager::thread_init(const SnortConfig*) { }
+void InspectorManager::thread_term() { }
+void InspectorManager::thread_stop(const SnortConfig*) { }
+void InspectorManager::thread_reinit(const SnortConfig*) { }
+void ModuleManager::accumulate() { }
+void Stream::handle_timeouts(bool) { }
+void Stream::purge_flows() { }
+bool Stream::set_packet_action_to_hold(Packet*) { return false; }
+void Stream::init_active_response(const Packet*, Flow*) { }
+void Stream::drop_flow(const Packet* ) { }
+void Stream::block_flow(const Packet*) { }
+IpsContext::IpsContext(unsigned) { }
+NetworkPolicy* get_network_policy() { return nullptr; }
+InspectionPolicy* get_inspection_policy() { return nullptr; }
+Flow::Flow() { }
+Flow::~Flow() { }
+}
index 48d4f4e933972dba00eb7c4d5fea8d12f4fa0e8f..d8f9e31c538846c4d44f959033dcd8ceaf306bb4 100644 (file)
@@ -312,9 +312,7 @@ static void snort_reputation(ReputationConfig* config, Packet* p)
         }
 
         DetectionEngine::queue_event(GID_REPUTATION, whitelist_event);
-        p->packet_flags |= PKT_IGNORE;
-        DetectionEngine::disable_all(p);
-        act->allow_session(p);
+        act->trust_session(p, true);
         reputationstats.whitelisted++;
     }
 }
index 61da692cbcd6d166745bbf0f24bdf95e76ae599d..2b7cfa257b876acd26c2f88b5eabd307ea769935 100644 (file)
@@ -57,6 +57,7 @@ public:
 
 const char* Active::act_str[Active::ACT_MAX][Active::AST_MAX] =
 {
+    { "trust", "error", "error", "error" },
     { "allow", "error", "error", "error" },
     { "hold", "error", "error", "error" },
     { "retry", "error", "error", "error" },
@@ -568,7 +569,10 @@ void Active::daq_drop_packet(const Packet* p)
 
 bool Active::retry_packet(const Packet* p)
 {
-    if (active_action != ACT_PASS || !SFDAQ::forwarding_packet(p->pkth))
+    if (ACT_RETRY == active_action)
+        return true;
+
+    if (ACT_RETRY < active_action || !SFDAQ::forwarding_packet(p->pkth))
         return false;
 
     // FIXIT-L semi-arbitrary heuristic for preventing retry queue saturation - reevaluate later
@@ -612,20 +616,28 @@ void Active::cancel_packet_hold()
 {
     assert(active_action == ACT_HOLD);
     active_counts.holds_canceled++;
-    active_action = ACT_PASS;
+    active_action = ACT_ALLOW;
 }
 
-void Active::allow_session(Packet* p)
+void Active::trust_session(Packet* p, bool force)
 {
-    active_action = ACT_PASS;
+    active_action = ACT_TRUST;
+    p->packet_flags |= PKT_IGNORE;
+    DetectionEngine::disable_all(p);
 
     if ( p->flow )
     {
+        p->flow->set_ignore_direction(SSN_DIR_BOTH);
         p->flow->set_state(Flow::FlowState::ALLOW);
-        p->flow->disable_inspection();
     }
 
-    p->disable_inspect = true;
+    if (force)
+    {
+        if ( p->flow )
+            p->flow->disable_inspection();
+
+        p->disable_inspect = true;
+    }
 }
 
 void Active::block_session(Packet* p, bool force)
@@ -694,7 +706,7 @@ void Active::apply_delayed_action(Packet* p)
 
     switch ( delayed_active_action )
     {
-    case ACT_PASS:
+    case ACT_ALLOW:
         break;
     case ACT_DROP:
         drop_packet(p, force);
@@ -714,7 +726,7 @@ void Active::apply_delayed_action(Packet* p)
         break;
     }
 
-    delayed_active_action = ACT_PASS;
+    delayed_active_action = ACT_ALLOW;
 }
 
 
@@ -758,9 +770,10 @@ void Active::close()
 void Active::reset()
 {
     active_tunnel_bypass = 0;
+    prevent_trust_action = false;
     active_status = AST_ALLOW;
-    active_action = ACT_PASS;
-    delayed_active_action = ACT_PASS;
+    active_action = ACT_ALLOW;
+    delayed_active_action = ACT_ALLOW;
     delayed_reject = nullptr;
 }
 
index 1ee25b2e510fba3b5f63dcdac9c913c9b757a442..cc8e97e409fb807ca5a5c41a99d1ccda2ae39e4d 100644 (file)
@@ -54,7 +54,7 @@ public:
     // apply_delayed_action, in a big switch(action). Do away with these and
     // use the actual (Base)Action objects.
     enum ActiveActionType : uint8_t
-    { ACT_PASS, ACT_HOLD, ACT_RETRY, ACT_DROP, ACT_BLOCK, ACT_RESET, ACT_MAX };
+    { ACT_TRUST, ACT_ALLOW, ACT_HOLD, ACT_RETRY, ACT_DROP, ACT_BLOCK, ACT_RESET, ACT_MAX };
 
 public:
 
@@ -99,7 +99,7 @@ public:
     bool hold_packet(const Packet*);
     void cancel_packet_hold();
 
-    void allow_session(Packet*);
+    void trust_session(Packet*, bool force = false);
     void block_session(Packet*, bool force = false);
     void reset_session(Packet*, bool force = false);
     void reset_session(Packet*, snort::ActiveAction* r, bool force = false);
@@ -123,6 +123,9 @@ public:
     bool packet_retry_requested() const
     { return active_action == ACT_RETRY; }
 
+    bool session_was_trusted() const
+    { return active_action == ACT_TRUST; }
+
     bool session_was_blocked() const
     { return active_action >= ACT_BLOCK; }
 
@@ -141,6 +144,12 @@ public:
     bool get_tunnel_bypass() const
     { return active_tunnel_bypass > 0; }
 
+    void set_prevent_trust_action()
+    { prevent_trust_action = true; }
+
+    bool get_prevent_trust_action() const
+    { return prevent_trust_action; }
+
     void set_delayed_action(ActiveActionType, bool force = false);
     void set_delayed_action(ActiveActionType, ActiveAction* act, bool force = false);
     void apply_delayed_action(Packet*);
@@ -168,6 +177,8 @@ private:
 
     int active_tunnel_bypass;
 
+    bool prevent_trust_action;
+
     // these can't be pkt flags because we do the handling
     // of these flags following all processing and the drop
     // or response may have been produced by a pseudopacket.
index 564a11575af07fb817ba2c5fc7289d9fcdcf0af4..772a5986ede12175548322c8ac96636f31d769ea 100644 (file)
@@ -279,6 +279,12 @@ struct SO_PUBLIC Packet
     bool is_from_server() const
     { return (packet_flags & PKT_FROM_SERVER) != 0; }
 
+    bool is_from_client_originally() const
+    { return (!flow || flow->flags.client_initiated) ? is_from_client() : is_from_server(); }
+
+    bool is_from_server_originally() const
+    { return (!flow || flow->flags.client_initiated) ? is_from_server() : is_from_client(); }
+
     bool is_full_pdu() const
     { return (packet_flags & PKT_PDU_FULL) == PKT_PDU_FULL; }
 
index b7a803bdea0b6f3e3b4941bd59bf5f7a5d286beb..2d869fd2094eb0caf5f6a9af36e9fb218823b183 100644 (file)
@@ -299,7 +299,7 @@ static const char* get_status(uint8_t stat)
 
 static const char* get_action(uint8_t act)
 {
-    const char* acts[] = { "pass", "hold", "retry", "drop", "block", "reset" };
+    const char* acts[] = { "trust", "pass", "hold", "retry", "drop", "block", "reset" };
     return lookup(acts, sizeof(acts)/sizeof(acts[0]), act);
 }