@ -14,9 +14,10 @@
# include "util-var-name.h"
# include "util-debug.h"
# include "util-unittest.h"
# define PARSE_CAPTURE_REGEX "\\(\\?P\\<([A-z]+)\\_([A-z0-9_]+)\\>"
# define PARSE_REGEX "(?<!\\\\) / (.*)(?<!\\\\) / ([ A-z ]*)"
# define PARSE_REGEX "(?<!\\\\) / (.*)(?<!\\\\) / ([ ^\" ]*)"
static pcre * parse_regex ;
static pcre_extra * parse_regex_study ;
static pcre * parse_capture_regex ;
@ -25,13 +26,14 @@ static pcre_extra *parse_capture_regex_study;
int DetectPcreMatch ( ThreadVars * , DetectEngineThreadCtx * , Packet * , Signature * , SigMatch * ) ;
int DetectPcreSetup ( DetectEngineCtx * , Signature * , SigMatch * , char * ) ;
void DetectPcreFree ( void * ) ;
void DetectPcreRegisterTests ( void ) ;
void DetectPcreRegister ( void ) {
sigmatch_table [ DETECT_PCRE ] . name = " pcre " ;
sigmatch_table [ DETECT_PCRE ] . Match = DetectPcreMatch ;
sigmatch_table [ DETECT_PCRE ] . Setup = DetectPcreSetup ;
sigmatch_table [ DETECT_PCRE ] . Free = DetectPcreFree ;
sigmatch_table [ DETECT_PCRE ] . RegisterTests = NULL ;
sigmatch_table [ DETECT_PCRE ] . RegisterTests = DetectPcreRegisterTests ;
sigmatch_table [ DETECT_PCRE ] . flags | = SIGMATCH_PAYLOAD ;
@ -177,37 +179,17 @@ int DetectPcreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, S
return ret ;
}
int DetectPcreSetup ( DetectEngineCtx * de_ctx , Signature * s , SigMatch * m , char * regexstr )
DetectPcreData * DetectPcreParse ( char * regexstr )
{
const char * eb ;
int eo ;
int opts = 0 ;
DetectPcreData * pd = NULL ;
SigMatch * sm = NULL ;
char * re = NULL , * op_ptr = NULL , * op = NULL ;
char dubbed = 0 ;
# define MAX_SUBSTRINGS 30
int ret = 0 , res = 0 ;
int ov [ MAX_SUBSTRINGS ] ;
const char * capture_str_ptr = NULL , * type_str_ptr = NULL ;
//printf("DetectPcreSetup: \'%s\'\n", regexstr);
ret = pcre_exec ( parse_capture_regex , parse_capture_regex_study , regexstr , strlen ( regexstr ) , 0 , 0 , ov , MAX_SUBSTRINGS ) ;
if ( ret > 1 ) {
res = pcre_get_substring ( ( char * ) regexstr , ov , MAX_SUBSTRINGS , 1 , & type_str_ptr ) ;
if ( res < 0 ) {
printf ( " DetectPcreSetup: pcre_get_substring failed \n " ) ;
return - 1 ;
}
res = pcre_get_substring ( ( char * ) regexstr , ov , MAX_SUBSTRINGS , 2 , & capture_str_ptr ) ;
if ( res < 0 ) {
printf ( " DetectPcreSetup: pcre_get_substring failed \n " ) ;
return - 1 ;
}
}
//printf("DetectPcreSetup: type \'%s\'\n", type_str_ptr ? type_str_ptr : "NULL");
//printf("DetectPcreSetup: capture \'%s\'\n", capture_str_ptr ? capture_str_ptr : "NULL");
ret = pcre_exec ( parse_regex , parse_regex_study , regexstr , strlen ( regexstr ) , 0 , 0 , ov , MAX_SUBSTRINGS ) ;
if ( ret < 0 ) {
@ -218,16 +200,16 @@ int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *r
const char * str_ptr ;
res = pcre_get_substring ( ( char * ) regexstr , ov , MAX_SUBSTRINGS , 1 , & str_ptr ) ;
if ( res < 0 ) {
printf ( " DetectPcre Setup : pcre_get_substring failed\n " ) ;
return - 1 ;
printf ( " DetectPcre Parse : pcre_get_substring failed\n " ) ;
return NULL ;
}
re = ( char * ) str_ptr ;
if ( ret > 2 ) {
res = pcre_get_substring ( ( char * ) regexstr , ov , MAX_SUBSTRINGS , 2 , & str_ptr ) ;
if ( res < 0 ) {
printf ( " DetectPcre Setup : pcre_get_substring failed\n " ) ;
return - 1 ;
printf ( " DetectPcre Parse : pcre_get_substring failed\n " ) ;
return NULL ;
}
op_ptr = op = ( char * ) str_ptr ;
}
@ -236,32 +218,11 @@ int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *r
pd = malloc ( sizeof ( DetectPcreData ) ) ;
if ( pd = = NULL ) {
printf ( " DetectPcre Setup malloc failed\n " ) ;
printf ( " DetectPcre Parse: malloc failed\n " ) ;
goto error ;
}
memset ( pd , 0 , sizeof ( DetectPcreData ) ) ;
pd - > depth = 0 ;
pd - > flags = 0 ;
if ( capture_str_ptr ! = NULL ) {
pd - > capname = strdup ( ( char * ) capture_str_ptr ) ;
}
if ( type_str_ptr ! = NULL ) {
if ( strcmp ( type_str_ptr , " pkt " ) = = 0 ) {
pd - > flags | = DETECT_PCRE_CAPTURE_PKT ;
} else if ( strcmp ( type_str_ptr , " flow " ) = = 0 ) {
pd - > flags | = DETECT_PCRE_CAPTURE_FLOW ;
}
if ( capture_str_ptr ! = NULL ) {
if ( pd - > flags & DETECT_PCRE_CAPTURE_PKT )
pd - > capidx = VariableNameGetIdx ( de_ctx , ( char * ) capture_str_ptr , DETECT_PKTVAR ) ;
else if ( pd - > flags & DETECT_PCRE_CAPTURE_FLOW )
pd - > capidx = VariableNameGetIdx ( de_ctx , ( char * ) capture_str_ptr , DETECT_FLOWVAR ) ;
}
}
//printf("DetectPcreSetup: pd->capname %s\n", pd->capname ? pd->capname : "NULL");
if ( op ! = NULL ) {
while ( * op ) {
SCLogDebug ( " regex option %c " , * op ) ;
@ -300,31 +261,115 @@ int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *r
pd - > flags | = DETECT_PCRE_URI ;
break ;
default :
printf ( " DetectPcre Setup : unknown regex modifier '%c'\n " , * op ) ;
break ;
printf ( " DetectPcre Parse : unknown regex modifier '%c'\n " , * op ) ;
goto error ;
}
op + + ;
}
}
//printf("DetectPcre Setup : \"%s\"\n", re);
//printf("DetectPcre Parse : \"%s\"\n", re);
pd - > re = pcre_compile ( re , opts , & eb , & eo , NULL ) ;
if ( pd - > re = = NULL )
{
printf ( " pcre compile of \" %s \" failed at offset % " PRId32 " : %s \n " , regexstr , eo , eb ) ;
printf ( " DetectPcreParse: pcre compile of \" %s \" failed at offset % " PRId32 " : %s \n " , regexstr , eo , eb ) ;
goto error ;
}
pd - > sd = pcre_study ( pd - > re , 0 , & eb ) ;
if ( eb ! = NULL )
{
printf ( " pcre study failed : %s \n " , eb ) ;
printf ( " DetectPcreParse: pcre study failed : %s \n " , eb ) ;
goto error ;
}
if ( re ! = NULL ) free ( re ) ;
if ( op_ptr ! = NULL ) free ( op_ptr ) ;
return pd ;
error :
if ( re ! = NULL ) free ( re ) ;
if ( op_ptr ! = NULL ) free ( op_ptr ) ;
if ( pd ! = NULL & & pd - > re ! = NULL ) pcre_free ( pd - > re ) ;
if ( pd ! = NULL & & pd - > sd ! = NULL ) pcre_free ( pd - > sd ) ;
if ( dubbed ) free ( re ) ;
if ( pd ) free ( pd ) ;
return NULL ;
}
DetectPcreData * DetectPcreParseCapture ( char * regexstr , DetectEngineCtx * de_ctx , DetectPcreData * pd )
{
int ret = 0 , res = 0 ;
int ov [ MAX_SUBSTRINGS ] ;
const char * capture_str_ptr = NULL , * type_str_ptr = NULL ;
if ( pd = = NULL )
goto error ;
if ( de_ctx = = NULL )
goto error ;
//printf("DetectPcreParseCapture: \'%s\'\n", regexstr);
ret = pcre_exec ( parse_capture_regex , parse_capture_regex_study , regexstr , strlen ( regexstr ) , 0 , 0 , ov , MAX_SUBSTRINGS ) ;
if ( ret > 1 ) {
res = pcre_get_substring ( ( char * ) regexstr , ov , MAX_SUBSTRINGS , 1 , & type_str_ptr ) ;
if ( res < 0 ) {
printf ( " DetectPcreParseCapture: pcre_get_substring failed \n " ) ;
goto error ;
}
res = pcre_get_substring ( ( char * ) regexstr , ov , MAX_SUBSTRINGS , 2 , & capture_str_ptr ) ;
if ( res < 0 ) {
printf ( " DetectPcreParseCapture: pcre_get_substring failed \n " ) ;
goto error ;
}
}
//printf("DetectPcreParseCapture: type \'%s\'\n", type_str_ptr ? type_str_ptr : "NULL");
//printf("DetectPcreParseCapture: capture \'%s\'\n", capture_str_ptr ? capture_str_ptr : "NULL");
pd - > depth = 0 ;
pd - > flags = 0 ;
if ( capture_str_ptr ! = NULL ) {
pd - > capname = strdup ( ( char * ) capture_str_ptr ) ;
}
if ( type_str_ptr ! = NULL ) {
if ( strcmp ( type_str_ptr , " pkt " ) = = 0 ) {
pd - > flags | = DETECT_PCRE_CAPTURE_PKT ;
} else if ( strcmp ( type_str_ptr , " flow " ) = = 0 ) {
pd - > flags | = DETECT_PCRE_CAPTURE_FLOW ;
}
if ( capture_str_ptr ! = NULL ) {
if ( pd - > flags & DETECT_PCRE_CAPTURE_PKT )
pd - > capidx = VariableNameGetIdx ( de_ctx , ( char * ) capture_str_ptr , DETECT_PKTVAR ) ;
else if ( pd - > flags & DETECT_PCRE_CAPTURE_FLOW )
pd - > capidx = VariableNameGetIdx ( de_ctx , ( char * ) capture_str_ptr , DETECT_FLOWVAR ) ;
}
}
//printf("DetectPcreParseCapture: pd->capname %s\n", pd->capname ? pd->capname : "NULL");
if ( type_str_ptr ! = NULL ) pcre_free ( ( char * ) type_str_ptr ) ;
if ( capture_str_ptr ! = NULL ) pcre_free ( ( char * ) capture_str_ptr ) ;
return pd ;
error :
if ( pd ! = NULL & & pd - > capname ! = NULL ) free ( pd - > capname ) ;
if ( pd ) free ( pd ) ;
return NULL ;
}
int DetectPcreSetup ( DetectEngineCtx * de_ctx , Signature * s , SigMatch * m , char * regexstr )
{
DetectPcreData * pd = NULL ;
SigMatch * sm = NULL ;
pd = DetectPcreParse ( regexstr ) ;
if ( pd = = NULL ) goto error ;
pd = DetectPcreParseCapture ( regexstr , de_ctx , pd ) ;
if ( pd = = NULL ) goto error ;
/* Okay so far so good, lets get this into a SigMatch
* and put it in the Signature . */
sm = SigMatchAlloc ( ) ;
if ( sm = = NULL )
goto error ;
@ -334,21 +379,11 @@ int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *r
SigMatchAppend ( s , m , sm ) ;
if ( type_str_ptr ! = NULL ) pcre_free ( ( char * ) type_str_ptr ) ;
if ( capture_str_ptr ! = NULL ) pcre_free ( ( char * ) capture_str_ptr ) ;
if ( re ! = NULL ) free ( re ) ;
if ( op_ptr ! = NULL ) free ( op_ptr ) ;
return 0 ;
error :
if ( re ! = NULL ) free ( re ) ;
if ( op_ptr ! = NULL ) free ( op_ptr ) ;
if ( pd ! = NULL & & pd - > capname ! = NULL ) free ( pd - > capname ) ;
if ( pd ! = NULL & & pd - > re ! = NULL ) pcre_free ( pd - > re ) ;
if ( pd ! = NULL & & pd - > sd ! = NULL ) pcre_free ( pd - > sd ) ;
if ( dubbed ) free ( re ) ;
if ( pd ) free ( pd ) ;
if ( sm ) free ( sm ) ;
if ( pd ! = NULL ) DetectPcreFree ( pd ) ;
if ( sm ! = NULL ) free ( sm ) ;
return - 1 ;
}
@ -363,3 +398,144 @@ void DetectPcreFree(void *ptr) {
return ;
}
# ifdef UNITTESTS /* UNITTESTS */
/**
* \ test DetectPcreParseTest01 make sure we don ' t allow invalid opts 7.
*/
int DetectPcreParseTest01 ( void ) {
int result = 1 ;
DetectPcreData * pd = NULL ;
char * teststring = " /blah/7 " ;
pd = DetectPcreParse ( teststring ) ;
if ( pd ! = NULL ) {
printf ( " expected NULL: got %p " , pd ) ;
result = 0 ;
DetectPcreFree ( pd ) ;
}
return result ;
}
/**
* \ test DetectPcreParseTest02 make sure we don ' t allow invalid opts Ui $ .
*/
int DetectPcreParseTest02 ( void ) {
int result = 1 ;
DetectPcreData * pd = NULL ;
char * teststring = " /blah/Ui$ " ;
pd = DetectPcreParse ( teststring ) ;
if ( pd ! = NULL ) {
printf ( " expected NULL: got %p " , pd ) ;
result = 0 ;
DetectPcreFree ( pd ) ;
}
return result ;
}
/**
* \ test DetectPcreParseTest03 make sure we don ' t allow invalid opts UZi .
*/
int DetectPcreParseTest03 ( void ) {
int result = 1 ;
DetectPcreData * pd = NULL ;
char * teststring = " /blah/UZi " ;
pd = DetectPcreParse ( teststring ) ;
if ( pd ! = NULL ) {
printf ( " expected NULL: got %p " , pd ) ;
result = 0 ;
DetectPcreFree ( pd ) ;
}
return result ;
}
/**
* \ test DetectPcreParseTest04 make sure we allow escaped "
*/
int DetectPcreParseTest04 ( void ) {
int result = 1 ;
DetectPcreData * pd = NULL ;
char * teststring = " /b \\ \" lah/i " ;
pd = DetectPcreParse ( teststring ) ;
if ( pd = = NULL ) {
printf ( " expected %p: got NULL " , pd ) ;
result = 0 ;
}
DetectPcreFree ( pd ) ;
return result ;
}
/**
* \ test DetectPcreParseTest05 make sure we parse pcre with no opts
*/
int DetectPcreParseTest05 ( void ) {
int result = 1 ;
DetectPcreData * pd = NULL ;
char * teststring = " /b(l|a)h/ " ;
pd = DetectPcreParse ( teststring ) ;
if ( pd = = NULL ) {
printf ( " expected %p: got NULL " , pd ) ;
result = 0 ;
}
DetectPcreFree ( pd ) ;
return result ;
}
/**
* \ test DetectPcreParseTest06 make sure we parse pcre with smi opts
*/
int DetectPcreParseTest06 ( void ) {
int result = 1 ;
DetectPcreData * pd = NULL ;
char * teststring = " /b(l|a)h/smi " ;
pd = DetectPcreParse ( teststring ) ;
if ( pd = = NULL ) {
printf ( " expected %p: got NULL " , pd ) ;
result = 0 ;
}
DetectPcreFree ( pd ) ;
return result ;
}
/**
* \ test DetectPcreParseTest07 make sure we parse pcre with / Ui opts
*/
int DetectPcreParseTest07 ( void ) {
int result = 1 ;
DetectPcreData * pd = NULL ;
char * teststring = " /blah/Ui " ;
pd = DetectPcreParse ( teststring ) ;
if ( pd = = NULL ) {
printf ( " expected %p: got NULL " , pd ) ;
result = 0 ;
}
DetectPcreFree ( pd ) ;
return result ;
}
# endif /* UNITTESTS */
/**
* \ brief this function registers unit tests for DetectPcre
*/
void DetectPcreRegisterTests ( void ) {
# ifdef UNITTESTS /* UNITTESTS */
UtRegisterTest ( " DetectPcreParseTest01 " , DetectPcreParseTest01 , 1 ) ;
UtRegisterTest ( " DetectPcreParseTest02 " , DetectPcreParseTest02 , 1 ) ;
UtRegisterTest ( " DetectPcreParseTest03 " , DetectPcreParseTest03 , 1 ) ;
UtRegisterTest ( " DetectPcreParseTest04 " , DetectPcreParseTest04 , 1 ) ;
UtRegisterTest ( " DetectPcreParseTest05 " , DetectPcreParseTest05 , 1 ) ;
UtRegisterTest ( " DetectPcreParseTest06 " , DetectPcreParseTest06 , 1 ) ;
UtRegisterTest ( " DetectPcreParseTest07 " , DetectPcreParseTest07 , 1 ) ;
# endif /* UNITTESTS */
}