@ -657,11 +657,24 @@ static AppLayerResult SMTPGetLine(SMTPState *state, SMTPInput *input, SMTPLine *
}
}
SCReturnStruct ( APP_LAYER_INCOMPLETE ( input - > consumed , input - > len + 1 ) ) ;
SCReturnStruct ( APP_LAYER_INCOMPLETE ( input - > consumed , input - > len + 1 ) ) ;
} else {
} else {
/* There could be one chunk of command data that has LF but post the line limit
* e . g . input_len = 5077
* lf_idx = 5010
* max_line_len = 4096 */
uint32_t o_consumed = input - > consumed ;
uint32_t o_consumed = input - > consumed ;
input - > consumed = lf_idx - input - > buf + 1 ;
input - > consumed = lf_idx - input - > buf + 1 ;
line - > len = input - > consumed - o_consumed ;
line - > len = input - > consumed - o_consumed ;
DEBUG_VALIDATE_BUG_ON ( line - > len < 0 ) ;
if ( line - > len < 0 )
SCReturnStruct ( APP_LAYER_ERROR ) ;
input - > len - = line - > len ;
input - > len - = line - > len ;
DEBUG_VALIDATE_BUG_ON ( ( input - > consumed + input - > len ) ! = input - > orig_len ) ;
DEBUG_VALIDATE_BUG_ON ( ( input - > consumed + input - > len ) ! = input - > orig_len ) ;
line - > buf = input - > buf + o_consumed ;
if ( line - > len > = SMTP_LINE_BUFFER_LIMIT ) {
line - > len = SMTP_LINE_BUFFER_LIMIT ;
line - > delim_len = 0 ;
SCReturnStruct ( APP_LAYER_OK ) ;
}
if ( state - > discard_till_lf ) {
if ( state - > discard_till_lf ) {
// Whatever came in with first LF should also get discarded
// Whatever came in with first LF should also get discarded
state - > discard_till_lf = false ;
state - > discard_till_lf = false ;
@ -669,7 +682,6 @@ static AppLayerResult SMTPGetLine(SMTPState *state, SMTPInput *input, SMTPLine *
line - > delim_len = 0 ;
line - > delim_len = 0 ;
SCReturnStruct ( APP_LAYER_OK ) ;
SCReturnStruct ( APP_LAYER_OK ) ;
}
}
line - > buf = input - > buf + o_consumed ;
if ( input - > consumed > = 2 & & input - > buf [ input - > consumed - 2 ] = = 0x0D ) {
if ( input - > consumed > = 2 & & input - > buf [ input - > consumed - 2 ] = = 0x0D ) {
line - > delim_len = 2 ;
line - > delim_len = 2 ;
line - > len - = 2 ;
line - > len - = 2 ;
@ -1270,6 +1282,8 @@ static int SMTPPreProcessCommands(
SMTPState * state , Flow * f , AppLayerParserState * pstate , SMTPInput * input , SMTPLine * line )
SMTPState * state , Flow * f , AppLayerParserState * pstate , SMTPInput * input , SMTPLine * line )
{
{
DEBUG_VALIDATE_BUG_ON ( ( state - > parser_state & SMTP_PARSER_STATE_COMMAND_DATA_MODE ) = = 0 ) ;
DEBUG_VALIDATE_BUG_ON ( ( state - > parser_state & SMTP_PARSER_STATE_COMMAND_DATA_MODE ) = = 0 ) ;
DEBUG_VALIDATE_BUG_ON ( line - > len ! = 0 ) ;
DEBUG_VALIDATE_BUG_ON ( line - > delim_len ! = 0 ) ;
/* fall back to strict line parsing for mime header parsing */
/* fall back to strict line parsing for mime header parsing */
if ( state - > curr_tx & & state - > curr_tx - > mime_state & &
if ( state - > curr_tx & & state - > curr_tx - > mime_state & &
@ -1307,6 +1321,7 @@ static int SMTPPreProcessCommands(
int32_t current_line_consumed = total_consumed - input - > consumed ;
int32_t current_line_consumed = total_consumed - input - > consumed ;
line - > buf = input - > buf + input - > consumed ;
line - > buf = input - > buf + input - > consumed ;
line - > len = current_line_consumed - line - > delim_len ;
line - > len = current_line_consumed - line - > delim_len ;
DEBUG_VALIDATE_BUG_ON ( line - > len < 0 ) ;
input - > consumed = total_consumed ;
input - > consumed = total_consumed ;
input - > len - = current_line_consumed ;
input - > len - = current_line_consumed ;
DEBUG_VALIDATE_BUG_ON ( input - > consumed + input - > len ! = input - > orig_len ) ;
DEBUG_VALIDATE_BUG_ON ( input - > consumed + input - > len ! = input - > orig_len ) ;
@ -1358,10 +1373,8 @@ static AppLayerResult SMTPParse(uint8_t direction, Flow *f, SMTPState *state,
}
}
AppLayerResult res = SMTPGetLine ( state , & input , & line ) ;
AppLayerResult res = SMTPGetLine ( state , & input , & line ) ;
while ( res . status = = 0 ) {
while ( res . status = = 0 ) {
DEBUG_VALIDATE_BUG_ON ( state - > discard_till_lf ) ;
int retval = SMTPProcessRequest ( state , f , pstate , & input , & line ) ;
if ( ! state - > discard_till_lf ) {
if ( retval ! = 0 )
if ( ( line . delim_len > 0 ) & &
( SMTPProcessRequest ( state , f , pstate , & input , & line ) = = - 1 ) )
SCReturnStruct ( APP_LAYER_ERROR ) ;
SCReturnStruct ( APP_LAYER_ERROR ) ;
if ( line . delim_len = = 0 & & line . len = = SMTP_LINE_BUFFER_LIMIT ) {
if ( line . delim_len = = 0 & & line . len = = SMTP_LINE_BUFFER_LIMIT ) {
state - > discard_till_lf = true ;
state - > discard_till_lf = true ;
@ -1371,17 +1384,13 @@ static AppLayerResult SMTPParse(uint8_t direction, Flow *f, SMTPState *state,
}
}
res = SMTPGetLine ( state , & input , & line ) ;
res = SMTPGetLine ( state , & input , & line ) ;
}
}
}
if ( res . status = = 1 )
if ( res . status = = 1 )
return res ;
return res ;
/* toclient */
/* toclient */
} else {
} else {
AppLayerResult res = SMTPGetLine ( state , & input , & line ) ;
AppLayerResult res = SMTPGetLine ( state , & input , & line ) ;
while ( res . status = = 0 ) {
while ( res . status = = 0 ) {
DEBUG_VALIDATE_BUG_ON ( state - > discard_till_lf ) ;
if ( SMTPProcessReply ( state , f , pstate , thread_data , & input , & line ) ! = 0 )
if ( ! state - > discard_till_lf ) {
if ( ( line . delim_len > 0 ) & &
( SMTPProcessReply ( state , f , pstate , thread_data , & input , & line ) = = - 1 ) )
SCReturnStruct ( APP_LAYER_ERROR ) ;
SCReturnStruct ( APP_LAYER_ERROR ) ;
if ( line . delim_len = = 0 & & line . len = = SMTP_LINE_BUFFER_LIMIT ) {
if ( line . delim_len = = 0 & & line . len = = SMTP_LINE_BUFFER_LIMIT ) {
state - > discard_till_lf = true ;
state - > discard_till_lf = true ;
@ -1391,7 +1400,6 @@ static AppLayerResult SMTPParse(uint8_t direction, Flow *f, SMTPState *state,
}
}
res = SMTPGetLine ( state , & input , & line ) ;
res = SMTPGetLine ( state , & input , & line ) ;
}
}
}
if ( res . status = = 1 )
if ( res . status = = 1 )
return res ;
return res ;
}
}