/* Copyright (C) 2007-2012 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 .
*/
/**
* \ ingroup httplayer
*
* @ {
*/
/**
* \ file
*
* \ author Anoop Saldanha < anoopsaldanha @ gmail . com >
*
* Implements support for the http_user_agent keyword .
*/
# include "suricata-common.h"
# include "threads.h"
# include "decode.h"
# include "detect.h"
# include "detect-parse.h"
# include "detect-engine.h"
# include "detect-engine-mpm.h"
# include "detect-engine-state.h"
# include "detect-content.h"
# include "detect-pcre.h"
# include "flow.h"
# include "flow-var.h"
# include "flow-util.h"
# include "util-debug.h"
# include "util-unittest.h"
# include "util-unittest-helper.h"
# include "util-spm.h"
# include "app-layer.h"
# include "app-layer-htp.h"
# include "stream-tcp.h"
# include "detect-http-ua.h"
int DetectHttpUASetup ( DetectEngineCtx * , Signature * , char * ) ;
void DetectHttpUARegisterTests ( void ) ;
void DetectHttpUAFree ( void * ) ;
/**
* \ brief Registers the keyword handlers for the " http_user_agent " keyword .
*/
void DetectHttpUARegister ( void )
{
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . name = " http_user_agent " ;
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . desc = " content modifier to match only on the HTTP User-Agent header " ;
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . url = " https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_user_agent " ;
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . Match = NULL ;
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . AppLayerMatch = NULL ;
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . Setup = DetectHttpUASetup ;
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . Free = DetectHttpUAFree ;
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . RegisterTests = DetectHttpUARegisterTests ;
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . alproto = ALPROTO_HTTP ;
sigmatch_table [ DETECT_AL_HTTP_USER_AGENT ] . flags | = SIGMATCH_PAYLOAD ;
return ;
}
/**
* \ brief The setup function for the http_user_agent keyword for a signature .
*
* \ param de_ctx Pointer to the detection engine context .
* \ param s Pointer to the signature for the current Signature being
* parsed from the rules .
* \ param m Pointer to the head of the SigMatch for the current rule
* being parsed .
* \ param arg Pointer to the string holding the keyword value .
*
* \ retval 0 On success
* \ retval - 1 On failure
*/
int DetectHttpUASetup ( DetectEngineCtx * de_ctx , Signature * s , char * arg )
{
DetectContentData * cd = NULL ;
SigMatch * sm = NULL ;
if ( arg ! = NULL & & strcmp ( arg , " " ) ! = 0 ) {
SCLogError ( SC_ERR_INVALID_ARGUMENT , " http_user_agent supplied with args " ) ;
goto error ;
}
sm = SigMatchGetLastSMFromLists ( s , 2 ,
DETECT_CONTENT , s - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] ) ;
/* if we still can't find any previous content keywords, it's an invalid
* rule */
if ( sm = = NULL ) {
SCLogError ( SC_ERR_INVALID_SIGNATURE , " \" http_user_agent \" keyword "
" found inside the rule without a content context. "
" Please use a \" content \" keyword before using the "
" \" http_user_agent \" keyword " ) ;
goto error ;
}
cd = ( DetectContentData * ) sm - > ctx ;
/* http_user_agent should not be used with the rawbytes rule */
if ( cd - > flags & DETECT_CONTENT_RAWBYTES ) {
SCLogError ( SC_ERR_INVALID_SIGNATURE , " http_user_agent rule can not "
" be used with the rawbytes rule keyword " ) ;
goto error ;
}
if ( s - > alproto ! = ALPROTO_UNKNOWN & & s - > alproto ! = ALPROTO_HTTP ) {
SCLogError ( SC_ERR_CONFLICTING_RULE_KEYWORDS , " rule contains a non http "
" alproto set " ) ;
goto error ;
}
if ( s - > flags & SIG_FLAG_TOCLIENT ) {
SCLogError ( SC_ERR_INVALID_SIGNATURE , " http_user_agent can not be used "
" with flow:to_client or flow:from_server. " ) ;
goto error ;
}
if ( ( cd - > flags & DETECT_CONTENT_WITHIN ) | | ( cd - > flags & DETECT_CONTENT_DISTANCE ) ) {
SigMatch * pm = SigMatchGetLastSMFromLists ( s , 4 ,
DETECT_CONTENT , sm - > prev ,
DETECT_PCRE , sm - > prev ) ;
/* pm can be NULL now. To accomodate parsing sigs like -
* content : one ; http_modifier ; content : two ; distance : 0 ; http_modifier */
if ( pm ! = NULL ) {
if ( pm - > type = = DETECT_CONTENT ) {
DetectContentData * tmp_cd = ( DetectContentData * ) pm - > ctx ;
tmp_cd - > flags & = ~ DETECT_CONTENT_RELATIVE_NEXT ;
} else {
DetectPcreData * tmp_pd = ( DetectPcreData * ) pm - > ctx ;
tmp_pd - > flags & = ~ DETECT_PCRE_RELATIVE_NEXT ;
}
} /* if (pm != NULL) */
/* reassigning pm */
pm = SigMatchGetLastSMFromLists ( s , 4 ,
DETECT_CONTENT , s - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] ,
DETECT_PCRE , s - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] ) ;
if ( pm = = NULL ) {
SCLogError ( SC_ERR_INVALID_SIGNATURE , " http_user_agent seen with a "
" distance or within without a previous http_user_agent "
" content. Invalidating signature. " ) ;
goto error ;
}
if ( pm - > type = = DETECT_PCRE ) {
DetectPcreData * tmp_pd = ( DetectPcreData * ) pm - > ctx ;
tmp_pd - > flags | = DETECT_PCRE_RELATIVE_NEXT ;
} else {
DetectContentData * tmp_cd = ( DetectContentData * ) pm - > ctx ;
tmp_cd - > flags | = DETECT_CONTENT_RELATIVE_NEXT ;
}
}
cd - > id = DetectPatternGetId ( de_ctx - > mpm_pattern_id_store , cd , DETECT_SM_LIST_HUADMATCH ) ;
sm - > type = DETECT_CONTENT ;
/* transfer the sm from the pmatch list to huadmatch list */
SigMatchTransferSigMatchAcrossLists ( sm ,
& s - > sm_lists [ DETECT_SM_LIST_PMATCH ] ,
& s - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] ,
& s - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] ,
& s - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] ) ;
/* flag the signature to indicate that we scan the app layer data */
s - > flags | = SIG_FLAG_APPLAYER ;
s - > alproto = ALPROTO_HTTP ;
return 0 ;
error :
return - 1 ;
}
/**
* \ brief The function to free the http_user_agent data .
*
* \ param ptr Pointer to the http_user_agent .
*/
void DetectHttpUAFree ( void * ptr )
{
DetectContentData * huad = ( DetectContentData * ) ptr ;
if ( huad = = NULL )
return ;
if ( huad - > content ! = NULL )
SCFree ( huad - > content ) ;
BoyerMooreCtxDeInit ( huad - > bm_ctx ) ;
SCFree ( huad ) ;
return ;
}
/************************************Unittests*********************************/
# ifdef UNITTESTS
# include "stream-tcp-reassemble.h"
/**
* \ test Test that a signature containting a http_user_agent is correctly parsed
* and the keyword is registered .
*/
static int DetectHttpUATest01 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Testing http_user_agent \" ; "
" content: \" one \" ; http_user_agent; sid:1;) " ) ;
if ( de_ctx - > sig_list ! = NULL ) {
result = 1 ;
} else {
goto end ;
}
end :
SigGroupCleanup ( de_ctx ) ;
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
/**
* \ test Test that a signature containing an valid http_user_agent entry is
* parsed .
*/
static int DetectHttpUATest02 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Testing http_user_agent \" ; "
" content: \" one \" ; http_user_agent:; sid:1;) " ) ;
if ( de_ctx - > sig_list ! = NULL )
result = 1 ;
end :
SigGroupCleanup ( de_ctx ) ;
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
/**
* \ test Test that an invalid signature containing no content but a
* http_user_agent is invalidated .
*/
static int DetectHttpUATest03 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Testing http_user_agent \" ; "
" http_user_agent; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
result = 1 ;
end :
SigGroupCleanup ( de_ctx ) ;
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
/**
* \ test Test that an invalid signature containing a rawbytes along with a
* http_user_agent is invalidated .
*/
static int DetectHttpUATest04 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Testing http_user_agent \" ; "
" content: \" one \" ; rawbytes; http_user_agent; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
result = 1 ;
end :
SigGroupCleanup ( de_ctx ) ;
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
/**
* \ test Test that a http_user_agent with nocase is parsed .
*/
static int DetectHttpUATest05 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (msg: \" Testing http_user_agent \" ; "
" content: \" one \" ; http_user_agent; nocase; sid:1;) " ) ;
if ( de_ctx - > sig_list ! = NULL )
result = 1 ;
end :
SigGroupCleanup ( de_ctx ) ;
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
/**
* \ test Test that the http_user_agent content matches against a http request
* which holds the content .
*/
static int DetectHttpUATest06 ( void )
{
TcpSession ssn ;
Packet * p = NULL ;
ThreadVars th_v ;
DetectEngineCtx * de_ctx = NULL ;
DetectEngineThreadCtx * det_ctx = NULL ;
HtpState * http_state = NULL ;
Flow f ;
uint8_t http_buf [ ] =
" GET /index.html HTTP/1.0 \r \n "
" Host: www.openinfosecfoundation.org \r \n "
" User-Agent: This is dummy message body \r \n "
" Content-Type: text/html \r \n "
" \r \n " ;
uint32_t http_len = sizeof ( http_buf ) - 1 ;
int result = 0 ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & f , 0 , sizeof ( f ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
p = UTHBuildPacket ( NULL , 0 , 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 ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert http any any -> any any "
" (msg: \" http user agent test \" ; "
" content: \" message \" ; http_user_agent; "
" sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
goto end ;
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf , http_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
http_state = f . alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: \n " ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( ! ( PacketAlertCheck ( p , 1 ) ) ) {
printf ( " sid 1 didn't match but should have \n " ) ;
goto end ;
}
result = 1 ;
end :
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
SigCleanSignatures ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
UTHFreePackets ( & p , 1 ) ;
return result ;
}
/**
* \ test Test that the http_user_agent content matches against a http request
* which holds the content .
*/
static int DetectHttpUATest07 ( void )
{
TcpSession ssn ;
Packet * p1 = NULL ;
Packet * p2 = NULL ;
ThreadVars th_v ;
DetectEngineCtx * de_ctx = NULL ;
DetectEngineThreadCtx * det_ctx = NULL ;
HtpState * http_state = NULL ;
Flow f ;
uint8_t http1_buf [ ] =
" GET /index.html HTTP/1.0 \r \n "
" Host: www.openinfosecfoundation.org \r \n "
" User-Agent: This is dummy message " ;
uint8_t http2_buf [ ] =
" body1 \r \n \r \n " ;
uint32_t http1_len = sizeof ( http1_buf ) - 1 ;
uint32_t http2_len = sizeof ( http2_buf ) - 1 ;
int result = 0 ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & f , 0 , sizeof ( f ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
p1 = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
p2 = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p1 - > flow = & f ;
p1 - > flowflags | = FLOW_PKT_TOSERVER ;
p1 - > flowflags | = FLOW_PKT_ESTABLISHED ;
p1 - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p2 - > flow = & f ;
p2 - > flowflags | = FLOW_PKT_TOSERVER ;
p2 - > flowflags | = FLOW_PKT_ESTABLISHED ;
p2 - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert http any any -> any any "
" (msg: \" http user agent test \" ; "
" content: \" message \" ; http_user_agent; "
" sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
goto end ;
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http1_buf , http1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
http_state = f . alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p1 ) ;
if ( PacketAlertCheck ( p1 , 1 ) ) {
printf ( " sid 1 matched on p1 but shouldn't have: " ) ;
goto end ;
}
r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http2_buf , http2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p2 ) ;
if ( ! ( PacketAlertCheck ( p2 , 1 ) ) ) {
printf ( " sid 1 didn't match on p2 but should have: " ) ;
goto end ;
}
result = 1 ;
end :
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
SigCleanSignatures ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
UTHFreePackets ( & p1 , 1 ) ;
UTHFreePackets ( & p2 , 1 ) ;
return result ;
}
/**
* \ test Test that the http_user_agent content matches against a http request
* which holds the content .
*/
static int DetectHttpUATest08 ( void )
{
TcpSession ssn ;
Packet * p1 = NULL ;
Packet * p2 = NULL ;
ThreadVars th_v ;
DetectEngineCtx * de_ctx = NULL ;
DetectEngineThreadCtx * det_ctx = NULL ;
HtpState * http_state = NULL ;
Flow f ;
uint8_t http1_buf [ ] =
" GET /index.html HTTP/1.0 \r \n "
" Host: www.openinfosecfoundation.org \r \n "
" User-Agent: This is dummy mess " ;
uint8_t http2_buf [ ] =
" age body \r \n \r \n " ;
uint32_t http1_len = sizeof ( http1_buf ) - 1 ;
uint32_t http2_len = sizeof ( http2_buf ) - 1 ;
int result = 0 ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & f , 0 , sizeof ( f ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
p1 = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
p2 = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p1 - > flow = & f ;
p1 - > flowflags | = FLOW_PKT_TOSERVER ;
p1 - > flowflags | = FLOW_PKT_ESTABLISHED ;
p1 - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p2 - > flow = & f ;
p2 - > flowflags | = FLOW_PKT_TOSERVER ;
p2 - > flowflags | = FLOW_PKT_ESTABLISHED ;
p2 - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert http any any -> any any "
" (msg: \" http user agent test \" ; "
" content: \" message \" ; http_user_agent; "
" sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
goto end ;
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http1_buf , http1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
http_state = f . alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p1 ) ;
if ( ( PacketAlertCheck ( p1 , 1 ) ) ) {
printf ( " sid 1 didn't match but should have " ) ;
goto end ;
}
r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http2_buf , http2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p2 ) ;
if ( ! ( PacketAlertCheck ( p2 , 1 ) ) ) {
printf ( " sid 1 didn't match but should have " ) ;
goto end ;
}
result = 1 ;
end :
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
SigCleanSignatures ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
UTHFreePackets ( & p1 , 1 ) ;
UTHFreePackets ( & p2 , 1 ) ;
return result ;
}
/**
* \ test Test that the http_user_agent content matches against a http request
* which holds the content , against a cross boundary present pattern .
*/
static int DetectHttpUATest09 ( void )
{
TcpSession ssn ;
Packet * p1 = NULL ;
Packet * p2 = NULL ;
ThreadVars th_v ;
DetectEngineCtx * de_ctx = NULL ;
DetectEngineThreadCtx * det_ctx = NULL ;
HtpState * http_state = NULL ;
Flow f ;
uint8_t http1_buf [ ] =
" GET /index.html HTTP/1.0 \r \n "
" Host: www.openinfosecfoundation.org \r \n "
" User-Agent: This is dummy body1 " ;
uint8_t http2_buf [ ] =
" This is dummy message body2 \r \n "
" Content-Type: text/html \r \n "
" Content-Length: 46 \r \n "
" \r \n "
" This is dummy body1 " ;
uint32_t http1_len = sizeof ( http1_buf ) - 1 ;
uint32_t http2_len = sizeof ( http2_buf ) - 1 ;
int result = 0 ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & f , 0 , sizeof ( f ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
p1 = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
p2 = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p1 - > flow = & f ;
p1 - > flowflags | = FLOW_PKT_TOSERVER ;
p1 - > flowflags | = FLOW_PKT_ESTABLISHED ;
p1 - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p2 - > flow = & f ;
p2 - > flowflags | = FLOW_PKT_TOSERVER ;
p2 - > flowflags | = FLOW_PKT_ESTABLISHED ;
p2 - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert http any any -> any any "
" (msg: \" http user agent test \" ; "
" content: \" body1This \" ; http_user_agent; "
" sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
goto end ;
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http1_buf , http1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
http_state = f . alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p1 ) ;
if ( ( PacketAlertCheck ( p1 , 1 ) ) ) {
printf ( " sid 1 didn't match but should have " ) ;
goto end ;
}
r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http2_buf , http2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p2 ) ;
if ( ! ( PacketAlertCheck ( p2 , 1 ) ) ) {
printf ( " sid 1 didn't match but should have " ) ;
goto end ;
}
result = 1 ;
end :
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
SigCleanSignatures ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
UTHFreePackets ( & p1 , 1 ) ;
UTHFreePackets ( & p2 , 1 ) ;
return result ;
}
/**
* \ test Test that the http_user_agent content matches against a http request
* against a case insensitive pattern .
*/
static int DetectHttpUATest10 ( void )
{
TcpSession ssn ;
Packet * p1 = NULL ;
Packet * p2 = NULL ;
ThreadVars th_v ;
DetectEngineCtx * de_ctx = NULL ;
DetectEngineThreadCtx * det_ctx = NULL ;
HtpState * http_state = NULL ;
Flow f ;
uint8_t http1_buf [ ] =
" GET /index.html HTTP/1.0 \r \n "
" Host: www.openinfosecfoundation.org \r \n "
" User-Agent: This is dummy bodY1 " ;
uint8_t http2_buf [ ] =
" This is dummy message body2 \r \n "
" Content-Type: text/html \r \n "
" Content-Length: 46 \r \n "
" \r \n "
" This is dummy bodY1 " ;
uint32_t http1_len = sizeof ( http1_buf ) - 1 ;
uint32_t http2_len = sizeof ( http2_buf ) - 1 ;
int result = 0 ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & f , 0 , sizeof ( f ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
p1 = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
p2 = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . flags | = FLOW_IPV4 ;
p1 - > flow = & f ;
p1 - > flowflags | = FLOW_PKT_TOSERVER ;
p1 - > flowflags | = FLOW_PKT_ESTABLISHED ;
p1 - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
p2 - > flow = & f ;
p2 - > flowflags | = FLOW_PKT_TOSERVER ;
p2 - > flowflags | = FLOW_PKT_ESTABLISHED ;
p2 - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert http any any -> any any "
" (msg: \" http user agent test \" ; "
" content: \" body1this \" ; http_user_agent; nocase; "
" sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
goto end ;
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http1_buf , http1_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
http_state = f . alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: \n " ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p1 ) ;
if ( ( PacketAlertCheck ( p1 , 1 ) ) ) {
printf ( " sid 1 didn't match but should have \n " ) ;
goto end ;
}
r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http2_buf , http2_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: \n " , r ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p2 ) ;
if ( ! ( PacketAlertCheck ( p2 , 1 ) ) ) {
printf ( " sid 1 didn't match but should have " ) ;
goto end ;
}
result = 1 ;
end :
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
SigCleanSignatures ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
UTHFreePackets ( & p1 , 1 ) ;
UTHFreePackets ( & p2 , 1 ) ;
return result ;
}
/**
* \ test Test that the negated http_user_agent content matches against a
* http request which doesn ' t hold the content .
*/
static int DetectHttpUATest11 ( void )
{
TcpSession ssn ;
Packet * p = NULL ;
ThreadVars th_v ;
DetectEngineCtx * de_ctx = NULL ;
DetectEngineThreadCtx * det_ctx = NULL ;
HtpState * http_state = NULL ;
Flow f ;
uint8_t http_buf [ ] =
" GET /index.html HTTP/1.0 \r \n "
" Host: www.openinfosecfoundation.org \r \n "
" User-Agent: This is dummy message body \r \n "
" Content-Type: text/html \r \n "
" \r \n " ;
uint32_t http_len = sizeof ( http_buf ) - 1 ;
int result = 0 ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & f , 0 , sizeof ( f ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
p = UTHBuildPacket ( NULL , 0 , 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 ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert http any any -> any any "
" (msg: \" http user agent test \" ; "
" content:! \" message \" ; http_user_agent; "
" sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
goto end ;
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf , http_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
http_state = f . alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) ) {
printf ( " sid 1 matched but shouldn't have " ) ;
goto end ;
}
result = 1 ;
end :
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
SigCleanSignatures ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
UTHFreePackets ( & p , 1 ) ;
return result ;
}
/**
* \ test Negative test that the negated http_user_agent content matches against a
* http request which holds hold the content .
*/
static int DetectHttpUATest12 ( void )
{
TcpSession ssn ;
Packet * p = NULL ;
ThreadVars th_v ;
DetectEngineCtx * de_ctx = NULL ;
DetectEngineThreadCtx * det_ctx = NULL ;
HtpState * http_state = NULL ;
Flow f ;
uint8_t http_buf [ ] =
" GET /index.html HTTP/1.0 \r \n "
" Host: www.openinfosecfoundation.org \r \n "
" User-Agent: This is dummy body \r \n "
" \r \n " ;
uint32_t http_len = sizeof ( http_buf ) - 1 ;
int result = 0 ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & f , 0 , sizeof ( f ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
p = UTHBuildPacket ( NULL , 0 , 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 ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert http any any -> any any "
" (msg: \" http user agent test \" ; "
" content:! \" message \" ; http_user_agent; "
" sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
goto end ;
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf , http_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
http_state = f . alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( ! ( PacketAlertCheck ( p , 1 ) ) ) {
printf ( " sid 1 didn't match but should have " ) ;
goto end ;
}
result = 1 ;
end :
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
SigCleanSignatures ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
UTHFreePackets ( & p , 1 ) ;
return result ;
}
/**
* \ test Test that the http_user_agent content matches against a http request
* which holds the content .
*/
static int DetectHttpUATest13 ( void )
{
TcpSession ssn ;
Packet * p = NULL ;
ThreadVars th_v ;
DetectEngineCtx * de_ctx = NULL ;
DetectEngineThreadCtx * det_ctx = NULL ;
HtpState * http_state = NULL ;
Flow f ;
uint8_t http_buf [ ] =
" GET /index.html HTTP/1.0 \r \n "
" Host: www.openinfosecfoundation.org \r \n "
" User-Agent: longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend \r \n "
" Content-Type: text/html \r \n "
" \r \n " ;
uint32_t http_len = sizeof ( http_buf ) - 1 ;
int result = 0 ;
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & f , 0 , sizeof ( f ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
p = UTHBuildPacket ( NULL , 0 , 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 ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert http any any -> any any "
" (msg: \" http user agent test \" ; "
" content: \" abcdefghijklmnopqrstuvwxyz0123456789 \" ; http_user_agent; "
" sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL )
goto end ;
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , http_buf , http_len ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
result = 0 ;
goto end ;
}
http_state = f . alstate ;
if ( http_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( ! ( PacketAlertCheck ( p , 1 ) ) ) {
printf ( " sid 1 didn't match but should have " ) ;
goto end ;
}
result = 1 ;
end :
if ( de_ctx ! = NULL )
SigGroupCleanup ( de_ctx ) ;
if ( de_ctx ! = NULL )
SigCleanSignatures ( de_ctx ) ;
if ( de_ctx ! = NULL )
DetectEngineCtxFree ( de_ctx ) ;
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
UTHFreePackets ( & p , 1 ) ;
return result ;
}
/**
* \ test multiple http transactions and body chunks of request handling
*/
static int DetectHttpUATest14 ( void )
{
int result = 0 ;
Signature * s = NULL ;
DetectEngineThreadCtx * det_ctx = NULL ;
ThreadVars th_v ;
Flow f ;
TcpSession ssn ;
Packet * p = NULL ;
uint8_t httpbuf1 [ ] = " POST / HTTP/1.1 \r \n " ;
uint8_t httpbuf2 [ ] = " Cookie: dummy1 \r \n " ;
uint8_t httpbuf3 [ ] = " User-Agent: Body one!! \r \n \r \n " ;
uint32_t httplen1 = sizeof ( httpbuf1 ) - 1 ; /* minus the \0 */
uint32_t httplen2 = sizeof ( httpbuf2 ) - 1 ; /* minus the \0 */
uint32_t httplen3 = sizeof ( httpbuf3 ) - 1 ; /* minus the \0 */
uint8_t httpbuf4 [ ] = " GET /?var=val HTTP/1.1 \r \n " ;
uint8_t httpbuf5 [ ] = " Cookie: dummy2 \r \n " ;
uint8_t httpbuf6 [ ] = " User-Agent: Body two \r \n \r \n " ;
uint32_t httplen4 = sizeof ( httpbuf4 ) - 1 ; /* minus the \0 */
uint32_t httplen5 = sizeof ( httpbuf5 ) - 1 ; /* minus the \0 */
uint32_t httplen6 = sizeof ( httpbuf6 ) - 1 ; /* minus the \0 */
memset ( & th_v , 0 , sizeof ( th_v ) ) ;
memset ( & f , 0 , sizeof ( f ) ) ;
memset ( & ssn , 0 , sizeof ( ssn ) ) ;
p = UTHBuildPacket ( NULL , 0 , IPPROTO_TCP ) ;
FLOW_INITIALIZE ( & f ) ;
f . protoctx = ( void * ) & ssn ;
f . proto = IPPROTO_TCP ;
f . flags | = FLOW_IPV4 ;
p - > flow = & f ;
p - > flowflags | = FLOW_PKT_TOSERVER ;
p - > flowflags | = FLOW_PKT_ESTABLISHED ;
p - > flags | = PKT_HAS_FLOW | PKT_STREAM_EST ;
f . alproto = ALPROTO_HTTP ;
StreamTcpInitConfig ( TRUE ) ;
DetectEngineCtx * de_ctx = DetectEngineCtxInit ( ) ;
if ( de_ctx = = NULL ) {
goto end ;
}
de_ctx - > flags | = DE_QUIET ;
s = DetectEngineAppendSig ( de_ctx , " alert tcp any any -> any any (content: \" POST \" ; http_method; content: \" dummy1 \" ; http_cookie; content: \" Body one \" ; http_user_agent; sid:1; rev:1;) " ) ;
if ( s = = NULL ) {
printf ( " sig parse failed: " ) ;
goto end ;
}
s = DetectEngineAppendSig ( de_ctx , " alert tcp any any -> any any (content: \" GET \" ; http_method; content: \" dummy2 \" ; http_cookie; content: \" Body two \" ; http_user_agent; sid:2; rev:1;) " ) ;
if ( s = = NULL ) {
printf ( " sig2 parse failed: " ) ;
goto end ;
}
SigGroupBuild ( de_ctx ) ;
DetectEngineThreadCtxInit ( & th_v , ( void * ) de_ctx , ( void * ) & det_ctx ) ;
int r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , httpbuf1 , httplen1 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 1 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) ) {
printf ( " sig 1 alerted: " ) ;
goto end ;
}
p - > alerts . cnt = 0 ;
r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , httpbuf2 , httplen2 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 2 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) ) {
printf ( " sig 1 alerted (2): " ) ;
goto end ;
}
p - > alerts . cnt = 0 ;
r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , httpbuf3 , httplen3 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 3 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( ! ( PacketAlertCheck ( p , 1 ) ) ) {
printf ( " sig 1 didn't alert: " ) ;
goto end ;
}
p - > alerts . cnt = 0 ;
r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , httpbuf4 , httplen4 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 5 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) | | PacketAlertCheck ( p , 2 ) ) {
printf ( " sig 1 alerted (4): " ) ;
goto end ;
}
p - > alerts . cnt = 0 ;
r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , httpbuf5 , httplen5 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 6 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( ( PacketAlertCheck ( p , 1 ) ) | | ( PacketAlertCheck ( p , 2 ) ) ) {
printf ( " sig 1 alerted (request 2, chunk 6): " ) ;
goto end ;
}
p - > alerts . cnt = 0 ;
SCLogDebug ( " sending data chunk 7 " ) ;
r = AppLayerParse ( NULL , & f , ALPROTO_HTTP , STREAM_TOSERVER , httpbuf6 , httplen6 ) ;
if ( r ! = 0 ) {
printf ( " toserver chunk 7 returned % " PRId32 " , expected 0: " , r ) ;
goto end ;
}
/* do detect */
SigMatchSignatures ( & th_v , de_ctx , det_ctx , p ) ;
if ( PacketAlertCheck ( p , 1 ) | | ! ( PacketAlertCheck ( p , 2 ) ) ) {
printf ( " signature 2 didn't match or sig 1 matched, but shouldn't have: " ) ;
goto end ;
}
p - > alerts . cnt = 0 ;
HtpState * htp_state = f . alstate ;
if ( htp_state = = NULL ) {
printf ( " no http state: " ) ;
result = 0 ;
goto end ;
}
if ( list_size ( htp_state - > connp - > conn - > transactions ) ! = 2 ) {
printf ( " The http app layer doesn't have 2 transactions, but it should: " ) ;
goto end ;
}
result = 1 ;
end :
if ( det_ctx ! = NULL ) {
DetectEngineThreadCtxDeinit ( & th_v , ( void * ) det_ctx ) ;
}
if ( de_ctx ! = NULL ) {
SigGroupCleanup ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
}
StreamTcpFreeConfig ( TRUE ) ;
FLOW_DESTROY ( & f ) ;
UTHFreePacket ( p ) ;
return result ;
}
int DetectHttpUATest16 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; content: \" one \" ; http_user_agent; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectContentData * cd = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( cd - > id = = huad - > id )
goto end ;
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest17 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; content: \" one \" ; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectContentData * cd = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( cd - > id = = huad - > id )
goto end ;
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest18 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; content: \" one \" ; content: \" one \" ; http_user_agent; content: \" one \" ; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectContentData * cd = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( cd - > id ! = 0 | | huad - > id ! = 1 )
goto end ;
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest19 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; content: \" one \" ; content: \" one \" ; content: \" one \" ; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectContentData * cd = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( cd - > id ! = 1 | | huad - > id ! = 0 )
goto end ;
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest20 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; "
" content: \" one \" ; content: \" one \" ; http_user_agent; content: \" one \" ; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectContentData * cd = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
if ( cd - > id ! = 1 | | huad1 - > id ! = 0 | | huad2 - > id ! = 0 )
goto end ;
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest21 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; "
" content: \" one \" ; content: \" one \" ; http_user_agent; content: \" two \" ; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectContentData * cd = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
if ( cd - > id ! = 2 | | huad1 - > id ! = 0 | | huad2 - > id ! = 0 )
goto end ;
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest22 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; content: \" two \" ; http_user_agent; "
" content: \" three \" ; distance:10; http_user_agent; content: \" four \" ; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectContentData * cd1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > prev - > ctx ;
DetectContentData * cd2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( cd1 - > flags ! = 0 | | memcmp ( cd1 - > content , " one " , cd1 - > content_len ) ! = 0 | |
cd2 - > flags ! = 0 | | memcmp ( cd2 - > content , " four " , cd2 - > content_len ) ! = 0 | |
huad1 - > flags ! = DETECT_CONTENT_RELATIVE_NEXT | |
memcmp ( huad1 - > content , " two " , huad1 - > content_len ) ! = 0 | |
huad2 - > flags ! = DETECT_CONTENT_DISTANCE | |
memcmp ( huad2 - > content , " three " , huad1 - > content_len ) ! = 0 ) {
goto end ;
}
if ( ! DETECT_CONTENT_IS_SINGLE ( cd1 ) | |
! DETECT_CONTENT_IS_SINGLE ( cd2 ) | |
DETECT_CONTENT_IS_SINGLE ( huad1 ) | |
DETECT_CONTENT_IS_SINGLE ( huad2 ) ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest23 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; pcre:/two/; "
" content: \" three \" ; distance:10; http_user_agent; content: \" four \" ; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectPcreData * pd1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > prev - > ctx ;
DetectContentData * cd2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( pd1 - > flags ! = 0 | |
cd2 - > flags ! = 0 | | memcmp ( cd2 - > content , " four " , cd2 - > content_len ) ! = 0 | |
huad1 - > flags ! = DETECT_CONTENT_RELATIVE_NEXT | |
memcmp ( huad1 - > content , " one " , huad1 - > content_len ) ! = 0 | |
huad2 - > flags ! = DETECT_CONTENT_DISTANCE | |
memcmp ( huad2 - > content , " three " , huad1 - > content_len ) ! = 0 ) {
goto end ;
}
if ( ! DETECT_CONTENT_IS_SINGLE ( cd2 ) | |
DETECT_CONTENT_IS_SINGLE ( huad1 ) | |
DETECT_CONTENT_IS_SINGLE ( huad2 ) ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest24 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; pcre:/two/; "
" content: \" three \" ; distance:10; within:15; http_user_agent; content: \" four \" ; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectPcreData * pd1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > prev - > ctx ;
DetectContentData * cd2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( pd1 - > flags ! = 0 | |
cd2 - > flags ! = 0 | | memcmp ( cd2 - > content , " four " , cd2 - > content_len ) ! = 0 | |
huad1 - > flags ! = DETECT_CONTENT_RELATIVE_NEXT | |
memcmp ( huad1 - > content , " one " , huad1 - > content_len ) ! = 0 | |
huad2 - > flags ! = ( DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN ) | |
memcmp ( huad2 - > content , " three " , huad1 - > content_len ) ! = 0 ) {
goto end ;
}
if ( ! DETECT_CONTENT_IS_SINGLE ( cd2 ) | |
DETECT_CONTENT_IS_SINGLE ( huad1 ) | |
DETECT_CONTENT_IS_SINGLE ( huad2 ) ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest25 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; pcre:/two/; "
" content: \" three \" ; distance:10; http_user_agent; "
" content: \" four \" ; distance:10; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectPcreData * pd1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > prev - > ctx ;
DetectContentData * cd2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( pd1 - > flags ! = DETECT_PCRE_RELATIVE_NEXT | |
cd2 - > flags ! = DETECT_CONTENT_DISTANCE | |
memcmp ( cd2 - > content , " four " , cd2 - > content_len ) ! = 0 | |
huad1 - > flags ! = DETECT_CONTENT_RELATIVE_NEXT | |
memcmp ( huad1 - > content , " one " , huad1 - > content_len ) ! = 0 | |
huad2 - > flags ! = DETECT_CONTENT_DISTANCE | |
memcmp ( huad2 - > content , " three " , huad1 - > content_len ) ! = 0 ) {
goto end ;
}
if ( DETECT_CONTENT_IS_SINGLE ( cd2 ) | |
DETECT_CONTENT_IS_SINGLE ( huad1 ) | |
DETECT_CONTENT_IS_SINGLE ( huad2 ) ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest26 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; offset:10; http_user_agent; pcre:/two/; "
" content: \" three \" ; distance:10; http_user_agent; within:10; "
" content: \" four \" ; distance:10; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectPcreData * pd1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > prev - > ctx ;
DetectContentData * cd2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( pd1 - > flags ! = ( DETECT_PCRE_RELATIVE_NEXT ) | |
cd2 - > flags ! = DETECT_CONTENT_DISTANCE | |
memcmp ( cd2 - > content , " four " , cd2 - > content_len ) ! = 0 | |
huad1 - > flags ! = ( DETECT_CONTENT_RELATIVE_NEXT | DETECT_CONTENT_OFFSET ) | |
memcmp ( huad1 - > content , " one " , huad1 - > content_len ) ! = 0 | |
huad2 - > flags ! = ( DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN ) | |
memcmp ( huad2 - > content , " three " , huad1 - > content_len ) ! = 0 ) {
printf ( " failed: http_user_agent incorrect flags " ) ;
goto end ;
}
if ( DETECT_CONTENT_IS_SINGLE ( cd2 ) | |
DETECT_CONTENT_IS_SINGLE ( huad1 ) | |
DETECT_CONTENT_IS_SINGLE ( huad2 ) ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest27 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; offset:10; http_user_agent; pcre:/two/; "
" content: \" three \" ; distance:10; http_user_agent; within:10; "
" content: \" four \" ; distance:10; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest28 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; pcre:/two/; "
" content: \" three \" ; http_user_agent; depth:10; "
" content: \" four \" ; distance:10; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectPcreData * pd1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > prev - > ctx ;
DetectContentData * cd2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_PMATCH ] - > ctx ;
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( pd1 - > flags ! = ( DETECT_PCRE_RELATIVE_NEXT ) | |
cd2 - > flags ! = DETECT_CONTENT_DISTANCE | |
memcmp ( cd2 - > content , " four " , cd2 - > content_len ) ! = 0 | |
huad1 - > flags ! = 0 | |
memcmp ( huad1 - > content , " one " , huad1 - > content_len ) ! = 0 | |
huad2 - > flags ! = DETECT_CONTENT_DEPTH | |
memcmp ( huad2 - > content , " three " , huad1 - > content_len ) ! = 0 ) {
goto end ;
}
if ( DETECT_CONTENT_IS_SINGLE ( cd2 ) | |
! DETECT_CONTENT_IS_SINGLE ( huad1 ) | |
DETECT_CONTENT_IS_SINGLE ( huad2 ) ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest29 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; "
" content: \" two \" ; distance:0; http_user_agent; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] ! = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( huad1 - > flags ! = DETECT_CONTENT_RELATIVE_NEXT | |
memcmp ( huad1 - > content , " one " , huad1 - > content_len ) ! = 0 | |
huad2 - > flags ! = DETECT_CONTENT_DISTANCE | |
memcmp ( huad2 - > content , " two " , huad1 - > content_len ) ! = 0 ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest30 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; "
" content: \" two \" ; within:5; http_user_agent; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] ! = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( huad1 - > flags ! = DETECT_CONTENT_RELATIVE_NEXT | |
memcmp ( huad1 - > content , " one " , huad1 - > content_len ) ! = 0 | |
huad2 - > flags ! = DETECT_CONTENT_WITHIN | |
memcmp ( huad2 - > content , " two " , huad1 - > content_len ) ! = 0 ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest31 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; within:5; http_user_agent; sid:1;) " ) ;
if ( de_ctx - > sig_list ! = NULL ) {
printf ( " de_ctx->sig_list != NULL \n " ) ;
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest32 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; http_user_agent; within:5; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list != NULL \n " ) ;
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest33 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" one \" ; within:5; sid:1;) " ) ;
if ( de_ctx - > sig_list ! = NULL ) {
printf ( " de_ctx->sig_list != NULL \n " ) ;
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest34 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (pcre:/one/V; "
" content: \" two \" ; within:5; http_user_agent; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] ! = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] = = NULL | |
de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > type ! = DETECT_CONTENT | |
de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev = = NULL | |
de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > type ! = DETECT_PCRE ) {
goto end ;
}
DetectPcreData * pd1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( pd1 - > flags ! = ( DETECT_PCRE_RELATIVE_NEXT | DETECT_PCRE_HTTP_USER_AGENT ) | |
huad2 - > flags ! = DETECT_CONTENT_WITHIN | |
memcmp ( huad2 - > content , " two " , huad2 - > content_len ) ! = 0 ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest35 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (content: \" two \" ; http_user_agent; "
" pcre:/one/VR; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] ! = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] = = NULL | |
de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > type ! = DETECT_PCRE | |
de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev = = NULL | |
de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > type ! = DETECT_CONTENT ) {
goto end ;
}
DetectContentData * huad1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectPcreData * pd2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( pd2 - > flags ! = ( DETECT_PCRE_RELATIVE | DETECT_PCRE_HTTP_USER_AGENT ) | |
huad1 - > flags ! = DETECT_CONTENT_RELATIVE_NEXT | |
memcmp ( huad1 - > content , " two " , huad1 - > content_len ) ! = 0 ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
int DetectHttpUATest36 ( void )
{
DetectEngineCtx * de_ctx = NULL ;
int result = 0 ;
if ( ( de_ctx = DetectEngineCtxInit ( ) ) = = NULL )
goto end ;
de_ctx - > flags | = DE_QUIET ;
de_ctx - > sig_list = SigInit ( de_ctx , " alert tcp any any -> any any "
" (pcre:/one/V; "
" content: \" two \" ; distance:5; http_user_agent; sid:1;) " ) ;
if ( de_ctx - > sig_list = = NULL ) {
printf ( " de_ctx->sig_list == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_PMATCH ] ! = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists [ DETECT_SM_LIST_HUADMATCH ] = = NULL ) {
printf ( " de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL \n " ) ;
goto end ;
}
if ( de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] = = NULL | |
de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > type ! = DETECT_CONTENT | |
de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev = = NULL | |
de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > type ! = DETECT_PCRE ) {
goto end ;
}
DetectPcreData * pd1 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > prev - > ctx ;
DetectContentData * huad2 = de_ctx - > sig_list - > sm_lists_tail [ DETECT_SM_LIST_HUADMATCH ] - > ctx ;
if ( pd1 - > flags ! = ( DETECT_PCRE_RELATIVE_NEXT | DETECT_PCRE_HTTP_USER_AGENT ) | |
huad2 - > flags ! = DETECT_CONTENT_DISTANCE | |
memcmp ( huad2 - > content , " two " , huad2 - > content_len ) ! = 0 ) {
goto end ;
}
result = 1 ;
end :
SigCleanSignatures ( de_ctx ) ;
DetectEngineCtxFree ( de_ctx ) ;
return result ;
}
# endif /* UNITTESTS */
void DetectHttpUARegisterTests ( void )
{
# ifdef UNITTESTS
UtRegisterTest ( " DetectHttpUATest01 " , DetectHttpUATest01 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest02 " , DetectHttpUATest02 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest03 " , DetectHttpUATest03 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest04 " , DetectHttpUATest04 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest05 " , DetectHttpUATest05 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest06 " , DetectHttpUATest06 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest07 " , DetectHttpUATest07 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest08 " , DetectHttpUATest08 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest09 " , DetectHttpUATest09 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest10 " , DetectHttpUATest10 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest11 " , DetectHttpUATest11 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest12 " , DetectHttpUATest12 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest13 " , DetectHttpUATest13 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest14 " , DetectHttpUATest14 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest16 " , DetectHttpUATest16 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest17 " , DetectHttpUATest17 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest18 " , DetectHttpUATest18 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest19 " , DetectHttpUATest19 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest20 " , DetectHttpUATest20 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest21 " , DetectHttpUATest21 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest22 " , DetectHttpUATest22 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest23 " , DetectHttpUATest23 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest24 " , DetectHttpUATest24 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest25 " , DetectHttpUATest25 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest26 " , DetectHttpUATest26 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest27 " , DetectHttpUATest27 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest28 " , DetectHttpUATest28 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest29 " , DetectHttpUATest29 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest30 " , DetectHttpUATest30 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest31 " , DetectHttpUATest31 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest32 " , DetectHttpUATest32 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest33 " , DetectHttpUATest33 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest34 " , DetectHttpUATest34 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest35 " , DetectHttpUATest35 , 1 ) ;
UtRegisterTest ( " DetectHttpUATest36 " , DetectHttpUATest36 , 1 ) ;
# endif /* UNITTESTS */
return ;
}
/**
* @ }
*/