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
if (GRE_SEQ(greh_out))
{
uint16_t len = 4; // Flags, version and protocol
-
+
if (GRE_CHKSUM(greh_out))
len += 4;
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());
}
c->packet->action = &c->packet->action_inst;
c->state = IpsContext::BUSY;
+ c->setup();
+
busy.emplace_back(c);
}
"(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;
c->abort();
c->state = IpsContext::IDLE;
c->clear_callbacks();
- c->clear_context_data();
+ c->clear();
idle.emplace_back(c);
}
non_flow_chain.abort();
idle.pop_back();
c->state = IpsContext::BUSY;
+ c->setup();
+
busy.emplace_back(c);
return c;
}
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);
#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"
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());
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;
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
//--------------------------------------------------------------------------
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*);
SnortProtocolId get_snort_protocol_id()
{ return flow.proto_id; }
+ void disable_detection();
+ void disable_inspection();
+
enum ActiveRules
{ NONE, NON_CONTENT, CONTENT };
std::vector<Callback> post_callbacks;
IpsContext* depends_on;
IpsContext* next_to_process;
+ bool remove_gadget;
};
}
#endif
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:
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; }
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;
std::vector<snort::Module*> mods_to_prep;
PerfConstraints* constraints;
- PerfConfig() { constraints = new PerfConstraints; }
+ PerfConfig() { constraints = new PerfConstraints; }
~PerfConfig() { delete constraints; }
bool resolve();
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;
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;
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;
};
void eval(Packet*) override;
StreamSplitter* get_splitter(bool to_server) override;
+
+ bool can_carve_files() const override
+ { return true; }
};
class FtpDataModule : public Module
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;
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;
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::Packet* p);
// Callbacks that provide "extra data"
static int get_xtra_trueip(snort::Flow*, uint8_t**, uint32_t*, uint32_t*);
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)
{
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;
};
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;
};
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;
};
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:
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);
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.
}
}
+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;
#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
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;
}
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)