if (det_ctx->base64_decoded_len) {
return DetectEngineContentInspection(de_ctx, det_ctx, s,
s->sm_arrays[DETECT_SM_LIST_BASE64_DATA], f, det_ctx->base64_decoded,
- det_ctx->base64_decoded_len, 0,
+ det_ctx->base64_decoded_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
}
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
buffer, buffer_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE,
dcerpc_state);
if (r == 1)
if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) {
r = DetectEngineContentInspection(de_ctx, det_ctx, s,
smd, f, tx->request_buffer,
- tx->request_buffer_len, 0, 0, NULL);
+ tx->request_buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
+ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
}
else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) {
r = DetectEngineContentInspection(de_ctx, det_ctx, s,
smd, f, tx->response_buffer,
- tx->response_buffer_len, 0, 0, NULL);
+ tx->response_buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
+ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
}
SCReturnInt(r);
f,
(uint8_t *)buffer->inspect,
buffer->inspect_len,
- buffer->inspect_offset,
+ buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (match == 1) {
return DETECT_ENGINE_INSPECT_SIG_MATCH;
f,
(uint8_t *)buffer->inspect,
buffer->inspect_len,
- buffer->inspect_offset,
+ buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (match == 1) {
return DETECT_ENGINE_INSPECT_SIG_MATCH;
const Signature *s, const SigMatchData *smd,
Flow *f,
uint8_t *buffer, uint32_t buffer_len,
- uint32_t stream_start_offset,
+ uint32_t stream_start_offset, uint8_t flags,
uint8_t inspection_mode, void *data)
{
SCEnter();
* search for another occurence of this content and see
* if the others match then until we run out of matches */
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
- f, buffer, buffer_len, stream_start_offset, inspection_mode, data);
+ f, buffer, buffer_len, stream_start_offset, flags,
+ inspection_mode, data);
if (r == 1) {
SCReturnInt(1);
}
* search for another occurence of this pcre and see
* if the others match, until we run out of matches */
r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
- f, buffer, buffer_len, stream_start_offset, inspection_mode, data);
+ f, buffer, buffer_len, stream_start_offset, flags,
+ inspection_mode, data);
if (r == 1) {
SCReturnInt(1);
}
} else if (smd->type == DETECT_BYTETEST) {
DetectBytetestData *btd = (DetectBytetestData *)smd->ctx;
- uint8_t flags = btd->flags;
+ uint8_t btflags = btd->flags;
int32_t offset = btd->offset;
uint64_t value = btd->value;
- if (flags & DETECT_BYTETEST_OFFSET_BE) {
+ if (btflags & DETECT_BYTETEST_OFFSET_BE) {
offset = det_ctx->bj_values[offset];
}
- if (flags & DETECT_BYTETEST_VALUE_BE) {
+ if (btflags & DETECT_BYTETEST_VALUE_BE) {
value = det_ctx->bj_values[value];
}
/* if we have dce enabled we will have to use the endianness
* specified by the dce header */
- if (flags & DETECT_BYTETEST_DCE && data != NULL) {
+ if (btflags & DETECT_BYTETEST_DCE && data != NULL) {
DCERPCState *dcerpc_state = (DCERPCState *)data;
/* enable the endianness flag temporarily. once we are done
* processing we reset the flags to the original value*/
- flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ?
+ btflags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ?
DETECT_BYTETEST_LITTLE: 0);
}
- if (DetectBytetestDoMatch(det_ctx, s, smd->ctx, buffer, buffer_len, flags,
+ if (DetectBytetestDoMatch(det_ctx, s, smd->ctx, buffer, buffer_len, btflags,
offset, value) != 1) {
goto no_match;
}
} else if (smd->type == DETECT_BYTEJUMP) {
DetectBytejumpData *bjd = (DetectBytejumpData *)smd->ctx;
- uint8_t flags = bjd->flags;
+ uint8_t bjflags = bjd->flags;
int32_t offset = bjd->offset;
- if (flags & DETECT_BYTEJUMP_OFFSET_BE) {
+ if (bjflags & DETECT_BYTEJUMP_OFFSET_BE) {
offset = det_ctx->bj_values[offset];
}
/* if we have dce enabled we will have to use the endianness
* specified by the dce header */
- if (flags & DETECT_BYTEJUMP_DCE && data != NULL) {
+ if (bjflags & DETECT_BYTEJUMP_DCE && data != NULL) {
DCERPCState *dcerpc_state = (DCERPCState *)data;
/* enable the endianness flag temporarily. once we are done
* processing we reset the flags to the original value*/
- flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ?
+ bjflags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ?
DETECT_BYTEJUMP_LITTLE: 0);
}
if (DetectBytejumpDoMatch(det_ctx, s, smd->ctx, buffer, buffer_len,
- flags, offset) != 1) {
+ bjflags, offset) != 1) {
goto no_match;
}
if (!smd->is_last) {
KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
- f, buffer, buffer_len, stream_start_offset, inspection_mode, data);
+ f, buffer, buffer_len, stream_start_offset, flags,
+ inspection_mode, data);
SCReturnInt(r);
}
final_match:
* \file
*
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
+ * \author Victor Julien <victor@inliniac.net>
*/
#ifndef __DETECT_ENGINE_CONTENT_INSPECTION_H__
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE,
};
+#define DETECT_CI_FLAGS_START BIT_U8(0) /**< unused, reserved for future use */
+#define DETECT_CI_FLAGS_END BIT_U8(1) /**< indication that current buffer
+ * is the end of the data */
+
+/** buffer is a single, non-streaming, buffer. Data sent to the content
+ * inspection function contains both start and end of the data. */
+#define DETECT_CI_FLAGS_SINGLE (DETECT_CI_FLAGS_START|DETECT_CI_FLAGS_END)
+
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
const Signature *s, const SigMatchData *smd,
Flow *f,
uint8_t *buffer, uint32_t buffer_len,
- uint32_t stream_start_offset,
+ uint32_t stream_start_offset, uint8_t flags,
uint8_t inspection_mode, void *data);
void DetectEngineContentInspectionRegisterTests(void);
if (buffer == NULL)
continue;
+ bool eof = (file->state == FILE_STATE_CLOSED);
+ uint8_t ciflags = eof ? DETECT_CI_FLAGS_END : 0;
+ if (buffer->inspect_offset == 0)
+ ciflags |= DETECT_CI_FLAGS_START;
+
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
f,
(uint8_t *)buffer->inspect,
buffer->inspect_len,
- buffer->inspect_offset,
+ buffer->inspect_offset, ciflags,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (match == 1) {
r = 1;
HtpState *htp_state = (HtpState *)alstate;
uint32_t buffer_len = 0;
uint32_t stream_start_offset = 0;
+ const bool eof = (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_BODY);
const uint8_t *buffer = DetectEngineHCBDGetBufferForTX(tx, tx_id,
de_ctx, det_ctx,
f, htp_state,
if (buffer_len == 0)
goto end;
+ uint8_t ci_flags = eof ? DETECT_CI_FLAGS_END : 0;
+ ci_flags |= (stream_start_offset == 0 ? DETECT_CI_FLAGS_START : 0);
+
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
f,
(uint8_t *)buffer,
buffer_len,
- stream_start_offset,
+ stream_start_offset, ci_flags,
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_REQUEST_BODY)
+ if (eof)
return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
else
return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
f,
(uint8_t *)bstr_ptr(h->value),
bstr_len(h->value),
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
hname, hname_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
f,
(uint8_t *)bstr_ptr(tx->request_method),
bstr_len(tx->request_method),
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
f,
headers_raw,
headers_raw_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
hname, hname_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
f,
(uint8_t *)bstr_ptr(tx->request_uri),
bstr_len(tx->request_uri),
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
f,
(uint8_t *)bstr_ptr(tx->response_status),
bstr_len(tx->response_status),
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
f,
(uint8_t *)bstr_ptr(tx->response_message),
bstr_len(tx->response_message),
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
f,
(uint8_t *)bstr_ptr(h->value),
bstr_len(h->value),
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
det_ctx->replist = NULL;
r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_arrays[DETECT_SM_LIST_PMATCH],
- f, p->payload, p->payload_len, 0,
+ f, p->payload, p->payload_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD, p);
if (r == 1) {
SCReturnInt(1);
det_ctx->replist = NULL;
r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f, p->payload, p->payload_len, 0,
+ f, p->payload, p->payload_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD, p);
if (r == 1) {
SCReturnInt(1);
r = DetectEngineContentInspection(smd->de_ctx, smd->det_ctx,
smd->s, smd->s->sm_arrays[DETECT_SM_LIST_PMATCH],
- smd->f, (uint8_t *)data, data_len, 0,
+ smd->f, (uint8_t *)data, data_len, 0, 0, //TODO
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STREAM, NULL);
if (r == 1) {
SCReturnInt(1);
r = DetectEngineContentInspection(smd->de_ctx, smd->det_ctx,
smd->s, smd->smd,
- smd->f, (uint8_t *)data, data_len, 0,
+ smd->f, (uint8_t *)data, data_len, 0, 0, // TODO
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STREAM, NULL);
if (r == 1) {
SCReturnInt(1);
buffer_len = strlen(ssl_state->client_connp.sni);
cnt = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f, buffer, buffer_len, 0,
+ f, buffer, buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
return cnt;
buffer_len = strlen(ssl_state->server_connp.cert0_issuerdn);
cnt = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f, buffer, buffer_len, 0,
+ f, buffer, buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
return cnt;
buffer_len = strlen(ssl_state->server_connp.cert0_subject);
cnt = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f, buffer, buffer_len, 0,
+ f, buffer, buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
return cnt;
buffer_len = strlen(ssl_state->server_connp.cert0_serial);
cnt = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f, buffer, buffer_len, 0,
+ f, buffer, buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
return cnt;
buffer_len = strlen(ssl_state->server_connp.cert0_fingerprint);
cnt = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f, buffer, buffer_len, 0,
+ f, buffer, buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
return cnt;
f,
bstr_ptr(tx_ud->request_uri_normalized),
bstr_len(tx_ud->request_uri_normalized),
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1) {
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx,
s, engine->smd,
f,
- (uint8_t *)data, data_len, offset,
+ (uint8_t *)data, data_len, offset, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1) {
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
buffer, buffer_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
f,
buffer,
buffer_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
buffer, buffer_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
buffer, buffer_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
buffer, buffer_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
f,
bstr_ptr(tx->response_line),
bstr_len(tx->response_line),
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1) {
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
buffer, buffer_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
buffer, buffer_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
buffer, buffer_len,
- 0,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) {
ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f, tx->request_buffer, tx->request_buffer_len, 0,
+ f, tx->request_buffer, tx->request_buffer_len,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
}
else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) {
ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f, tx->response_buffer, tx->response_buffer_len, 0,
+ f, tx->response_buffer, tx->response_buffer_len,
+ 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
}
FAIL_IF_NULL(det_ctx); \
int r = DetectEngineContentInspection(de_ctx, det_ctx, \
s, s->sm_arrays[DETECT_SM_LIST_PMATCH], &f, \
- (uint8_t *)(buf), (buflen), 0, \
+ (uint8_t *)(buf), (buflen), 0, DETECT_CI_FLAGS_SINGLE, \
DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD, NULL); \
FAIL_IF_NOT(r == (match)); \
FAIL_IF_NOT(det_ctx->inspection_recursion_counter == (steps)); \