diff --git a/src/detect-engine.c b/src/detect-engine.c index 913d1b653b..7f2bbefc51 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -2802,6 +2802,12 @@ void DetectEngineCtxFree(DetectEngineCtx *de_ctx) HashTableFree(de_ctx->non_pf_engine_names); } if (de_ctx->fw_policies) { + for (uint32_t i = 0; i < DETECT_FIREWALL_POLICY_SIZE; i++) { + if (de_ctx->fw_policies->pkt_policy_signatures[i]) { + SCFree(de_ctx->fw_policies->pkt_policy_signatures[i]->msg); + SCFree(de_ctx->fw_policies->pkt_policy_signatures[i]); + } + } HashTableFree(de_ctx->fw_policies->policy_signatures); } SCFree(de_ctx->fw_policies); diff --git a/src/detect-parse.c b/src/detect-parse.c index 86518b6d48..9d6accc4bf 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -3828,6 +3828,44 @@ void DetectFirewallPolicyToString(const struct DetectFirewallPolicy *p, char *ou } } +static int AddPktPolicySignature(struct DetectFirewallPolicies *fw_policies, + struct DetectFirewallPolicy *pol, enum DetectFirewallPacketPolicies pkt_pol) +{ + Signature *s = SCCalloc(1, sizeof(*s)); // SigAlloc does way more than we need + if (s == NULL) + return -1; + char msg[256]; + switch (pkt_pol) { + case DETECT_FIREWALL_POLICY_PACKET_FILTER: + s->detect_table = DETECT_TABLE_PACKET_FILTER; + break; + case DETECT_FIREWALL_POLICY_PRE_FLOW: + s->detect_table = DETECT_TABLE_PACKET_PRE_FLOW; + break; + case DETECT_FIREWALL_POLICY_PRE_STREAM: + s->detect_table = DETECT_TABLE_PACKET_PRE_STREAM; + break; + } + snprintf(msg, sizeof(msg), "SURICATA FW default packet policy"); + s->msg = SCStrdup(msg); + if (s->msg == NULL) { + SCFree(s); + return -1; + } + s->action = pol->action; + s->action_scope = pol->action_scope; + s->flags = SIG_FLAG_FIREWALL; + s->type = SIG_TYPE_PKT; + s->id = 2201000; + s->rev = 1; + s->gid = 1; + s->prio = 3; + + fw_policies->pkt_policy_signatures[pkt_pol] = s; + SCLogDebug("added to array"); + return 0; +} + static int AddAppPolicySignature(HashTable *ht, const int direction, const AppProto alproto, const char *app_name, const uint8_t hook, const char *hookname, struct DetectFirewallPolicy *pol) @@ -4023,6 +4061,11 @@ int DetectFirewallLoadDefaultPolicies(DetectEngineCtx *de_ctx) r = DoParsePolicy(policy_name, &fw_policies->pkt[DETECT_FIREWALL_POLICY_PACKET_FILTER]); if (r < 0) return -1; + if (fw_policies->pkt[DETECT_FIREWALL_POLICY_PACKET_FILTER].action & ACTION_ALERT) + if (AddPktPolicySignature(fw_policies, + &fw_policies->pkt[DETECT_FIREWALL_POLICY_PACKET_FILTER], + DETECT_FIREWALL_POLICY_PACKET_FILTER) < 0) + return -1; r = snprintf(policy_name, sizeof(policy_name), "%s.packet-pre-flow", prefix); if (r < 0 || (size_t)r >= sizeof(policy_name)) { @@ -4031,6 +4074,10 @@ int DetectFirewallLoadDefaultPolicies(DetectEngineCtx *de_ctx) r = DoParsePolicy(policy_name, &fw_policies->pkt[DETECT_FIREWALL_POLICY_PRE_FLOW]); if (r < 0) return -1; + if (fw_policies->pkt[DETECT_FIREWALL_POLICY_PRE_FLOW].action & ACTION_ALERT) + if (AddPktPolicySignature(fw_policies, &fw_policies->pkt[DETECT_FIREWALL_POLICY_PRE_FLOW], + DETECT_FIREWALL_POLICY_PRE_FLOW) < 0) + return -1; r = snprintf(policy_name, sizeof(policy_name), "%s.packet-pre-stream", prefix); if (r < 0 || (size_t)r >= sizeof(policy_name)) { @@ -4039,6 +4086,10 @@ int DetectFirewallLoadDefaultPolicies(DetectEngineCtx *de_ctx) r = DoParsePolicy(policy_name, &fw_policies->pkt[DETECT_FIREWALL_POLICY_PRE_STREAM]); if (r < 0) return -1; + if (fw_policies->pkt[DETECT_FIREWALL_POLICY_PRE_STREAM].action & ACTION_ALERT) + if (AddPktPolicySignature(fw_policies, &fw_policies->pkt[DETECT_FIREWALL_POLICY_PRE_STREAM], + DETECT_FIREWALL_POLICY_PRE_STREAM) < 0) + return -1; for (AppProto a = 0; a < g_alproto_max; a++) { if (!AppProtoIsValid(a)) diff --git a/src/detect.c b/src/detect.c index 7725122085..17cda58735 100644 --- a/src/detect.c +++ b/src/detect.c @@ -693,7 +693,8 @@ static inline bool SkipFwRules(const Packet *p) * packet:filter accept:hook to the packet as well. */ static uint8_t DetectRunApplyPacketPolicy(const DetectEngineCtx *de_ctx, - const enum DetectFirewallPacketPolicies policy, Packet *p, const bool final) + DetectEngineThreadCtx *det_ctx, const enum DetectFirewallPacketPolicies policy, Packet *p, + const bool final) { DEBUG_VALIDATE_BUG_ON(de_ctx->fw_policies == NULL); const struct DetectFirewallPolicy *pol = &de_ctx->fw_policies->pkt[policy]; @@ -727,6 +728,10 @@ static uint8_t DetectRunApplyPacketPolicy(const DetectEngineCtx *de_ctx, /* should be unreachable */ DEBUG_VALIDATE_BUG_ON(1); } + Signature *s = de_ctx->fw_policies->pkt_policy_signatures[policy]; + if (s != NULL) { + AlertQueueAppend(det_ctx, s, p, 0, PACKET_ALERT_FLAG_APPLY_ACTION_TO_PACKET); + } return p->action; } @@ -979,7 +984,7 @@ next: } else { DEBUG_VALIDATE_BUG_ON(action & ACTION_DROP); /* non-final call as we may have to consider app-layer still */ - action |= DetectRunApplyPacketPolicy(de_ctx, scratch->fw_pkt_policy, p, false); + action |= DetectRunApplyPacketPolicy(de_ctx, det_ctx, scratch->fw_pkt_policy, p, false); } } return action; @@ -1118,7 +1123,7 @@ static inline void DetectRunPostRules(ThreadVars *tv, const DetectEngineCtx *de_ p->pkt_src == PKT_SRC_WIRE) { SCLogDebug("packet %" PRIu64 ": default action as no verdict set %02x (pkt %s)", PcapPacketCntGet(p), p->action, PktSrcToString(p->pkt_src)); - (void)DetectRunApplyPacketPolicy(de_ctx, scratch->fw_pkt_policy, p, true); + (void)DetectRunApplyPacketPolicy(de_ctx, det_ctx, scratch->fw_pkt_policy, p, true); DEBUG_VALIDATE_BUG_ON((p->action & (ACTION_DROP | ACTION_ACCEPT)) == 0); } } diff --git a/src/detect.h b/src/detect.h index ac80dc3dc8..9dd6c39c51 100644 --- a/src/detect.h +++ b/src/detect.h @@ -934,6 +934,7 @@ struct DetectFirewallAppPolicy { struct DetectFirewallPolicies { /** policy for packet_filter, pre_flow, pre_stream hooks */ struct DetectFirewallPolicy pkt[DETECT_FIREWALL_POLICY_SIZE]; + Signature *pkt_policy_signatures[DETECT_FIREWALL_POLICY_SIZE]; /* hash table with a Signature object per default policy that has `alert` enabled. */ HashTable *policy_signatures;