}
}
+const FileLogState* MailLogState::get_file_log_state()
+{
+ return &log_state;
+}
+
MailLogState::MailLogState(MailLogConfig* conf)
{
if (conf && (conf->log_email_hdrs || conf->log_filename
/* 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;
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;
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
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)
{
{
if (EmailDecode(attach_start, attach_end, decode_state) < DECODE_SUCCESS )
{
- if (methods && methods->decode_alert)
- methods->decode_alert(decode_state);
+ decode_alert(decode_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 */
{
/* 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();
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 */
if (done_data)
{
reset_mime_state();
- if (methods && methods->reset_state)
- methods->reset_state(flow);
+ reset_state(flow);
}
return end;
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
/* 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);
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)
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
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)
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 )
{
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)
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)
{
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;
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);
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);
}
}
+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
//-------------------------------------------------------------------------
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;
int session_flags;
uint32_t body_len;
uint32_t body_read;
- MimeSession mime_ssn;
+ ImapMime* mime_ssn;
};
class ImapFlowData : public FlowData
if (mime_state != nullptr)
{
- free_mime_session(mime_state);
+ delete(mime_state);
}
delete_pipeline();
method_id = METH__NOTPRESENT;
if (mime_state != nullptr)
{
- free_mime_session(mime_state);
+ delete(mime_state);
mime_state = nullptr;
}
}
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;
}
}
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;
}
}
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();
{
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;
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)
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)
{
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;
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);
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);
}
}
+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
//-------------------------------------------------------------------------
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
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)
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))
{
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)
}
}
-/*
- * * Reset SMTP session state
- * *
- * * @param none
- * *
- * * @return none
- * */
static void SMTP_ResetState(void* ssn)
{
SMTPData* smtp_ssn = get_session_data((Flow*)ssn);
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;
}
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;
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;
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
*
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:
}
}
- SMTP_LogFuncs(config, p, &(smtp_ssn->mime_ssn));
+ SMTP_LogFuncs(config, p, smtp_ssn->mime_ssn);
}
/* Callback to return the MIME attachment filenames accumulated */
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;
}
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;
}
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;
}
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;
}
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
//-------------------------------------------------------------------------
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;
};