From: George Koikara (gkoikara) Date: Fri, 29 Apr 2022 14:36:20 +0000 (+0000) Subject: Pull request #3333: http_inspect: install header files, create SO_PUBLIC base class... X-Git-Tag: 3.1.29.0~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3bfb733cd7f5afe3cac87e4ffff7f64e58d2028b;p=thirdparty%2Fsnort3.git Pull request #3333: http_inspect: install header files, create SO_PUBLIC base class for HttpStreamSplitter and HttpInspect Merge in SNORT/snort3 from ~SHIKV/snort3:h3_initial to master Squashed commit of the following: commit f027a9fa26ff3ee219eb3ed4717a90056c01a0f7 Author: shibin k v Date: Wed Mar 30 11:19:21 2022 +0000 http_inspect: install header files, create a virtual base class for http_inspect and http_stream_splitter --- diff --git a/src/service_inspectors/http2_inspect/http2_data_cutter.cc b/src/service_inspectors/http2_inspect/http2_data_cutter.cc index f0d22edb2..89ff65ba2 100644 --- a/src/service_inspectors/http2_inspect/http2_data_cutter.cc +++ b/src/service_inspectors/http2_inspect/http2_data_cutter.cc @@ -74,7 +74,7 @@ StreamSplitter::Status Http2DataCutter::skip_over_frame(Http2Stream* const strea bool Http2DataCutter::check_http_state(Http2Stream* const stream) { HttpFlowData* const http_flow = stream->get_hi_flow_data(); - if ((http_flow->get_type_expected(source_id) != HttpEnums::SEC_BODY_H2)) + if ((http_flow->get_type_expected(source_id) != SEC_BODY_H2)) { stream->set_state(source_id, STREAM_ERROR); if (data_len > 0) @@ -138,7 +138,7 @@ StreamSplitter::Status Http2DataCutter::scan(const uint8_t* data, uint32_t lengt if ((data_bytes_read == data_len) && (frame_flags & FLAG_END_STREAM)) { HttpFlowData* const hi_flow = stream->get_hi_flow_data(); - hi_flow->set_h2_body_state(source_id, HttpEnums::H2_BODY_LAST_SEG); + hi_flow->set_h2_body_state(source_id, H2_BODY_LAST_SEG); } scan_result = session_data->hi_ss[source_id]->scan(&dummy_pkt, data + cur_data_offset, cur_data, unused, &http_flush_offset); diff --git a/src/service_inspectors/http2_inspect/http2_headers_frame.cc b/src/service_inspectors/http2_inspect/http2_headers_frame.cc index 09b22d862..8c1f99576 100644 --- a/src/service_inspectors/http2_inspect/http2_headers_frame.cc +++ b/src/service_inspectors/http2_inspect/http2_headers_frame.cc @@ -24,7 +24,6 @@ #include "http2_headers_frame.h" #include "protocols/packet.h" -#include "service_inspectors/http_inspect/http_enum.h" #include "service_inspectors/http_inspect/http_flow_data.h" #include "service_inspectors/http_inspect/http_inspect.h" #include "service_inspectors/http_inspect/http_stream_splitter.h" @@ -152,7 +151,7 @@ void Http2HeadersFrame::process_decoded_headers(HttpFlowData* http_flow, SourceI dummy_pkt.data = stream_buf.data; dummy_pkt.xtradata_mask = 0; session_data->hi->eval(&dummy_pkt); - if (http_flow->get_type_expected(hi_source_id) == HttpEnums::SEC_ABORT) + if (http_flow->get_type_expected(hi_source_id) == SEC_ABORT) { assert(session_data->is_processing_partial_header()); stream->set_state(hi_source_id, STREAM_ERROR); diff --git a/src/service_inspectors/http2_inspect/http2_headers_frame_header.cc b/src/service_inspectors/http2_inspect/http2_headers_frame_header.cc index 074ff8e9e..41b823084 100644 --- a/src/service_inspectors/http2_inspect/http2_headers_frame_header.cc +++ b/src/service_inspectors/http2_inspect/http2_headers_frame_header.cc @@ -23,7 +23,6 @@ #include "http2_headers_frame_header.h" -#include "service_inspectors/http_inspect/http_enum.h" #include "service_inspectors/http_inspect/http_flow_data.h" #include "http2_enum.h" @@ -73,7 +72,7 @@ void Http2HeadersFrameHeader::analyze_http1() // if END_STREAM flag set on headers, tell http_inspect not to expect a message body if (get_flags() & FLAG_END_STREAM) - stream->get_hi_flow_data()->finish_h2_body(source_id, HttpEnums::H2_BODY_NO_BODY, false); + stream->get_hi_flow_data()->finish_h2_body(source_id, H2_BODY_NO_BODY, false); process_decoded_headers(http_flow, source_id); } diff --git a/src/service_inspectors/http2_inspect/http2_headers_frame_trailer.cc b/src/service_inspectors/http2_inspect/http2_headers_frame_trailer.cc index a71df628c..7925e9861 100644 --- a/src/service_inspectors/http2_inspect/http2_headers_frame_trailer.cc +++ b/src/service_inspectors/http2_inspect/http2_headers_frame_trailer.cc @@ -24,7 +24,6 @@ #include "http2_headers_frame_trailer.h" #include "protocols/packet.h" -#include "service_inspectors/http_inspect/http_enum.h" #include "service_inspectors/http_inspect/http_flow_data.h" #include "service_inspectors/http_inspect/http_inspect.h" #include "service_inspectors/http_inspect/http_stream_splitter.h" @@ -72,11 +71,11 @@ void Http2HeadersFrameTrailer::analyze_http1() assert(http_flow); const bool valid_headers = http1_header.length() > 0; - if (http_flow->get_type_expected(source_id) != HttpEnums::SEC_TRAILER) + if (http_flow->get_type_expected(source_id) != SEC_TRAILER) { // http_inspect is not yet expecting trailers. Flush empty buffer through scan, reassemble, // and eval to prepare http_inspect for trailers. - assert(http_flow->get_type_expected(source_id) == HttpEnums::SEC_BODY_H2); + assert(http_flow->get_type_expected(source_id) == SEC_BODY_H2); stream->finish_msg_body(source_id, valid_headers, true); // calls http_inspect scan() unsigned copied; @@ -93,8 +92,8 @@ void Http2HeadersFrameTrailer::analyze_http1() dummy_pkt.dsize = stream_buf.length; dummy_pkt.data = stream_buf.data; session_data->hi->eval(&dummy_pkt); - assert (!valid_headers || http_flow->get_type_expected(source_id) == HttpEnums::SEC_TRAILER); - if (http_flow->get_type_expected(source_id) == HttpEnums::SEC_ABORT) + assert (!valid_headers || http_flow->get_type_expected(source_id) == SEC_TRAILER); + if (http_flow->get_type_expected(source_id) == SEC_ABORT) { stream->set_state(source_id, STREAM_ERROR); return; diff --git a/src/service_inspectors/http2_inspect/http2_headers_frame_with_startline.cc b/src/service_inspectors/http2_inspect/http2_headers_frame_with_startline.cc index 024a225be..5574dbf8d 100644 --- a/src/service_inspectors/http2_inspect/http2_headers_frame_with_startline.cc +++ b/src/service_inspectors/http2_inspect/http2_headers_frame_with_startline.cc @@ -24,7 +24,6 @@ #include "http2_headers_frame_with_startline.h" #include "protocols/packet.h" -#include "service_inspectors/http_inspect/http_enum.h" #include "service_inspectors/http_inspect/http_flow_data.h" #include "service_inspectors/http_inspect/http_inspect.h" #include "service_inspectors/http_inspect/http_stream_splitter.h" @@ -90,7 +89,7 @@ bool Http2HeadersFrameWithStartline::process_start_line(HttpFlowData*& http_flow dummy_pkt.dsize = stream_buf.length; dummy_pkt.data = stream_buf.data; session_data->hi->eval(&dummy_pkt); - if (http_flow->get_type_expected(hi_source_id) != HttpEnums::SEC_HEADER) + if (http_flow->get_type_expected(hi_source_id) != SEC_HEADER) { stream->set_state(hi_source_id, STREAM_ERROR); return false; diff --git a/src/service_inspectors/http2_inspect/http2_push_promise_frame.cc b/src/service_inspectors/http2_inspect/http2_push_promise_frame.cc index b72a892d8..2083985cf 100644 --- a/src/service_inspectors/http2_inspect/http2_push_promise_frame.cc +++ b/src/service_inspectors/http2_inspect/http2_push_promise_frame.cc @@ -23,7 +23,6 @@ #include "http2_push_promise_frame.h" -#include "service_inspectors/http_inspect/http_enum.h" #include "service_inspectors/http_inspect/http_flow_data.h" #include "http2_flow_data.h" @@ -117,7 +116,7 @@ void Http2PushPromiseFrame::analyze_http1() // Push promise cannot have a message body // FIXIT-E handle bad request lines and cases where a message body is implied - stream->get_hi_flow_data()->finish_h2_body(SRC_CLIENT, HttpEnums::H2_BODY_NO_BODY, false); + stream->get_hi_flow_data()->finish_h2_body(SRC_CLIENT, H2_BODY_NO_BODY, false); process_decoded_headers(http_flow, SRC_CLIENT); } diff --git a/src/service_inspectors/http2_inspect/http2_stream.cc b/src/service_inspectors/http2_inspect/http2_stream.cc index 99abd7d2a..cdbdbcf6f 100644 --- a/src/service_inspectors/http2_inspect/http2_stream.cc +++ b/src/service_inspectors/http2_inspect/http2_stream.cc @@ -24,7 +24,6 @@ #include "http2_enum.h" #include "http2_stream.h" -#include "service_inspectors/http_inspect/http_enum.h" #include "service_inspectors/http_inspect/http_flow_data.h" #include "service_inspectors/http_inspect/http_stream_splitter.h" @@ -34,7 +33,6 @@ using namespace HttpCommon; using namespace Http2Enums; -using namespace HttpEnums; Http2Stream::Http2Stream(uint32_t stream_id_, Http2FlowData* session_data_) : stream_id(stream_id_), diff --git a/src/service_inspectors/http2_inspect/http2_stream_splitter.cc b/src/service_inspectors/http2_inspect/http2_stream_splitter.cc index c921c3a42..27f28dd67 100644 --- a/src/service_inspectors/http2_inspect/http2_stream_splitter.cc +++ b/src/service_inspectors/http2_inspect/http2_stream_splitter.cc @@ -264,7 +264,7 @@ bool Http2StreamSplitter::finish(Flow* flow) (stream->get_state(source_id) >= STREAM_COMPLETE) || (stream->get_hi_flow_data() == nullptr) || (stream->get_hi_flow_data()->get_type_expected(source_id) - != HttpEnums::SEC_BODY_H2) || + != SEC_BODY_H2) || (session_data->processing_partial_header && (stream->get_stream_id() == session_data->current_stream[source_id]))) { diff --git a/src/service_inspectors/http_inspect/CMakeLists.txt b/src/service_inspectors/http_inspect/CMakeLists.txt index c9069f2ce..3ef0ac168 100644 --- a/src/service_inspectors/http_inspect/CMakeLists.txt +++ b/src/service_inspectors/http_inspect/CMakeLists.txt @@ -1,9 +1,16 @@ +set(HTTP_INCLUDES + http_field.h + http_common.h + http_inspect_base.h + http_stream_splitter_base.h +) set (FILE_LIST + ${HTTP_INCLUDES} ips_http.cc ips_http.h - http_buffer_info.h http_buffer_info.cc + http_buffer_info.h http_inspect.cc http_inspect.h http_msg_section.cc @@ -60,9 +67,7 @@ set (FILE_LIST http_transaction.h http_test_manager.cc http_test_manager.h - http_enum.h http_field.cc - http_field.h http_stream_splitter_finish.cc http_stream_splitter_reassemble.cc http_stream_splitter_scan.cc @@ -91,6 +96,8 @@ set (FILE_LIST #add_dynamic_module(http_inspect inspectors ${FILE_LIST}) #endif(STATIC_INSPECTORS) - +install(FILES ${HTTP_INCLUDES} + DESTINATION "${INCLUDE_INSTALL_PATH}/service_inspectors/http_inspect" +) add_subdirectory ( test ) diff --git a/src/service_inspectors/http_inspect/http_common.h b/src/service_inspectors/http_inspect/http_common.h index e67603c6a..679a9ff79 100644 --- a/src/service_inspectors/http_inspect/http_common.h +++ b/src/service_inspectors/http_inspect/http_common.h @@ -32,6 +32,14 @@ enum StatusCode { STAT_NO_SOURCE=-16, STAT_NOT_CONFIGURED=-15, STAT_NOT_COMPUTE= // Message originator--client or server enum SourceId { SRC__NOT_COMPUTE=-14, SRC_CLIENT=0, SRC_SERVER=1 }; +// Type of message section +enum SectionType { SEC_DISCARD = -19, SEC_ABORT = -18, SEC__NOT_COMPUTE=-14, SEC__NOT_PRESENT=-11, + SEC_REQUEST = 2, SEC_STATUS, SEC_HEADER, SEC_BODY_CL, SEC_BODY_CHUNK, SEC_TRAILER, + SEC_BODY_OLD, SEC_BODY_H2 }; + +enum H2BodyState { H2_BODY_NOT_COMPLETE, H2_BODY_LAST_SEG, H2_BODY_COMPLETE, + H2_BODY_COMPLETE_EXPECT_TRAILERS, H2_BODY_NO_BODY }; + } // end namespace HttpCommon #endif diff --git a/src/service_inspectors/http_inspect/http_cutter.cc b/src/service_inspectors/http_inspect/http_cutter.cc index 22057be21..929f07bc8 100644 --- a/src/service_inspectors/http_inspect/http_cutter.cc +++ b/src/service_inspectors/http_inspect/http_cutter.cc @@ -29,9 +29,10 @@ #include "http_module.h" using namespace HttpEnums; +using namespace HttpCommon; ScanResult HttpStartCutter::cut(const uint8_t* buffer, uint32_t length, - HttpInfractions* infractions, HttpEventGen* events, uint32_t, bool, HttpEnums::H2BodyState) + HttpInfractions* infractions, HttpEventGen* events, uint32_t, bool, H2BodyState) { for (uint32_t k = 0; k < length; k++) { @@ -183,7 +184,7 @@ HttpStartCutter::ValidationResult HttpStatusCutter::validate(uint8_t octet, } ScanResult HttpHeaderCutter::cut(const uint8_t* buffer, uint32_t length, - HttpInfractions* infractions, HttpEventGen* events, uint32_t, bool, HttpEnums::H2BodyState) + HttpInfractions* infractions, HttpEventGen* events, uint32_t, bool, H2BodyState) { // Header separators: leading \r\n, leading \n, leading \r\r\n, nonleading \r\n\r\n, nonleading // \n\r\n, nonleading \r\r\n, nonleading \r\n\n, and nonleading \n\n. The separator itself @@ -323,7 +324,7 @@ HttpBodyCutter::~HttpBodyCutter() } ScanResult HttpBodyClCutter::cut(const uint8_t* buffer, uint32_t length, HttpInfractions*, - HttpEventGen*, uint32_t flow_target, bool stretch, HttpEnums::H2BodyState) + HttpEventGen*, uint32_t flow_target, bool stretch, H2BodyState) { assert(remaining > octets_seen); @@ -400,7 +401,7 @@ ScanResult HttpBodyClCutter::cut(const uint8_t* buffer, uint32_t length, HttpInf } ScanResult HttpBodyOldCutter::cut(const uint8_t* buffer, uint32_t length, HttpInfractions*, - HttpEventGen*, uint32_t flow_target, bool stretch, HttpEnums::H2BodyState) + HttpEventGen*, uint32_t flow_target, bool stretch, H2BodyState) { if (flow_target == 0) { @@ -446,7 +447,7 @@ void HttpBodyChunkCutter::transition_to_chunk_bad(bool& accelerate_this_packet) ScanResult HttpBodyChunkCutter::cut(const uint8_t* buffer, uint32_t length, HttpInfractions* infractions, HttpEventGen* events, uint32_t flow_target, bool stretch, - HttpEnums::H2BodyState) + H2BodyState) { // Are we skipping through the rest of this chunked body to the trailers and the next message? const bool discard_mode = (flow_target == 0); @@ -764,7 +765,7 @@ ScanResult HttpBodyH2Cutter::cut(const uint8_t* buffer, uint32_t length, { *infractions += INF_H2_DATA_OVERRUNS_CL; events->create_event(EVENT_H2_DATA_OVERRUNS_CL); - expected_body_length = HttpCommon::STAT_NOT_COMPUTE; + expected_body_length = STAT_NOT_COMPUTE; } else if (state != H2_BODY_NOT_COMPLETE and ((total_octets_scanned + length) < expected_body_length)) diff --git a/src/service_inspectors/http_inspect/http_cutter.h b/src/service_inspectors/http_inspect/http_cutter.h index 024d2e09b..1edc8b70f 100644 --- a/src/service_inspectors/http_inspect/http_cutter.h +++ b/src/service_inspectors/http_inspect/http_cutter.h @@ -23,6 +23,7 @@ #include #include +#include "http_common.h" #include "http_enum.h" #include "http_event.h" #include "http_module.h" @@ -39,7 +40,7 @@ public: virtual ~HttpCutter() = default; virtual HttpEnums::ScanResult cut(const uint8_t* buffer, uint32_t length, HttpInfractions* infractions, HttpEventGen* events, uint32_t flow_target, bool stretch, - HttpEnums::H2BodyState state) = 0; + HttpCommon::H2BodyState state) = 0; uint32_t get_num_flush() const { return num_flush; } uint32_t get_octets_seen() const { return octets_seen; } uint32_t get_num_excess() const { return num_crlf; } @@ -59,7 +60,7 @@ class HttpStartCutter : public HttpCutter { public: HttpEnums::ScanResult cut(const uint8_t* buffer, uint32_t length, - HttpInfractions* infractions, HttpEventGen* events, uint32_t, bool, HttpEnums::H2BodyState) + HttpInfractions* infractions, HttpEventGen* events, uint32_t, bool, HttpCommon::H2BodyState) override; protected: @@ -90,7 +91,7 @@ class HttpHeaderCutter : public HttpCutter { public: HttpEnums::ScanResult cut(const uint8_t* buffer, uint32_t length, - HttpInfractions* infractions, HttpEventGen* events, uint32_t, bool, HttpEnums::H2BodyState) + HttpInfractions* infractions, HttpEventGen* events, uint32_t, bool, HttpCommon::H2BodyState) override; uint32_t get_num_head_lines() const override { return num_head_lines; } @@ -137,7 +138,7 @@ public: remaining(expected_length) { assert(remaining > 0); } HttpEnums::ScanResult cut(const uint8_t*, uint32_t length, HttpInfractions*, HttpEventGen*, - uint32_t flow_target, bool stretch, HttpEnums::H2BodyState) override; + uint32_t flow_target, bool stretch, HttpCommon::H2BodyState) override; private: int64_t remaining; @@ -151,7 +152,7 @@ public: HttpBodyCutter(accelerated_blocking, finder, compression) {} HttpEnums::ScanResult cut(const uint8_t*, uint32_t, HttpInfractions*, HttpEventGen*, - uint32_t flow_target, bool stretch, HttpEnums::H2BodyState) override; + uint32_t flow_target, bool stretch, HttpCommon::H2BodyState) override; }; class HttpBodyChunkCutter : public HttpBodyCutter @@ -164,7 +165,7 @@ public: {} HttpEnums::ScanResult cut(const uint8_t* buffer, uint32_t length, HttpInfractions* infractions, HttpEventGen* events, uint32_t flow_target, bool stretch, - HttpEnums::H2BodyState) override; + HttpCommon::H2BodyState) override; bool get_is_broken_chunk() const override { return curr_state == HttpEnums::CHUNK_BAD; } uint32_t get_num_good_chunks() const override { return num_good_chunks; } void soft_reset() override { num_good_chunks = 0; HttpBodyCutter::soft_reset(); } @@ -193,7 +194,7 @@ public: expected_body_length(expected_length) {} HttpEnums::ScanResult cut(const uint8_t* buffer, uint32_t length, HttpInfractions*, - HttpEventGen*, uint32_t flow_target, bool stretch, HttpEnums::H2BodyState state) override; + HttpEventGen*, uint32_t flow_target, bool stretch, HttpCommon::H2BodyState state) override; private: int64_t expected_body_length; uint32_t total_octets_scanned = 0; diff --git a/src/service_inspectors/http_inspect/http_enum.h b/src/service_inspectors/http_inspect/http_enum.h index 6c6df7423..bbbcc320c 100755 --- a/src/service_inspectors/http_inspect/http_enum.h +++ b/src/service_inspectors/http_inspect/http_enum.h @@ -48,11 +48,6 @@ static const uint8_t MAX_CUSTOM_HEADERS = MAX_XFF_HEADERS; // This can grow into a bitmap for the get_buf() form parameter static const uint64_t FORM_REQUEST = 0x1; -// Type of message section -enum SectionType { SEC_DISCARD = -19, SEC_ABORT = -18, SEC__NOT_COMPUTE=-14, SEC__NOT_PRESENT=-11, - SEC_REQUEST = 2, SEC_STATUS, SEC_HEADER, SEC_BODY_CL, SEC_BODY_CHUNK, SEC_TRAILER, - SEC_BODY_OLD, SEC_BODY_H2 }; - // HTTP rule options. // Lower numbered portion is message buffers available to clients. // That part must remain synchronized with HttpApi::classic_buffer_names[] @@ -449,9 +444,6 @@ extern const bool is_sp_tab_quote_dquote[256]; extern const bool is_print_char[256]; // printable includes SP, tab, CR, LF extern const bool is_sp_comma[256]; -enum H2BodyState { H2_BODY_NOT_COMPLETE, H2_BODY_LAST_SEG, H2_BODY_COMPLETE, - H2_BODY_COMPLETE_EXPECT_TRAILERS, H2_BODY_NO_BODY }; - } // end namespace HttpEnums #endif diff --git a/src/service_inspectors/http_inspect/http_flow_data.cc b/src/service_inspectors/http_inspect/http_flow_data.cc index 117d1b138..b5542fc8d 100644 --- a/src/service_inspectors/http_inspect/http_flow_data.cc +++ b/src/service_inspectors/http_inspect/http_flow_data.cc @@ -343,7 +343,7 @@ HttpInfractions* HttpFlowData::get_infractions(SourceId source_id) return transaction[source_id]->get_infractions(source_id); } -void HttpFlowData::finish_h2_body(HttpCommon::SourceId source_id, HttpEnums::H2BodyState state, +void HttpFlowData::finish_h2_body(HttpCommon::SourceId source_id, HttpCommon::H2BodyState state, bool clear_partial_buffer) { assert((h2_body_state[source_id] == H2_BODY_NOT_COMPLETE) || diff --git a/src/service_inspectors/http_inspect/http_flow_data.h b/src/service_inspectors/http_inspect/http_flow_data.h index 050acfb8b..10438f2eb 100644 --- a/src/service_inspectors/http_inspect/http_flow_data.h +++ b/src/service_inspectors/http_inspect/http_flow_data.h @@ -75,13 +75,13 @@ public: friend class HttpUnitTestSetup; #endif - HttpEnums::SectionType get_type_expected(HttpCommon::SourceId source_id) const + HttpCommon::SectionType get_type_expected(HttpCommon::SourceId source_id) const { return type_expected[source_id]; } - void finish_h2_body(HttpCommon::SourceId source_id, HttpEnums::H2BodyState state, + void finish_h2_body(HttpCommon::SourceId source_id, HttpCommon::H2BodyState state, bool clear_partial_buffer); - void set_h2_body_state(HttpCommon::SourceId source_id, HttpEnums::H2BodyState state) + void set_h2_body_state(HttpCommon::SourceId source_id, HttpCommon::H2BodyState state) { h2_body_state[source_id] = state; } uint32_t get_h2_stream_id() const; @@ -118,8 +118,8 @@ private: bool is_broken_chunk[2] = { false, false }; // *** StreamSplitter => Inspector (facts about the most recent message section) - HttpEnums::SectionType section_type[2] = { HttpEnums::SEC__NOT_COMPUTE, - HttpEnums::SEC__NOT_COMPUTE }; + HttpCommon::SectionType section_type[2] = { HttpCommon::SEC__NOT_COMPUTE, + HttpCommon::SEC__NOT_COMPUTE }; int32_t octets_reassembled[2] = { HttpCommon::STAT_NOT_PRESENT, HttpCommon::STAT_NOT_PRESENT }; int32_t num_head_lines[2] = { HttpCommon::STAT_NOT_PRESENT, HttpCommon::STAT_NOT_PRESENT }; bool tcp_close[2] = { false, false }; @@ -137,7 +137,7 @@ private: HttpInfractions* get_infractions(HttpCommon::SourceId source_id); // *** Inspector => StreamSplitter (facts about the message section that is coming next) - HttpEnums::SectionType type_expected[2] = { HttpEnums::SEC_REQUEST, HttpEnums::SEC_STATUS }; + HttpCommon::SectionType type_expected[2] = { HttpCommon::SEC_REQUEST, HttpCommon::SEC_STATUS }; bool last_request_was_connect = false; z_stream* compress_stream[2] = { nullptr, nullptr }; uint64_t zero_nine_expected = 0; @@ -223,8 +223,8 @@ private: // *** HTTP/2 handling bool for_http2 = false; uint32_t h2_stream_id = 0; - HttpEnums::H2BodyState h2_body_state[2] = { HttpEnums::H2_BODY_NOT_COMPLETE, - HttpEnums::H2_BODY_NOT_COMPLETE }; + HttpCommon::H2BodyState h2_body_state[2] = { HttpCommon::H2_BODY_NOT_COMPLETE, + HttpCommon::H2_BODY_NOT_COMPLETE }; #ifdef REG_TEST static uint64_t instance_count; diff --git a/src/service_inspectors/http_inspect/http_inspect.cc b/src/service_inspectors/http_inspect/http_inspect.cc index e2ca27238..57edbea66 100755 --- a/src/service_inspectors/http_inspect/http_inspect.cc +++ b/src/service_inspectors/http_inspect/http_inspect.cc @@ -325,6 +325,25 @@ VersionId HttpInspect::http_get_version_id(Packet* p, return current_section->get_version_id(buffer_info); } +HttpCommon::SectionType HttpInspect::get_type_expected(snort::Flow* flow, HttpCommon::SourceId source_id) const +{ + HttpFlowData* session_data = http_get_flow_data(flow); + return session_data->get_type_expected(source_id); +} + +void HttpInspect::finish_h2_body(snort::Flow* flow, HttpCommon::SourceId source_id, HttpCommon::H2BodyState state, + bool clear_partial_buffer) const +{ + HttpFlowData* session_data = http_get_flow_data(flow); + session_data->finish_h2_body(source_id, state, clear_partial_buffer); +} + +void HttpInspect::set_h2_body_state(snort::Flow* flow, HttpCommon::SourceId source_id, HttpCommon::H2BodyState state) const +{ + HttpFlowData* session_data = http_get_flow_data(flow); + session_data->set_h2_body_state(source_id, state); +} + bool HttpInspect::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b) { if (get_latest_is(p) == IS_NONE) diff --git a/src/service_inspectors/http_inspect/http_inspect.h b/src/service_inspectors/http_inspect/http_inspect.h index c6954b368..0865fe96d 100644 --- a/src/service_inspectors/http_inspect/http_inspect.h +++ b/src/service_inspectors/http_inspect/http_inspect.h @@ -32,14 +32,14 @@ #include "http_common.h" #include "http_enum.h" #include "http_field.h" +#include "http_inspect_base.h" #include "http_module.h" -#include "http_msg_section.h" #include "http_stream_splitter.h" class HttpApi; class HttpParam; -class HttpInspect : public snort::Inspector +class HttpInspect : public HttpInspectBase { public: HttpInspect(const HttpParaList* params_); @@ -54,6 +54,10 @@ public: int32_t http_get_num_headers(snort::Packet* p, const HttpBufferInfo& buffer_info) const; HttpEnums::VersionId http_get_version_id(snort::Packet* p, const HttpBufferInfo& buffer_info) const; + HttpCommon::SectionType get_type_expected(snort::Flow* flow, HttpCommon::SourceId source_id) const override; + void finish_h2_body(snort::Flow* flow, HttpCommon::SourceId source_id, HttpCommon::H2BodyState state, + bool clear_partial_buffer) const override; + void set_h2_body_state(snort::Flow* flow, HttpCommon::SourceId source_id, HttpCommon::H2BodyState state) const override; bool get_fp_buf(snort::InspectionBuffer::Type ibt, snort::Packet* p, snort::InspectionBuffer& b) override; bool configure(snort::SnortConfig*) override; diff --git a/src/service_inspectors/http_inspect/http_inspect_base.h b/src/service_inspectors/http_inspect/http_inspect_base.h new file mode 100644 index 000000000..1c853f6e3 --- /dev/null +++ b/src/service_inspectors/http_inspect/http_inspect_base.h @@ -0,0 +1,41 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2022-2022 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. +//-------------------------------------------------------------------------- +// http_inspect_base.h author Shibin K V + +#ifndef HTTP_INSPECT_BASE_H +#define HTTP_INSPECT_BASE_H + +#include "flow/flow.h" +#include "framework/inspector.h" +#include "main/snort_types.h" + +#include "http_common.h" + +class SO_PUBLIC HttpInspectBase : public snort::Inspector +{ +public: + virtual ~HttpInspectBase() override = default; + + virtual HttpCommon::SectionType get_type_expected(snort::Flow* flow, HttpCommon::SourceId source_id) const = 0; + virtual void finish_h2_body(snort::Flow* flow, HttpCommon::SourceId source_id, HttpCommon::H2BodyState state, + bool clear_partial_buffer) const = 0; + virtual void set_h2_body_state(snort::Flow* flow, HttpCommon::SourceId source_id, HttpCommon::H2BodyState state) const = 0; +}; + +#endif + diff --git a/src/service_inspectors/http_inspect/http_msg_body_h2.cc b/src/service_inspectors/http_inspect/http_msg_body_h2.cc index 906b85553..0a601958b 100644 --- a/src/service_inspectors/http_inspect/http_msg_body_h2.cc +++ b/src/service_inspectors/http_inspect/http_msg_body_h2.cc @@ -23,7 +23,7 @@ #include "http_msg_body_h2.h" -using namespace HttpEnums; +using namespace HttpCommon; void HttpMsgBodyH2::update_flow() { diff --git a/src/service_inspectors/http_inspect/http_stream_splitter.h b/src/service_inspectors/http_inspect/http_stream_splitter.h index b9ea3ad7d..e64bde152 100644 --- a/src/service_inspectors/http_inspect/http_stream_splitter.h +++ b/src/service_inspectors/http_inspect/http_stream_splitter.h @@ -22,20 +22,19 @@ #include -#include "stream/stream_splitter.h" - #include "http_common.h" #include "http_enum.h" #include "http_flow_data.h" +#include "http_stream_splitter_base.h" #include "http_test_manager.h" class HttpInspect; -class HttpStreamSplitter : public snort::StreamSplitter +class HttpStreamSplitter : public HttpStreamSplitterBase { public: HttpStreamSplitter(bool is_client_to_server, HttpInspect* my_inspector_) : - snort::StreamSplitter(is_client_to_server), + HttpStreamSplitterBase(is_client_to_server), my_inspector(my_inspector_), source_id(is_client_to_server ? HttpCommon::SRC_CLIENT : HttpCommon::SRC_SERVER) {} Status scan(snort::Packet* pkt, const uint8_t* data, uint32_t length, uint32_t not_used, @@ -43,7 +42,7 @@ public: const snort::StreamBuffer reassemble(snort::Flow* flow, unsigned total, unsigned, const uint8_t* data, unsigned len, uint32_t flags, unsigned& copied) override; bool finish(snort::Flow* flow) override; - void prep_partial_flush(snort::Flow* flow, uint32_t num_flush); + void prep_partial_flush(snort::Flow* flow, uint32_t num_flush) override; bool is_paf() override { return true; } static StreamSplitter::Status status_value(StreamSplitter::Status ret_val, bool http2 = false); @@ -52,11 +51,11 @@ public: void go_away() override {} private: - void prepare_flush(HttpFlowData* session_data, uint32_t* flush_offset, HttpEnums::SectionType + void prepare_flush(HttpFlowData* session_data, uint32_t* flush_offset, HttpCommon::SectionType section_type, uint32_t num_flushed, uint32_t num_excess, int32_t num_head_lines, bool is_broken_chunk, uint32_t num_good_chunks, uint32_t octets_seen) const; - HttpCutter* get_cutter(HttpEnums::SectionType type, HttpFlowData* session) const; + HttpCutter* get_cutter(HttpCommon::SectionType type, HttpFlowData* session) const; void chunk_spray(HttpFlowData* session_data, uint8_t* buffer, const uint8_t* data, unsigned length) const; void decompress_copy(uint8_t* buffer, uint32_t& offset, const uint8_t* data, diff --git a/src/service_inspectors/http_inspect/http_stream_splitter_base.h b/src/service_inspectors/http_inspect/http_stream_splitter_base.h new file mode 100644 index 000000000..65b98fb1b --- /dev/null +++ b/src/service_inspectors/http_inspect/http_stream_splitter_base.h @@ -0,0 +1,38 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2022-2022 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. +//-------------------------------------------------------------------------- +// http_stream_splitter_base.h author Shibin K V + +#ifndef HTTP_STREAM_SPLITTER_BASE_H +#define HTTP_STREAM_SPLITTER_BASE_H + +#include "main/snort_types.h" +#include "stream/stream_splitter.h" + +class SO_PUBLIC HttpStreamSplitterBase : public snort::StreamSplitter +{ +public: + virtual ~HttpStreamSplitterBase() override = default; + + virtual void prep_partial_flush(snort::Flow* flow, uint32_t num_flush) = 0; + +protected: + HttpStreamSplitterBase(bool c2s) : StreamSplitter(c2s) { } +}; + +#endif + diff --git a/src/service_inspectors/http_inspect/http_stream_splitter_finish.cc b/src/service_inspectors/http_inspect/http_stream_splitter_finish.cc index 641f8ece3..ec2140574 100644 --- a/src/service_inspectors/http_inspect/http_stream_splitter_finish.cc +++ b/src/service_inspectors/http_inspect/http_stream_splitter_finish.cc @@ -21,6 +21,8 @@ #include "config.h" #endif +#include "http_stream_splitter.h" + #include "file_api/file_flows.h" #include "pub_sub/http_request_body_event.h" @@ -32,7 +34,6 @@ #include "http_module.h" #include "http_msg_header.h" #include "http_msg_request.h" -#include "http_stream_splitter.h" #include "http_test_input.h" using namespace HttpCommon; diff --git a/src/service_inspectors/http_inspect/http_stream_splitter_reassemble.cc b/src/service_inspectors/http_inspect/http_stream_splitter_reassemble.cc index e06d67097..605003371 100644 --- a/src/service_inspectors/http_inspect/http_stream_splitter_reassemble.cc +++ b/src/service_inspectors/http_inspect/http_stream_splitter_reassemble.cc @@ -21,13 +21,15 @@ #include "config.h" #endif +#include "http_stream_splitter.h" + #include "protocols/packet.h" #include "http_inspect.h" #include "http_module.h" -#include "http_stream_splitter.h" #include "http_test_input.h" +using namespace HttpCommon; using namespace HttpEnums; using namespace snort; diff --git a/src/service_inspectors/http_inspect/http_stream_splitter_scan.cc b/src/service_inspectors/http_inspect/http_stream_splitter_scan.cc index 21ace0227..3155adb25 100644 --- a/src/service_inspectors/http_inspect/http_stream_splitter_scan.cc +++ b/src/service_inspectors/http_inspect/http_stream_splitter_scan.cc @@ -21,6 +21,8 @@ #include "config.h" #endif +#include "http_stream_splitter.h" + #include "packet_io/active.h" #include "http_common.h" @@ -28,7 +30,7 @@ #include "http_enum.h" #include "http_inspect.h" #include "http_module.h" -#include "http_stream_splitter.h" +#include "http_msg_section.h" #include "http_test_input.h" using namespace snort; diff --git a/src/service_inspectors/http_inspect/ips_http_param.cc b/src/service_inspectors/http_inspect/ips_http_param.cc index a864f8df2..3db8f2ff0 100644 --- a/src/service_inspectors/http_inspect/ips_http_param.cc +++ b/src/service_inspectors/http_inspect/ips_http_param.cc @@ -33,6 +33,7 @@ #include "http_common.h" #include "http_enum.h" #include "http_inspect.h" +#include "http_msg_section.h" #include "http_param.h" using namespace snort;