]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
proto: introduce signature protocol, as extension to flow protocol
authorPhilippe Antoine <contact@catenacyber.fr>
Mon, 7 Dec 2020 13:41:00 +0000 (14:41 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 18 Feb 2021 11:22:55 +0000 (12:22 +0100)
AppProtoEquals function allows to check if a flow protocol
matches a signature protocol

src/app-layer-detect-proto.c
src/app-layer-protos.h
src/detect-engine-prefilter-common.h
src/detect-engine.c
src/detect-filestore.c
src/detect-lua.c
src/detect-parse.c
src/detect-pcre.c
src/detect.c

index c123e12e3f582b0dbafe80b8e164b8b41a752241..c85e86459599cf25d9954f1a1908f1eaecec0fde 100644 (file)
@@ -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");
         }
     }
 
index 278c3e4389b050a00b2aa248d1533c73b5ad09f8..77a37b7bf2d7e96f4dec8b998c8060bbeef26293 100644 (file)
@@ -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.
  *
index 2ae1098a051ae29238f99275843d1b460118448b..315bb270f6cd8329d84ae15d62f35e7045b72bd8 100644 (file)
@@ -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:
index 83f80913cda0d76353b1711b3a4c8984d7c3e122..1667926579e6fdf8876df695be29e4388e4c4a37 100644 (file)
@@ -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)) {
index 9b6c5a1a49e51a598b6087635b9d6fb775e02317..b35565cd45585598fa4e8fdaf47195db2a05d363 100644 (file)
@@ -517,4 +517,4 @@ void DetectFilestoreRegisterTests(void)
 {
     UtRegisterTest("DetectFilestoreTest01", DetectFilestoreTest01);
 }
-#endif /* UNITTESTS */
\ No newline at end of file
+#endif /* UNITTESTS */
index 054378f40cb7db29125163e5c7f032ac86e4cc10..faf19980131d2f9945e17e358217de527074389c 100644 (file)
@@ -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;
index 59517b55918d949a85335331ffd70063893523b9..2fe943ae0407ec45c8a33128751889a8eb3006b5 100644 (file)
@@ -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);
index 9bff6d044d4f50b657c50d6bafd9710a9693ed79..7b73a5251d7fdfe6a230731cf13378ead4a4b9dd 100644 (file)
@@ -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 */
\ No newline at end of file
+#endif /* UNITTESTS */
index 63a97d893942978162616d67ad6529ca9b9aba42..4124adf385965605cd2182aa8ecd67c8050b019b 100644 (file)
@@ -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;
         }