diff --git a/src/Makefile.am b/src/Makefile.am index 8158772b1e..b68c503ca4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -122,7 +122,7 @@ detect-engine-modbus.c detect-engine-modbus.h \ detect-engine-enip.c detect-engine-enip.h \ detect-engine-event.c detect-engine-event.h \ detect-engine-file.c detect-engine-file.h \ -detect-engine-filedata-smtp.c detect-engine-filedata-smtp.h \ +detect-engine-filedata.c detect-engine-filedata.h \ detect-engine-hcbd.c detect-engine-hcbd.h \ detect-engine-hcd.c detect-engine-hcd.h \ detect-engine-hhhd.c detect-engine-hhhd.h \ diff --git a/src/detect-engine-filedata-smtp.c b/src/detect-engine-filedata.c similarity index 75% rename from src/detect-engine-filedata-smtp.c rename to src/detect-engine-filedata.c index f2790e4829..e36ccecb14 100644 --- a/src/detect-engine-filedata-smtp.c +++ b/src/detect-engine-filedata.c @@ -34,7 +34,7 @@ #include "detect-engine-state.h" #include "detect-engine-content-inspection.h" #include "detect-engine-prefilter.h" -#include "detect-engine-filedata-smtp.h" +#include "detect-engine-filedata.h" #include "flow-util.h" #include "util-debug.h" @@ -58,33 +58,33 @@ #define BUFFER_STEP 50 -static inline int SMTPCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size) +static inline int FiledataCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size) { void *ptmp; - if (size > det_ctx->smtp_buffers_size) { - ptmp = SCRealloc(det_ctx->smtp, - (det_ctx->smtp_buffers_size + BUFFER_STEP) * sizeof(FiledataReassembledBody)); + if (size > det_ctx->file_data_buffers_size) { + ptmp = SCRealloc(det_ctx->file_data, + (det_ctx->file_data_buffers_size + BUFFER_STEP) * sizeof(FiledataReassembledBody)); if (ptmp == NULL) { - SCFree(det_ctx->smtp); - det_ctx->smtp = NULL; - det_ctx->smtp_buffers_size = 0; - det_ctx->smtp_buffers_list_len = 0; + SCFree(det_ctx->file_data); + det_ctx->file_data = NULL; + det_ctx->file_data_buffers_size = 0; + det_ctx->file_data_buffers_list_len = 0; return -1; } - det_ctx->smtp = ptmp; + det_ctx->file_data = ptmp; - memset(det_ctx->smtp + det_ctx->smtp_buffers_size, 0, BUFFER_STEP * sizeof(FiledataReassembledBody)); - det_ctx->smtp_buffers_size += BUFFER_STEP; + memset(det_ctx->file_data + det_ctx->file_data_buffers_size, 0, BUFFER_STEP * sizeof(FiledataReassembledBody)); + det_ctx->file_data_buffers_size += BUFFER_STEP; } - for (int i = det_ctx->smtp_buffers_list_len; i < (size); i++) { - det_ctx->smtp[i].buffer_len = 0; - det_ctx->smtp[i].offset = 0; + for (int i = det_ctx->file_data_buffers_list_len; i < (size); i++) { + det_ctx->file_data[i].buffer_len = 0; + det_ctx->file_data[i].offset = 0; } return 0; } -static const uint8_t *DetectEngineSMTPGetBufferForTX(uint64_t tx_id, +static const uint8_t *DetectEngineFiledataGetBufferForTX(uint64_t tx_id, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Flow *f, File *curr_file, @@ -99,38 +99,43 @@ static const uint8_t *DetectEngineSMTPGetBufferForTX(uint64_t tx_id, *stream_start_offset = 0; uint64_t file_size = FileDataSize(curr_file); - if (det_ctx->smtp_buffers_list_len == 0) { - if (SMTPCreateSpace(det_ctx, 1) < 0) + const uint32_t content_limit = de_ctx->filedata_config[f->alproto].content_limit; + const uint32_t content_inspect_min_size = de_ctx->filedata_config[f->alproto].content_inspect_min_size; + // TODO this is unused, is that right? + //const uint32_t content_inspect_window = de_ctx->filedata_config[f->alproto].content_inspect_window; + + if (det_ctx->file_data_buffers_list_len == 0) { + if (FiledataCreateSpace(det_ctx, 1) < 0) goto end; index = 0; - if (det_ctx->smtp_buffers_list_len == 0) { - det_ctx->smtp_start_tx_id = tx_id; + if (det_ctx->file_data_buffers_list_len == 0) { + det_ctx->file_data_start_tx_id = tx_id; } - det_ctx->smtp_buffers_list_len++; + det_ctx->file_data_buffers_list_len++; } else { - if ((tx_id - det_ctx->smtp_start_tx_id) < det_ctx->smtp_buffers_list_len) { - if (det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len != 0) { - *buffer_len = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len; - *stream_start_offset = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].offset; - buffer = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer; + if ((tx_id - det_ctx->file_data_start_tx_id) < det_ctx->file_data_buffers_list_len) { + if (det_ctx->file_data[(tx_id - det_ctx->file_data_start_tx_id)].buffer_len != 0) { + *buffer_len = det_ctx->file_data[(tx_id - det_ctx->file_data_start_tx_id)].buffer_len; + *stream_start_offset = det_ctx->file_data[(tx_id - det_ctx->file_data_start_tx_id)].offset; + buffer = det_ctx->file_data[(tx_id - det_ctx->file_data_start_tx_id)].buffer; SCReturnPtr(buffer, "uint8_t"); } } else { - if (SMTPCreateSpace(det_ctx, (tx_id - det_ctx->smtp_start_tx_id) + 1) < 0) + if (FiledataCreateSpace(det_ctx, (tx_id - det_ctx->file_data_start_tx_id) + 1) < 0) goto end; - if (det_ctx->smtp_buffers_list_len == 0) { - det_ctx->smtp_start_tx_id = tx_id; + if (det_ctx->file_data_buffers_list_len == 0) { + det_ctx->file_data_start_tx_id = tx_id; } - det_ctx->smtp_buffers_list_len++; + det_ctx->file_data_buffers_list_len++; } - index = (tx_id - det_ctx->smtp_start_tx_id); + index = (tx_id - det_ctx->file_data_start_tx_id); } - SCLogDebug("smtp_config.content_limit %u, smtp_config.content_inspect_min_size %u", - smtp_config.content_limit, smtp_config.content_inspect_min_size); + SCLogDebug("content_limit %u, content_inspect_min_size %u", + content_limit, content_inspect_min_size); SCLogDebug("file %p size %"PRIu64", state %d", curr_file, file_size, curr_file->state); @@ -145,8 +150,8 @@ static const uint8_t *DetectEngineSMTPGetBufferForTX(uint64_t tx_id, goto end; } - if ((smtp_config.content_limit == 0 || file_size < smtp_config.content_limit) && - file_size < smtp_config.content_inspect_min_size && + if ((content_limit == 0 || file_size < content_limit) && + file_size < content_inspect_min_size && !(flags & STREAM_EOF) && !(curr_file->state > FILE_STATE_OPENED)) { SCLogDebug("we still haven't seen the entire content. " "Let's defer content inspection till we see the " @@ -155,50 +160,56 @@ static const uint8_t *DetectEngineSMTPGetBufferForTX(uint64_t tx_id, } StreamingBufferGetDataAtOffset(curr_file->sb, - &det_ctx->smtp[index].buffer, &det_ctx->smtp[index].buffer_len, + &det_ctx->file_data[index].buffer, &det_ctx->file_data[index].buffer_len, curr_file->content_inspected); - det_ctx->smtp[index].offset = curr_file->content_inspected; + det_ctx->file_data[index].offset = curr_file->content_inspected; - /* updat inspected tracker */ + /* update inspected tracker */ curr_file->content_inspected = FileDataSize(curr_file); SCLogDebug("content_inspected %"PRIu64", offset %"PRIu64, - curr_file->content_inspected, det_ctx->smtp[index].offset); + curr_file->content_inspected, det_ctx->file_data[index].offset); - buffer = det_ctx->smtp[index].buffer; - *buffer_len = det_ctx->smtp[index].buffer_len; - *stream_start_offset = det_ctx->smtp[index].offset; + buffer = det_ctx->file_data[index].buffer; + *buffer_len = det_ctx->file_data[index].buffer_len; + *stream_start_offset = det_ctx->file_data[index].offset; end: SCLogDebug("buffer %p, len %u", buffer, *buffer_len); SCReturnPtr(buffer, "uint8_t"); } -int DetectEngineInspectSMTPFiledata(ThreadVars *tv, +int DetectEngineInspectFiledata(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, uint8_t flags, void *alstate, void *tx, uint64_t tx_id) { - SMTPState *smtp_state = (SMTPState *)alstate; - FileContainer *ffc = smtp_state->files_ts; int r = 0; int match = 0; uint32_t buffer_len = 0; uint32_t stream_start_offset = 0; const uint8_t *buffer = 0; - if (ffc != NULL) { - File *file = ffc->head; - for (; file != NULL; file = file->next) { - buffer = DetectEngineSMTPGetBufferForTX(tx_id, - de_ctx, det_ctx, - f, file, - flags, - &buffer_len, - &stream_start_offset); + FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, + f->alstate, flags); + if (ffc == NULL) { + return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; + } + + File *file = ffc->head; + for (; file != NULL; file = file->next) { + if (file->txid != tx_id) + continue; + + buffer = DetectEngineFiledataGetBufferForTX(tx_id, + de_ctx, det_ctx, + f, file, + flags, + &buffer_len, + &stream_start_offset); if (buffer_len == 0) - goto end; + continue; det_ctx->buffer_offset = 0; det_ctx->discontinue_matching = 0; @@ -209,43 +220,41 @@ int DetectEngineInspectSMTPFiledata(ThreadVars *tv, buffer_len, stream_start_offset, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); - if (match == 1) + if (match == 1) { r = 1; + break; } } -end: if (r == 1) return DETECT_ENGINE_INSPECT_SIG_MATCH; else return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; } -void DetectEngineCleanSMTPBuffers(DetectEngineThreadCtx *det_ctx) +void DetectEngineCleanFiledataBuffers(DetectEngineThreadCtx *det_ctx) { - if (det_ctx->smtp_buffers_list_len > 0) { - for (int i = 0; i < det_ctx->smtp_buffers_list_len; i++) { - det_ctx->smtp[i].buffer_len = 0; - det_ctx->smtp[i].offset = 0; + if (det_ctx->file_data_buffers_list_len > 0) { + for (int i = 0; i < det_ctx->file_data_buffers_list_len; i++) { + det_ctx->file_data[i].buffer_len = 0; + det_ctx->file_data[i].offset = 0; } } - det_ctx->smtp_buffers_list_len = 0; - det_ctx->smtp_start_tx_id = 0; + det_ctx->file_data_buffers_list_len = 0; + det_ctx->file_data_start_tx_id = 0; return; } -/** \brief SMTP Filedata Mpm prefilter callback +/** \brief Filedata Filedata Mpm prefilter callback * * \param det_ctx detection engine thread ctx * \param p packet to inspect * \param f flow to inspect * \param txv tx to inspect * \param pectx inspection context - * - * \todo check files against actual tx */ -static void PrefilterTxSmtpFiledata(DetectEngineThreadCtx *det_ctx, +void PrefilterTxFiledata(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f, void *txv, const uint64_t idx, const uint8_t flags) @@ -253,16 +262,19 @@ static void PrefilterTxSmtpFiledata(DetectEngineThreadCtx *det_ctx, SCEnter(); const MpmCtx *mpm_ctx = (MpmCtx *)pectx; - SMTPState *smtp_state = f->alstate; - FileContainer *ffc = smtp_state->files_ts; + FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, + f->alstate, flags); if (ffc != NULL) { File *file = ffc->head; for (; file != NULL; file = file->next) { + if (file->txid != idx) + continue; + uint32_t buffer_len = 0; uint32_t stream_start_offset = 0; - const uint8_t *buffer = DetectEngineSMTPGetBufferForTX(idx, - NULL, det_ctx, + const uint8_t *buffer = DetectEngineFiledataGetBufferForTX(idx, + det_ctx->de_ctx, det_ctx, f, file, flags, &buffer_len, @@ -275,15 +287,6 @@ static void PrefilterTxSmtpFiledata(DetectEngineThreadCtx *det_ctx, } } -int PrefilterTxSmtpFiledataRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx) -{ - SCEnter(); - - return PrefilterAppendTxEngine(sgh, PrefilterTxSmtpFiledata, - ALPROTO_SMTP, 0, - mpm_ctx, NULL, "file_data (smtp)"); -} - #ifdef UNITTESTS static int DetectEngineSMTPFiledataTest01(void) diff --git a/src/detect-engine-filedata-smtp.h b/src/detect-engine-filedata.h similarity index 71% rename from src/detect-engine-filedata-smtp.h rename to src/detect-engine-filedata.h index a6f3fc4fa8..6a272daa67 100644 --- a/src/detect-engine-filedata-smtp.h +++ b/src/detect-engine-filedata.h @@ -20,20 +20,20 @@ * \author Giuseppe Longo */ -#ifndef __DETECT_ENGINE_FILEDATA_SMTP_H__ -#define __DETECT_ENGINE_FILEDATA_SMTP_H__ - -#include "app-layer-smtp.h" - -int PrefilterTxSmtpFiledataRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx); - -int DetectEngineInspectSMTPFiledata(ThreadVars *tv, +#ifndef __DETECT_ENGINE_FILEDATA_H__ +#define __DETECT_ENGINE_FILEDATA_H__ + +void PrefilterTxFiledata(DetectEngineThreadCtx *det_ctx, + const void *pectx, + Packet *p, Flow *f, void *txv, + const uint64_t idx, const uint8_t flags); +int DetectEngineInspectFiledata(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, uint8_t flags, void *alstate, void *tx, uint64_t tx_id); -void DetectEngineCleanSMTPBuffers(DetectEngineThreadCtx *det_ctx); +void DetectEngineCleanFiledataBuffers(DetectEngineThreadCtx *det_ctx); void DetectEngineSMTPFiledataRegisterTests(void); -#endif /* __DETECT_ENGINE_FILEDATA_SMTP_H__ */ +#endif /* __DETECT_ENGINE_FILEDATA_H__ */ diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 7bf4a74e99..2297c0581c 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -62,7 +62,6 @@ #include "detect-engine-hcbd.h" #include "detect-engine-hsbd.h" #include "detect-engine-dns.h" -#include "detect-engine-filedata-smtp.h" #include "detect-engine-tls.h" #include "stream.h" diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index f91852d5d2..776ebe6fd7 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -54,7 +54,7 @@ #include "detect-tls-cert-serial.h" #include "detect-engine-state.h" #include "detect-engine-analyzer.h" -#include "detect-engine-filedata-smtp.h" +#include "detect-engine-filedata.h" #include "detect-http-cookie.h" #include "detect-http-method.h" diff --git a/src/detect-engine.c b/src/detect-engine.c index 0a0ad08f7a..dad0c8e85a 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -1990,10 +1990,10 @@ static void DetectEngineThreadCtxFree(DetectEngineThreadCtx *det_ctx) SCFree(det_ctx->hcbd); } - /* SMTP */ - if (det_ctx->smtp != NULL) { - SCLogDebug("det_ctx smtp %u", det_ctx->smtp_buffers_size); - SCFree(det_ctx->smtp); + /* file data */ + if (det_ctx->file_data != NULL) { + SCLogDebug("det_ctx file_data %u", det_ctx->file_data_buffers_size); + SCFree(det_ctx->file_data); } /* Decoded base64 data. */ diff --git a/src/detect-file-data.c b/src/detect-file-data.c index 326ebbf784..f0a20f3d2f 100644 --- a/src/detect-file-data.c +++ b/src/detect-file-data.c @@ -33,11 +33,13 @@ #include "detect-engine.h" #include "detect-engine-mpm.h" #include "detect-engine-state.h" - -#include "detect-engine-filedata-smtp.h" +#include "detect-engine-prefilter.h" +#include "detect-engine-filedata.h" #include "detect-engine-hsbd.h" #include "detect-file-data.h" +#include "app-layer-smtp.h" + #include "flow.h" #include "flow-var.h" #include "flow-util.h" @@ -52,6 +54,8 @@ static void DetectFiledataRegisterTests(void); static void DetectFiledataSetupCallback(Signature *s); static int g_file_data_buffer_id = 0; +static int PrefilterTxSmtpFiledataRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx); + /** * \brief Registration function for keyword: file_data */ @@ -76,7 +80,7 @@ void DetectFiledataRegister(void) DetectEngineInspectHttpServerBody); DetectAppLayerInspectEngineRegister("file_data", ALPROTO_SMTP, SIG_FLAG_TOSERVER, 0, - DetectEngineInspectSMTPFiledata); + DetectEngineInspectFiledata); DetectBufferTypeRegisterSetupCallback("file_data", DetectFiledataSetupCallback); @@ -87,6 +91,40 @@ void DetectFiledataRegister(void) g_file_data_buffer_id = DetectBufferTypeGetByName("file_data"); } +static int PrefilterTxSmtpFiledataRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx) +{ + SCEnter(); + + return PrefilterAppendTxEngine(sgh, PrefilterTxFiledata, + ALPROTO_SMTP, 0, + mpm_ctx, NULL, "file_data (smtp)"); +} + +#define FILEDATA_CONTENT_LIMIT 100000 +#define FILEDATA_CONTENT_INSPECT_MIN_SIZE 32768 +#define FILEDATA_CONTENT_INSPECT_WINDOW 4096 + +static void SetupDetectEngineConfig(DetectEngineCtx *de_ctx) { + if (de_ctx->filedata_config_initialized) + return; + + /* initialize default */ + for (int i = 0; i < (int)ALPROTO_MAX; i++) { + de_ctx->filedata_config[i].content_limit = FILEDATA_CONTENT_LIMIT; + de_ctx->filedata_config[i].content_inspect_min_size = FILEDATA_CONTENT_INSPECT_MIN_SIZE; + de_ctx->filedata_config[i].content_inspect_window = FILEDATA_CONTENT_INSPECT_WINDOW; + } + + /* add protocol specific settings here */ + + /* SMTP */ + de_ctx->filedata_config[ALPROTO_SMTP].content_limit = smtp_config.content_limit; + de_ctx->filedata_config[ALPROTO_SMTP].content_inspect_min_size = smtp_config.content_inspect_min_size; + de_ctx->filedata_config[ALPROTO_SMTP].content_inspect_window = smtp_config.content_inspect_window; + + de_ctx->filedata_config_initialized = true; +} + /** * \brief this function is used to parse filedata options * \brief into the current signature @@ -124,6 +162,8 @@ static int DetectFiledataSetup (DetectEngineCtx *de_ctx, Signature *s, const cha } s->init_data->list = DetectBufferTypeGetByName("file_data"); + + SetupDetectEngineConfig(de_ctx); return 0; } diff --git a/src/detect.c b/src/detect.c index c376867335..e11ab0ad14 100644 --- a/src/detect.c +++ b/src/detect.c @@ -48,9 +48,10 @@ #include "detect-engine-prefilter.h" #include "detect-engine-state.h" #include "detect-engine-analyzer.h" +#include "detect-engine-filedata.h" + #include "detect-engine-payload.h" -#include "detect-engine-filedata-smtp.h" #include "detect-engine-event.h" #include "detect-engine-hcbd.h" #include "detect-engine-hsbd.h" @@ -947,7 +948,7 @@ end: DetectEngineCleanHCBDBuffers(det_ctx); DetectEngineCleanHSBDBuffers(det_ctx); - DetectEngineCleanSMTPBuffers(det_ctx); + DetectEngineCleanFiledataBuffers(det_ctx); } } PACKET_PROFILING_DETECT_END(p, PROF_DETECT_CLEANUP); diff --git a/src/detect.h b/src/detect.h index 0e2c022991..4ea043d8f2 100644 --- a/src/detect.h +++ b/src/detect.h @@ -717,6 +717,13 @@ typedef struct DetectEngineCtx_ { DetectEngineThreadKeywordCtxItem *keyword_list; int keyword_id; + struct { + uint32_t content_limit; + uint32_t content_inspect_min_size; + uint32_t content_inspect_window; + } filedata_config[ALPROTO_MAX]; + bool filedata_config_initialized; + #ifdef PROFILING struct SCProfileDetectCtx_ *profile_ctx; struct SCProfileKeywordDetectCtx_ *profile_keyword_ctx; @@ -850,10 +857,10 @@ typedef struct DetectEngineThreadCtx_ { uint16_t hcbd_buffers_size; uint16_t hcbd_buffers_list_len; - FiledataReassembledBody *smtp; - uint64_t smtp_start_tx_id; - uint16_t smtp_buffers_size; - uint16_t smtp_buffers_list_len; + FiledataReassembledBody *file_data; + uint64_t file_data_start_tx_id; + uint16_t file_data_buffers_size; + uint16_t file_data_buffers_list_len; /** id for alert counter */ uint16_t counter_alerts; diff --git a/src/runmode-unittests.c b/src/runmode-unittests.c index a1c1657f72..f89a9439ed 100644 --- a/src/runmode-unittests.c +++ b/src/runmode-unittests.c @@ -51,7 +51,7 @@ #include "detect-engine-state.h" #include "detect-engine-tag.h" #include "detect-engine-modbus.h" -#include "detect-engine-filedata-smtp.h" +#include "detect-engine-filedata.h" #include "detect-fast-pattern.h" #include "flow.h" #include "flow-timeout.h"