From: Philippe Antoine Date: Sat, 30 Dec 2023 20:28:50 +0000 (+0100) Subject: protodetect: allows not port-based probing parsers X-Git-Tag: suricata-8.0.0-beta1~1464 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=155d671b26db7862a66a8dfcd9de0253066ccb2f;p=thirdparty%2Fsuricata.git protodetect: allows not port-based probing parsers As for WebSocket which is detected only by protocol change. --- diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index 99cf4756ff..35fc39ced4 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -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 {