Flags keyword fix. Fatal init fix.

remotes/origin/master-1.0.x
Victor Julien 15 years ago
parent ac03873f5d
commit 778228d1c5

@ -14,11 +14,13 @@
#include "detect-flags.h"
#include "util-unittest.h"
#include "util-debug.h"
/**
* Regex (by Brian Rectanus)
* flags: [!+*](SAPRFU120)[,SAPRFU12]
*/
#define PARSE_REGEX "^\\s*(?:([\\+\\*!]))?\\s*([SAPRFU120]+)(?:\\s*,\\s*([SAPRFU12]+))?\\s*$"
#define PARSE_REGEX "^\\s*(?:([\\+\\*!]))?\\s*([SAPRFU120\\+\\*!]+)(?:\\s*,\\s*([SAPRFU12]+))?\\s*$"
/**
* Flags args[0] *(3) +(2) !(1)
@ -85,6 +87,8 @@ error:
*/
static int DetectFlagsMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m)
{
SCEnter();
int ret = 0;
uint8_t flags = 0;
DetectFlagsData *de = (DetectFlagsData *)m->ctx;
@ -94,33 +98,42 @@ static int DetectFlagsMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Pack
flags = p->tcph->th_flags;
if(!de->flags && flags) {
if(de->modifier == 1)
return 1;
return ret;
if (!de->flags && flags) {
if(de->modifier == MODIFIER_NOT) {
SCReturnInt(1);
}
SCReturnInt(ret);
}
flags &= (de->flags & de->ignored_flags);
switch(de->modifier) {
case MODIFIER_ANY:
if((flags & de->flags) > 0)
return 1;
return ret;
if((flags & de->flags) > 0) {
SCReturnInt(1);
}
SCReturnInt(ret);
case MODIFIER_PLUS:
if(((flags & de->flags) == de->flags) && (((p->tcph->th_flags - flags) + de->ignored_flags) != 0xff))
return 1;
return ret;
if(((flags & de->flags) == de->flags) && (((p->tcph->th_flags - flags) + de->ignored_flags) != 0xff)) {
SCReturnInt(1);
}
SCReturnInt(ret);
case MODIFIER_NOT:
if((flags & de->flags) != de->flags)
return 1;
return ret;
if((flags & de->flags) != de->flags) {
SCReturnInt(1);
}
SCReturnInt(ret);
default:
if((flags & de->flags) == de->flags)
return 1;
if((flags & de->flags) == de->flags) {
SCReturnInt(1);
}
}
return ret;
SCReturnInt(ret);
}
/**
@ -134,6 +147,8 @@ static int DetectFlagsMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Pack
*/
static DetectFlagsData *DetectFlagsParse (char *rawstr)
{
SCEnter();
DetectFlagsData *de = NULL;
#define MAX_SUBSTRINGS 30
int ret = 0, found = 0, ignore = 0, res = 0;
@ -144,24 +159,26 @@ static DetectFlagsData *DetectFlagsParse (char *rawstr)
int i;
ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
if (ret < 1) {
SCLogDebug("pcre match failed");
goto error;
}
for (i = 0; i < (ret - 1); i++) {
res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS,i + 1, &str_ptr);
if (res < 0) {
SCLogDebug("pcre_get_substring failed");
goto error;
}
args[i] = (char *)str_ptr;
}
if(args[1] == NULL)
if(args[1] == NULL) {
SCLogDebug("args[1] == NULL");
goto error;
}
de = malloc(sizeof(DetectFlagsData));
if (de == NULL) {
@ -181,6 +198,49 @@ static DetectFlagsData *DetectFlagsParse (char *rawstr)
while (*ptr != '\0') {
switch (*ptr) {
case 'S':
case 's':
de->flags |= TH_SYN;
found++;
break;
case 'A':
case 'a':
de->flags |= TH_ACK;
found++;
break;
case 'F':
case 'f':
de->flags |= TH_FIN;
found++;
break;
case 'R':
case 'r':
de->flags |= TH_RST;
found++;
break;
case 'P':
case 'p':
de->flags |= TH_PUSH;
found++;
break;
case 'U':
case 'u':
de->flags |= TH_URG;
found++;
break;
case '1':
de->flags |= TH_RES1;
found++;
break;
case '2':
de->flags |= TH_RES2;
found++;
break;
case '0':
de->flags = 0;
found++;
break;
case '!':
de->modifier = MODIFIER_NOT;
break;
@ -243,6 +303,29 @@ static DetectFlagsData *DetectFlagsParse (char *rawstr)
case '0':
de->flags = 0;
found++;
break;
case '!':
if (de->modifier != 0) {
SCLogError(SC_ERR_FLAGS_MODIFIER, "\"flags\" supports only one modifier at a time");
goto error;
}
de->modifier = MODIFIER_NOT;
break;
case '+':
if (de->modifier != 0) {
SCLogError(SC_ERR_FLAGS_MODIFIER, "\"flags\" supports only one modifier at a time");
goto error;
}
de->modifier = MODIFIER_PLUS;
break;
case '*':
if (de->modifier != 0) {
SCLogError(SC_ERR_FLAGS_MODIFIER, "\"flags\" supports only one modifier at a time");
goto error;
}
de->modifier = MODIFIER_ANY;
break;
default:
break;
}
@ -306,22 +389,24 @@ static DetectFlagsData *DetectFlagsParse (char *rawstr)
ptr++;
}
if(ignore == 0)
if(ignore == 0) {
SCLogDebug("ignore == 0");
goto error;
}
}
for (i = 0; i < (ret - 1); i++){
if (args[i] != NULL) free(args[i]);
}
return de;
SCReturnPtr(de, "DetectFlagsData");
error:
for (i = 0; i < (ret - 1); i++){
if (args[i] != NULL) free(args[i]);
}
if (de) free(de);
return NULL;
SCReturnPtr(NULL, "DetectFlagsData");
}
/**
@ -887,8 +972,10 @@ static int FlagsTestParse12 (void) {
de = DetectFlagsParse("0");
if (de == NULL || de->flags != 0)
if (de == NULL || de->flags != 0) {
printf("de setup: ");
goto error;
}
sm = SigMatchAlloc();
if (sm == NULL)
@ -911,6 +998,23 @@ error:
return 0;
}
/**
* \test test for a valid flags value
*
* \retval 1 on succces
* \retval 0 on failure
*/
static int FlagsTestParse13 (void) {
DetectFlagsData *de = NULL;
de = DetectFlagsParse("+S*");
if (de != NULL) {
DetectFlagsFree(de);
return 0;
}
return 1;
}
#endif /* UNITTESTS */
/**
@ -930,5 +1034,6 @@ void FlagsRegisterTests(void) {
UtRegisterTest("FlagsTestParse10", FlagsTestParse10, 1);
UtRegisterTest("FlagsTestParse11", FlagsTestParse11, 0);
UtRegisterTest("FlagsTestParse12", FlagsTestParse12, 0);
UtRegisterTest("FlagsTestParse13", FlagsTestParse13, 1);
#endif /* UNITTESTS */
}

@ -251,7 +251,7 @@ int SigParseOptions(DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *op
/* Call option parsing */
st = SigTableGet((char *)arr[0]);
if (st == NULL) {
printf("Unknown rule keyword '%s'.\n", (char *)arr[0]);
SCLogError(SC_RULE_KEYWORD_UNKNOWN, "unknown rule keyword '%s'.", (char *)arr[0]);
goto error;
}
@ -269,8 +269,10 @@ int SigParseOptions(DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *op
}
/* setup may or may not add a new SigMatch to the list */
if (st->Setup(de_ctx, s, m, optvalue) < 0)
if (st->Setup(de_ctx, s, m, optvalue) < 0) {
SCLogDebug("\"%s\" failed to setup", st->name);
goto error;
}
/* thats why we check for that here
* (it may install more than one SigMatch!) */
@ -512,12 +514,14 @@ error:
}
int SigParse(DetectEngineCtx *de_ctx, Signature *s, char *sigstr, uint8_t addrs_direction) {
SCEnter();
char **basics;
int ret = SigParseBasics(s, sigstr, &basics, addrs_direction);
if (ret < 0) {
//printf("SigParseBasics failed\n");
return -1;
SCReturnInt(-1);
}
#ifdef DEBUG
@ -532,6 +536,7 @@ int SigParse(DetectEngineCtx *de_ctx, Signature *s, char *sigstr, uint8_t addrs_
/* we can have no options, so make sure we have them */
if (basics[CONFIG_OPTS] != NULL) {
ret = SigParseOptions(de_ctx, s, NULL, strdup(basics[CONFIG_OPTS]));
SCLogDebug("ret from SigParseOptions %d", ret);
}
/* cleanup */
@ -544,7 +549,7 @@ int SigParse(DetectEngineCtx *de_ctx, Signature *s, char *sigstr, uint8_t addrs_
free(basics);
}
return ret;
SCReturnInt(ret);
}
Signature *SigAlloc (void) {

@ -254,6 +254,8 @@ int DetectLoadSigFile(DetectEngineCtx *de_ctx, char *sig_file) {
int SigLoadSignatures (DetectEngineCtx *de_ctx, char *sig_file)
{
SCEnter();
Signature *prevsig = NULL, *sig;
ConfNode *rule_files;
ConfNode *file = NULL;
@ -268,14 +270,14 @@ int SigLoadSignatures (DetectEngineCtx *de_ctx, char *sig_file)
/* http_uri -- for uricontent */
sig = SigInit(de_ctx, "alert tcp any any -> any $HTTP_PORTS (msg:\"HTTP GET URI cap\"; flow:to_server,established; content:\"GET \"; depth:4; pcre:\"/^GET (?P<pkt_http_uri>.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; noalert; sid:1;)");
if (sig == NULL)
return -1;
ret = -1;
prevsig = sig;
de_ctx->sig_list = sig;
sig = SigInit(de_ctx, "alert tcp any any -> any $HTTP_PORTS (msg:\"HTTP POST URI cap\"; flow:to_server,established; content:\"POST \"; depth:5; pcre:\"/^POST (?P<pkt_http_uri>.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; noalert; sid:2;)");
if (sig == NULL)
return -1;
ret = -1;
prevsig->next = sig;
prevsig = sig;
@ -283,7 +285,7 @@ int SigLoadSignatures (DetectEngineCtx *de_ctx, char *sig_file)
/* http_host -- for the log-httplog module */
sig = SigInit(de_ctx, "alert tcp any any -> any $HTTP_PORTS (msg:\"HTTP host cap\"; flow:to_server,established; content:\"|0d 0a|Host:\"; pcre:\"/^Host: (?P<pkt_http_host>.*)\\r\\n/m\"; noalert; sid:3;)");
if (sig == NULL)
return -1;
ret = -1;
prevsig->next = sig;
prevsig = sig;
@ -291,7 +293,7 @@ int SigLoadSignatures (DetectEngineCtx *de_ctx, char *sig_file)
/* http_ua -- for the log-httplog module */
sig = SigInit(de_ctx, "alert tcp any any -> any $HTTP_PORTS (msg:\"HTTP UA cap\"; flow:to_server,established; content:\"|0d 0a|User-Agent:\"; pcre:\"/^User-Agent: (?P<pkt_http_ua>.*)\\r\\n/m\"; noalert; sid:4;)");
if (sig == NULL)
return -1;
ret = -1;
prevsig->next = sig;
@ -301,12 +303,14 @@ int SigLoadSignatures (DetectEngineCtx *de_ctx, char *sig_file)
TAILQ_FOREACH(file, &rule_files->head, next) {
sfile = DetectLoadCompleteSigPath(file->val);
SCLogInfo("Loading rule file: %s", sfile);
r = DetectLoadSigFile(de_ctx, sfile);
cntf++;
if (r > 0) {
cnt += r;
} else if (r == 0){
SCLogError(SC_ERR_NO_RULES, "No rules loaded from %s", sfile);
ret = -1;
}
free(sfile);
}
@ -332,13 +336,17 @@ int SigLoadSignatures (DetectEngineCtx *de_ctx, char *sig_file)
SCLogInfo("%d rules loaded from %d files.", cnt, cntf);
}
if (ret < 0 && de_ctx->failure_fatal) {
SCReturnInt(ret);
}
SCSigRegisterSignatureOrderingFuncs(de_ctx);
SCSigOrderSignatures(de_ctx);
SCSigSignatureOrderingModuleCleanup(de_ctx);
/* Setup the signature group lookup structure and pattern matchers */
SigGroupBuild(de_ctx);
return 0;
SCReturnInt(0);
}
/**

@ -609,6 +609,8 @@ int main(int argc, char **argv)
} else {
SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed.");
}
if (de_ctx->failure_fatal)
exit(EXIT_FAILURE);
}
struct timeval start_time;

@ -63,6 +63,8 @@ const char * SCErrorToString(SCError err)
CASE_CODE (SC_ERR_FOPEN);
CASE_CODE (SC_ERR_THRESHOLD_HASH_ADD);
CASE_CODE (SC_ERR_UNDEFINED_VAR);
CASE_CODE (SC_RULE_KEYWORD_UNKNOWN);
CASE_CODE (SC_ERR_FLAGS_MODIFIER);
default:
return "UNKNOWN_ERROR";
}

@ -75,6 +75,8 @@ typedef enum {
SC_ERR_FWRITE,
SC_ERR_THRESHOLD_HASH_ADD,
SC_ERR_UNDEFINED_VAR,
SC_RULE_KEYWORD_UNKNOWN,
SC_ERR_FLAGS_MODIFIER,
} SCError;
const char *SCErrorToString(SCError);

Loading…
Cancel
Save