From: Tom Peters (thopeter) Date: Thu, 4 Apr 2019 19:46:52 +0000 (-0400) Subject: Merge pull request #1568 in SNORT/snort3 from ~SBAIGAL/snort3:mime_filename to master X-Git-Tag: 3.0.0-252~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91ac2482ab10702edafbb59b980ff8e331054ab8;p=thirdparty%2Fsnort3.git Merge pull request #1568 in SNORT/snort3 from ~SBAIGAL/snort3:mime_filename to master Squashed commit of the following: commit c8ba2e41d3bbf7c8a7664ca65539026e1cc1510b Author: Steven Baigal (sbaigal) Date: Fri Mar 29 14:46:32 2019 -0400 file_api: add extract filename to FileFlow from mime header --- diff --git a/src/mime/file_mime_log.cc b/src/mime/file_mime_log.cc index 33d8221f1..e2911fcf8 100644 --- a/src/mime/file_mime_log.cc +++ b/src/mime/file_mime_log.cc @@ -29,7 +29,6 @@ #include "file_api/file_flows.h" #include "utils/safec.h" #include "utils/util.h" -#include "utils/util_cstring.h" using namespace snort; @@ -42,98 +41,20 @@ using namespace snort; #define MIME_FLAG_FILENAME_PRESENT 0x00000004 #define MIME_FLAG_EMAIL_HDRS_PRESENT 0x00000008 -/* Extract the filename from the header */ -int MailLogState::extract_file_name(const char** start, int length, bool* disp_cont) -{ - const char* tmp = nullptr; - const char* end = *start+length; - - if (length <= 0) - return -1; - - if (!(*disp_cont)) - { - tmp = SnortStrcasestr(*start, length, "filename"); - - if ( tmp == nullptr ) - return -1; - - tmp = tmp + 8; - while ( (tmp < end) && ((isspace(*tmp)) || (*tmp == '=') )) - { - tmp++; - } - } - else - tmp = *start; - - if (tmp < end) - { - if (*tmp == '"' || (*disp_cont)) - { - if (*tmp == '"') - { - if (*disp_cont) - { - *disp_cont = false; - return (tmp - *start); - } - tmp++; - } - *start = tmp; - tmp = SnortStrnPbrk(*start,(end - tmp),"\""); - if (tmp == nullptr ) - { - if ((end - tmp) > 0 ) - { - tmp = end; - *disp_cont = true; - } - else - return -1; - } - else - *disp_cont = false; - end = tmp; - } - else - { - *start = tmp; - } - return (end - *start); - } - else - { - return -1; - } -} - /* accumulate MIME attachment filenames. The filenames are appended by commas */ -int MailLogState::log_file_name(const uint8_t* start, int length, bool* disp_cont) +int MailLogState::log_file_name(const uint8_t* start, int length) { uint8_t* alt_buf; int alt_size; uint16_t* alt_len; - int ret=0; - int cont =0; + int log_avail = 0; if (!start || (length <= 0)) { - *disp_cont = false; return -1; } - if (*disp_cont) - cont = 1; - - ret = extract_file_name((const char**)(&start), length, disp_cont); - - if (ret == -1) - return ret; - - length = ret; - alt_buf = filenames; alt_size = MAX_FILE; alt_len = &(file_logged); @@ -144,11 +65,8 @@ int MailLogState::log_file_name(const uint8_t* start, int length, bool* disp_con if ( *alt_len > 0 && ((*alt_len + 1) < alt_size)) { - if (!cont) - { - alt_buf[*alt_len] = ','; - *alt_len = *alt_len + 1; - } + alt_buf[*alt_len] = ','; + *alt_len = *alt_len + 1; } if (length > log_avail) @@ -169,24 +87,6 @@ int MailLogState::log_file_name(const uint8_t* start, int length, bool* disp_con return 0; } -void MailLogState::set_file_name_from_log(Flow* flow) -{ - FileFlows* files = FileFlows::get_file_flows(flow); - - if (!files) - return; - - if (file_logged > file_current) - { - files->set_file_name(filenames + file_current, - file_logged - file_current); - } - else - { - files->set_file_name(nullptr, 0); - } -} - /* Accumulate EOL separated headers, one or more at a time */ int MailLogState::log_email_hdrs(const uint8_t* start, int length) { diff --git a/src/mime/file_mime_log.h b/src/mime/file_mime_log.h index f4a7e777f..9938b73d6 100644 --- a/src/mime/file_mime_log.h +++ b/src/mime/file_mime_log.h @@ -54,8 +54,7 @@ public: ~MailLogState(); /* accumulate MIME attachment filenames. The filenames are appended by commas */ - int log_file_name(const uint8_t* start, int length, bool* disp_cont); - void set_file_name_from_log(snort::Flow*); + int log_file_name(const uint8_t* start, int length); int log_email_hdrs(const uint8_t* start, int length); int log_email_id (const uint8_t* start, int length, EmailUserType); @@ -70,7 +69,6 @@ public: bool is_email_to_present(); private: - int extract_file_name(const char** start, int length, bool* disp_cont); int log_flags = 0; uint8_t* buf = nullptr; unsigned char* emailHdrs; diff --git a/src/mime/file_mime_process.cc b/src/mime/file_mime_process.cc index fbfb6646d..e12eebf8d 100644 --- a/src/mime/file_mime_process.cc +++ b/src/mime/file_mime_process.cc @@ -30,6 +30,7 @@ #include "file_api/file_flows.h" #include "log/messages.h" #include "search_engines/search_tool.h" +#include "utils/util_cstring.h" using namespace snort; @@ -369,10 +370,20 @@ const uint8_t* MimeSession::process_mime_header(const uint8_t* ptr, cont_disp) { bool disp_cont = (state_flags & MIME_FLAG_IN_CONT_DISP_CONT) ? true : false; - if (log_config->log_filename && log_state ) + int len = extract_file_name((const char*&)cont_disp, eolm - cont_disp, &disp_cont); + + if (len > 0) { - log_state->log_file_name(cont_disp, eolm - cont_disp, &disp_cont); + filename.assign((const char*)cont_disp, len); + + if (log_config->log_filename && log_state) + { + log_state->log_file_name(cont_disp, len); + } } + else + filename.clear(); + if (disp_cont) { state_flags |= MIME_FLAG_IN_CONT_DISP_CONT; @@ -590,7 +601,8 @@ const uint8_t* MimeSession::process_mime_data_paf( if (file_flows && file_flows->file_process(p, buffer, buf_size, position, upload) && (isFileStart(position)) && log_state) { - log_state->set_file_name_from_log(flow); + file_flows->set_file_name((const uint8_t*)filename.c_str(), filename.length()); + filename.clear(); } if (mime_stats) { @@ -694,6 +706,68 @@ MailLogState* MimeSession::get_log_state() return log_state; } +int MimeSession::extract_file_name(const char*& start, int length, bool* disp_cont) +{ + const char* tmp = nullptr; + const char* end = start+length; + + if (length <= 0) + return -1; + + if (!(*disp_cont)) + { + tmp = SnortStrcasestr(start, length, "filename"); + + if ( tmp == nullptr ) + return -1; + + tmp = tmp + 8; + while ( (tmp < end) && ((isspace(*tmp)) || (*tmp == '=') )) + { + tmp++; + } + } + else + tmp = start; + + if (tmp < end) + { + if (*tmp == '"' || (*disp_cont)) + { + if (*tmp == '"') + { + if (*disp_cont) + { + *disp_cont = false; + return (tmp - start); + } + tmp++; + } + start = tmp; + tmp = SnortStrnPbrk(start,(end - tmp),"\""); + if (tmp == nullptr ) + { + if ((end - tmp) > 0 ) + { + tmp = end; + *disp_cont = true; + } + else + return -1; + } + else + *disp_cont = false; + end = tmp; + } + else + { + start = tmp; + } + return (end - start); + } + return -1; +} + /* * This is the initialization function for mime processing. * This should be called when snort initializes diff --git a/src/mime/file_mime_process.h b/src/mime/file_mime_process.h index 5097b6212..a871672b2 100644 --- a/src/mime/file_mime_process.h +++ b/src/mime/file_mime_process.h @@ -23,7 +23,7 @@ // Provides list of MIME processing functions. Encoded file data will be decoded // and file name will be extracted from MIME header - +#include #include "file_api/file_api.h" #include "mime/file_mime_config.h" #include "mime/file_mime_decode.h" @@ -83,6 +83,7 @@ private: MailLogConfig* log_config = nullptr; MailLogState* log_state = nullptr; MimeStats* mime_stats = nullptr; + std::string filename; // SMTP, IMAP, POP might have different implementation for this virtual int handle_header_line(const uint8_t*, const uint8_t*, int) { return 0; } @@ -98,6 +99,7 @@ private: const uint8_t* process_mime_body(const uint8_t* ptr, const uint8_t* data_end,bool is_data_end); const uint8_t* process_mime_data_paf(Packet*, const uint8_t* start, const uint8_t* end, bool upload, FilePosition); + int extract_file_name(const char*& start, int length, bool* disp_cont); }; } #endif