]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4286: service_inspectors: fix get_buf handling
authorAdrian Mamolea (admamole) <admamole@cisco.com>
Mon, 20 May 2024 08:07:31 +0000 (08:07 +0000)
committerOleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Mon, 20 May 2024 08:07:31 +0000 (08:07 +0000)
Merge in SNORT/snort3 from ~ADMAMOLE/snort3:get_buf_2 to master

Squashed commit of the following:

commit e243f646716bfa8f66330a2a059983274cc59f82
Author: Adrian Mamolea <admamole@cisco.com>
Date:   Thu Apr 4 08:11:09 2024 -0400

    service_inspectors: fix get_buf handling

25 files changed:
src/loggers/alert_fast.cc
src/service_inspectors/dnp3/dnp3.cc
src/service_inspectors/dnp3/dnp3.h
src/service_inspectors/dnp3/ips_dnp3_data.cc
src/service_inspectors/http2_inspect/http2_api.cc
src/service_inspectors/http2_inspect/http2_inspect.cc
src/service_inspectors/http_inspect/http_api.cc
src/service_inspectors/http_inspect/http_api.h
src/service_inspectors/http_inspect/http_msg_section.cc
src/service_inspectors/imap/imap.cc
src/service_inspectors/mms/ips_mms_data.cc
src/service_inspectors/mms/mms.cc
src/service_inspectors/mms/mms.h
src/service_inspectors/modbus/ips_modbus_data.cc
src/service_inspectors/modbus/modbus.cc
src/service_inspectors/modbus/modbus.h
src/service_inspectors/pop/pop.cc
src/service_inspectors/s7commplus/ips_s7comm_content.cc
src/service_inspectors/s7commplus/s7comm.cc
src/service_inspectors/s7commplus/s7comm.h
src/service_inspectors/sip/ips_sip.cc
src/service_inspectors/sip/ips_sip_method.cc
src/service_inspectors/sip/sip.cc
src/service_inspectors/sip/sip.h
src/service_inspectors/smtp/smtp.cc

index cb2d4a30c0dc94cfb7ce566fbddf53f9a5cee880..bccb3c78641f8a8ca098375ae70258b4839505b1 100644 (file)
@@ -58,6 +58,24 @@ static once_flag init_flag;
 #define S_NAME "alert_fast"
 #define F_NAME S_NAME ".txt"
 
+//-------------------------------------------------------------------------
+// translation stuff
+//-------------------------------------------------------------------------
+
+enum BuffersToOutput
+{
+    BUFFERS_NONE = 0,
+    BUFFERS_RULE,
+    BUFFERS_INSPECTOR,
+    BUFFERS_BOTH,
+};
+
+static void param_to_buffers(unsigned param, bool& buffers_rule, bool& buffers_inspector)
+{
+    buffers_rule = param == BUFFERS_RULE or param == BUFFERS_BOTH;
+    buffers_inspector = param == BUFFERS_INSPECTOR or param == BUFFERS_BOTH;
+}
+
 //-------------------------------------------------------------------------
 // module stuff
 //-------------------------------------------------------------------------
@@ -70,8 +88,8 @@ static const Parameter s_params[] =
     { "packet", Parameter::PT_BOOL, nullptr, "false",
       "output packet dump with alert" },
 
-    { "buffers", Parameter::PT_BOOL, nullptr, "false",
-      "output IPS buffer dump" },
+    { "buffers", Parameter::PT_ENUM, "none | rule | inspector | both", "none",
+      "output IPS buffer dump (evaluated by IPS rule or an inspector)" },
 
     { "buffers_depth", Parameter::PT_INT, "0:maxSZ", "0",
       "number of IPS buffer bytes to dump per buffer (0 is unlimited)" },
@@ -101,7 +119,8 @@ public:
     size_t buffers_depth = 0;
     bool file = false;
     bool packet = false;
-    bool buffers = false;
+    bool buffers_rule = false;
+    bool buffers_inspector = false;
 };
 
 bool FastModule::set(const char*, Value& v, SnortConfig*)
@@ -113,7 +132,7 @@ bool FastModule::set(const char*, Value& v, SnortConfig*)
         packet = v.get_bool();
 
     else if ( v.is("buffers") )
-        buffers = v.get_bool();
+        param_to_buffers(v.get_uint8(), buffers_rule, buffers_inspector);
 
     else if ( v.is("limit") )
         limit = v.get_size() * 1024 * 1024;
@@ -129,7 +148,8 @@ bool FastModule::begin(const char*, int, SnortConfig*)
     file = false;
     limit = 0;
     packet = false;
-    buffers = false;
+    buffers_rule = false;
+    buffers_inspector = false;
     buffers_depth = 0;
     return true;
 }
@@ -212,6 +232,31 @@ static void log_ips_buffers(Packet* p, const char** buffs_to_dump, unsigned long
     }
 }
 
+static void log_inspector_buffers(Packet* p, unsigned long depth)
+{
+    if ( !p->flow or !p->flow->gadget )
+        return;
+
+    Inspector* gadget = p->flow->gadget;
+    const char* gadget_name = gadget->get_name();
+    const char** buffers = gadget->get_api()->buffers;
+
+    if ( !buffers )
+        return;
+
+    for ( ; *buffers; buffers++ )
+    {
+        InspectionBuffer buf;
+
+        // FIXIT-E avoid forcing evaluation of JIT buffers
+        if ( gadget->get_buf(*buffers, p, buf) )
+        {
+            int log_depth = depth && depth < buf.len ? depth : buf.len;
+            ObfuscateLogNetData(fast_log, buf.data, log_depth, p, *buffers, *buffers, gadget_name);
+        }
+    }
+}
+
 using BufferIds = std::vector<unsigned>;
 
 //-------------------------------------------------------------------------
@@ -239,7 +284,8 @@ private:
     unsigned long limit;
     unsigned long buffers_depth;
     bool packet;
-    bool log_buffers;
+    bool buffers_rule;
+    bool buffers_inspector;
 
     static std::vector<unsigned> req_ids;
     static std::vector<unsigned> rsp_ids;
@@ -249,7 +295,8 @@ std::vector<unsigned> FastLogger::req_ids;
 std::vector<unsigned> FastLogger::rsp_ids;
 
 FastLogger::FastLogger(FastModule* m) : file(m->file ? F_NAME : "stdout"), limit(m->limit),
-    buffers_depth(m->buffers_depth), packet(m->packet), log_buffers(m->buffers)
+    buffers_depth(m->buffers_depth), packet(m->packet), buffers_rule(m->buffers_rule),
+    buffers_inspector(m->buffers_inspector)
 { }
 
 //-----------------------------------------------------------------
@@ -326,6 +373,9 @@ void FastLogger::alert(Packet* p, const char* msg, const Event& event)
     }
     TextLog_NewLine(fast_log);
     TextLog_Flush(fast_log);
+
+    if ( buffers_inspector )
+        log_inspector_buffers(p, buffers_depth);
 }
 
 // log packet (p) if this is not an http request with one or more buffers
@@ -389,7 +439,7 @@ void FastLogger::log_data(Packet* p, const Event& event)
     if ( buf.len and event.get_gid() != 116 )
         LogNetData(fast_log, buf.data, buf.len, p, "alt");
 
-    if ( log_buffers )
+    if ( buffers_rule )
         log_ips_buffers(p, event.get_buffers(), buffers_depth);
 }
 
index 9f6344c53d533cef016ea2cb3da7017aee7131bb..77d87712c3a5386b5d6da599eedf75f3e683c04c 100644 (file)
 
 using namespace snort;
 
+// Indices in the buffer array exposed by InspectApi
+// Must remain synchronized with dnp3_bufs
+enum Dnp3BufId
+{
+    DNP3_DATA_BUFID = 1
+};
+
 THREAD_LOCAL Dnp3Stats dnp3_stats;
 THREAD_LOCAL ProfileStats dnp3_perf_stats;
 
+bool get_buf_dnp3_data(snort::Packet* p, snort::InspectionBuffer& b)
+{
+    if ((p->has_tcp_data() && !p->is_full_pdu()) || !p->flow || !p->dsize)
+        return false;
+
+    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_flow_data(Dnp3FlowData::inspector_id);
+    if (!fd)
+        return false;
+
+    const dnp3_session_data_t& sd = fd->dnp3_session;
+    const dnp3_reassembly_data_t& rdata = (sd.direction == DNP3_CLIENT) ? sd.client_rdata : sd.server_rdata;
+
+    /* Return a buffer only for complete application-layer fragments */
+    if (rdata.state != DNP3_REASSEMBLY_STATE__DONE)
+        return false;
+
+    b.data = rdata.buffer;
+    b.len = rdata.buflen;
+    b.is_accumulated = false;
+    return true;
+}
+
 Dnp3FlowData::Dnp3FlowData() : FlowData(inspector_id)
 {
     dnp3_stats.concurrent_sessions++;
@@ -200,6 +229,9 @@ public:
     StreamSplitter* get_splitter(bool c2s) override
     { return new Dnp3Splitter(c2s); }
 
+    bool get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b) override
+    { return (id == DNP3_DATA_BUFID) ? get_buf_dnp3_data(p, b) : false; }
+
 private:
     dnp3ProtoConf config;
 };
index 52645d176c79697405f472a8a00888e7465cf1c8..52bf4c81f57fd7ccaeff2c4d00e2799006758ddd 100644 (file)
@@ -184,5 +184,7 @@ public:
 extern THREAD_LOCAL Dnp3Stats dnp3_stats;
 extern THREAD_LOCAL snort::ProfileStats dnp3_perf_stats;
 
+bool get_buf_dnp3_data(snort::Packet* p, snort::InspectionBuffer& b);
+
 #endif
 
index 439637b615862d4c60c05e3608ec8235799044da..9e8ec83eb4f05162b558102c9a415c7bb4e0974c 100644 (file)
@@ -78,27 +78,11 @@ IpsOption::EvalStatus Dnp3DataOption::eval(Cursor& c, Packet* p)
     // cppcheck-suppress unreadVariable
     RuleProfile profile(dnp3_data_perf_stats);
 
-    if ((p->has_tcp_data() && !p->is_full_pdu()) || !p->flow || !p->dsize)
+    InspectionBuffer b;
+    if (!get_buf_dnp3_data(p, b))
         return NO_MATCH;
 
-    Dnp3FlowData* fd = (Dnp3FlowData*)p->flow->get_flow_data(Dnp3FlowData::inspector_id);
-
-    if (!fd)
-        return NO_MATCH;
-
-    dnp3_session_data_t* dnp3_session = &fd->dnp3_session;
-    dnp3_reassembly_data_t* rdata;
-
-    if (dnp3_session->direction == DNP3_CLIENT)
-        rdata = &(dnp3_session->client_rdata);
-    else
-        rdata = &(dnp3_session->server_rdata);
-
-    /* Only evaluate rules against complete Application-layer fragments */
-    if (rdata->state != DNP3_REASSEMBLY_STATE__DONE)
-        return NO_MATCH;
-
-    c.set(s_name,(uint8_t*)rdata->buffer, rdata->buflen);
+    c.set(s_name, b.data, b.len);
 
     return MATCH;
 }
index 0956349954dfd42f40ff952e3737a79be5e439c7..a5c554927432989195f63edede2f5f0ba1518bc5 100644 (file)
@@ -21,8 +21,9 @@
 #include "config.h"
 #endif
 
-#include "http2_api.h"
+#include "service_inspectors/http_inspect/http_api.h"
 
+#include "http2_api.h"
 #include "http2_inspect.h"
 
 using namespace snort;
@@ -42,6 +43,7 @@ const char* Http2Api::classic_buffer_names[] =
     "http2_frame_header",
     "http2_decoded_header",
 #endif
+    HTTP_CLASSIC_BUFFER_NAMES,
     nullptr
 };
 
index 40d7b03ae65a03b0aab48ee396bbdc72140f1498..c44ae0996390a17e54eccf393734c69cf98041c8 100644 (file)
@@ -79,6 +79,9 @@ bool Http2Inspect::get_buf(unsigned id, Packet* p, InspectionBuffer& b)
     if (session_data->stream_in_hi == Http2Enums::NO_STREAM_ID)
         return false;
 
+    if  (id >= HTTP2_BUFFER__MAX)
+        return session_data->hi->get_buf(id - HTTP2_BUFFER__MAX + 1, p, b);
+
     Http2Stream* const stream = session_data->find_processing_stream();
     assert(stream != nullptr);
     const Field& buffer = stream->get_buf(id);
index 27d9309e1de5abfc819020795a184ecc6e597d20..c7831a0c8f73b1ba423bfc80beccb78761dfda27 100644 (file)
@@ -49,27 +49,7 @@ void HttpApi::http_init()
 
 const char* HttpApi::classic_buffer_names[] =
 {
-    "file_data",
-    "http_client_body",
-    "http_cookie",
-    "http_header",
-    "http_method",
-    "http_param",
-    "http_raw_body",
-    "http_raw_cookie",
-    "http_raw_header",
-    "http_raw_request",
-    "http_raw_status",
-    "http_raw_trailer",
-    "http_raw_uri",
-    "http_stat_code",
-    "http_stat_msg",
-    "http_trailer",
-    "http_true_ip",
-    "http_uri",
-    "http_version",
-    "js_data",
-    "vba_data",
+    HTTP_CLASSIC_BUFFER_NAMES,
     nullptr
 };
 
index 1ad901ca4974a6105e982b9fa88572c73f045550..dc58d332728c408fafbbb052322eb8f81d62d2a7 100644 (file)
 #include "http_flow_data.h"
 #include "http_module.h"
 
+#define HTTP_CLASSIC_BUFFER_NAMES \
+    "file_data",                  \
+    "http_client_body",           \
+    "http_cookie",                \
+    "http_header",                \
+    "http_method",                \
+    "http_param",                 \
+    "http_raw_body",              \
+    "http_raw_cookie",            \
+    "http_raw_header",            \
+    "http_raw_request",           \
+    "http_raw_status",            \
+    "http_raw_trailer",           \
+    "http_raw_uri",               \
+    "http_stat_code",             \
+    "http_stat_msg",              \
+    "http_trailer",               \
+    "http_true_ip",               \
+    "http_uri",                   \
+    "http_version",               \
+    "js_data",                    \
+    "vba_data"
+
 class HttpApi
 {
 public:
index b578440dac7737993664f09dff7de617e6f3bfa9..c93e03db75ba62c0d5566d1975fab4800cfc13e6 100644 (file)
@@ -283,7 +283,7 @@ const Field& HttpMsgSection::get_classic_buffer(const HttpBufferInfo& buf)
             return Field::FIELD_NULL;
     }
     default:
-        assert(false);
+        assert(buf.type <= HTTP__BUFFER_MAX);
         return Field::FIELD_NULL;
     }
 }
index 5617f46c3ec48be0aa72948b65513c18be4acef4..cd5b4e677ae0268c889845e6365574882b497f3b 100644 (file)
 
 using namespace snort;
 
+// Indices in the buffer array exposed by InspectApi
+// Must remain synchronized with imap_bufs
+enum ImapBufId
+{
+    IMAP_FILE_DATA_ID = 1, IMAP_VBA_DATA_ID, IMAP_JS_DATA_ID
+};
+
 THREAD_LOCAL ProfileStats imapPerfStats;
 THREAD_LOCAL ImapStats imapstats;
 
@@ -763,6 +770,7 @@ public:
     bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
     bool get_fp_buf(snort::InspectionBuffer::Type ibt, snort::Packet* p,
         snort::InspectionBuffer& b) override;
+    bool get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b) override;
 
 private:
     IMAP_PROTO_CONF* config;
@@ -860,6 +868,21 @@ bool Imap::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b
     return get_buf(ibt, p, b);
 }
 
+bool Imap::get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b)
+{
+    switch (id)
+    {
+    case IMAP_FILE_DATA_ID:
+        return false;
+    case IMAP_VBA_DATA_ID:
+        return get_buf(InspectionBuffer::IBT_VBA, p, b);
+    case IMAP_JS_DATA_ID:
+        return get_buf(InspectionBuffer::IBT_JS_DATA, p, b);
+    default:
+        return false;
+    }
+}
+
 //-------------------------------------------------------------------------
 // api stuff
 //-------------------------------------------------------------------------
index 9402b3d3d4309747fd2ba0da2e90bf1ae07e112c..2109ced33e3a70dc9702899c1e2c838824fec7c9 100644 (file)
@@ -58,34 +58,11 @@ IpsOption::EvalStatus MmsDataOption::eval(Cursor& c, Packet* p)
     // cppcheck-suppress unreadVariable
     RuleProfile profile(mms_data_prof);
 
-    if (!p->flow)
-    {
-        return NO_MATCH;
-    }
-
-    // not including any checks for a full PDU as we're not guaranteed to
-    // have one with the available pipelining options to get to MMS
-
-    MmsFlowData* mmsfd = (MmsFlowData*)p->flow->get_flow_data(MmsFlowData::inspector_id);
-
-    if (!mmsfd)
-    {
-        return NO_MATCH;
-    }
-
-    if (!mmsfd->is_mms_found())
-    {
-        return NO_MATCH;
-    }
-
-    if (mmsfd->get_mms_offset() >= p->dsize)
-    {
+    InspectionBuffer b;
+    if (!get_buf_mms_data(p, b))
         return NO_MATCH;
-    }
 
-    // setting the cursor to the offset previously determined by util_tpkt
-    // to be the start of the MMS message
-    c.set(s_name, p->data + mmsfd->get_mms_offset(), p->dsize - mmsfd->get_mms_offset());
+    c.set(s_name, b.data, b.len);
 
     return MATCH;
 }
index 9c7506d4430ea61577e5c6637b7389bf881c926c..cca73ce6d6227e05fcc8a9ab2d7bee3456e45b45 100644 (file)
 
 using namespace snort;
 
+// Indices in the buffer array exposed by InspectApi
+// Must remain synchronized with mms_bufs
+enum MmsBufId
+{
+    MMS_DATA_BUFID = 1
+};
+
 THREAD_LOCAL MmsStats mms_stats;
 
+bool get_buf_mms_data(snort::Packet* p, snort::InspectionBuffer& b)
+{
+    if (!p->flow)
+        return false;
+
+    // not including any checks for a full PDU as we're not guaranteed to
+    // have one with the available pipelining options to get to MMS
+    MmsFlowData* mmsfd = (MmsFlowData*)p->flow->get_flow_data(MmsFlowData::inspector_id);
+    if (!mmsfd or !mmsfd->is_mms_found() or mmsfd->get_mms_offset() >= p->dsize)
+        return false;
+
+    // setting the cursor to the offset previously determined by util_tpkt
+    // to be the start of the MMS message
+    b.data = p->data + mmsfd->get_mms_offset();
+    b.len = p->dsize - mmsfd->get_mms_offset();
+    b.is_accumulated = false;
+    return true;
+}
+
 //-------------------------------------------------------------------------
 // flow stuff
 //-------------------------------------------------------------------------
@@ -83,6 +109,11 @@ public:
     {
         return new MmsSplitter(c2s);
     }
+
+    bool get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b) override
+    {
+        return (id == MMS_DATA_BUFID) ? get_buf_mms_data(p, b) : false;
+    }
 };
 
 void Mms::eval(Packet* p)
index b47f40b56ca2fd4547ccb04882d92873b84415f8..d30af461441d810cfcd39a1fcb787d806cf8ee98 100644 (file)
@@ -108,6 +108,7 @@ enum MmsMsgType
 };
 
 extern THREAD_LOCAL MmsStats mms_stats;
+bool get_buf_mms_data(snort::Packet* p, snort::InspectionBuffer& b);
 
 #endif
 
index d7d7192267dfc871ac54162f798cfd51bd107f99..1a1f059208c3192601811cbcb2b3b99757c4ef91 100644 (file)
@@ -30,6 +30,7 @@
 #include "profiler/profiler.h"
 #include "protocols/packet.h"
 
+#include "modbus.h"
 #include "modbus_decode.h"
 
 using namespace snort;
@@ -75,16 +76,11 @@ IpsOption::EvalStatus ModbusDataOption::eval(Cursor& c, Packet* p)
 {
     RuleProfile profile(modbus_data_prof);  // cppcheck-suppress unreadVariable
 
-    if ( !p->flow )
+    InspectionBuffer b;
+    if (!get_buf_modbus_data(p, b))
         return NO_MATCH;
 
-    if ( !p->is_full_pdu() )
-        return NO_MATCH;
-
-    if ( p->dsize < MODBUS_MIN_LEN )
-        return NO_MATCH;
-
-    c.set(s_name, p->data + MODBUS_MIN_LEN, p->dsize - MODBUS_MIN_LEN);
+    c.set(s_name, b.data, b.len);
 
     return MATCH;
 }
index 80efed276793bef933acd1e9b31b80256205cbf5..35a3c4b545e901c043cb2a2541309e3ab7b8c005 100644 (file)
@@ -36,6 +36,23 @@ using namespace snort;
 
 THREAD_LOCAL ModbusStats modbus_stats;
 
+// Indices in the buffer array exposed by InspectApi
+// Must remain synchronized with modbus_bufs
+enum ModbusBufId
+{
+     MODBUS_DATA_BUFID = 1
+};
+
+bool get_buf_modbus_data(Packet* p, InspectionBuffer& b)
+{
+    if ( !p->is_full_pdu() or p->dsize < MODBUS_MIN_LEN )
+        return false;
+
+    b.data = p->data + MODBUS_MIN_LEN;
+    b.len = p->dsize - MODBUS_MIN_LEN;
+    return true;
+}
+
 //-------------------------------------------------------------------------
 // flow stuff
 //-------------------------------------------------------------------------
@@ -70,7 +87,10 @@ class Modbus : public Inspector
 public:
     // default ctor / dtor
     void eval(Packet*) override;
-    bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
+    bool get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b) override
+    { return (ibt == InspectionBuffer::IBT_BODY) ? get_buf_modbus_data(p, b) : false; }
+    bool get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b) override
+    { return (id == MODBUS_DATA_BUFID) ? get_buf_modbus_data(p, b) : false; }
 
     int get_message_type(int version, const char* name);
     int get_info_type(int version, const char* name);
@@ -118,16 +138,6 @@ void Modbus::eval(Packet* p)
         mfd->reset();
 }
 
-bool Modbus::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
-{
-    if ( ibt !=  InspectionBuffer::IBT_BODY or p->dsize <= MODBUS_MIN_LEN )
-        return false;
-
-    b.data = p->data + MODBUS_MIN_LEN;
-    b.len = p->dsize - MODBUS_MIN_LEN;
-    return true;
-}
-
 //-------------------------------------------------------------------------
 // plugin stuff
 //-------------------------------------------------------------------------
index 35a85ae3b7fcdd619eebd939e2754eacdc01d484..3a4c13f27e6e9ea7fc51bf0c5a7c66de82342775 100644 (file)
@@ -63,6 +63,7 @@ int get_message_type(int version, const char* name);
 int get_info_type(int version, const char* name);
 
 extern THREAD_LOCAL ModbusStats modbus_stats;
+bool get_buf_modbus_data(snort::Packet* p, snort::InspectionBuffer& b);
 
 #endif
 
index cfea8852aedfda1b747d95653872f65aefa7c50a..fc82f8a445cca77046c7847ae05b943fa1339916 100644 (file)
 
 using namespace snort;
 
+// Indices in the buffer array exposed by InspectApi
+// Must remain synchronized with pop_bufs
+enum PopBufId
+{
+    POP_FILE_DATA_ID = 1, POP_VBA_DATA_ID, POP_JS_DATA_ID
+};
+
 THREAD_LOCAL ProfileStats popPerfStats;
 THREAD_LOCAL PopStats popstats;
 
@@ -699,8 +706,7 @@ public:
     { return true; }
 
     bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&) override;
-    bool get_fp_buf(snort::InspectionBuffer::Type ibt, snort::Packet* p,
-        snort::InspectionBuffer& b) override;
+    bool get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b) override;
 
 private:
     POP_PROTO_CONF* config;
@@ -791,9 +797,19 @@ bool Pop::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
     return dst && dst_len;
 }
 
-bool Pop::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
+bool Pop::get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b)
 {
-    return get_buf(ibt, p, b);
+    switch (id)
+    {
+    case POP_FILE_DATA_ID:
+        return false;
+    case POP_VBA_DATA_ID:
+        return get_buf(InspectionBuffer::IBT_VBA, p, b);
+    case POP_JS_DATA_ID:
+        return get_buf(InspectionBuffer::IBT_JS_DATA, p, b);
+    default:
+        return false;
+    }
 }
 
 //-------------------------------------------------------------------------
index 15405ab3fba0498c16d2b9be10e36e99040d3f03..5756e36a5612cf6870b3bbcbfc8e6a8e5669ca68 100644 (file)
@@ -30,6 +30,7 @@
 #include "profiler/profiler.h"
 #include "protocols/packet.h"
 
+#include "s7comm.h"
 #include "s7comm_decode.h"
 
 using namespace snort;
@@ -75,16 +76,11 @@ IpsOption::EvalStatus S7commplusContentOption::eval(Cursor& c, Packet* p)
 {
     RuleProfile profile(s7commplus_content_prof);   // cppcheck-suppress unreadVariable
 
-    if ( !p->flow )
+    InspectionBuffer b;
+    if (!get_buf_s7commplus_content(p, b))
         return NO_MATCH;
 
-    if ( !p->is_full_pdu() )
-        return NO_MATCH;
-
-    if ( p->dsize < S7COMMPLUS_MIN_HDR_LEN )
-        return NO_MATCH;
-
-    c.set(s_name, p->data + S7COMMPLUS_MIN_HDR_LEN, p->dsize - S7COMMPLUS_MIN_HDR_LEN);
+    c.set(s_name, b.data, b.len);
 
     return MATCH;
 }
index 007e430a6858cbf8ec79db6ce0f7caac63066ce0..e3b30005d9e550b722a6f4291788a11a4466b5e3 100644 (file)
 
 using namespace snort;
 
+#define S7COMMPLUS_CONTENT_BUFID 1
+
 THREAD_LOCAL S7commplusStats s7commplus_stats;
 
+bool get_buf_s7commplus_content(Packet* p, InspectionBuffer& b)
+{
+    if ( !p->is_full_pdu() or p->dsize < S7COMMPLUS_MIN_HDR_LEN )
+        return false;
+
+    b.data = p->data + S7COMMPLUS_MIN_HDR_LEN;
+    b.len = p->dsize - S7COMMPLUS_MIN_HDR_LEN;
+    b.is_accumulated = false;
+    return true;
+}
+
 //-------------------------------------------------------------------------
 // flow stuff
 //-------------------------------------------------------------------------
@@ -76,6 +89,9 @@ public:
 
     StreamSplitter* get_splitter(bool c2s) override
     { return new S7commplusSplitter(c2s); }
+
+    bool get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b) override
+    { return ( id == S7COMMPLUS_CONTENT_BUFID ) ? get_buf_s7commplus_content(p, b) : false; }
 };
 
 void S7commplus::eval(Packet* p)
@@ -113,7 +129,7 @@ void S7commplus::eval(Packet* p)
     // evaluating on the first PDU. Setting this flag stops the caching.
     p->packet_flags |= PKT_ALLOW_MULTIPLE_DETECT;
 
-    if ( !S7commplusDecode(p, mfd))
+    if ( !S7commplusDecode(p, mfd) )
         mfd->reset();
 }
 
index b77b936ed1d8482fc29bf6e73c9a8d0629f6d46c..2a0a7db9ef4d4566a5a457962acb5d76a4e9e4e5 100644 (file)
@@ -73,6 +73,7 @@ int get_message_type(int version, const char* name);
 int get_info_type(int version, const char* name);
 
 extern THREAD_LOCAL S7commplusStats s7commplus_stats;
+bool get_buf_s7commplus_content(snort::Packet* p, snort::InspectionBuffer& b);
 
 #endif
 
index 58e271d417c20836b5261d05398dc9d97cfd96a6..1a1ec8f87418116bea3a8439670bd59fabb9c830 100644 (file)
@@ -91,6 +91,7 @@ public:
     EvalStatus eval(Cursor&, Packet*) override;
 
 private:
+    unsigned get_bufid() const { return (idx == SIP_HEADER) ? SIP_HEADER_ID : SIP_BODY_ID; }
     const char* key;
     CursorActionType cat;
     SipIdx idx;
@@ -98,42 +99,14 @@ private:
 
 IpsOption::EvalStatus SipIpsOption::eval(Cursor& c, Packet* p)
 {
-    RuleProfile profile(sip_ps[idx]);
+    RuleProfile profile(sip_ps[idx]);  // cppcheck-suppress unreadVariable
 
-    if ((!p->has_tcp_data() && !p->is_udp()) || !p->flow || !p->dsize)
-        return NO_MATCH;
+    InspectionBuffer b;
+    if (!get_buf_sip(get_bufid(), p, b))
+         return NO_MATCH;
 
-    // FIXIT-P cache id at parse time for runtime use
-    SIPData* sd = get_sip_session_data(p->flow);
-
-    if (!sd)
-        return NO_MATCH;
-
-    SIP_Roptions* ropts = &sd->ropts;
-    const uint8_t* data = nullptr;
-    unsigned len = 0;
-
-    switch (idx)
-    {
-    case SIP_HEADER:
-        data = ropts->header_data;
-        len = ropts->header_len;
-        break;
-    case SIP_BODY:
-        data = ropts->body_data;
-        len = ropts->body_len;
-        break;
-    default:
-        break;
-    }
-
-    if (data != nullptr)
-    {
-        c.set(key, data, len);
-        return MATCH;
-    }
-
-    return NO_MATCH;
+    c.set(key, b.data, b.len);
+    return MATCH;
 }
 
 //-------------------------------------------------------------------------
index bff4af3c0b7c83c2a4cb58b5344f7beb0817aa43..ed3a62c659ca5aa4f6b803bba19e194bbb0d007c 100644 (file)
@@ -102,7 +102,7 @@ IpsOption::EvalStatus SipMethodOption::eval(Cursor&, Packet* p)
 {
     RuleProfile profile(sipMethodRuleOptionPerfStats);  // cppcheck-suppress unreadVariable
 
-    if ( !p->flow )
+    if ((!p->has_tcp_data() && !p->is_udp()) || !p->flow || !p->dsize)
         return NO_MATCH;
 
     SIPData* sd = get_sip_session_data(p->flow);
index ba3c2a82432ab1272450fdeabbcde90d7f6995a0..e04afbae4cef81f28c13480df80fa0d5e539eb99 100644 (file)
@@ -44,6 +44,33 @@ static void FreeSipData(void*);
 unsigned SipFlowData::inspector_id = 0;
 unsigned SIPData::pub_id = 0;
 
+bool get_buf_sip(unsigned id, snort::Packet* p, snort::InspectionBuffer& b)
+{
+    if (id != SIP_HEADER_ID and id != SIP_BODY_ID)
+        return false;
+
+    if ((!p->has_tcp_data() and !p->is_udp()) or !p->flow or !p->dsize)
+        return false;
+
+    if (p->has_tcp_data() and !p->is_full_pdu())
+        return false;
+
+    SIPData* sd = get_sip_session_data(p->flow);
+    if (!sd)
+        return false;
+
+    const SIP_Roptions& ropts = sd->ropts;
+    const uint8_t* data = (id == SIP_HEADER_ID) ? ropts.header_data : ropts.body_data;
+    unsigned len = (id == SIP_HEADER_ID) ? ropts.header_len : ropts.body_len;
+    if (!data or !len)
+        return false;
+
+    b.data = data;
+    b.len = len;
+    b.is_accumulated = false;
+    return true;
+}
+
 SipFlowData::SipFlowData() : FlowData(inspector_id)
 {
     memset(&session, 0, sizeof(session));
@@ -115,7 +142,7 @@ static inline int SIP_Process(Packet* p, SIPData* sessp, SIP_PROTO_CONF* config)
     bool status;
     const char* sip_buff = (const char*)p->data;
     const char* end;
-    SIP_Roptions* pRopts;
+    SIP_Roptions* pRopts = &(sessp->ropts);
     SIPMsg sipMsg;
 
     memset(&sipMsg, 0, SIPMSG_ZERO_LEN);
@@ -127,13 +154,13 @@ static inline int SIP_Process(Packet* p, SIPData* sessp, SIP_PROTO_CONF* config)
 
     status = sip_parse(&sipMsg, sip_buff, end, config);
 
+    memset(pRopts, 0, sizeof(*pRopts));
     if (true == status)
     {
         /*Update the dialog state*/
         SIP_updateDialog(sipMsg, &(sessp->dialogs), p, config);
     }
     /*Update the session data*/
-    pRopts = &(sessp->ropts);
     pRopts->method_data = sipMsg.method;
     pRopts->method_len = sipMsg.methodLen;
     pRopts->header_data = sipMsg.header;
@@ -194,6 +221,9 @@ public:
     bool is_control_channel() const override
     { return true; }
 
+    bool get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b) override
+    { return get_buf_sip(id, p, b); }
+
 private:
     SIP_PROTO_CONF* config;
 };
index a89cd38eaca5216283c2a6e80cc7c31b9ec13b15..6b7d50271b1745eefebb414203c1070eab3d9166 100644 (file)
@@ -57,4 +57,13 @@ public:
 SIPData* get_sip_session_data(const snort::Flow*);
 SIPMethodNode* add_sip_method(const char*);
 
+// Indices in the buffer array exposed by InspectApi
+// Must remain synchronized with sip_bufs
+enum SipBufId
+{
+    SIP_HEADER_ID = 1, SIP_BODY_ID
+};
+
+bool get_buf_sip(unsigned id, snort::Packet* p, snort::InspectionBuffer& b);
+
 #endif
index 3375336294f47d921c6c907b59ec7f9031243cf0..cdcff88b17bff5679f8effc385c9d6206f6e4aa4 100644 (file)
 
 using namespace snort;
 
+// Indices in the buffer array exposed by InspectApi
+// Must remain synchronized with smtp_bufs
+enum SmtpBufId
+{
+    SMTP_FILE_DATA_ID = 1, SMTP_VBA_DATA_ID, SMTP_JS_DATA_ID
+};
+
 THREAD_LOCAL ProfileStats smtpPerfStats;
 THREAD_LOCAL SmtpStats smtpstats;
 THREAD_LOCAL bool smtp_normalizing;
@@ -1531,7 +1538,8 @@ public:
 
     void ProcessSmtpCmdsList(const SmtpCmd*);
 
-    bool get_fp_buf(snort::InspectionBuffer::Type, snort::Packet*, snort::InspectionBuffer&) override;
+    bool get_buf(snort::InspectionBuffer::Type, snort::Packet*, snort::InspectionBuffer&) override;
+    bool get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b) override;
 
 private:
     SmtpProtoConf* config;
@@ -1623,7 +1631,7 @@ void Smtp::ProcessSmtpCmdsList(const SmtpCmd* sc)
         config->cmd_config[id].max_line_len = sc->number;
 }
 
-bool Smtp::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
+bool Smtp::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
 {
     SMTPData* smtp_ssn = get_session_data(p->flow);
 
@@ -1667,6 +1675,21 @@ bool Smtp::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b
     return dst && dst_len;
 }
 
+bool Smtp::get_buf(unsigned id, snort::Packet* p, snort::InspectionBuffer& b)
+{
+    switch (id)
+    {
+    case SMTP_FILE_DATA_ID:
+        return false;
+    case SMTP_VBA_DATA_ID:
+        return get_buf(InspectionBuffer::IBT_VBA, p, b);
+    case SMTP_JS_DATA_ID:
+        return get_buf(InspectionBuffer::IBT_JS_DATA, p, b);
+    default:
+        return false;
+    }
+}
+
 //-------------------------------------------------------------------------
 // api stuff
 //-------------------------------------------------------------------------