/* 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 "detect-byte-extract.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 ( ) ;
det_ctx - > inspection_recursion_counter + + ;
if ( det_ctx - > inspection_recursion_counter = = de_ctx - > inspection_recursion_limit ) {
det_ctx - > discontinue_matching = 1 ;
SCReturnInt ( 0 ) ;
}
if ( sm = = NULL ) {
SCReturnInt ( 0 ) ;
}
if ( sm - > type = = DETECT_URICONTENT ) {
if ( payload_len = = 0 ) {
SCReturnInt ( 0 ) ;
}
DetectContentData * ud = NULL ;
ud = ( DetectContentData * ) sm - > ctx ;
SCLogDebug ( " inspecting content % " PRIu32 " payload_len % " PRIu32 , ud - > id , payload_len ) ;
//if (ud->flags & DETECT_CONTENT_URI_MPM && !(ud->flags & DETECT_CONTENT_NEGATED))
// goto match;
/* rule parsers should take care of this */
# ifdef DEBUG
BUG_ON ( ud - > depth ! = 0 & & ud - > depth < = ud - > offset ) ;
# endif
/* 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_CONTENT_DISTANCE | |
ud - > flags & DETECT_CONTENT_WITHIN ) {
SCLogDebug ( " prev_payload_offset % " PRIu32 , prev_payload_offset ) ;
offset = prev_payload_offset ;
depth = payload_len ;
int distance = ud - > distance ;
if ( ud - > flags & DETECT_CONTENT_DISTANCE ) {
if ( ud - > flags & DETECT_CONTENT_DISTANCE_BE ) {
distance = det_ctx - > bj_values [ ud - > distance ] ;
}
if ( distance < 0 & & ( uint32_t ) ( abs ( distance ) ) > offset )
offset = 0 ;
else
offset + = distance ;
SCLogDebug ( " ud->distance % " PRIi32 " , offset % " PRIu32 " , depth % " PRIu32 ,
distance , offset , depth ) ;
}
if ( ud - > flags & DETECT_CONTENT_WITHIN ) {
if ( ud - > flags & DETECT_CONTENT_WITHIN_BE ) {
if ( ( int32_t ) depth > ( int32_t ) ( prev_payload_offset + det_ctx - > bj_values [ ud - > within ] + distance ) ) {
depth = prev_payload_offset + det_ctx - > bj_values [ ud - > within ] + distance ;
}
} else {
if ( ( int32_t ) depth > ( int32_t ) ( prev_payload_offset + ud - > within + distance ) ) {
depth = prev_payload_offset + ud - > within + distance ;
}
SCLogDebug ( " ud->within % " PRIi32 " , prev_payload_offset % " PRIu32 " , depth % " PRIu32 ,
ud - > within , prev_payload_offset , depth ) ;
}
}
if ( ud - > flags & DETECT_CONTENT_DEPTH_BE ) {
if ( ( det_ctx - > bj_values [ ud - > depth ] + prev_payload_offset ) < depth ) {
depth = prev_payload_offset + det_ctx - > bj_values [ ud - > depth ] ;
}
} else {
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 - > flags & DETECT_CONTENT_OFFSET_BE ) {
if ( det_ctx - > bj_values [ ud - > offset ] > offset )
offset = det_ctx - > bj_values [ ud - > offset ] ;
} else {
if ( ud - > offset > offset ) {
offset = ud - > offset ;
SCLogDebug ( " setting offset % " PRIu32 , offset ) ;
}
}
} else { /* implied no relative matches */
/* set depth */
if ( ud - > flags & DETECT_CONTENT_DEPTH_BE ) {
depth = det_ctx - > bj_values [ ud - > depth ] ;
} else {
if ( ud - > depth ! = 0 ) {
depth = ud - > depth ;
}
}
/* set offset */
if ( ud - > flags & DETECT_CONTENT_OFFSET_BE )
offset = det_ctx - > bj_values [ ud - > offset ] ;
else
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_CONTENT_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 ) ;
# ifdef DEBUG
BUG_ON ( spayload_len > payload_len ) ;
# endif
//PrintRawDataFp(stdout,ud->content,ud->content_len);
/* If we got no matches from the mpm, avoid searching (just check if negated) */
//if (det_ctx->de_have_httpuri == TRUE) {
/* do the actual search with boyer moore precooked ctx */
if ( ud - > flags & DETECT_CONTENT_NOCASE )
found = BoyerMooreNocase ( ud - > content , ud - > content_len , spayload , spayload_len , ud - > bm_ctx - > bmGs , ud - > bm_ctx - > bmBc ) ;
else
found = BoyerMoore ( ud - > content , ud - > content_len , spayload , spayload_len , ud - > bm_ctx - > bmGs , ud - > bm_ctx - > bmBc ) ;
//} else {
// found = NULL;
//}
/* next we evaluate the result in combination with the
* negation flag . */
SCLogDebug ( " found %p ud negated %s " , found , ud - > flags & DETECT_CONTENT_NEGATED ? " true " : " false " ) ;
if ( found = = NULL & & ! ( ud - > flags & DETECT_CONTENT_NEGATED ) ) {
SCReturnInt ( 0 ) ;
} else if ( found = = NULL & & ud - > flags & DETECT_CONTENT_NEGATED ) {
goto match ;
} else if ( found ! = NULL & & ud - > flags & DETECT_CONTENT_NEGATED ) {
SCLogDebug ( " uricontent % " PRIu32 " matched at offset % " PRIu32 " , but negated so no match " , ud - > id , match_offset ) ;
det_ctx - > discontinue_matching = 1 ;
SCReturnInt ( 0 ) ;
} else {
match_offset = ( uint32_t ) ( ( found - payload ) + ud - > content_len ) ;
SCLogDebug ( " uricontent % " PRIu32 " matched at offset % " PRIu32 " " , ud - > id , match_offset ) ;
det_ctx - > payload_offset = match_offset ;
if ( ! ( ud - > flags & DETECT_CONTENT_RELATIVE_NEXT ) ) {
SCLogDebug ( " no relative match coming up, so this is a match " ) ;
goto match ;
}
/* bail out if we have no next match. Technically this is an
* error , as the current cd has the DETECT_CONTENT_RELATIVE_NEXT
* flag set . */
if ( sm - > next = = NULL ) {
SCReturnInt ( 0 ) ;
}
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 ) ;
}
if ( det_ctx - > discontinue_matching )
SCReturnInt ( 0 ) ;
/* set the previous match offset to the start of this match + 1 */
prev_offset = ( match_offset - ( ud - > content_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 " ) ;
DetectPcreData * pe = ( DetectPcreData * ) sm - > ctx ;
uint32_t prev_payload_offset = det_ctx - > payload_offset ;
uint32_t prev_offset = 0 ;
int r = 0 ;
det_ctx - > pcre_match_start_offset = 0 ;
do {
r = DetectPcrePayloadMatch ( det_ctx , s , sm , NULL , NULL ,
payload , payload_len ) ;
if ( r = = 0 ) {
det_ctx - > discontinue_matching = 1 ;
SCReturnInt ( 0 ) ;
}
if ( ! ( pe - > flags & DETECT_PCRE_RELATIVE_NEXT ) ) {
SCLogDebug ( " no relative match coming up, so this is a match " ) ;
goto match ;
}
/* save it, in case we need to do a pcre match once again */
prev_offset = det_ctx - > pcre_match_start_offset ;
/* see if the next payload keywords match. If not, we will
* search for another occurence of this pcre and see
* if the others match , until we run out of matches */
r = DoInspectPacketUri ( de_ctx , det_ctx , s , sm - > next ,
payload , payload_len ) ;
if ( r = = 1 ) {
SCReturnInt ( 1 ) ;
}
if ( det_ctx - > discontinue_matching )
SCReturnInt ( 0 ) ;
det_ctx - > payload_offset = prev_payload_offset ;
det_ctx - > pcre_match_start_offset = prev_offset ;
} while ( 1 ) ;
} else if ( sm - > type = = DETECT_ISDATAAT ) {
SCLogDebug ( " inspecting isdataat " ) ;
DetectIsdataatData * id = ( DetectIsdataatData * ) sm - > ctx ;
if ( id - > flags & ISDATAAT_RELATIVE ) {
if ( det_ctx - > payload_offset + id - > dataat > payload_len ) {
SCLogDebug ( " det_ctx->payload_offset + id->dataat % " PRIu32 " > % " PRIu32 , det_ctx - > payload_offset + id - > dataat , payload_len ) ;
if ( id - > flags & ISDATAAT_NEGATED )
goto match ;
SCReturnInt ( 0 ) ;
} else {
SCLogDebug ( " relative isdataat match " ) ;
if ( id - > flags & ISDATAAT_NEGATED )
SCReturnInt ( 0 ) ;
goto match ;
}
} else {
if ( id - > dataat < payload_len ) {
SCLogDebug ( " absolute isdataat match " ) ;
if ( id - > flags & ISDATAAT_NEGATED )
SCReturnInt ( 0 ) ;
goto match ;
} else {
SCLogDebug ( " absolute isdataat mismatch, id->isdataat % " PRIu32 " , payload_len % " PRIu32 " " , id - > dataat , payload_len ) ;
if ( id - > flags & ISDATAAT_NEGATED )
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 if ( sm - > type = = DETECT_BYTE_EXTRACT ) {
DetectByteExtractData * bed = ( DetectByteExtractData * ) sm - > ctx ;
if ( DetectByteExtractDoMatch ( det_ctx , sm , s , payload ,
payload_len ,
& det_ctx - > bj_values [ bed - > local_id ] ,
bed - > endian ) ! = 1 ) {
SCReturnInt ( 0 ) ;
}
goto match ;
} else {
/* we should never get here, but bail out just in case */
SCLogDebug ( " sm->type %u " , sm - > type ) ;
# ifdef DEBUG
BUG_ON ( 1 ) ;
# endif
}
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 ( ) ;
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 | | htp_state - > connp - > conn = = NULL ) {
SCLogDebug ( " HTP state has no conn(p) " ) ;
goto end ;
}
# ifdef DEBUG
SigMatch * sm = s - > sm_lists [ DETECT_SM_LIST_UMATCH ] ;
DetectContentData * co = ( DetectContentData * ) 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 ;
det_ctx - > discontinue_matching = 0 ;
det_ctx - > payload_offset = 0 ;
det_ctx - > inspection_recursion_counter = 0 ;
//PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized),
// bstr_len(tx->request_uri_normalized));
/* Inspect all the uricontents fetched on each
* transaction at the app layer */
r = DoInspectPacketUri ( de_ctx , det_ctx , s , s - > sm_lists [ DETECT_SM_LIST_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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
Signature * s = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf1 , http_buf1_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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/ \" ; 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 . alstate ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
/**
* \ test Test multiple relative contents with a negated content .
*/
static int UriTestSig21 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /we_need_to_fix_this_and_yes_fix_this_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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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: \" fix \" ; uricontent: \" this \" ; within:6; "
" uricontent:! \" and \" ; distance:0; 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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
/**
* \ test Test relative pcre .
*/
static int UriTestSig22 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /this_is_a_super_duper_ "
" nova_in_super_nova_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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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 \" ; "
" pcre:/super/U; uricontent: \" nova \" ; within:7; 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 . alstate ;
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 didn't alert, but it should have: " ) ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
/**
* \ test Test multiple relative contents with a negated content .
*/
static int UriTestSig23 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /we_need_to_fix_this_and_yes_fix_this_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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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:! \" fix_this_now \" ; 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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
/**
* \ test Test multiple relative contents with a negated content .
*/
static int UriTestSig24 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /we_need_to_fix_this_and_yes_fix_this_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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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: \" we_need_to \" ; uricontent:! \" fix_this_now \" ; 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 . alstate ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
/**
* \ test Test normalized uricontents .
*/
static int UriTestSig25 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /normalized%20uri "
" 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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
StreamTcpInitConfig ( TRUE ) ;
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 \" ; "
" pcre:/normalized/U; uricontent: \" normalized uri \" ; 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 . alstate ;
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 didn't alert, but it should have: " ) ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
/**
* \ test Test multiple relative contents with a negated content .
*/
static int UriTestSig26 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /we_need_to_fix_this_and_yes_fix_this_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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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: \" fix_this \" ; isdataat:4,relative; 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 . alstate ;
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 didn't alert, but it should have: " ) ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
/**
* \ test Test multiple relative contents with a negated content .
*/
static int UriTestSig27 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /we_need_to_fix_this_and_yes_fix_this_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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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: \" fix_this \" ; isdataat:!10,relative; 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 . alstate ;
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 didn't alert, but it should have: " ) ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
static int UriTestSig28 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /this_b5ig_string_now_in_http 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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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: \" dummy \" ; "
" uricontent: \" this \" ; "
" byte_extract:1,2,one,string,dec,relative; "
" uricontent: \" ring \" ; distance:one; 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 . alstate ;
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 didn't alert, but should have: " ) ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
static int UriTestSig29 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /this_b5ig_string_now_in_http 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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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: \" dummy \" ; "
" uricontent: \" this \" ; "
" byte_extract:1,2,one,string,dec,relative; "
" uricontent: \" ring \" ; distance:one; 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 . alstate ;
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 didn't alert, but should have: " ) ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
static int UriTestSig30 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /this_b5ig_string_now_in_http 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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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: \" dummy \" ; "
" uricontent: \" this \" ; "
" byte_extract:1,2,one,string,dec,relative; "
" uricontent: \" _b5ig \" ; offset:one; 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 . alstate ;
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 didn't alert, but should have: " ) ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
static int UriTestSig31 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /this_b5ig_string_now_in_http 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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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: \" dummy \" ; "
" uricontent: \" this \" ; "
" byte_extract:1,2,one,string,dec,relative; "
" uricontent: \" his \" ; depth:one; 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 . alstate ;
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 didn't alert, but should have: " ) ;
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 ) ;
UTHFreePacket ( p ) ;
return result ;
}
static int UriTestSig32 ( void )
{
int result = 0 ;
uint8_t * http_buf = ( uint8_t * ) " POST /this_b5ig_string_now_in_http 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 = NULL ;
ThreadVars tv ;
DetectEngineThreadCtx * det_ctx = NULL ;
memset ( & tv , 0 , sizeof ( ThreadVars ) ) ;
memset ( & f , 0 , sizeof ( Flow ) ) ;
memset ( & ssn , 0 , sizeof ( TcpSession ) ) ;
p = UTHBuildPacket ( http_buf , http_buf_len , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
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: \" dummy \" ; "
" uricontent: \" this \" ; "
" byte_extract:1,2,one,string,dec,relative; "
" uricontent: \" g_st \" ; within:one; 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 . alstate ;
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 didn't alert, but should have: " ) ;
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 ) ;
UTHFreePacket ( p ) ;
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 ) ;
UtRegisterTest ( " UriTestSig21 " , UriTestSig21 , 1 ) ;
UtRegisterTest ( " UriTestSig22 " , UriTestSig22 , 1 ) ;
UtRegisterTest ( " UriTestSig23 " , UriTestSig23 , 1 ) ;
UtRegisterTest ( " UriTestSig24 " , UriTestSig24 , 1 ) ;
UtRegisterTest ( " UriTestSig25 " , UriTestSig25 , 1 ) ;
UtRegisterTest ( " UriTestSig26 " , UriTestSig26 , 1 ) ;
UtRegisterTest ( " UriTestSig27 " , UriTestSig27 , 1 ) ;
UtRegisterTest ( " UriTestSig28 " , UriTestSig28 , 1 ) ;
UtRegisterTest ( " UriTestSig29 " , UriTestSig29 , 1 ) ;
UtRegisterTest ( " UriTestSig30 " , UriTestSig30 , 1 ) ;
UtRegisterTest ( " UriTestSig31 " , UriTestSig31 , 1 ) ;
UtRegisterTest ( " UriTestSig32 " , UriTestSig32 , 1 ) ;
# endif /* UNITTESTS */
return ;
}