return;
}
-/**
- * \brief Parses a line from the threshold file and adds it to Thresholdtype
- *
- * \param rawstr Pointer to the string to be parsed.
- * \param de_ctx Pointer to the Detection Engine Context.
- *
- * \retval 0 On success.
- * \retval -1 On failure.
+/** \internal
+ * \brief setup suppress rules
+ * \retval 0 ok
+ * \retval -1 error
*/
-int SCThresholdConfAddThresholdtype(char *rawstr, DetectEngineCtx *de_ctx)
+static int SetupSuppressRule(DetectEngineCtx *de_ctx, uint32_t id, uint32_t gid,
+ uint8_t parsed_type, uint8_t parsed_track, uint32_t parsed_count,
+ uint32_t parsed_seconds, uint32_t parsed_timeout, uint8_t parsed_new_action,
+ const char *th_ip)
{
- const char *th_rule_type = NULL;
- const char *th_gid = NULL;
- const char *th_sid = NULL;
- const char *th_type = NULL;
- const char *th_track = NULL;
- const char *th_count = NULL;
- const char *th_seconds = NULL;
- const char *th_new_action= NULL;
- const char *th_timeout = NULL;
- const char *th_ip = NULL;
- const char *rule_extend = NULL;
-
- uint8_t parsed_type = 0;
- uint8_t parsed_track = 0;
- uint8_t parsed_new_action = 0;
- uint32_t parsed_count = 0;
- uint32_t parsed_seconds = 0;
- uint32_t parsed_timeout = 0;
-
- Signature *sig = NULL;
- Signature *s = NULL, *ns = NULL;
- DetectThresholdData *de = NULL;
+ Signature *s = NULL;
SigMatch *sm = NULL;
- SigMatch *m = NULL;
-#define MAX_SUBSTRINGS 30
- int ret = 0;
- int ov[MAX_SUBSTRINGS];
- uint32_t id = 0, gid = 0;
- ThresholdRuleType rule_type;
- int fret = -1;
-
- if (de_ctx == NULL)
- return -1;
-
- ret = pcre_exec(regex_base, regex_base_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
- if (ret < 4) {
- SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
- goto error;
- }
-
- /* retrieve the classtype name */
- ret = pcre_get_substring((char *)rawstr, ov, 30, 1, &th_rule_type);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
-
- /* retrieve the classtype name */
- ret = pcre_get_substring((char *)rawstr, ov, 30, 2, &th_gid);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
-
- ret = pcre_get_substring((char *)rawstr, ov, 30, 3, &th_sid);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
+ DetectThresholdData *de = NULL;
- ret = pcre_get_substring((char *)rawstr, ov, 30, 4, &rule_extend);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
+ BUG_ON(parsed_type != TYPE_SUPPRESS);
- /* get type of rule */
- if (strncasecmp(th_rule_type,"event_filter",strlen("event_filter")) == 0) {
- rule_type = THRESHOLD_TYPE_EVENT_FILTER;
- } else if (strncasecmp(th_rule_type,"threshold",strlen("threshold")) == 0) {
- rule_type = THRESHOLD_TYPE_THRESHOLD;
- } else if (strncasecmp(th_rule_type,"rate",strlen("rate")) == 0) {
- rule_type = THRESHOLD_TYPE_RATE;
- } else if (strncasecmp(th_rule_type,"suppress",strlen("suppress")) == 0) {
- rule_type = THRESHOLD_TYPE_SUPPRESS;
- } else {
- SCLogError(SC_ERR_INVALID_VALUE, "rule type %s is unknown", th_rule_type);
- goto error;
- }
+ /* Install it */
+ if (id == 0 && gid == 0) {
+ if (parsed_track == TRACK_RULE) {
+ SCLogWarning(SC_ERR_EVENT_ENGINE, "suppressing all rules");
+ }
- /* get end of rule */
- switch(rule_type) {
- case THRESHOLD_TYPE_EVENT_FILTER:
- case THRESHOLD_TYPE_THRESHOLD:
- if (strlen(rule_extend) > 0) {
- ret = pcre_exec(regex_threshold, regex_threshold_study,
- rule_extend, strlen(rule_extend),
- 0, 0, ov, MAX_SUBSTRINGS);
- if (ret < 4) {
- SCLogError(SC_ERR_PCRE_MATCH,
- "pcre_exec parse error, ret %" PRId32 ", string %s",
- ret, rule_extend);
- goto error;
- }
+ /* update each sig with our suppress info */
+ for (s = de_ctx->sig_list; s != NULL; s = s->next) {
+ /* tag the rule as noalert */
+ if (parsed_track == TRACK_RULE) {
+ s->flags |= SIG_FLAG_NOALERT;
+ continue;
+ }
- ret = pcre_get_substring((char *)rule_extend, ov, 30, 1, &th_type);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
+ de = SCMalloc(sizeof(DetectThresholdData));
+ if (unlikely(de == NULL))
+ goto error;
+ memset(de,0,sizeof(DetectThresholdData));
- ret = pcre_get_substring((char *)rule_extend, ov, 30, 2, &th_track);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
+ de->type = TYPE_SUPPRESS;
+ de->track = parsed_track;
+ de->count = parsed_count;
+ de->seconds = parsed_seconds;
+ de->new_action = parsed_new_action;
+ de->timeout = parsed_timeout;
+ de->addr = NULL;
- ret = pcre_get_substring((char *)rule_extend, ov, 30, 3, &th_count);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ if (parsed_track != TRACK_RULE) {
+ de->addr = DetectAddressInit();
+ if (de->addr == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Can't init DetectAddress");
goto error;
}
-
- ret = pcre_get_substring((char *)rule_extend, ov, 30, 4, &th_seconds);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ if (DetectAddressParseString(de->addr, (char *)th_ip) < 0) {
+ SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Can't add %s to address group", th_ip);
goto error;
}
+ }
- if (strcasecmp(th_type,"limit") == 0)
- parsed_type = TYPE_LIMIT;
- else if (strcasecmp(th_type,"both") == 0)
- parsed_type = TYPE_BOTH;
- else if (strcasecmp(th_type,"threshold") == 0)
- parsed_type = TYPE_THRESHOLD;
- else {
- SCLogError(SC_ERR_INVALID_ARGUMENTS, "limit type not supported: %s", th_type);
- goto error;
- }
- } else {
- SCLogError(SC_ERR_INVALID_ARGUMENTS, "rule invalid: %s", rawstr);
+ sm = SigMatchAlloc();
+ if (sm == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch");
goto error;
}
- break;
- case THRESHOLD_TYPE_SUPPRESS:
- if (strlen(rule_extend) > 0) {
- ret = pcre_exec(regex_suppress, regex_suppress_study,
- rule_extend, strlen(rule_extend),
- 0, 0, ov, MAX_SUBSTRINGS);
- if (ret < 2) {
- SCLogError(SC_ERR_PCRE_MATCH,
- "pcre_exec parse error, ret %" PRId32 ", string %s",
- ret, rule_extend);
- goto error;
- }
- /* retrieve the track mode */
- ret = pcre_get_substring((char *)rule_extend, ov, 30, 1, &th_track);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
- /* retrieve the IP */
- ret = pcre_get_substring((char *)rule_extend, ov, 30, 2, &th_ip);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
- } else {
- parsed_track = TRACK_RULE;
+
+ sm->type = DETECT_THRESHOLD;
+ sm->ctx = (void *)de;
+ SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_SUPPRESS);
+ }
+ } else if (id == 0 && gid > 0) {
+ if (parsed_track == TRACK_RULE) {
+ SCLogWarning(SC_ERR_EVENT_ENGINE, "suppressing all rules with gid %"PRIu32, gid);
+ }
+ /* set up suppression for each signature with a matching gid */
+ for (s = de_ctx->sig_list; s != NULL; s = s->next) {
+ if (s->gid != gid)
+ continue;
+
+ /* tag the rule as noalert */
+ if (parsed_track == TRACK_RULE) {
+ s->flags |= SIG_FLAG_NOALERT;
+ continue;
}
- parsed_type = TYPE_SUPPRESS;
- break;
- case THRESHOLD_TYPE_RATE:
- if (strlen(rule_extend) > 0) {
- ret = pcre_exec(regex_rate, regex_rate_study,
- rule_extend, strlen(rule_extend),
- 0, 0, ov, MAX_SUBSTRINGS);
- if (ret < 5) {
- SCLogError(SC_ERR_PCRE_MATCH,
- "pcre_exec parse error, ret %" PRId32 ", string %s",
- ret, rule_extend);
- goto error;
- }
- ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 1, &th_track);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
+ de = SCMalloc(sizeof(DetectThresholdData));
+ if (unlikely(de == NULL))
+ goto error;
- ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 2, &th_count);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
+ memset(de,0,sizeof(DetectThresholdData));
- ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 3, &th_seconds);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
- goto error;
- }
+ de->type = TYPE_SUPPRESS;
+ de->track = parsed_track;
+ de->count = parsed_count;
+ de->seconds = parsed_seconds;
+ de->new_action = parsed_new_action;
+ de->timeout = parsed_timeout;
+ de->addr = NULL;
- ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 4, &th_new_action);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ if (parsed_track != TRACK_RULE) {
+ de->addr = DetectAddressInit();
+ if (de->addr == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Can't init DetectAddress");
goto error;
}
-
- ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 5, &th_timeout);
- if (ret < 0) {
- SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ if (DetectAddressParseString(de->addr, (char *)th_ip) < 0) {
+ SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Can't add %s to address group", th_ip);
goto error;
}
+ }
- /* TODO: implement option "apply_to" */
+ sm = SigMatchAlloc();
+ if (sm == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch");
+ goto error;
+ }
- if (ByteExtractStringUint32(&parsed_timeout, 10, strlen(th_timeout), th_timeout) <= 0) {
- goto error;
- }
+ sm->type = DETECT_THRESHOLD;
+ sm->ctx = (void *)de;
- /* Get the new action to take */
- if (strcasecmp(th_new_action, "alert") == 0)
- parsed_new_action = TH_ACTION_ALERT;
- if (strcasecmp(th_new_action, "drop") == 0)
- parsed_new_action = TH_ACTION_DROP;
- if (strcasecmp(th_new_action, "pass") == 0)
- parsed_new_action = TH_ACTION_PASS;
- if (strcasecmp(th_new_action, "reject") == 0)
- parsed_new_action = TH_ACTION_REJECT;
- if (strcasecmp(th_new_action, "log") == 0) {
- SCLogInfo("log action for rate_filter not supported yet");
- parsed_new_action = TH_ACTION_LOG;
- }
- if (strcasecmp(th_new_action, "sdrop") == 0) {
- SCLogInfo("sdrop action for rate_filter not supported yet");
- parsed_new_action = TH_ACTION_SDROP;
- }
- parsed_type = TYPE_RATE;
- } else {
- SCLogError(SC_ERR_INVALID_ARGUMENTS, "rule invalid: %s", rawstr);
- goto error;
+ SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_SUPPRESS);
+ }
+ } else if (id > 0 && gid == 0) {
+ SCLogError(SC_ERR_INVALID_VALUE, "Can't use a event config that has "
+ "sid > 0 and gid == 0. Please fix this "
+ "in your threshold.conf file");
+ goto error;
+ } else {
+ s = SigFindSignatureBySidGid(de_ctx, id, gid);
+ if (s == NULL) {
+ SCLogWarning(SC_ERR_EVENT_ENGINE, "can't suppress sid "
+ "%"PRIu32", gid %"PRIu32": unknown rule", id, gid);
+ } else {
+ if (parsed_track == TRACK_RULE) {
+ s->flags |= SIG_FLAG_NOALERT;
+ goto end;
}
- break;
- default:
- SCLogError(SC_ERR_PCRE_MATCH, "unable to find rule type for string %s", rawstr);
- goto error;
- }
- switch (rule_type) {
- /* This part is common to threshold/event_filter/rate_filter */
- case THRESHOLD_TYPE_EVENT_FILTER:
- case THRESHOLD_TYPE_THRESHOLD:
- case THRESHOLD_TYPE_RATE:
- if (strcasecmp(th_track,"by_dst") == 0)
- parsed_track = TRACK_DST;
- else if (strcasecmp(th_track,"by_src") == 0)
- parsed_track = TRACK_SRC;
- else if (strcasecmp(th_track,"by_rule") == 0)
- parsed_track = TRACK_RULE;
- else {
- SCLogError(SC_ERR_INVALID_VALUE, "Invalid track parameter %s in %s", th_track, rawstr);
+ de = SCMalloc(sizeof(DetectThresholdData));
+ if (unlikely(de == NULL))
goto error;
- }
+ memset(de,0,sizeof(DetectThresholdData));
- if (ByteExtractStringUint32(&parsed_count, 10, strlen(th_count), th_count) <= 0) {
+ de->type = TYPE_SUPPRESS;
+ de->track = parsed_track;
+ de->count = parsed_count;
+ de->seconds = parsed_seconds;
+ de->new_action = parsed_new_action;
+ de->timeout = parsed_timeout;
+
+ de->addr = DetectAddressInit();
+ if (de->addr == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Can't init DetectAddress");
goto error;
}
- if (parsed_count == 0) {
- SCLogError(SC_ERR_INVALID_VALUE, "rate filter count should be > 0");
+ if (DetectAddressParseString(de->addr, (char *)th_ip) < 0) {
+ SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Can't add %s to address group", th_ip);
goto error;
}
- if (ByteExtractStringUint32(&parsed_seconds, 10, strlen(th_seconds), th_seconds) <= 0) {
+ sm = SigMatchAlloc();
+ if (sm == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch");
goto error;
}
- break;
- case THRESHOLD_TYPE_SUPPRESS:
- /* need to get IP if extension is provided */
- if (th_track != NULL) {
- if (strcasecmp(th_track,"by_dst") == 0)
- parsed_track = TRACK_DST;
- else if (strcasecmp(th_track,"by_src") == 0)
- parsed_track = TRACK_SRC;
- else {
- SCLogError(SC_ERR_INVALID_VALUE, "Invalid track parameter %s in %s", th_track, rule_extend);
- goto error;
- }
- }
- break;
- }
+ sm->type = DETECT_THRESHOLD;
+ sm->ctx = (void *)de;
- if (ByteExtractStringUint32(&id, 10, strlen(th_sid), th_sid) <= 0) {
- goto error;
+ SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_SUPPRESS);
+ }
}
- if (ByteExtractStringUint32(&gid, 10, strlen(th_gid), th_gid) <= 0) {
- goto error;
+end:
+ return 0;
+error:
+ if (de != NULL) {
+ if (de->addr != NULL)
+ DetectAddressFree(de->addr);
+ SCFree(de);
}
+ return -1;
+}
+
+/** \internal
+ * \brief setup suppress rules
+ * \retval 0 ok
+ * \retval -1 error
+ */
+static int SetupThresholdRule(DetectEngineCtx *de_ctx, uint32_t id, uint32_t gid,
+ uint8_t parsed_type, uint8_t parsed_track, uint32_t parsed_count,
+ uint32_t parsed_seconds, uint32_t parsed_timeout, uint8_t parsed_new_action,
+ const char *th_ip)
+{
+ Signature *s = NULL;
+ SigMatch *sm = NULL;
+ DetectThresholdData *de = NULL;
+
+ BUG_ON(parsed_type == TYPE_SUPPRESS);
/* Install it */
if (id == 0 && gid == 0) {
- for (s = de_ctx->sig_list; s != NULL;) {
- ns = s->next;
- if (parsed_type != TYPE_SUPPRESS) {
- m = SigMatchGetLastSMFromLists(s, 2,
+ for (s = de_ctx->sig_list; s != NULL; s = s->next) {
+ sm = SigMatchGetLastSMFromLists(s, 2,
+ DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ if (sm != NULL) {
+ SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
+ "an event var set. The signature event var is "
+ "given precedence over the threshold.conf one. "
+ "We'll change this in the future though.", s->id);
+ goto end;
+ }
+
+ sm = SigMatchGetLastSMFromLists(s, 2,
+ DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ if (sm != NULL) {
+ SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
+ "an event var set. The signature event var is "
+ "given precedence over the threshold.conf one. "
+ "We'll change this in the future though.", s->id);
+ goto end;
+ }
+
+ de = SCMalloc(sizeof(DetectThresholdData));
+ if (unlikely(de == NULL))
+ goto error;
+ memset(de,0,sizeof(DetectThresholdData));
+
+ de->type = parsed_type;
+ de->track = parsed_track;
+ de->count = parsed_count;
+ de->seconds = parsed_seconds;
+ de->new_action = parsed_new_action;
+ de->timeout = parsed_timeout;
+ de->addr = NULL;
+
+ sm = SigMatchAlloc();
+ if (sm == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch");
+ goto error;
+ }
+
+ if (parsed_type == TYPE_RATE)
+ sm->type = DETECT_DETECTION_FILTER;
+ else
+ sm->type = DETECT_THRESHOLD;
+ sm->ctx = (void *)de;
+
+ if (parsed_track == TRACK_RULE) {
+ de_ctx->ths_ctx.th_entry = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *));
+ if (de_ctx->ths_ctx.th_entry == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config"
+ " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1);
+ } else {
+ de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL;
+ de_ctx->ths_ctx.th_size++;
+ }
+ }
+ SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD);
+ }
+
+ } else if (id == 0 && gid > 0) {
+ for (s = de_ctx->sig_list; s != NULL; s = s->next) {
+ if (s->gid == gid) {
+ sm = SigMatchGetLastSMFromLists(s, 2,
+ DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ if (sm != NULL) {
+ SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
+ "an event var set. The signature event var is "
+ "given precedence over the threshold.conf one. "
+ "We'll change this in the future though.", id);
+ goto end;
+ }
+
+ sm = SigMatchGetLastSMFromLists(s, 2,
+ DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ if (sm != NULL) {
+ SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
+ "an event var set. The signature event var is "
+ "given precedence over the threshold.conf one. "
+ "We'll change this in the future though.", id);
+ goto end;
+ }
+
+ de = SCMalloc(sizeof(DetectThresholdData));
+ if (unlikely(de == NULL))
+ goto error;
+ memset(de,0,sizeof(DetectThresholdData));
+
+ de->type = parsed_type;
+ de->track = parsed_track;
+ de->count = parsed_count;
+ de->seconds = parsed_seconds;
+ de->new_action = parsed_new_action;
+ de->timeout = parsed_timeout;
+ de->addr = NULL;
+
+ sm = SigMatchAlloc();
+ if (sm == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch");
+ goto error;
+ }
+
+ if (parsed_type == TYPE_RATE)
+ sm->type = DETECT_DETECTION_FILTER;
+ else
+ sm->type = DETECT_THRESHOLD;
+ sm->ctx = (void *)de;
+
+ if (parsed_track == TRACK_RULE) {
+ de_ctx->ths_ctx.th_entry = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *));
+ if (de_ctx->ths_ctx.th_entry == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config"
+ " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1);
+ } else {
+ de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL;
+ de_ctx->ths_ctx.th_size++;
+ }
+ }
+ SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD);
+ }
+ }
+ } else if (id > 0 && gid == 0) {
+ SCLogError(SC_ERR_INVALID_VALUE, "Can't use a event config that has "
+ "sid > 0 and gid == 0. Please fix this "
+ "in your threshold.conf file");
+ } else {
+ s = SigFindSignatureBySidGid(de_ctx, id, gid);
+ if (s == NULL) {
+ SCLogWarning(SC_ERR_EVENT_ENGINE, "can't suppress sid "
+ "%"PRIu32", gid %"PRIu32": unknown rule", id, gid);
+ } else {
+ if (parsed_type != TYPE_SUPPRESS && parsed_type != TYPE_THRESHOLD &&
+ parsed_type != TYPE_BOTH && parsed_type != TYPE_LIMIT)
+ {
+ sm = SigMatchGetLastSMFromLists(s, 2,
DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
-
- if (m != NULL) {
+ if (sm != NULL) {
SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
- "an event var set. The signature event var is "
- "given precedence over the threshold.conf one. "
- "We'll change this in the future though.", s->id);
+ "a threshold set. The signature event var is "
+ "given precedence over the threshold.conf one. "
+ "Bug #425.", s->id);
goto end;
}
- m = SigMatchGetLastSMFromLists(s, 2,
+ sm = SigMatchGetLastSMFromLists(s, 2,
DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
-
- if (m != NULL) {
+ if (sm != NULL) {
SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
- "an event var set. The signature event var is "
- "given precedence over the threshold.conf one. "
- "We'll change this in the future though.", s->id);
+ "a detection_filter set. The signature event var is "
+ "given precedence over the threshold.conf one. "
+ "Bug #425.", s->id);
goto end;
}
+
+ /* replace threshold on sig if we have a global override for it */
+#if 1
+ } else if (parsed_type == TYPE_THRESHOLD || parsed_type == TYPE_BOTH || parsed_type == TYPE_LIMIT) {
+ sm = SigMatchGetLastSMFromLists(s, 2,
+ DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ if (sm == NULL) {
+ sm = SigMatchGetLastSMFromLists(s, 2,
+ DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ }
+ if (sm != NULL) {
+ SigMatchRemoveSMFromList(s, sm, DETECT_SM_LIST_THRESHOLD);
+ SigMatchFree(sm);
+ sm = NULL;
+ }
+#endif
}
de = SCMalloc(sizeof(DetectThresholdData));
if (unlikely(de == NULL))
goto error;
-
memset(de,0,sizeof(DetectThresholdData));
de->type = parsed_type;
de->timeout = parsed_timeout;
de->addr = NULL;
- if ((parsed_type == TYPE_SUPPRESS) && (parsed_track != TRACK_RULE)) {
- de->addr = DetectAddressInit();
- if (de->addr == NULL) {
- SCLogError(SC_ERR_MEM_ALLOC, "Can't init DetectAddress");
- goto error;
- }
- if (DetectAddressParseString(de->addr, (char *)th_ip) < 0) {
- SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Can't add %s to address group", th_ip);
- goto error;
- }
- }
-
sm = SigMatchAlloc();
if (sm == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch");
de_ctx->ths_ctx.th_size++;
}
}
+
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD);
- s = ns;
}
+ }
+end:
+ return 0;
+error:
+ if (de != NULL) {
+ if (de->addr != NULL)
+ DetectAddressFree(de->addr);
+ SCFree(de);
+ }
+ return -1;
+}
- } else if (id == 0 && gid > 0) {
- for (s = de_ctx->sig_list; s != NULL;) {
- ns = s->next;
-
- if(s->gid == gid) {
- if (parsed_type != TYPE_SUPPRESS) {
- m = SigMatchGetLastSMFromLists(s, 2,
- DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
-
- if (m != NULL) {
- SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
- "an event var set. The signature event var is "
- "given precedence over the threshold.conf one. "
- "We'll change this in the future though.", id);
- goto end;
- }
+/**
+ * \brief Parses a line from the threshold file and adds it to Thresholdtype
+ *
+ * \param rawstr Pointer to the string to be parsed.
+ * \param de_ctx Pointer to the Detection Engine Context.
+ *
+ * \retval 0 On success.
+ * \retval -1 On failure.
+ */
+int SCThresholdConfAddThresholdtype(char *rawstr, DetectEngineCtx *de_ctx)
+{
+ const char *th_rule_type = NULL;
+ const char *th_gid = NULL;
+ const char *th_sid = NULL;
+ const char *th_type = NULL;
+ const char *th_track = NULL;
+ const char *th_count = NULL;
+ const char *th_seconds = NULL;
+ const char *th_new_action= NULL;
+ const char *th_timeout = NULL;
+ const char *th_ip = NULL;
+ const char *rule_extend = NULL;
- m = SigMatchGetLastSMFromLists(s, 2,
- DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ uint8_t parsed_type = 0;
+ uint8_t parsed_track = 0;
+ uint8_t parsed_new_action = 0;
+ uint32_t parsed_count = 0;
+ uint32_t parsed_seconds = 0;
+ uint32_t parsed_timeout = 0;
- if (m != NULL) {
- SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
- "an event var set. The signature event var is "
- "given precedence over the threshold.conf one. "
- "We'll change this in the future though.", id);
- goto end;
- }
- }
+#define MAX_SUBSTRINGS 30
+ int ret = 0;
+ int ov[MAX_SUBSTRINGS];
+ uint32_t id = 0, gid = 0;
+ ThresholdRuleType rule_type;
+ int fret = -1;
- de = SCMalloc(sizeof(DetectThresholdData));
- if (unlikely(de == NULL))
- goto error;
+ if (de_ctx == NULL)
+ return -1;
- memset(de,0,sizeof(DetectThresholdData));
+ ret = pcre_exec(regex_base, regex_base_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
+ if (ret < 4) {
+ SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
+ goto error;
+ }
- de->type = parsed_type;
- de->track = parsed_track;
- de->count = parsed_count;
- de->seconds = parsed_seconds;
- de->new_action = parsed_new_action;
- de->timeout = parsed_timeout;
- de->addr = NULL;
+ /* retrieve the classtype name */
+ ret = pcre_get_substring((char *)rawstr, ov, 30, 1, &th_rule_type);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
- if ((parsed_type == TYPE_SUPPRESS) && (parsed_track != TRACK_RULE)) {
- de->addr = DetectAddressInit();
- if (de->addr == NULL) {
- SCLogError(SC_ERR_MEM_ALLOC, "Can't init DetectAddress");
- goto error;
- }
- if (DetectAddressParseString(de->addr, (char *)th_ip) < 0) {
- SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Can't add %s to address group", th_ip);
- goto error;
- }
- }
+ /* retrieve the classtype name */
+ ret = pcre_get_substring((char *)rawstr, ov, 30, 2, &th_gid);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
- sm = SigMatchAlloc();
- if (sm == NULL) {
- SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch");
+ ret = pcre_get_substring((char *)rawstr, ov, 30, 3, &th_sid);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
+
+ ret = pcre_get_substring((char *)rawstr, ov, 30, 4, &rule_extend);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
+
+ /* get type of rule */
+ if (strncasecmp(th_rule_type,"event_filter",strlen("event_filter")) == 0) {
+ rule_type = THRESHOLD_TYPE_EVENT_FILTER;
+ } else if (strncasecmp(th_rule_type,"threshold",strlen("threshold")) == 0) {
+ rule_type = THRESHOLD_TYPE_THRESHOLD;
+ } else if (strncasecmp(th_rule_type,"rate",strlen("rate")) == 0) {
+ rule_type = THRESHOLD_TYPE_RATE;
+ } else if (strncasecmp(th_rule_type,"suppress",strlen("suppress")) == 0) {
+ rule_type = THRESHOLD_TYPE_SUPPRESS;
+ } else {
+ SCLogError(SC_ERR_INVALID_VALUE, "rule type %s is unknown", th_rule_type);
+ goto error;
+ }
+
+ /* get end of rule */
+ switch(rule_type) {
+ case THRESHOLD_TYPE_EVENT_FILTER:
+ case THRESHOLD_TYPE_THRESHOLD:
+ if (strlen(rule_extend) > 0) {
+ ret = pcre_exec(regex_threshold, regex_threshold_study,
+ rule_extend, strlen(rule_extend),
+ 0, 0, ov, MAX_SUBSTRINGS);
+ if (ret < 4) {
+ SCLogError(SC_ERR_PCRE_MATCH,
+ "pcre_exec parse error, ret %" PRId32 ", string %s",
+ ret, rule_extend);
goto error;
}
- if (parsed_type == TYPE_RATE)
- sm->type = DETECT_DETECTION_FILTER;
- else
- sm->type = DETECT_THRESHOLD;
- sm->ctx = (void *)de;
+ ret = pcre_get_substring((char *)rule_extend, ov, 30, 1, &th_type);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
- if (parsed_track == TRACK_RULE) {
- de_ctx->ths_ctx.th_entry = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *));
- if (de_ctx->ths_ctx.th_entry == NULL) {
- SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config"
- " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1);
- } else {
- de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL;
- de_ctx->ths_ctx.th_size++;
- }
+ ret = pcre_get_substring((char *)rule_extend, ov, 30, 2, &th_track);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
}
- SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD);
- }
- s = ns;
- }
- } else if (id > 0 && gid == 0) {
- SCLogError(SC_ERR_INVALID_VALUE, "Can't use a event config that has "
- "sid > 0 and gid == 0. Please fix this "
- "in your threshold.conf file");
- } else {
- sig = SigFindSignatureBySidGid(de_ctx,id,gid);
- if(sig != NULL) {
- if ((parsed_type == TYPE_SUPPRESS) && (parsed_track == TRACK_RULE)) {
- sig->flags |= SIG_FLAG_NOALERT;
- goto end;
- }
+ ret = pcre_get_substring((char *)rule_extend, ov, 30, 3, &th_count);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
- if (parsed_type != TYPE_SUPPRESS && parsed_type != TYPE_THRESHOLD &&
- parsed_type != TYPE_BOTH && parsed_type != TYPE_LIMIT)
- {
- m = SigMatchGetLastSMFromLists(sig, 2,
- DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ ret = pcre_get_substring((char *)rule_extend, ov, 30, 4, &th_seconds);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
- if (m != NULL) {
- SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
- "a threshold set. The signature event var is "
- "given precedence over the threshold.conf one. "
- "Bug #425.", sig->id);
- goto end;
+ if (strcasecmp(th_type,"limit") == 0)
+ parsed_type = TYPE_LIMIT;
+ else if (strcasecmp(th_type,"both") == 0)
+ parsed_type = TYPE_BOTH;
+ else if (strcasecmp(th_type,"threshold") == 0)
+ parsed_type = TYPE_THRESHOLD;
+ else {
+ SCLogError(SC_ERR_INVALID_ARGUMENTS, "limit type not supported: %s", th_type);
+ goto error;
+ }
+ } else {
+ SCLogError(SC_ERR_INVALID_ARGUMENTS, "rule invalid: %s", rawstr);
+ goto error;
+ }
+ break;
+ case THRESHOLD_TYPE_SUPPRESS:
+ if (strlen(rule_extend) > 0) {
+ ret = pcre_exec(regex_suppress, regex_suppress_study,
+ rule_extend, strlen(rule_extend),
+ 0, 0, ov, MAX_SUBSTRINGS);
+ if (ret < 2) {
+ SCLogError(SC_ERR_PCRE_MATCH,
+ "pcre_exec parse error, ret %" PRId32 ", string %s",
+ ret, rule_extend);
+ goto error;
+ }
+ /* retrieve the track mode */
+ ret = pcre_get_substring((char *)rule_extend, ov, 30, 1, &th_track);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
+ /* retrieve the IP */
+ ret = pcre_get_substring((char *)rule_extend, ov, 30, 2, &th_ip);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
+ } else {
+ parsed_track = TRACK_RULE;
+ }
+ parsed_type = TYPE_SUPPRESS;
+ break;
+ case THRESHOLD_TYPE_RATE:
+ if (strlen(rule_extend) > 0) {
+ ret = pcre_exec(regex_rate, regex_rate_study,
+ rule_extend, strlen(rule_extend),
+ 0, 0, ov, MAX_SUBSTRINGS);
+ if (ret < 5) {
+ SCLogError(SC_ERR_PCRE_MATCH,
+ "pcre_exec parse error, ret %" PRId32 ", string %s",
+ ret, rule_extend);
+ goto error;
}
- m = SigMatchGetLastSMFromLists(sig, 2,
- DETECT_DETECTION_FILTER, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]);
-
- if (m != NULL) {
- SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has "
- "a detection_filter set. The signature event var is "
- "given precedence over the threshold.conf one. "
- "Bug #425.", sig->id);
- goto end;
+ ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 1, &th_track);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
}
- /* replace threshold on sig if we have a global override for it */
- } else if (parsed_type == TYPE_THRESHOLD || parsed_type == TYPE_BOTH || parsed_type == TYPE_LIMIT) {
- m = SigMatchGetLastSMFromLists(sig, 2,
- DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]);
- if (m == NULL) {
- m = SigMatchGetLastSMFromLists(sig, 2,
- DETECT_DETECTION_FILTER, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 2, &th_count);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
}
- if (m != NULL) {
- SigMatchRemoveSMFromList(sig, m, DETECT_SM_LIST_THRESHOLD);
- SigMatchFree(m);
- m = NULL;
+
+ ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 3, &th_seconds);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
}
- }
- de = SCMalloc(sizeof(DetectThresholdData));
- if (unlikely(de == NULL))
- goto error;
+ ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 4, &th_new_action);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
- memset(de,0,sizeof(DetectThresholdData));
+ ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 5, &th_timeout);
+ if (ret < 0) {
+ SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
+ goto error;
+ }
- de->type = parsed_type;
- de->track = parsed_track;
- de->count = parsed_count;
- de->seconds = parsed_seconds;
- de->new_action = parsed_new_action;
- de->timeout = parsed_timeout;
- de->addr = NULL;
+ /* TODO: implement option "apply_to" */
- if ((parsed_type == TYPE_SUPPRESS) && (parsed_track != TRACK_RULE)) {
- de->addr = DetectAddressInit();
- if (de->addr == NULL) {
- SCLogError(SC_ERR_MEM_ALLOC, "Can't init DetectAddress");
+ if (ByteExtractStringUint32(&parsed_timeout, 10, strlen(th_timeout), th_timeout) <= 0) {
goto error;
}
- if (DetectAddressParseString(de->addr, (char *)th_ip) < 0) {
- SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Can't add %s to address group", th_ip);
- goto error;
+
+ /* Get the new action to take */
+ if (strcasecmp(th_new_action, "alert") == 0)
+ parsed_new_action = TH_ACTION_ALERT;
+ if (strcasecmp(th_new_action, "drop") == 0)
+ parsed_new_action = TH_ACTION_DROP;
+ if (strcasecmp(th_new_action, "pass") == 0)
+ parsed_new_action = TH_ACTION_PASS;
+ if (strcasecmp(th_new_action, "reject") == 0)
+ parsed_new_action = TH_ACTION_REJECT;
+ if (strcasecmp(th_new_action, "log") == 0) {
+ SCLogInfo("log action for rate_filter not supported yet");
+ parsed_new_action = TH_ACTION_LOG;
+ }
+ if (strcasecmp(th_new_action, "sdrop") == 0) {
+ SCLogInfo("sdrop action for rate_filter not supported yet");
+ parsed_new_action = TH_ACTION_SDROP;
}
+ parsed_type = TYPE_RATE;
+ } else {
+ SCLogError(SC_ERR_INVALID_ARGUMENTS, "rule invalid: %s", rawstr);
+ goto error;
}
+ break;
+ default:
+ SCLogError(SC_ERR_PCRE_MATCH, "unable to find rule type for string %s", rawstr);
+ goto error;
+ }
- sm = SigMatchAlloc();
- if (sm == NULL) {
- SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch");
+ switch (rule_type) {
+ /* This part is common to threshold/event_filter/rate_filter */
+ case THRESHOLD_TYPE_EVENT_FILTER:
+ case THRESHOLD_TYPE_THRESHOLD:
+ case THRESHOLD_TYPE_RATE:
+ if (strcasecmp(th_track,"by_dst") == 0)
+ parsed_track = TRACK_DST;
+ else if (strcasecmp(th_track,"by_src") == 0)
+ parsed_track = TRACK_SRC;
+ else if (strcasecmp(th_track,"by_rule") == 0)
+ parsed_track = TRACK_RULE;
+ else {
+ SCLogError(SC_ERR_INVALID_VALUE, "Invalid track parameter %s in %s", th_track, rawstr);
goto error;
}
- if (parsed_type == TYPE_RATE)
- sm->type = DETECT_DETECTION_FILTER;
- else
- sm->type = DETECT_THRESHOLD;
- sm->ctx = (void *)de;
+ if (ByteExtractStringUint32(&parsed_count, 10, strlen(th_count), th_count) <= 0) {
+ goto error;
+ }
+ if (parsed_count == 0) {
+ SCLogError(SC_ERR_INVALID_VALUE, "rate filter count should be > 0");
+ goto error;
+ }
- if (parsed_track == TRACK_RULE) {
- de_ctx->ths_ctx.th_entry = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *));
- if (de_ctx->ths_ctx.th_entry == NULL) {
- SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config"
- " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1);
- } else {
- de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL;
- de_ctx->ths_ctx.th_size++;
+ if (ByteExtractStringUint32(&parsed_seconds, 10, strlen(th_seconds), th_seconds) <= 0) {
+ goto error;
+ }
+
+ break;
+ case THRESHOLD_TYPE_SUPPRESS:
+ /* need to get IP if extension is provided */
+ if (th_track != NULL) {
+ if (strcasecmp(th_track,"by_dst") == 0)
+ parsed_track = TRACK_DST;
+ else if (strcasecmp(th_track,"by_src") == 0)
+ parsed_track = TRACK_SRC;
+ else {
+ SCLogError(SC_ERR_INVALID_VALUE, "Invalid track parameter %s in %s", th_track, rule_extend);
+ goto error;
}
}
+ break;
+ }
- SigMatchAppendSMToList(sig, sm, DETECT_SM_LIST_THRESHOLD);
- }
+ if (ByteExtractStringUint32(&id, 10, strlen(th_sid), th_sid) <= 0) {
+ goto error;
+ }
+
+ if (ByteExtractStringUint32(&gid, 10, strlen(th_gid), th_gid) <= 0) {
+ goto error;
+ }
+
+ int r = 0;
+ if (parsed_type == TYPE_SUPPRESS) {
+ r = SetupSuppressRule(de_ctx, id, gid, parsed_type, parsed_track,
+ parsed_count, parsed_seconds, parsed_timeout, parsed_new_action,
+ th_ip);
+ } else {
+ r = SetupThresholdRule(de_ctx, id, gid, parsed_type, parsed_track,
+ parsed_count, parsed_seconds, parsed_timeout, parsed_new_action,
+ th_ip);
+ }
+ if (r < 0) {
+ goto error;
}
-end:
fret = 0;
error:
- if (fret == -1) {
- if (de != NULL) {
- if (de->addr != NULL) DetectAddressFree(de->addr);
- SCFree(de);
- }
- }
- if(th_rule_type != NULL) SCFree((char *)th_rule_type);
- if(th_sid != NULL) SCFree((char *)th_sid);
- if(th_gid != NULL) SCFree((char *)th_gid);
- if(th_track != NULL) SCFree((char *)th_track);
- if(th_count != NULL) SCFree((char *)th_count);
- if(th_seconds != NULL) SCFree((char *)th_seconds);
- if(th_type != NULL) SCFree((char *)th_type);
- if(th_ip != NULL) SCFree((char *)th_ip);
- if(rule_extend != NULL) SCFree((char *)rule_extend);
+ if (th_rule_type != NULL)
+ SCFree((char *)th_rule_type);
+ if (th_sid != NULL)
+ SCFree((char *)th_sid);
+ if (th_gid != NULL)
+ SCFree((char *)th_gid);
+ if (th_track != NULL)
+ SCFree((char *)th_track);
+ if (th_count != NULL)
+ SCFree((char *)th_count);
+ if (th_seconds != NULL)
+ SCFree((char *)th_seconds);
+ if (th_type != NULL)
+ SCFree((char *)th_type);
+ if (th_ip != NULL)
+ SCFree((char *)th_ip);
+ if (rule_extend != NULL)
+ SCFree((char *)rule_extend);
return fret;
}
SCThresholdConfInitContext(de_ctx,fd);
m = SigMatchGetLastSMFromLists(sig, 2,
- DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]);
+ DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_SUPPRESS]);
- if(m != NULL) {
+ if (m != NULL) {
de = (DetectThresholdData *)m->ctx;
if(de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC))
result = 1;
SCThresholdConfInitContext(de_ctx,fd);
SigGroupBuild(de_ctx);
- if (s->sm_lists[DETECT_SM_LIST_THRESHOLD] == NULL) {
+ if (s->sm_lists[DETECT_SM_LIST_SUPPRESS] == NULL) {
printf("no thresholds: ");
goto end;
}
- sm = s->sm_lists[DETECT_SM_LIST_THRESHOLD];
+ sm = s->sm_lists[DETECT_SM_LIST_SUPPRESS];
if (sm == NULL) {
printf("no sm: ");
goto end;
SCThresholdConfInitContext(de_ctx,fd);
SigGroupBuild(de_ctx);
- if (s->sm_lists[DETECT_SM_LIST_THRESHOLD] == NULL) {
+ if (s->sm_lists[DETECT_SM_LIST_SUPPRESS] == NULL) {
printf("no thresholds: ");
goto end;
}
- sm = s->sm_lists[DETECT_SM_LIST_THRESHOLD];
+ sm = s->sm_lists[DETECT_SM_LIST_SUPPRESS];
if (sm == NULL) {
printf("no sm: ");
goto end;
return result;
}
+/**
+ * \brief Creates a dummy threshold file, with all valid options, for testing purposes.
+ *
+ * \retval fd Pointer to file descriptor.
+ */
+FILE *SCThresholdConfGenerateValidDummyFD20()
+{
+ FILE *fd = NULL;
+ const char *buffer =
+ "suppress gen_id 1, sig_id 1000, track by_src, ip 2.2.3.4\n"
+ "suppress gen_id 1, sig_id 1000, track by_src, ip 1.2.3.4\n"
+ "suppress gen_id 1, sig_id 1000, track by_src, ip 192.168.1.1\n";
+
+ fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
+ if (fd == NULL)
+ SCLogDebug("Error with SCFmemopen() called by Threshold Config test code");
+
+ return fd;
+}
+
+/**
+ * \test Check if the threshold file is loaded and well parsed
+ *
+ * \retval 1 on succces
+ * \retval 0 on failure
+ */
+static int SCThresholdConfTest20(void)
+{
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ DetectThresholdData *de = NULL;
+ Signature *sig = NULL;
+ SigMatch *m = NULL;
+ int result = 0;
+ FILE *fd = NULL;
+
+ HostInitConfig(HOST_QUIET);
+
+ if (de_ctx == NULL)
+ return result;
+
+ de_ctx->flags |= DE_QUIET;
+
+ sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; content:\"abc\"; sid:1000;)");
+ if (sig == NULL) {
+ goto end;
+ }
+
+ fd = SCThresholdConfGenerateValidDummyFD20();
+ SCThresholdConfInitContext(de_ctx,fd);
+
+ m = SigMatchGetLastSMFromLists(sig, 2,
+ DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_SUPPRESS]);
+ if (m != NULL) {
+ de = (DetectThresholdData *)m->ctx;
+ if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) {
+ m = m->next;
+ if (m != NULL) {
+ de = (DetectThresholdData *)m->ctx;
+ if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) {
+ m = m->next;
+ if (m != NULL) {
+ de = (DetectThresholdData *)m->ctx;
+ if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) {
+ result = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+end:
+ SigGroupBuild(de_ctx);
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ HostShutdown();
+ return result;
+}
+
+/**
+ * \test Check if the threshold file is loaded and well parsed, and applied
+ * correctly to a rule with thresholding
+ *
+ * \retval 1 on succces
+ * \retval 0 on failure
+ */
+static int SCThresholdConfTest21(void)
+{
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ DetectThresholdData *de = NULL;
+ Signature *sig = NULL;
+ SigMatch *m = NULL;
+ int result = 0;
+ FILE *fd = NULL;
+
+ HostInitConfig(HOST_QUIET);
+
+ if (de_ctx == NULL)
+ return result;
+
+ de_ctx->flags |= DE_QUIET;
+
+ sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; content:\"abc\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
+ if (sig == NULL) {
+ goto end;
+ }
+
+ fd = SCThresholdConfGenerateValidDummyFD20();
+ SCThresholdConfInitContext(de_ctx,fd);
+
+ m = SigMatchGetLastSMFromLists(sig, 2,
+ DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_SUPPRESS]);
+ if (m != NULL) {
+ de = (DetectThresholdData *)m->ctx;
+ if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) {
+ m = m->next;
+ if (m != NULL) {
+ de = (DetectThresholdData *)m->ctx;
+ if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) {
+ m = m->next;
+ if (m != NULL) {
+ de = (DetectThresholdData *)m->ctx;
+ if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) {
+ result = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+end:
+ SigGroupBuild(de_ctx);
+ SigGroupCleanup(de_ctx);
+ SigCleanSignatures(de_ctx);
+ DetectEngineCtxFree(de_ctx);
+ HostShutdown();
+ return result;
+}
+
#endif /* UNITTESTS */
/**
UtRegisterTest("SCThresholdConfTest18 - suppress parsing", SCThresholdConfTest18, 1);
UtRegisterTest("SCThresholdConfTest19 - suppress parsing", SCThresholdConfTest19, 1);
+ UtRegisterTest("SCThresholdConfTest20 - suppress parsing", SCThresholdConfTest20, 1);
+ UtRegisterTest("SCThresholdConfTest21 - suppress parsing", SCThresholdConfTest21, 1);
#endif /* UNITTESTS */
}