Signature *s);
static int g_file_data_buffer_id = 0;
+static inline HtpBody *GetResponseBody(htp_tx_t *tx);
+
/* HTTP */
static InspectionBuffer *HttpServerBodyGetDataCallback(DetectEngineThreadCtx *det_ctx,
const DetectEngineTransforms *transforms,
SigGroupHead *sgh, MpmCtx *mpm_ctx,
const DetectBufferMpmRegistery *mpm_reg, int list_id);
+static int DetectEngineInspectBufferHttpBody(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);
+
/**
* \brief Registration function for keyword: file_data
*/
PrefilterMpmFiledataRegister, NULL,
ALPROTO_HTTP2, HTTP2StateDataServer);
- DetectAppLayerInspectEngineRegister2("file_data",
- ALPROTO_HTTP, SIG_FLAG_TOCLIENT, HTP_RESPONSE_BODY,
- DetectEngineInspectBufferGeneric, HttpServerBodyGetDataCallback);
+ DetectAppLayerInspectEngineRegister2("file_data", ALPROTO_HTTP, SIG_FLAG_TOCLIENT,
+ HTP_RESPONSE_BODY, DetectEngineInspectBufferHttpBody, HttpServerBodyGetDataCallback);
DetectAppLayerInspectEngineRegister2("file_data",
ALPROTO_SMTP, SIG_FLAG_TOSERVER, 0,
DetectEngineInspectFiledata, NULL);
de_ctx->filedata_config_initialized = true;
}
+static int DetectEngineInspectBufferHttpBody(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)
+{
+ const int list_id = engine->sm_list;
+ const InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
+ bool eof = false;
+ if (buffer->inspect == NULL) {
+ SCLogDebug("running inspect on %d", list_id);
+
+ eof = (AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) > engine->progress);
+
+ SCLogDebug("list %d mpm? %s transforms %p", engine->sm_list, engine->mpm ? "true" : "false",
+ engine->v2.transforms);
+
+ /* if prefilter didn't already run, we need to consider transformations */
+ const DetectEngineTransforms *transforms = NULL;
+ if (!engine->mpm) {
+ transforms = engine->v2.transforms;
+ }
+
+ buffer = engine->v2.GetData(det_ctx, transforms, f, flags, txv, list_id);
+ if (unlikely(buffer == NULL)) {
+ return eof ? DETECT_ENGINE_INSPECT_SIG_CANT_MATCH : DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+ }
+ }
+
+ const uint32_t data_len = buffer->inspect_len;
+ const uint8_t *data = buffer->inspect;
+ const uint64_t offset = buffer->inspect_offset;
+
+ uint8_t ci_flags = eof ? DETECT_CI_FLAGS_END : 0;
+ ci_flags |= (offset == 0 ? DETECT_CI_FLAGS_START : 0);
+ ci_flags |= buffer->flags;
+
+ det_ctx->discontinue_matching = 0;
+ det_ctx->buffer_offset = 0;
+ det_ctx->inspection_recursion_counter = 0;
+
+ /* Inspect all the uricontents fetched on each
+ * transaction at the app layer */
+ int r = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, (uint8_t *)data,
+ data_len, offset, ci_flags, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
+
+ /* move inspected tracker to end of the data. HtpBodyPrune will consider
+ * the window sizes when freeing data */
+ htp_tx_t *tx = txv;
+ HtpBody *body = GetResponseBody(tx);
+ body->body_inspected = body->content_len_so_far;
+ SCLogDebug("body->body_inspected now: %" PRIu64, body->body_inspected);
+
+ if (r == 1) {
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
+ }
+
+ if (flags & STREAM_TOSERVER) {
+ if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) >
+ HTP_REQUEST_BODY)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ } else {
+ if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) >
+ HTP_RESPONSE_BODY)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ }
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+}
+
/**
* \brief this function is used to parse filedata options
* \brief into the current signature
InspectionBufferApplyTransforms(buffer, transforms);
- /* move inspected tracker to end of the data. HtpBodyPrune will consider
- * the window sizes when freeing data */
- body->body_inspected = body->content_len_so_far;
- SCLogDebug("body->body_inspected now: %"PRIu64, body->body_inspected);
-
SCReturnPtr(buffer, "InspectionBuffer");
}
// TODO this is unused, is that right?
//const uint32_t content_inspect_window = de_ctx->filedata_config[f->alproto].content_inspect_window;
- SCLogDebug("content_limit %u, content_inspect_min_size %u",
- content_limit, content_inspect_min_size);
+ SCLogDebug("[list %d] first: %d, content_limit %u, content_inspect_min_size %u", list_id,
+ first ? 1 : 0, content_limit, content_inspect_min_size);
- SCLogDebug("file %p size %"PRIu64", state %d", cur_file, file_size, cur_file->state);
+ SCLogDebug("[list %d] file %p size %" PRIu64 ", state %d", list_id, cur_file, file_size,
+ cur_file->state);
/* no new data */
if (cur_file->content_inspected == file_size) {
&data, &data_len,
cur_file->content_inspected);
InspectionBufferSetup(buffer, data, data_len);
+ SCLogDebug("[list %d] [before] buffer offset %" PRIu64 "; buffer len %" PRIu32
+ "; data_len %" PRIu32 "; file_size %" PRIu64,
+ list_id, buffer->inspect_offset, buffer->inspect_len, data_len, file_size);
buffer->inspect_offset = cur_file->content_inspected;
InspectionBufferApplyTransforms(buffer, transforms);
+ SCLogDebug("[list %d] [after] buffer offset %" PRIu64 "; buffer len %" PRIu32, list_id,
+ buffer->inspect_offset, buffer->inspect_len);
- /* update inspected tracker */
- cur_file->content_inspected = file_size;
- SCLogDebug("content_inspected %"PRIu64, cur_file->content_inspected);
+ SCLogDebug("[list %d] content_inspected %" PRIu64, list_id, cur_file->content_inspected);
- SCLogDebug("file_data buffer %p, data %p len %u offset %"PRIu64,
- buffer, buffer->inspect, buffer->inspect_len, buffer->inspect_offset);
+ SCLogDebug("[list %d] file_data buffer %p, data %p len %u offset %" PRIu64, list_id, buffer,
+ buffer->inspect, buffer->inspect_len, buffer->inspect_offset);
SCReturnPtr(buffer, "InspectionBuffer");
}
buffer->inspect_len,
buffer->inspect_offset, ciflags,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
+ /* update inspected tracker */
+ file->content_inspected = buffer->inspect_len + buffer->inspect_offset;
if (match == 1) {
r = 1;
break;