/* Copyright (C) 2007-2010 Open Information Security Foundation
*
* You can copy , redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA
* 02110 - 1301 , USA .
*/
/** \file
*
* \ author Victor Julien < victor @ inliniac . net >
* \ author Pablo Rincon Crespo < pablo . rincon . crespo @ gmail . com >
*
* Based on detect - engine - uri . c
*/
# include "suricata-common.h"
# include "suricata.h"
# include "decode.h"
# include "detect.h"
# include "detect-engine.h"
# include "detect-parse.h"
# include "detect-engine-state.h"
# include "detect-uricontent.h"
# include "detect-urilen.h"
# include "detect-pcre.h"
# include "detect-isdataat.h"
# include "detect-bytetest.h"
# include "detect-bytejump.h"
# include "flow-util.h"
# include "util-spm.h"
# include "util-debug.h"
# include "util-print.h"
# include "flow.h"
# include "detect-flow.h"
# include "flow-var.h"
# include "threads.h"
# include "flow-alert-sid.h"
# include "stream-tcp.h"
# include "stream.h"
# include "app-layer-parser.h"
# include "util-unittest.h"
# include "util-unittest-helper.h"
# include "app-layer.h"
# include "app-layer-htp.h"
# include "app-layer-protos.h"
/**
* \ brief Run the actual payload match function for uricontent .
*
* For accounting the last match in relative matching the
* det_ctx - > payload_offset int is used .
*
* \ param de_ctx Detection engine context .
* \ param det_ctx Detection engine thread context .
* \ param s Signature to inspect .
* \ param sm SigMatch to inspect .
* \ param payload Ptr to the uricontent payload to inspect .
* \ param payload_len Length of the uricontent payload .
*
* \ retval 0 no match .
* \ retval 1 match .
*/
static int DoInspectPacketUri ( DetectEngineCtx * de_ctx ,
DetectEngineThreadCtx * det_ctx ,
Signature * s , SigMatch * sm ,
uint8_t * payload , uint32_t payload_len )
{
SCEnter ( ) ;
if ( sm = = NULL ) {
SCReturnInt ( 0 ) ;
}
if ( sm - > type = = DETECT_URICONTENT ) {
if ( payload_len = = 0 ) {
SCReturnInt ( 0 ) ;
}
DetectUricontentData * ud = NULL ;
ud = ( DetectUricontentData * ) sm - > ctx ;
SCLogDebug ( " inspecting content % " PRIu32 " payload_len % " PRIu32 , ud - > id , payload_len ) ;
/* rule parsers should take care of this */
BUG_ON ( ud - > depth ! = 0 & & ud - > depth < = ud - > offset ) ;
/* search for our pattern, checking the matches recursively.
* if we match we look for the next SigMatch as well */
uint8_t * found = NULL ;
uint32_t offset = 0 ;
uint32_t depth = payload_len ;
uint32_t prev_offset = 0 ; /**< used in recursive searching */
uint32_t prev_payload_offset = det_ctx - > payload_offset ;
do {
if ( ud - > flags & DETECT_URICONTENT_DISTANCE | |
ud - > flags & DETECT_URICONTENT_WITHIN ) {
SCLogDebug ( " prev_payload_offset % " PRIu32 , prev_payload_offset ) ;
offset = prev_payload_offset ;
depth = payload_len ;
if ( ud - > flags & DETECT_URICONTENT_DISTANCE ) {
if ( ud - > distance < 0 & & ( uint32_t ) ( abs ( ud - > distance ) ) > offset )
offset = 0 ;
else
offset + = ud - > distance ;
SCLogDebug ( " ud->distance % " PRIi32 " , offset % " PRIu32 " , depth % " PRIu32 ,
ud - > distance , offset , depth ) ;
}
if ( ud - > flags & DETECT_URICONTENT_WITHIN ) {
if ( ( int32_t ) depth > ( int32_t ) ( prev_payload_offset + ud - > within ) ) {
depth = prev_payload_offset + ud - > within ;
}
SCLogDebug ( " ud->within % " PRIi32 " , prev_payload_offset % " PRIu32 " , depth % " PRIu32 ,
ud - > within , prev_payload_offset , depth ) ;
}
if ( ud - > depth ! = 0 ) {
if ( ( ud - > depth + prev_payload_offset ) < depth ) {
depth = prev_payload_offset + ud - > depth ;
}
SCLogDebug ( " ud->depth % " PRIu32 " , depth % " PRIu32 , ud - > depth , depth ) ;
}
if ( ud - > offset > offset ) {
offset = ud - > offset ;
SCLogDebug ( " setting offset % " PRIu32 , offset ) ;
}
} else { /* implied no relative matches */
/* set depth */
if ( ud - > depth ! = 0 ) {
depth = ud - > depth ;
}
/* set offset */
offset = ud - > offset ;
prev_payload_offset = 0 ;
}
/* update offset with prev_offset if we're searching for
* matches after the first occurence . */
SCLogDebug ( " offset % " PRIu32 " , prev_offset % " PRIu32 , prev_offset , depth ) ;
if ( prev_offset ! = 0 )
offset = prev_offset ;
SCLogDebug ( " offset % " PRIu32 " , depth % " PRIu32 , offset , depth ) ;
if ( depth > payload_len )
depth = payload_len ;
/* if offset is bigger than depth we can never match on a pattern.
* We can however , " match " on a negated pattern . */
if ( offset > depth | | depth = = 0 ) {
if ( ud - > flags & DETECT_URICONTENT_NEGATED ) {
goto match ;
} else {
SCReturnInt ( 0 ) ;
}
}
uint8_t * spayload = payload + offset ;
uint32_t spayload_len = depth - offset ;
uint32_t match_offset = 0 ;
SCLogDebug ( " spayload_len % " PRIu32 , spayload_len ) ;
BUG_ON ( spayload_len > payload_len ) ;
//PrintawDataFp(stdout,ud->uricontent,ud->uricontent_len);
/* do the actual search with boyer moore precooked ctx */
if ( ud - > flags & DETECT_URICONTENT_NOCASE )
found = BoyerMooreNocase ( ud - > uricontent , ud - > uricontent_len , spayload , spayload_len , ud - > bm_ctx - > bmGs , ud - > bm_ctx - > bmBc ) ;
else
found = BoyerMoore ( ud - > uricontent , ud - > uricontent_len , spayload , spayload_len , ud - > bm_ctx - > bmGs , ud - > bm_ctx - > bmBc ) ;
/* next we evaluate the result in combination with the
* negation flag . */
SCLogDebug ( " found %p ud negated %s " , found , ud - > flags & DETECT_URICONTENT_NEGATED ? " true " : " false " ) ;
if ( found = = NULL & & ! ( ud - > flags & DETECT_URICONTENT_NEGATED ) ) {
SCReturnInt ( 0 ) ;
} else if ( found = = NULL & & ud - > flags & DETECT_URICONTENT_NEGATED ) {
goto match ;
} else if ( found ! = NULL & & ud - > flags & DETECT_URICONTENT_NEGATED ) {
/* why are we saving match offset here? */
match_offset = ( uint32_t ) ( ( found - payload ) + ud - > uricontent_len ) ;
SCLogDebug ( " uricontent % " PRIu32 " matched at offset % " PRIu32 " , but negated so no match " , ud - > id , match_offset ) ;
SCReturnInt ( 0 ) ;
} else {
match_offset = ( uint32_t ) ( ( found - payload ) + ud - > uricontent_len ) ;
SCLogDebug ( " uricontent % " PRIu32 " matched at offset % " PRIu32 " " , ud - > id , match_offset ) ;
det_ctx - > payload_offset = match_offset ;
if ( ! ( ud - > flags & DETECT_URICONTENT_RELATIVE_NEXT ) ) {
SCLogDebug ( " no relative match coming up, so this is a match " ) ;
goto match ;
}
BUG_ON ( sm - > next = = NULL ) ;
SCLogDebug ( " uricontent % " PRIu32 , ud - > id ) ;
/* see if the next payload keywords match. If not, we will
* search for another occurence of this uricontent and see
* if the others match then until we run out of matches */
int r = DoInspectPacketUri ( de_ctx , det_ctx , s , sm - > next , payload , payload_len ) ;
if ( r = = 1 ) {
SCReturnInt ( 1 ) ;
}
/* set the previous match offset to the start of this match + 1 */
prev_offset = ( match_offset - ( ud - > uricontent_len - 1 ) ) ;
SCLogDebug ( " trying to see if there is another match after prev_offset % " PRIu32 , prev_offset ) ;
}
} while ( 1 ) ;
} else if ( sm - > type = = DETECT_PCRE ) {
SCLogDebug ( " inspecting pcre " ) ;
int r = DetectPcrePayloadMatch ( det_ctx , s , sm , /* no packet */ NULL ,
NULL , payload , payload_len ) ;
/* PrintRawDataFp(stdout, payload, payload_len); */
if ( r = = 1 ) {
goto match ;
}
SCReturnInt ( 0 ) ;
} else if ( sm - > type = = DETECT_AL_URILEN ) {
SCLogDebug ( " inspecting uri len " ) ;
int r = 0 ;
DetectUrilenData * urilend = ( DetectUrilenData * ) sm - > ctx ;
switch ( urilend - > mode ) {
case DETECT_URILEN_EQ :
if ( payload_len = = urilend - > urilen1 )
r = 1 ;
break ;
case DETECT_URILEN_LT :
if ( payload_len < urilend - > urilen1 )
r = 1 ;
break ;
case DETECT_URILEN_GT :
if ( payload_len > urilend - > urilen1 )
r = 1 ;
break ;
case DETECT_URILEN_RA :
if ( payload_len > urilend - > urilen1 & &
payload_len < urilend - > urilen2 )
r = 1 ;
break ;
}
if ( r = = 1 ) {
goto match ;
}
SCReturnInt ( 0 ) ;
} else {
/* we should never get here, but bail out just in case */
BUG_ON ( 1 ) ;
}
SCReturnInt ( 0 ) ;
match :
/* this sigmatch matched, inspect the next one. If it was the last,
* the payload portion of the signature matched . */
if ( sm - > next ! = NULL ) {
int r = DoInspectPacketUri ( de_ctx , det_ctx , s , sm - > next , payload ,
payload_len ) ;
SCReturnInt ( r ) ;
} else {
SCReturnInt ( 1 ) ;
}
}
/** \brief Do the content inspection & validation for a signature
*
* \ param de_ctx Detection engine context
* \ param det_ctx Detection engine thread context
* \ param s Signature to inspect
* \ param sm SigMatch to inspect
* \ param f Flow
* \ param flags app layer flags
* \ param state App layer state
*
* \ retval 0 no match
* \ retval 1 match
*/
int DetectEngineInspectPacketUris ( DetectEngineCtx * de_ctx ,
DetectEngineThreadCtx * det_ctx , Signature * s , Flow * f , uint8_t flags ,
void * alstate )
{
SCEnter ( ) ;
SigMatch * sm = NULL ;
int r = 0 ;
HtpState * htp_state = NULL ;
htp_state = ( HtpState * ) alstate ;
if ( htp_state = = NULL ) {
SCLogDebug ( " no HTTP state " ) ;
SCReturnInt ( 0 ) ;
}
/* locking the flow, we will inspect the htp state */
SCMutexLock ( & f - > m ) ;
if ( htp_state - > connp = = NULL ) {
SCLogDebug ( " HTP state has no connp " ) ;
goto end ;
}
det_ctx - > de_have_httpuri = TRUE ;
/* If we have the uricontent multi pattern matcher signatures in
signature list , then search the received HTTP uri ( s ) in the htp
state against those patterns */
if ( s - > flags & SIG_FLAG_MPM_URI ) {
if ( det_ctx - > de_mpm_scanned_uri = = FALSE ) {
uint32_t cnt = DetectUricontentInspectMpm ( det_ctx , f , htp_state ) ;
/* only consider uri sigs if we've seen at least one match */
/** \warning when we start supporting negated uri content matches
* we need to update this check as well */
if ( cnt < = 0 ) {
det_ctx - > de_have_httpuri = FALSE ;
}
SCLogDebug ( " uricontent cnt % " PRIu32 " " , cnt ) ;
/* make sure we don't inspect this mpm again */
det_ctx - > de_mpm_scanned_uri = TRUE ;
}
}
/* if we don't have a uri, don't bother inspecting */
if ( det_ctx - > de_have_httpuri = = FALSE ) {
SCLogDebug ( " We don't have uri " ) ;
goto end ;
}
if ( ( s - > flags & SIG_FLAG_MPM_URI ) & & ( det_ctx - > de_mpm_scanned_uri = = TRUE ) ) {
if ( det_ctx - > pmq . pattern_id_bitarray ! = NULL ) {
/* filter out sigs that want pattern matches, but
* have no matches */
if ( ! ( det_ctx - > pmq . pattern_id_bitarray [ ( s - > mpm_uripattern_id / 8 ) ] & ( 1 < < ( s - > mpm_uripattern_id % 8 ) ) ) & &
( s - > flags & SIG_FLAG_MPM_URI ) & & ! ( s - > flags & SIG_FLAG_MPM_URI_NEG ) ) {
SCLogDebug ( " mpm sig without matches (pat id % " PRIu32
" check in uri). " , s - > mpm_uripattern_id ) ;
goto end ;
}
}
}
sm = s - > umatch ;
det_ctx - > payload_offset = 0 ;
# ifdef DEBUG
DetectUricontentData * co = ( DetectUricontentData * ) sm - > ctx ;
SCLogDebug ( " co->id % " PRIu32 , co - > id ) ;
# endif
size_t idx = AppLayerTransactionGetInspectId ( f ) ;
htp_tx_t * tx = NULL ;
for ( ; idx < list_size ( htp_state - > connp - > conn - > transactions ) ; idx + + )
{
tx = list_get ( htp_state - > connp - > conn - > transactions , idx ) ;
if ( tx = = NULL | | tx - > request_uri_normalized = = NULL )
continue ;
/* Inspect all the uricontents fetched on each
* transaction at the app layer */
r = DoInspectPacketUri ( de_ctx , det_ctx , s , s - > umatch ,
( uint8_t * ) bstr_ptr ( tx - > request_uri_normalized ) ,
bstr_len ( tx - > request_uri_normalized ) ) ;
if ( r = = 1 ) {
break ;
}
}
if ( r < 1 )
r = 0 ;
end :
SCMutexUnlock ( & f - > m ) ;
SCReturnInt ( r ) ;
}
/***********************************Unittests**********************************/
# ifdef UNITTESTS
/** \test Test a simple uricontent option */
static int UriTestSig01 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /one HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test uricontent option \" ; "
" uricontent:one; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test the pcre /U option */
static int UriTestSig02 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /on HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /one HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test pcre /U option \" ; "
" pcre:/one/U; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted with payload2, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert, but it should: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test the pcre /U option */
static int UriTestSig03 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /one HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test pcre /U option \" ; "
" pcre:/blah/U; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test the urilen option */
static int UriTestSig04 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /one HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test urilen option \" ; "
" urilen:>20; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test the urilen option */
static int UriTestSig05 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /one HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test urilen option \" ; "
" urilen:>4; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert with payload2, but it should: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test the pcre /U option */
static int UriTestSig06 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /oneoneoneone HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test pcre /U option \" ; "
" pcre:/(oneself)+/U; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert on payload2, but it should: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test the pcre /U option in combination with urilen */
static int UriTestSig07 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /oneoneoneone HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneoneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test pcre /U option with urilen \" ; "
" pcre:/(one){2,}(self)?/U; urilen:3<>20; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert, but it should: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert with payload2, but it should: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test the pcre /U option in combination with urilen */
static int UriTestSig08 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /oneoneoneone HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneoneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test pcre /U option with urilen \" ; "
" pcre:/(blabla){2,}(self)?/U; urilen:3<>20; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test the pcre /U option in combination with urilen */
static int UriTestSig09 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /oneoneoneone HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneoneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test pcre /U option with urilen \" ; "
" pcre:/(one){2,}(self)?/U; urilen:<2; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test the uricontent option in combination with urilen */
static int UriTestSig10 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /oneoneoneone HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneoneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test uricontent with urilen option \" ; "
" uricontent:one; urilen:<2; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test content, uricontent, urilen, pcre /U options */
static int UriTestSig11 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /oneoneoneone HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneoneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test content, uricontent, pcre /U and urilen options \" ; "
" content:one; uricontent:one; pcre:/(one){2,}(self)?/U; "
" urilen:<2; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test uricontent, urilen, pcre /U options */
static int UriTestSig12 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /oneoneoneone HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneoneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test pcre /U, uricontent and urilen option \" ; "
" uricontent:one; "
" pcre:/(one)+self/U; urilen:>2; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert with payload2, but it should: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test uricontent, urilen */
static int UriTestSig13 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /one HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test urilen option \" ; "
" urilen:>2; uricontent:one; sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert with pkt, but it should: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert with payload2, but it should: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test uricontent, pcre /U */
static int UriTestSig14 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /one HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test uricontent option \" ; "
" uricontent:one; pcre:/one(self)?/U;sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert with pkt, but it should: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert with payload2, but it should: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test pcre /U with anchored regex (bug 155) */
static int UriTestSig15 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /one HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /oneself HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Test uricontent option \" ; "
" uricontent:one; pcre:/^ \\ /one(self)?$/U;sid:1;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert with pkt, but it should: " ) ;
goto end ;
}
DetectEngineStateReset ( f . de_state ) ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 didnt alert with payload2, but it should: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/** \test Test pcre /U with anchored regex (bug 155) */
static int UriTestSig16 ( void )
{
int result = 0 ;
Flow f ;
HtpState * http_state = NULL ;
uint8_t http_buf1 [ ] = " POST /search?q=123&aq=7123abcee HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0/ \r \n "
" Host: 1.2.3.4 \r \n \r \n " ;
uint32_t http_buf1_len = sizeof ( http_buf1 ) - 1 ;
uint8_t http_buf2 [ ] = " POST /search?q=123&aq=7123abcee HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n "
" Cookie: hellocatch \r \n \r \n " ;
uint32_t http_buf2_len = sizeof ( http_buf2 ) - 1 ;
TcpSession ssn ;
Packet p ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf1 ;
p . payload_len = http_buf1_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
s = de_ctx - > sig_list = SigInit ( de_ctx , " drop tcp any any -> any any (msg: \" ET TROJAN Downadup/Conficker A or B Worm reporting \" ; flow:to_server,established; uricontent: \" /search?q= \" ; pcre: \" /^ \\ /search \\ ?q=[0-9]{1,3}(&aq=7( \\ ?[0-9a-f]{8})?)?/U \" ; pcre: \" / \\ x0d \\ x0aHost \\ : \\ d+ \\ . \\ d+ \\ . \\ d+ \\ . \\ d+ \\ x0d \\ x0a/ \" ; reference:url,www.f-secure.com/weblog/archives/00001584.html; reference:url,doc.emergingthreats.net/bin/view/Main/2009024; reference:url,www.emergingthreats.net/cgi-bin/cvsweb.cgi/sigs/VIRUS/TROJAN_Conficker; sid:2009024; rev:9;) " ) ;
if ( s = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf1 , http_buf1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 2009024 ) ) {
printf ( " sig 1 didnt alert with pkt, but it should: " ) ;
goto end ;
}
p . alerts . cnt = 0 ;
DetectEngineStateReset ( f . de_state ) ;
p . payload = http_buf2 ;
p . payload_len = http_buf2_len ;
r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf2 , http_buf2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( PacketAlertCheck ( & p , 2009024 ) ) {
printf ( " sig 1 alerted, but it should not (host should not match): " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/**
* \ test Test multiple relative contents
*/
static int UriTestSig17 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /now_this_is_is_big_big_string_now HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n " ;
uint32_t http_buf_len = strlen ( ( char * ) http_buf ) ;
Flow f ;
TcpSession ssn ;
HtpState * http_state = NULL ;
Packet p ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf ;
p . payload_len = http_buf_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" test multiple relative uricontents \" ; "
" uricontent:this; uricontent:is; within:6; "
" uricontent:big; within:8; "
" uricontent:string; within:8; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf , http_buf_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/**
* \ test Test multiple relative contents
*/
static int UriTestSig18 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /now_this_is_is_is_big_big_big_string_now HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n " ;
uint32_t http_buf_len = strlen ( ( char * ) http_buf ) ;
Flow f ;
TcpSession ssn ;
HtpState * http_state = NULL ;
Packet p ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf ;
p . payload_len = http_buf_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" test multiple relative uricontents \" ; "
" uricontent:this; uricontent:is; within:9; "
" uricontent:big; within:12; "
" uricontent:string; within:8; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf , http_buf_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/**
* \ test Test multiple relative contents
*/
static int UriTestSig19 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /this_this_now_is_is_____big_string_now HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n " ;
uint32_t http_buf_len = strlen ( ( char * ) http_buf ) ;
Flow f ;
TcpSession ssn ;
HtpState * http_state = NULL ;
Packet p ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf ;
p . payload_len = http_buf_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" test multiple relative uricontents \" ; "
" uricontent:now; uricontent:this; "
" uricontent:is; within:12; "
" uricontent:big; within:8; "
" uricontent:string; within:8; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf , http_buf_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
/**
* \ test Test multiple relative contents with offset
*/
static int UriTestSig20 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /_________thus_thus_is_a_big HTTP/1.0 \r \n "
" User-Agent: Mozilla/1.0 \r \n " ;
uint32_t http_buf_len = strlen ( ( char * ) http_buf ) ;
Flow f ;
TcpSession ssn ;
HtpState * http_state = NULL ;
Packet p ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & p , 0 , sizeof ( Packet ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p . src . family = AF_INET ;
p . dst . family = AF_INET ;
p . payload = http_buf ;
p . payload_len = http_buf_len ;
p . proto = IPPROTO_TCP ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . src . family = AF_INET ;
f . dst . family = AF_INET ;
p . flow = & f ;
p . flowflags | = FLOW_PKT_TOSERVER ;
p . flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
FlowL7DataPtrInit ( & f ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > mpm_matcher = MPM_B2G ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" test multiple relative uricontents \" ; "
" uricontent:thus; offset:8; "
" uricontent:is; within:6; "
" uricontent:big; within:8; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & tv , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf , http_buf_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
http_state = f . aldata [ AlpGetStateIdx ( ALPROTO_HTTP ) ] ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & tv , de_ctx , det_ctx , & p ) ;
if ( ! PacketAlertCheck ( & p , 1 ) ) {
printf ( " sig 1 alerted, but it should not: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL )
DetectEngineThreadCtxDeinit ( & tv , det_ctx ) ;
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
return result ;
}
# endif /* UNITTESTS */
void UriRegisterTests ( void )
{
# ifdef UNITTESTS
UtRegisterTest ( " UriTestSig01 " , UriTestSig01 , 1 ) ;
UtRegisterTest ( " UriTestSig02 " , UriTestSig02 , 1 ) ;
UtRegisterTest ( " UriTestSig03 " , UriTestSig03 , 1 ) ;
UtRegisterTest ( " UriTestSig04 " , UriTestSig04 , 1 ) ;
UtRegisterTest ( " UriTestSig05 " , UriTestSig05 , 1 ) ;
UtRegisterTest ( " UriTestSig06 " , UriTestSig06 , 1 ) ;
UtRegisterTest ( " UriTestSig07 " , UriTestSig07 , 1 ) ;
UtRegisterTest ( " UriTestSig08 " , UriTestSig08 , 1 ) ;
UtRegisterTest ( " UriTestSig09 " , UriTestSig09 , 1 ) ;
UtRegisterTest ( " UriTestSig10 " , UriTestSig10 , 1 ) ;
UtRegisterTest ( " UriTestSig11 " , UriTestSig11 , 1 ) ;
UtRegisterTest ( " UriTestSig12 " , UriTestSig12 , 1 ) ;
UtRegisterTest ( " UriTestSig13 " , UriTestSig13 , 1 ) ;
UtRegisterTest ( " UriTestSig14 " , UriTestSig14 , 1 ) ;
UtRegisterTest ( " UriTestSig15 " , UriTestSig15 , 1 ) ;
UtRegisterTest ( " UriTestSig16 " , UriTestSig16 , 1 ) ;
UtRegisterTest ( " UriTestSig17 " , UriTestSig17 , 1 ) ;
UtRegisterTest ( " UriTestSig18 " , UriTestSig18 , 1 ) ;
UtRegisterTest ( " UriTestSig19 " , UriTestSig19 , 1 ) ;
UtRegisterTest ( " UriTestSig20 " , UriTestSig20 , 1 ) ;
# endif /* UNITTESTS */
return ;
}