detect/firewall: support lte mode for substate

pull/15846/head
Victor Julien 2 weeks ago
parent e1e24d6cb4
commit 2511070a58

@ -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;

@ -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;

@ -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 */

@ -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);

Loading…
Cancel
Save