From: Oleg Torubara -X (otorubar - SOFTSERVE INC at Cisco) Date: Thu, 10 Oct 2024 18:58:20 +0000 (+0000) Subject: Pull request #4454: file_api, http_inspect: set uri for file processing X-Git-Tag: 3.4.0.0~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5e951423f395bae3e9880d55fb48f09c36b6a58;p=thirdparty%2Fsnort3.git Pull request #4454: file_api, http_inspect: set uri for file processing Merge in SNORT/snort3 from ~OTORUBAR/snort3:set_uri_for_file_processing to master Squashed commit of the following: commit 02350f3bcb2b5d023bed4f74cb707b7ebc7cf3c1 Author: otorubar Date: Thu Sep 19 04:44:33 2024 -0700 file_api,http_inspect: extract and set hostname for file processing --- diff --git a/src/file_api/file_flows.cc b/src/file_api/file_flows.cc index 6cc014b2e..c00610180 100644 --- a/src/file_api/file_flows.cc +++ b/src/file_api/file_flows.cc @@ -324,7 +324,8 @@ void FileFlows::remove_processed_file_context(uint64_t file_id) */ bool FileFlows::file_process(Packet* p, uint64_t file_id, const uint8_t* file_data, int data_size, uint64_t offset, FileDirection dir, uint64_t multi_file_processing_id, - FilePosition position, const uint8_t* fname, uint32_t name_size) + FilePosition position, const uint8_t* fname, uint32_t name_size, + const uint8_t* url, uint32_t url_size, const std::string& host_name) { int64_t file_depth = FileService::get_max_file_depth(); bool continue_processing; @@ -348,7 +349,9 @@ bool FileFlows::file_process(Packet* p, uint64_t file_id, const uint8_t* file_da "file_process:context missing, returning \n"); return false; } - context->set_file_name((const char*)fname, name_size, false); + context->set_weak_file_name((const char*)fname, name_size); + context->set_weak_url((const char*)url, url_size); + context->set_host(host_name.c_str(), host_name.size()); if (PacketTracer::is_daq_activated()) PacketTracer::restart_timer(); @@ -448,7 +451,7 @@ bool FileFlows::file_process(Packet* p, const uint8_t* file_data, int data_size, context = find_main_file_context(position, direction, file_index); set_current_file_context(context); - context->set_file_name((const char*)fname, name_size, false); + context->set_weak_file_name((const char*)fname, name_size); context->set_signature_state(gen_signature); bool file_process_ret = context->process(p, file_data, data_size, position, file_policy); diff --git a/src/file_api/file_flows.h b/src/file_api/file_flows.h index 4978e39d2..1a0686ec5 100644 --- a/src/file_api/file_flows.h +++ b/src/file_api/file_flows.h @@ -96,7 +96,8 @@ public: // This is used for each file context. Support multiple files per session bool file_process(Packet* p, uint64_t file_id, const uint8_t* file_data, int data_size, uint64_t offset, FileDirection, uint64_t multi_file_processing_id=0, - FilePosition=SNORT_FILE_POSITION_UNKNOWN, const uint8_t* fname = nullptr, uint32_t name_size = 0); + FilePosition=SNORT_FILE_POSITION_UNKNOWN, const uint8_t* fname = nullptr, uint32_t name_size = 0, + const uint8_t* url = nullptr, uint32_t url_size = 0, const std::string& host_name = ""); static unsigned file_flow_data_id; diff --git a/src/file_api/file_lib.cc b/src/file_api/file_lib.cc index ed9d100ab..3799e665c 100644 --- a/src/file_api/file_lib.cc +++ b/src/file_api/file_lib.cc @@ -129,6 +129,8 @@ void FileInfo::copy(const FileInfo& other, bool clear_data) file_name_set = other.file_name_set; url = other.url; url_set = other.url_set; + host_name = other.host_name; + host_set = other.host_set; verdict = other.verdict; file_type_enabled = other.file_type_enabled; file_signature_enabled = other.file_signature_enabled; @@ -161,31 +163,57 @@ FileInfo& FileInfo::operator=(const FileInfo& other) /*File properties*/ -void FileInfo::set_file_name(const char* name, uint32_t name_size, bool fn_set) +void FileInfo::set_file_name(const char* name, uint32_t name_size) { if (name and name_size) file_name.assign(name, name_size); - if (fn_set) - file_name_set = fn_set; + file_name_set = true; +} + +void FileInfo::set_weak_file_name(const char* name, uint32_t name_size) +{ + if (name and name_size) + file_name.assign(name, name_size); } void FileInfo::set_url(const char* url_name, uint32_t url_size) { if (url_name and url_size) - { url.assign(url_name, url_size); - } url_set = true; } -std::string& FileInfo::get_file_name() +void FileInfo::set_weak_url(const char* url_name, uint32_t url_size) +{ + if (url_name and url_size) + url.assign(url_name, url_size); +} + +void FileInfo::set_host(const char* host_name, uint32_t host_size) +{ + if (this->host_set) + return; + + if (host_name and host_size) + { + this->host_name.assign(host_name, host_size); + this->host_set = true; + } +} + +const std::string& FileInfo::get_host_name() const +{ + return host_name; +} + +const std::string& FileInfo::get_file_name() const { return file_name; } -std::string& FileInfo::get_url() +const std::string& FileInfo::get_url() const { return url; } @@ -940,6 +968,8 @@ void FileContext::print(std::ostream& log) print_file_name(log); if (url.length() > 0) log << "File URI: "<< url << std::endl; + if (host_name.length() > 0) + log << "Host name: "<< host_name << std::endl; log << "File type: " << config->file_type_name(file_type_id) << '('<< file_type_id << ')' << std::endl; log << "File size: " << file_size << std::endl; diff --git a/src/file_api/file_lib.h b/src/file_api/file_lib.h index c9ea2bf47..900625e8a 100644 --- a/src/file_api/file_lib.h +++ b/src/file_api/file_lib.h @@ -55,13 +55,21 @@ public: FileInfo& operator=(const FileInfo& other); uint32_t get_file_type() const; void set_file_type(uint64_t index); - void set_file_name(const char* file_name, uint32_t name_size, bool fn_set = true); + void set_file_name(const char* file_name, uint32_t name_size); void set_url(const char* url, uint32_t url_size); - std::string& get_file_name(); - std::string& get_url(); + void set_host(const char* host_name, uint32_t host_size); + + void set_weak_url(const char* url_name, uint32_t url_size); + void set_weak_file_name(const char* file_name, uint32_t name_size); + + const std::string& get_file_name() const; + const std::string& get_url() const; + const std::string& get_host_name() const; + // Whether file name has been set (could be empty file name) bool is_file_name_set() const { return file_name_set; } bool is_url_set() const { return url_set; } + bool is_host_set() const { return host_set; } void set_file_size(uint64_t size); uint64_t get_file_size() const; @@ -101,6 +109,8 @@ protected: bool file_name_set = false; std::string url; bool url_set = false; + std::string host_name; + bool host_set = false; uint64_t file_size = 0; FileDirection direction = FILE_DOWNLOAD; uint32_t file_type_id = SNORT_FILE_TYPE_CONTINUE; diff --git a/src/file_api/file_log.cc b/src/file_api/file_log.cc index 7e748432e..8684fab15 100644 --- a/src/file_api/file_log.cc +++ b/src/file_api/file_log.cc @@ -93,7 +93,7 @@ private: void LogHandler::log_file_name(TextLog* log, FileContext* file) { - std::string& name = file->get_file_name(); + const std::string& name = file->get_file_name(); if ( name.empty() ) return; diff --git a/src/service_inspectors/http_inspect/http_msg_body.cc b/src/service_inspectors/http_inspect/http_msg_body.cc index 6628e867b..80b468158 100644 --- a/src/service_inspectors/http_inspect/http_msg_body.cc +++ b/src/service_inspectors/http_inspect/http_msg_body.cc @@ -690,7 +690,7 @@ void HttpMsgBody::do_file_processing(const Field& file_data) const FileDirection dir = source_id == SRC_SERVER ? FILE_DOWNLOAD : FILE_UPLOAD; uint64_t file_index = get_header(source_id)->get_file_cache_index(); - + const std::string host = get_header(source_id)->get_host_header_field(); const uint8_t* filename_buffer = nullptr; uint32_t filename_length = 0; const uint8_t* uri_buffer = nullptr; @@ -701,7 +701,7 @@ void HttpMsgBody::do_file_processing(const Field& file_data) bool continue_processing_file = file_flows->file_process(p, file_index, file_data.start(), fp_length, session_data->file_octets[source_id], dir, get_header(source_id)->get_multi_file_processing_id(), file_position, - filename_buffer, filename_length); + filename_buffer, filename_length, uri_buffer, uri_length, host); if (continue_processing_file) { session_data->file_depth_remaining[source_id] -= fp_length; diff --git a/src/service_inspectors/http_inspect/http_msg_header.cc b/src/service_inspectors/http_inspect/http_msg_header.cc index 648a8b355..ee2c05a17 100755 --- a/src/service_inspectors/http_inspect/http_msg_header.cc +++ b/src/service_inspectors/http_inspect/http_msg_header.cc @@ -167,6 +167,14 @@ int32_t HttpMsgHeader::get_num_cookies() return num_cookies; } + std::string HttpMsgHeader::get_host_header_field() const + { + if (host_name.length() > STAT_EMPTY_STRING) + return std::string((const char*)host_name.start(), host_name.length()); + + return ""; + } + void HttpMsgHeader::gen_events() { if ((get_header_count(HEAD_CONTENT_LENGTH) > 0) && @@ -178,7 +186,7 @@ void HttpMsgHeader::gen_events() // Force inspection of the Host field if (source_id == SRC_CLIENT) - get_header_value_norm(HEAD_HOST); + host_name.set(get_header_value_norm(HEAD_HOST)); // Host header value too long if ((params->maximum_host_length != -1) && (source_id == SRC_CLIENT)) diff --git a/src/service_inspectors/http_inspect/http_msg_header.h b/src/service_inspectors/http_inspect/http_msg_header.h index b3c66bb5d..48a387299 100644 --- a/src/service_inspectors/http_inspect/http_msg_header.h +++ b/src/service_inspectors/http_inspect/http_msg_header.h @@ -56,6 +56,8 @@ public: void set_multi_file_processing_id(const uint64_t transaction_id, const uint32_t stream_id); uint64_t get_multi_file_processing_id() { return multi_file_processing_id; } + std::string get_host_header_field() const; + private: void prepare_body(); void setup_mime(); @@ -69,6 +71,7 @@ private: bool mime_boundary_found = false; + Field host_name; Field true_ip; Field true_ip_addr; int32_t num_cookies = HttpCommon::STAT_NOT_COMPUTE;