From: Brandon Stultz (brastult) Date: Fri, 8 Dec 2023 09:14:05 +0000 (+0000) Subject: Pull request #4135: Feature Prep X-Git-Tag: 3.1.77.0~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=70ee594c6d348eddc50475eae12a7bb2b3a12d1b;p=thirdparty%2Fsnort3.git Pull request #4135: Feature Prep Merge in SNORT/snort3 from ~BRASTULT/snort3:feature_prep to master Squashed commit of the following: commit 85e2bbe582be1ff3980da214aa92927fa9b2007e Author: Brandon Stultz Date: Mon Nov 20 17:58:17 2023 -0500 utils: add get_file_size commit 5362d679a2b1f162554647f970de07c66d80df94 Author: Brandon Stultz Date: Thu Nov 9 14:58:42 2023 -0500 main: fix reload_id data race commit ada5805e25cf9d7d1ede3d44aec0c96bb25bb5e9 Author: Brandon Stultz Date: Fri Nov 3 11:47:28 2023 -0400 parser: add CWD to conf search order commit b11e3124844d717857d8b0bf7995c0396203e610 Author: Brandon Stultz Date: Fri Sep 22 16:44:24 2023 -0400 pub_sub: add get_client_body and is_mime methods commit 4da05779e308734d705e2de2c3afe4ec210413ce Author: Brandon Stultz Date: Fri Sep 22 16:40:09 2023 -0400 http_inspect: publish HTTP/1 request bodies, track MIME boundary --- diff --git a/doc/user/overview.txt b/doc/user/overview.txt index 701c4c1cf..8ad429f30 100644 --- a/doc/user/overview.txt +++ b/doc/user/overview.txt @@ -323,6 +323,7 @@ various parameters. Snort will find relative includes in the following order: 1. If you specify --include-path, this directory will be tried first. 2. Snort will try the directory containing the including file. 3. Snort will try the directory containing the -c configuration file. +4. Snort will try the current working directory. Some things to keep in mind: diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index 76ff805bc..6b8aa3b83 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -1009,8 +1009,13 @@ const SnortConfig* SnortConfig::get_conf() unsigned SnortConfig::get_thread_reload_id() { return thread_snort_config.reload_id; } +std::mutex SnortConfig::reload_id_mutex; + void SnortConfig::update_thread_reload_id() -{ thread_snort_config.reload_id = thread_snort_config.snort_conf->reload_id; } +{ + std::lock_guard reload_id_lock(reload_id_mutex); + thread_snort_config.reload_id = thread_snort_config.snort_conf->reload_id; +} void SnortConfig::set_conf(const SnortConfig* sc) { @@ -1041,6 +1046,7 @@ void SnortConfig::clear_reload_resource_tuner_list() void SnortConfig::update_reload_id() { + std::lock_guard reload_id_lock(reload_id_mutex); static unsigned reload_id_tracker = 0; reload_id = ++reload_id_tracker; } diff --git a/src/main/snort_config.h b/src/main/snort_config.h index c348a2ffb..8c5498982 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -417,6 +417,7 @@ public: DumpConfigType dump_config_type = DUMP_CONFIG_NONE; private: std::list reload_tuners; + static std::mutex reload_id_mutex; unsigned reload_id = 0; static std::mutex static_names_mutex; static std::unordered_map static_names; diff --git a/src/parser/parse_conf.cc b/src/parser/parse_conf.cc index edcb838a0..f10dbac38 100644 --- a/src/parser/parse_conf.cc +++ b/src/parser/parse_conf.cc @@ -160,6 +160,12 @@ static bool relative_to_include_dir(const char* file, std::string& path) return valid_file(file, path); } +static bool relative_to_working_dir(const char* file, std::string& path) +{ + path = "."; + return valid_file(file, path); +} + const char* get_config_file(const char* arg, std::string& file) { assert(arg); @@ -184,6 +190,9 @@ const char* get_config_file(const char* arg, std::string& file) if ( relative_to_config_dir(arg, file) ) return "C"; + if ( relative_to_working_dir(arg, file) ) + return "W"; + return nullptr; } diff --git a/src/pub_sub/http_events.cc b/src/pub_sub/http_events.cc index d333a9060..6facdfae6 100644 --- a/src/pub_sub/http_events.cc +++ b/src/pub_sub/http_events.cc @@ -98,6 +98,11 @@ const uint8_t* HttpEvent::get_uri_host(int32_t &length) } } +const uint8_t* HttpEvent::get_uri_query(int32_t& length) +{ + return get_header(HttpEnums::HTTP_BUFFER_URI, HttpEnums::UC_QUERY, length); +} + const uint8_t* HttpEvent::get_location(int32_t& length) { return get_header(HttpEnums::HTTP_BUFFER_HEADER, HttpEnums::HEAD_LOCATION, diff --git a/src/pub_sub/http_events.h b/src/pub_sub/http_events.h index 882ee8850..74062840b 100644 --- a/src/pub_sub/http_events.h +++ b/src/pub_sub/http_events.h @@ -41,6 +41,7 @@ public: const uint8_t* get_cookie(int32_t &length); const uint8_t* get_authority(int32_t &length); const uint8_t* get_uri_host(int32_t &length); + const uint8_t* get_uri_query(int32_t &length); const uint8_t* get_location(int32_t &length); const uint8_t* get_referer(int32_t &length); const uint8_t* get_server(int32_t &length); diff --git a/src/pub_sub/http_request_body_event.cc b/src/pub_sub/http_request_body_event.cc index 16bb41b95..2b9bba60d 100644 --- a/src/pub_sub/http_request_body_event.cc +++ b/src/pub_sub/http_request_body_event.cc @@ -23,7 +23,10 @@ #include "http_request_body_event.h" +#include "service_inspectors/http_inspect/http_field.h" #include "service_inspectors/http_inspect/http_flow_data.h" +#include "service_inspectors/http_inspect/http_msg_body.h" +#include "service_inspectors/http_inspect/http_msg_header.h" using namespace snort; @@ -46,11 +49,38 @@ const uint8_t* HttpRequestBodyEvent::get_request_body_data(int32_t& length, int3 return nullptr; } +const uint8_t* HttpRequestBodyEvent::get_client_body(int32_t& length) +{ + if (http_msg_body) + { + const Field& body = http_msg_body->get_classic_client_body(); + + length = body.length(); + return body.start(); + } + + length = 0; + return nullptr; +} + bool HttpRequestBodyEvent::is_last_request_body_piece() { return last_piece; } +bool HttpRequestBodyEvent::is_mime() const +{ + if (http_msg_body) + { + HttpMsgHeader* header = http_msg_body->get_header(HttpCommon::SRC_CLIENT); + + if (header) + return header->has_mime_boundary(); + } + + return false; +} + int64_t HttpRequestBodyEvent::get_httpx_stream_id() const { return http_flow_data->get_hx_stream_id(); diff --git a/src/pub_sub/http_request_body_event.h b/src/pub_sub/http_request_body_event.h index 9841775fa..0500644d7 100644 --- a/src/pub_sub/http_request_body_event.h +++ b/src/pub_sub/http_request_body_event.h @@ -21,12 +21,10 @@ #define HTTP_REQUEST_BODY_EVENT_H #include "framework/data_bus.h" -#include "service_inspectors/http_inspect/http_enum.h" -#include "service_inspectors/http_inspect/http_field.h" -#include "service_inspectors/http_inspect/http_msg_body.h" #include "http_event_ids.h" +class HttpMsgBody; class HttpFlowData; namespace snort @@ -41,11 +39,13 @@ public: { } const uint8_t* get_request_body_data(int32_t& length, int32_t& offset); + const uint8_t* get_client_body(int32_t& length); bool is_last_request_body_piece(); + bool is_mime() const; int64_t get_httpx_stream_id() const; private: - const HttpMsgBody* const http_msg_body; + HttpMsgBody* const http_msg_body; const int32_t msg_offset; const bool last_piece; HttpFlowData* const http_flow_data; diff --git a/src/pub_sub/test/pub_sub_http_request_body_event_test.cc b/src/pub_sub/test/pub_sub_http_request_body_event_test.cc index c80036eb7..0321e1dae 100644 --- a/src/pub_sub/test/pub_sub_http_request_body_event_test.cc +++ b/src/pub_sub/test/pub_sub_http_request_body_event_test.cc @@ -58,6 +58,7 @@ void HttpMsgBody::do_file_decompression(const Field&, Field&) {} void HttpMsgBody::clean_partial(uint32_t&, uint32_t&, uint8_t*&, uint32_t&) {} void HttpMsgBody::bookkeeping_regular_flush(uint32_t&, uint8_t*&, uint32_t&, int32_t) {} bool HttpMsgBody::run_detection(snort::Packet*) { return true; } +const Field& HttpMsgBody::get_classic_client_body() { return classic_client_body; } void HttpMsgBody::clear() {} void HttpMsgSection::clear() {} #ifdef REG_TEST diff --git a/src/service_inspectors/http_inspect/http_module.cc b/src/service_inspectors/http_inspect/http_module.cc index eb207abb3..eae0263f2 100755 --- a/src/service_inspectors/http_inspect/http_module.cc +++ b/src/service_inspectors/http_inspect/http_module.cc @@ -142,8 +142,8 @@ const Parameter HttpModule::http_params[] = "of preference as defined" }, { "request_body_app_detection", Parameter::PT_BOOL, nullptr, "true", - "make HTTP/2 request message bodies available for application detection " - "(detection requires AppId)" }, + "make HTTP request message bodies available for application detection " + "(AppId) and other inspectors" }, { "allowed_methods", Parameter::PT_STRING, nullptr, nullptr, "list of allowed methods" }, diff --git a/src/service_inspectors/http_inspect/http_msg_header.cc b/src/service_inspectors/http_inspect/http_msg_header.cc index 4edbf4b19..597d75adb 100755 --- a/src/service_inspectors/http_inspect/http_msg_header.cc +++ b/src/service_inspectors/http_inspect/http_msg_header.cc @@ -491,7 +491,7 @@ void HttpMsgHeader::prepare_body() // body session_data->detect_depth_remaining[source_id] = INT64_MAX; } - if ((source_id == SRC_CLIENT) and params->publish_request_body and session_data->for_httpx) + if ((source_id == SRC_CLIENT) and params->publish_request_body) { session_data->publish_octets[source_id] = 0; session_data->publish_depth_remaining[source_id] = REQUEST_PUBLISH_DEPTH; @@ -528,6 +528,8 @@ void HttpMsgHeader::setup_mime() { if (boundary_present(content_type)) { + mime_boundary_found = true; + // Generate the unique file id for multi file processing set_multi_file_processing_id(get_transaction_id(), session_data->get_hx_stream_id()); diff --git a/src/service_inspectors/http_inspect/http_msg_header.h b/src/service_inspectors/http_inspect/http_msg_header.h index 8012dba20..40aa4465a 100644 --- a/src/service_inspectors/http_inspect/http_msg_header.h +++ b/src/service_inspectors/http_inspect/http_msg_header.h @@ -48,6 +48,9 @@ public: const Field& get_true_ip_addr(); int32_t get_num_cookies(); + bool has_mime_boundary() const + { return mime_boundary_found; } + // The multi_file_processing_id is unique for each file transferred within a single connection // and is used by file processing to store partially processed file contexts in the flow data. void set_multi_file_processing_id(const uint64_t transaction_id, const uint32_t stream_id); @@ -64,6 +67,8 @@ private: // Dummy configurations to support MIME processing snort::MailLogConfig mime_conf; + bool mime_boundary_found = false; + Field true_ip; Field true_ip_addr; int32_t num_cookies = HttpCommon::STAT_NOT_COMPUTE; diff --git a/src/utils/util.cc b/src/utils/util.cc index d6dec9be9..a5a9f2f8c 100644 --- a/src/utils/util.cc +++ b/src/utils/util.cc @@ -64,6 +64,18 @@ extern "C" { #include "catch/snort_catch.h" #endif +#ifdef _WIN32 +#define STAT _stat +#else +#define STAT stat +#endif + +#ifdef _WIN32 +#define ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#else +#define ISREG(m) S_ISREG(m) +#endif + using namespace snort; /**************************************************************************** @@ -478,6 +490,23 @@ unsigned int get_random_seed() return seed; } +bool get_file_size(const std::string& path, size_t& size) +{ + struct STAT sb; + + if (STAT(path.c_str(), &sb)) + return false; + + if (!ISREG(sb.st_mode)) + return false; + + if (sb.st_size < 0) + return false; + + size = static_cast(sb.st_size); + return true; +} + #if defined(NOCOREFILE) void SetNoCores() { diff --git a/src/utils/util.h b/src/utils/util.h index 096a39d0d..ac6675347 100644 --- a/src/utils/util.h +++ b/src/utils/util.h @@ -55,6 +55,7 @@ void InitGroups(int, int); bool EnterChroot(std::string& root_dir, std::string& log_dir); void InitProtoNames(); unsigned int get_random_seed(); +bool get_file_size(const std::string&, size_t&); #if defined(NOCOREFILE) void SetNoCores();