proto: introduce signature protocol, as extension to flow protocol

AppProtoEquals function allows to check if a flow protocol
matches a signature protocol
pull/5875/head
Philippe Antoine 5 years ago committed by Victor Julien
parent 93ce39d450
commit c8dbe24fb6

@ -2106,12 +2106,10 @@ AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
SCEnter();
AppProto a;
AppProto b = StringToAppProto(alproto_name);
for (a = 0; a < ALPROTO_MAX; a++) {
if (alpd_ctx.alproto_names[a] != NULL &&
strlen(alpd_ctx.alproto_names[a]) == strlen(alproto_name) &&
(SCMemcmp(alpd_ctx.alproto_names[a], alproto_name, strlen(alproto_name)) == 0))
{
SCReturnCT(a, "AppProto");
if (alpd_ctx.alproto_names[a] != NULL && AppProtoEquals(b, a)) {
SCReturnCT(b, "AppProto");
}
}

@ -77,6 +77,12 @@ static inline bool AppProtoIsValid(AppProto a)
return ((a > ALPROTO_UNKNOWN && a < ALPROTO_FAILED));
}
// wether a signature AppProto matches a flow (or signature) AppProto
static inline bool AppProtoEquals(AppProto sigproto, AppProto alproto)
{
return (sigproto == alproto);
}
/**
* \brief Maps the ALPROTO_*, to its string equivalent.
*

@ -79,7 +79,7 @@ PrefilterPacketHeaderExtraMatch(const PrefilterPacketHeaderCtx *ctx,
case PREFILTER_EXTRA_MATCH_UNUSED:
break;
case PREFILTER_EXTRA_MATCH_ALPROTO:
if (p->flow == NULL || p->flow->alproto != ctx->value)
if (p->flow == NULL || !AppProtoEquals(ctx->value, p->flow->alproto))
return FALSE;
break;
case PREFILTER_EXTRA_MATCH_SRCPORT:

@ -480,7 +480,7 @@ int DetectEngineAppInspectionEngine2Signature(DetectEngineCtx *de_ctx, Signature
if (t->alproto == ALPROTO_UNKNOWN) {
/* special case, inspect engine applies to all protocols */
} else if (s->alproto != ALPROTO_UNKNOWN && s->alproto != t->alproto)
} else if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, t->alproto))
goto next;
if (s->flags & SIG_FLAG_TOSERVER && !(s->flags & SIG_FLAG_TOCLIENT)) {

@ -517,4 +517,4 @@ void DetectFilestoreRegisterTests(void)
{
UtRegisterTest("DetectFilestoreTest01", DetectFilestoreTest01);
}
#endif /* UNITTESTS */
#endif /* UNITTESTS */

@ -1011,7 +1011,7 @@ static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *st
goto error;
if (lua->alproto != ALPROTO_UNKNOWN) {
if (s->alproto != ALPROTO_UNKNOWN && lua->alproto != s->alproto) {
if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, lua->alproto)) {
goto error;
}
s->alproto = lua->alproto;

@ -163,7 +163,7 @@ int DetectEngineContentModifierBufferSetup(DetectEngineCtx *de_ctx,
sigmatch_table[sm_type].name);
goto end;
}
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != alproto) {
if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, alproto)) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting "
"alprotos set");
goto end;
@ -1491,11 +1491,15 @@ int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
return -1;
}
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != alproto) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS,
"can't set rule app proto to %s: already set to %s",
AppProtoToString(alproto), AppProtoToString(s->alproto));
return -1;
if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, alproto)) {
if (AppProtoEquals(alproto, s->alproto)) {
alproto = s->alproto;
} else {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS,
"can't set rule app proto to %s: already set to %s", AppProtoToString(alproto),
AppProtoToString(s->alproto));
return -1;
}
}
s->alproto = alproto;
@ -1687,7 +1691,8 @@ static int SigValidate(DetectEngineCtx *de_ctx, Signature *s)
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) || s->alproto == 0)) {
if (app->sm_list == x &&
(AppProtoEquals(s->alproto, app->alproto) || s->alproto == 0)) {
SCLogDebug("engine %s dir %d alproto %d",
DetectBufferTypeGetNameById(de_ctx, app->sm_list),
app->dir, app->alproto);

@ -904,8 +904,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, const char *r
if (alproto != ALPROTO_UNKNOWN) {
/* see if the proto doesn't conflict
* with what we already have. */
if (s->alproto != ALPROTO_UNKNOWN &&
alproto != s->alproto) {
if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, alproto)) {
goto error;
}
if (DetectSignatureSetAppProto(s, alproto) < 0)
@ -3656,4 +3655,4 @@ static void DetectPcreRegisterTests(void)
UtRegisterTest("DetectPcreParseCaptureTest", DetectPcreParseCaptureTest);
}
#endif /* UNITTESTS */
#endif /* UNITTESTS */

@ -361,7 +361,8 @@ DetectPrefilterBuildNonPrefilterList(DetectEngineThreadCtx *det_ctx,
* so build the non_mpm array only for match candidates */
const SignatureMask rule_mask = det_ctx->non_pf_store_ptr[x].mask;
const uint8_t rule_alproto = det_ctx->non_pf_store_ptr[x].alproto;
if ((rule_mask & mask) == rule_mask && (rule_alproto == 0 || rule_alproto == alproto)) {
if ((rule_mask & mask) == rule_mask &&
(rule_alproto == 0 || AppProtoEquals(rule_alproto, alproto))) {
det_ctx->non_pf_id_array[det_ctx->non_pf_id_cnt++] = det_ctx->non_pf_store_ptr[x].id;
}
}
@ -775,7 +776,7 @@ static inline void DetectRulePacketRules(
/* if the sig has alproto and the session as well they should match */
if (likely(sflags & SIG_FLAG_APPLAYER)) {
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != scratch->alproto) {
if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, scratch->alproto)) {
if (s->alproto == ALPROTO_DCERPC) {
if (scratch->alproto != ALPROTO_SMB) {
SCLogDebug("DCERPC sig, alproto not SMB");
@ -1088,7 +1089,7 @@ static bool DetectRunTxInspectRule(ThreadVars *tv,
return false;
}
/* stream mpm and negated mpm sigs can end up here with wrong proto */
if (!(f->alproto == s->alproto || s->alproto == ALPROTO_UNKNOWN)) {
if (!(AppProtoEquals(s->alproto, f->alproto) || s->alproto == ALPROTO_UNKNOWN)) {
TRACE_SID_TXS(s->id, tx, "alproto mismatch");
return false;
}

Loading…
Cancel
Save