endif()
if (DAQ_STATIC_MODULES)
list(SORT DAQ_STATIC_MODULES)
- set(DAQ_STATIC_MODULES ${DAQ_STATIC_MODULES} CACHE INTERNAL "Static DAQ modules")
+ # set(DAQ_STATIC_MODULES ${DAQ_STATIC_MODULES} CACHE INTERNAL "Static DAQ modules")
endif()
endif()
set (FLOW_INCLUDES
+ deferred_trust.h
expect_cache.h
flow.h
flow_data.h
add_library (flow OBJECT
${FLOW_INCLUDES}
+ deferred_trust.cc
expect_cache.cc
flow.cc
flow_cache.cc
--- /dev/null
+//--------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+// deferred_trust.cc author Ron Dempster <rdempste@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "deferred_trust.h"
+
+#include "packet_io/active.h"
+
+using namespace snort;
+
+void DeferredTrust::set_deferred_trust(unsigned module_id, bool on)
+{
+ if (on)
+ {
+ if (deferred_trust_modules.empty())
+ {
+ if (TRUST_DEFER_DO_TRUST == deferred_trust)
+ deferred_trust = TRUST_DEFER_DEFERRING;
+ else
+ deferred_trust = TRUST_DEFER_ON;
+ }
+ auto element = deferred_trust_modules.begin();
+ for (; element != deferred_trust_modules.end() && *element != module_id;
+ ++element);
+ if (element == deferred_trust_modules.end())
+ deferred_trust_modules.emplace_front(module_id);
+ }
+ else if (!deferred_trust_modules.empty())
+ {
+ deferred_trust_modules.remove(module_id);
+ if (deferred_trust_modules.empty())
+ {
+ if (TRUST_DEFER_DEFERRING == deferred_trust)
+ deferred_trust = TRUST_DEFER_DO_TRUST;
+ else
+ deferred_trust = TRUST_DEFER_OFF;
+ }
+ }
+}
+
+void DeferredTrust::finalize(Active& active)
+{
+ if (active.packet_was_dropped())
+ clear();
+ else if (TRUST_DEFER_DO_TRUST == deferred_trust && active.session_was_allowed())
+ active.set_trust();
+ else if (TRUST_DEFER_ON == deferred_trust && active.session_was_trusted())
+ {
+ // This is the case where defer was called after session trust while processing
+ // the same packet
+ deferred_trust = TRUST_DEFER_DEFERRING;
+ active.set_allow();
+ }
+}
--- /dev/null
+//--------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+// deferred_trust.h author Ron Dempster <rdempste@cisco.com>
+
+#ifndef DEFERRED_TRUST_H
+#define DEFERRED_TRUST_H
+
+#include <cstdint>
+#include <forward_list>
+
+#include "main/snort_types.h"
+
+namespace snort
+{
+
+class Active;
+class Flow;
+struct Packet;
+
+class DeferredTrust
+{
+ // This class is used to delay session trust. This is used in cases where
+ // a module needs to continue inspecting a session to enforce policy.
+ // A module calls set_deferred_trust with the on parameter true to begin
+ // deferring. The sets the state to TRUST_DEFER_ON. If trust session is called
+ // while deferring, the state is changed to TRUST_DEFER_DEFERRING to the trust action.
+ // A module calls set_deferred_trust with the on parameter false to stop deferring.
+ // When all modules have stopped deferring, the state is checked. If the state is
+ // TRUST_DEFER_DEFERRING, the state is changed to TRUST_DEFER_DO_TRUST. Otherwise, the state
+ // is set to TRUST_DEFER_OFF.
+ // The TRUST_DEFER_DO_TRUST state is checked at the end of packet processing. If the state
+ // is TRUST_DEFER_DO_TRUST and the action is ACT_ALLOW, the session is trusted.
+ // If a drop, block or reset action occurs while deferring, deferring is stopped and the
+ // block or blacklist version is enforced.
+ // The module_id, a unique module identifier created by calling
+ // FlowData::create_flow_data_id(), is used to track the modules that are currently deferring.
+ // This allows the module to use whitelist deferring without needing to track the deferring
+ // state of the module.
+ enum DeferredTrustState : uint8_t
+ {
+ TRUST_DEFER_OFF = 0,
+ TRUST_DEFER_ON,
+ TRUST_DEFER_DEFERRING,
+ TRUST_DEFER_DO_TRUST,
+ };
+
+public:
+ DeferredTrust() = default;
+ ~DeferredTrust() = default;
+ SO_PUBLIC void set_deferred_trust(unsigned module_id, bool on);
+ bool is_active()
+ { return TRUST_DEFER_ON == deferred_trust || TRUST_DEFER_DEFERRING == deferred_trust; }
+ bool try_trust()
+ {
+ if (TRUST_DEFER_ON == deferred_trust)
+ deferred_trust = TRUST_DEFER_DEFERRING;
+ return TRUST_DEFER_DEFERRING != deferred_trust;
+ }
+ bool is_deferred()
+ { return TRUST_DEFER_DEFERRING == deferred_trust; }
+ void clear()
+ {
+ deferred_trust = TRUST_DEFER_OFF;
+ deferred_trust_modules.clear();
+ }
+ void finalize(Active&);
+
+protected:
+ std::forward_list<unsigned> deferred_trust_modules;
+ DeferredTrustState deferred_trust = TRUST_DEFER_OFF;
+};
+
+}
+
+#endif
Flow::Flow()
{
memory::MemoryCap::update_allocations(sizeof(*this) + sizeof(FlowStash));
- memset(this, 0, sizeof(*this));
+ constexpr size_t offset = offsetof(Flow, key);
+ // FIXIT-L need a struct to zero here to make future proof
+ memset((uint8_t*)this+offset, 0, sizeof(*this)-offset);
}
Flow::~Flow()
if ( stash )
stash->reset();
- constexpr size_t offset = offsetof(Flow, flow_data);
+ deferred_trust.clear();
+
+ constexpr size_t offset = offsetof(Flow, context_chain);
// FIXIT-L need a struct to zero here to make future proof
memset((uint8_t*)this+offset, 0, sizeof(Flow)-offset);
}
clear_gadget();
}
+void Flow::trust()
+{
+ set_ignore_direction(SSN_DIR_BOTH);
+ set_state(Flow::FlowState::ALLOW);
+ disable_inspection();
+}
+
int Flow::set_flow_data(FlowData* fd)
{
FlowData* old = get_flow_data(fd->get_id());
#include <sys/time.h>
#include "detection/ips_context_chain.h"
+#include "flow/deferred_trust.h"
#include "flow/flow_data.h"
#include "flow/flow_stash.h"
#include "framework/data_bus.h"
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
{
bool is_hard_expiration()
{ return (ssn_state.session_flags & SSNFLAG_HARD_EXPIRATION) != 0; }
- void set_deferred_whitelist(DeferredWhitelist defer_state)
- {
- if (defer_state == WHITELIST_DEFER_DONE )
- {
- if (deferred_whitelist == WHITELIST_DEFER_STARTED )
- deferred_whitelist = WHITELIST_DEFER_DONE;
- else
- deferred_whitelist = WHITELIST_DEFER_OFF;
- }
- else
- deferred_whitelist = defer_state;
- }
+ void set_deferred_trust(unsigned module_id, bool on)
+ { deferred_trust.set_deferred_trust(module_id, on); }
+
+ bool cannot_trust()
+ { return deferred_trust.is_active(); }
- DeferredWhitelist get_deferred_whitelist_state()
+ bool try_trust()
+ { return deferred_trust.try_trust(); }
+
+ void stop_deferring_trust()
+ { deferred_trust.clear(); }
+
+ void finalize_trust(Active& active)
{
- return deferred_whitelist;
+ deferred_trust.finalize(active);
}
+ void trust();
+
+ bool trust_is_deferred()
+ { return deferred_trust.is_deferred(); }
+
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
// these fields are const after initialization
+ DeferredTrust deferred_trust;
+
+ // Anything before this comment is not zeroed during construction
const FlowKey* key;
BitOp* bitop;
FlowHAState* ha_state;
uint64_t expire_time;
- DeferredWhitelist deferred_whitelist = WHITELIST_DEFER_OFF;
-
unsigned inspection_policy_id;
unsigned ips_policy_id;
unsigned network_policy_id;
add_cpputest( ha_test )
+add_cpputest( deferred_trust_test
+ SOURCES ../deferred_trust.cc
+)
+
add_cpputest( flow_stash_test
SOURCES ../flow_stash.cc
)
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2015-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.
+//--------------------------------------------------------------------------
+
+// deferred_trust_test.cc author Ron Dempster <rdempste@cisco.com>
+// unit test main
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "flow/deferred_trust.h"
+#include "packet_io/active.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+
+using namespace snort;
+
+//-------------------------------------------------------------------------
+// tests
+//-------------------------------------------------------------------------
+
+TEST_GROUP(deferred_trust_test)
+{
+ DeferredTrust deferred_trust;
+};
+
+TEST(deferred_trust_test, set_deferred_trust)
+{
+ // Disable non-existent module_id
+ deferred_trust.set_deferred_trust(1, false);
+ CHECK_TEXT(!deferred_trust.is_active(), "Deferred trust should not be active");
+
+ // Enable
+ deferred_trust.set_deferred_trust(1, true);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(!deferred_trust.is_deferred(), "Deferred trust should not be deferring");
+ // Disable non-existent module_id, no state change
+ deferred_trust.set_deferred_trust(2, false);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(!deferred_trust.is_deferred(), "Deferred trust should not be deferring");
+ // Disable the only module_id disables deferring
+ deferred_trust.set_deferred_trust(1, false);
+ CHECK_TEXT(!deferred_trust.is_active(), "Deferred trust should not be active");
+
+ // Enable
+ deferred_trust.set_deferred_trust(1, true);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(!deferred_trust.is_deferred(), "Deferred trust should not be deferring");
+ // Enable second module_id
+ deferred_trust.set_deferred_trust(2, true);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(!deferred_trust.is_deferred(), "Deferred trust should not be deferring");
+ // Disable the first module_id, no state change
+ deferred_trust.set_deferred_trust(1, false);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(!deferred_trust.is_deferred(), "Deferred trust should not be deferring");
+ // Disable the second module_id disables deferring
+ deferred_trust.set_deferred_trust(2, false);
+ CHECK_TEXT(!deferred_trust.is_active(), "Deferred trust should not be active");
+
+ // Enable
+ deferred_trust.set_deferred_trust(1, true);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(!deferred_trust.is_deferred(), "Deferred trust should not be deferring");
+ // Try to trust, change state to deferring
+ deferred_trust.try_trust();
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(deferred_trust.is_deferred(), "Deferred trust should be deferring");
+ // Disable the only module_id disables deferring
+ deferred_trust.set_deferred_trust(1, false);
+ CHECK_TEXT(!deferred_trust.is_active(), "Deferred trust should not be active");
+}
+
+TEST(deferred_trust_test, finalize)
+{
+ Active active{};
+ active.block_again();
+
+ // Enable
+ deferred_trust.set_deferred_trust(1, true);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(!deferred_trust.is_deferred(), "Deferred trust should not be deferring");
+ // finalize with blocked packet disables deferring
+ deferred_trust.finalize(active);
+ CHECK_TEXT(!deferred_trust.is_active(), "Deferred trust should not be active");
+
+ active.set_allow();
+ // Enable
+ deferred_trust.set_deferred_trust(1, true);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(!deferred_trust.is_deferred(), "Deferred trust should not be deferring");
+ // Try to trust, change state to deferring
+ deferred_trust.try_trust();
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(deferred_trust.is_deferred(), "Deferred trust should be deferring");
+ // Disable the only module_id disables deferring
+ deferred_trust.set_deferred_trust(1, false);
+ CHECK_TEXT(!deferred_trust.is_active(), "Deferred trust should not be active");
+ // State should be do trust
+ deferred_trust.finalize(active);
+ CHECK_TEXT(active.session_was_trusted(), "Session was not trusted from do trust");
+
+ // Enable with state do trust goes to deferring
+ deferred_trust.set_deferred_trust(1, true);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(deferred_trust.is_deferred(), "Deferred trust should be deferring");
+
+ deferred_trust.clear();
+ // Enable
+ deferred_trust.set_deferred_trust(1, true);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(!deferred_trust.is_deferred(), "Deferred trust should not be deferring");
+ // Session is trusted, defer should move to deferring and session should not be trusted
+ deferred_trust.finalize(active);
+ CHECK_TEXT(deferred_trust.is_active(), "Deferred trust should be active");
+ CHECK_TEXT(deferred_trust.is_deferred(), "Deferred trust should be deferring");
+ CHECK_TEXT(!active.session_was_trusted(), "Session was trusted while deferring trust");
+ CHECK_TEXT(active.session_was_allowed(), "Session was not allowed while deferring trust");
+}
+
+
+int main(int argc, char** argv)
+{
+ return CommandLineTestRunner::RunAllTests(argc, argv);
+}
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->flags.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->flags.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->flags.disable_inspect = true;
- }
-}
-
// Finalize DAQ message verdict
static DAQ_Verdict distill_verdict(Packet* 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++;
- }
- }
+ verdict = DAQ_VERDICT_WHITELIST;
else if ( (p->packet_flags & PKT_IGNORE) ||
(p->flow &&
(p->flow->get_ignore_direction() == SSN_DIR_BOTH ||
p->flow->flow_state == Flow::FlowState::ALLOW)) )
{
- if ( !(act->get_tunnel_bypass() || act->get_prevent_trust_action()) )
- {
- verdict = DAQ_VERDICT_WHITELIST;
- }
- else
- {
- verdict = DAQ_VERDICT_PASS;
- daq_stats.internal_whitelist++;
- }
+ verdict = DAQ_VERDICT_WHITELIST;
}
else if ( p->ptrs.decode_flags & DECODE_PKT_TRUST )
{
else
verdict = DAQ_VERDICT_PASS;
- handle_deferred_whitelist(p, verdict);
-
+ if (DAQ_VERDICT_WHITELIST == verdict)
+ {
+ if (p->flow && p->flow->cannot_trust())
+ verdict = DAQ_VERDICT_PASS;
+ else if (act->get_tunnel_bypass())
+ {
+ verdict = DAQ_VERDICT_PASS;
+ daq_stats.internal_whitelist++;
+ }
+ }
return verdict;
}
if (verdict == DAQ_VERDICT_BLOCK or verdict == DAQ_VERDICT_BLACKLIST)
p->active->send_reason_to_daq(*p);
-
+
oops_handler->set_current_message(nullptr);
p->pkth = nullptr; // No longer avail after finalize_message.
mock().actualCall("finalize_message").onObject(this).withParameter("verdict", verdict);
return -1;
}
+void DeferredTrust::finalize(Active&) { }
+void DeferredTrust::set_deferred_trust(unsigned module_id, bool on)
+{
+ deferred_trust = on ? TRUST_DEFER_ON : TRUST_DEFER_OFF;
+}
+void Flow::trust() { }
}
using namespace snort;
mock().checkExpectations();
}
-TEST(distill_verdict_tests, trust_session_whitelist)
+TEST(distill_verdict_tests, trust_session_whitelist_on_blocked)
{
- // Trust session whitelist verdict
+ // Trust session whitelist verdict on blocked packet does nothing
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.drop_packet(&pkt, true);
act.trust_session(&pkt);
- mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_WHITELIST);
+ mock().expectNCalls(1, "finalize_message").onObject(di).withParameter("verdict", DAQ_VERDICT_BLOCK);
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)
+TEST(distill_verdict_tests, trust_session_whitelist)
{
- // Prevent trust_session whitelist verdict
+ // Trust session whitelist verdict
pkt.flow = &flow;
pkt.packet_flags = PKT_FROM_CLIENT;
flow.flags.disable_inspect = false;
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);
+ 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, flow_state_whitelist)
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
CHECK_TEXT(!flow.flags.disable_inspect, "Disable inspection should not have been called");
}
-TEST(distill_verdict_tests, prevent_ignore_both_whitelist)
+TEST(distill_verdict_tests, deferred_trust_prevent_whitelist)
{
- // Prevent ignore both directions whitelist verdict
+ // Deferred trust prevent whitelist
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;
+ flow.ssn_state.ignore_direction = SSN_DIR_NONE;
+ flow.flow_state = Flow::FlowState::ALLOW;
+ flow.set_deferred_trust(53, true);
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");
}
//-------------------------------------------------------------------------
if ( T )
trace_ulogf(snort_trace, TRACE_INSPECTOR_MANAGER, p,
"exit %s, elapsed time: %" PRId64" usec\n", inspector_name, TO_USECS(timer.get()));
+
+ // must check between each ::execute()
+ if ( p->disable_inspect )
+ return;
}
}
void Active::trust_session(Packet* p, bool force)
{
- active_action = ACT_TRUST;
- p->packet_flags |= PKT_IGNORE;
- DetectionEngine::disable_all(p);
+ if (ACT_ALLOW < active_action)
+ return;
- if ( p->flow )
- {
- p->flow->set_ignore_direction(SSN_DIR_BOTH);
- p->flow->set_state(Flow::FlowState::ALLOW);
- }
+ DetectionEngine::disable_all(p);
if (force)
{
+ p->packet_flags |= PKT_IGNORE;
if ( p->flow )
- p->flow->disable_inspection();
-
+ {
+ p->flow->trust();
+ p->flow->stop_deferring_trust();
+ }
p->disable_inspect = true;
}
+ else if (p->flow && p->flow->try_trust())
+ active_action = ACT_TRUST;
}
void Active::block_session(Packet* p, bool force)
void Active::reset()
{
active_tunnel_bypass = 0;
- prevent_trust_action = false;
active_status = AST_ALLOW;
active_would_reason = WHD_NONE;
active_action = ACT_ALLOW;
(*p->action)->exec(p);
*p->action = nullptr;
}
+
+ if (p->flow)
+ {
+ p->flow->finalize_trust(*p->active);
+ if (p->active->session_was_trusted())
+ p->flow->trust();
+ }
}
void Active::set_default_drop_reason(uint8_t reason_id)
void reset_again()
{ active_action = ACT_RESET; }
+ void set_trust()
+ { active_action = ACT_TRUST; }
+
+ void set_allow()
+ { active_action = ACT_ALLOW; }
+
bool packet_was_dropped() const
{ return active_action >= ACT_DROP; }
bool session_was_blocked() const
{ return active_action >= ACT_BLOCK; }
+ bool session_was_allowed() const
+ { return active_action <= ACT_ALLOW; }
+
bool packet_force_dropped() const
{ return active_status == AST_FORCE; }
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*);
int active_tunnel_bypass;
const char* drop_reason;
- 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.