]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2164 in SNORT/snort3 from ~RUCOMBS/snort3:avc_only to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Fri, 17 Apr 2020 02:51:15 +0000 (02:51 +0000)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Fri, 17 Apr 2020 02:51:15 +0000 (02:51 +0000)
Squashed commit of the following:

commit de9579872286a2c44b89e8f1ebd4dc3b0c0593d2
Author: russ <rucombs@cisco.com>
Date:   Sat Apr 11 21:06:42 2020 -0400

    ftp_data: fix ids flushing at EOF

commit 22804f385fd0fc2eaf200fd69d7560b404700e07
Author: russ <rucombs@cisco.com>
Date:   Sat Apr 11 02:14:33 2020 -0400

    style: fix nits

commit 3248176e5aaf8132121290d791b1788db4c58469
Author: russ <rucombs@cisco.com>
Date:   Sun Apr 12 19:33:27 2020 -0400

    inspectors: designate service inspectors for start tls

    This applies to pop, imap, and smtp wich can do start tls as well as to
    ftp which can do auth tls.

commit 66a13456a5817ac628c3457365ba065f04f6b03e
Author: russ <rucombs@cisco.com>
Date:   Sat Apr 11 00:35:01 2020 -0400

    inspectors: designate service inspectors for file carving

    This applies to dce_smb, ftp_data, http_inspect, http2_inspect, imap,
    pop, and smtp which process files.

commit 3700b32c0d3e596bdea00beb321edb4a992533b4
Author: russ <rucombs@cisco.com>
Date:   Sat Apr 11 00:33:39 2020 -0400

    inspectors: designate service inspectors control channels for avc only

    This applies to cip, ftp_server, and sip inspectors which support other
    flows.

commit 0749035648aaee49de05e77100b268a23b89b484
Author: russ <rucombs@cisco.com>
Date:   Sat Apr 11 00:18:26 2020 -0400

    ips_context: add support to fallback to avc only

24 files changed:
src/codecs/ip/cd_gre.cc
src/detection/context_switcher.cc
src/detection/ips_context.cc
src/detection/ips_context.h
src/flow/session.h
src/framework/inspector.h
src/network_inspectors/perf_monitor/perf_module.h
src/service_inspectors/cip/cip.cc
src/service_inspectors/dce_rpc/dce_smb.cc
src/service_inspectors/ftp_telnet/ftp.cc
src/service_inspectors/ftp_telnet/ftp_data.cc
src/service_inspectors/ftp_telnet/ftpdata_splitter.h
src/service_inspectors/http2_inspect/http2_inspect.h
src/service_inspectors/http_inspect/http_inspect.h
src/service_inspectors/http_inspect/http_stream_splitter_reassemble.cc
src/service_inspectors/imap/imap.cc
src/service_inspectors/pop/pop.cc
src/service_inspectors/sip/sip.cc
src/service_inspectors/smtp/smtp.cc
src/stream/stream.cc
src/stream/stream.h
src/stream/tcp/tcp_stream_session.cc
src/stream/tcp/tcp_stream_session.h
src/stream/tcp/tcp_stream_tracker.cc

index d25e3a02cde1359cbf0ad22aeaaf16d258748831..41f0e4da9676c8d5899949ddaf0d65452f0233f0 100644 (file)
@@ -136,7 +136,7 @@ bool GreCodec::encode(const uint8_t* const raw_in, const uint16_t raw_len,
     if (GRE_SEQ(greh_out))
     {
         uint16_t len = 4; // Flags, version and protocol
-        
+
         if (GRE_CHKSUM(greh_out))
             len += 4;
 
@@ -151,7 +151,7 @@ bool GreCodec::encode(const uint8_t* const raw_in, const uint16_t raw_len,
         assert(raw_len >= 6);
         // Checksum field is zero for computing checksum
         *(uint16_t*)(buf.data() + 4) = 0;
-        *(uint16_t*)(buf.data() + 4) = checksum::cksum_add((uint16_t*)buf.data(), 
+        *(uint16_t*)(buf.data() + 4) = checksum::cksum_add((uint16_t*)buf.data(),
             buf.size());
     }
 
index ed36251991b697bd0d24ff1350e47c7bada0c8c1..686be66bfcb1b15e4590d57de90aa35be278a081 100644 (file)
@@ -83,6 +83,8 @@ void ContextSwitcher::start()
     c->packet->action = &c->packet->action_inst;
     c->state = IpsContext::BUSY;
 
+    c->setup();
+
     busy.emplace_back(c);
 }
 
@@ -98,7 +100,8 @@ void ContextSwitcher::stop()
                "(wire) %" PRIu64 " cs::stop %" PRIu64 " (i=%zu, b=%zu)\n",
         get_packet_number(), c->context_num, idle.size(), busy.size());
 
-    c->clear_context_data();
+    c->clear();
+
     c->packet->active = nullptr;
     c->packet->action = nullptr;
     c->state = IpsContext::IDLE;
@@ -137,7 +140,7 @@ void ContextSwitcher::abort()
         c->abort();
         c->state = IpsContext::IDLE;
         c->clear_callbacks();
-        c->clear_context_data();
+        c->clear();
         idle.emplace_back(c);
     }
     non_flow_chain.abort();
@@ -160,6 +163,8 @@ IpsContext* ContextSwitcher::interrupt()
     idle.pop_back();
 
     c->state = IpsContext::BUSY;
+    c->setup();
+
     busy.emplace_back(c);
     return c;
 }
@@ -178,7 +183,7 @@ IpsContext* ContextSwitcher::complete()
         c->packet_number, c->context_num, idle.size(), busy.size());
 
     busy.pop_back();
-    c->clear_context_data();
+    c->clear();
     c->state = IpsContext::IDLE;
     idle.emplace_back(c);
 
index 69cebb4de8a75d334b3ce5c582ecf8f8c4150adf..a5752c6164921854de68253489c6d93be29f76a3 100644 (file)
@@ -32,6 +32,7 @@
 #include "events/event_queue.h"
 #include "events/sfeventq.h"
 #include "main/snort_config.h"
+#include "stream/stream.h"
 
 #ifdef UNIT_TEST
 #include "catch/snort_catch.h"
@@ -88,6 +89,31 @@ IpsContext::~IpsContext()
     delete packet;
 }
 
+void IpsContext::setup()
+{
+    conf = SnortConfig::get_conf();
+    remove_gadget = false;
+}
+
+void IpsContext::clear()
+{
+    for ( auto id : ids_in_use )
+    {
+        auto* p = data[id];
+        if ( p )
+            p->clear();
+    }
+    if ( remove_gadget and packet->flow and !packet->is_rebuilt() )
+    {
+       Stream::disable_reassembly(packet->flow);
+
+       if ( packet->flow->gadget )
+           packet->flow->clear_gadget();
+    }
+    remove_gadget = false;
+    assert(post_callbacks.empty());
+}
+
 void IpsContext::set_context_data(unsigned id, IpsContextData* cd)
 {
     assert(id < data.size());
@@ -101,16 +127,6 @@ IpsContextData* IpsContext::get_context_data(unsigned id) const
     return data[id];
 }
 
-void IpsContext::clear_context_data()
-{
-    for ( auto id : ids_in_use )
-    {
-        auto* p = data[id];
-        if ( p )
-            p->clear();
-    }
-}
-
 void IpsContext::snapshot_flow(Flow* f)
 {
     flow.session_flags = f->ssn_state.session_flags;
@@ -125,6 +141,26 @@ void IpsContext::post_detection()
     post_callbacks.clear();
 }
 
+void IpsContext::disable_detection()
+{
+    if ( active_rules == IpsContext::NONE )
+        return;
+
+    IpsPolicy* empty_policy = get_empty_ips_policy(conf);
+    set_ips_policy(empty_policy);
+
+    if ( Flow* f = packet->flow )
+    {
+        f->ips_policy_id = empty_policy->policy_id;
+        f->set_to_client_detection(false);
+        f->set_to_server_detection(false);
+    }
+    active_rules = IpsContext::NONE;
+}
+
+void IpsContext::disable_inspection()
+{ remove_gadget = true; }
+
 //--------------------------------------------------------------------------
 // unit tests
 //--------------------------------------------------------------------------
index 409b417739bbd972e46a4a46cd47b67b8f90052e..885f5de1c006d9dbbec5ab3dc640ef9c626950fd 100644 (file)
@@ -67,9 +67,11 @@ public:
     IpsContext(const IpsContext&) = delete;
     IpsContext& operator=(const IpsContext&) = delete;
 
+    void setup();
+    void clear();
+
     void set_context_data(unsigned id, IpsContextData*);
     IpsContextData* get_context_data(unsigned id) const;
-    void clear_context_data();
 
     void snapshot_flow(Flow*);
 
@@ -79,6 +81,9 @@ public:
     SnortProtocolId get_snort_protocol_id()
     { return flow.proto_id; }
 
+    void disable_detection();
+    void disable_inspection();
+
     enum ActiveRules
     { NONE, NON_CONTENT, CONTENT };
 
@@ -170,6 +175,7 @@ private:
     std::vector<Callback> post_callbacks;
     IpsContext* depends_on;
     IpsContext* next_to_process;
+    bool remove_gadget;
 };
 }
 #endif
index 1f5a37a1b23543197a39d0c6377aa28151871d3b..0fcd598fb20ff1d8ac1f787f5a2713b803b8e827 100644 (file)
@@ -72,8 +72,10 @@ public:
     virtual bool is_sequenced(uint8_t /*dir*/) { return true; }
     virtual bool are_packets_missing(uint8_t /*dir*/) { return true; }
 
+    virtual void disable_reassembly(snort::Flow*) { }
     virtual uint8_t get_reassembly_direction() { return SSN_DIR_NONE; }
     virtual uint8_t missing_in_reassembled(uint8_t /*dir*/) { return SSN_MISSING_NONE; }
+
     virtual bool set_packet_action_to_hold(snort::Packet*) { return false; }
 
 protected:
index d6dffc84c9810ff6c7c69f91bd9e7f018ac83342..a53c2a1343828a0ee5c913dbb534dce76fc90c03 100644 (file)
@@ -102,9 +102,7 @@ public:
     bool is_inactive();
 
     void set_service(SnortProtocolId snort_protocol_id_param)
-    {
-        snort_protocol_id = snort_protocol_id_param;
-    }
+    { snort_protocol_id = snort_protocol_id_param; }
 
     SnortProtocolId get_service() { return snort_protocol_id; }
 
@@ -136,6 +134,15 @@ public:
 
     const char* get_name();
 
+    virtual bool is_control_channel() const
+    { return false; }
+
+    virtual bool can_carve_files() const
+    { return false; }
+
+    virtual bool can_start_tls() const
+    { return false; }
+
 public:
     static unsigned max_slots;
     static THREAD_LOCAL unsigned slot;
index c6a2aa8bebac86c533d1b070c6ff37a347dc2bc6..5782b087360fac070b7a967e14bb4d7df755877a 100644 (file)
@@ -99,7 +99,7 @@ struct PerfConfig
     std::vector<snort::Module*> mods_to_prep;
     PerfConstraints* constraints;
 
-    PerfConfig() { constraints = new PerfConstraints; } 
+    PerfConfig() { constraints = new PerfConstraints; }
     ~PerfConfig() { delete constraints; }
 
     bool resolve();
index 4ccc0504b556a2e56d824f8fd1673cc07e753d7b..4ffc824ccdeadbab61c0bd7286c67332c3e416b7 100644 (file)
@@ -256,9 +256,10 @@ public:
     void eval(Packet*) override;
 
     class StreamSplitter* get_splitter(bool c2s) override
-    {
-        return new CipSplitter(c2s);
-    }
+    { return new CipSplitter(c2s); }
+
+    bool is_control_channel() const override
+    { return true; }
 
 private:
     CipProtoConf* config;
index 4b165a57385aa65dbbc5e3ace262623d4ff51b6b..9fc6e14650ca8c0e0c45a899a30f11f0d55f7d0b 100644 (file)
@@ -324,10 +324,12 @@ public:
     void show(SnortConfig*) override;
     void eval(Packet*) override;
     void clear(Packet*) override;
+
     StreamSplitter* get_splitter(bool c2s) override
-    {
-        return new Dce2SmbSplitter(c2s);
-    }
+    { return new Dce2SmbSplitter(c2s); }
+
+    bool can_carve_files() const override
+    { return true; }
 
 private:
     dce2SmbProtoConf config;
index 6ece3faa094ddd8471966fa6506bbd481b9a7775..b89a4bb8003db427a6a618546ca05d8c517b3dc9 100644 (file)
@@ -217,6 +217,12 @@ public:
     void eval(Packet*) override;
     StreamSplitter* get_splitter(bool) override;
 
+    bool is_control_channel() const override
+    { return true; }
+
+    bool can_start_tls() const override
+    { return true; }
+
     FTP_SERVER_PROTO_CONF* ftp_server;
 };
 
index a5f05d04470a7a8bb118c3ad8a6e3bd66dc78a99..a75d8a0f5a65b020ce3dbf339c0ae3ff6a88ff7e 100644 (file)
@@ -245,6 +245,9 @@ public:
 
     void eval(Packet*) override;
     StreamSplitter* get_splitter(bool to_server) override;
+
+    bool can_carve_files() const override
+    { return true; }
 };
 
 class FtpDataModule : public Module
index cb3b1d9a7bcfc6e1327a149170c9b97e6e63a6d8..83aa87f1a9f0016b89defa010aaf4adbf07c9799 100644 (file)
@@ -36,10 +36,12 @@ public:
         expected_seg_size = 0;
     }
 
-
     Status scan(snort::Packet*, const uint8_t*, uint32_t len, uint32_t flags, uint32_t* fp ) override;
     bool finish(snort::Flow*) override;
 
+    bool is_paf() override
+    { return true; }
+
 private:
     uint16_t min;
     uint16_t segs;
index 38db7caa8f5cc2b6ceb4684d6e3fc5bc5b944fd9..10904e9758c88499bf790972234b00ac97265e7d 100644 (file)
@@ -47,10 +47,12 @@ public:
     bool configure(snort::SnortConfig*) override;
     void eval(snort::Packet* p) override;
     void clear(snort::Packet* p) override;
+
     Http2StreamSplitter* get_splitter(bool is_client_to_server) override
-    {
-        return new Http2StreamSplitter(is_client_to_server);
-    }
+    { return new Http2StreamSplitter(is_client_to_server); }
+
+    bool can_carve_files() const override
+    { return true; }
 
 private:
     friend Http2Api;
index 356ecda7a1d416df7106928f53fb5c1596a14672..1c51e1474b8df31d8e419c625d4a8ba3032bbeec 100644 (file)
@@ -54,13 +54,16 @@ public:
     void show(snort::SnortConfig*) override;
     void eval(snort::Packet* p) override;
     void clear(snort::Packet* p) override;
+
     HttpStreamSplitter* get_splitter(bool is_client_to_server) override
-    {
-        return new HttpStreamSplitter(is_client_to_server, this);
-    }
+    { return new HttpStreamSplitter(is_client_to_server, this); }
+
+    bool can_carve_files() const override
+    { return true; }
+
     static HttpEnums::InspectSection get_latest_is(const snort::Packet* p);
     static HttpCommon::SourceId get_latest_src(const snort::Packet* p);
-    void disable_detection(snort::Packet *p);
+    void disable_detection(snort::Packetp);
 
     // Callbacks that provide "extra data"
     static int get_xtra_trueip(snort::Flow*, uint8_t**, uint32_t*, uint32_t*);
index 04b408142c77f53d04c2213d5f0e8f10a0d3309f..49be2d494e5ec43ad584039e354dd06f4628ad62 100644 (file)
@@ -362,10 +362,12 @@ const StreamBuffer HttpStreamSplitter::reassemble(Flow* flow, unsigned total,
 
     HttpModule::increment_peg_counts(PEG_REASSEMBLE);
 
-    const bool is_body = (session_data->section_type[source_id] == SEC_BODY_CHUNK) ||
-                         (session_data->section_type[source_id] == SEC_BODY_CL) ||
-                         (session_data->section_type[source_id] == SEC_BODY_OLD) ||
-                         (session_data->section_type[source_id] == SEC_BODY_H2);
+    const bool is_body =
+        (session_data->section_type[source_id] == SEC_BODY_CHUNK) ||
+        (session_data->section_type[source_id] == SEC_BODY_CL) ||
+        (session_data->section_type[source_id] == SEC_BODY_OLD) ||
+        (session_data->section_type[source_id] == SEC_BODY_H2);
+
     uint8_t*& buffer = session_data->section_buffer[source_id];
     if (buffer == nullptr)
     {
index 87b596b9757501ea7100d2694d2947fbb3794395..001f8e9c0851c68cdee73bedbf3f84414ef949f4 100644 (file)
@@ -700,6 +700,12 @@ public:
     StreamSplitter* get_splitter(bool c2s) override
     { return new ImapSplitter(c2s); }
 
+    bool can_carve_files() const override
+    { return true; }
+
+    bool can_start_tls() const override
+    { return true; }
+
 private:
     IMAP_PROTO_CONF* config;
 };
index 9eac981c7f1607b1e522f41c24c4b20ea61492b7..4819da9e86b502b31f4884badadf8933c0d65813 100644 (file)
@@ -641,6 +641,12 @@ public:
     StreamSplitter* get_splitter(bool c2s) override
     { return new PopSplitter(c2s); }
 
+    bool can_carve_files() const override
+    { return true; }
+
+    bool can_start_tls() const override
+    { return true; }
+
 private:
     POP_PROTO_CONF* config;
 };
index 74e916845c13c563e95946e1f7841b2517bada0f..6902a05f9daf20e42b419255c6d8e0e557548b0f 100644 (file)
@@ -199,6 +199,9 @@ public:
     class StreamSplitter* get_splitter(bool to_server) override
     { return new SipSplitter(to_server); }
 
+    bool is_control_channel() const override
+    { return true; }
+
 private:
     SIP_PROTO_CONF* config;
 };
index 3aea12cef0a758ca16f5b95c36854028b63de8ef..c6b0eb04ee2fc51bc33346ba41b422a5c696c3b2 100644 (file)
@@ -1410,6 +1410,12 @@ public:
     StreamSplitter* get_splitter(bool c2s) override
     { return new SmtpSplitter(c2s, config->max_auth_command_line_len); }
 
+    bool can_carve_files() const override
+    { return true; }
+
+    bool can_start_tls() const override
+    { return true; }
+
     void ProcessSmtpCmdsList(const SmtpCmd*);
 
 private:
index b017e9d76b2b0f954bc4ad0a9fb4dc849ce70553..c3ef74196560ed24b8151e065a96759eb1d9fa04 100644 (file)
@@ -737,6 +737,12 @@ void Stream::set_extra_data(
     flow->session->set_extra_data(p, flag);
 }
 
+void Stream::disable_reassembly(Flow* flow)
+{
+    assert(flow && flow->session);
+    return flow->session->disable_reassembly(flow);
+}
+
 char Stream::get_reassembly_direction(Flow* flow)
 {
     assert(flow && flow->session);
index 50cd483c0af0e24c0fd0133cee0e50f8e35e1c3f..1a893c18993a51ca0cabf7e80aaeffd7f66c2a3e 100644 (file)
@@ -143,7 +143,7 @@ public:
         Flow*, Packet* p, uint32_t gid, uint32_t sid,
         uint32_t eventId, uint32_t eventSecond);
 
-    // Get reassembly direction for given session
+    static void disable_reassembly(Flow*);
     static char get_reassembly_direction(Flow*);
 
     // Returns true if stream data for the flow is in sequence, otherwise return false.
index ef929c9d4eb45b44fd7e1fa7892115e0faac7f1e..a5b2cbe815c58ba9cb3309cbbf696986be5df983 100644 (file)
@@ -139,6 +139,21 @@ void TcpStreamSession::set_no_ack(bool b)
     }
 }
 
+void TcpStreamSession::disable_reassembly(Flow* f)
+{
+    client.set_splitter((StreamSplitter*)nullptr);
+    server.set_splitter((StreamSplitter*)nullptr);
+
+    client.reassembler.purge_segment_list();
+    server.reassembler.purge_segment_list();
+
+    client.flush_policy = STREAM_FLPOLICY_IGNORE;
+    server.flush_policy = STREAM_FLPOLICY_IGNORE;
+
+    client.finalize_held_packet(f);
+    server.finalize_held_packet(f);
+}
+
 uint8_t TcpStreamSession::get_reassembly_direction()
 {
     uint8_t dir = SSN_DIR_NONE;
index eb4dc54b9607a473da0fa24eada7af47c8c4950e..aaf2d4d717278a9f4e7182b0c8273ae500a32f41 100644 (file)
@@ -29,7 +29,7 @@
 #include "tcp_stream_config.h"
 #include "tcp_stream_tracker.h"
 
-// FIXIT-L session tracking must be split from reassembly
+// FIXIT-L session tracking could be split from reassembly
 // into a separate module a la ip_session.cc and ip_defrag.cc
 // (of course defrag should also be cleaned up)
 class TcpStreamSession : public Session
@@ -40,16 +40,22 @@ public:
     bool setup(snort::Packet*) override;
     void clear() override;
     void cleanup(snort::Packet* = nullptr) override;
+
     void set_splitter(bool, snort::StreamSplitter*) override;
     snort::StreamSplitter* get_splitter(bool) override;
+
     bool is_sequenced(uint8_t /*dir*/) override;
     bool are_packets_missing(uint8_t /*dir*/) override;
+
+    void disable_reassembly(snort::Flow*) override;
     uint8_t get_reassembly_direction() override;
     uint8_t missing_in_reassembled(uint8_t /*dir*/) override;
+
     bool add_alert(snort::Packet*, uint32_t gid, uint32_t sid) override;
     bool check_alerted(snort::Packet*, uint32_t gid, uint32_t sid) override;
     int update_alert(snort::Packet*, uint32_t /*gid*/, uint32_t /*sid*/,
         uint32_t /*event_id*/, uint32_t /*event_second*/) override;
+
     bool set_packet_action_to_hold(snort::Packet*) override;
 
     uint16_t get_mss(bool to_server) const;
index b2e078c495f1d1e88cda7080d3fe2f33a3aa13fc..a0368c55d22e9af7f4f0b6f5a005aa5b81fdda03 100644 (file)
@@ -509,7 +509,7 @@ void TcpStreamTracker::update_tracker_ack_sent(TcpSegmentDescriptor& tsd)
     }
 
     snd_wnd = tsd.get_seg_wnd();
-    reassembler.flush_on_ack_policy(tsd.get_pkt() );
+    reassembler.flush_on_ack_policy(tsd.get_pkt());
 }
 
 bool TcpStreamTracker::update_on_3whs_ack(TcpSegmentDescriptor& tsd)