@ -208,6 +208,10 @@ static SuricataFileContext sfc = { &sbcfg };
# define SMB_CONFIG_DEFAULT_STREAM_DEPTH 0
# ifdef UNITTESTS
static void SMBParserRegisterTests ( void ) ;
# endif
static uint32_t stream_depth = SMB_CONFIG_DEFAULT_STREAM_DEPTH ;
void RegisterRustSMBTCPParsers ( void )
@ -299,7 +303,177 @@ void RegisterRustSMBTCPParsers(void)
SCLogInfo ( " Parsed disabled for %s protocol. Protocol detection "
" still on. " , proto_name ) ;
}
# ifdef UNITTESTS
AppLayerParserRegisterProtocolUnittests ( IPPROTO_TCP , ALPROTO_SMB , SMBParserRegisterTests ) ;
# endif
return ;
}
# ifdef UNITTESTS
# include "stream-tcp.h"
# include "util-unittest-helper.h"
/** \test multi transactions and cleanup */
static int SMBParserTxCleanupTest ( void )
{
uint64_t ret [ 4 ] ;
AppLayerParserThreadCtx * alp_tctx = AppLayerParserThreadCtxAlloc ( ) ;
FAIL_IF_NULL ( alp_tctx ) ;
StreamTcpInitConfig ( TRUE ) ;
TcpSession ssn ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
Flow * f = UTHBuildFlow ( AF_INET , " 1.2.3.4 " , " 1.2.3.5 " , 1024 , 445 ) ;
FAIL_IF_NULL ( f ) ;
f - > protoctx = & ssn ;
f - > proto = IPPROTO_TCP ;
f - > alproto = ALPROTO_SMB ;
char req_str [ ] = " \x00 \x00 \x00 \x79 \xfe \x53 \x4d \x42 \x40 \x00 \x01 \x00 \x00 \x00 \x00 \x00 " \
" \x05 \x00 \xe0 \x1e \x10 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x0b \x00 \x00 \x00 " \
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x10 \x72 \xd2 \x9f \x36 \xc2 \x08 \x14 " \
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " \
" \x00 \x00 \x00 \x00 \x39 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " \
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x80 \x00 \x00 \x00 " \
" \x00 \x00 \x00 \x00 \x07 \x00 \x00 \x00 \x01 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " \
" \x78 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ;
req_str [ 28 ] = 0x01 ;
int r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOSERVER | STREAM_START , ( uint8_t * ) req_str , sizeof ( req_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
req_str [ 28 ] + + ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOSERVER , ( uint8_t * ) req_str , sizeof ( req_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
req_str [ 28 ] + + ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOSERVER , ( uint8_t * ) req_str , sizeof ( req_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
req_str [ 28 ] + + ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOSERVER , ( uint8_t * ) req_str , sizeof ( req_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
req_str [ 28 ] + + ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOSERVER , ( uint8_t * ) req_str , sizeof ( req_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
req_str [ 28 ] + + ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOSERVER , ( uint8_t * ) req_str , sizeof ( req_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
req_str [ 28 ] + + ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOSERVER , ( uint8_t * ) req_str , sizeof ( req_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
req_str [ 28 ] + + ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOSERVER , ( uint8_t * ) req_str , sizeof ( req_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
req_str [ 28 ] + + ;
AppLayerParserTransactionsCleanup ( f ) ;
UTHAppLayerParserStateGetIds ( f - > alparser , & ret [ 0 ] , & ret [ 1 ] , & ret [ 2 ] , & ret [ 3 ] ) ;
FAIL_IF_NOT ( ret [ 0 ] = = 0 ) ; // inspect_id[0]
FAIL_IF_NOT ( ret [ 1 ] = = 0 ) ; // inspect_id[1]
FAIL_IF_NOT ( ret [ 2 ] = = 0 ) ; // log_id
FAIL_IF_NOT ( ret [ 3 ] = = 0 ) ; // min_id
char resp_str [ ] = " \x00 \x00 \x00 \x98 \xfe \x53 \x4d \x42 \x40 \x00 \x01 \x00 \x00 \x00 \x00 \x00 " \
" \x05 \x00 \x21 \x00 \x11 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x0b \x00 \x00 \x00 " \
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x10 \x72 \xd2 \x9f \x36 \xc2 \x08 \x14 " \
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " \
" \x00 \x00 \x00 \x00 \x59 \x00 \x00 \x00 \x01 \x00 \x00 \x00 \x48 \x38 \x40 \xb3 " \
" \x0f \xa8 \xd3 \x01 \x84 \x9a \x2b \x46 \xf7 \xa8 \xd3 \x01 \x48 \x38 \x40 \xb3 " \
" \x0f \xa8 \xd3 \x01 \x48 \x38 \x40 \xb3 \x0f \xa8 \xd3 \x01 \x00 \x00 \x00 \x00 " \
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x10 \x00 \x00 \x00 " \
" \x00 \x00 \x00 \x00 \x9e \x8f \xb8 \x91 \x00 \x00 \x00 \x00 \x01 \x5b \x11 \xbb " \
" \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ;
resp_str [ 28 ] = 0x01 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOCLIENT | STREAM_START , ( uint8_t * ) resp_str , sizeof ( resp_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
resp_str [ 28 ] = 0x04 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOCLIENT , ( uint8_t * ) resp_str , sizeof ( resp_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
resp_str [ 28 ] = 0x05 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOCLIENT , ( uint8_t * ) resp_str , sizeof ( resp_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
resp_str [ 28 ] = 0x06 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOCLIENT , ( uint8_t * ) resp_str , sizeof ( resp_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
resp_str [ 28 ] = 0x08 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOCLIENT , ( uint8_t * ) resp_str , sizeof ( resp_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
resp_str [ 28 ] = 0x02 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOCLIENT , ( uint8_t * ) resp_str , sizeof ( resp_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
resp_str [ 28 ] = 0x07 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOCLIENT , ( uint8_t * ) resp_str , sizeof ( resp_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
AppLayerParserTransactionsCleanup ( f ) ;
UTHAppLayerParserStateGetIds ( f - > alparser , & ret [ 0 ] , & ret [ 1 ] , & ret [ 2 ] , & ret [ 3 ] ) ;
FAIL_IF_NOT ( ret [ 0 ] = = 2 ) ; // inspect_id[0]
FAIL_IF_NOT ( ret [ 1 ] = = 2 ) ; // inspect_id[1]
FAIL_IF_NOT ( ret [ 2 ] = = 2 ) ; // log_id
FAIL_IF_NOT ( ret [ 3 ] = = 2 ) ; // min_id
resp_str [ 28 ] = 0x03 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOCLIENT , ( uint8_t * ) resp_str , sizeof ( resp_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
AppLayerParserTransactionsCleanup ( f ) ;
UTHAppLayerParserStateGetIds ( f - > alparser , & ret [ 0 ] , & ret [ 1 ] , & ret [ 2 ] , & ret [ 3 ] ) ;
FAIL_IF_NOT ( ret [ 0 ] = = 8 ) ; // inspect_id[0]
FAIL_IF_NOT ( ret [ 1 ] = = 8 ) ; // inspect_id[1]
FAIL_IF_NOT ( ret [ 2 ] = = 8 ) ; // log_id
FAIL_IF_NOT ( ret [ 3 ] = = 8 ) ; // min_id
req_str [ 28 ] = 0x09 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOSERVER | STREAM_EOF , ( uint8_t * ) req_str , sizeof ( req_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
AppLayerParserTransactionsCleanup ( f ) ;
UTHAppLayerParserStateGetIds ( f - > alparser , & ret [ 0 ] , & ret [ 1 ] , & ret [ 2 ] , & ret [ 3 ] ) ;
FAIL_IF_NOT ( ret [ 0 ] = = 8 ) ; // inspect_id[0] not updated by ..Cleanup() until full tx is done
FAIL_IF_NOT ( ret [ 1 ] = = 8 ) ; // inspect_id[1]
FAIL_IF_NOT ( ret [ 2 ] = = 8 ) ; // log_id
FAIL_IF_NOT ( ret [ 3 ] = = 8 ) ; // min_id
resp_str [ 28 ] = 0x09 ;
r = AppLayerParserParse ( NULL , alp_tctx , f , ALPROTO_SMB ,
STREAM_TOCLIENT | STREAM_EOF , ( uint8_t * ) resp_str , sizeof ( resp_str ) ) ;
FAIL_IF_NOT ( r = = 0 ) ;
AppLayerParserTransactionsCleanup ( f ) ;
UTHAppLayerParserStateGetIds ( f - > alparser , & ret [ 0 ] , & ret [ 1 ] , & ret [ 2 ] , & ret [ 3 ] ) ;
FAIL_IF_NOT ( ret [ 0 ] = = 9 ) ; // inspect_id[0]
FAIL_IF_NOT ( ret [ 1 ] = = 9 ) ; // inspect_id[1]
FAIL_IF_NOT ( ret [ 2 ] = = 9 ) ; // log_id
FAIL_IF_NOT ( ret [ 3 ] = = 9 ) ; // min_id
AppLayerParserThreadCtxFree ( alp_tctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
UTHFreeFlow ( f ) ;
PASS ;
}
static void SMBParserRegisterTests ( void )
{
UtRegisterTest ( " SMBParserTxCleanupTest " , SMBParserTxCleanupTest ) ;
}
# endif /* UNITTESTS */
# endif /* HAVE_RUST */