if (!cb->elems)
{
snort_free(cb);
- return NULL;
+ return nullptr;
}
return cb;
if (cb && cb->elems)
{
snort_free(cb->elems);
- cb->elems = NULL;
+ cb->elems = nullptr;
}
snort_free(cb);
bool is_reserved() { return reserved; }
// Get the file that is reserved in memory, this should be called repeatedly
- // until NULL is returned to get the full file
+ // until nullptr is returned to get the full file
// Returns:
// the next memory block
- // NULL: end of file or fail to get file
+ // nullptr: end of file or fail to get file
FileCaptureBlock* get_file_data(uint8_t** buff, int* size);
// Get the file size captured in the file buffer
FileEnforcer::FileEnforcer()
{
fileHash = sfxhash_new(MAX_FILES_TRACKED, sizeof(FileHashKey), sizeof(FileNode),
- MAX_MEMORY_USED, 1, NULL, NULL, 1);
+ MAX_MEMORY_USED, 1, nullptr, nullptr, 1);
if (!fileHash)
FatalError("Failed to create the expected channel hash table.\n");
}
* Args:
* FileMemPool: pointer to a FileMemPool struct
*
- * Returns: a pointer to the FileMemPool object on success, NULL on failure
+ * Returns: a pointer to the FileMemPool object on success, nullptr on failure
*/
void* FileMemPool::m_alloc()
{
- void* b = NULL;
+ void* b = nullptr;
std::lock_guard<std::mutex> lock(pool_mutex);
{
if (cbuffer_read(released_list, &b))
{
- return NULL;
+ return nullptr;
}
}
}
}
-/*
- * - Only accepts 1 (ONE) callback being registered.
- *
- * - Call with NULL callback to "force" (guarantee) file type identification.
- *
- * TBD: Remove per-context "file_type_enabled" checking to simplify implementation.
- *
- */
void FileService::enable_file_type()
{
if (!file_type_id_enabled)
return DECODE_SUCCESS;
}
-B64Decode::B64Decode(int max_depth):DataDecode(max_depth)
+B64Decode::B64Decode(int max_depth, int detect_depth) : DataDecode(max_depth, detect_depth)
{
buffer = new DecodeBuffer(max_depth);
}
B64Decode::~B64Decode()
{
- if (buffer)
- delete buffer;
+ if (buffer)
+ delete buffer;
}
uint8_t sf_decode64tab[256] =
class B64Decode : public DataDecode
{
public:
- B64Decode(int max_depth);
+ B64Decode(int max_depth, int detect_depth);
~B64Decode();
// Main function to decode file data
uint8_t* inbuf, uint32_t inbuf_size,
uint8_t* outbuf, uint32_t outbuf_size,
uint32_t* bytes_written
-);
+ );
#endif
void DataDecode::reset_decode_state()
{
reset_decoded_bytes();
+ decode_bytes_read = 0;
}
int DataDecode::get_detection_depth()
{
// unlimited
- if (!decode_depth)
+ if (!detection_depth)
return decoded_bytes;
// exceeded depth before (decode_bytes_read has been updated)
- else if (decode_depth < (int64_t)decode_bytes_read - decoded_bytes)
+ else if (detection_depth < (int64_t)decode_bytes_read - decoded_bytes)
return 0;
// lower than depth
- else if (decode_depth > (int64_t)decode_bytes_read)
+ else if (detection_depth > (int64_t)decode_bytes_read)
return decoded_bytes;
// cut off
else
- return (decode_depth + (int64_t )decoded_bytes - decode_bytes_read);
+ return (detection_depth + (int64_t )decoded_bytes - decode_bytes_read);
}
int DataDecode::get_decoded_data(uint8_t** buf, uint32_t* size)
else
return 0;
- if (decodePtr != NULL)
+ if (decodePtr != nullptr)
*buf = decodePtr;
else
return 0;
return (*size);
}
-#define MAX_DEPTH 65536
-
-DataDecode::DataDecode(int max_depth)
+DataDecode::DataDecode(int, int detect_depth)
{
- decode_depth = max_depth;
+ detection_depth = detect_depth;
decode_bytes_read = 0;
decoded_bytes = 0;
}
DataDecode::~DataDecode()
{
-
}
+
DECODE_SUCCESS,
DECODE_EXCEEDED, // Decode Complete when we reach the max depths
DECODE_FAIL
-} ;
+};
class DataDecode
{
public:
- DataDecode(int max_depth);
+ DataDecode(int max_depth, int detect_depth);
virtual ~DataDecode();
// Main function to decode file data
virtual void reset_decode_state();
+ // Used to limit number of bytes examined for rule evaluation
int get_detection_depth();
protected:
uint32_t decoded_bytes = 0;
uint32_t decode_bytes_read;
uint8_t* decodePtr = nullptr;
- int decode_depth;
+ int detection_depth;
};
#endif
DecodeResult BitDecode::decode_data(const uint8_t* start, const uint8_t* end)
{
uint32_t bytes_avail = 0;
- uint32_t act_size = 0;
+ uint32_t act_size = end - start;
if (!(decode_depth))
{
- bytes_avail = buf_size;
+ bytes_avail = act_size;
}
- else if ( decode_depth < 0 )
+ else if ( (uint32_t)decode_depth > decode_bytes_read )
{
- return DECODE_EXCEEDED;
+ bytes_avail = (uint32_t)decode_depth - decode_bytes_read;
}
else
- {
- bytes_avail = decode_depth - decode_bytes_read;
- }
-
- /* 1. Stop decoding when we have reached either the decode depth or encode depth.
- * 2. Stop decoding when we are out of memory */
- if (bytes_avail ==0)
{
reset_decode_state();
return DECODE_EXCEEDED;
}
- if ( (uint32_t)(end-start) < bytes_avail )
- {
- act_size = ( end - start);
- }
- else
+ if ( act_size > bytes_avail )
{
act_size = bytes_avail;
}
return DECODE_SUCCESS;
}
-#define MAX_DEPTH 65536
-
-BitDecode::BitDecode(int max_depth):DataDecode(max_depth)
+BitDecode::BitDecode(int max_depth, int detect_depth) : DataDecode(max_depth, detect_depth)
{
- if (!max_depth)
- buf_size = MAX_DEPTH;
- else
- buf_size = max_depth;
decode_depth = max_depth;
decode_bytes_read = 0;
decoded_bytes = 0;
BitDecode::~BitDecode()
{
-
}
-
class BitDecode : public DataDecode
{
public:
- BitDecode(int max_depth);
+ BitDecode(int max_depth, int detect_depth);
~BitDecode();
// Main function to decode file data
void reset_decode_state() override;
private:
- uint32_t buf_size;
int decode_depth;
};
if (prev_encoded_bytes > encode_avail)
prev_encoded_bytes = encode_avail;
-
uint32_t prev_bytes = prev_encoded_bytes;
uint32_t i = 0;
prev_encoded_bytes = buff_size;
prev_encoded_buf = buff;
}
+
void update_buffer(uint32_t act_encode_size, uint32_t act_decode_size);
void reset();
- uint8_t* get_decode_buff() {return decodeBuf;}
- uint8_t* get_encode_buff() {return encodeBuf;}
- uint32_t get_decode_bytes_read() {return decode_bytes_read;}
+ uint8_t* get_decode_buff() { return decodeBuf; }
+ uint8_t* get_encode_buff() { return encodeBuf; }
+ uint32_t get_decode_bytes_read() { return decode_bytes_read; }
uint32_t get_decode_avail();
uint32_t get_encode_avail();
- uint32_t get_prev_encoded_bytes() {return prev_encoded_bytes;}
+ uint32_t get_prev_encoded_bytes() { return prev_encoded_bytes; }
private:
uint32_t buf_size;
}
else if (!act_decode_size && !encode_avail)
{
- reset_decode_state();
- return DECODE_FAIL;
+ reset_decode_state();
+ return DECODE_FAIL;
}
if (bytes_read < act_encode_size)
return DECODE_SUCCESS;
}
-
-QPDecode::QPDecode(int max_depth):DataDecode(max_depth)
+QPDecode::QPDecode(int max_depth, int detect_depth) : DataDecode(max_depth, detect_depth)
{
buffer = new DecodeBuffer(max_depth);
}
{
if (buffer)
delete buffer;
-
}
int sf_qpdecode(char* src, uint32_t slen, char* dst, uint32_t dlen, uint32_t* bytes_read,
return 0;
}
+
class QPDecode : public DataDecode
{
public:
- QPDecode(int max_depth);
+ QPDecode(int max_depth, int detect_depth);
~QPDecode();
// Main function to decode file data
private:
class DecodeBuffer* buffer = nullptr;
-
};
int sf_qpdecode(char* src, uint32_t slen, char* dst, uint32_t dlen, uint32_t* bytes_read,
act_encode_size = act_encode_size + buffer->get_prev_encoded_bytes();
if (sf_uudecode(buffer->get_encode_buff(), act_encode_size, buffer->get_decode_buff(),
- buffer->get_decode_avail(), &bytes_read, &act_decode_size,
- &(begin_found), &(end_found)) != 0)
+ buffer->get_decode_avail(), &bytes_read, &act_decode_size,
+ &(begin_found), &(end_found)) != 0)
{
reset_decode_state();
return DECODE_FAIL;
return DECODE_SUCCESS;
}
-
-UUDecode::UUDecode(int max_depth):DataDecode(max_depth)
+UUDecode::UUDecode(int max_depth, int detect_depth) : DataDecode(max_depth, detect_depth)
{
buffer = new DecodeBuffer(max_depth);
}
{
if (buffer)
delete buffer;
-
}
int sf_uudecode(uint8_t* src, uint32_t slen, uint8_t* dst, uint32_t dlen, uint32_t* bytes_read,
*bytes_copied = dptr - dst;
return 0;
}
+
class UUDecode : public DataDecode
{
public:
- UUDecode(int max_depth);
+ UUDecode(int max_depth, int detect_depth);
~UUDecode();
// Main function to decode file data
#include "file_mime_process.h"
-void DecodeConfig::update_max_depth(int64_t depth)
+DecodeConfig::DecodeConfig()
{
- // 0 means unlimited
- if (!depth)
- max_depth = MAX_DEPTH;
- else if (max_depth < depth)
- max_depth = depth;
+ sync_all_depths();
}
void DecodeConfig::set_ignore_data(bool ignored)
void DecodeConfig::set_b64_depth(int depth)
{
b64_depth = depth;
- update_max_depth(depth);
}
int DecodeConfig::get_b64_depth()
void DecodeConfig::set_qp_depth(int depth)
{
qp_depth = depth;
- update_max_depth(depth);
}
int DecodeConfig::get_qp_depth()
void DecodeConfig::set_bitenc_depth(int depth)
{
bitenc_depth = depth;
- update_max_depth(depth);
}
int DecodeConfig::get_bitenc_depth()
void DecodeConfig::set_uu_depth(int depth)
{
uu_depth = depth;
- update_max_depth(depth);
}
int DecodeConfig::get_uu_depth()
return file_depth;
}
-int DecodeConfig::get_max_depth()
-{
- return max_depth;
-}
-
bool DecodeConfig::is_decoding_enabled()
{
- if (max_depth > -1)
- return true;
- else
- return false;
-}
-
-void DecodeConfig::set_file_depth(int64_t file_depth)
-{
- if ((!file_depth) || (file_depth > MAX_DEPTH))
- {
- max_depth = MAX_DEPTH;
- }
- else if (file_depth > max_depth)
- {
- max_depth = (int)file_depth;
- }
+ return decode_enabled;
}
// update file depth and max_depth etc
void DecodeConfig::sync_all_depths()
{
file_depth = FileService::get_max_file_depth();
+ if ((file_depth >= 0)or (b64_depth >= 0) or (qp_depth >= 0)
+ or (bitenc_depth >= 0) or (uu_depth >= 0))
+ decode_enabled = true;
+ else
+ decode_enabled = false;
+}
- set_file_depth(file_depth);
+int DecodeConfig::get_max_depth(int decode_depth)
+{
+ sync_all_depths();
+
+ if (!file_depth or !decode_depth)
+ return 0;
+ else if (file_depth > decode_depth)
+ return file_depth;
+ else
+ return decode_depth;
}
void DecodeConfig::print_decode_conf()
else
LogMessage(" Non-Encoded MIME attachment Extraction/text: %s\n", "Disabled");
}
+
class SO_PUBLIC DecodeConfig
{
public:
+ DecodeConfig();
void set_ignore_data(bool);
bool is_ignore_data();
void set_max_mime_mem(int);
int get_bitenc_depth();
void set_uu_depth(int);
int get_uu_depth();
- int get_max_depth();
int64_t get_file_depth();
bool is_decoding_enabled();
void sync_all_depths();
void print_decode_conf();
+ int get_max_depth(int);
private:
bool ignore_data = false;
int bitenc_depth = DEFAULT_DEPTH;
int uu_depth = DEFAULT_DEPTH;
int64_t file_depth = MIN_DEPTH;
- int max_depth = DEFAULT_DEPTH; //is the max of all depths
- void set_file_depth(int64_t);
- void update_max_depth(int64_t);
+ bool decode_enabled = true;
};
#endif
decoder->reset_decode_state();
}
-void MimeDecode::process_decode_type(const char* start, int length, bool cnt_xf, MimeStats* mime_stats)
+void MimeDecode::process_decode_type(const char* start, int length, bool cnt_xf,
+ MimeStats* mime_stats)
{
- const char* tmp = NULL;
+ const char* tmp = nullptr;
if (decoder)
delete decoder;
if (config->get_b64_depth() > -1)
{
tmp = SnortStrcasestr(start, length, "base64");
- if ( tmp != NULL )
+ if ( tmp != nullptr )
{
decode_type = DECODE_B64;
if (mime_stats)
mime_stats->b64_attachments++;
- decoder = new B64Decode(config->get_b64_depth());
+ decoder = new B64Decode(config->get_max_depth(config->get_b64_depth()),
+ config->get_b64_depth());
return;
}
}
if (config->get_qp_depth() > -1)
{
tmp = SnortStrcasestr(start, length, "quoted-printable");
- if ( tmp != NULL )
+ if ( tmp != nullptr )
{
decode_type = DECODE_QP;
if (mime_stats)
mime_stats->qp_attachments++;
- decoder = new QPDecode(config->get_qp_depth());
+ decoder = new QPDecode(config->get_max_depth(config->get_qp_depth()),
+ config->get_qp_depth());
return;
}
}
if (config->get_uu_depth() > -1)
{
tmp = SnortStrcasestr(start, length, "uuencode");
- if ( tmp != NULL )
+ if ( tmp != nullptr )
{
decode_type = DECODE_UU;
if (mime_stats)
mime_stats->uu_attachments++;
- decoder = new UUDecode(config->get_uu_depth());
+ decoder = new UUDecode(config->get_max_depth(config->get_uu_depth()),
+ config->get_uu_depth());
return;
}
}
decode_type = DECODE_BITENC;
if (mime_stats)
mime_stats->bitenc_attachments++;
- decoder = new BitDecode(config->get_bitenc_depth());
+ decoder = new BitDecode(config->get_max_depth(config->get_bitenc_depth()),
+ config->get_bitenc_depth());
return;
}
}
DecodeResult MimeDecode::decode_data(const uint8_t* start, const uint8_t* end)
{
- return (decoder? decoder->decode_data(start,end):DECODE_SUCCESS);
+ return (decoder ? decoder->decode_data(start,end) : DECODE_SUCCESS);
}
int MimeDecode::get_detection_depth()
{
- return (decoder?decoder->get_detection_depth():0);
+ return (decoder ? decoder->get_detection_depth() : 0);
}
int MimeDecode::get_decoded_data(uint8_t** buf, uint32_t* size)
{
- return (decoder? decoder->get_decoded_data(buf, size):0);
+ return (decoder ? decoder->get_decoded_data(buf, size) : 0);
}
DecodeType MimeDecode::get_decode_type()
if (decoder)
delete decoder;
}
+
#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 = NULL;
+ const char* tmp = nullptr;
const char* end = *start+length;
if (length <= 0)
{
tmp = SnortStrcasestr(*start, length, "filename");
- if ( tmp == NULL )
+ if ( tmp == nullptr )
return -1;
tmp = tmp + 8;
}
*start = tmp;
tmp = SnortStrnPbrk(*start,(end - tmp),"\"");
- if (tmp == NULL )
+ if (tmp == nullptr )
{
if ((end - tmp) > 0 )
{
return 0;
}
-
void MailLogState::set_file_name_from_log(Flow* flow)
{
FileFlows* files = FileFlows::get_file_flows(flow);
return -1;
tmp_eol = (uint8_t*)memchr(start, ':', length);
- if (tmp_eol == NULL)
+ if (tmp_eol == nullptr)
return -1;
if ((tmp_eol+1) < (start+length))
{
*buf = emailHdrs;
*len = hdrs_logged;
-
}
void MailLogState::get_email_id(uint8_t** buf, uint32_t* len, EmailUserType type)
MailLogState::MailLogState(MailLogConfig* conf)
{
if (conf && (conf->log_email_hdrs || conf->log_filename
- || conf->log_mailfrom || conf->log_rcptto))
+ || conf->log_mailfrom || conf->log_rcptto))
{
uint32_t bufsz = (2* MAX_EMAIL) + MAX_FILE + conf->email_hdrs_log_depth;
buf = (uint8_t*)snort_calloc(bufsz);
MailLogState::~MailLogState()
{
- if (buf != NULL)
+ if (buf != nullptr)
snort_free(buf);
}
+
~MailLogState();
/* accumulate MIME attachment filenames. The filenames are appended by commas */
- int log_file_name (const uint8_t* start, int length, bool* disp_cont);
+ int log_file_name(const uint8_t* start, int length, bool* disp_cont);
void set_file_name_from_log(Flow*);
int log_email_hdrs(const uint8_t* start, int length);
int log_email_id (const uint8_t* start, int length, EmailUserType);
- void get_file_name (uint8_t** buf, uint32_t* len);
- void get_email_hdrs (uint8_t** buf, uint32_t* len);
- void get_email_id (uint8_t** buf, uint32_t* len, EmailUserType);
+ void get_file_name(uint8_t** buf, uint32_t* len);
+ void get_email_hdrs(uint8_t** buf, uint32_t* len);
+ void get_email_id(uint8_t** buf, uint32_t* len, EmailUserType);
bool is_file_name_present();
bool is_email_hdrs_present();
if (val == '=')
data_info->boundary_search++;
else if (!isspace(val))
- data_info->boundary_search = NULL;
+ data_info->boundary_search = nullptr;
}
else if (*(data_info->boundary_search) == '\0')
{
if ((val == '.') || isspace (val))
data_info->boundary_search = (char*)&boundary_str[0];
else
- data_info->boundary_search = NULL;
+ data_info->boundary_search = nullptr;
}
return false;
switch (data_info->boundary_state)
{
case MIME_PAF_BOUNDARY_UNKNOWN:
- if (data == '\n')
- data_info->boundary_state = MIME_PAF_BOUNDARY_LF;
- break;
-
- case MIME_PAF_BOUNDARY_LF:
if (data == '-')
data_info->boundary_state = MIME_PAF_BOUNDARY_HYPEN_FIRST;
- else if (data != '\n')
- data_info->boundary_state = MIME_PAF_BOUNDARY_UNKNOWN;
break;
case MIME_PAF_BOUNDARY_HYPEN_FIRST:
data_info->boundary_state = MIME_PAF_BOUNDARY_HYPEN_SECOND;
data_info->boundary_search = data_info->boundary;
}
- else if (data == '\n')
- data_info->boundary_state = MIME_PAF_BOUNDARY_LF;
else
data_info->boundary_state = MIME_PAF_BOUNDARY_UNKNOWN;
break;
}
else if (*(data_info->boundary_search) == data)
data_info->boundary_search++;
+ else if (data == '-')
+ data_info->boundary_state = MIME_PAF_BOUNDARY_HYPEN_FIRST;
else
data_info->boundary_state = MIME_PAF_BOUNDARY_UNKNOWN;
break;
void reset_mime_paf_state(MimeDataPafInfo* data_info)
{
- data_info->boundary_search = NULL;
+ data_info->boundary_search = nullptr;
data_info->boundary_len = 0;
data_info->boundary[0] = '\0';
data_info->boundary_state = MIME_PAF_BOUNDARY_UNKNOWN;
enum MimeBoundaryState
{
MIME_PAF_BOUNDARY_UNKNOWN = 0, /* UNKNOWN */
- MIME_PAF_BOUNDARY_LF, /* '\n' */
MIME_PAF_BOUNDARY_HYPEN_FIRST, /* First '-' */
MIME_PAF_BOUNDARY_HYPEN_SECOND /* Second '-' */
};
const char* name;
int name_len;
int search_id;
-} ;
+};
enum MimeHdrEnum
{
{ "Content-type:", 13, HDR_CONTENT_TYPE },
{ "Content-Transfer-Encoding:", 26, HDR_CONT_TRANS_ENC },
{ "Content-Disposition:", 20, HDR_CONT_DISP },
- { NULL, 0, 0 }
+ { nullptr, 0, 0 }
};
struct MIMESearch
{
const char* name;
int name_len;
-} ;
+};
struct MIMESearchInfo
{
int id;
int index;
int length;
-} ;
+};
MIMESearchInfo mime_search_info;
SearchTool* mime_hdr_search_mpse = nullptr;
MIMESearch mime_hdr_search[HDR_LAST];
-MIMESearch* mime_current_search = NULL;
+MIMESearch* mime_current_search = nullptr;
static void get_mime_eol(const uint8_t* ptr, const uint8_t* end,
const uint8_t** eol, const uint8_t** eolm)
}
tmp_eol = (uint8_t*)memchr(ptr, '\n', end - ptr);
- if (tmp_eol == NULL)
+ if (tmp_eol == nullptr)
{
tmp_eol = end;
tmp_eolm = end;
/* Check for Encoding Type */
if ( decode_conf && decode_conf->is_decoding_enabled())
{
- if (decode_state == NULL)
+ if (decode_state == nullptr)
{
decode_state = new MimeDecode(decode_conf);
}
- if (decode_state != NULL)
+ if (decode_state != nullptr)
{
decode_state->process_decode_type(data, size, cnt_xf, mime_stats);
state_flags |= MIME_FLAG_EMAIL_ATTACH;
const uint8_t* eol = data_end_marker;
const uint8_t* eolm = eol;
const uint8_t* colon;
- const uint8_t* content_type_ptr = NULL;
- const uint8_t* cont_trans_enc = NULL;
- const uint8_t* cont_disp = NULL;
+ const uint8_t* content_type_ptr = nullptr;
+ const uint8_t* cont_trans_enc = nullptr;
+ const uint8_t* cont_disp = nullptr;
int header_found;
const uint8_t* start_hdr;
int ret = handle_header_line(ptr, eol, max_header_name_len);
if (ret < 0)
- return NULL;
+ return nullptr;
else if (ret > 0)
{
/* assume we guessed wrong and are in the body */
data_state = STATE_DATA_BODY;
state_flags &=
~(MIME_FLAG_FOLDING | MIME_FLAG_IN_CONTENT_TYPE | MIME_FLAG_DATA_HEADER_CONT
- | MIME_FLAG_IN_CONT_TRANS_ENC | MIME_FLAG_IN_CONT_DISP);
+ | MIME_FLAG_IN_CONT_TRANS_ENC | MIME_FLAG_IN_CONT_DISP);
return ptr;
}
* because boundary=BOUNDARY can be split across mulitple folded lines before
* or after the '=' */
if ((state_flags &
- (MIME_FLAG_IN_CONTENT_TYPE | MIME_FLAG_FOLDING)) == MIME_FLAG_IN_CONTENT_TYPE)
+ (MIME_FLAG_IN_CONTENT_TYPE | MIME_FLAG_FOLDING)) == MIME_FLAG_IN_CONTENT_TYPE)
{
if ((data_state == STATE_MIME_HEADER) && !(state_flags &
- MIME_FLAG_EMAIL_ATTACH))
+ MIME_FLAG_EMAIL_ATTACH))
{
setup_decode((const char*)content_type_ptr, (eolm - content_type_ptr), false);
}
state_flags &= ~MIME_FLAG_IN_CONTENT_TYPE;
- content_type_ptr = NULL;
+ content_type_ptr = nullptr;
}
else if ((state_flags &
- (MIME_FLAG_IN_CONT_TRANS_ENC | MIME_FLAG_FOLDING)) == MIME_FLAG_IN_CONT_TRANS_ENC)
+ (MIME_FLAG_IN_CONT_TRANS_ENC | MIME_FLAG_FOLDING)) == MIME_FLAG_IN_CONT_TRANS_ENC)
{
setup_decode((const char*)cont_trans_enc, (eolm - cont_trans_enc), true);
state_flags &= ~MIME_FLAG_IN_CONT_TRANS_ENC;
- cont_trans_enc = NULL;
+ cont_trans_enc = nullptr;
}
else if (((state_flags &
- (MIME_FLAG_IN_CONT_DISP | MIME_FLAG_FOLDING)) == MIME_FLAG_IN_CONT_DISP) && cont_disp)
+ (MIME_FLAG_IN_CONT_DISP | MIME_FLAG_FOLDING)) == MIME_FLAG_IN_CONT_DISP) &&
+ cont_disp)
{
bool disp_cont = (state_flags & MIME_FLAG_IN_CONT_DISP_CONT) ? true : false;
if (log_config->log_filename && log_state )
{
log_state->log_file_name(cont_disp, eolm - cont_disp, &disp_cont);
-
}
if (disp_cont)
{
state_flags &= ~MIME_FLAG_IN_CONT_DISP_CONT;
}
- cont_disp = NULL;
+ cont_disp = nullptr;
}
- data_state = STATE_DATA_HEADER;
-
ptr = eol;
if (ptr == data_end_marker)
const uint8_t* MimeSession::process_mime_body(const uint8_t* ptr,
const uint8_t* data_end, bool is_data_end)
{
-
if (state_flags & MIME_FLAG_EMAIL_ATTACH)
{
const uint8_t* attach_start = ptr;
{
if ((start < end) && (*start == '.'))
{
- const uint8_t* eol = NULL;
- const uint8_t* eolm = NULL;
+ const uint8_t* eol = nullptr;
+ const uint8_t* eolm = nullptr;
get_mime_eol(start, end, &eol, &eolm);
/* if we're normalizing and not ignoring data copy data end marker
* and dot to alt buffer */
if (normalize_data(start, end) < 0)
- return NULL;
+ return nullptr;
reset_mime_state();
#endif
start = process_mime_header(start, end);
- if (start == NULL)
- return NULL;
+ if (start == nullptr)
+ return nullptr;
}
if (normalize_data(start, end) < 0)
- return NULL;
+ return nullptr;
/* now we shouldn't have to worry about copying any data to the alt buffer
* * only mime headers if we find them and only if we're ignoring data */
- while ((start != NULL) && (start < end))
+ while ((start != nullptr) && (start < end))
{
switch (data_state)
{
/* We have either reached the end of MIME header or end of MIME encoded data*/
- if ((decode_state) != NULL)
+ if ((decode_state) != nullptr)
{
DecodeConfig* conf= decode_conf;
- uint8_t* buffer = NULL;
+ uint8_t* buffer = nullptr;
uint32_t buf_size = 0;
decode_state->get_decoded_data(&buffer, &buf_size);
}
if (mime_stats)
{
- switch(decode_state->get_decode_type())
+ switch (decode_state->get_decode_type())
{
- case DECODE_B64:
- mime_stats->b64_bytes += buf_size;
- break;
- case DECODE_QP:
- mime_stats->qp_bytes += buf_size;
- break;
- case DECODE_UU:
- mime_stats->uu_bytes += buf_size;
- break;
- case DECODE_BITENC:
- mime_stats->bitenc_bytes += buf_size;
- break;
- default:
- break;
+ case DECODE_B64:
+ mime_stats->b64_bytes += buf_size;
+ break;
+ case DECODE_QP:
+ mime_stats->qp_bytes += buf_size;
+ break;
+ case DECODE_UU:
+ mime_stats->uu_bytes += buf_size;
+ break;
+ case DECODE_BITENC:
+ mime_stats->bitenc_bytes += buf_size;
+ break;
+ default:
+ break;
}
}
finalFilePosition(&position);
process_mime_data_paf(flow, attach_start, attach_end,
upload, position);
+ data_state = STATE_MIME_HEADER;
position = SNORT_FILE_START;
attach_start = start + 1;
}
/* Header search */
mime_hdr_search_mpse = new SearchTool();
- if (mime_hdr_search_mpse == NULL)
+ if (mime_hdr_search_mpse == nullptr)
{
// FIXIT-M make configurable or at least fall back to any
// available search engine
FatalError("Could not instantiate ac_bnfa search engine.\n");
}
- for (tmp = &mime_hdrs[0]; tmp->name != NULL; tmp++)
+ for (tmp = &mime_hdrs[0]; tmp->name != nullptr; tmp++)
{
mime_hdr_search[tmp->search_id].name = tmp->name;
mime_hdr_search[tmp->search_id].name_len = tmp->name_len;
// Free anything that needs it before shutting down preprocessor
void MimeSession::exit()
{
- if (mime_hdr_search_mpse != NULL)
+ if (mime_hdr_search_mpse != nullptr)
delete mime_hdr_search_mpse;
}
if ( log_state )
delete(log_state);
}
+
// SMTP, IMAP, POP might have different implementation for this
virtual int handle_header_line(const uint8_t*, const uint8_t*, int) { return 0; }
- virtual int normalize_data(const uint8_t* , const uint8_t* ) { return 0; }
+ virtual int normalize_data(const uint8_t*, const uint8_t*) { return 0; }
virtual void decode_alert() { }
- virtual void reset_state(Flow* ) { }
- virtual bool is_end_of_data(Flow* ) { return false; }
+ virtual void reset_state(Flow*) { }
+ virtual bool is_end_of_data(Flow*) { return false; }
void reset_mime_state();
void setup_decode(const char* data, int size, bool cnt_xf);
const int32_t fp_length = (file_data.length <= session_data->file_depth_remaining[source_id]) ?
file_data.length : session_data->file_depth_remaining[source_id];
- if (source_id == SRC_SERVER)
+ if (!session_data->mime_state)
{
FileFlows* file_flows = FileFlows::get_file_flows(flow);
+ bool download = (source_id == SRC_SERVER);
if (file_flows->file_process(file_data.start, fp_length,
- file_position, false))
+ file_position, !download))
{
session_data->file_depth_remaining[source_id] -= fp_length;
else
{
session_data->mime_state->process_mime_data(flow, file_data.start,
- fp_length, true, file_position);
+ fp_length, true, SNORT_FILE_POSITION_UNKNOWN);
session_data->file_depth_remaining[source_id] -= fp_length;
if (session_data->file_depth_remaining[source_id] == 0)
session_data->file_depth_remaining[source_id] = 0;
return;
}
-
- if (source_id == SRC_CLIENT)
+ // FIXIT check boundary to make sure this is not MIME for sure
+ if ((source_id == SRC_CLIENT) and (get_header_value_norm(HEAD_CONTENT_TYPE).length > 0 ))
{
session_data->mime_state = new MimeSession(&decode_conf, &mime_conf);
+ const Field& headers = get_classic_raw_header();
+ if (headers.length > 0)
+ {
+ session_data->mime_state->process_mime_data(flow, headers.start,
+ headers.length, true, SNORT_FILE_POSITION_UNKNOWN);
+ }
}
else
{
(session_data->cutter[source_id] != nullptr) &&
(session_data->cutter[source_id]->get_octets_seen() == 0))
{
- if (source_id == SRC_SERVER)
+ if (!session_data->mime_state)
{
FileFlows* file_flows = FileFlows::get_file_flows(flow);
- file_flows->file_process(nullptr, 0, SNORT_FILE_END, false);
+ bool download = (source_id == SRC_SERVER);
+ file_flows->file_process(nullptr, 0, SNORT_FILE_END, !download);
}
- else if (session_data->mime_state != nullptr)
+ else
{
session_data->mime_state->process_mime_data(flow, nullptr, 0, true,
- SNORT_FILE_END);
+ SNORT_FILE_POSITION_UNKNOWN);
delete session_data->mime_state;
session_data->mime_state = nullptr;
}