* \retval -1 Either when we don't have any new lines to supply anymore or
* on failure.
*/
-static int SMTPGetLine(SMTPState *state)
+static AppLayerResult SMTPGetLine(SMTPState *state)
{
SCEnter();
- void *ptmp;
/* we have run out of input */
if (state->input_len <= 0)
- return -1;
-
- /* toserver */
- if (state->direction == 0) {
- if (state->ts_current_line_lf_seen == 1) {
- /* we have seen the lf for the previous line. Clear the parser
- * details to parse new line */
- state->ts_current_line_lf_seen = 0;
- if (state->ts_current_line_db == 1) {
- state->ts_current_line_db = 0;
- SCFree(state->ts_db);
- state->ts_db = NULL;
- state->ts_db_len = 0;
- state->current_line = NULL;
- state->current_line_len = 0;
- }
- }
-
- uint8_t *lf_idx = memchr(state->input, 0x0a, state->input_len);
-
- if (lf_idx == NULL) {
- /* fragmented lines. Decoder event for special cases. Not all
- * fragmented lines should be treated as a possible evasion
- * attempt. With multi payload smtp chunks we can have valid
- * cases of fragmentation. But within the same segment chunk
- * if we see fragmentation then it's definitely something you
- * should alert about */
- if (state->ts_current_line_db == 0) {
- state->ts_db = SCMalloc(state->input_len);
- if (state->ts_db == NULL) {
- return -1;
- }
- state->ts_current_line_db = 1;
- memcpy(state->ts_db, state->input, state->input_len);
- state->ts_db_len = state->input_len;
- } else {
- ptmp = SCRealloc(state->ts_db,
- (state->ts_db_len + state->input_len));
- if (ptmp == NULL) {
- SCFree(state->ts_db);
- state->ts_db = NULL;
- state->ts_db_len = 0;
- return -1;
- }
- state->ts_db = ptmp;
-
- memcpy(state->ts_db + state->ts_db_len,
- state->input, state->input_len);
- state->ts_db_len += state->input_len;
- } /* else */
- state->input += state->input_len;
- state->input_len = 0;
-
- return -1;
-
- } else {
- state->ts_current_line_lf_seen = 1;
-
- if (state->ts_current_line_db == 1) {
- ptmp = SCRealloc(state->ts_db,
- (state->ts_db_len + (lf_idx + 1 - state->input)));
- if (ptmp == NULL) {
- SCFree(state->ts_db);
- state->ts_db = NULL;
- state->ts_db_len = 0;
- return -1;
- }
- state->ts_db = ptmp;
-
- memcpy(state->ts_db + state->ts_db_len,
- state->input, (lf_idx + 1 - state->input));
- state->ts_db_len += (lf_idx + 1 - state->input);
-
- if (state->ts_db_len > 1 &&
- state->ts_db[state->ts_db_len - 2] == 0x0D) {
- state->ts_db_len -= 2;
- state->current_line_delimiter_len = 2;
- } else {
- state->ts_db_len -= 1;
- state->current_line_delimiter_len = 1;
- }
-
- state->current_line = state->ts_db;
- state->current_line_len = state->ts_db_len;
+ return APP_LAYER_ERROR;
- } else {
- state->current_line = state->input;
- state->current_line_len = lf_idx - state->input;
-
- if (state->input != lf_idx &&
- *(lf_idx - 1) == 0x0D) {
- state->current_line_len--;
- state->current_line_delimiter_len = 2;
- } else {
- state->current_line_delimiter_len = 1;
- }
- }
-
- state->input_len -= (lf_idx - state->input) + 1;
- state->input = (lf_idx + 1);
-
- return 0;
- }
+ uint8_t *lf_idx = memchr(state->input + state->consumed, 0x0a, state->input_len);
- /* toclient */
+ if (lf_idx == NULL) {
+ SCReturnStruct(APP_LAYER_INCOMPLETE(state->consumed, state->input_len + 1));
} else {
- if (state->tc_current_line_lf_seen == 1) {
- /* we have seen the lf for the previous line. Clear the parser
- * details to parse new line */
- state->tc_current_line_lf_seen = 0;
- if (state->tc_current_line_db == 1) {
- state->tc_current_line_db = 0;
- SCFree(state->tc_db);
- state->tc_db = NULL;
- state->tc_db_len = 0;
- state->current_line = NULL;
- state->current_line_len = 0;
- }
- }
-
- uint8_t *lf_idx = memchr(state->input, 0x0a, state->input_len);
-
- if (lf_idx == NULL) {
- /* fragmented lines. Decoder event for special cases. Not all
- * fragmented lines should be treated as a possible evasion
- * attempt. With multi payload smtp chunks we can have valid
- * cases of fragmentation. But within the same segment chunk
- * if we see fragmentation then it's definitely something you
- * should alert about */
- if (state->tc_current_line_db == 0) {
- state->tc_db = SCMalloc(state->input_len);
- if (state->tc_db == NULL) {
- return -1;
- }
- state->tc_current_line_db = 1;
- memcpy(state->tc_db, state->input, state->input_len);
- state->tc_db_len = state->input_len;
- } else {
- ptmp = SCRealloc(state->tc_db,
- (state->tc_db_len + state->input_len));
- if (ptmp == NULL) {
- SCFree(state->tc_db);
- state->tc_db = NULL;
- state->tc_db_len = 0;
- return -1;
- }
- state->tc_db = ptmp;
-
- memcpy(state->tc_db + state->tc_db_len,
- state->input, state->input_len);
- state->tc_db_len += state->input_len;
- } /* else */
- state->input += state->input_len;
- state->input_len = 0;
-
- return -1;
-
+ uint32_t o_consumed = state->consumed;
+ state->consumed = lf_idx - state->input + 1;
+ state->current_line_len = state->consumed - o_consumed;
+ state->current_line = state->input + o_consumed;
+ state->input_len -= state->current_line_len;
+ if (state->consumed >= 2 && state->input[state->consumed - 2] == 0x0D) {
+ state->current_line_delimiter_len = 2;
+ state->current_line_len -= 2;
} else {
- state->tc_current_line_lf_seen = 1;
-
- if (state->tc_current_line_db == 1) {
- ptmp = SCRealloc(state->tc_db,
- (state->tc_db_len + (lf_idx + 1 - state->input)));
- if (ptmp == NULL) {
- SCFree(state->tc_db);
- state->tc_db = NULL;
- state->tc_db_len = 0;
- return -1;
- }
- state->tc_db = ptmp;
-
- memcpy(state->tc_db + state->tc_db_len,
- state->input, (lf_idx + 1 - state->input));
- state->tc_db_len += (lf_idx + 1 - state->input);
-
- if (state->tc_db_len > 1 &&
- state->tc_db[state->tc_db_len - 2] == 0x0D) {
- state->tc_db_len -= 2;
- state->current_line_delimiter_len = 2;
- } else {
- state->tc_db_len -= 1;
- state->current_line_delimiter_len = 1;
- }
-
- state->current_line = state->tc_db;
- state->current_line_len = state->tc_db_len;
-
- } else {
- state->current_line = state->input;
- state->current_line_len = lf_idx - state->input;
-
- if (state->input != lf_idx &&
- *(lf_idx - 1) == 0x0D) {
- state->current_line_len--;
- state->current_line_delimiter_len = 2;
- } else {
- state->current_line_delimiter_len = 1;
- }
- }
-
- state->input_len -= (lf_idx - state->input) + 1;
- state->input = (lf_idx + 1);
-
- return 0;
- } /* else - if (lf_idx == NULL) */
+ state->current_line_delimiter_len = 1;
+ state->current_line_len -= 1;
+ }
+ SCReturnStruct(APP_LAYER_OK);
}
-
}
static int SMTPInsertCommandIntoCommandBuffer(uint8_t command, SMTPState *state, Flow *f)
state->input = input;
state->input_len = input_len;
+ state->consumed = 0;
state->direction = direction;
+ AppLayerResult res = SMTPGetLine(state);
/* toserver */
if (direction == 0) {
- while (SMTPGetLine(state) >= 0) {
+ while (res.status == 0) {
if (SMTPProcessRequest(state, f, pstate) == -1)
SCReturnStruct(APP_LAYER_ERROR);
+ res = SMTPGetLine(state);
}
-
+ if (res.status == 1)
+ return res;
/* toclient */
} else {
- while (SMTPGetLine(state) >= 0) {
+ while (res.status == 0) {
if (SMTPProcessReply(state, f, pstate, thread_data) == -1)
SCReturnStruct(APP_LAYER_ERROR);
+ res = SMTPGetLine(state);
}
+ if (res.status == 1)
+ return res;
}
SCReturnStruct(APP_LAYER_OK);
if (smtp_state->cmds != NULL) {
SCFree(smtp_state->cmds);
}
- if (smtp_state->ts_current_line_db) {
- SCFree(smtp_state->ts_db);
- }
- if (smtp_state->tc_current_line_db) {
- SCFree(smtp_state->tc_db);
- }
if (smtp_state->helo) {
SCFree(smtp_state->helo);
printf("no smtp state: ");
goto end;
}
- if (smtp_state->input_len != 0 ||
- smtp_state->cmds_cnt != 0 ||
- smtp_state->cmds_idx != 0 ||
- smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
+ if (smtp_state->cmds_cnt != 0 || smtp_state->cmds_idx != 0 ||
+ smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
goto end;
}
FLOWLOCK_UNLOCK(&f);
- if (smtp_state->input_len != 0 ||
- smtp_state->cmds_cnt != 1 ||
- smtp_state->cmds_idx != 0 ||
- smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD ||
- smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
+ if (smtp_state->cmds_cnt != 1 || smtp_state->cmds_idx != 0 ||
+ smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD ||
+ smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
goto end;
}
FLOWLOCK_UNLOCK(&f);
- if (smtp_state->input_len != 0 ||
- smtp_state->cmds_cnt != 0 ||
- smtp_state->cmds_idx != 0 ||
- smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
+ if (smtp_state->cmds_cnt != 0 || smtp_state->cmds_idx != 0 ||
+ smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
goto end;
}
FLOWLOCK_UNLOCK(&f);
- if (smtp_state->input_len != 0 ||
- smtp_state->cmds_cnt != 1 ||
- smtp_state->cmds_idx != 0 ||
- smtp_state->cmds[0] != SMTP_COMMAND_STARTTLS ||
- smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
+ if (smtp_state->cmds_cnt != 1 || smtp_state->cmds_idx != 0 ||
+ smtp_state->cmds[0] != SMTP_COMMAND_STARTTLS ||
+ smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
goto end;
}
FLOWLOCK_UNLOCK(&f);
- if (smtp_state->input_len != 0 ||
- smtp_state->cmds_cnt != 0 ||
- smtp_state->cmds_idx != 0 ||
- smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN |
- SMTP_PARSER_STATE_COMMAND_DATA_MODE)) {
+ if (smtp_state->cmds_cnt != 0 || smtp_state->cmds_idx != 0 ||
+ smtp_state->parser_state !=
+ (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | SMTP_PARSER_STATE_COMMAND_DATA_MODE)) {
printf("smtp parser in inconsistent state\n");
goto end;
}
return result;
}
-/*
- * \test Test retrieving lines when frag'ed.
- */
-static int SMTPParserTest07(void)
-{
- int result = 0;
- Flow f;
- int r = 0;
-
- const char *request1_str = "EHLO boo.com";
- /* EHLO boo.com<CR> */
- uint8_t request1_1[] = {
- 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f,
- 0x2e, 0x63, 0x6f, 0x6d, 0x0d,
- };
- int32_t request1_1_len = sizeof(request1_1);
-
- /* <LF> */
- uint8_t request1_2[] = {
- 0x0a
- };
- int32_t request1_2_len = sizeof(request1_2);
-
- /* EHLO boo.com<CR><LF> */
- uint8_t request2[] = {
- 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f,
- 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a,
- };
- int32_t request2_len = sizeof(request2);
-
- TcpSession ssn;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&f, 0, sizeof(f));
- memset(&ssn, 0, sizeof(ssn));
-
- FLOW_INITIALIZE(&f);
- f.protoctx = (void *)&ssn;
- f.proto = IPPROTO_TCP;
- f.alproto = ALPROTO_SMTP;
-
- StreamTcpInitConfig(true);
- SMTPTestInitConfig();
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request1_1, request1_1_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- SMTPState *smtp_state = f.alstate;
- if (smtp_state == NULL) {
- printf("no smtp state: ");
- goto end;
- }
- if (smtp_state->current_line != NULL ||
- smtp_state->current_line_len != 0 ||
- smtp_state->ts_current_line_db != 1 ||
- smtp_state->ts_db == NULL ||
- smtp_state->ts_db_len != request1_1_len ||
- memcmp(smtp_state->ts_db, request1_1, request1_1_len) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request1_2, request1_2_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- if (smtp_state->ts_current_line_db != 1 ||
- smtp_state->ts_db == NULL ||
- smtp_state->ts_db_len != (int32_t)strlen(request1_str) ||
- memcmp(smtp_state->ts_db, request1_str, strlen(request1_str)) != 0 ||
- smtp_state->current_line != smtp_state->ts_db ||
- smtp_state->current_line_len != smtp_state->ts_db_len) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request2, request2_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- if (smtp_state->ts_current_line_db != 0 ||
- smtp_state->ts_db != NULL ||
- smtp_state->ts_db_len != 0 ||
- smtp_state->current_line == NULL ||
- smtp_state->current_line_len != (int32_t)strlen(request1_str) ||
- memcmp(smtp_state->current_line, request1_str, strlen(request1_str)) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- result = 1;
-end:
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- StreamTcpFreeConfig(true);
- FLOW_DESTROY(&f);
- return result;
-}
-
-/*
- * \test Test retrieving lines when frag'ed.
- */
-static int SMTPParserTest08(void)
-{
- int result = 0;
- Flow f;
- int r = 0;
-
- const char *request1_str = "EHLO boo.com";
- /* EHLO boo.com */
- uint8_t request1_1[] = {
- 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f,
- 0x2e, 0x63, 0x6f, 0x6d,
- };
- int32_t request1_1_len = sizeof(request1_1);
-
- /* <CR><LF> */
- uint8_t request1_2[] = {
- 0x0d, 0x0a
- };
- int32_t request1_2_len = sizeof(request1_2);
-
- /* EHLO boo.com<CR><LF> */
- uint8_t request2[] = {
- 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f,
- 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a,
- };
- int32_t request2_len = sizeof(request2);
-
- TcpSession ssn;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&f, 0, sizeof(f));
- memset(&ssn, 0, sizeof(ssn));
-
- FLOW_INITIALIZE(&f);
- f.protoctx = (void *)&ssn;
- f.proto = IPPROTO_TCP;
- f.alproto = ALPROTO_SMTP;
-
- StreamTcpInitConfig(true);
- SMTPTestInitConfig();
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request1_1, request1_1_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- SMTPState *smtp_state = f.alstate;
- if (smtp_state == NULL) {
- printf("no smtp state: ");
- goto end;
- }
- if (smtp_state->current_line != NULL ||
- smtp_state->current_line_len != 0 ||
- smtp_state->ts_current_line_db != 1 ||
- smtp_state->ts_db == NULL ||
- smtp_state->ts_db_len != request1_1_len ||
- memcmp(smtp_state->ts_db, request1_1, request1_1_len) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request1_2, request1_2_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- if (smtp_state->ts_current_line_db != 1 ||
- smtp_state->ts_db == NULL ||
- smtp_state->ts_db_len != (int32_t)strlen(request1_str) ||
- memcmp(smtp_state->ts_db, request1_str, strlen(request1_str)) != 0 ||
- smtp_state->current_line != smtp_state->ts_db ||
- smtp_state->current_line_len != smtp_state->ts_db_len) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request2, request2_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- if (smtp_state->ts_current_line_db != 0 ||
- smtp_state->ts_db != NULL ||
- smtp_state->ts_db_len != 0 ||
- smtp_state->current_line == NULL ||
- smtp_state->current_line_len != (int32_t)strlen(request1_str) ||
- memcmp(smtp_state->current_line, request1_str, strlen(request1_str)) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- result = 1;
-end:
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- StreamTcpFreeConfig(true);
- FLOW_DESTROY(&f);
- return result;
-}
-
-/*
- * \test Test retrieving lines when frag'ed.
- */
-static int SMTPParserTest09(void)
-{
- int result = 0;
- Flow f;
- int r = 0;
-
- const char *request1_str = "EHLO boo.com";
- /* EHLO boo. */
- uint8_t request1_1[] = {
- 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f,
- 0x2e,
- };
- int32_t request1_1_len = sizeof(request1_1);
-
- /* com<CR><LF> */
- uint8_t request1_2[] = {
- 0x63, 0x6f, 0x6d, 0x0d, 0x0a
- };
- int32_t request1_2_len = sizeof(request1_2);
-
- /* EHLO boo.com<CR><LF> */
- uint8_t request2[] = {
- 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f,
- 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a,
- };
- int32_t request2_len = sizeof(request2);
-
- TcpSession ssn;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&f, 0, sizeof(f));
- memset(&ssn, 0, sizeof(ssn));
-
- FLOW_INITIALIZE(&f);
- f.protoctx = (void *)&ssn;
- f.proto = IPPROTO_TCP;
- f.alproto = ALPROTO_SMTP;
-
- StreamTcpInitConfig(true);
- SMTPTestInitConfig();
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request1_1, request1_1_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- SMTPState *smtp_state = f.alstate;
- if (smtp_state == NULL) {
- printf("no smtp state: ");
- goto end;
- }
- if (smtp_state->current_line != NULL ||
- smtp_state->current_line_len != 0 ||
- smtp_state->ts_current_line_db != 1 ||
- smtp_state->ts_db == NULL ||
- smtp_state->ts_db_len != request1_1_len ||
- memcmp(smtp_state->ts_db, request1_1, request1_1_len) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request1_2, request1_2_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- if (smtp_state->ts_current_line_db != 1 ||
- smtp_state->ts_db == NULL ||
- smtp_state->ts_db_len != (int32_t)strlen(request1_str) ||
- memcmp(smtp_state->ts_db, request1_str, strlen(request1_str)) != 0 ||
- smtp_state->current_line != smtp_state->ts_db ||
- smtp_state->current_line_len != smtp_state->ts_db_len) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request2, request2_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- if (smtp_state->ts_current_line_db != 0 ||
- smtp_state->ts_db != NULL ||
- smtp_state->ts_db_len != 0 ||
- smtp_state->current_line == NULL ||
- smtp_state->current_line_len != (int32_t)strlen(request1_str) ||
- memcmp(smtp_state->current_line, request1_str, strlen(request1_str)) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- result = 1;
-end:
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- StreamTcpFreeConfig(true);
- FLOW_DESTROY(&f);
- return result;
-}
-
-/*
- * \test Test retrieving lines when frag'ed.
- */
-static int SMTPParserTest10(void)
-{
- int result = 0;
- Flow f;
- int r = 0;
-
- const char *request1_str = "";
- /* EHLO boo. */
- uint8_t request1_1[] = {
- 0x0d,
- };
- int32_t request1_1_len = sizeof(request1_1);
-
- /* com<CR><LF> */
- uint8_t request1_2[] = {
- 0x0a,
- };
- int32_t request1_2_len = sizeof(request1_2);
-
- const char *request2_str = "EHLO boo.com";
- /* EHLO boo.com<CR><LF> */
- uint8_t request2[] = {
- 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f,
- 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a,
- };
- int32_t request2_len = sizeof(request2);
-
- TcpSession ssn;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&f, 0, sizeof(f));
- memset(&ssn, 0, sizeof(ssn));
-
- FLOW_INITIALIZE(&f);
- f.protoctx = (void *)&ssn;
- f.proto = IPPROTO_TCP;
- f.alproto = ALPROTO_SMTP;
-
- StreamTcpInitConfig(true);
- SMTPTestInitConfig();
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request1_1, request1_1_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- SMTPState *smtp_state = f.alstate;
- if (smtp_state == NULL) {
- printf("no smtp state: ");
- goto end;
- }
- if (smtp_state->current_line != NULL ||
- smtp_state->current_line_len != 0 ||
- smtp_state->ts_current_line_db != 1 ||
- smtp_state->ts_db == NULL ||
- smtp_state->ts_db_len != request1_1_len ||
- memcmp(smtp_state->ts_db, request1_1, request1_1_len) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request1_2, request1_2_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- if (smtp_state->ts_current_line_db != 1 ||
- smtp_state->ts_db == NULL ||
- smtp_state->ts_db_len != (int32_t)strlen(request1_str) ||
- memcmp(smtp_state->ts_db, request1_str, strlen(request1_str)) != 0 ||
- smtp_state->current_line != smtp_state->ts_db ||
- smtp_state->current_line_len != smtp_state->ts_db_len) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request2, request2_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- if (smtp_state->ts_current_line_db != 0 ||
- smtp_state->ts_db != NULL ||
- smtp_state->ts_db_len != 0 ||
- smtp_state->current_line == NULL ||
- smtp_state->current_line_len != (int32_t)strlen(request2_str) ||
- memcmp(smtp_state->current_line, request2_str, strlen(request2_str)) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- result = 1;
-end:
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- StreamTcpFreeConfig(true);
- FLOW_DESTROY(&f);
- return result;
-}
-
-/*
- * \test Test retrieving lines when frag'ed.
- */
-static int SMTPParserTest11(void)
-{
- int result = 0;
- Flow f;
- int r = 0;
-
- const char *request1_str = "";
- /* EHLO boo. */
- uint8_t request1[] = {
- 0x0a,
- };
- int32_t request1_len = sizeof(request1);
-
- const char *request2_str = "EHLO boo.com";
- /* EHLO boo.com<CR><LF> */
- uint8_t request2[] = {
- 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f,
- 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a,
- };
- int32_t request2_len = sizeof(request2);
-
- TcpSession ssn;
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
-
- memset(&f, 0, sizeof(f));
- memset(&ssn, 0, sizeof(ssn));
-
- FLOW_INITIALIZE(&f);
- f.protoctx = (void *)&ssn;
- f.proto = IPPROTO_TCP;
- f.alproto = ALPROTO_SMTP;
-
- StreamTcpInitConfig(true);
- SMTPTestInitConfig();
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request1, request1_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- SMTPState *smtp_state = f.alstate;
- if (smtp_state == NULL) {
- printf("no smtp state: ");
- goto end;
- }
- if (smtp_state->current_line == NULL ||
- smtp_state->current_line_len != 0 ||
- smtp_state->ts_current_line_db == 1 ||
- smtp_state->ts_db != NULL ||
- smtp_state->ts_db_len != 0 ||
- memcmp(smtp_state->current_line, request1_str, strlen(request1_str)) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(&f);
- r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SMTP,
- STREAM_TOSERVER, request2, request2_len);
- if (r != 0) {
- printf("smtp check returned %" PRId32 ", expected 0: ", r);
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
- if (smtp_state->ts_current_line_db != 0 ||
- smtp_state->ts_db != NULL ||
- smtp_state->ts_db_len != 0 ||
- smtp_state->current_line == NULL ||
- smtp_state->current_line_len != (int32_t)strlen(request2_str) ||
- memcmp(smtp_state->current_line, request2_str, strlen(request2_str)) != 0) {
- printf("smtp parser in inconsistent state\n");
- goto end;
- }
-
- result = 1;
-end:
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
- StreamTcpFreeConfig(true);
- FLOW_DESTROY(&f);
- return result;
-}
-
static int SMTPParserTest12(void)
{
int result = 0;
UtRegisterTest("SMTPParserTest04", SMTPParserTest04);
UtRegisterTest("SMTPParserTest05", SMTPParserTest05);
UtRegisterTest("SMTPParserTest06", SMTPParserTest06);
- UtRegisterTest("SMTPParserTest07", SMTPParserTest07);
- UtRegisterTest("SMTPParserTest08", SMTPParserTest08);
- UtRegisterTest("SMTPParserTest09", SMTPParserTest09);
- UtRegisterTest("SMTPParserTest10", SMTPParserTest10);
- UtRegisterTest("SMTPParserTest11", SMTPParserTest11);
UtRegisterTest("SMTPParserTest12", SMTPParserTest12);
UtRegisterTest("SMTPParserTest13", SMTPParserTest13);
UtRegisterTest("SMTPParserTest14", SMTPParserTest14);