@ -464,17 +464,24 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
SCLogDebug ( " inspecting http raw uri " ) ;
}
if ( s - > sm_lists [ DETECT_SM_LIST_FILEMATCH ] ! = NULL ) {
inspect_flags | = DE_STATE_FLAG_FILE_TS_INSPECT ;
match = DetectFileInspectHttp ( tv , det_ctx , f , s , alstate , flags ) ;
if ( match = = 1 ) {
match_flags | = DE_STATE_FLAG_FILE_TS_MATCH ;
} else if ( match = = 2 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
} else if ( match = = 3 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
file_no_match + + ;
SCLogDebug ( " file inspection " ) ;
if ( match_flags = = inspect_flags ) {
SCLogDebug ( " ready to inspect files " ) ;
inspect_flags | = DE_STATE_FLAG_FILE_TS_INSPECT ;
match = DetectFileInspectHttp ( tv , det_ctx , f , s , alstate , flags ) ;
if ( match = = 1 ) {
match_flags | = DE_STATE_FLAG_FILE_TS_MATCH ;
} else if ( match = = 2 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
} else if ( match = = 3 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
file_no_match + + ;
}
} else {
SCLogDebug ( " skipping file inspection as we're not yet done with the other inspection " ) ;
}
}
} else if ( flags & STREAM_TOCLIENT ) {
@ -518,17 +525,24 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
inspect_flags | = DE_STATE_FLAG_HRUD_INSPECT ;
}
if ( s - > sm_lists [ DETECT_SM_LIST_FILEMATCH ] ! = NULL ) {
inspect_flags | = DE_STATE_FLAG_FILE_TC_INSPECT ;
match = DetectFileInspectHttp ( tv , det_ctx , f , s , alstate , flags ) ;
SCLogDebug ( " match %d " , match ) ;
if ( match = = 1 ) {
match_flags | = DE_STATE_FLAG_FILE_TC_MATCH ;
} else if ( match = = 2 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
} else if ( match = = 3 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
file_no_match + + ;
SCLogDebug ( " file inspection " ) ;
if ( match_flags = = inspect_flags ) {
SCLogDebug ( " ready to inspect files " ) ;
inspect_flags | = DE_STATE_FLAG_FILE_TC_INSPECT ;
match = DetectFileInspectHttp ( tv , det_ctx , f , s , alstate , flags ) ;
SCLogDebug ( " match %d " , match ) ;
if ( match = = 1 ) {
match_flags | = DE_STATE_FLAG_FILE_TC_MATCH ;
} else if ( match = = 2 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
} else if ( match = = 3 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
file_no_match + + ;
}
} else {
SCLogDebug ( " skipping file inspection as we're not yet done with the other inspection " ) ;
}
}
}
@ -616,6 +630,13 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
DeStateSignatureAppend ( f - > de_state , s , sm , match_flags ) ;
DeStateStoreStateVersion ( f - > de_state , flags , alversion ) ;
DeStateStoreFileNoMatch ( f - > de_state , flags , file_no_match ) ;
if ( DeStateStoreFilestoreSigsCantMatch ( det_ctx - > sgh , f - > de_state , flags ) = = 1 ) {
SCLogDebug ( " disabling file storage for transaction %u " , det_ctx - > tx_id ) ;
FileDisableStoringForTransaction ( f , flags & ( STREAM_TOCLIENT | STREAM_TOSERVER ) ,
det_ctx - > tx_id ) ;
f - > de_state - > flags | = DE_STATE_FILE_STORE_DISABLED ;
}
}
SCMutexUnlock ( & f - > de_state_m ) ;
@ -811,16 +832,23 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
if ( s - > sm_lists [ DETECT_SM_LIST_FILEMATCH ] ! = NULL ) {
if ( ! ( item - > flags & DE_STATE_FLAG_FILE_TS_MATCH ) ) {
inspect_flags | = DE_STATE_FLAG_FILE_TS_INSPECT ;
match = DetectFileInspectHttp ( tv , det_ctx , f , s , alstate , flags ) ;
if ( match = = 1 ) {
match_flags | = DE_STATE_FLAG_FILE_TS_MATCH ;
} else if ( match = = 2 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
} else if ( match = = 3 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
file_no_match + + ;
SCLogDebug ( " file inspection " ) ;
if ( match_flags = = inspect_flags ) {
SCLogDebug ( " ready to inspect files " ) ;
inspect_flags | = DE_STATE_FLAG_FILE_TS_INSPECT ;
match = DetectFileInspectHttp ( tv , det_ctx , f , s , alstate , flags ) ;
if ( match = = 1 ) {
match_flags | = DE_STATE_FLAG_FILE_TS_MATCH ;
} else if ( match = = 2 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
} else if ( match = = 3 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
file_no_match + + ;
}
} else {
SCLogDebug ( " skipping file inspection as we're not yet done with the other inspection " ) ;
}
}
}
@ -866,16 +894,23 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
if ( s - > sm_lists [ DETECT_SM_LIST_FILEMATCH ] ! = NULL ) {
if ( ! ( item - > flags & DE_STATE_FLAG_FILE_TC_MATCH ) ) {
inspect_flags | = DE_STATE_FLAG_FILE_TC_INSPECT ;
match = DetectFileInspectHttp ( tv , det_ctx , f , s , alstate , flags ) ;
if ( match = = 1 ) {
match_flags | = DE_STATE_FLAG_FILE_TC_MATCH ;
} else if ( match = = 2 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
} else if ( match = = 3 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
file_no_match + + ;
SCLogDebug ( " file inspection " ) ;
if ( match_flags = = inspect_flags ) {
SCLogDebug ( " ready to inspect files " ) ;
inspect_flags | = DE_STATE_FLAG_FILE_TC_INSPECT ;
match = DetectFileInspectHttp ( tv , det_ctx , f , s , alstate , flags ) ;
if ( match = = 1 ) {
match_flags | = DE_STATE_FLAG_FILE_TC_MATCH ;
} else if ( match = = 2 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
} else if ( match = = 3 ) {
match_flags | = DE_STATE_FLAG_SIG_CANT_MATCH ;
file_no_match + + ;
}
} else {
SCLogDebug ( " skipping file inspection as we're not yet done with the other inspection " ) ;
}
}
}
@ -1466,6 +1501,599 @@ end:
UTHFreePacket ( p ) ;
return result ;
}
static int DeStateSigTest03 ( void ) {
uint8_t httpbuf1 [ ] = " POST /upload.cgi HTTP/1.1 \r \n "
" Host: www.server.lan \r \n "
" Content-Type: multipart/form-data; boundary=---------------------------277531038314945 \r \n "
" Content-Length: 215 \r \n "
" \r \n "
" -----------------------------277531038314945 \r \n "
" Content-Disposition: form-data; name= \" uploadfile_0 \" ; filename= \" somepicture1.jpg \" \r \n "
" Content-Type: image/jpeg \r \n "
" \r \n "
" filecontent \r \n "
" -----------------------------277531038314945-- " ;
uint32_t httplen1 = sizeof ( httpbuf1 ) - 1 ; /* minus the \0 */
ThreadVars th_v ;
TcpSession ssn ;
int result = 0 ;
Flow * f = NULL ;
Packet * p = NULL ;
HtpState * http_state = NULL ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
DetectEngineThreadCtx * det_ctx = NULL ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > flags | = DE_QUIET ;
Signature * s = DetectEngineAppendSig ( de_ctx , " alert http any any -> any any (content: \" POST \" ; http_method; content: \" upload.cgi \" ; http_uri; filestore; sid:1; rev:1;) " ) ;
if ( s = = NULL ) {
printf ( " sig parse failed: " ) ;
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
f = UTHBuildFlow ( AF_INET , " 1.2.3.4 " , " 1.2.3.5 " , 1024 , 80 ) ;
if ( f = = NULL )
goto end ;
f - > protoctx = & ssn ;
f - > alproto = ALPROTO_HTTP ;
p = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
if ( p = = NULL )
goto end ;
p - > flow = f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
StreamTcpInitConfig ( TRUE ) ;
int r = AppLayerParse ( NULL , f , ALPROTO_HTTP , STREAM_TOSERVER | STREAM_START | STREAM_EOF , httpbuf1 , httplen1 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( ! ( PacketAlertCheck ( p , 1 ) ) ) {
printf ( " sig 1 didn't alert: " ) ;
goto end ;
}
http_state = f - > alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
if ( http_state - > files_ts = = NULL ) {
printf ( " no files in state: " ) ;
goto end ;
}
FileContainer * files = AppLayerGetFilesFromFlow ( p - > flow , STREAM_TOSERVER ) ;
if ( files = = NULL ) {
printf ( " no stored files: " ) ;
goto end ;
}
File * file = files - > head ;
if ( file = = NULL ) {
printf ( " no file: " ) ;
goto end ;
}
if ( file - > store ! = 1 ) {
printf ( " file is set to store, but sig didn't match: " ) ;
goto end ;
}
result = 1 ;
end :
UTHFreeFlow ( f ) ;
if ( det_ctx ! = NULL ) {
DetectEngineThreadCtxDeinit ( & th_v , ( void * ) det_ctx ) ;
}
if ( de_ctx ! = NULL ) {
SigGroupCleanup ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
}
StreamTcpFreeConfig ( TRUE ) ;
return result ;
}
static int DeStateSigTest04 ( void ) {
uint8_t httpbuf1 [ ] = " POST /upload.cgi HTTP/1.1 \r \n "
" Host: www.server.lan \r \n "
" Content-Type: multipart/form-data; boundary=---------------------------277531038314945 \r \n "
" Content-Length: 215 \r \n "
" \r \n "
" -----------------------------277531038314945 \r \n "
" Content-Disposition: form-data; name= \" uploadfile_0 \" ; filename= \" somepicture1.jpg \" \r \n "
" Content-Type: image/jpeg \r \n "
" \r \n "
" filecontent \r \n "
" -----------------------------277531038314945-- " ;
uint32_t httplen1 = sizeof ( httpbuf1 ) - 1 ; /* minus the \0 */
ThreadVars th_v ;
TcpSession ssn ;
int result = 0 ;
Flow * f = NULL ;
Packet * p = NULL ;
HtpState * http_state = NULL ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
DetectEngineThreadCtx * det_ctx = NULL ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > flags | = DE_QUIET ;
Signature * s = DetectEngineAppendSig ( de_ctx , " alert http any any -> any any (content: \" GET \" ; http_method; content: \" upload.cgi \" ; http_uri; filestore; sid:1; rev:1;) " ) ;
if ( s = = NULL ) {
printf ( " sig parse failed: " ) ;
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
f = UTHBuildFlow ( AF_INET , " 1.2.3.4 " , " 1.2.3.5 " , 1024 , 80 ) ;
if ( f = = NULL )
goto end ;
f - > protoctx = & ssn ;
f - > alproto = ALPROTO_HTTP ;
p = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
if ( p = = NULL )
goto end ;
p - > flow = f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
StreamTcpInitConfig ( TRUE ) ;
int r = AppLayerParse ( NULL , f , ALPROTO_HTTP , STREAM_TOSERVER | STREAM_START | STREAM_EOF , httpbuf1 , httplen1 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) ) {
printf ( " sig 1 alerted: " ) ;
goto end ;
}
http_state = f - > alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
if ( http_state - > files_ts = = NULL ) {
printf ( " no files in state: " ) ;
goto end ;
}
FileContainer * files = AppLayerGetFilesFromFlow ( p - > flow , STREAM_TOSERVER ) ;
if ( files = = NULL ) {
printf ( " no stored files: " ) ;
goto end ;
}
File * file = files - > head ;
if ( file = = NULL ) {
printf ( " no file: " ) ;
goto end ;
}
if ( file - > store = = 1 ) {
printf ( " file is set to store, but sig didn't match: " ) ;
goto end ;
}
result = 1 ;
end :
UTHFreeFlow ( f ) ;
if ( det_ctx ! = NULL ) {
DetectEngineThreadCtxDeinit ( & th_v , ( void * ) det_ctx ) ;
}
if ( de_ctx ! = NULL ) {
SigGroupCleanup ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
}
StreamTcpFreeConfig ( TRUE ) ;
return result ;
}
static int DeStateSigTest05 ( void ) {
uint8_t httpbuf1 [ ] = " POST /upload.cgi HTTP/1.1 \r \n "
" Host: www.server.lan \r \n "
" Content-Type: multipart/form-data; boundary=---------------------------277531038314945 \r \n "
" Content-Length: 215 \r \n "
" \r \n "
" -----------------------------277531038314945 \r \n "
" Content-Disposition: form-data; name= \" uploadfile_0 \" ; filename= \" somepicture1.jpg \" \r \n "
" Content-Type: image/jpeg \r \n "
" \r \n "
" filecontent \r \n "
" -----------------------------277531038314945-- " ;
uint32_t httplen1 = sizeof ( httpbuf1 ) - 1 ; /* minus the \0 */
ThreadVars th_v ;
TcpSession ssn ;
int result = 0 ;
Flow * f = NULL ;
Packet * p = NULL ;
HtpState * http_state = NULL ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
DetectEngineThreadCtx * det_ctx = NULL ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > flags | = DE_QUIET ;
Signature * s = DetectEngineAppendSig ( de_ctx , " alert http any any -> any any (content: \" GET \" ; http_method; content: \" upload.cgi \" ; http_uri; filename: \" nomatch \" ; sid:1; rev:1;) " ) ;
if ( s = = NULL ) {
printf ( " sig parse failed: " ) ;
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
f = UTHBuildFlow ( AF_INET , " 1.2.3.4 " , " 1.2.3.5 " , 1024 , 80 ) ;
if ( f = = NULL )
goto end ;
f - > protoctx = & ssn ;
f - > alproto = ALPROTO_HTTP ;
p = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
if ( p = = NULL )
goto end ;
p - > flow = f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
StreamTcpInitConfig ( TRUE ) ;
int r = AppLayerParse ( NULL , f , ALPROTO_HTTP , STREAM_TOSERVER | STREAM_START | STREAM_EOF , httpbuf1 , httplen1 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) ) {
printf ( " sig 1 alerted: " ) ;
goto end ;
}
http_state = f - > alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
if ( http_state - > files_ts = = NULL ) {
printf ( " no files in state: " ) ;
goto end ;
}
FileContainer * files = AppLayerGetFilesFromFlow ( p - > flow , STREAM_TOSERVER ) ;
if ( files = = NULL ) {
printf ( " no stored files: " ) ;
goto end ;
}
File * file = files - > head ;
if ( file = = NULL ) {
printf ( " no file: " ) ;
goto end ;
}
if ( file - > store ! = - 1 ) {
printf ( " file is not set to \" no store \" , but %d: " , file - > store ) ;
goto end ;
}
result = 1 ;
end :
UTHFreeFlow ( f ) ;
if ( det_ctx ! = NULL ) {
DetectEngineThreadCtxDeinit ( & th_v , ( void * ) det_ctx ) ;
}
if ( de_ctx ! = NULL ) {
SigGroupCleanup ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
}
StreamTcpFreeConfig ( TRUE ) ;
return result ;
}
static int DeStateSigTest06 ( void ) {
uint8_t httpbuf1 [ ] = " POST /upload.cgi HTTP/1.1 \r \n "
" Host: www.server.lan \r \n "
" Content-Type: multipart/form-data; boundary=---------------------------277531038314945 \r \n "
" Content-Length: 215 \r \n "
" \r \n "
" -----------------------------277531038314945 \r \n "
" Content-Disposition: form-data; name= \" uploadfile_0 \" ; filename= \" somepicture1.jpg \" \r \n "
" Content-Type: image/jpeg \r \n "
" \r \n "
" filecontent \r \n "
" -----------------------------277531038314945-- " ;
uint32_t httplen1 = sizeof ( httpbuf1 ) - 1 ; /* minus the \0 */
ThreadVars th_v ;
TcpSession ssn ;
int result = 0 ;
Flow * f = NULL ;
Packet * p = NULL ;
HtpState * http_state = NULL ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
DetectEngineThreadCtx * det_ctx = NULL ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > flags | = DE_QUIET ;
Signature * s = DetectEngineAppendSig ( de_ctx , " alert http any any -> any any (content: \" POST \" ; http_method; content: \" upload.cgi \" ; http_uri; filename: \" nomatch \" ; filestore; sid:1; rev:1;) " ) ;
if ( s = = NULL ) {
printf ( " sig parse failed: " ) ;
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
f = UTHBuildFlow ( AF_INET , " 1.2.3.4 " , " 1.2.3.5 " , 1024 , 80 ) ;
if ( f = = NULL )
goto end ;
f - > protoctx = & ssn ;
f - > alproto = ALPROTO_HTTP ;
p = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
if ( p = = NULL )
goto end ;
p - > flow = f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
StreamTcpInitConfig ( TRUE ) ;
int r = AppLayerParse ( NULL , f , ALPROTO_HTTP , STREAM_TOSERVER | STREAM_START | STREAM_EOF , httpbuf1 , httplen1 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) ) {
printf ( " sig 1 alerted: " ) ;
goto end ;
}
http_state = f - > alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
if ( http_state - > files_ts = = NULL ) {
printf ( " no files in state: " ) ;
goto end ;
}
FileContainer * files = AppLayerGetFilesFromFlow ( p - > flow , STREAM_TOSERVER ) ;
if ( files = = NULL ) {
printf ( " no stored files: " ) ;
goto end ;
}
File * file = files - > head ;
if ( file = = NULL ) {
printf ( " no file: " ) ;
goto end ;
}
if ( file - > store ! = - 1 ) {
printf ( " file is not set to \" no store \" , but %d: " , file - > store ) ;
goto end ;
}
result = 1 ;
end :
UTHFreeFlow ( f ) ;
if ( det_ctx ! = NULL ) {
DetectEngineThreadCtxDeinit ( & th_v , ( void * ) det_ctx ) ;
}
if ( de_ctx ! = NULL ) {
SigGroupCleanup ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
}
StreamTcpFreeConfig ( TRUE ) ;
return result ;
}
static int DeStateSigTest07 ( void ) {
uint8_t httpbuf1 [ ] = " POST /upload.cgi HTTP/1.1 \r \n "
" Host: www.server.lan \r \n "
" Content-Type: multipart/form-data; boundary=---------------------------277531038314945 \r \n "
" Content-Length: 215 \r \n "
" \r \n "
" -----------------------------277531038314945 \r \n "
" Content-Disposition: form-data; name= \" uploadfile_0 \" ; filename= \" somepicture1.jpg \" \r \n "
" Content-Type: image/jpeg \r \n "
" \r \n " ;
uint32_t httplen1 = sizeof ( httpbuf1 ) - 1 ; /* minus the \0 */
uint8_t httpbuf2 [ ] = " filecontent \r \n "
" -----------------------------277531038314945-- " ;
uint32_t httplen2 = sizeof ( httpbuf2 ) - 1 ; /* minus the \0 */
ThreadVars th_v ;
TcpSession ssn ;
int result = 0 ;
Flow * f = NULL ;
Packet * p = NULL ;
HtpState * http_state = NULL ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
DetectEngineThreadCtx * det_ctx = NULL ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > flags | = DE_QUIET ;
Signature * s = DetectEngineAppendSig ( de_ctx , " alert http any any -> any any (content: \" GET \" ; http_method; content: \" upload.cgi \" ; http_uri; filestore; sid:1; rev:1;) " ) ;
if ( s = = NULL ) {
printf ( " sig parse failed: " ) ;
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
f = UTHBuildFlow ( AF_INET , " 1.2.3.4 " , " 1.2.3.5 " , 1024 , 80 ) ;
if ( f = = NULL )
goto end ;
f - > protoctx = & ssn ;
f - > alproto = ALPROTO_HTTP ;
p = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
if ( p = = NULL )
goto end ;
p - > flow = f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
StreamTcpInitConfig ( TRUE ) ;
SCLogDebug ( " \n >>>> processing chunk 1 <<<< \n " ) ;
int r = AppLayerParse ( NULL , f , ALPROTO_HTTP , STREAM_TOSERVER | STREAM_START , httpbuf1 , httplen1 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) ) {
printf ( " sig 1 alerted: " ) ;
goto end ;
}
SCLogDebug ( " \n >>>> processing chunk 2 size %u <<<< \n " , httplen2 ) ;
r = AppLayerParse ( NULL , f , ALPROTO_HTTP , STREAM_TOSERVER | STREAM_EOF , httpbuf2 , httplen2 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 2 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) ) {
printf ( " sig 1 alerted: " ) ;
goto end ;
}
http_state = f - > alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
if ( http_state - > files_ts = = NULL ) {
printf ( " no files in state: " ) ;
goto end ;
}
FileContainer * files = AppLayerGetFilesFromFlow ( p - > flow , STREAM_TOSERVER ) ;
if ( files = = NULL ) {
printf ( " no stored files: " ) ;
goto end ;
}
File * file = files - > head ;
if ( file = = NULL ) {
printf ( " no file: " ) ;
goto end ;
}
if ( file - > store = = 1 ) {
printf ( " file is set to store, but sig didn't match: " ) ;
goto end ;
}
result = 1 ;
end :
UTHFreeFlow ( f ) ;
if ( det_ctx ! = NULL ) {
DetectEngineThreadCtxDeinit ( & th_v , ( void * ) det_ctx ) ;
}
if ( de_ctx ! = NULL ) {
SigGroupCleanup ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
}
StreamTcpFreeConfig ( TRUE ) ;
return result ;
}
# endif
void DeStateRegisterTests ( void ) {
@ -1475,6 +2103,11 @@ void DeStateRegisterTests(void) {
UtRegisterTest ( " DeStateTest03 " , DeStateTest03 , 1 ) ;
UtRegisterTest ( " DeStateSigTest01 " , DeStateSigTest01 , 1 ) ;
UtRegisterTest ( " DeStateSigTest02 " , DeStateSigTest02 , 1 ) ;
UtRegisterTest ( " DeStateSigTest03 " , DeStateSigTest03 , 1 ) ;
UtRegisterTest ( " DeStateSigTest04 " , DeStateSigTest04 , 1 ) ;
UtRegisterTest ( " DeStateSigTest05 " , DeStateSigTest05 , 1 ) ;
UtRegisterTest ( " DeStateSigTest06 " , DeStateSigTest06 , 1 ) ;
UtRegisterTest ( " DeStateSigTest07 " , DeStateSigTest07 , 1 ) ;
# endif
}