From: Rishabh Choudhary (rishacho) Date: Mon, 22 Jul 2024 05:15:21 +0000 (+0000) Subject: Pull request #4374: sip: fallback functionality for sip inspector X-Git-Tag: 3.3.2.0~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f49e5255830f2a19124403856447435047e49a6;p=thirdparty%2Fsnort3.git Pull request #4374: sip: fallback functionality for sip inspector Merge in SNORT/snort3 from ~RISHACHO/snort3:sip_fallback to master Squashed commit of the following: commit 99297bb4fd415533b2eb3ca527a165c0f7124510 Author: Rishabh Choudhary Date: Thu Jul 4 22:18:00 2024 +0530 sip: fallback functionality for sip inspector --- diff --git a/src/service_inspectors/sip/sip.cc b/src/service_inspectors/sip/sip.cc index 5407989e8..b0dd6a046 100644 --- a/src/service_inspectors/sip/sip.cc +++ b/src/service_inspectors/sip/sip.cc @@ -198,7 +198,8 @@ static void snort_sip(SIP_PROTO_CONF* config, Packet* p) if (sessp->state_flags & SIP_FLG_MISSED_PACKETS) return; - SIP_Process(p,sessp, config); + if (!SIP_Process(p,sessp, config)) + sessp->sip_aborted = true; } //------------------------------------------------------------------------- diff --git a/src/service_inspectors/sip/sip.h b/src/service_inspectors/sip/sip.h index 6b7d50271..8f09c3b0a 100644 --- a/src/service_inspectors/sip/sip.h +++ b/src/service_inspectors/sip/sip.h @@ -36,6 +36,7 @@ struct SIPData SIP_DialogList dialogs; SIP_Roptions ropts; SIP_PROTO_CONF *sip_config; + bool sip_aborted; static unsigned pub_id; }; diff --git a/src/service_inspectors/sip/sip_config.h b/src/service_inspectors/sip/sip_config.h index f9c704e49..fce232f1d 100644 --- a/src/service_inspectors/sip/sip_config.h +++ b/src/service_inspectors/sip/sip_config.h @@ -57,6 +57,7 @@ struct SipStats PegCount sessions; PegCount concurrent_sessions; PegCount max_concurrent_sessions; + PegCount aborted_sessions; PegCount events; PegCount dialogs; PegCount ignoreChannels; diff --git a/src/service_inspectors/sip/sip_module.cc b/src/service_inspectors/sip/sip_module.cc index de8d4623a..6374570ce 100644 --- a/src/service_inspectors/sip/sip_module.cc +++ b/src/service_inspectors/sip/sip_module.cc @@ -149,6 +149,7 @@ static const PegInfo sip_pegs[] = { CountType::SUM, "sessions", "total sessions" }, { CountType::NOW, "concurrent_sessions", "total concurrent SIP sessions" }, { CountType::MAX, "max_concurrent_sessions", "maximum concurrent SIP sessions" }, + { CountType::SUM, "aborted_sessions", "total session aborted" }, { CountType::SUM, "events", "events generated" }, { CountType::SUM, "dialogs", "total dialogs" }, { CountType::SUM, "ignored_channels", "total channels ignored" }, diff --git a/src/service_inspectors/sip/sip_splitter.cc b/src/service_inspectors/sip/sip_splitter.cc index ff9f7ad9c..e49a2225c 100644 --- a/src/service_inspectors/sip/sip_splitter.cc +++ b/src/service_inspectors/sip/sip_splitter.cc @@ -27,6 +27,10 @@ #include #include +#include "protocols/packet.h" + +#include "sip.h" + using namespace snort; const char SipSplitter::content_len_key[] = "Content-Length"; @@ -167,9 +171,18 @@ void SipSplitter::process_command(const uint8_t ch) } StreamSplitter::Status SipSplitter::scan( - Packet*, const uint8_t* data, uint32_t len, + Packet* pkt, const uint8_t* data, uint32_t len, uint32_t, uint32_t* fp) { + SIPData* sip_sess; + Flow* flow = pkt->flow; + + sip_sess = get_sip_session_data(flow); + if (sip_sess && sip_sess->sip_aborted) { + sip_stats.aborted_sessions++; + return StreamSplitter::ABORT; + } + for (uint32_t i = 0; i < len; i++) { uint8_t ch = data[i]; diff --git a/src/service_inspectors/sip/test/sip_splitter_scan_test.cc b/src/service_inspectors/sip/test/sip_splitter_scan_test.cc index 05351ad73..1b53bbb39 100644 --- a/src/service_inspectors/sip/test/sip_splitter_scan_test.cc +++ b/src/service_inspectors/sip/test/sip_splitter_scan_test.cc @@ -24,6 +24,7 @@ #include "sip_splitter_test.h" #include "log/messages.h" +#include "protocols/packet.h" #include "service_inspectors/sip/sip_splitter.h" #include "stream/stream_splitter.h" @@ -33,6 +34,13 @@ using namespace snort; +Packet::Packet(bool) +{ + memset((char*) this , 0, sizeof(*this)); +} + +Packet::~Packet() = default; + TEST_GROUP(sip_splitter_scan_test) { SipSplitterUT ssut = SipSplitterUT(SipSplitter(true)); @@ -46,7 +54,9 @@ TEST_GROUP(sip_splitter_scan_test) TEST(sip_splitter_scan_test, scan_start_content_len_test) { uint32_t fp = 0; - StreamSplitter::Status ret = ssut.splitter_scan(nullptr, + Packet p(true); + + StreamSplitter::Status ret = ssut.splitter_scan(&p, (const uint8_t *)"0xBEEF0xBEEF\n", 13, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::SEARCH); CHECK_EQUAL(ssut.splitter_get_paf_state(), SIP_PAF_CONTENT_LEN_CMD); @@ -56,7 +66,9 @@ TEST(sip_splitter_scan_test, scan_start_content_len_test) TEST(sip_splitter_scan_test, scan_start_content_len_negative_test) { uint32_t fp = 0; - StreamSplitter::Status ret = ssut.splitter_scan(nullptr, + Packet p(true); + + StreamSplitter::Status ret = ssut.splitter_scan(&p, (const uint8_t *)"0xBEEF0xBEEF", 12, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::SEARCH); CHECK_EQUAL(ssut.splitter_get_paf_state(), SIP_PAF_START_STATE); @@ -66,8 +78,10 @@ TEST(sip_splitter_scan_test, scan_start_content_len_negative_test) TEST(sip_splitter_scan_test, scan_process_cmd_test) { uint32_t fp = 0; + Packet p(true); + ssut.splitter_set_paf_state(SIP_PAF_CONTENT_LEN_CMD); - StreamSplitter::Status ret = ssut.splitter_scan(nullptr, + StreamSplitter::Status ret = ssut.splitter_scan(&p, (const uint8_t *)"C", 1, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::SEARCH); CHECK_EQUAL(ssut.splitter_get_paf_state(), SIP_PAF_CONTENT_LEN_CMD); @@ -78,8 +92,10 @@ TEST(sip_splitter_scan_test, scan_process_cmd_test) TEST(sip_splitter_scan_test, scan_content_len_convert_body_search_test) { uint32_t fp = 0; + Packet p(true); + ssut.splitter_set_paf_state(SIP_PAF_CONTENT_LEN_CONVERT); - StreamSplitter::Status ret = ssut.splitter_scan(nullptr, + StreamSplitter::Status ret = ssut.splitter_scan(&p, (const uint8_t *)"144 ", 4, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::SEARCH); CHECK_EQUAL(ssut.splitter_get_paf_state(), SIP_PAF_BODY_SEARCH); @@ -90,8 +106,10 @@ TEST(sip_splitter_scan_test, scan_content_len_convert_body_search_test) TEST(sip_splitter_scan_test, scan_content_len_invalid_test) { uint32_t fp = 0; + Packet p(true); + ssut.splitter_set_paf_state(SIP_PAF_CONTENT_LEN_CONVERT); - StreamSplitter::Status ret = ssut.splitter_scan(nullptr, + StreamSplitter::Status ret = ssut.splitter_scan(&p, (const uint8_t *)"144i", 4, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::SEARCH); CHECK_TRUE(ssut.is_init()); @@ -101,8 +119,10 @@ TEST(sip_splitter_scan_test, scan_content_len_invalid_test) TEST(sip_splitter_scan_test, scan_search_body_test) { uint32_t fp = 0; + Packet p(true); + ssut.splitter_set_paf_state(SIP_PAF_BODY_SEARCH); - StreamSplitter::Status ret = ssut.splitter_scan(nullptr, + StreamSplitter::Status ret = ssut.splitter_scan(&p, (const uint8_t *)"\r\n\r\n", 4, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::SEARCH); CHECK_EQUAL(ssut.splitter_get_paf_state(), SIP_PAF_FLUSH_STATE); @@ -111,7 +131,7 @@ TEST(sip_splitter_scan_test, scan_search_body_test) ssut.splitter_reset_states(); ssut.splitter_set_paf_state(SIP_PAF_BODY_SEARCH); - ret = ssut.splitter_scan(nullptr, (const uint8_t *)"\n\n", 2, 0, &fp); + ret = ssut.splitter_scan(&p, (const uint8_t *)"\n\n", 2, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::SEARCH); CHECK_EQUAL(ssut.splitter_get_paf_state(), SIP_PAF_FLUSH_STATE); CHECK_EQUAL(fp, 0); @@ -120,11 +140,13 @@ TEST(sip_splitter_scan_test, scan_search_body_test) TEST(sip_splitter_scan_test, scan_flush_test) { uint32_t fp = 0; + Packet p(true); + ssut.splitter_set_paf_state(SIP_PAF_FLUSH_STATE); ssut.splitter_set_content_length(6); // Sip splitter starts searching body from one character behind the actual body. - StreamSplitter::Status ret = ssut.splitter_scan(nullptr, + StreamSplitter::Status ret = ssut.splitter_scan(&p, (const uint8_t *)"\nfoobar", 7, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::FLUSH); CHECK_TRUE(ssut.is_init()); @@ -136,14 +158,14 @@ TEST(sip_splitter_scan_test, scan_flush_test) ssut.splitter_set_paf_state(SIP_PAF_FLUSH_STATE); ssut.splitter_set_content_length(12); - ret = ssut.splitter_scan(nullptr, (const uint8_t *)"\nfoobar", 7, 0, &fp); + ret = ssut.splitter_scan(&p, (const uint8_t *)"\nfoobar", 7, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::SEARCH); CHECK_EQUAL(ssut.splitter_get_paf_state(), SIP_PAF_FLUSH_STATE); CHECK_EQUAL(ssut.splitter_get_content_length(), 5); CHECK_EQUAL(fp, 0); //Continue scanning the remaining buffer - ret = ssut.splitter_scan(nullptr, (const uint8_t *)"foobar", 6, 0, &fp); + ret = ssut.splitter_scan(&p, (const uint8_t *)"foobar", 6, 0, &fp); CHECK_EQUAL(ret, StreamSplitter::FLUSH); CHECK_TRUE(ssut.is_init()); CHECK_EQUAL(fp, 6); diff --git a/src/service_inspectors/sip/test/sip_splitter_test.h b/src/service_inspectors/sip/test/sip_splitter_test.h index 46c71282f..f9e86d7ab 100644 --- a/src/service_inspectors/sip/test/sip_splitter_test.h +++ b/src/service_inspectors/sip/test/sip_splitter_test.h @@ -23,15 +23,18 @@ #include "stream/stream_splitter.h" #include "service_inspectors/sip/sip_splitter.h" +#include "service_inspectors/sip/sip.h" //stubs to avoid link errors const snort::StreamBuffer snort::StreamSplitter::reassemble(snort::Flow*, unsigned int, unsigned int, unsigned char const*, unsigned int, unsigned int, unsigned int &) { return {}; } unsigned snort::StreamSplitter::max(snort::Flow *) { return 0; } +SIPData* get_sip_session_data(const snort::Flow*) { return nullptr; } const uint8_t line_feed = '\n'; const uint8_t carriage_return = '\r'; const uint8_t no_lf_cr = '\t'; +THREAD_LOCAL SipStats sip_stats; //characters recognized by isspace() as spaces const uint8_t spaces[] = {' ', '\t', '\n', '\v', '\f', '\r'};