suricata
detect-file-data.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2022 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 */
24
25#include "suricata-common.h"
26#include "threads.h"
27#include "decode.h"
28
29#include "detect.h"
30#include "detect-parse.h"
31
32#include "detect-engine.h"
34#include "detect-engine-mpm.h"
35#include "detect-engine-state.h"
38#include "detect-engine-file.h"
39#include "detect-file-data.h"
40
41#include "app-layer.h"
42#include "app-layer-parser.h"
43#include "app-layer-htp.h"
44#include "app-layer-smtp.h"
45
46#include "flow.h"
47#include "flow-var.h"
48#include "flow-util.h"
49
50#include "util-debug.h"
51#include "util-spm-bm.h"
52#include "util-unittest.h"
55#include "util-profiling.h"
56
57static int DetectFiledataSetup (DetectEngineCtx *, Signature *, const char *);
58#ifdef UNITTESTS
59static void DetectFiledataRegisterTests(void);
60#endif
61static void DetectFiledataSetupCallback(const DetectEngineCtx *de_ctx,
62 Signature *s);
63static int g_file_data_buffer_id = 0;
64
65/* file API */
67 const DetectBufferMpmRegistry *mpm_reg, int list_id);
68
69// file protocols with common file handling
76
77/* Table with all filehandler registrations */
79
80#define ALPROTO_WITHFILES_MAX 16
81
82// file protocols with common file handling
85 { .alproto = ALPROTO_SMB, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
86 { .alproto = ALPROTO_FTP, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
87 { .alproto = ALPROTO_FTPDATA, .direction = SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT },
88 { .alproto = ALPROTO_HTTP1,
90 .to_client_progress = HTP_RESPONSE_PROGRESS_BODY,
91 .to_server_progress = HTP_REQUEST_PROGRESS_BODY },
92 { .alproto = ALPROTO_HTTP2,
94 .to_client_progress = HTTP2StateDataServer,
95 .to_server_progress = HTTP2StateDataClient },
96 { .alproto = ALPROTO_SMTP, .direction = SIG_FLAG_TOSERVER }, { .alproto = ALPROTO_UNKNOWN }
97};
98
100 AppProto alproto, int direction, int to_client_progress, int to_server_progress)
101{
102 size_t i = 0;
103 while (i < ALPROTO_WITHFILES_MAX && al_protocols[i].alproto != ALPROTO_UNKNOWN) {
104 i++;
105 }
106 if (i == ALPROTO_WITHFILES_MAX) {
107 return;
108 }
109 al_protocols[i].alproto = alproto;
110 al_protocols[i].direction = direction;
111 al_protocols[i].to_client_progress = to_client_progress;
112 al_protocols[i].to_server_progress = to_server_progress;
113 if (i + 1 < ALPROTO_WITHFILES_MAX) {
115 }
116}
117
144
145/**
146 * \brief Registration function for keyword: file_data
147 */
149{
150 sigmatch_table[DETECT_FILE_DATA].name = "file.data";
152 sigmatch_table[DETECT_FILE_DATA].desc = "make content keywords match on file data";
153 sigmatch_table[DETECT_FILE_DATA].url = "/rules/file-keywords.html#file-data";
154 sigmatch_table[DETECT_FILE_DATA].Setup = DetectFiledataSetup;
155#ifdef UNITTESTS
157#endif
159
164
165 DetectBufferTypeRegisterSetupCallback("file_data", DetectFiledataSetupCallback);
166
167 DetectBufferTypeSetDescriptionByName("file_data", "data from tracked files");
169
170 g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
171}
172
173static void SetupDetectEngineConfig(DetectEngineCtx *de_ctx) {
175 return;
176
178 if (unlikely(de_ctx->filedata_config == NULL))
179 return;
180 /* initialize default */
181 for (AppProto i = 0; i < g_alproto_max; i++) {
184 }
185
186 /* add protocol specific settings here */
187
188 /* SMTP */
192}
193
194/**
195 * \brief this function is used to parse filedata options
196 * \brief into the current signature
197 *
198 * \param de_ctx pointer to the Detection Engine Context
199 * \param s pointer to the Current Signature
200 * \param str pointer to the user provided "filestore" option
201 *
202 * \retval 0 on Success
203 * \retval -1 on Failure
204 */
205static int DetectFiledataSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
206{
207 SCEnter();
208
209 if (!DetectProtoContainsProto(&s->proto, IPPROTO_TCP)) {
210 SCLogError("The 'file_data' keyword cannot be used with non-TCP protocols");
211 return -1;
212 }
213
214 if (s->alproto != ALPROTO_UNKNOWN && !AppLayerParserSupportsFiles(IPPROTO_TCP, s->alproto)) {
215 SCLogError("The 'file_data' keyword cannot be used with TCP protocol %s",
217 return -1;
218 }
219
222 SCLogError("The 'file-data' keyword cannot be used with SMTP flow:to_client or "
223 "flow:from_server.");
224 return -1;
225 }
226
228 return -1;
229
232 // we cannot use a transactional rule with a fast pattern to client and this
234 SCLogError("fast_pattern cannot be used on to_client keyword for "
235 "transactional rule with a streaming buffer to server %u",
236 s->id);
237 return -1;
238 }
240 }
241
242 SetupDetectEngineConfig(de_ctx);
243 return 0;
244}
245
246static void DetectFiledataSetupCallback(const DetectEngineCtx *de_ctx,
247 Signature *s)
248{
249 if (s->alproto == ALPROTO_HTTP1 || s->alproto == ALPROTO_UNKNOWN ||
250 s->alproto == ALPROTO_HTTP) {
252 }
253
254 /* server body needs to be inspected in sync with stream if possible */
256
257 SCLogDebug("callback invoked by %u", s->id);
258}
259
260/* common */
261
262static void PrefilterMpmFiledataFree(void *ptr)
263{
264 SCFree(ptr);
265}
266
267/* file API based inspection */
268
269static inline InspectionBuffer *FiledataWithXformsGetDataCallback(DetectEngineThreadCtx *det_ctx,
270 const DetectEngineTransforms *transforms, const int list_id, int local_file_id,
271 InspectionBuffer *base_buffer)
272{
273 InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_file_id);
274 if (buffer == NULL) {
275 SCLogDebug("list_id: %d: no buffer", list_id);
276 return NULL;
277 }
278 if (buffer->initialized) {
279 SCLogDebug("list_id: %d: returning %p", list_id, buffer);
280 return buffer;
281 }
282
284 det_ctx, buffer, transforms, base_buffer->inspect, base_buffer->inspect_len);
285 buffer->inspect_offset = base_buffer->inspect_offset;
286 SCLogDebug("xformed buffer %p size %u", buffer, buffer->inspect_len);
287 SCReturnPtr(buffer, "InspectionBuffer");
288}
289
290static InspectionBuffer *FiledataGetDataCallback(DetectEngineThreadCtx *det_ctx,
291 const DetectEngineTransforms *transforms, Flow *f, uint8_t flow_flags, File *cur_file,
292 const int list_id, const int base_id, int local_file_id, void *txv)
293{
294 SCEnter();
295 SCLogDebug("starting: list_id %d base_id %d", list_id, base_id);
296
297 InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, base_id, local_file_id);
298 SCLogDebug("base: buffer %p", buffer);
299 if (buffer == NULL)
300 return NULL;
301 if (base_id != list_id && buffer->inspect != NULL) {
302 SCLogDebug("handle xform %s", (list_id != base_id) ? "true" : "false");
303 return FiledataWithXformsGetDataCallback(
304 det_ctx, transforms, list_id, local_file_id, buffer);
305 }
306 if (buffer->initialized) {
307 SCLogDebug("base_id: %d, not first: use %p", base_id, buffer);
308 return buffer;
309 }
310
311 const uint64_t file_size = FileDataSize(cur_file);
312 const DetectEngineCtx *de_ctx = det_ctx->de_ctx;
313 uint32_t content_limit = FILEDATA_CONTENT_LIMIT;
314 uint32_t content_inspect_min_size = FILEDATA_CONTENT_INSPECT_MIN_SIZE;
315 if (de_ctx->filedata_config) {
316 content_limit = de_ctx->filedata_config[f->alproto].content_limit;
317 content_inspect_min_size = de_ctx->filedata_config[f->alproto].content_inspect_min_size;
318 }
319
320 SCLogDebug("[list %d] content_limit %u, content_inspect_min_size %u", list_id, content_limit,
321 content_inspect_min_size);
322
323 SCLogDebug("[list %d] file %p size %" PRIu64 ", state %d", list_id, cur_file, file_size,
324 cur_file->state);
325
326 /* no new data */
327 if (cur_file->content_inspected == file_size) {
328 SCLogDebug("no new data");
329 goto empty_return;
330 }
331
332 if (file_size == 0) {
333 SCLogDebug("no data to inspect for this transaction");
334 goto empty_return;
335 }
336
337 SCLogDebug("offset %" PRIu64, StreamingBufferGetOffset(cur_file->sb));
338 SCLogDebug("size %" PRIu64, cur_file->size);
339 SCLogDebug("content_inspected %" PRIu64, cur_file->content_inspected);
340 SCLogDebug("inspect_window %" PRIu32, cur_file->inspect_window);
341 SCLogDebug("inspect_min_size %" PRIu32, cur_file->inspect_min_size);
342
343 bool ips = false;
344 uint64_t offset = 0;
345 if (f->alproto == ALPROTO_HTTP1) {
346
347 htp_tx_t *tx = txv;
348 HtpState *htp_state = f->alstate;
349 ips = htp_state->cfg->http_body_inline;
350
351 const bool body_done = AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP1, tx,
352 flow_flags) > HTP_RESPONSE_PROGRESS_BODY;
353
354 SCLogDebug("response.body_limit %u file_size %" PRIu64
355 ", cur_file->inspect_min_size %" PRIu32 ", EOF %s, progress > body? %s",
356 htp_state->cfg->response.body_limit, file_size, cur_file->inspect_min_size,
357 flow_flags & STREAM_EOF ? "true" : "false", BOOL2STR(body_done));
358
359 if (!htp_state->cfg->http_body_inline) {
360 /* inspect the body if the transfer is complete or we have hit
361 * our body size limit */
362 if ((htp_state->cfg->response.body_limit == 0 ||
363 file_size < htp_state->cfg->response.body_limit) &&
364 file_size < cur_file->inspect_min_size && !body_done &&
365 !(flow_flags & STREAM_EOF)) {
366 SCLogDebug("we still haven't seen the entire response body. "
367 "Let's defer body inspection till we see the "
368 "entire body.");
369 goto empty_return;
370 }
371 SCLogDebug("inline and we're continuing");
372 }
373
374 bool force = (flow_flags & STREAM_EOF) || (cur_file->state > FILE_STATE_OPENED) ||
375 body_done || htp_state->cfg->http_body_inline;
376 /* get the inspect buffer
377 *
378 * make sure that we have at least the configured inspect_win size.
379 * If we have more, take at least 1/4 of the inspect win size before
380 * the new data.
381 */
382 if (cur_file->content_inspected == 0) {
383 if (!force && file_size < cur_file->inspect_min_size) {
384 SCLogDebug("skip as file_size %" PRIu64 " < inspect_min_size %u", file_size,
385 cur_file->inspect_min_size);
386 goto empty_return;
387 }
388 } else {
389 uint64_t new_data = file_size - cur_file->content_inspected;
390 DEBUG_VALIDATE_BUG_ON(new_data == 0);
391 if (new_data < cur_file->inspect_window) {
392 uint64_t inspect_short = cur_file->inspect_window - new_data;
393 if (cur_file->content_inspected < inspect_short) {
394 offset = 0;
395 SCLogDebug("offset %" PRIu64, offset);
396 } else {
397 offset = cur_file->content_inspected - inspect_short;
398 SCLogDebug("offset %" PRIu64, offset);
399 }
400 } else {
401 BUG_ON(cur_file->content_inspected == 0);
402 uint32_t margin = cur_file->inspect_window / 4;
403 if ((uint64_t)margin <= cur_file->content_inspected) {
404 offset = cur_file->content_inspected - (cur_file->inspect_window / 4);
405 } else {
406 offset = 0;
407 }
408 SCLogDebug("offset %" PRIu64 " (data from offset %" PRIu64 ")", offset,
409 file_size - offset);
410 }
411 }
412
413 } else {
414 if ((content_limit == 0 || file_size < content_limit) &&
415 file_size < content_inspect_min_size && !(flow_flags & STREAM_EOF) &&
416 !(cur_file->state > FILE_STATE_OPENED)) {
417 SCLogDebug("we still haven't seen the entire content. "
418 "Let's defer content inspection till we see the "
419 "entire content. We've seen %ld and need at least %d",
420 file_size, content_inspect_min_size);
421 goto empty_return;
422 }
423 offset = cur_file->content_inspected;
424 }
425
426 const uint8_t *data;
427 uint32_t data_len;
428
429 SCLogDebug("Fetching data at offset: %ld", offset);
430 StreamingBufferGetDataAtOffset(cur_file->sb, &data, &data_len, offset);
431 SCLogDebug("data_len %u", data_len);
432 /* update inspected tracker */
433 buffer->inspect_offset = offset;
434
435 if (ips && file_size < cur_file->inspect_min_size) {
436 // don't update content_inspected yet
437 } else {
438 SCLogDebug("content inspected: %" PRIu64, cur_file->content_inspected);
439 cur_file->content_inspected = MAX(cur_file->content_inspected, offset + data_len);
440 SCLogDebug("content inspected: %" PRIu64, cur_file->content_inspected);
441 }
442
443 InspectionBufferSetupMulti(det_ctx, buffer, NULL, data, data_len);
444 SCLogDebug("[list %d] [before] buffer offset %" PRIu64 "; buffer len %" PRIu32
445 "; data_len %" PRIu32 "; file_size %" PRIu64,
446 list_id, buffer->inspect_offset, buffer->inspect_len, data_len, file_size);
447
448 if (f->alproto == ALPROTO_HTTP1 && flow_flags & STREAM_TOCLIENT) {
449 HtpState *htp_state = f->alstate;
450 /* built-in 'transformation' */
451 if (htp_state->cfg->swf_decompression_enabled) {
452 int swf_file_type = FileIsSwfFile(data, data_len);
453 if (swf_file_type == FILE_SWF_ZLIB_COMPRESSION ||
454 swf_file_type == FILE_SWF_LZMA_COMPRESSION) {
455 SCLogDebug("decompressing ...");
456 (void)FileSwfDecompression(data, data_len, det_ctx, buffer,
457 htp_state->cfg->swf_compression_type, htp_state->cfg->swf_decompress_depth,
458 htp_state->cfg->swf_compress_depth);
459 SCLogDebug("uncompressed buffer %p size %u; buf: \"%s\"", buffer,
460 buffer->inspect_len, (char *)buffer->inspect);
461 }
462 }
463 }
464
465 SCLogDebug("content inspected: %" PRIu64, cur_file->content_inspected);
466
467 /* get buffer for the list id if it is different from the base id */
468 if (list_id != base_id) {
469 SCLogDebug("regular %d has been set up: now handle xforms id %d", base_id, list_id);
470 InspectionBuffer *tbuffer = FiledataWithXformsGetDataCallback(
471 det_ctx, transforms, list_id, local_file_id, buffer);
472 SCReturnPtr(tbuffer, "InspectionBuffer");
473 }
474 SCReturnPtr(buffer, "InspectionBuffer");
475
476empty_return:
478 return NULL;
479}
480
482 const DetectEngineAppInspectionEngine *engine, const Signature *s, Flow *f, uint8_t flags,
483 void *alstate, void *txv, uint64_t tx_id)
484{
485 const DetectEngineTransforms *transforms = NULL;
486 if (!engine->mpm) {
487 transforms = engine->v2.transforms;
488 }
489
491 FileContainer *ffc = files.fc;
492 if (ffc == NULL) {
494 }
495 if (ffc->head == NULL) {
496 const bool eof = (AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) >
497 engine->progress);
498 if (eof && engine->match_on_null) {
500 }
502 }
503
504 int local_file_id = 0;
505 File *file = ffc->head;
506 for (; file != NULL; file = file->next) {
507 InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx, transforms, f, flags, file,
508 engine->sm_list, engine->sm_list_base, local_file_id, txv);
509 if (buffer == NULL) {
510 local_file_id++;
511 continue;
512 }
513
514 bool eof = (file->state == FILE_STATE_CLOSED);
515 uint8_t ciflags = eof ? DETECT_CI_FLAGS_END : 0;
516 if (buffer->inspect_offset == 0)
517 ciflags |= DETECT_CI_FLAGS_START;
518
519 const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f,
520 buffer->inspect, buffer->inspect_len, buffer->inspect_offset, ciflags,
522 if (match) {
524 }
525 local_file_id++;
526 }
527
529}
530
531/** \brief Filedata Filedata Mpm prefilter callback
532 *
533 * \param det_ctx detection engine thread ctx
534 * \param pectx inspection context
535 * \param p packet to inspect
536 * \param f flow to inspect
537 * \param txv tx to inspect
538 * \param idx transaction id
539 * \param flags STREAM_* flags including direction
540 */
541static void PrefilterTxFiledata(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p,
542 Flow *f, void *txv, const uint64_t idx, const AppLayerTxData *txd, const uint8_t flags)
543{
544 SCEnter();
545
547 return;
548
549 const PrefilterMpmFiledata *ctx = (const PrefilterMpmFiledata *)pectx;
550 const MpmCtx *mpm_ctx = ctx->mpm_ctx;
551 const int list_id = ctx->list_id;
552
554 FileContainer *ffc = files.fc;
555 if (ffc != NULL) {
556 int local_file_id = 0;
557 for (File *file = ffc->head; file != NULL; file = file->next) {
558 InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx, ctx->transforms, f, flags,
559 file, list_id, ctx->base_list_id, local_file_id, txv);
560 if (buffer == NULL) {
561 local_file_id++;
562 continue;
563 }
564 SCLogDebug("[%" PRIu64 "] buffer size %u", p->pcap_cnt, buffer->inspect_len);
565
566 if (buffer->inspect_len >= mpm_ctx->minlen) {
567 uint32_t prev_rule_id_array_cnt = det_ctx->pmq.rule_id_array_cnt;
568 (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, &det_ctx->mtc, &det_ctx->pmq,
569 buffer->inspect, buffer->inspect_len);
571
572 if (det_ctx->pmq.rule_id_array_cnt > prev_rule_id_array_cnt) {
574 "%u matches", det_ctx->pmq.rule_id_array_cnt - prev_rule_id_array_cnt);
575 }
576 }
577 local_file_id++;
578 }
579 }
580}
581
583 const DetectBufferMpmRegistry *mpm_reg, int list_id)
584{
585 PrefilterMpmFiledata *pectx = SCCalloc(1, sizeof(*pectx));
586 if (pectx == NULL)
587 return -1;
588 pectx->list_id = list_id;
589 pectx->base_list_id = mpm_reg->sm_list_base;
590 pectx->mpm_ctx = mpm_ctx;
591 pectx->transforms = &mpm_reg->transforms;
592
593 return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxFiledata,
594 mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress,
595 pectx, PrefilterMpmFiledataFree, mpm_reg->pname);
596}
597
598#ifdef UNITTESTS
600#endif
AppLayerGetFileState AppLayerParserGetTxFiles(const Flow *f, void *tx, const uint8_t direction)
bool AppLayerParserSupportsFiles(uint8_t ipproto, AppProto alproto)
int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto, void *alstate, uint8_t flags)
get the progress value for a tx/protocol
struct AppLayerGetFileState AppLayerGetFileState
struct AppLayerTxData AppLayerTxData
#define AppLayerParserHasFilesInDir(txd, direction)
check if tx (possibly) has files in this tx for the direction
AppProto g_alproto_max
uint16_t AppProto
@ ALPROTO_NFS
@ ALPROTO_HTTP2
@ ALPROTO_FTP
@ ALPROTO_SMTP
@ ALPROTO_HTTP
@ ALPROTO_SMB
@ ALPROTO_UNKNOWN
@ ALPROTO_FTPDATA
@ ALPROTO_HTTP1
#define FILEDATA_CONTENT_LIMIT
#define FILEDATA_CONTENT_INSPECT_MIN_SIZE
SMTPConfig smtp_config
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition app-layer.c:1009
uint8_t flags
Definition decode-gre.h:0
int SCDetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len, const uint64_t stream_start_offset, const uint8_t flags, const enum DetectContentInspectionType inspection_mode)
wrapper around DetectEngineContentInspectionInternal to return true/false only
@ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
#define DETECT_CI_FLAGS_END
#define DETECT_CI_FLAGS_START
void InspectionBufferSetupMultiEmpty(InspectionBuffer *buffer)
setup the buffer empty
InspectionBuffer * InspectionBufferMultipleForListGet(DetectEngineThreadCtx *det_ctx, const int list_id, const uint32_t local_id)
for a InspectionBufferMultipleForList get a InspectionBuffer
void InspectionBufferSetupMulti(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, const DetectEngineTransforms *transforms, const uint8_t *data, const uint32_t data_len)
setup the buffer with our initial data
void DetectAppLayerMpmRegister(const char *name, int direction, int priority, PrefilterRegisterFunc PrefilterRegister, InspectionBufferGetDataPtr GetData, AppProto alproto, int tx_min_progress)
register an app layer keyword for mpm
int PrefilterAppendTxEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, PrefilterTxFn PrefilterTxFunc, AppProto alproto, int tx_min_progress, void *pectx, void(*FreeFunc)(void *pectx), const char *name)
int DetectProtoContainsProto(const DetectProto *dp, int proto)
see if a DetectProto contains a certain proto
@ DETECT_TBLSIZE_STATIC
Data structures and function prototypes for keeping state for the detection engine.
#define DETECT_ENGINE_INSPECT_SIG_MATCH
#define DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILES
#define DETECT_ENGINE_INSPECT_SIG_NO_MATCH
void DetectBufferTypeSetDescriptionByName(const char *name, const char *desc)
void DetectBufferTypeRegisterSetupCallback(const char *name, void(*SetupCallback)(const DetectEngineCtx *, Signature *))
void DetectBufferTypeSupportsMultiInstance(const char *name)
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
int DetectBufferTypeGetByName(const char *name)
void DetectFileRegisterProto(AppProto alproto, int direction, int to_client_progress, int to_server_progress)
DetectFileHandlerProtocol_t al_protocols[ALPROTO_WITHFILES_MAX]
DetectFileHandlerTableElmt filehandler_table[DETECT_TBLSIZE_STATIC]
void DetectFiledataRegister(void)
Registration function for keyword: file_data.
void DetectFileRegisterFileProtocols(DetectFileHandlerTableElmt *reg)
#define ALPROTO_WITHFILES_MAX
uint8_t DetectEngineInspectFiledata(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
int PrefilterMpmFiledataRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
SigTableElmt * sigmatch_table
#define SIGMATCH_SUPPORT_DIR
Definition detect.h:1684
#define SIG_FLAG_TOCLIENT
Definition detect.h:272
#define SIG_FLAG_INIT_FLOW
Definition detect.h:292
#define SIG_FLAG_INIT_TXDIR_STREAMING_TOSERVER
Definition detect.h:304
#define SIG_FLAG_INIT_NEED_FLUSH
Definition detect.h:297
#define SIG_FLAG_INIT_FILEDATA
Definition detect.h:300
#define SIG_FLAG_INIT_TXDIR_FAST_TOCLIENT
Definition detect.h:306
#define SIG_FLAG_TOSERVER
Definition detect.h:271
#define SIGMATCH_OPTIONAL_OPT
Definition detect.h:1661
#define SIG_FLAG_INIT_FORCE_TOCLIENT
Definition detect.h:301
DetectEngineCtx * de_ctx
void AppLayerHtpEnableResponseBodyCallback(void)
Sets a flag that informs the HTP app layer that some module in the engine needs the http request body...
struct Thresholds ctx
one time registration of keywords at start up
Definition detect.h:762
DetectEngineTransforms transforms
Definition detect.h:775
struct DetectBufferMpmRegistry_::@98::@100 app_v2
const DetectEngineTransforms * transforms
Definition detect.h:436
struct DetectEngineAppInspectionEngine_::@90 v2
main detection engine ctx
Definition detect.h:932
DetectFileDataCfg * filedata_config
Definition detect.h:1039
MpmThreadCtx mtc
Definition detect.h:1345
DetectEngineCtx * de_ctx
Definition detect.h:1364
PrefilterRuleStore pmq
Definition detect.h:1349
uint32_t content_limit
Definition detect.h:915
uint32_t content_inspect_min_size
Definition detect.h:916
InspectionBufferGetDataPtr GetData
PrefilterRegisterFunc PrefilterFn
InspectEngineFuncPtr Callback
uint32_t inspect_window
Definition util-file.h:103
StreamingBuffer * sb
Definition util-file.h:83
uint64_t size
Definition util-file.h:102
FileState state
Definition util-file.h:82
uint32_t inspect_min_size
Definition util-file.h:104
struct File_ * next
Definition util-file.h:92
uint64_t content_inspected
Definition util-file.h:99
Flow data structure.
Definition flow.h:356
uint8_t proto
Definition flow.h:378
AppProto alproto
application level protocol
Definition flow.h:450
void * alstate
Definition flow.h:479
uint32_t body_limit
HtpSwfCompressType swf_compression_type
uint32_t swf_decompress_depth
int swf_decompression_enabled
HTPCfgDir response
uint32_t swf_compress_depth
const struct HTPCfgRec_ * cfg
uint8_t mpm_type
Definition util-mpm.h:95
uint16_t minlen
Definition util-mpm.h:104
uint32_t(* Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
Definition util-mpm.h:178
uint64_t pcap_cnt
Definition decode.h:626
const DetectEngineTransforms * transforms
uint32_t content_inspect_min_size
uint32_t content_limit
Container for matching data for a signature group.
Definition detect.h:1629
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
uint16_t flags
Definition detect.h:1450
const char * desc
Definition detect.h:1461
void(* RegisterTests)(void)
Definition detect.h:1448
const char * alias
Definition detect.h:1460
const char * name
Definition detect.h:1459
uint32_t init_flags
Definition detect.h:608
Signature container.
Definition detect.h:668
uint32_t flags
Definition detect.h:669
SignatureInitData * init_data
Definition detect.h:747
AppProto alproto
Definition detect.h:673
DetectProto proto
Definition detect.h:687
uint32_t id
Definition detect.h:713
#define BUG_ON(x)
#define MAX(x, y)
#define str(s)
void DetectFiledataRegisterTests(void)
#define SCEnter(...)
Definition util-debug.h:277
#define BOOL2STR(b)
Definition util-debug.h:535
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnPtr(x, type)
Definition util-debug.h:293
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len, DetectEngineThreadCtx *det_ctx, InspectionBuffer *out_buffer, int swf_type, uint32_t decompress_depth, uint32_t compress_depth)
This function decompresses a buffer with zlib/lzma algorithm.
int FileIsSwfFile(const uint8_t *buffer, uint32_t buffer_len)
@ FILE_SWF_ZLIB_COMPRESSION
@ FILE_SWF_LZMA_COMPRESSION
uint64_t FileDataSize(const File *file)
get the size of the file data
Definition util-file.c:309
@ FILE_STATE_OPENED
Definition util-file.h:70
@ FILE_STATE_CLOSED
Definition util-file.h:71
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
Definition util-mpm.c:47
#define unlikely(expr)
#define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes)
int StreamingBufferGetDataAtOffset(const StreamingBuffer *sb, const uint8_t **data, uint32_t *data_len, uint64_t offset)
uint64_t offset
#define DEBUG_VALIDATE_BUG_ON(exp)