]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
protodetect: allows not port-based probing parsers
authorPhilippe Antoine <pantoine@oisf.net>
Sat, 30 Dec 2023 20:28:50 +0000 (21:28 +0100)
committerVictor Julien <victor@inliniac.net>
Wed, 17 Apr 2024 05:17:02 +0000 (07:17 +0200)
As for WebSocket which is detected only by protocol change.

src/app-layer-detect-proto.c

index 99cf4756ff5005cfa10ef6f43debef2fd789c7fd..35fc39ced4635db170f11b1bc162ffcc6d46e6ef 100644 (file)
@@ -86,6 +86,9 @@ typedef struct AppLayerProtoDetectProbingParserElement_ {
 typedef struct AppLayerProtoDetectProbingParserPort_ {
     /* the port no for which probing parser(s) are invoked */
     uint16_t port;
+    /* wether to use this probing parser port-based */
+    // WebSocket has this set to false as it only works with protocol change
+    bool use_ports;
 
     uint32_t alproto_mask;
 
@@ -441,7 +444,8 @@ static AppLayerProtoDetectProbingParserPort *AppLayerProtoDetectGetProbingParser
 
     pp_port = pp->port;
     while (pp_port != NULL) {
-        if (pp_port->port == port || pp_port->port == 0) {
+        // always check use_ports
+        if ((pp_port->port == port || pp_port->port == 0) && pp_port->use_ports) {
             break;
         }
         pp_port = pp_port->next;
@@ -933,12 +937,14 @@ static void AppLayerProtoDetectProbingParserPortAppend(AppLayerProtoDetectProbin
         goto end;
     }
 
-    if ((*head_port)->port == 0) {
+    // port == 0 && use_ports is special run on any ports, kept at tail
+    if ((*head_port)->port == 0 && (*head_port)->use_ports) {
         new_port->next = *head_port;
         *head_port = new_port;
     } else {
         AppLayerProtoDetectProbingParserPort *temp_port = *head_port;
-        while (temp_port->next != NULL && temp_port->next->port != 0) {
+        while (temp_port->next != NULL &&
+                !(temp_port->next->port == 0 && temp_port->next->use_ports)) {
             temp_port = temp_port->next;
         }
         new_port->next = temp_port->next;
@@ -950,13 +956,9 @@ static void AppLayerProtoDetectProbingParserPortAppend(AppLayerProtoDetectProbin
 }
 
 static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbingParser **pp,
-                                                             uint8_t ipproto,
-                                                             uint16_t port,
-                                                             AppProto alproto,
-                                                             uint16_t min_depth, uint16_t max_depth,
-                                                             uint8_t direction,
-                                                             ProbingParserFPtr ProbingParser1,
-                                                             ProbingParserFPtr ProbingParser2)
+        uint8_t ipproto, bool use_ports, uint16_t port, AppProto alproto, uint16_t min_depth,
+        uint16_t max_depth, uint8_t direction, ProbingParserFPtr ProbingParser1,
+        ProbingParserFPtr ProbingParser2)
 {
     SCEnter();
 
@@ -977,13 +979,15 @@ static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbing
     /* get the top level port pp */
     AppLayerProtoDetectProbingParserPort *curr_port = curr_pp->port;
     while (curr_port != NULL) {
-        if (curr_port->port == port)
+        // when not use_ports, always insert a new AppLayerProtoDetectProbingParserPort
+        if (curr_port->port == port && use_ports)
             break;
         curr_port = curr_port->next;
     }
     if (curr_port == NULL) {
         AppLayerProtoDetectProbingParserPort *new_port = AppLayerProtoDetectProbingParserPortAlloc();
         new_port->port = port;
+        new_port->use_ports = use_ports;
         AppLayerProtoDetectProbingParserPortAppend(&curr_pp->port, new_port);
         curr_port = new_port;
         if (direction & STREAM_TOSERVER) {
@@ -995,7 +999,8 @@ static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbing
         AppLayerProtoDetectProbingParserPort *zero_port;
 
         zero_port = curr_pp->port;
-        while (zero_port != NULL && zero_port->port != 0) {
+        // get special run on any port if any, to add it to this port
+        while (zero_port != NULL && !(zero_port->port == 0 && zero_port->use_ports)) {
             zero_port = zero_port->next;
         }
         if (zero_port != NULL) {
@@ -1091,9 +1096,10 @@ static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbing
     }
     AppLayerProtoDetectProbingParserElementAppend(head_pe, new_pe);
 
-    if (curr_port->port == 0) {
+    // when adding special run on any port, add it on all existing ones
+    if (curr_port->port == 0 && curr_port->use_ports) {
         AppLayerProtoDetectProbingParserPort *temp_port = curr_pp->port;
-        while (temp_port != NULL && temp_port->port != 0) {
+        while (temp_port != NULL && !(temp_port->port == 0 && temp_port->use_ports)) {
             if (direction & STREAM_TOSERVER) {
                 if (temp_port->dp == NULL)
                     temp_port->dp_max_depth = curr_pe->max_depth;
@@ -1121,7 +1127,7 @@ static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbing
             }
             temp_port = temp_port->next;
         } /* while */
-    } /* if */
+    }     /* if */
 
  error:
     SCReturn;
@@ -1542,6 +1548,13 @@ void AppLayerProtoDetectPPRegister(uint8_t ipproto,
     SCEnter();
 
     DetectPort *head = NULL;
+    if (portstr == NULL) {
+        // WebSocket has a probing parser, but no port
+        // as it works only on HTTP1 protocol upgrade
+        AppLayerProtoDetectInsertNewProbingParser(&alpd_ctx.ctx_pp, ipproto, false, 0, alproto,
+                min_depth, max_depth, direction, ProbingParser1, ProbingParser2);
+        return;
+    }
     DetectPortParse(NULL,&head, portstr);
     DetectPort *temp_dp = head;
     while (temp_dp != NULL) {
@@ -1549,14 +1562,8 @@ void AppLayerProtoDetectPPRegister(uint8_t ipproto,
         if (port == 0 && temp_dp->port2 != 0)
             port++;
         for (;;) {
-            AppLayerProtoDetectInsertNewProbingParser(&alpd_ctx.ctx_pp,
-                                                      ipproto,
-                                                      port,
-                                                      alproto,
-                                                      min_depth, max_depth,
-                                                      direction,
-                                                      ProbingParser1,
-                                                      ProbingParser2);
+            AppLayerProtoDetectInsertNewProbingParser(&alpd_ctx.ctx_pp, ipproto, true, port,
+                    alproto, min_depth, max_depth, direction, ProbingParser1, ProbingParser2);
             if (port == temp_dp->port2) {
                 break;
             } else {