]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4135: Feature Prep
authorBrandon Stultz (brastult) <brastult@cisco.com>
Fri, 8 Dec 2023 09:14:05 +0000 (09:14 +0000)
committerOleksii. Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Fri, 8 Dec 2023 09:14:05 +0000 (09:14 +0000)
Merge in SNORT/snort3 from ~BRASTULT/snort3:feature_prep to master

Squashed commit of the following:

commit 85e2bbe582be1ff3980da214aa92927fa9b2007e
Author: Brandon Stultz <brastult@cisco.com>
Date:   Mon Nov 20 17:58:17 2023 -0500

    utils: add get_file_size

commit 5362d679a2b1f162554647f970de07c66d80df94
Author: Brandon Stultz <brastult@cisco.com>
Date:   Thu Nov 9 14:58:42 2023 -0500

    main: fix reload_id data race

commit ada5805e25cf9d7d1ede3d44aec0c96bb25bb5e9
Author: Brandon Stultz <brastult@cisco.com>
Date:   Fri Nov 3 11:47:28 2023 -0400

    parser: add CWD to conf search order

commit b11e3124844d717857d8b0bf7995c0396203e610
Author: Brandon Stultz <brastult@cisco.com>
Date:   Fri Sep 22 16:44:24 2023 -0400

    pub_sub: add get_client_body and is_mime methods

commit 4da05779e308734d705e2de2c3afe4ec210413ce
Author: Brandon Stultz <brastult@cisco.com>
Date:   Fri Sep 22 16:40:09 2023 -0400

    http_inspect: publish HTTP/1 request bodies, track MIME boundary

14 files changed:
doc/user/overview.txt
src/main/snort_config.cc
src/main/snort_config.h
src/parser/parse_conf.cc
src/pub_sub/http_events.cc
src/pub_sub/http_events.h
src/pub_sub/http_request_body_event.cc
src/pub_sub/http_request_body_event.h
src/pub_sub/test/pub_sub_http_request_body_event_test.cc
src/service_inspectors/http_inspect/http_module.cc
src/service_inspectors/http_inspect/http_msg_header.cc
src/service_inspectors/http_inspect/http_msg_header.h
src/utils/util.cc
src/utils/util.h

index 701c4c1cf8920f5279e6aec81c0a10e826675872..8ad429f30003f4e835e92d79d7d08c1c9479d64b 100644 (file)
@@ -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:
 
index 76ff805bcc4fad99cc01ce114bfc74932986a98c..6b8aa3b83bb4752b1b92fbaaadf2168cf7fab82b 100644 (file)
@@ -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<std::mutex> 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<std::mutex> reload_id_lock(reload_id_mutex);
     static unsigned reload_id_tracker = 0;
     reload_id = ++reload_id_tracker;
 }
index c348a2ffb32f5de018537b2a5a22faf0869d7b01..8c54989826e616b8ce52aa9e5bf4e2688157b6d3 100644 (file)
@@ -417,6 +417,7 @@ public:
     DumpConfigType dump_config_type = DUMP_CONFIG_NONE;
 private:
     std::list<ReloadResourceTuner*> reload_tuners;
+    static std::mutex reload_id_mutex;
     unsigned reload_id = 0;
     static std::mutex static_names_mutex;
     static std::unordered_map<std::string, std::string> static_names;
index edcb838a055527caa82cb11790daa85755b45fd4..f10dbac38888dffea9b874eef1ca2df5e979537f 100644 (file)
@@ -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;
 }
 
index d333a9060e95f1ecdd1182e7911b36c11d84ccc1..6facdfae65d7c350528cd96c1b311321826073c1 100644 (file)
@@ -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,
index 882ee885032f4999016fabcf1613e7586dde1b03..74062840b881bfe218507f7c124027d3a34a486d 100644 (file)
@@ -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);
index 16bb41b95b5a64bce78c88c5403c8004e0758585..2b9bba60d3230924ffe4bfb1903868e9e8e85a37 100644 (file)
 
 #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();
index 9841775fa0b6d6dba4c7cf1fcb2316ce38dba084..0500644d7ac6868abb63480a869bf15658542252 100644 (file)
 #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;
index c80036eb768c503208cdfbeecffd890801460d3b..0321e1dae0d2782786ed4d59bac0e714c5e1612e 100644 (file)
@@ -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
index eb207abb38081d1d3071c276575e63f6d5a9b352..eae0263f206e9b3124dfd3009ceeb298a6a1c918 100755 (executable)
@@ -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" },
index 4edbf4b1915d25d9c64f6882d479312e144557d1..597d75adbee89ce977e66789e358cfb5cf25be1a 100755 (executable)
@@ -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());
 
index 8012dba20863515ecd59e7dd836f490c763b8a98..40aa4465a75b8520e243bf0f5490935934a07992 100644 (file)
@@ -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;
index d6dec9be9bd66c76bca203ba1fe7ee6c5b60b074..a5a9f2f8c75b69fd9a40b5d5f0f892674fd6cb15 100644 (file)
@@ -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<size_t>(sb.st_size);
+    return true;
+}
+
 #if defined(NOCOREFILE)
 void SetNoCores()
 {
index 096a39d0d1cc55cfbfecfeaba25d1253f2c11ee3..ac66753475a05e0b90a9bf3297ba81ef40e2a46d 100644 (file)
@@ -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();