detect: explicit action scopes

For drop and pass allow setting the scope explicitly:

        drop:flow
        drop:packet

        pass:flow
        pass:packet

Ticket: #7481.
pull/12979/head
Victor Julien 8 months ago committed by Victor Julien
parent 9539002b39
commit 4071acd659

@ -38,4 +38,10 @@
#define ACTION_DROP_REJECT (ACTION_REJECT_ANY | ACTION_DROP)
enum ActionScope {
ACTION_SCOPE_AUTO = 0,
ACTION_SCOPE_PACKET, /**< apply action to packet */
ACTION_SCOPE_FLOW, /**< apply drop/pass/accept action to flow */
};
#endif /* SURICATA_ACTION_GLOBALS_H */

@ -341,7 +341,11 @@ static inline void FlowApplySignatureActions(
DEBUG_VALIDATE_BUG_ON(s->type == SIG_TYPE_NOT_SET);
DEBUG_VALIDATE_BUG_ON(s->type == SIG_TYPE_MAX);
enum SignaturePropertyFlowAction flow_action = signature_properties[s->type].flow_action;
if (s->action_scope == ACTION_SCOPE_FLOW) {
pa->flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
} else if (s->action_scope == ACTION_SCOPE_AUTO) {
enum SignaturePropertyFlowAction flow_action =
signature_properties[s->type].flow_action;
if (flow_action == SIG_PROP_FLOW_ACTION_FLOW) {
pa->flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
} else if (flow_action == SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL) {
@ -349,6 +353,7 @@ static inline void FlowApplySignatureActions(
pa->flags |= PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW;
}
}
}
if (pa->flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW) {
SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x (set "

@ -1035,6 +1035,8 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
SCJbAppendString(ctx.js, "pass");
}
SCJbClose(ctx.js);
if (s->action_scope == ACTION_SCOPE_AUTO) {
enum SignaturePropertyFlowAction flow_action = signature_properties[s->type].flow_action;
switch (flow_action) {
case SIG_PROP_FLOW_ACTION_PACKET:
@ -1047,6 +1049,19 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
SCJbSetString(ctx.js, "scope", "flow_if_stateful");
break;
}
} else {
enum ActionScope as = s->action_scope;
switch (as) {
case ACTION_SCOPE_PACKET:
SCJbSetString(ctx.js, "scope", "packet");
break;
case ACTION_SCOPE_FLOW:
SCJbSetString(ctx.js, "scope", "flow");
break;
case ACTION_SCOPE_AUTO: /* should be unreachable */
break;
}
}
SCJbClose(ctx.js);
switch (s->type) {

@ -1268,7 +1268,7 @@ static int SigParseProtoHookApp(Signature *s, const char *proto_hook, const char
}
s->init_data->hook.sm_list = list;
SCLogNotice("protocol:%s hook:%s: type:%s alproto:%u hook:%d", p, h,
SCLogDebug("protocol:%s hook:%s: type:%s alproto:%u hook:%d", p, h,
SignatureHookTypeToString(s->init_data->hook.type), s->init_data->hook.t.app.alproto,
s->init_data->hook.t.app.app_progress);
return 0;
@ -1453,12 +1453,52 @@ static uint8_t ActionStringToFlags(const char *action)
* Signature.
* \retval -1 On failure.
*/
static int SigParseAction(Signature *s, const char *action)
static int SigParseAction(Signature *s, const char *action_in)
{
uint8_t flags = ActionStringToFlags(action);
char action[32];
strlcpy(action, action_in, sizeof(action));
const char *a = action;
const char *o = NULL;
bool has_scope = strchr(action, ':') != NULL;
if (has_scope) {
char *xsaveptr = NULL;
a = strtok_r(action, ":", &xsaveptr);
o = strtok_r(NULL, ":", &xsaveptr);
SCLogDebug("a: '%s' o: '%s'", a, o);
}
if (a == NULL) {
SCLogError("invalid protocol specification '%s'", action_in);
return -1;
}
uint8_t flags = ActionStringToFlags(a);
if (flags == 0)
return -1;
/* parse scope, if any */
if (o) {
uint8_t scope_flags = 0;
if (flags & (ACTION_DROP | ACTION_PASS)) {
if (strcmp(o, "packet") == 0) {
scope_flags = (uint8_t)ACTION_SCOPE_PACKET;
} else if (strcmp(o, "flow") == 0) {
scope_flags = (uint8_t)ACTION_SCOPE_FLOW;
} else {
SCLogError("invalid action scope '%s' in action '%s': only 'packet' and 'flow' "
"allowed",
o, action_in);
return -1;
}
s->action_scope = scope_flags;
} else {
SCLogError("invalid action scope '%s' in action '%s': scope only supported for actions "
"'drop', 'pass' and 'reject'",
o, action_in);
return -1;
}
}
s->action = flags;
return 0;
}

@ -667,6 +667,9 @@ typedef struct Signature_ {
/** addresses, ports and proto this sig matches on */
DetectProto proto;
/* scope setting for the action: enum ActionScope */
uint8_t action_scope;
/** ipv4 match arrays */
uint16_t addr_dst_match4_cnt;
uint16_t addr_src_match4_cnt;

Loading…
Cancel
Save