diff --git a/src/detect-engine-prefilter.c b/src/detect-engine-prefilter.c index 448172c045..4f69de66fe 100644 --- a/src/detect-engine-prefilter.c +++ b/src/detect-engine-prefilter.c @@ -973,14 +973,15 @@ static int SetupNonPrefilter(DetectEngineCtx *de_ctx, SigGroupHead *sgh) for (uint8_t state = 0; state < s->app_progress_hook; state++) { SCLogDebug("handle HOOK %u LTE", state); const int dir = (s->flags & SIG_FLAG_TOSERVER) ? 0 : 1; + const uint8_t sub_state = s->init_data->hook.t.app.sub_state; const char *pname = DetectEngineAppHookToName( - s->alproto, state, dir == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT); + s->alproto, sub_state, state, dir == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT); if (pname == NULL) { goto error; } - const int sm_list = DetectEngineAppHookToSmlist( - s->alproto, state, dir == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT); - uint8_t sub_state = s->init_data->hook.t.app.sub_state; + const uint8_t direction = dir == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT; + const int sm_list = + DetectEngineAppHookToSmlist(s->alproto, sub_state, state, direction); if (TxNonPFAddSig(de_ctx, tx_engines_hash, s->alproto, sub_state, dir, state, sm_list, pname, s) != 0) { goto error; diff --git a/src/detect-engine.c b/src/detect-engine.c index ed1f36651d..0a4109c760 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -839,37 +839,46 @@ static void AppendAppInspectEngine(DetectEngineCtx *de_ctx, * \param direction STREAM_TOSERVER or STREAM_TOCLIENT */ const char *DetectEngineAppHookToName( - const AppProto p, const uint8_t state, const uint8_t direction) + const AppProto p, const uint8_t sub_state, const uint8_t state, const uint8_t direction) { if (!((direction & (STREAM_TOSERVER | STREAM_TOCLIENT)) == STREAM_TOSERVER) && !((direction & (STREAM_TOSERVER | STREAM_TOCLIENT)) == STREAM_TOCLIENT)) return NULL; - const char *pname = AppLayerParserGetStateNameById(IPPROTO_TCP, // TODO - p, state, direction); - if (pname == NULL) { - if (state == 0) { - if (direction == STREAM_TOSERVER) { - pname = "request_started"; - } else { - pname = "response_started"; - } - } else { - const int complete = AppLayerParserGetStateProgressCompletionStatus(p, direction); - if (state == complete) { + if (sub_state == 0) { + const char *pname = AppLayerParserGetStateNameById(IPPROTO_TCP, // TODO + p, state, direction); + if (pname == NULL) { + if (state == 0) { if (direction == STREAM_TOSERVER) { - pname = "request_complete"; + pname = "request_started"; } else { - pname = "response_complete"; + pname = "response_started"; + } + } else { + const int complete = AppLayerParserGetStateProgressCompletionStatus(p, direction); + if (state == complete) { + if (direction == STREAM_TOSERVER) { + pname = "request_complete"; + } else { + pname = "response_complete"; + } } } } + return pname; + } else { + BUG_ON(!AppLayerParserSupportsSubStates(p)); + const char *name = AppLayerParserGetSubStateProgressName(p, sub_state, state, direction); + return name; } - return pname; } -/** \brief get the sm_list for a app hook */ -int DetectEngineAppHookToSmlist(const AppProto p, const uint8_t state, const int direction) +/** \brief get the sm_list for a app hook + * \param sub_state sub_state to use or 0 if not in use + * */ +int DetectEngineAppHookToSmlist( + const AppProto p, const uint8_t sub_state, const uint8_t state, const uint8_t direction) { const char *app_proto = AppProtoToString(p); if (app_proto == NULL) { @@ -879,20 +888,45 @@ int DetectEngineAppHookToSmlist(const AppProto p, const uint8_t state, const int if (strcmp(app_proto, "http") == 0) app_proto = "http1"; - const char *name = - DetectEngineAppHookToName(p, state, direction & (STREAM_TOSERVER | STREAM_TOCLIENT)); - if (name == NULL) { - return -1; - } - char generic_hook_name[256]; - snprintf(generic_hook_name, sizeof(generic_hook_name), "%s:%s:generic", app_proto, name); - int list = DetectBufferTypeGetByName(generic_hook_name); - if (list < 0) { - SCLogError("no list registered as %s for %s hook %s", generic_hook_name, app_proto, name); - return -1; + if (sub_state == 0) { + const char *name = DetectEngineAppHookToName( + p, 0, state, direction & (STREAM_TOSERVER | STREAM_TOCLIENT)); + if (name == NULL) { + return -1; + } + + snprintf(generic_hook_name, sizeof(generic_hook_name), "%s:%s:generic", app_proto, name); + + int list = DetectBufferTypeGetByName(generic_hook_name); + if (list < 0) { + SCLogError( + "no list registered as %s for %s hook %s", generic_hook_name, app_proto, name); + return -1; + } + return list; + } else { + BUG_ON(!AppLayerParserSupportsSubStates(p)); + + const char *sname = AppLayerParserGetSubStateName(p, sub_state); + if (sname == NULL) + return -1; + + const char *name = AppLayerParserGetSubStateProgressName(p, sub_state, state, direction); + if (name == NULL) + return -1; + + snprintf(generic_hook_name, sizeof(generic_hook_name), "%s:%s:%s:generic", app_proto, sname, + name); + + int list = DetectBufferTypeGetByName(generic_hook_name); + if (list < 0) { + SCLogError("no list registered as %s for %s sub_state %s hook %s", generic_hook_name, + app_proto, sname, name); + return -1; + } + return list; } - return list; } /** @@ -911,7 +945,7 @@ int DetectEngineAppInspectionEngine2Signature(DetectEngineCtx *de_ctx, Signature SCLogDebug("need an inspect engine per state, range 0-%u", s->app_progress_hook); for (uint8_t state = 0; state < s->app_progress_hook; state++) { uint8_t dir = 0; - int direction = 0; + uint8_t direction = 0; BUG_ON((s->flags & (SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT)) == (SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT)); BUG_ON((s->flags & (SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT)) == 0); @@ -923,8 +957,8 @@ int DetectEngineAppInspectionEngine2Signature(DetectEngineCtx *de_ctx, Signature dir = 1; } - int sm_list = - DetectEngineAppHookToSmlist(s->init_data->hook.t.app.alproto, 0, direction); + int sm_list = DetectEngineAppHookToSmlist(s->init_data->hook.t.app.alproto, + s->init_data->hook.t.app.sub_state, 0, direction); if (sm_list < 0) return -1; diff --git a/src/detect-engine.h b/src/detect-engine.h index 12d95411d5..0c2bfcfee5 100644 --- a/src/detect-engine.h +++ b/src/detect-engine.h @@ -218,7 +218,8 @@ void DetectLowerSetupCallback( void DeStateRegisterTests(void); const char *DetectEngineAppHookToName( - const AppProto p, const uint8_t state, const uint8_t direction); -int DetectEngineAppHookToSmlist(const AppProto p, const uint8_t state, const int direction); + const AppProto p, const uint8_t sub_state, const uint8_t state, const uint8_t direction); +int DetectEngineAppHookToSmlist( + const AppProto p, const uint8_t sub_state, const uint8_t state, const uint8_t direction); #endif /* SURICATA_DETECT_ENGINE_H */ diff --git a/src/detect-parse.c b/src/detect-parse.c index 80c93b51e2..9c513170af 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -1388,6 +1388,7 @@ static int SigParseProtoHookApp( Signature *s, const char *proto_hook, const char *p, const char *in_h) { char hook[64]; + char generic_hook_name[256]; strlcpy(hook, in_h, sizeof(hook)); const char *h = hook; const char *t = NULL; @@ -1425,6 +1426,12 @@ static int SigParseProtoHookApp( SCLogError("sub states currently only supported for http2"); return -1; } + /* FW hook LTE mode */ + if (*h == '<') { + h++; + SCLogDebug("hook and prior hooks: '%s'", h); + s->flags |= SIG_FLAG_FW_HOOK_LTE; + } const uint8_t max_state = AppLayerParserGetSubStateCompletion( s->alproto, sub_state); // TODO allow different completion per direction? if (strcmp(h, "request_started") == 0) { @@ -1457,7 +1464,14 @@ static int SigParseProtoHookApp( s->init_data->hook = SetAppHook(s->alproto, sub_state, progress_tc); } } + snprintf(generic_hook_name, sizeof(generic_hook_name), "%s:%s:%s:generic", p, t, h); } else { + /* FW hook LTE mode */ + if (*h == '<') { + h++; + SCLogDebug("hook and prior hooks: '%s'", h); + s->flags |= SIG_FLAG_FW_HOOK_LTE; + } SCLogDebug("h:'%s'", h); if (strcmp(h, "request_started") == 0) { s->flags |= SIG_FLAG_TOSERVER; @@ -1494,11 +1508,10 @@ static int SigParseProtoHookApp( s->init_data->hook = SetAppHook(s->alproto, sub_state, (uint8_t)progress_tc); } } + snprintf(generic_hook_name, sizeof(generic_hook_name), "%s:%s:generic", p, h); } + SCLogDebug("generic_hook_name %s", generic_hook_name); - /* use in_h to include sub state */ - char generic_hook_name[128]; - snprintf(generic_hook_name, sizeof(generic_hook_name), "%s:%s:generic", p, in_h); int list = DetectBufferTypeGetByName(generic_hook_name); if (list < 0) { SCLogError("no list registered as %s for hook %s", generic_hook_name, proto_hook); @@ -1570,14 +1583,6 @@ static int SigParseProto(Signature *s, const char *protostr) SCLogError("invalid protocol specification '%s'", proto); return -1; } - - /* FW hook LTE mode */ - SCLogDebug("hook '%s'", h); - if (*h == '<') { - h++; - SCLogDebug("hook and prior hooks: '%s'", h); - s->flags |= SIG_FLAG_FW_HOOK_LTE; - } if (SigParseProtoHookApp(s, protostr, p, h) < 0) { SCLogError("protocol \"%s\" does not support hook \"%s\"", p, h); SCReturnInt(-1);