SMTPConfig smtp_config = { 0, { 0, 0, 0, 0, 0 }, 0, 0, 0, 0, STREAMING_BUFFER_CONFIG_INITIALIZER};
static SMTPString *SMTPStringAlloc(void);
-
+static int SMTPPreProcessCommands(SMTPState *state, Flow *f, AppLayerParserState *pstate);
/**
* \brief Configure SMTP Mime Decoder by parsing out mime section of YAML
* config file
}
}
+static int SMTPPreProcessCommands(SMTPState *state, Flow *f, AppLayerParserState *pstate)
+{
+ // By this time we should have had the command line parsed
+ uint8_t *lf_idx = memchr(state->input + state->consumed, 0x0a, state->input_len);
+ const uint32_t orig_input_len = state->input_len;
+ // Both DATA and BDAT set SMTP_PARSER_STATE_COMMAND_DATA_MODE, so this while
+ // loop should be valid for both
+ while (state->input_len > 0 && (state->parser_state & SMTP_PARSER_STATE_COMMAND_DATA_MODE)) {
+ uint8_t delim_len = 0;
+ uint32_t consumed_line = 0;
+ state->current_line = state->input + state->consumed;
+ if (lf_idx == NULL) {
+ state->consumed = state->input_len;
+ consumed_line = state->input_len;
+ } else {
+ ptrdiff_t idx = lf_idx - state->input;
+ state->consumed = idx + 1;
+ consumed_line = lf_idx - state->current_line + 1;
+ if (orig_input_len >= idx && idx > 0 && state->input[idx - 1] == 0x0d) {
+ delim_len = 2;
+ } else if (orig_input_len == 1 ||
+ (orig_input_len >= idx + 1 && idx > 0 && state->input[idx - 1] != 0x0d)) {
+ delim_len = 1;
+ }
+ }
+ state->current_line_delimiter_len = delim_len;
+ state->current_line_len = consumed_line - delim_len;
+ state->input_len -= (state->current_line_len + delim_len);
+ if (SMTPProcessRequest(state, f, pstate) == -1) {
+ return -1;
+ }
+ lf_idx = memchr(state->input + state->consumed, 0x0a, state->input_len);
+ }
+ return 0;
+}
+
static int SMTPParse(int direction, Flow *f, SMTPState *state,
AppLayerParserState *pstate, const uint8_t *input,
uint32_t input_len,
state->input = input;
state->input_len = input_len;
+ state->consumed = 0;
state->direction = direction;
+ if (direction == 0) {
+ if (((state->current_command == SMTP_COMMAND_DATA) ||
+ (state->current_command == SMTP_COMMAND_BDAT)) &&
+ (state->parser_state & SMTP_PARSER_STATE_COMMAND_DATA_MODE)) {
+ int ret = SMTPPreProcessCommands(state, f, pstate);
+ if (ret == 0 && state->consumed == state->input_len) {
+ return 0;
+ }
+ }
+ }
int res = SMTPGetLine(state);
/* toserver */
if (direction == 0) {
while (res == 0) {
+ BUG_ON(state->discard_till_lf);
if (!state->discard_till_lf) {
if ((state->current_line_len > 0) && (SMTPProcessRequest(state, f, pstate) == -1))
SCReturnInt(-1);
/* toclient */
} else {
while (res == 0) {
+ BUG_ON(state->discard_till_lf);
if (!state->discard_till_lf) {
if ((state->current_line_len > 0) && (SMTPProcessReply(state, f, pstate, thread_data) == -1))
SCReturnInt(-1);