|
|
|
@ -415,6 +415,7 @@ static void StoreStateTxHandleFiles(DetectEngineThreadCtx *det_ctx, Flow *f,
|
|
|
|
|
DetectEngineState *destate, const uint8_t flags,
|
|
|
|
|
const uint64_t tx_id, const uint16_t file_no_match)
|
|
|
|
|
{
|
|
|
|
|
SCLogDebug("tx %u, file_no_match %u", (uint)tx_id, file_no_match);
|
|
|
|
|
DeStateStoreFileNoMatchCnt(destate, file_no_match, flags);
|
|
|
|
|
if (DeStateStoreFilestoreSigsCantMatch(det_ctx->sgh, destate, flags) == 1) {
|
|
|
|
|
FileDisableStoringForTransaction(f, flags & (STREAM_TOCLIENT | STREAM_TOSERVER), tx_id);
|
|
|
|
@ -464,6 +465,8 @@ static void StoreStateTx(DetectEngineThreadCtx *det_ctx,
|
|
|
|
|
SCLogDebug("destate created for %"PRIu64, tx_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SCLogDebug("file_no_match %u", file_no_match);
|
|
|
|
|
|
|
|
|
|
if (check_before_add == 0 || DeStateSearchState(destate, flags, s->num) == 0)
|
|
|
|
|
DeStateSignatureAppend(destate, s, inspect_flags, flags);
|
|
|
|
|
DeStateStoreStateVersion(f, alversion, flags);
|
|
|
|
@ -485,6 +488,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
|
|
|
|
|
int alert_cnt = 0;
|
|
|
|
|
int check_before_add = 0;
|
|
|
|
|
|
|
|
|
|
SCLogDebug("rule %u", s->id);
|
|
|
|
|
|
|
|
|
|
FLOWLOCK_WRLOCK(f);
|
|
|
|
|
/* TX based matches (inspect engines) */
|
|
|
|
|
if (AppLayerParserProtocolSupportsTxs(f->proto, alproto)) {
|
|
|
|
@ -516,18 +521,24 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
|
|
|
|
|
for (; tx_id < total_txs; tx_id++) {
|
|
|
|
|
int total_matches = 0;
|
|
|
|
|
void *tx = AppLayerParserGetTx(f->proto, alproto, alstate, tx_id);
|
|
|
|
|
SCLogDebug("tx %p", tx);
|
|
|
|
|
if (tx == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
det_ctx->tx_id = tx_id;
|
|
|
|
|
det_ctx->tx_id_set = 1;
|
|
|
|
|
|
|
|
|
|
DetectEngineAppInspectionEngine *engine = app_inspection_engine[f->protomap][alproto][direction];
|
|
|
|
|
SCLogDebug("engine %p", engine);
|
|
|
|
|
inspect_flags = 0;
|
|
|
|
|
while (engine != NULL) {
|
|
|
|
|
SCLogDebug("engine %p", engine);
|
|
|
|
|
SCLogDebug("inspect_flags %x", inspect_flags);
|
|
|
|
|
if (s->sm_lists[engine->sm_list] != NULL) {
|
|
|
|
|
KEYWORD_PROFILING_SET_LIST(det_ctx, engine->sm_list);
|
|
|
|
|
int match = engine->Callback(tv, de_ctx, det_ctx, s, f,
|
|
|
|
|
flags, alstate,
|
|
|
|
|
tx, tx_id);
|
|
|
|
|
SCLogDebug("engine %p match %d", engine, match);
|
|
|
|
|
if (match == DETECT_ENGINE_INSPECT_SIG_MATCH) {
|
|
|
|
|
inspect_flags |= engine->inspect_flags;
|
|
|
|
|
engine = engine->next;
|
|
|
|
@ -545,6 +556,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
|
|
|
|
|
}
|
|
|
|
|
engine = engine->next;
|
|
|
|
|
}
|
|
|
|
|
SCLogDebug("inspect_flags %x", inspect_flags);
|
|
|
|
|
/* all the engines seem to be exhausted at this point. If we
|
|
|
|
|
* didn't have a match in one of the engines we would have
|
|
|
|
|
* broken off and engine wouldn't be NULL. Hence the alert. */
|
|
|
|
@ -712,6 +724,8 @@ static int DoInspectItem(ThreadVars *tv,
|
|
|
|
|
{
|
|
|
|
|
Signature *s = de_ctx->sig_array[item->sid];
|
|
|
|
|
|
|
|
|
|
SCLogDebug("file_no_match %u, sid %u", *file_no_match, s->id);
|
|
|
|
|
|
|
|
|
|
/* check if a sig in state 'full inspect' needs to be reconsidered
|
|
|
|
|
* as the result of a new file in the existing tx */
|
|
|
|
|
if (item->flags & DE_STATE_FLAG_FULL_INSPECT) {
|
|
|
|
@ -719,6 +733,7 @@ static int DoInspectItem(ThreadVars *tv,
|
|
|
|
|
if ((flags & STREAM_TOCLIENT) &&
|
|
|
|
|
(dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW))
|
|
|
|
|
{
|
|
|
|
|
SCLogDebug("~DE_STATE_FLAG_FILE_TC_INSPECT");
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT;
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_FULL_INSPECT;
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH;
|
|
|
|
@ -727,6 +742,7 @@ static int DoInspectItem(ThreadVars *tv,
|
|
|
|
|
if ((flags & STREAM_TOSERVER) &&
|
|
|
|
|
(dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW))
|
|
|
|
|
{
|
|
|
|
|
SCLogDebug("~DE_STATE_FLAG_FILE_TS_INSPECT");
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT;
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_FULL_INSPECT;
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH;
|
|
|
|
@ -736,7 +752,7 @@ static int DoInspectItem(ThreadVars *tv,
|
|
|
|
|
if (item->flags & DE_STATE_FLAG_FULL_INSPECT) {
|
|
|
|
|
if (TxIsLast(inspect_tx_id, total_txs) || inprogress || next_tx_no_progress) {
|
|
|
|
|
det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
|
|
|
|
|
SCLogDebug("skip and bypass: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt);
|
|
|
|
|
SCLogDebug("skip and bypass %u: tx %u packet %u", s->id, (uint)inspect_tx_id, (uint)p->pcap_cnt);
|
|
|
|
|
} else {
|
|
|
|
|
SCLogDebug("just skip: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt);
|
|
|
|
|
|
|
|
|
@ -758,17 +774,23 @@ static int DoInspectItem(ThreadVars *tv,
|
|
|
|
|
|
|
|
|
|
/* check if a sig in state 'cant match' needs to be reconsidered
|
|
|
|
|
* as the result of a new file in the existing tx */
|
|
|
|
|
SCLogDebug("item->flags %x", item->flags);
|
|
|
|
|
if (item->flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
|
|
|
|
|
SCLogDebug("DE_STATE_FLAG_SIG_CANT_MATCH");
|
|
|
|
|
|
|
|
|
|
if ((flags & STREAM_TOSERVER) &&
|
|
|
|
|
(item->flags & DE_STATE_FLAG_FILE_TS_INSPECT) &&
|
|
|
|
|
(dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW))
|
|
|
|
|
{
|
|
|
|
|
SCLogDebug("unset ~DE_STATE_FLAG_FILE_TS_INSPECT ~DE_STATE_FLAG_SIG_CANT_MATCH");
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT;
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH;
|
|
|
|
|
|
|
|
|
|
} else if ((flags & STREAM_TOCLIENT) &&
|
|
|
|
|
(item->flags & DE_STATE_FLAG_FILE_TC_INSPECT) &&
|
|
|
|
|
(dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW))
|
|
|
|
|
{
|
|
|
|
|
SCLogDebug("unset ~DE_STATE_FLAG_FILE_TC_INSPECT ~DE_STATE_FLAG_SIG_CANT_MATCH");
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT;
|
|
|
|
|
item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH;
|
|
|
|
|
} else {
|
|
|
|
@ -821,6 +843,7 @@ static int DoInspectItem(ThreadVars *tv,
|
|
|
|
|
if (!(item->flags & engine->inspect_flags) &&
|
|
|
|
|
s->sm_lists[engine->sm_list] != NULL)
|
|
|
|
|
{
|
|
|
|
|
SCLogDebug("inspect_flags %x", inspect_flags);
|
|
|
|
|
KEYWORD_PROFILING_SET_LIST(det_ctx, engine->sm_list);
|
|
|
|
|
int match = engine->Callback(tv, de_ctx, det_ctx, s, f,
|
|
|
|
|
flags, alstate, inspect_tx, inspect_tx_id);
|
|
|
|
@ -841,6 +864,7 @@ static int DoInspectItem(ThreadVars *tv,
|
|
|
|
|
}
|
|
|
|
|
engine = engine->next;
|
|
|
|
|
}
|
|
|
|
|
SCLogDebug("inspect_flags %x", inspect_flags);
|
|
|
|
|
if (total_matches > 0 && (engine == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH)) {
|
|
|
|
|
if (engine == NULL)
|
|
|
|
|
alert = 1;
|
|
|
|
@ -1025,6 +1049,8 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
|
|
|
|
|
DetectEngineStateDirection *tx_dir_state = &tx_de_state->dir_state[direction];
|
|
|
|
|
DeStateStore *tx_store = tx_dir_state->head;
|
|
|
|
|
|
|
|
|
|
SCLogDebug("tx_dir_state->filestore_cnt %u", tx_dir_state->filestore_cnt);
|
|
|
|
|
|
|
|
|
|
/* see if we need to consider the next tx in our decision to add
|
|
|
|
|
* a sig to the 'no inspect array'. */
|
|
|
|
|
if (!TxIsLast(inspect_tx_id, total_txs)) {
|
|
|
|
|