detect: set implied flow direction based on keywords

pull/3246/head
Victor Julien 9 years ago
parent 82ffba20f4
commit c8bd489aa1

@ -316,6 +316,37 @@ error:
}
int DetectFlowSetupImplicit(Signature *s, uint32_t flags)
{
#define SIG_FLAG_BOTH (SIG_FLAG_TOSERVER|SIG_FLAG_TOCLIENT)
BUG_ON(flags == 0);
BUG_ON(flags & ~SIG_FLAG_BOTH);
BUG_ON((flags & SIG_FLAG_BOTH) == SIG_FLAG_BOTH);
SCLogDebug("want %08x", flags & SIG_FLAG_BOTH);
SCLogDebug("have %08x", s->flags & SIG_FLAG_BOTH);
if (flags & SIG_FLAG_TOSERVER) {
if ((s->flags & SIG_FLAG_BOTH) == SIG_FLAG_BOTH) {
/* both is set if we just have 'flow:established' */
s->flags &= ~SIG_FLAG_TOCLIENT;
} else if (s->flags & SIG_FLAG_TOCLIENT) {
return -1;
}
s->flags |= SIG_FLAG_TOSERVER;
} else {
if ((s->flags & SIG_FLAG_BOTH) == SIG_FLAG_BOTH) {
/* both is set if we just have 'flow:established' */
s->flags &= ~SIG_FLAG_TOSERVER;
} else if (s->flags & SIG_FLAG_TOSERVER) {
return -1;
}
s->flags |= SIG_FLAG_TOCLIENT;
}
return 0;
#undef SIG_FLAG_BOTH
}
/**
* \brief this function is used to add the parsed flowdata into the current signature
*

@ -39,6 +39,8 @@ typedef struct DetectFlowData_ {
uint8_t match_cnt; /* number of matches we need */
} DetectFlowData;
int DetectFlowSetupImplicit(Signature *s, uint32_t flags);
/* prototypes */
void DetectFlowRegister (void);

@ -1553,15 +1553,65 @@ static int SigValidate(DetectEngineCtx *de_ctx, Signature *s)
SCReturnInt(0);
}
struct BufferVsDir {
int ts;
int tc;
} bufdir[nlists];
memset(&bufdir, 0, nlists * sizeof(struct BufferVsDir));
int x;
for (x = 0; x < nlists; x++) {
if (s->init_data->smlists[x]) {
const DetectEngineAppInspectionEngine *app = de_ctx->app_inspect_engines;
for ( ; app != NULL; app = app->next) {
if (app->sm_list == x && s->alproto == app->alproto) {
SCLogDebug("engine %s dir %d alproto %d",
DetectBufferTypeGetNameById(de_ctx, app->sm_list),
app->dir, app->alproto);
bufdir[x].ts += (app->dir == 0);
bufdir[x].tc += (app->dir == 1);
}
}
if (DetectBufferRunValidateCallback(de_ctx, x, s, &de_ctx->sigerror) == FALSE) {
SCReturnInt(0);
}
}
}
int ts_excl = 0;
int tc_excl = 0;
int dir_amb = 0;
for (x = 0; x < nlists; x++) {
if (bufdir[x].ts == 0 && bufdir[x].tc == 0)
continue;
ts_excl += (bufdir[x].ts > 0 && bufdir[x].tc == 0);
tc_excl += (bufdir[x].ts == 0 && bufdir[x].tc > 0);
dir_amb += (bufdir[x].ts > 0 && bufdir[x].tc > 0);
SCLogDebug("%s/%d: %d/%d", DetectBufferTypeGetNameById(de_ctx, x),
x, bufdir[x].ts, bufdir[x].tc);
}
if (ts_excl && tc_excl) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "rule %u mixes keywords with conflicting directions", s->id);
SCReturnInt(0);
} else if (ts_excl) {
SCLogDebug("%u: implied rule direction is toserver", s->id);
if (DetectFlowSetupImplicit(s, SIG_FLAG_TOSERVER) < 0) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "rule %u mixes keywords with conflicting directions", s->id);
SCReturnInt(0);
}
} else if (tc_excl) {
SCLogDebug("%u: implied rule direction is toclient", s->id);
if (DetectFlowSetupImplicit(s, SIG_FLAG_TOCLIENT) < 0) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "rule %u mixes keywords with conflicting directions", s->id);
SCReturnInt(0);
}
} else if (dir_amb) {
SCLogDebug("%u: rule direction cannot be deduced from keywords", s->id);
}
if ((s->flags & SIG_FLAG_REQUIRE_PACKET) &&
(s->flags & SIG_FLAG_REQUIRE_STREAM)) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "can't mix packet keywords with "

Loading…
Cancel
Save