suricata
detect-metadata.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2017 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Implements metadata keyword support
24  *
25  * \todo Do we need to do anything more this is used in snort host attribute table
26  * It is also used for rule managment.
27  */
28 
29 #include "suricata-common.h"
30 #include "detect.h"
31 #include "detect-parse.h"
32 #include "detect-engine.h"
33 #include "detect-metadata.h"
34 #include "util-hash-string.h"
35 #include "util-unittest.h"
36 
37 static int DetectMetadataSetup (DetectEngineCtx *, Signature *, const char *);
38 static void DetectMetadataRegisterTests(void);
39 
41 {
42  sigmatch_table[DETECT_METADATA].name = "metadata";
43  sigmatch_table[DETECT_METADATA].desc = "used for logging";
44  sigmatch_table[DETECT_METADATA].url = "/rules/meta.html#metadata";
46  sigmatch_table[DETECT_METADATA].Setup = DetectMetadataSetup;
48  sigmatch_table[DETECT_METADATA].RegisterTests = DetectMetadataRegisterTests;
49 }
50 
51 /**
52  * \brief Free a Metadata object
53  */
55 {
56  SCEnter();
57 
58  SCFree(mdata);
59 
60  SCReturn;
61 }
62 
64 {
66  return 0;
67 
69  if (de_ctx->metadata_table == NULL)
70  return -1;
71  return 0;
72 }
73 
75 {
78 }
79 
80 static const char *DetectMedatataHashAdd(DetectEngineCtx *de_ctx, const char *string)
81 {
82  const char * hstring = (char *)HashTableLookup(de_ctx->metadata_table, (void *)string, strlen(string));
83  if (hstring) {
84  return hstring;
85  }
86 
87  const char *astring = SCStrdup(string);
88  if (astring == NULL) {
89  return NULL;
90  }
91 
92  if (HashTableAdd(de_ctx->metadata_table, (void *)astring, strlen(astring)) == 0) {
93  return (char *)HashTableLookup(de_ctx->metadata_table, (void *)astring, strlen(astring));
94  } else {
95  SCFree((void *)astring);
96  }
97  return NULL;
98 }
99 
100 static int DetectMetadataParse(DetectEngineCtx *de_ctx, Signature *s, const char *metadatastr)
101 {
102  char copy[strlen(metadatastr)+1];
103  strlcpy(copy, metadatastr, sizeof(copy));
104  char *xsaveptr = NULL;
105  char *key = strtok_r(copy, ",", &xsaveptr);
106  while (key != NULL) {
107  while (*key != '\0' && isblank(*key)) {
108  key++;
109  }
110  char *val = strchr(key, ' ');
111  if (val != NULL) {
112  *val++ = '\0';
113  while (*val != '\0' && isblank(*val)) {
114  val++;
115  }
116  } else {
117  /* Skip metadata without a value. */
118  goto next;
119  }
120 
121  /* Also skip metadata if the key or value is empty. */
122  if (strlen(key) == 0 || strlen(val) == 0) {
123  goto next;
124  }
125 
126  const char *hkey = DetectMedatataHashAdd(de_ctx, key);
127  if (hkey == NULL) {
128  SCLogError(SC_ERR_MEM_ALLOC, "can't create metadata key");
129  continue;
130  }
131 
132  const char *hval = DetectMedatataHashAdd(de_ctx, val);
133  if (hval == NULL) {
134  SCLogError(SC_ERR_MEM_ALLOC, "can't create metadata value");
135  goto next;
136  }
137 
138  SCLogDebug("key: %s, value: %s", hkey, hval);
139 
140  DetectMetadata *dkv = SCMalloc(sizeof(DetectMetadata));
141  if (dkv == NULL) {
142  goto next;
143  }
144  dkv->key = hkey;
145  dkv->value = hval;
146  dkv->next = s->metadata;
147  s->metadata = dkv;
148 
149  next:
150  key = strtok_r(NULL, ",", &xsaveptr);
151  }
152 
153  return 0;
154 }
155 
156 static int DetectMetadataSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
157 {
159  DetectMetadataParse(de_ctx, s, rawstr);
160  }
161 
162  return 0;
163 }
164 
165 #ifdef UNITTESTS
166 
167 static int DetectMetadataParseTest01(void)
168 {
172 
174  "alert tcp any any -> any any "
175  "(metadata: toto 1; sid:1; rev:1;)");
176  FAIL_IF_NULL(sig);
177  FAIL_IF(sig->metadata);
178 
180  PASS;
181 }
182 
183 static int DetectMetadataParseTest02(void)
184 {
186  DetectEngineCtx *de_ctx = NULL;
187  DetectMetadata *dm;
188 
192  "alert tcp any any -> any any "
193  "(metadata: toto 1; "
194  "metadata: titi 2, jaivu gros_minet;"
195  "sid:1; rev:1;)");
196  FAIL_IF_NULL(sig);
197  FAIL_IF_NULL(sig->metadata);
198  FAIL_IF_NULL(sig->metadata->key);
199  FAIL_IF(strcmp("jaivu", sig->metadata->key));
200  FAIL_IF(strcmp("gros_minet", sig->metadata->value));
201  FAIL_IF_NULL(sig->metadata->next);
202  dm = sig->metadata->next;
203  FAIL_IF(strcmp("titi", dm->key));
204  dm = dm->next;
205  FAIL_IF_NULL(dm);
206  FAIL_IF(strcmp("toto", dm->key));
207 
209  PASS;
210 }
211 
212 #endif /* UNITTESTS */
213 
214 /**
215  * \brief this function registers unit tests for DetectCipService
216  */
217 static void DetectMetadataRegisterTests(void)
218 {
219 #ifdef UNITTESTS
220  UtRegisterTest("DetectMetadataParseTest01", DetectMetadataParseTest01);
221  UtRegisterTest("DetectMetadataParseTest02", DetectMetadataParseTest02);
222 #endif /* UNITTESTS */
223 }
224 
SigTableElmt_::url
const char * url
Definition: detect.h:1212
util-hash-string.h
DetectMetadataFree
void DetectMetadataFree(DetectMetadata *mdata)
Free a Metadata object.
Definition: detect-metadata.c:54
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SigTableElmt_::desc
const char * desc
Definition: detect.h:1211
DetectMetadata_::value
const char * value
Definition: detect-metadata.h:34
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1200
DetectMetadata_::key
const char * key
Definition: detect-metadata.h:32
DetectEngineMustParseMetadata
int DetectEngineMustParseMetadata(void)
Definition: detect-engine.c:4225
SigTableElmt_::name
const char * name
Definition: detect.h:1209
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
Signature_::metadata
DetectMetadata * metadata
Definition: detect.h:592
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:766
DetectMetadataHashInit
int DetectMetadataHashInit(DetectEngineCtx *de_ctx)
Definition: detect-metadata.c:63
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2089
DetectMetadataRegister
void DetectMetadataRegister(void)
Definition: detect-metadata.c:40
StringHashCompareFunc
char StringHashCompareFunc(void *data1, uint16_t datalen1, void *data2, uint16_t datalen2)
Definition: util-hash-string.c:35
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1195
StringHashFunc
uint32_t StringHashFunc(HashTable *ht, void *data, uint16_t datalen)
Definition: util-hash-string.c:22
util-unittest.h
HashTableFree
void HashTableFree(HashTable *ht)
Definition: util-hash.c:79
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
HashTableLookup
void * HashTableLookup(HashTable *ht, void *data, uint16_t datalen)
Definition: util-hash.c:193
DetectMetadataHashFree
void DetectMetadataHashFree(DetectEngineCtx *de_ctx)
Definition: detect-metadata.c:74
DETECT_METADATA
@ DETECT_METADATA
Definition: detect-engine-register.h:55
detect.h
HashTableAdd
int HashTableAdd(HashTable *ht, void *data, uint16_t datalen)
Definition: util-hash.c:113
StringHashFreeFunc
void StringHashFreeFunc(void *data)
Definition: util-hash-string.c:48
SCReturn
#define SCReturn
Definition: util-debug.h:302
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1178
DetectMetadata_
Signature metadata list.
Definition: detect-metadata.h:30
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2326
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
suricata-common.h
detect-metadata.h
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
DetectEngineUnsetParseMetadata
void DetectEngineUnsetParseMetadata(void)
Definition: detect-engine.c:4220
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DetectMetadata_::next
struct DetectMetadata_ * next
Definition: detect-metadata.h:36
detect-parse.h
Signature_
Signature container.
Definition: detect.h:527
HashTableInit
HashTable * HashTableInit(uint32_t size, uint32_t(*Hash)(struct HashTable_ *, void *, uint16_t), char(*Compare)(void *, uint16_t, void *, uint16_t), void(*Free)(void *))
Definition: util-hash.c:34
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2044
SC_ERR_MEM_ALLOC
@ SC_ERR_MEM_ALLOC
Definition: util-error.h:31
DetectEngineSetParseMetadata
void DetectEngineSetParseMetadata(void)
Definition: detect-engine.c:4215
DetectEngineCtx_::metadata_table
HashTable * metadata_table
Definition: detect.h:921
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1201