PCRE O Modifier

remotes/origin/master-1.0.x
Breno Silva 16 years ago committed by Victor Julien
parent 574bcea09d
commit c552ccbd93

@ -17,9 +17,19 @@
#include "util-var-name.h"
#include "util-debug.h"
#include "util-unittest.h"
#include "conf.h"
#define PARSE_CAPTURE_REGEX "\\(\\?P\\<([A-z]+)\\_([A-z0-9_]+)\\>"
#define PARSE_REGEX "(?<!\\\\)/(.*)(?<!\\\\)/([^\"]*)"
#define DEFAULT_MATCH_LIMIT 10000000
#define DEFAULT_MATCH_LIMIT_RECURSION 10000000
#define MATCH_LIMIT_DEFAULT 1500
static int pcre_match_limit = 0;
static int pcre_match_limit_recursion = 0;
static pcre *parse_regex;
static pcre_extra *parse_regex_study;
static pcre *parse_capture_regex;
@ -42,6 +52,23 @@ void DetectPcreRegister (void) {
const char *eb;
int eo;
int opts = 0;
intmax_t val = 0;
if (!ConfGetInt("pcre.match-limit", &val)) {
pcre_match_limit = DEFAULT_MATCH_LIMIT;
}
else {
pcre_match_limit = val;
}
val = 0;
if (!ConfGetInt("pcre.match-limit-recursion", &val)) {
pcre_match_limit_recursion = DEFAULT_MATCH_LIMIT_RECURSION;
}
else {
pcre_match_limit_recursion = val;
}
parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL);
if(parse_regex == NULL)
@ -262,6 +289,9 @@ DetectPcreData *DetectPcreParse (char *regexstr)
case 'U': /* snort's option */
pd->flags |= DETECT_PCRE_URI;
break;
case 'O':
pd->flags |= DETECT_PCRE_MATCH_LIMIT;
break;
default:
printf("DetectPcreParse: unknown regex modifier '%c'\n", *op);
goto error;
@ -273,19 +303,47 @@ DetectPcreData *DetectPcreParse (char *regexstr)
//printf("DetectPcreParse: \"%s\"\n", re);
pd->re = pcre_compile(re, opts, &eb, &eo, NULL);
if(pd->re == NULL)
{
if(pd->re == NULL) {
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)
{
if(eb != NULL) {
printf("DetectPcreParse: pcre study failed : %s\n", eb);
goto error;
}
if(pd->sd == NULL)
pd->sd = (pcre_extra *) calloc(1,sizeof(pcre_extra));
if(pd->sd) {
if(pd->flags & DETECT_PCRE_MATCH_LIMIT) {
if(pcre_match_limit >= -1) {
pd->sd->match_limit = pcre_match_limit;
pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
}
if(pcre_match_limit_recursion >= -1) {
pd->sd->match_limit_recursion = pcre_match_limit_recursion;
pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
}
}
else {
pd->sd->match_limit = MATCH_LIMIT_DEFAULT;
pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
pd->sd->match_limit_recursion = MATCH_LIMIT_DEFAULT;
pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
}
}
if (re != NULL) free(re);
if (op_ptr != NULL) free(op_ptr);
return pd;
@ -405,7 +463,7 @@ void DetectPcreFree(void *ptr) {
/**
* \test DetectPcreParseTest01 make sure we don't allow invalid opts 7.
*/
int DetectPcreParseTest01 (void) {
static int DetectPcreParseTest01 (void) {
int result = 1;
DetectPcreData *pd = NULL;
char *teststring = "/blah/7";
@ -422,7 +480,7 @@ int DetectPcreParseTest01 (void) {
/**
* \test DetectPcreParseTest02 make sure we don't allow invalid opts Ui$.
*/
int DetectPcreParseTest02 (void) {
static int DetectPcreParseTest02 (void) {
int result = 1;
DetectPcreData *pd = NULL;
char *teststring = "/blah/Ui$";
@ -439,7 +497,7 @@ int DetectPcreParseTest02 (void) {
/**
* \test DetectPcreParseTest03 make sure we don't allow invalid opts UZi.
*/
int DetectPcreParseTest03 (void) {
static int DetectPcreParseTest03 (void) {
int result = 1;
DetectPcreData *pd = NULL;
char *teststring = "/blah/UZi";
@ -456,7 +514,7 @@ int DetectPcreParseTest03 (void) {
/**
* \test DetectPcreParseTest04 make sure we allow escaped "
*/
int DetectPcreParseTest04 (void) {
static int DetectPcreParseTest04 (void) {
int result = 1;
DetectPcreData *pd = NULL;
char *teststring = "/b\\\"lah/i";
@ -474,7 +532,7 @@ int DetectPcreParseTest04 (void) {
/**
* \test DetectPcreParseTest05 make sure we parse pcre with no opts
*/
int DetectPcreParseTest05 (void) {
static int DetectPcreParseTest05 (void) {
int result = 1;
DetectPcreData *pd = NULL;
char *teststring = "/b(l|a)h/";
@ -492,7 +550,7 @@ int DetectPcreParseTest05 (void) {
/**
* \test DetectPcreParseTest06 make sure we parse pcre with smi opts
*/
int DetectPcreParseTest06 (void) {
static int DetectPcreParseTest06 (void) {
int result = 1;
DetectPcreData *pd = NULL;
char *teststring = "/b(l|a)h/smi";
@ -510,7 +568,7 @@ int DetectPcreParseTest06 (void) {
/**
* \test DetectPcreParseTest07 make sure we parse pcre with /Ui opts
*/
int DetectPcreParseTest07 (void) {
static int DetectPcreParseTest07 (void) {
int result = 1;
DetectPcreData *pd = NULL;
char *teststring = "/blah/Ui";
@ -525,6 +583,24 @@ int DetectPcreParseTest07 (void) {
return result;
}
/**
* \test DetectPcreParseTest08 make sure we parse pcre with O opts
*/
static int DetectPcreParseTest08 (void) {
int result = 1;
DetectPcreData *pd = NULL;
char *teststring = "/b(l|a)h/O";
pd = DetectPcreParse(teststring);
if (pd == NULL) {
printf("expected %p: got NULL", pd);
result = 0;
}
DetectPcreFree(pd);
return result;
}
static int DetectPcreTestSig01Real(int mpm_type) {
uint8_t *buf = (uint8_t *)
"GET /one/ HTTP/1.1\r\n"
@ -577,6 +653,61 @@ end:
return result;
}
static int DetectPcreTestSig02Real(int mpm_type) {
uint8_t *buf = (uint8_t *)
"GET /one/ HTTP/1.1\r\n"
"Host: one.example.org\r\n"
"\r\n\r\n"
"GET /two/ HTTP/1.1\r\n"
"Host: two.example.org\r\n"
"\r\n\r\n";
uint16_t buflen = strlen((char *)buf);
Packet p;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
memset(&p, 0, sizeof(p));
p.src.family = AF_INET;
p.dst.family = AF_INET;
p.payload = buf;
p.payload_len = buflen;
p.proto = IPPROTO_TCP;
pcre_match_limit = 100;
pcre_match_limit_recursion = 100;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->mpm_matcher = mpm_type;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; pcre:\"/two/O\"; sid:2;)");
if (de_ctx->sig_list == NULL) {
result = 0;
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
if (PacketAlertCheck(&p, 2))
result = 1;
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
end:
return result;
}
static int DetectPcreTestSig01B2g (void) {
return DetectPcreTestSig01Real(MPM_B2G);
}
@ -587,6 +718,15 @@ static int DetectPcreTestSig01Wm (void) {
return DetectPcreTestSig01Real(MPM_WUMANBER);
}
static int DetectPcreTestSig02B2g (void) {
return DetectPcreTestSig02Real(MPM_B2G);
}
static int DetectPcreTestSig02B3g (void) {
return DetectPcreTestSig02Real(MPM_B3G);
}
static int DetectPcreTestSig02Wm (void) {
return DetectPcreTestSig02Real(MPM_WUMANBER);
}
#endif /* UNITTESTS */
/**
@ -601,9 +741,13 @@ void DetectPcreRegisterTests(void) {
UtRegisterTest("DetectPcreParseTest05", DetectPcreParseTest05, 1);
UtRegisterTest("DetectPcreParseTest06", DetectPcreParseTest06, 1);
UtRegisterTest("DetectPcreParseTest07", DetectPcreParseTest07, 1);
UtRegisterTest("DetectPcreParseTest08", DetectPcreParseTest08, 1);
UtRegisterTest("DetectPcreTestSig01B2g -- pcre test", DetectPcreTestSig01B2g, 1);
UtRegisterTest("DetectPcreTestSig01B3g -- pcre test", DetectPcreTestSig01B3g, 1);
UtRegisterTest("DetectPcreTestSig01Wm -- pcre test", DetectPcreTestSig01Wm, 1);
UtRegisterTest("DetectPcreTestSig02B2g -- pcre test", DetectPcreTestSig02B2g, 1);
UtRegisterTest("DetectPcreTestSig02B3g -- pcre test", DetectPcreTestSig02B3g, 1);
UtRegisterTest("DetectPcreTestSig02Wm -- pcre test", DetectPcreTestSig02Wm, 1);
#endif /* UNITTESTS */
}

@ -4,6 +4,7 @@
#define DETECT_PCRE_DISTANCE 0x0001
#define DETECT_PCRE_WITHIN 0x0002
#define DETECT_PCRE_RELATIVE 0x0004
#define DETECT_PCRE_MATCH_LIMIT 0x0006
#define DETECT_PCRE_DISTANCE_NEXT 0x0008
#define DETECT_PCRE_WITHIN_NEXT 0x0010

Loading…
Cancel
Save