#include "app-layer-parser.h"
-#define BUFFER_STEP 50
-
-static inline int FiledataCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size)
+static InspectionBuffer *GetBuffer(InspectionBufferMultipleForList *fb, uint32_t id)
{
- if (size > det_ctx->file_data_buffers_size) {
- uint16_t grow_by = size - det_ctx->file_data_buffers_size;
- grow_by = MAX(grow_by, BUFFER_STEP);
-
- void *ptmp = SCRealloc(det_ctx->file_data,
- (det_ctx->file_data_buffers_size + grow_by) * sizeof(FiledataReassembledBody));
- if (ptmp == NULL) {
- 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->file_data = ptmp;
-
- memset(det_ctx->file_data + det_ctx->file_data_buffers_size, 0, grow_by * sizeof(FiledataReassembledBody));
- det_ctx->file_data_buffers_size += grow_by;
- }
- uint16_t i;
- for (i = det_ctx->file_data_buffers_list_len;
- i < det_ctx->file_data_buffers_size; i++)
- {
- det_ctx->file_data[i].buffer_len = 0;
- det_ctx->file_data[i].offset = 0;
+ if (id >= fb->size) {
+ uint32_t old_size = fb->size;
+ uint32_t new_size = id + 1;
+ uint32_t grow_by = new_size - old_size;
+ SCLogDebug("size is %u, need %u, so growing by %u", old_size, new_size, grow_by);
+
+ void *ptr = SCRealloc(fb->inspection_buffers, (id + 1) * sizeof(InspectionBuffer));
+ if (ptr == NULL)
+ return NULL;
+
+ InspectionBuffer *to_zero = (InspectionBuffer *)ptr + old_size;
+ SCLogDebug("fb->inspection_buffers %p ptr %p to_zero %p", fb->inspection_buffers, ptr, to_zero);
+ memset((uint8_t *)to_zero, 0, (grow_by * sizeof(InspectionBuffer)));
+ fb->inspection_buffers = ptr;
+ fb->size = new_size;
}
- return 0;
+ InspectionBuffer *buffer = &fb->inspection_buffers[id];
+ SCLogDebug("using file_data buffer %p", buffer);
+ return buffer;
}
-static const uint8_t *DetectEngineFiledataGetBufferForTX(uint64_t tx_id,
- DetectEngineCtx *de_ctx,
- DetectEngineThreadCtx *det_ctx,
- Flow *f, File *curr_file,
- uint8_t flags,
- uint32_t *buffer_len,
- uint32_t *stream_start_offset)
+static InspectionBuffer *FiledataGetDataCallback(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transforms,
+ Flow *f, uint8_t flow_flags, File *cur_file,
+ int list_id, int local_file_id, bool first)
{
SCEnter();
- int index = 0;
- const uint8_t *buffer = NULL;
- *buffer_len = 0;
- *stream_start_offset = 0;
- uint64_t file_size = FileDataSize(curr_file);
+ InspectionBufferMultipleForList *fb = &det_ctx->multi_inspect_buffers[list_id];
+ InspectionBuffer *buffer = GetBuffer(fb, local_file_id);
+ if (buffer == NULL)
+ return NULL;
+ if (!first && buffer->inspect != NULL)
+ return buffer;
+
+ const uint64_t file_size = FileDataSize(cur_file);
+ const DetectEngineCtx *de_ctx = det_ctx->de_ctx;
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->file_data_buffers_list_len == 0) {
- det_ctx->file_data_start_tx_id = tx_id;
- }
- det_ctx->file_data_buffers_list_len++;
- } else {
- 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 (FiledataCreateSpace(det_ctx, (tx_id - det_ctx->file_data_start_tx_id) + 1) < 0)
- goto end;
-
- if (det_ctx->file_data_buffers_list_len == 0) {
- det_ctx->file_data_start_tx_id = tx_id;
- }
- det_ctx->file_data_buffers_list_len++;
- }
- index = (tx_id - det_ctx->file_data_start_tx_id);
- }
-
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);
+ SCLogDebug("file %p size %"PRIu64", state %d", cur_file, file_size, cur_file->state);
/* no new data */
- if (curr_file->content_inspected == file_size) {
+ if (cur_file->content_inspected == file_size) {
SCLogDebug("no new data");
- goto end;
+ return NULL;
}
if (file_size == 0) {
SCLogDebug("no data to inspect for this transaction");
- goto end;
+ return NULL;
}
if ((content_limit == 0 || file_size < content_limit) &&
file_size < content_inspect_min_size &&
- !(flags & STREAM_EOF) && !(curr_file->state > FILE_STATE_OPENED)) {
+ !(flow_flags & STREAM_EOF) && !(cur_file->state > FILE_STATE_OPENED)) {
SCLogDebug("we still haven't seen the entire content. "
"Let's defer content inspection till we see the "
"entire content.");
- goto end;
+ return NULL;
}
- StreamingBufferGetDataAtOffset(curr_file->sb,
- &det_ctx->file_data[index].buffer, &det_ctx->file_data[index].buffer_len,
- curr_file->content_inspected);
+ const uint8_t *data;
+ uint32_t data_len;
- det_ctx->file_data[index].offset = curr_file->content_inspected;
+ StreamingBufferGetDataAtOffset(cur_file->sb,
+ &data, &data_len,
+ cur_file->content_inspected);
+ InspectionBufferSetup(buffer, data, data_len);
+ buffer->inspect_offset = cur_file->content_inspected;
+ InspectionBufferApplyTransforms(buffer, transforms);
/* update inspected tracker */
- curr_file->content_inspected = FileDataSize(curr_file);
-
- SCLogDebug("content_inspected %"PRIu64", offset %"PRIu64,
- curr_file->content_inspected, det_ctx->file_data[index].offset);
+ cur_file->content_inspected = file_size;
+ SCLogDebug("content_inspected %"PRIu64, cur_file->content_inspected);
- 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;
+ SCLogDebug("file_data buffer %p, data %p len %u offset %"PRIu64,
+ buffer, buffer->inspect, buffer->inspect_len, buffer->inspect_offset);
-end:
- SCLogDebug("buffer %p, len %u", buffer, *buffer_len);
- SCReturnPtr(buffer, "uint8_t");
+ SCReturnPtr(buffer, "InspectionBuffer");
}
-int DetectEngineInspectFiledata(ThreadVars *tv,
+int DetectEngineInspectFiledata(
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)
+ const DetectEngineAppInspectionEngine *engine,
+ const Signature *s,
+ Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
{
int r = 0;
int match = 0;
- uint32_t buffer_len = 0;
- uint32_t stream_start_offset = 0;
- const uint8_t *buffer = 0;
+ // TODO remove
if (f->alproto == ALPROTO_HTTP) {
- return DetectEngineInspectHttpServerBody(tv, de_ctx, det_ctx, s,
- smd, f, flags, alstate, tx, tx_id);
+ abort();
+ }
+
+ const DetectEngineTransforms *transforms = NULL;
+ if (!engine->mpm) {
+ transforms = engine->v2.transforms;
}
FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto,
return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
+ int local_file_id = 0;
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)
+ InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx,
+ transforms, f, flags, file, engine->sm_list, local_file_id, false);
+ if (buffer == NULL)
continue;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
- match = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
+ match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd,
f,
- (uint8_t *)buffer,
- buffer_len,
- stream_start_offset,
+ (uint8_t *)buffer->inspect,
+ buffer->inspect_len,
+ buffer->inspect_offset,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (match == 1) {
r = 1;
break;
}
+ local_file_id++;
}
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
-void DetectEngineCleanFiledataBuffers(DetectEngineThreadCtx *det_ctx)
-{
- 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->file_data_buffers_list_len = 0;
- det_ctx->file_data_start_tx_id = 0;
-
- return;
-}
+typedef struct PrefilterMpmFiledata {
+ int list_id;
+ const MpmCtx *mpm_ctx;
+ const DetectEngineTransforms *transforms;
+} PrefilterMpmFiledata;
/** \brief Filedata Filedata Mpm prefilter callback
*
* \param txv tx to inspect
* \param pectx inspection context
*/
-void PrefilterTxFiledata(DetectEngineThreadCtx *det_ctx,
+static void PrefilterTxFiledata(DetectEngineThreadCtx *det_ctx,
const void *pectx,
Packet *p, Flow *f, void *txv,
const uint64_t idx, const uint8_t flags)
{
SCEnter();
- const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
+ const PrefilterMpmFiledata *ctx = (const PrefilterMpmFiledata *)pectx;
+ const MpmCtx *mpm_ctx = ctx->mpm_ctx;
+ const int list_id = ctx->list_id;
+
FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto,
f->alstate, flags);
+ int local_file_id = 0;
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;
+ InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx,
+ ctx->transforms, f, flags, file, list_id, local_file_id, true);
+ if (buffer == NULL)
+ continue;
- const uint8_t *buffer = DetectEngineFiledataGetBufferForTX(idx,
- det_ctx->de_ctx, det_ctx,
- f, file,
- flags,
- &buffer_len,
- &stream_start_offset);
- if (buffer != NULL && buffer_len >= mpm_ctx->minlen) {
+ if (buffer->inspect_len >= mpm_ctx->minlen) {
(void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
- &det_ctx->mtcu, &det_ctx->pmq, buffer, buffer_len);
+ &det_ctx->mtcu, &det_ctx->pmq,
+ buffer->inspect, buffer->inspect_len);
}
}
}
}
+static void PrefilterMpmFiledataFree(void *ptr)
+{
+ SCFree(ptr);
+}
+
+int PrefilterMpmFiledataRegister(DetectEngineCtx *de_ctx,
+ SigGroupHead *sgh, MpmCtx *mpm_ctx,
+ const DetectMpmAppLayerRegistery *mpm_reg, int list_id)
+{
+ PrefilterMpmFiledata *pectx = SCCalloc(1, sizeof(*pectx));
+ if (pectx == NULL)
+ return -1;
+ pectx->list_id = list_id;
+ pectx->mpm_ctx = mpm_ctx;
+ pectx->transforms = &mpm_reg->v2.transforms;
+
+ return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxFiledata,
+ mpm_reg->v2.alproto, mpm_reg->v2.tx_min_progress,
+ pectx, PrefilterMpmFiledataFree, mpm_reg->pname);
+}
+
#ifdef UNITTESTS
#include "tests/detect-engine-filedata.c"
#endif /* UNITTESTS */
int PrefilterMpmFiledataRegister(DetectEngineCtx *de_ctx,
SigGroupHead *sgh, MpmCtx *mpm_ctx,
const DetectMpmAppLayerRegistery *mpm_reg, int list_id);
-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,
+int DetectEngineInspectFiledata(
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);
+ const DetectEngineAppInspectionEngine *engine,
+ const Signature *s,
+ Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id);
void DetectEngineCleanFiledataBuffers(DetectEngineThreadCtx *det_ctx);
#include "util-validate.h"
-#define BUFFER_STEP 50
-static inline int HSBDCreateSpace(DetectEngineThreadCtx *det_ctx, uint64_t size)
+InspectionBuffer *HttpServerBodyGetDataCallback(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transforms,
+ Flow *f, const uint8_t flow_flags,
+ void *txv, const int list_id)
{
- if (size >= (USHRT_MAX - BUFFER_STEP))
- return -1;
-
- void *ptmp;
- if (size > det_ctx->hsbd_buffers_size) {
- uint16_t grow_by = size - det_ctx->hsbd_buffers_size;
- grow_by = MAX(grow_by, BUFFER_STEP);
-
- ptmp = SCRealloc(det_ctx->hsbd,
- (det_ctx->hsbd_buffers_size + grow_by) * sizeof(HttpReassembledBody));
- if (ptmp == NULL) {
- SCFree(det_ctx->hsbd);
- det_ctx->hsbd = NULL;
- det_ctx->hsbd_buffers_size = 0;
- det_ctx->hsbd_buffers_list_len = 0;
- return -1;
- }
- det_ctx->hsbd = ptmp;
-
- memset(det_ctx->hsbd + det_ctx->hsbd_buffers_size, 0, grow_by * sizeof(HttpReassembledBody));
- det_ctx->hsbd_buffers_size += grow_by;
- }
- uint16_t i;
- for (i = det_ctx->hsbd_buffers_list_len; i < det_ctx->hsbd_buffers_size; i++) {
- det_ctx->hsbd[i].buffer_len = 0;
- det_ctx->hsbd[i].offset = 0;
- det_ctx->hsbd[i].decompressed_buffer_len = 0;
- }
-
- return 0;
-}
+ SCEnter();
-static const uint8_t *DetectEngineHSBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
- DetectEngineCtx *de_ctx,
- DetectEngineThreadCtx *det_ctx,
- Flow *f, HtpState *htp_state,
- uint8_t flags,
- int *hsbd_index,
- uint32_t *buffer_len,
- uint32_t *stream_start_offset)
-{
- int index = 0;
- const uint8_t *buffer = NULL;
- *buffer_len = 0;
- *stream_start_offset = 0;
-
- if (det_ctx->hsbd_buffers_list_len == 0) {
- /* get the inspect id to use as a 'base id' */
- uint64_t base_inspect_id = AppLayerParserGetTransactionInspectId(f->alparser, flags);
- BUG_ON(base_inspect_id > tx_id);
- /* see how many space we need for the current tx_id */
- uint64_t txs = (tx_id - base_inspect_id) + 1;
- if (HSBDCreateSpace(det_ctx, txs) < 0)
- goto end;
- index = (tx_id - base_inspect_id);
- det_ctx->hsbd_start_tx_id = base_inspect_id;
- det_ctx->hsbd_buffers_list_len = txs;
- *hsbd_index = index;
- } else {
- if ((tx_id - det_ctx->hsbd_start_tx_id) < det_ctx->hsbd_buffers_list_len) {
- if (det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer_len != 0) {
- *buffer_len = det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer_len;
- *stream_start_offset = det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].offset;
- *hsbd_index = (tx_id - det_ctx->hsbd_start_tx_id);
- return det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer;
- }
- } else {
- uint64_t txs = (tx_id - det_ctx->hsbd_start_tx_id) + 1;
- if (HSBDCreateSpace(det_ctx, txs) < 0)
- goto end;
+ InspectionBuffer *buffer = &det_ctx->inspect_buffers[list_id];
+ if (buffer->inspect != NULL)
+ return buffer;
- det_ctx->hsbd_buffers_list_len = txs;
- }
- index = (tx_id - det_ctx->hsbd_start_tx_id);
- *hsbd_index = index;
- }
+ htp_tx_t *tx = txv;
+ HtpState *htp_state = f->alstate;
+ const uint8_t flags = flow_flags;
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud == NULL) {
SCLogDebug("no htud");
- goto end;
+ return NULL;
}
/* no new data */
if (htud->response_body.body_inspected == htud->response_body.content_len_so_far) {
SCLogDebug("no new data");
- goto end;
+ return NULL;
}
HtpBodyChunk *cur = htud->response_body.first;
if (cur == NULL) {
SCLogDebug("No http chunks to inspect for this transacation");
- goto end;
+ return NULL;
}
SCLogDebug("response.body_limit %u response_body.content_len_so_far %"PRIu64
SCLogDebug("we still haven't seen the entire response body. "
"Let's defer body inspection till we see the "
"entire body.");
- goto end;
+ return NULL;
}
}
}
}
- StreamingBufferGetDataAtOffset(htud->response_body.sb,
- &det_ctx->hsbd[index].buffer, &det_ctx->hsbd[index].buffer_len,
- offset);
- det_ctx->hsbd[index].offset = offset;
-
- /* move inspected tracker to end of the data. HtpBodyPrune will consider
- * the window sizes when freeing data */
- htud->response_body.body_inspected = htud->response_body.content_len_so_far;
- SCLogDebug("htud->response_body.body_inspected now: %"PRIu64, htud->response_body.body_inspected);
-
- buffer = det_ctx->hsbd[index].buffer;
- *buffer_len = det_ctx->hsbd[index].buffer_len;
- *stream_start_offset = det_ctx->hsbd[index].offset;
- end:
- return buffer;
-}
-
-/** \brief HTTP Server Body 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
- */
-static void PrefilterTxHttpResponseBody(DetectEngineThreadCtx *det_ctx,
- const void *pectx,
- Packet *p, Flow *f, void *txv,
- const uint64_t idx, const uint8_t flags)
-{
- SCEnter();
+ const uint8_t *data;
+ uint32_t data_len;
- const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
- htp_tx_t *tx = (htp_tx_t *)txv;
- HtpState *htp_state = f->alstate;
- int ret = 0;
- int hsbd_index = 0;
- uint32_t buffer_len = 0;
- uint32_t stream_start_offset = 0;
- const uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx, idx,
- NULL, det_ctx,
- f, htp_state,
- flags,
- &hsbd_index,
- &buffer_len,
- &stream_start_offset);
+ StreamingBufferGetDataAtOffset(htud->response_body.sb,
+ &data, &data_len, offset);
+ InspectionBufferSetup(buffer, data, data_len);
+ buffer->inspect_offset = offset;
+ /* built-in 'transformation' */
if (htp_state->cfg->swf_decompression_enabled) {
- int swf_file_type = FileIsSwfFile(buffer, buffer_len);
+ int swf_file_type = FileIsSwfFile(data, data_len);
if (swf_file_type == FILE_SWF_ZLIB_COMPRESSION ||
swf_file_type == FILE_SWF_LZMA_COMPRESSION)
{
- ret = FileSwfDecompression(buffer, buffer_len,
+ (void)FileSwfDecompression(data, data_len,
det_ctx,
- hsbd_index,
+ buffer,
htp_state->cfg->swf_compression_type,
htp_state->cfg->swf_decompress_depth,
htp_state->cfg->swf_compress_depth);
-
- if (ret == 1 && det_ctx->hsbd &&
- det_ctx->hsbd[hsbd_index].decompressed_buffer_len != 0) {
- buffer = det_ctx->hsbd[hsbd_index].decompressed_buffer;
- buffer_len = det_ctx->hsbd[hsbd_index].decompressed_buffer_len;
- }
}
}
- if (buffer_len >= mpm_ctx->minlen) {
- (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
- &det_ctx->mtcu, &det_ctx->pmq, buffer, buffer_len);
- }
-}
-
-int PrefilterTxHttpResponseBodyRegister(DetectEngineCtx *de_ctx,
- SigGroupHead *sgh, MpmCtx *mpm_ctx)
-{
- SCEnter();
-
- return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpResponseBody,
- ALPROTO_HTTP, HTP_RESPONSE_BODY,
- mpm_ctx, NULL, "file_data (http response)");
-}
-
-
-int DetectEngineInspectHttpServerBody(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)
-{
- HtpState *htp_state = (HtpState *)alstate;
- int hsbd_index = 0;
- uint32_t buffer_len = 0;
- uint32_t stream_start_offset = 0;
- const uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx, tx_id,
- de_ctx, det_ctx,
- f, htp_state,
- flags,
- &hsbd_index,
- &buffer_len,
- &stream_start_offset);
-
- if (htp_state->cfg->swf_decompression_enabled) {
- if (det_ctx->hsbd && det_ctx->hsbd[hsbd_index].decompressed_buffer_len != 0) {
- buffer = det_ctx->hsbd[hsbd_index].decompressed_buffer;
- buffer_len = det_ctx->hsbd[hsbd_index].decompressed_buffer_len;
- }
- }
-
- if (buffer_len == 0)
- goto end;
-
- det_ctx->buffer_offset = 0;
- det_ctx->discontinue_matching = 0;
- det_ctx->inspection_recursion_counter = 0;
- int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f,
- (uint8_t *)buffer,
- buffer_len,
- stream_start_offset,
- DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
- if (r == 1)
- return DETECT_ENGINE_INSPECT_SIG_MATCH;
-
- end:
- if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_BODY)
- return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
- else
- return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
-}
-
-void DetectEngineCleanHSBDBuffers(DetectEngineThreadCtx *det_ctx)
-{
- if (det_ctx->hsbd_buffers_list_len > 0) {
- for (int i = 0; i < det_ctx->hsbd_buffers_list_len; i++) {
- det_ctx->hsbd[i].buffer_len = 0;
- det_ctx->hsbd[i].offset = 0;
- }
- }
- det_ctx->hsbd_buffers_list_len = 0;
- det_ctx->hsbd_start_tx_id = 0;
+ /* move inspected tracker to end of the data. HtpBodyPrune will consider
+ * the window sizes when freeing data */
+ htud->response_body.body_inspected = htud->response_body.content_len_so_far;
+ SCLogDebug("htud->response_body.body_inspected now: %"PRIu64, htud->response_body.body_inspected);
- return;
+ SCReturnPtr(buffer, "InspectionBuffer");
}
/***********************************Unittests**********************************/
#ifndef __DETECT_ENGINE_HSBD_H__
#define __DETECT_ENGINE_HSBD_H__
-#define ENGINE_HSBD_BUFFER_LIMIT 20000
-
#include "app-layer-htp.h"
int PrefilterTxHttpResponseBodyRegister(DetectEngineCtx *de_ctx,
Flow *f, uint8_t flags, void *alstate,
void *tx, uint64_t tx_id);
+InspectionBuffer *HttpServerBodyGetDataCallback(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transform,
+ Flow *f, const uint8_t flow_flags, void *txv, const int list_id);
+
void DetectEngineCleanHSBDBuffers(DetectEngineThreadCtx *det_ctx);
void DetectEngineHttpServerBodyRegisterTests(void);
if (det_ctx->bj_values != NULL)
SCFree(det_ctx->bj_values);
- /* HSBD */
- if (det_ctx->hsbd != NULL) {
- if (det_ctx->hsbd->decompressed_buffer != NULL) {
- SCFree(det_ctx->hsbd->decompressed_buffer);
- }
- SCLogDebug("det_ctx hsbd %u", det_ctx->hsbd_buffers_size);
- SCFree(det_ctx->hsbd);
- }
-
/* HSCB */
if (det_ctx->hcbd != NULL) {
SCLogDebug("det_ctx hcbd %u", det_ctx->hcbd_buffers_size);
static void DetectFiledataSetupCallback(Signature *s);
static int g_file_data_buffer_id = 0;
-static int PrefilterTxSmtpFiledataRegister(DetectEngineCtx *de_ctx,
- SigGroupHead *sgh, MpmCtx *mpm_ctx);
-
/**
* \brief Registration function for keyword: file_data
*/
sigmatch_table[DETECT_FILE_DATA].RegisterTests = DetectFiledataRegisterTests;
sigmatch_table[DETECT_FILE_DATA].flags = SIGMATCH_NOOPT;
- DetectAppLayerMpmRegister("file_data", SIG_FLAG_TOSERVER, 2,
- PrefilterTxSmtpFiledataRegister);
- DetectAppLayerMpmRegister("file_data", SIG_FLAG_TOCLIENT, 2,
- PrefilterTxHttpResponseBodyRegister);
+ DetectAppLayerMpmRegister2("file_data", SIG_FLAG_TOSERVER, 2,
+ PrefilterMpmFiledataRegister, NULL,
+ ALPROTO_SMTP, 0);
+ DetectAppLayerMpmRegister2("file_data", SIG_FLAG_TOCLIENT, 2,
+ PrefilterGenericMpmRegister,
+ HttpServerBodyGetDataCallback,
+ ALPROTO_HTTP, HTP_RESPONSE_BODY);
- DetectAppLayerInspectEngineRegister("file_data",
+ DetectAppLayerInspectEngineRegister2("file_data",
ALPROTO_HTTP, SIG_FLAG_TOCLIENT, HTP_RESPONSE_BODY,
- DetectEngineInspectFiledata);
- DetectAppLayerInspectEngineRegister("file_data",
+ DetectEngineInspectBufferGeneric, HttpServerBodyGetDataCallback);
+ DetectAppLayerInspectEngineRegister2("file_data",
ALPROTO_SMTP, SIG_FLAG_TOSERVER, 0,
- DetectEngineInspectFiledata);
-
+ DetectEngineInspectFiledata, NULL);
DetectBufferTypeRegisterSetupCallback("file_data",
DetectFiledataSetupCallback);
g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
}
-static int PrefilterTxSmtpFiledataRegister(DetectEngineCtx *de_ctx,
- SigGroupHead *sgh, MpmCtx *mpm_ctx)
-{
- SCEnter();
-
- return PrefilterAppendTxEngine(de_ctx, 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
return -1;
}
- s->init_data->list = DetectBufferTypeGetByName("file_data");
+ DetectBufferSetActiveList(s, DetectBufferTypeGetByName("file_data"));
SetupDetectEngineConfig(de_ctx);
return 0;
det_ctx->raw_stream_progress);
DetectEngineCleanHCBDBuffers(det_ctx);
- DetectEngineCleanHSBDBuffers(det_ctx);
- DetectEngineCleanFiledataBuffers(det_ctx);
}
}
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_CLEANUP);
uint64_t offset; /**< data offset */
} HttpReassembledBody;
-typedef struct FiledataReassembledBody_ {
- const uint8_t *buffer;
- uint32_t buffer_size; /**< size of the buffer itself */
- uint32_t buffer_len; /**< data len in the buffer */
- uint64_t offset; /**< data offset */
-} FiledataReassembledBody;
-
#define DETECT_FILESTORE_MAX 15
typedef struct SignatureNonPrefilterStore_ {
/* counter for the filestore array below -- up here for cache reasons. */
uint16_t filestore_cnt;
- HttpReassembledBody *hsbd;
- uint64_t hsbd_start_tx_id;
- uint16_t hsbd_buffers_size;
- uint16_t hsbd_buffers_list_len;
-
HttpReassembledBody *hcbd;
uint64_t hcbd_start_tx_id;
uint16_t hcbd_buffers_size;
uint16_t hcbd_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;
#ifdef PROFILING
#include "suricata-common.h"
#include "suricata.h"
+#include "detect-engine.h"
#include "app-layer-htp.h"
#include "util-file-decompression.h"
*/
int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len,
DetectEngineThreadCtx *det_ctx,
- int index,
+ InspectionBuffer *out_buffer,
int swf_type,
uint32_t decompress_depth,
uint32_t compress_depth)
uint32_t decompressed_data_len = (decompress_depth == 0) ? decompressed_swf_len : decompress_depth;
decompressed_data_len += 8;
- if (det_ctx->hsbd[index].decompressed_buffer_len == 0 ||
- det_ctx->hsbd[index].decompressed_buffer_len < decompressed_data_len) {
- void *ptmp = NULL;
- ptmp = SCRealloc(det_ctx->hsbd[index].decompressed_buffer,
- decompressed_data_len);
- if (ptmp == NULL) {
- DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_NO_MEM);
- return 0;
- }
- det_ctx->hsbd[index].decompressed_buffer = ptmp;
+ /* make sure the inspection buffer has enough space */
+ InspectionBufferCheckAndExpand(out_buffer, decompressed_data_len);
+ if (out_buffer->size < decompressed_data_len) {
+ DetectEngineSetEvent(det_ctx, FILE_DECODER_EVENT_NO_MEM);
+ return 0;
}
-
- det_ctx->hsbd[index].decompressed_buffer_len = decompressed_data_len;
- memset(det_ctx->hsbd[index].decompressed_buffer, 0x00,
- det_ctx->hsbd[index].decompressed_buffer_len);
+ out_buffer->len = decompressed_data_len;
/*
* FWS format
* | 4 bytes | 4 bytes | n bytes |
* | 'FWS' + version | script len | data |
*/
- det_ctx->hsbd[index].decompressed_buffer[0] = 'F';
- det_ctx->hsbd[index].decompressed_buffer[1] = 'W';
- det_ctx->hsbd[index].decompressed_buffer[2] = 'S';
- det_ctx->hsbd[index].decompressed_buffer[3] = swf_version;
- memcpy(det_ctx->hsbd[index].decompressed_buffer + 4, &decompressed_swf_len, 4);
+ out_buffer->buf[0] = 'F';
+ out_buffer->buf[1] = 'W';
+ out_buffer->buf[2] = 'S';
+ out_buffer->buf[3] = swf_version;
+ memcpy(out_buffer->buf + 4, &decompressed_swf_len, 4);
+ memset(out_buffer->buf + 8, 0, decompressed_data_len - 8);
if ((swf_type == HTTP_SWF_COMPRESSION_ZLIB || swf_type == HTTP_SWF_COMPRESSION_BOTH) &&
- compression_type == FILE_SWF_ZLIB_COMPRESSION)
+ compression_type == FILE_SWF_ZLIB_COMPRESSION)
{
/* the first 8 bytes represents the fws header, see 'FWS format' above.
* data will start from 8th bytes
*/
r = FileSwfZlibDecompression(det_ctx,
(uint8_t *)buffer + offset, compressed_data_len,
- det_ctx->hsbd[index].decompressed_buffer + 8,
- det_ctx->hsbd[index].decompressed_buffer_len - 8);
+ out_buffer->buf + 8, out_buffer->len - 8);
if (r == 0)
goto error;
*/
r = FileSwfLzmaDecompression(det_ctx,
compressed_data, compressed_data_len,
- det_ctx->hsbd[index].decompressed_buffer + 8,
- det_ctx->hsbd[index].decompressed_buffer_len - 8);
+ out_buffer->buf + 8, out_buffer->len - 8);
SCFree(compressed_data);
if (r == 0)
goto error;
goto error;
}
+ /* all went well so switch the buffer's inspect pointer/size
+ * to use the new data. */
+ out_buffer->inspect = out_buffer->buf;
+ out_buffer->inspect_len = out_buffer->len;
+
return 1;
error:
- det_ctx->hsbd[index].decompressed_buffer_len = 0;
- memset(det_ctx->hsbd[index].decompressed_buffer, 0x00,
- det_ctx->hsbd[index].decompressed_buffer_len);
return 0;
}
int FileIsSwfFile(const uint8_t *buffer, uint32_t buffer_len);
int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len,
DetectEngineThreadCtx *det_ctx,
- int hsbd_index,
+ InspectionBuffer *out_buffer,
int swf_type,
uint32_t decompress_depth, uint32_t compress_depth);