]> 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>
Mon, 14 Jun 2021 19:05:19 +0000 (21:05 +0200)
AppProtoEquals function allows to check if a flow protocol
matches a signature protocol

This allows HTTP1 keywords on HTTP2 traffic

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 f2562d016a15d1eaf93efa95d8cbb143ffea4f8b..1ac54950361b9943878ffad5e2e5c961798f123c 100644 (file)
@@ -2081,12 +2081,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..ff383c15149927b243bf62664db98d08d3f2cb7c 100644 (file)
@@ -77,6 +77,16 @@ 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)
+{
+    if (alproto == ALPROTO_HTTP2 && sigproto == ALPROTO_HTTP) {
+        // TODO config option
+        return true;
+    }
+    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 3a41868fb5dcbc54ba9e4cbfe6119cdaf373e93a..cc06e73a59905658f00be32dab78bc412cc0339e 100644 (file)
@@ -551,7 +551,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 2bed7cf277b3459ae8171f048ec7d1e1f97c2254..4960486b17013ce3095f4acd8e60a8b619e13cf8 100644 (file)
@@ -1017,7 +1017,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 5464835a7dc3bdc7ef4c231e18bd3d9b880cea87..08f651a72e323a1fd5d80b07464e9444a4057bcb 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,16 +1491,15 @@ int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
         return -1;
     }
 
-    if (s->alproto != ALPROTO_UNKNOWN && s->alproto != alproto &&
-            // allow to keep HTTP2 with HTTP1 keywords
-            !(s->alproto == ALPROTO_HTTP2 && alproto == ALPROTO_HTTP)) {
+    if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(alproto, s->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_HTTP2 && alproto == ALPROTO_HTTP)) {
+    // allow to keep HTTP2 as s->alproto with HTTP1 alproto keywords
+    if (!AppProtoEquals(alproto, s->alproto)) {
         s->alproto = alproto;
     }
     s->flags |= SIG_FLAG_APPLAYER;
@@ -1691,7 +1690,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 bd061763259cafd589e80d1a1e7bb4f0961950ee..d842f586a5ae4e8a0d13b4b8d7209f0f10ae5274 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;
         }
     }
@@ -777,7 +778,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");
@@ -1090,7 +1091,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;
         }