-/* Copyright (C) 2007-2010 Open Information Security Foundation
+/* Copyright (C) 2007-2019 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
* \file
*
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
+ * \author Victor Julien <victor@inliniac.net>
*
* Implements classtype keyword.
*/
#include "detect.h"
#include "detect-parse.h"
#include "detect-engine.h"
-#include "detect-engine-mpm.h"
#include "detect-classtype.h"
-#include "flow-var.h"
#include "util-classification-config.h"
#include "util-error.h"
#include "util-debug.h"
sigmatch_table[DETECT_CLASSTYPE].name = "classtype";
sigmatch_table[DETECT_CLASSTYPE].desc = "information about the classification of rules and alerts";
sigmatch_table[DETECT_CLASSTYPE].url = DOC_URL DOC_VERSION "/rules/meta.html#classtype";
- sigmatch_table[DETECT_CLASSTYPE].Match = NULL;
sigmatch_table[DETECT_CLASSTYPE].Setup = DetectClasstypeSetup;
- sigmatch_table[DETECT_CLASSTYPE].Free = NULL;
sigmatch_table[DETECT_CLASSTYPE].RegisterTests = DetectClasstypeRegisterTests;
DetectSetupParseRegexes(PARSE_REGEX, ®ex, ®ex_study);
static int DetectClasstypeParseRawString(const char *rawstr, char *out, size_t outsize)
{
#define MAX_SUBSTRINGS 30
- int ret = 0;
int ov[MAX_SUBSTRINGS];
size_t len = strlen(rawstr);
- ret = pcre_exec(regex, regex_study, rawstr, len, 0, 0, ov, 30);
+ int ret = pcre_exec(regex, regex_study, rawstr, len, 0, 0, ov, 30);
if (ret < 0) {
SCLogError(SC_ERR_PCRE_MATCH, "Invalid Classtype in Signature");
- goto end;
+ return -1;
}
ret = pcre_copy_substring((char *)rawstr, ov, 30, 1, out, outsize);
if (ret < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
- goto end;
+ return -1;
}
return 0;
- end:
- return -1;
}
/**
if ((s->class > 0) || (s->class_msg != NULL)) {
SCLogWarning(SC_ERR_CONFLICTING_RULE_KEYWORDS, "duplicated 'classtype' "
- "keyword detected. Using first occurence in the rule");
- return 0;
+ "keyword detected. Using instance with highest priority");
}
if (DetectClasstypeParseRawString(rawstr, parsed_ct_name, sizeof(parsed_ct_name)) < 0) {
SCClassConfClasstype *ct = SCClassConfGetClasstype(parsed_ct_name, de_ctx);
if (ct == NULL) {
- SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown Classtype: \"%s\". Invalidating the Signature",
+ SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown classtype: \"%s\"",
parsed_ct_name);
return -1;
}
- /* if we have retrieved the classtype, assign the message to be displayed
- * for this Signature by fast.log, if a Packet matches this Signature */
- s->class = ct->classtype_id;
- s->class_msg = ct->classtype_desc;
-
- /* if a priority keyword has appeared before the classtype, s->prio would
- * hold a value which is != -1, in which case we don't overwrite the value.
- * Otherwise, overwrite the value */
- if (s->prio == -1)
+ if ((s->init_data->init_flags & SIG_FLAG_INIT_PRIO_EXPLICT) != 0) {
+ /* don't touch Signature::prio */
+ s->class = ct->classtype_id;
+ s->class_msg = ct->classtype_desc;
+ } else if (s->prio == -1) {
s->prio = ct->priority;
+ s->class = ct->classtype_id;
+ s->class_msg = ct->classtype_desc;
+ } else {
+ if (ct->priority < s->prio) {
+ s->prio = ct->priority;
+ s->class = ct->classtype_id;
+ s->class_msg = ct->classtype_desc;
+ }
+ }
return 0;
}
-/*------------------------------Unittests-------------------------------------*/
-
#ifdef UNITTESTS
/**
*/
static int DetectClasstypeTest01(void)
{
- int result = 0;
-
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- if (de_ctx == NULL) {
- goto end;
- }
+ FAIL_IF_NULL(de_ctx);
FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01();
+ FAIL_IF_NULL(fd);
SCClassConfLoadClassficationConfigFile(de_ctx, fd);
-
- de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
+ de_ctx->sig_list = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
"(msg:\"Classtype test\"; "
"Classtype:not_available; sid:1;)");
- if (de_ctx->sig_list == NULL)
- result = 1;
+ FAIL_IF_NOT_NULL(de_ctx->sig_list);
DetectEngineCtxFree(de_ctx);
-
-end:
- return result;
+ PASS;
}
/**
*/
static int DetectClasstypeTest02(void)
{
- int result = 0;
- Signature *last = NULL;
- Signature *sig = NULL;
-
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- if (de_ctx == NULL) {
- goto end;
- }
+ FAIL_IF_NULL(de_ctx);
FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01();
+ FAIL_IF_NULL(fd);
SCClassConfLoadClassficationConfigFile(de_ctx, fd);
- sig = SigInit(de_ctx, "alert tcp any any -> any any "
- "(msg:\"Classtype test\"; Classtype:bad-unknown; sid:1;)");
- if (sig == NULL) {
- printf("first sig failed to parse: ");
- result = 0;
- goto end;
- }
- de_ctx->sig_list = last = sig;
- result = (sig != NULL);
-
- sig = SigInit(de_ctx, "alert tcp any any -> any any "
- "(msg:\"Classtype test\"; Classtype:not-there; sid:1;)");
- last->next = sig;
- result &= (sig == NULL);
-
- sig = SigInit(de_ctx, "alert tcp any any -> any any "
- "(msg:\"Classtype test\"; Classtype:Bad-UnkNown; sid:1;)");
- if (sig == NULL) {
- printf("second sig failed to parse: ");
- result = 0;
- goto end;
- }
- last->next = sig;
- last = sig;
- result &= (sig != NULL);
-
- sig = SigInit(de_ctx, "alert tcp any any -> any any "
- "(msg:\"Classtype test\"; Classtype:nothing-wrong; sid:1;)");
- if (sig == NULL) {
- result = 0;
- goto end;
- }
- last->next = sig;
- last = sig;
- result &= (sig != NULL);
+ Signature *sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
+ "(Classtype:bad-unknown; sid:1;)");
+ FAIL_IF_NULL(sig);
- sig = SigInit(de_ctx, "alert tcp any any -> any any "
- "(msg:\"Classtype test\"; Classtype:attempted_dos; sid:1;)");
- last->next = sig;
- result &= (sig == NULL);
+ sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
+ "(Classtype:not-there; sid:2;)");
+ FAIL_IF_NOT_NULL(sig);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
+ sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
+ "(Classtype:Bad-UnkNown; sid:3;)");
+ FAIL_IF_NULL(sig);
-end:
- return result;
+ sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
+ "(Classtype:nothing-wrong; sid:4;)");
+ FAIL_IF_NULL(sig);
+
+ sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
+ "(Classtype:attempted_dos; sid:5;)");
+ FAIL_IF_NOT_NULL(sig);
+
+ /* duplicate test */
+ sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
+ "(Classtype:nothing-wrong; Classtype:Bad-UnkNown; sid:6;)");
+ FAIL_IF_NULL(sig);
+ FAIL_IF_NOT(sig->prio == 2);
+
+ DetectEngineCtxFree(de_ctx);
+ PASS;
}
/**
*/
static int DetectClasstypeTest03(void)
{
- int result = 0;
- Signature *last = NULL;
- Signature *sig = NULL;
-
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- if (de_ctx == NULL) {
- goto end;
- }
+ FAIL_IF_NULL(de_ctx);
FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01();
+ FAIL_IF_NULL(fd);
SCClassConfLoadClassficationConfigFile(de_ctx, fd);
- sig = SigInit(de_ctx, "alert tcp any any -> any any "
+ Signature *sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
"(msg:\"Classtype test\"; Classtype:bad-unknown; priority:1; sid:1;)");
- if (sig == NULL) {
- result = 0;
- goto end;
- }
- de_ctx->sig_list = last = sig;
- result = (sig != NULL);
- result &= (sig->prio == 1);
+ FAIL_IF_NULL(sig);
+ FAIL_IF_NOT(sig->prio == 1);
- sig = SigInit(de_ctx, "alert tcp any any -> any any "
+ sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
"(msg:\"Classtype test\"; Classtype:unKnoWn; "
- "priority:3; sid:1;)");
- if (sig == NULL) {
- result = 0;
- goto end;
- }
- last->next = sig;
- last = sig;
- result &= (sig != NULL);
- result &= (sig->prio == 3);
-
- sig = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"Classtype test\"; "
- "Classtype:nothing-wrong; priority:1; sid:1;)");
- if (sig == NULL) {
- result = 0;
- goto end;
- }
- last->next = sig;
- last = sig;
- result &= (sig != NULL);
- result &= (sig->prio == 1);
+ "priority:3; sid:2;)");
+ FAIL_IF_NULL(sig);
+ FAIL_IF_NOT(sig->prio == 3);
+ sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"Classtype test\"; "
+ "Classtype:nothing-wrong; priority:1; sid:3;)");
+ FAIL_IF_NOT(sig->prio == 1);
- SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
-
-end:
- return result;
+ PASS;
}
#endif /* UNITTESTS */
*/
static void DetectClasstypeRegisterTests(void)
{
-
#ifdef UNITTESTS
-
UtRegisterTest("DetectClasstypeTest01", DetectClasstypeTest01);
UtRegisterTest("DetectClasstypeTest02", DetectClasstypeTest02);
UtRegisterTest("DetectClasstypeTest03", DetectClasstypeTest03);
-
#endif /* UNITTESTS */
-
}