suricata
detect-filesize.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2020 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 the filesize keyword
24 */
25
26#include "suricata-common.h"
27#include "app-layer-protos.h"
28#include "app-layer-htp.h"
29#include "util-unittest.h"
31#include "util-misc.h"
32
33#include "detect.h"
34#include "detect-parse.h"
35#include "detect-engine.h"
36#include "detect-engine-state.h"
37#include "detect-engine-uint.h"
38#include "detect-engine-build.h"
39
40#include "detect-filesize.h"
41#include "util-debug.h"
42#include "util-byte.h"
43#include "flow-util.h"
44#include "stream-tcp.h"
45
46
47/*prototypes*/
48static int DetectFilesizeMatch (DetectEngineThreadCtx *det_ctx, Flow *f,
49 uint8_t flags, File *file, const Signature *s, const SigMatchCtx *m);
50static int DetectFilesizeSetup (DetectEngineCtx *, Signature *, const char *);
51static void DetectFilesizeFree (DetectEngineCtx *, void *);
52#ifdef UNITTESTS
53static void DetectFilesizeRegisterTests (void);
54#endif
55static int g_file_match_list_id = 0;
56
57/**
58 * \brief Registration function for filesize: keyword
59 */
60
62{
64 sigmatch_table[DETECT_FILESIZE].desc = "match on the size of the file as it is being transferred";
65 sigmatch_table[DETECT_FILESIZE].url = "/rules/file-keywords.html#filesize";
66 sigmatch_table[DETECT_FILESIZE].FileMatch = DetectFilesizeMatch;
67 sigmatch_table[DETECT_FILESIZE].Setup = DetectFilesizeSetup;
68 sigmatch_table[DETECT_FILESIZE].Free = DetectFilesizeFree;
70#ifdef UNITTESTS
71 sigmatch_table[DETECT_FILESIZE].RegisterTests = DetectFilesizeRegisterTests;
72#endif
73
74 g_file_match_list_id = DetectBufferTypeRegister("files");
75}
76
77/**
78 * \brief This function is used to match filesize rule option.
79 *
80 * \param t thread local vars
81 * \param det_ctx pattern matcher thread local data
82 * \param f *LOCKED* flow
83 * \param flags direction flags
84 * \param file file being inspected
85 * \param s signature being inspected
86 * \param m sigmatch that we will cast into DetectU64Data
87 *
88 * \retval 0 no match
89 * \retval 1 match
90 */
91static int DetectFilesizeMatch (DetectEngineThreadCtx *det_ctx, Flow *f,
92 uint8_t flags, File *file, const Signature *s, const SigMatchCtx *m)
93{
94 SCEnter();
95
97 int ret = 0;
98 uint64_t file_size = FileTrackedSize(file);
99
100 SCLogDebug("file size %" PRIu64 ", check %" PRIu64, file_size, fsd->arg1);
101
102 if (file->state == FILE_STATE_CLOSED) {
103 return DetectU64Match(file_size, fsd);
104 /* truncated, error: only see if what we have meets the GT condition */
105 } else if (file->state > FILE_STATE_CLOSED) {
106 if (fsd->mode == DETECT_UINT_GT || fsd->mode == DETECT_UINT_GTE) {
107 ret = DetectU64Match(file_size, fsd);
108 }
109 }
110 SCReturnInt(ret);
111}
112
113/**
114 * \brief this function is used to parse filesize data into the current signature
115 *
116 * \param de_ctx pointer to the Detection Engine Context
117 * \param s pointer to the Current Signature
118 * \param str pointer to the user provided options
119 *
120 * \retval 0 on Success
121 * \retval -1 on Failure
122 */
123static int DetectFilesizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
124{
125 SCEnter();
127 if (fsd == NULL)
128 SCReturnInt(-1);
129
131 de_ctx, s, DETECT_FILESIZE, (SigMatchCtx *)fsd, g_file_match_list_id) == NULL) {
132 DetectFilesizeFree(de_ctx, fsd);
133 SCReturnInt(-1);
134 }
135
137 SCReturnInt(0);
138}
139
140/**
141 * \brief this function will free memory associated with DetectU64Data
142 *
143 * \param ptr pointer to DetectU64Data
144 */
145static void DetectFilesizeFree(DetectEngineCtx *de_ctx, void *ptr)
146{
147 SCDetectU64Free(ptr);
148}
149
150#ifdef UNITTESTS
151#include "stream.h"
152#include "stream-tcp-private.h"
154#include "detect-engine-mpm.h"
155#include "app-layer-parser.h"
156
157/** \test Test the Filesize keyword setup */
158static int DetectFilesizeParseTest01(void)
159{
160 DetectU64Data *fsd = DetectU64Parse("10");
161 FAIL_IF_NULL(fsd);
162 FAIL_IF_NOT(fsd->arg1 == 10);
163 FAIL_IF_NOT(fsd->mode == DETECT_UINT_EQ);
164 DetectFilesizeFree(NULL, fsd);
165
166 PASS;
167}
168
169/** \test Test the Filesize keyword setup */
170static int DetectFilesizeParseTest02(void)
171{
172 DetectU64Data *fsd = DetectU64Parse(" < 10 ");
173 FAIL_IF_NULL(fsd);
174 FAIL_IF_NOT(fsd->arg1 == 10);
175 FAIL_IF_NOT(fsd->mode == DETECT_UINT_LT);
176 DetectFilesizeFree(NULL, fsd);
177
178 PASS;
179}
180
181/** \test Test the Filesize keyword setup */
182static int DetectFilesizeParseTest03(void)
183{
184 DetectU64Data *fsd = DetectU64Parse(" > 10 ");
185 FAIL_IF_NULL(fsd);
186 FAIL_IF_NOT(fsd->arg1 == 10);
187 FAIL_IF_NOT(fsd->mode == DETECT_UINT_GT);
188 DetectFilesizeFree(NULL, fsd);
189
190 PASS;
191}
192
193/** \test Test the Filesize keyword setup */
194static int DetectFilesizeParseTest04(void)
195{
196 DetectU64Data *fsd = DetectU64Parse(" 5 <> 10 ");
197 FAIL_IF_NULL(fsd);
198 FAIL_IF_NOT(fsd->arg1 == 5);
199 FAIL_IF_NOT(fsd->arg2 == 10);
200 FAIL_IF_NOT(fsd->mode == DETECT_UINT_RA);
201 DetectFilesizeFree(NULL, fsd);
202
203 PASS;
204}
205
206/** \test Test the Filesize keyword setup */
207static int DetectFilesizeParseTest05(void)
208{
209 DetectU64Data *fsd = DetectU64Parse("5<>10");
210 FAIL_IF_NULL(fsd);
211 FAIL_IF_NOT(fsd->arg1 == 5);
212 FAIL_IF_NOT(fsd->arg2 == 10);
213 FAIL_IF_NOT(fsd->mode == DETECT_UINT_RA);
214 DetectFilesizeFree(NULL, fsd);
215
216 PASS;
217}
218
219/**
220 * \brief this function is used to initialize the detection engine context and
221 * setup the signature with passed values.
222 *
223 */
224
225static int DetectFilesizeInitTest(
226 DetectEngineCtx **de_ctx, Signature **sig, DetectU64Data **fsd, const char *str)
227{
228 char fullstr[1024];
229 *de_ctx = NULL;
230
232 (*de_ctx)->flags |= DE_QUIET;
234
235 *sig = NULL;
236
237 FAIL_IF(snprintf(fullstr, 1024,
238 "alert http any any -> any any (msg:\"Filesize "
239 "test\"; filesize:%s; sid:1;)",
240 str) >= 1024);
241
242 Signature *s = DetectEngineAppendSig(*de_ctx, fullstr);
243 FAIL_IF_NULL(s);
244
245 *sig = (*de_ctx)->sig_list;
246
247 *fsd = DetectU64Parse(str);
248
249 PASS;
250}
251
252/**
253 * \test DetectFilesizeSetpTest01 is a test for setting up an valid filesize values
254 * with valid "<>" operator and include spaces arround the given values.
255 * In the test the values are setup with initializing the detection engine
256 * context and setting up the signature itself.
257 */
258
259static int DetectFilesizeSetpTest01(void)
260{
261
262 DetectU64Data *fsd = NULL;
263 uint8_t res = 0;
264 Signature *sig = NULL;
265 DetectEngineCtx *de_ctx = NULL;
266
267 res = DetectFilesizeInitTest(&de_ctx, &sig, &fsd, "1 <> 3 ");
268 FAIL_IF(res == 0);
269
270 FAIL_IF_NULL(fsd);
271 FAIL_IF_NOT(fsd->arg1 == 1);
272 FAIL_IF_NOT(fsd->arg2 == 3);
273 FAIL_IF_NOT(fsd->mode == DETECT_UINT_RA);
274
275 DetectFilesizeFree(NULL, fsd);
277
278 PASS;
279}
280
281/**
282 * \brief this function registers unit tests for DetectFilesize
283 */
284void DetectFilesizeRegisterTests(void)
285{
286 UtRegisterTest("DetectFilesizeParseTest01", DetectFilesizeParseTest01);
287 UtRegisterTest("DetectFilesizeParseTest02", DetectFilesizeParseTest02);
288 UtRegisterTest("DetectFilesizeParseTest03", DetectFilesizeParseTest03);
289 UtRegisterTest("DetectFilesizeParseTest04", DetectFilesizeParseTest04);
290 UtRegisterTest("DetectFilesizeParseTest05", DetectFilesizeParseTest05);
291 UtRegisterTest("DetectFilesizeSetpTest01", DetectFilesizeSetpTest01);
292}
293#endif /* UNITTESTS */
uint8_t flags
Definition decode-gre.h:0
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Data structures and function prototypes for keeping state for the detection engine.
DetectUintData_u64 * DetectU64Parse(const char *u64str)
int DetectU64Match(const uint64_t parg, const DetectUintData_u64 *du64)
#define DETECT_UINT_LT
DetectUintData_u64 DetectU64Data
#define DETECT_UINT_GTE
#define DETECT_UINT_EQ
#define DETECT_UINT_GT
#define DETECT_UINT_RA
int DetectBufferTypeRegister(const char *name)
void DetectFilesizeRegister(void)
Registration function for filesize: keyword.
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
#define FILE_SIG_NEED_SIZE
Definition detect.h:327
#define SIGMATCH_SUPPORT_DIR
Definition detect.h:1684
#define DE_QUIET
Definition detect.h:330
#define FILE_SIG_NEED_FILE
Definition detect.h:320
SCMutex m
Definition flow-hash.h:6
DetectEngineCtx * de_ctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
main detection engine ctx
Definition detect.h:932
FileState state
Definition util-file.h:82
Flow data structure.
Definition flow.h:356
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
uint16_t flags
Definition detect.h:1450
const char * desc
Definition detect.h:1461
void(* RegisterTests)(void)
Definition detect.h:1448
const char * name
Definition detect.h:1459
int(* FileMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, File *, const Signature *, const SigMatchCtx *)
Definition detect.h:1429
Signature container.
Definition detect.h:668
uint8_t file_flags
Definition detect.h:684
#define str(s)
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
uint64_t FileTrackedSize(const File *file)
get the size of the file
Definition util-file.c:326
@ FILE_STATE_CLOSED
Definition util-file.h:71