From: Ron Dempster (rdempste) Date: Tue, 2 Jun 2020 17:57:50 +0000 (+0000) Subject: Merge pull request #2223 in SNORT/snort3 from ~RDEMPSTE/snort3:direction_prevent_whit... X-Git-Tag: 3.0.1-5~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71975524f6505f2fe52395b337fa9b8f0a814ef8;p=thirdparty%2Fsnort3.git Merge pull request #2223 in SNORT/snort3 from ~RDEMPSTE/snort3:direction_prevent_whitelist to master Squashed commit of the following: commit 8b95f26e28f56d5815c75c6cd42f163e3f3f85ef Author: rdempste Date: Mon Jun 1 16:32:28 2020 -0400 active: add a facility to prevent a DAQ whitelist verdict commit 63fb0a693a3cea1ff45f1931d01e3b120dc4ab7a Author: rdempste 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 Date: Thu May 7 17:36:36 2020 -0400 flow: make client_initiated flag depend on the DAQ reverse flow flag --- diff --git a/src/flow/flow.h b/src/flow/flow.h index b0a7c11ee..f093d7978 100644 --- a/src/flow/flow.h +++ b/src/flow/flow.h @@ -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; diff --git a/src/flow/flow_control.cc b/src/flow/flow_control.cc index d32204d17..3735a7519 100644 --- a/src/flow/flow_control.cc +++ b/src/flow/flow_control.cc @@ -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: diff --git a/src/main/analyzer.cc b/src/main/analyzer.cc index fa6be4d21..37105a1ec 100644 --- a/src/main/analyzer.cc +++ b/src/main/analyzer.cc @@ -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; } diff --git a/src/main/test/CMakeLists.txt b/src/main/test/CMakeLists.txt index fe5aff786..4edae5227 100644 --- a/src/main/test/CMakeLists.txt +++ b/src/main/test/CMakeLists.txt @@ -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 index 000000000..3e16dad49 --- /dev/null +++ b/src/main/test/distill_verdict_test.cc @@ -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 + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "stubs.h" + +#include "main/analyzer.h" + +#include +#include +#include + +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 index 000000000..75f564d42 --- /dev/null +++ b/src/main/test/stubs.h @@ -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 + +#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() { } +} diff --git a/src/network_inspectors/reputation/reputation_inspect.cc b/src/network_inspectors/reputation/reputation_inspect.cc index 48d4f4e93..d8f9e31c5 100644 --- a/src/network_inspectors/reputation/reputation_inspect.cc +++ b/src/network_inspectors/reputation/reputation_inspect.cc @@ -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++; } } diff --git a/src/packet_io/active.cc b/src/packet_io/active.cc index 61da692cb..2b7cfa257 100644 --- a/src/packet_io/active.cc +++ b/src/packet_io/active.cc @@ -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; } diff --git a/src/packet_io/active.h b/src/packet_io/active.h index 1ee25b2e5..cc8e97e40 100644 --- a/src/packet_io/active.h +++ b/src/packet_io/active.h @@ -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. diff --git a/src/protocols/packet.h b/src/protocols/packet.h index 564a11575..772a5986e 100644 --- a/src/protocols/packet.h +++ b/src/protocols/packet.h @@ -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; } diff --git a/tools/u2spewfoo/u2spewfoo.cc b/tools/u2spewfoo/u2spewfoo.cc index b7a803bde..2d869fd20 100644 --- a/tools/u2spewfoo/u2spewfoo.cc +++ b/tools/u2spewfoo/u2spewfoo.cc @@ -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); }