From: huica Date: Tue, 21 Jul 2015 20:42:26 +0000 (-0400) Subject: first compiled version X-Git-Tag: 3.0.0-233~828^2~49 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=55a609496c97df9f94ebd31c5bb78d112f4974be;p=thirdparty%2Fsnort3.git first compiled version --- diff --git a/src/file_api/file_mime_log.cc b/src/file_api/file_mime_log.cc index 12894223d..5c243998f 100644 --- a/src/file_api/file_mime_log.cc +++ b/src/file_api/file_mime_log.cc @@ -175,6 +175,11 @@ void MailLogState::set_file_name_from_log(void* pv) } } +const FileLogState* MailLogState::get_file_log_state() +{ + return &log_state; +} + MailLogState::MailLogState(MailLogConfig* conf) { if (conf && (conf->log_email_hdrs || conf->log_filename diff --git a/src/file_api/file_mime_log.h b/src/file_api/file_mime_log.h index f5c5fbebc..d153aa0ca 100644 --- a/src/file_api/file_mime_log.h +++ b/src/file_api/file_mime_log.h @@ -47,9 +47,7 @@ public: /* 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(void* pv); - -private: - int extract_file_name(const char** start, int length, bool* disp_cont); + const FileLogState* get_file_log_state(); unsigned char* emailHdrs; uint32_t log_depth; uint32_t hdrs_logged; @@ -57,13 +55,15 @@ private: uint16_t rcpts_logged; uint8_t* senders; uint16_t snds_logged; + +private: + int extract_file_name(const char** start, int length, bool* disp_cont); FileLogState log_state; uint8_t* buf; }; struct MailLogConfig { - uint32_t memcap = DEFAULT_MIME_MEMCAP; char log_mailfrom = 0; char log_rcptto = 0; char log_filename = 0; diff --git a/src/file_api/file_mime_process.cc b/src/file_api/file_mime_process.cc index cb8735129..3dc4a0f64 100644 --- a/src/file_api/file_mime_process.cc +++ b/src/file_api/file_mime_process.cc @@ -370,20 +370,17 @@ const uint8_t* MimeSession::process_mime_header(const uint8_t* ptr, state_flags &= ~MIME_FLAG_DATA_HEADER_CONT; } - if (methods && methods->handle_header_line) + int ret = handle_header_line(config, ptr, eol, max_header_name_len); + if (ret < 0) + return NULL; + else if (ret > 0) { - int ret = methods->handle_header_line(config, ptr, eol, max_header_name_len, NULL); - if (ret < 0) - return NULL; - 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 + /* 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); - return ptr; - } + return ptr; } /* check for folding @@ -507,7 +504,6 @@ static const uint8_t* GetDataEnd(const uint8_t* data_start, const uint8_t* MimeSession::process_mime_body(const uint8_t* ptr, const uint8_t* data_end, bool is_data_end) { - Email_DecodeState* decode_state = (Email_DecodeState*)(decode_state); if (state_flags & MIME_FLAG_EMAIL_ATTACH) { @@ -527,8 +523,7 @@ const uint8_t* MimeSession::process_mime_body(const uint8_t* ptr, { if (EmailDecode(attach_start, attach_end, decode_state) < DECODE_SUCCESS ) { - if (methods && methods->decode_alert) - methods->decode_alert(decode_state); + decode_alert(decode_state); } } } @@ -560,12 +555,8 @@ void MimeSession::reset_mime_state() const uint8_t* MimeSession::process_mime_data_paf(Flow* flow, const uint8_t* start, const uint8_t* end, bool upload, FilePosition position) { - bool done_data = false; - if (methods && methods->is_end_of_data) - { - done_data = methods->is_end_of_data(flow); - } + bool done_data = is_end_of_data(flow); /* if we've just entered the data state, check for a dot + end of line * if found, no data */ @@ -585,11 +576,8 @@ const uint8_t* MimeSession::process_mime_data_paf(Flow* flow, const uint8_t* sta { /* if we're normalizing and not ignoring data copy data end marker * and dot to alt buffer */ - if (methods && methods->normalize_data) - { - if (methods->normalize_data(config, start, end) < 0) - return NULL; - } + if (normalize_data(config, start, end) < 0) + return NULL; reset_mime_state(); @@ -636,11 +624,9 @@ const uint8_t* MimeSession::process_mime_data_paf(Flow* flow, const uint8_t* sta return NULL; } - if (methods && methods->normalize_data) - { - if (methods->normalize_data(config, start, end) < 0) - return NULL; - } + + if (normalize_data(config, start, end) < 0) + return NULL; /* 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 */ @@ -689,8 +675,7 @@ const uint8_t* MimeSession::process_mime_data_paf(Flow* flow, const uint8_t* sta if (done_data) { reset_mime_state(); - if (methods && methods->reset_state) - methods->reset_state(flow); + reset_state(flow); } return end; @@ -743,6 +728,21 @@ const uint8_t* MimeSession::process_mime_data(Flow* flow, const uint8_t* start, return data_end_marker; } +int MimeSession::get_data_state() +{ + return data_state; +} + +void MimeSession::set_data_state(int state) +{ + data_state = state; +} + +MailLogState* MimeSession::get_log_state() +{ + return log_state; +} + /* * This is the initialization function for mime processing. * This should be called when snort initializes diff --git a/src/file_api/file_mime_process.h b/src/file_api/file_mime_process.h index c429225cb..bdc7407f8 100644 --- a/src/file_api/file_mime_process.h +++ b/src/file_api/file_mime_process.h @@ -55,44 +55,42 @@ /* Maximum length of header chars before colon, based on Exim 4.32 exploit */ #define MAX_HEADER_NAME_LEN 64 -typedef int (*Handle_header_line_func)(void* conf, const uint8_t* ptr, - const uint8_t* eol, int - max_header_len, void* mime_ssn); -typedef int (*Normalize_data_func)(void* conf, const uint8_t* ptr, - const uint8_t* data_end); -typedef void (*Decode_alert_func)(void* decode_state); -typedef void (*Reset_state_func)(void* ssn); -typedef bool (*Is_end_of_data_func)(void* ssn); - -struct MimeMethods -{ - Handle_header_line_func handle_header_line; - Normalize_data_func normalize_data; - Decode_alert_func decode_alert; - Reset_state_func reset_state; - Is_end_of_data_func is_end_of_data; -}; - class MimeSession { public: MimeSession(DecodeConfig*, MailLogConfig*); - ~MimeSession(); + virtual ~MimeSession(); static void init(); static void exit(); const uint8_t* process_mime_data(Flow *flow, const uint8_t *start, const uint8_t *end, bool upload, FilePosition position); + int get_data_state(); + void set_data_state(int); + MailLogState* get_log_state(); + int log_flags = 0; private: int data_state = STATE_DATA_INIT; int state_flags = 0; - int log_flags = 0; Email_DecodeState* decode_state = NULL; MimeDataPafInfo mime_boundary; DecodeConfig* decode_conf = NULL; MailLogConfig* log_config = NULL; MailLogState* log_state = NULL; + + // SMTP, IMAP, POP might have different implementation for this void* config = NULL; - MimeMethods* methods = NULL; + virtual int handle_header_line(void* conf, const uint8_t* ptr, const uint8_t* eol, + int max_header_len) + { return 0; } + virtual int normalize_data(void* conf, const uint8_t* ptr, const uint8_t* data_end) + { return 0; } + virtual void decode_alert(void* decode_state) + { } + virtual void reset_state(void* ssn) + { } + virtual bool is_end_of_data(void* ssn) + { return false; } + void set_mime_buffers(); void reset_mime_state(); void process_decode_type(const char* start, int length, bool cnt_xf); diff --git a/src/service_inspectors/http_inspect/hi_main.cc b/src/service_inspectors/http_inspect/hi_main.cc index 9a5a88c41..c3ace92d6 100644 --- a/src/service_inspectors/http_inspect/hi_main.cc +++ b/src/service_inspectors/http_inspect/hi_main.cc @@ -654,7 +654,7 @@ int HttpInspectMain(HTTPINSPECT_CONF* conf, Packet* p) if (hsd->mime_ssn) { uint8_t* end = ( uint8_t*)(p->data) + p->dsize; - file_api->process_mime_data(p->flow, p->data, end, hsd->mime_ssn, 1, + hsd->mime_ssn->process_mime_data(p->flow, p->data, end, 1, SNORT_FILE_POSITION_UNKNOWN); } else if (file_api->get_file_processed_size(p->flow) >0) @@ -772,22 +772,13 @@ int HttpInspectMain(HTTPINSPECT_CONF* conf, Packet* p) if (!hsd->mime_ssn) { - hsd->mime_ssn = (MimeSession*)SnortAlloc(sizeof(MimeSession)); - if (!hsd->mime_ssn) - return 0; - hsd->mime_ssn->log_config = &(conf->global->mime_conf); - hsd->mime_ssn->decode_conf = conf->global->decode_conf; - /*Set log buffers per session*/ - if (file_api->set_log_buffers( - &(hsd->mime_ssn->log_state), hsd->mime_ssn->log_config) < 0) - { - return 0; - } + hsd->mime_ssn = new MimeSession(conf->global->decode_conf, + &(conf->global->mime_conf)); } end = (uint8_t*)(session->client.request.post_raw + session->client.request.post_raw_size); - file_api->process_mime_data(p->flow, start, end, hsd->mime_ssn, 1, + hsd->mime_ssn->process_mime_data(p->flow, start, end, 1, SNORT_FILE_POSITION_UNKNOWN); } else @@ -825,7 +816,7 @@ int HttpInspectMain(HTTPINSPECT_CONF* conf, Packet* p) if (hsd->mime_ssn) { uint8_t* end = ( uint8_t*)(p->data) + p->dsize; - file_api->process_mime_data(p->flow, p->data, end, hsd->mime_ssn, 1, + hsd->mime_ssn->process_mime_data(p->flow, p->data, end, 1, SNORT_FILE_POSITION_UNKNOWN); } else if (file_api->get_file_processed_size(p->flow) >0) @@ -1169,7 +1160,8 @@ void FreeHttpSessionData(void* data) if (hsd->true_ip) sfip_free(hsd->true_ip); - file_api->free_mime_session(hsd->mime_ssn); + if (hsd->mime_ssn) + delete(hsd->mime_ssn); if ( hsd->fd_state != 0 ) { diff --git a/src/service_inspectors/imap/imap.cc b/src/service_inspectors/imap/imap.cc index 56ac15b91..464ad1ee8 100644 --- a/src/service_inspectors/imap/imap.cc +++ b/src/service_inspectors/imap/imap.cc @@ -129,17 +129,16 @@ IMAPSearch imap_cmd_search[CMD_LAST]; THREAD_LOCAL const IMAPSearch* imap_current_search = NULL; THREAD_LOCAL IMAPSearchInfo imap_search_info; -static void snort_imap(IMAP_PROTO_CONF* GlobalConf, Packet* p); -static void IMAP_ResetState(void*); -void IMAP_DecodeAlert(void* ds); - -MimeMethods imap_mime_methods = { NULL, NULL, IMAP_DecodeAlert, IMAP_ResetState, imap_is_data_end }; +static void POP_ResetState(void*); ImapFlowData::ImapFlowData() : FlowData(flow_id) { memset(&session, 0, sizeof(session)); } ImapFlowData::~ImapFlowData() -{ free_mime_session(session.mime_ssn); } +{ + if(session.mime_ssn) + delete(session.mime_ssn); +} unsigned ImapFlowData::flow_id = 0; static IMAPData* get_session_data(Flow* flow) @@ -158,14 +157,9 @@ IMAPData* SetNewIMAPData(IMAP_PROTO_CONF* config, Packet* p) p->flow->set_application_data(fd); imap_ssn = &fd->session; - imap_ssn->mime_ssn.log_config = &(config->log_config); - imap_ssn->mime_ssn.decode_conf = &(config->decode_conf); - imap_ssn->mime_ssn.methods = &(imap_mime_methods); - imap_ssn->mime_ssn.config = config; - if (file_api->set_log_buffers(&(imap_ssn->mime_ssn.log_state), &(config->log_config)) < 0) - { - return NULL; - } + imap_ssn->mime_ssn= new ImapMime(&(config->decode_conf),&(config->log_config)); + //imap_ssn->mime_ssn.methods = &(imap_mime_methods); + //imap_ssn->mime_ssn.config = config; if (p->packet_flags & SSNFLAG_MIDSTREAM) { @@ -179,26 +173,6 @@ IMAPData* SetNewIMAPData(IMAP_PROTO_CONF* config, Packet* p) return imap_ssn; } -void IMAP_DecodeAlert(void* ds) -{ - Email_DecodeState* decode_state = (Email_DecodeState*)ds; - switch ( decode_state->decode_type ) - { - case DECODE_B64: - SnortEventqAdd(GID_IMAP, IMAP_B64_DECODING_FAILED); - break; - case DECODE_QP: - SnortEventqAdd(GID_IMAP, IMAP_QP_DECODING_FAILED); - break; - case DECODE_UU: - SnortEventqAdd(GID_IMAP, IMAP_UU_DECODING_FAILED); - break; - - default: - break; - } -} - void IMAP_SearchInit(void) { const IMAPToken* tmp; @@ -238,13 +212,6 @@ void IMAP_SearchFree(void) delete imap_resp_search_mpse; } -/* -* Reset IMAP session state -* -* @param none -* -* @return none -*/ static void IMAP_ResetState(void* ssn) { IMAPData* imap_ssn = get_session_data((Flow*)ssn); @@ -555,7 +522,7 @@ static void IMAP_ProcessServerPacket(Packet* p, IMAPData* imap_ssn) data_end = ptr + len; FilePosition position = file_api->get_file_position(p); - ptr = file_api->process_mime_data(p->flow, ptr, end, &(imap_ssn->mime_ssn), 0, + ptr = imap_ssn->mime_ssn->process_mime_data(p->flow, ptr, end, 0, position); if ( ptr < data_end) len = len - (data_end - ptr); @@ -774,6 +741,37 @@ static void snort_imap(IMAP_PROTO_CONF* config, Packet* p) } } +void ImapMime::decode_alert(void* ds) +{ + Email_DecodeState* decode_state = (Email_DecodeState*)ds; + switch ( decode_state->decode_type ) + { + case DECODE_B64: + SnortEventqAdd(GID_IMAP, IMAP_B64_DECODING_FAILED); + break; + case DECODE_QP: + SnortEventqAdd(GID_IMAP, IMAP_QP_DECODING_FAILED); + break; + case DECODE_UU: + SnortEventqAdd(GID_IMAP, IMAP_UU_DECODING_FAILED); + break; + + default: + break; + } +} + +void ImapMime::reset_state(void* ssn) +{ + IMAP_ResetState(ssn); +} + + +bool ImapMime::is_end_of_data(void* session) +{ + return imap_is_data_end(session); +} + //------------------------------------------------------------------------- // class stuff //------------------------------------------------------------------------- diff --git a/src/service_inspectors/imap/imap.h b/src/service_inspectors/imap/imap.h index b07291cf9..9fa5f1190 100644 --- a/src/service_inspectors/imap/imap.h +++ b/src/service_inspectors/imap/imap.h @@ -146,6 +146,15 @@ struct IMAPSearchInfo int length; }; +class ImapMime : public MimeSession +{ + using MimeSession::MimeSession; +private: + void decode_alert(void* decode_state) override; + void reset_state(void* ssn) override; + bool is_end_of_data(void* ssn) override; +}; + struct IMAPData { int state; @@ -153,7 +162,7 @@ struct IMAPData int session_flags; uint32_t body_len; uint32_t body_read; - MimeSession mime_ssn; + ImapMime* mime_ssn; }; class ImapFlowData : public FlowData diff --git a/src/service_inspectors/nhttp_inspect/nhttp_flow_data.cc b/src/service_inspectors/nhttp_inspect/nhttp_flow_data.cc index 198831bb2..bc7183c96 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_flow_data.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_flow_data.cc @@ -55,7 +55,7 @@ NHttpFlowData::~NHttpFlowData() if (mime_state != nullptr) { - free_mime_session(mime_state); + delete(mime_state); } delete_pipeline(); @@ -79,7 +79,7 @@ void NHttpFlowData::half_reset(SourceId source_id) method_id = METH__NOTPRESENT; if (mime_state != nullptr) { - free_mime_session(mime_state); + delete(mime_state); mime_state = nullptr; } } diff --git a/src/service_inspectors/nhttp_inspect/nhttp_msg_body.cc b/src/service_inspectors/nhttp_inspect/nhttp_msg_body.cc index 2eae4015d..db826c992 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_msg_body.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_msg_body.cc @@ -110,15 +110,15 @@ void NHttpMsgBody::do_file_processing() session_data->file_depth_remaining[source_id] = 0; } } - else + else if (session_data->mime_state != nullptr) { - file_api->process_mime_data(flow, data.start, data.start + fp_length, - session_data->mime_state, true, file_position); + session_data->mime_state->process_mime_data(flow, data.start, data.start + fp_length, + true, file_position); session_data->file_depth_remaining[source_id] -= fp_length; if (session_data->file_depth_remaining[source_id] == 0) { - free_mime_session(session_data->mime_state); + delete(session_data->mime_state); session_data->mime_state = nullptr; } } diff --git a/src/service_inspectors/nhttp_inspect/nhttp_msg_chunk.cc b/src/service_inspectors/nhttp_inspect/nhttp_msg_chunk.cc index 83b65e8d4..a93c48541 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_msg_chunk.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_msg_chunk.cc @@ -57,7 +57,7 @@ void NHttpMsgChunk::update_flow() if ((source_id == SRC_CLIENT) && (session_data->mime_state != nullptr)) { - free_mime_session(session_data->mime_state); + delete(session_data->mime_state); session_data->mime_state = nullptr; } } diff --git a/src/service_inspectors/nhttp_inspect/nhttp_msg_header.cc b/src/service_inspectors/nhttp_inspect/nhttp_msg_header.cc index efe27f6b1..a6e983b90 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_msg_header.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_msg_header.cc @@ -106,13 +106,7 @@ void NHttpMsgHeader::update_flow() session_data->file_depth_remaining[source_id] = file_api->get_max_file_depth(); if (source_id == SRC_CLIENT) { - // FIXIT-L Cannot use new because file_api insists on freeing the mime_state using - // free(). - session_data->mime_state = (MimeSession*) new_calloc(1, sizeof(MimeSession)); - session_data->mime_state->log_config = &mime_conf; - session_data->mime_state->decode_conf = &decode_conf; - file_api->set_log_buffers(&session_data->mime_state->log_state, - session_data->mime_state->log_config); + session_data->mime_state = new MimeSession(&decode_conf, &mime_conf); } } session_data->infractions[source_id].reset(); diff --git a/src/service_inspectors/nhttp_inspect/nhttp_stream_splitter.cc b/src/service_inspectors/nhttp_inspect/nhttp_stream_splitter.cc index 1af30bcf4..b4b7ff76f 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_stream_splitter.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_stream_splitter.cc @@ -467,11 +467,11 @@ bool NHttpStreamSplitter::finish(Flow* flow) { file_api->file_process(flow, nullptr, 0, SNORT_FILE_END, false, false); } - else + else if (session_data->mime_state != nullptr) { - file_api->process_mime_data(flow, nullptr, 0, session_data->mime_state, true, + session_data->mime_state->process_mime_data(flow, nullptr, 0, true, SNORT_FILE_END); - free_mime_session(session_data->mime_state); + delete(session_data->mime_state); session_data->mime_state = nullptr; } return false; diff --git a/src/service_inspectors/pop/pop.cc b/src/service_inspectors/pop/pop.cc index 8603779a4..a6eb212cf 100644 --- a/src/service_inspectors/pop/pop.cc +++ b/src/service_inspectors/pop/pop.cc @@ -85,15 +85,15 @@ THREAD_LOCAL POPSearchInfo pop_search_info; static void snort_pop(POP_PROTO_CONF* GlobalConf, Packet* p); static void POP_ResetState(void*); -void POP_DecodeAlert(void* ds); - -MimeMethods pop_mime_methods = { NULL, NULL, POP_DecodeAlert, POP_ResetState, pop_is_data_end }; PopFlowData::PopFlowData() : FlowData(flow_id) { memset(&session, 0, sizeof(session)); } PopFlowData::~PopFlowData() -{ free_mime_session(session.mime_ssn); } +{ + if (session.mime_ssn) + delete(session.mime_ssn); +} unsigned PopFlowData::flow_id = 0; static POPData* get_session_data(Flow* flow) @@ -112,14 +112,9 @@ POPData* SetNewPOPData(POP_PROTO_CONF* config, Packet* p) p->flow->set_application_data(fd); pop_ssn = &fd->session; - pop_ssn->mime_ssn.log_config = &(config->log_config); - pop_ssn->mime_ssn.decode_conf = &(config->decode_conf); - pop_ssn->mime_ssn.methods = &(pop_mime_methods); - pop_ssn->mime_ssn.config = config; - if (file_api->set_log_buffers(&(pop_ssn->mime_ssn.log_state), &(config->log_config)) < 0) - { - return NULL; - } + pop_ssn->mime_ssn = new PopMime( &(config->decode_conf), &(config->log_config)); + //pop_ssn->mime_ssn.methods = &(pop_mime_methods); + //pop_ssn->mime_ssn.config = config; if (p->packet_flags & SSNFLAG_MIDSTREAM) { @@ -131,26 +126,6 @@ POPData* SetNewPOPData(POP_PROTO_CONF* config, Packet* p) return pop_ssn; } -void POP_DecodeAlert(void* ds) -{ - Email_DecodeState* decode_state = (Email_DecodeState*)ds; - switch ( decode_state->decode_type ) - { - case DECODE_B64: - SnortEventqAdd(GID_POP, POP_B64_DECODING_FAILED); - break; - case DECODE_QP: - SnortEventqAdd(GID_POP, POP_QP_DECODING_FAILED); - break; - case DECODE_UU: - SnortEventqAdd(GID_POP, POP_UU_DECODING_FAILED); - break; - - default: - break; - } -} - void POP_SearchInit(void) { const POPToken* tmp; @@ -190,13 +165,6 @@ void POP_SearchFree(void) delete pop_resp_search_mpse; } -/* -* Reset POP session state -* -* @param none -* -* @return none -*/ static void POP_ResetState(void* ssn) { POPData* pop_ssn = get_session_data((Flow*)ssn); @@ -521,8 +489,7 @@ static void POP_ProcessServerPacket(Packet* p, POPData* pop_ssn) DEBUG_WRAP(DebugMessage(DEBUG_POP, "DATA STATE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); ); //ptr = POP_HandleData(p, ptr, end); FilePosition position = file_api->get_file_position(p); - ptr = file_api->process_mime_data(p->flow, ptr, end, &(pop_ssn->mime_ssn), 0, - position); + ptr = pop_ssn->mime_ssn->process_mime_data(p->flow, ptr, end, 0, position); continue; } POP_GetEOL(ptr, end, &eol, &eolm); @@ -708,6 +675,37 @@ static void snort_pop(POP_PROTO_CONF* config, Packet* p) } } +void PopMime::decode_alert(void* ds) +{ + Email_DecodeState* decode_state = (Email_DecodeState*)ds; + switch ( decode_state->decode_type ) + { + case DECODE_B64: + SnortEventqAdd(GID_POP, POP_B64_DECODING_FAILED); + break; + case DECODE_QP: + SnortEventqAdd(GID_POP, POP_QP_DECODING_FAILED); + break; + case DECODE_UU: + SnortEventqAdd(GID_POP, POP_UU_DECODING_FAILED); + break; + + default: + break; + } +} + +void PopMime::reset_state(void* ssn) +{ + POP_ResetState(ssn); +} + + +bool PopMime::is_end_of_data(void* session) +{ + return pop_is_data_end(session); +} + //------------------------------------------------------------------------- // class stuff //------------------------------------------------------------------------- diff --git a/src/service_inspectors/pop/pop.h b/src/service_inspectors/pop/pop.h index a0b244d1c..40100c78f 100644 --- a/src/service_inspectors/pop/pop.h +++ b/src/service_inspectors/pop/pop.h @@ -101,13 +101,22 @@ struct POPSearchInfo int length; }; +class PopMime : public MimeSession +{ + using MimeSession::MimeSession; +private: + void decode_alert(void* decode_state) override; + void reset_state(void* ssn) override; + bool is_end_of_data(void* ssn) override; +}; + struct POPData { int state; int prev_response; int state_flags; int session_flags; - MimeSession mime_ssn; + PopMime* mime_ssn; }; class PopFlowData : public FlowData diff --git a/src/service_inspectors/smtp/smtp.cc b/src/service_inspectors/smtp/smtp.cc index 1b79fe5e2..d9d318165 100644 --- a/src/service_inspectors/smtp/smtp.cc +++ b/src/service_inspectors/smtp/smtp.cc @@ -165,18 +165,14 @@ static void snort_smtp(SMTP_PROTO_CONF* GlobalConf, Packet* p); static void SMTP_ResetState(void*); void SMTP_DecodeAlert(void* ds); -static int SMTP_HandleHeaderLine(void* conf, const uint8_t* ptr, const uint8_t* eol, - int max_header_len, void* ssn); -static int SMTP_NormalizeData(void* conf, const uint8_t* ptr, const uint8_t* data_end); - -MimeMethods smtp_mime_methods = { SMTP_HandleHeaderLine, SMTP_NormalizeData, SMTP_DecodeAlert, - SMTP_ResetState, smtp_is_data_end }; - SmtpFlowData::SmtpFlowData() : FlowData(flow_id) { memset(&session, 0, sizeof(session)); } SmtpFlowData::~SmtpFlowData() -{ free_mime_session(session.mime_ssn); } +{ + if (session.mime_ssn) + delete(session.mime_ssn); +} unsigned SmtpFlowData::flow_id = 0; static SMTPData* get_session_data(Flow* flow) @@ -195,14 +191,9 @@ SMTPData* SetNewSMTPData(SMTP_PROTO_CONF* config, Packet* p) p->flow->set_application_data(fd); smtp_ssn = &fd->session; - smtp_ssn->mime_ssn.log_config = &(config->log_config); - smtp_ssn->mime_ssn.decode_conf = &(config->decode_conf); - smtp_ssn->mime_ssn.methods = &(smtp_mime_methods); - smtp_ssn->mime_ssn.config = config; - if (file_api->set_log_buffers(&(smtp_ssn->mime_ssn.log_state), &(config->log_config)) < 0) - { - return NULL; - } + smtp_ssn->mime_ssn = new SmtpMime(&(config->decode_conf), &(config->log_config)); + //smtp_ssn->mime_ssn.methods = &(smtp_mime_methods); + //smtp_ssn->mime_ssn.config = config; if(stream.is_midstream(p->flow)) { @@ -214,26 +205,6 @@ SMTPData* SetNewSMTPData(SMTP_PROTO_CONF* config, Packet* p) return smtp_ssn; } -void SMTP_DecodeAlert(void* ds) -{ - Email_DecodeState* decode_state = (Email_DecodeState*)ds; - switch ( decode_state->decode_type ) - { - case DECODE_B64: - SnortEventqAdd(GID_SMTP, SMTP_B64_DECODING_FAILED); - break; - case DECODE_QP: - SnortEventqAdd(GID_SMTP, SMTP_QP_DECODING_FAILED); - break; - case DECODE_UU: - SnortEventqAdd(GID_SMTP, SMTP_UU_DECODING_FAILED); - break; - - default: - break; - } -} - static void SMTP_InitCmds(SMTP_PROTO_CONF* config) { if (config == NULL) @@ -581,13 +552,6 @@ void SMTP_PrintConfig(SMTP_PROTO_CONF *config) } } -/* - * * Reset SMTP session state - * * - * * @param none - * * - * * @return none - * */ static void SMTP_ResetState(void* ssn) { SMTPData* smtp_ssn = get_session_data((Flow*)ssn); @@ -835,7 +799,7 @@ static const uint8_t* SMTP_HandleCommand(SMTP_PROTO_CONF* config, Packet* p, SMT smtp_ssn->session_flags &= ~SMTP_FLAG_CHECK_SSL; smtp_ssn->state = STATE_DATA; - smtp_ssn->mime_ssn.data_state = STATE_DATA_UNKNOWN; + smtp_ssn->mime_ssn->set_data_state(STATE_DATA_UNKNOWN); return ptr; } @@ -895,8 +859,8 @@ static const uint8_t* SMTP_HandleCommand(SMTP_PROTO_CONF* config, Packet* p, SMT smtp_ssn->state_flags |= SMTP_FLAG_GOT_MAIL_CMD; if ( config->log_config.log_mailfrom ) { - if (!SMTP_CopyEmailID(ptr, eolm - ptr, CMD_MAIL, smtp_ssn->mime_ssn.log_state)) - smtp_ssn->mime_ssn.log_flags |= MIME_FLAG_MAIL_FROM_PRESENT; + if (!SMTP_CopyEmailID(ptr, eolm - ptr, CMD_MAIL, smtp_ssn->mime_ssn->get_log_state())) + smtp_ssn->mime_ssn->log_flags |= MIME_FLAG_MAIL_FROM_PRESENT; } break; @@ -910,8 +874,8 @@ static const uint8_t* SMTP_HandleCommand(SMTP_PROTO_CONF* config, Packet* p, SMT if ( config->log_config.log_rcptto) { - if (!SMTP_CopyEmailID(ptr, eolm - ptr, CMD_RCPT, smtp_ssn->mime_ssn.log_state)) - smtp_ssn->mime_ssn.log_flags |= MIME_FLAG_RCPT_TO_PRESENT; + if (!SMTP_CopyEmailID(ptr, eolm - ptr, CMD_RCPT, smtp_ssn->mime_ssn->get_log_state())) + smtp_ssn->mime_ssn->log_flags |= MIME_FLAG_RCPT_TO_PRESENT; } break; @@ -1084,76 +1048,6 @@ static const uint8_t* SMTP_HandleCommand(SMTP_PROTO_CONF* config, Packet* p, SMT return eol; } -static int SMTP_NormalizeData(void* conf, const uint8_t* ptr, const uint8_t* data_end) -{ - SMTP_PROTO_CONF* config = (SMTP_PROTO_CONF*)conf; - - /* if we're ignoring data and not already normalizing, copy everything - * up to here into alt buffer so detection engine doesn't have - * to look at the data; otherwise, if we're normalizing and not - * ignoring data, copy all of the data into the alt buffer */ - /*if (config->decode_conf.ignore_data && !smtp_normalizing) - { - return SMTP_CopyToAltBuffer(p->data, ptr - p->data); - } - else */ - if (!config->decode_conf.is_ignore_data() && smtp_normalizing) - { - return SMTP_CopyToAltBuffer(ptr, data_end - ptr); - } - - return 0; -} - -static int SMTP_HandleHeaderLine(void* conf, const uint8_t* ptr, const uint8_t* eol, - int max_header_len, void* ssn) -{ - int ret; - int header_line_len; - SMTP_PROTO_CONF* config = (SMTP_PROTO_CONF*)conf; - MimeSession* mime_ssn = (MimeSession*)ssn; - /* get length of header line */ - header_line_len = eol - ptr; - - if (max_header_len) - SnortEventqAdd(GID_SMTP, SMTP_HEADER_NAME_OVERFLOW); - - if ((config->max_header_line_len != 0) && - (header_line_len > config->max_header_line_len)) - { - if (mime_ssn->data_state != STATE_DATA_UNKNOWN) - { - SnortEventqAdd(GID_SMTP, SMTP_DATA_HDR_OVERFLOW); - } - else - { - /* assume we guessed wrong and are in the body */ - return 1; - } - } - - /* XXX Does VRT want data headers normalized? - * currently the code does not normalize headers */ - if (smtp_normalizing) - { - ret = SMTP_CopyToAltBuffer(ptr, eol - ptr); - if (ret == -1) - return (-1); - } - - if (config->log_config.log_email_hdrs) - { - if (mime_ssn->data_state == STATE_DATA_HEADER) - { - ret = SMTP_CopyEmailHdrs(ptr, eol - ptr, mime_ssn->log_state); - if (ret == 0) - mime_ssn->log_flags |= MIME_FLAG_EMAIL_HDRS_PRESENT; - } - } - - return 0; -} - /* * Process client packet * @@ -1185,8 +1079,7 @@ static void SMTP_ProcessClientPacket(SMTP_PROTO_CONF* config, Packet* p, SMTPDat case STATE_BDATA: DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "DATA STATE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); ); position = file_api->get_file_position(p); - ptr = file_api->process_mime_data(p->flow, ptr, end, &(smtp_ssn->mime_ssn), 1, - position); + ptr = smtp_ssn->mime_ssn->process_mime_data(p->flow, ptr, end, 1, position); //ptr = SMTP_HandleData(p, ptr, end, &(smtp_ssn->mime_ssn)); break; case STATE_XEXCH50: @@ -1488,7 +1381,7 @@ static void snort_smtp(SMTP_PROTO_CONF* config, Packet* p) } } - SMTP_LogFuncs(config, p, &(smtp_ssn->mime_ssn)); + SMTP_LogFuncs(config, p, smtp_ssn->mime_ssn); } /* Callback to return the MIME attachment filenames accumulated */ @@ -1499,8 +1392,8 @@ int SMTP_GetFilename(Flow* flow, uint8_t** buf, uint32_t* len, uint32_t* type) if (ssn == NULL) return 0; - *buf = ssn->mime_ssn.log_state->file_log.filenames; - *len = ssn->mime_ssn.log_state->file_log.file_logged; + *buf = ssn->mime_ssn->get_log_state()->get_file_log_state()->filenames; + *len = ssn->mime_ssn->get_log_state()->get_file_log_state()->file_logged; *type = EVENT_INFO_SMTP_FILENAME; return 1; } @@ -1513,8 +1406,8 @@ int SMTP_GetMailFrom(Flow* flow, uint8_t** buf, uint32_t* len, uint32_t* type) if (ssn == NULL) return 0; - *buf = ssn->mime_ssn.log_state->senders; - *len = ssn->mime_ssn.log_state->snds_logged; + *buf = ssn->mime_ssn->get_log_state()->senders; + *len = ssn->mime_ssn->get_log_state()->snds_logged; *type = EVENT_INFO_SMTP_MAILFROM; return 1; } @@ -1527,8 +1420,8 @@ int SMTP_GetRcptTo(Flow* flow, uint8_t** buf, uint32_t* len, uint32_t* type) if (ssn == NULL) return 0; - *buf = ssn->mime_ssn.log_state->recipients; - *len = ssn->mime_ssn.log_state->rcpts_logged; + *buf = ssn->mime_ssn->get_log_state()->recipients; + *len = ssn->mime_ssn->get_log_state()->rcpts_logged; *type = EVENT_INFO_SMTP_RCPTTO; return 1; } @@ -1541,8 +1434,8 @@ int SMTP_GetEmailHdrs(Flow* flow, uint8_t** buf, uint32_t* len, uint32_t* type) if (ssn == NULL) return 0; - *buf = ssn->mime_ssn.log_state->emailHdrs; - *len = ssn->mime_ssn.log_state->hdrs_logged; + *buf = ssn->mime_ssn->get_log_state()->emailHdrs; + *len = ssn->mime_ssn->get_log_state()->hdrs_logged; *type = EVENT_INFO_SMTP_EMAIL_HDRS; return 1; } @@ -1555,6 +1448,107 @@ static void SMTP_RegXtraDataFuncs(SMTP_PROTO_CONF* config) config->xtra_ehdrs_id = stream.reg_xtra_data_cb(SMTP_GetEmailHdrs); } +int SmtpMime::handle_header_line(void* conf, const uint8_t* ptr, const uint8_t* eol, + int max_header_len) +{ + int ret; + int header_line_len; + SMTP_PROTO_CONF* config = (SMTP_PROTO_CONF*)conf; + MimeSession* mime_ssn = (MimeSession*)this; + /* get length of header line */ + header_line_len = eol - ptr; + + if (max_header_len) + SnortEventqAdd(GID_SMTP, SMTP_HEADER_NAME_OVERFLOW); + + if ((config->max_header_line_len != 0) && + (header_line_len > config->max_header_line_len)) + { + if (mime_ssn->get_data_state() != STATE_DATA_UNKNOWN) + { + SnortEventqAdd(GID_SMTP, SMTP_DATA_HDR_OVERFLOW); + } + else + { + /* assume we guessed wrong and are in the body */ + return 1; + } + } + + /* XXX Does VRT want data headers normalized? + * currently the code does not normalize headers */ + if (smtp_normalizing) + { + ret = SMTP_CopyToAltBuffer(ptr, eol - ptr); + if (ret == -1) + return (-1); + } + + if (config->log_config.log_email_hdrs) + { + if (mime_ssn->get_data_state() == STATE_DATA_HEADER) + { + ret = SMTP_CopyEmailHdrs(ptr, eol - ptr, mime_ssn->get_log_state()); + if (ret == 0) + mime_ssn->log_flags |= MIME_FLAG_EMAIL_HDRS_PRESENT; + } + } + + return 0; +} + +int SmtpMime::normalize_data(void* conf, const uint8_t* ptr, const uint8_t* data_end) +{ + SMTP_PROTO_CONF* config = (SMTP_PROTO_CONF*)conf; + + /* if we're ignoring data and not already normalizing, copy everything + * up to here into alt buffer so detection engine doesn't have + * to look at the data; otherwise, if we're normalizing and not + * ignoring data, copy all of the data into the alt buffer */ + /*if (config->decode_conf.ignore_data && !smtp_normalizing) + { + return SMTP_CopyToAltBuffer(p->data, ptr - p->data); + } + else */ + if (!config->decode_conf.is_ignore_data() && smtp_normalizing) + { + return SMTP_CopyToAltBuffer(ptr, data_end - ptr); + } + + return 0; +} + +void SmtpMime::decode_alert(void* ds) +{ + Email_DecodeState* decode_state = (Email_DecodeState*)ds; + switch ( decode_state->decode_type ) + { + case DECODE_B64: + SnortEventqAdd(GID_SMTP, SMTP_B64_DECODING_FAILED); + break; + case DECODE_QP: + SnortEventqAdd(GID_SMTP, SMTP_QP_DECODING_FAILED); + break; + case DECODE_UU: + SnortEventqAdd(GID_SMTP, SMTP_UU_DECODING_FAILED); + break; + + default: + break; + } +} + +void SmtpMime::reset_state(void* ssn) +{ + SMTP_ResetState(ssn); +} + + +bool SmtpMime::is_end_of_data(void* session) +{ + return smtp_is_data_end(session); +} + //------------------------------------------------------------------------- // class stuff //------------------------------------------------------------------------- diff --git a/src/service_inspectors/smtp/smtp.h b/src/service_inspectors/smtp/smtp.h index be3440932..d559a54c1 100644 --- a/src/service_inspectors/smtp/smtp.h +++ b/src/service_inspectors/smtp/smtp.h @@ -141,13 +141,25 @@ struct SMTPAuthName char name[MAX_AUTH_NAME_LEN]; }; +class SmtpMime : public MimeSession +{ + using MimeSession::MimeSession; +private: + int handle_header_line(void* conf, const uint8_t* ptr, const uint8_t* eol, + int max_header_len) override; + int normalize_data(void* conf, const uint8_t* ptr, const uint8_t* data_end) override; + void decode_alert(void* decode_state) override; + void reset_state(void* ssn) override; + bool is_end_of_data(void* ssn) override; +}; + struct SMTPData { int state; int state_flags; int session_flags; uint32_t dat_chunk; - MimeSession mime_ssn; + SmtpMime* mime_ssn; SMTPAuthName* auth_name; };