detect-metadata: store metadata key value pairs

This patch updates the Signature structure so it contains the
metadata under a key value form.
Later patch will make that dictionary available in the events.
pull/3204/head
Eric Leblond 9 years ago committed by Jason Ish
parent d0ea147263
commit 474fc60671

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
/* Copyright (C) 2007-2017 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
@ -28,23 +28,148 @@
#include "suricata-common.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-metadata.h"
#define PARSE_REGEX "^\\s*([^\\s]+)\\s+([^\\s]+)(?:,\\s*([^\\s]+)\\s+([^\\s]+))*$"
#define PARSE_TAG_REGEX "\\s*([^\\s]+)\\s+([^,]+)\\s*"
static pcre *parse_regex;
static pcre_extra *parse_regex_study;
static pcre *parse_tag_regex;
static pcre_extra *parse_tag_regex_study;
static int DetectMetadataSetup (DetectEngineCtx *, Signature *, const char *);
void DetectMetadataRegister (void)
{
sigmatch_table[DETECT_METADATA].name = "metadata";
sigmatch_table[DETECT_METADATA].desc = "ignored by suricata";
sigmatch_table[DETECT_METADATA].desc = "used by suricata for logging";
sigmatch_table[DETECT_METADATA].url = DOC_URL DOC_VERSION "/rules/meta.html#metadata";
sigmatch_table[DETECT_METADATA].Match = NULL;
sigmatch_table[DETECT_METADATA].Setup = DetectMetadataSetup;
sigmatch_table[DETECT_METADATA].Free = NULL;
sigmatch_table[DETECT_METADATA].RegisterTests = NULL;
DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
DetectSetupParseRegexes(PARSE_TAG_REGEX, &parse_tag_regex, &parse_tag_regex_study);
}
/**
* \brief Free a Metadata object
*/
void DetectMetadataFree(DetectMetadata *mdata)
{
SCEnter();
if (mdata->key != NULL) {
SCFree((void *)mdata->key);
}
if (mdata->value != NULL) {
SCFree((void *)mdata->value);
}
SCFree(mdata);
SCReturn;
}
static int DetectMetadataParse(Signature *s, const char *metadatastr)
{
#define MAX_SUBSTRINGS 30
int ret = 0, res = 0;
int ov[MAX_SUBSTRINGS];
ret = pcre_exec(parse_regex, parse_regex_study, metadatastr,
strlen(metadatastr), 0, 0, ov, MAX_SUBSTRINGS);
if (ret < 2) {
/* Only warn user that the metadata are not parsed due
* to invalid format */
SCLogInfo("signature metadata not in key value format, ret %" PRId32
", string %s", ret, metadatastr);
return 0;
}
char *saveptr = NULL;
size_t metadatalen = strlen(metadatastr)+1;
char rawstr[metadatalen];
strlcpy(rawstr, metadatastr, metadatalen);
char * kv = strtok_r(rawstr, ",", &saveptr);
const char *key = NULL;
const char *value = NULL;
char pkey[256];
char pvalue[256];
/* now check key value */
do {
DetectMetadata *dkv;
ret = pcre_exec(parse_tag_regex, parse_tag_regex_study, kv, strlen(kv), 0, 0, ov, MAX_SUBSTRINGS);
if (ret < 2) {
SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32
", string %s", ret, rawstr);
goto error;
}
res = pcre_copy_substring(kv, ov, MAX_SUBSTRINGS, 1, pkey, sizeof(pkey));
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
goto error;
}
key = SCStrdup(pkey);
if (key == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "can't create metadata key");
goto error;
}
res = pcre_copy_substring(kv, ov, MAX_SUBSTRINGS, 2, pvalue, sizeof(pvalue));
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
goto error;
}
value = SCStrdup(pvalue);
if (value == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "can't create metadata value");
goto error;
}
SCLogDebug("key: %s, value: %s", key, value);
dkv = SCMalloc(sizeof(DetectMetadata));
if (dkv) {
dkv->key = key;
if (!dkv->key) {
SCFree(dkv);
} else {
dkv->value = value;
if (!dkv->value) {
SCFree((void *)dkv->key);
SCFree(dkv);
} else {
dkv->next = s->metadata;
s->metadata = dkv;
}
}
} else {
goto error;
}
kv = strtok_r(NULL, ",", &saveptr);
} while (kv);
return 0;
error:
if (key)
SCFree((void *)key);
if (value)
SCFree((void *)value);
return -1;
}
static int DetectMetadataSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
static int DetectMetadataSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
{
DetectMetadataParse(s, rawstr);
return 0;
}

@ -24,8 +24,22 @@
#ifndef __DETECT_METADATA_H__
#define __DETECT_METADATA_H__
/**
* \brief Signature metadata list.
*/
typedef struct DetectMetadata_ {
/* pointer to key */
const char *key;
/* value data */
const char *value;
/* next reference in the signature */
struct DetectMetadata_ *next;
} DetectMetadata;
/* prototypes */
void DetectMetadataRegister (void);
void DetectMetadataFree(DetectMetadata *mdata);
#endif /* __DETECT_METADATA_H__ */

@ -1184,6 +1184,36 @@ Signature *SigAlloc (void)
return sig;
}
/**
* \internal
* \brief Free Medadata list
*
* \param s Pointer to the signature
*/
static void SigMetadataFree(Signature *s)
{
SCEnter();
DetectMetadata *mdata = NULL;
DetectMetadata *next_mdata = NULL;
if (s == NULL) {
SCReturn;
}
SCLogDebug("s %p, s->metadata %p", s, s->metadata);
for (mdata = s->metadata; mdata != NULL;) {
next_mdata = mdata->next;
DetectMetadataFree(mdata);
mdata = next_mdata;
}
s->metadata = NULL;
SCReturn;
}
/**
* \internal
* \brief Free Reference list
@ -1294,6 +1324,7 @@ void SigFree(Signature *s)
}
SigRefFree(s);
SigMetadataFree(s);
DetectEngineAppInspectionEngineSignatureFree(s);

@ -30,6 +30,7 @@
#include "detect-engine-proto.h"
#include "detect-reference.h"
#include "detect-metadata.h"
#include "packet-queue.h"
#include "util-prefilter.h"
@ -457,6 +458,8 @@ typedef struct Signature_ {
char *class_msg;
/** Reference */
DetectReference *references;
/** Metadata */
DetectMetadata *metadata;
/* Be careful, this pointer is only valid while parsing the sig,
* to warn the user about any possible problem */

Loading…
Cancel
Save