#include "util-misc.h"
#include "stream-tcp-reassemble.h"
+enum ExceptionPolicy g_eps_master_switch = EXCEPTION_POLICY_NOT_SET;
+
+static const char *ExceptionPolicyEnumToString(enum ExceptionPolicy policy)
+{
+ switch (policy) {
+ case EXCEPTION_POLICY_NOT_SET:
+ return "ignore";
+ case EXCEPTION_POLICY_REJECT:
+ return "reject";
+ case EXCEPTION_POLICY_BYPASS_FLOW:
+ return "bypass";
+ case EXCEPTION_POLICY_DROP_FLOW:
+ return "drop-flow";
+ case EXCEPTION_POLICY_DROP_PACKET:
+ return "drop-packet";
+ case EXCEPTION_POLICY_PASS_PACKET:
+ return "pass-packet";
+ case EXCEPTION_POLICY_PASS_FLOW:
+ return "pass-flow";
+ }
+ // TODO we shouldn't reach this, but if we do, better not to leave this as simply null...
+ return "not set";
+}
+
+void SetMasterExceptionPolicy(void)
+{
+ g_eps_master_switch = ExceptionPolicyParse("exception-policy", true);
+}
+
+static enum ExceptionPolicy GetMasterExceptionPolicy(const char *option)
+{
+ return g_eps_master_switch;
+}
+
void ExceptionPolicyApply(Packet *p, enum ExceptionPolicy policy, enum PacketDropReason drop_reason)
{
SCLogDebug("start: pcap_cnt %" PRIu64 ", policy %u", p->pcap_cnt, policy);
- if (EngineModeIsIPS()) {
- switch (policy) {
- case EXCEPTION_POLICY_IGNORE:
- break;
- case EXCEPTION_POLICY_REJECT:
- SCLogDebug("EXCEPTION_POLICY_REJECT");
- PacketDrop(p, ACTION_REJECT, drop_reason);
- /* fall through */
- case EXCEPTION_POLICY_DROP_FLOW:
- SCLogDebug("EXCEPTION_POLICY_DROP_FLOW");
- if (p->flow) {
- p->flow->flags |= FLOW_ACTION_DROP;
- FlowSetNoPayloadInspectionFlag(p->flow);
- FlowSetNoPacketInspectionFlag(p->flow);
- StreamTcpDisableAppLayer(p->flow);
- }
- /* fall through */
- case EXCEPTION_POLICY_DROP_PACKET:
- SCLogDebug("EXCEPTION_POLICY_DROP_PACKET");
- DecodeSetNoPayloadInspectionFlag(p);
- DecodeSetNoPacketInspectionFlag(p);
- PacketDrop(p, ACTION_DROP, drop_reason);
- break;
- case EXCEPTION_POLICY_BYPASS_FLOW:
- PacketBypassCallback(p);
- /* fall through */
- case EXCEPTION_POLICY_PASS_FLOW:
- SCLogDebug("EXCEPTION_POLICY_PASS_FLOW");
- if (p->flow) {
- p->flow->flags |= FLOW_ACTION_PASS;
- FlowSetNoPacketInspectionFlag(p->flow); // TODO util func
- }
- /* fall through */
- case EXCEPTION_POLICY_PASS_PACKET:
- SCLogDebug("EXCEPTION_POLICY_PASS_PACKET");
- DecodeSetNoPayloadInspectionFlag(p);
- DecodeSetNoPacketInspectionFlag(p);
- PacketSetActionOnCurrentPkt(p, ACTION_PASS);
- break;
- }
+ switch (policy) {
+ case EXCEPTION_POLICY_NOT_SET:
+ break;
+ case EXCEPTION_POLICY_REJECT:
+ SCLogDebug("EXCEPTION_POLICY_REJECT");
+ PacketDrop(p, ACTION_REJECT, drop_reason);
+ /* fall through */
+ case EXCEPTION_POLICY_DROP_FLOW:
+ SCLogDebug("EXCEPTION_POLICY_DROP_FLOW");
+ if (p->flow) {
+ p->flow->flags |= FLOW_ACTION_DROP;
+ FlowSetNoPayloadInspectionFlag(p->flow);
+ FlowSetNoPacketInspectionFlag(p->flow);
+ StreamTcpDisableAppLayer(p->flow);
+ }
+ /* fall through */
+ case EXCEPTION_POLICY_DROP_PACKET:
+ SCLogDebug("EXCEPTION_POLICY_DROP_PACKET");
+ DecodeSetNoPayloadInspectionFlag(p);
+ DecodeSetNoPacketInspectionFlag(p);
+ PacketDrop(p, ACTION_DROP, drop_reason);
+ break;
+ case EXCEPTION_POLICY_BYPASS_FLOW:
+ PacketBypassCallback(p);
+ /* fall through */
+ case EXCEPTION_POLICY_PASS_FLOW:
+ SCLogDebug("EXCEPTION_POLICY_PASS_FLOW");
+ if (p->flow) {
+ p->flow->flags |= FLOW_ACTION_PASS;
+ FlowSetNoPacketInspectionFlag(p->flow); // TODO util func
+ }
+ /* fall through */
+ case EXCEPTION_POLICY_PASS_PACKET:
+ SCLogDebug("EXCEPTION_POLICY_PASS_PACKET");
+ DecodeSetNoPayloadInspectionFlag(p);
+ DecodeSetNoPacketInspectionFlag(p);
+ break;
}
SCLogDebug("end");
}
case EXCEPTION_POLICY_BYPASS_FLOW:
SCLogWarning(SC_ERR_INVALID_VALUE,
"flow actions not supported for %s, defaulting to \"ignore\"", option);
- return EXCEPTION_POLICY_IGNORE;
+ return EXCEPTION_POLICY_NOT_SET;
/* add all cases, to make sure new cases not handle will raise
* errors */
case EXCEPTION_POLICY_DROP_PACKET:
break;
case EXCEPTION_POLICY_REJECT:
break;
- case EXCEPTION_POLICY_IGNORE:
+ case EXCEPTION_POLICY_NOT_SET:
break;
}
return p;
}
+static enum ExceptionPolicy SetIPSOption(
+ const char *option, const char *value_str, enum ExceptionPolicy p)
+{
+ if (!EngineModeIsIPS()) {
+ SCLogConfig("%s: %s not a valid config in IDS mode. Ignoring it.)", option, value_str);
+ return EXCEPTION_POLICY_NOT_SET;
+ }
+ return p;
+}
+
enum ExceptionPolicy ExceptionPolicyParse(const char *option, const bool support_flow)
{
- enum ExceptionPolicy policy = EXCEPTION_POLICY_IGNORE;
+ enum ExceptionPolicy policy = EXCEPTION_POLICY_NOT_SET;
const char *value_str = NULL;
if ((ConfGet(option, &value_str)) == 1 && value_str != NULL) {
if (strcmp(value_str, "drop-flow") == 0) {
- policy = EXCEPTION_POLICY_DROP_FLOW;
+ policy = SetIPSOption(option, value_str, EXCEPTION_POLICY_DROP_FLOW);
SCLogConfig("%s: %s", option, value_str);
} else if (strcmp(value_str, "pass-flow") == 0) {
policy = EXCEPTION_POLICY_PASS_FLOW;
policy = EXCEPTION_POLICY_BYPASS_FLOW;
SCLogConfig("%s: %s", option, value_str);
} else if (strcmp(value_str, "drop-packet") == 0) {
- policy = EXCEPTION_POLICY_DROP_PACKET;
+ policy = SetIPSOption(option, value_str, EXCEPTION_POLICY_DROP_PACKET);
SCLogConfig("%s: %s", option, value_str);
} else if (strcmp(value_str, "pass-packet") == 0) {
policy = EXCEPTION_POLICY_PASS_PACKET;
policy = EXCEPTION_POLICY_REJECT;
SCLogConfig("%s: %s", option, value_str);
} else if (strcmp(value_str, "ignore") == 0) { // TODO name?
- policy = EXCEPTION_POLICY_IGNORE;
+ policy = EXCEPTION_POLICY_NOT_SET;
+ SCLogConfig("%s: %s", option, value_str);
+ } else if (strcmp(value_str, "auto") == 0) {
+ policy = SetIPSOption(option, value_str, EXCEPTION_POLICY_DROP_FLOW);
SCLogConfig("%s: %s", option, value_str);
} else {
FatalErrorOnInit(SC_ERR_INVALID_ARGUMENT,
policy = PickPacketAction(option, policy);
}
+ } else if (strcmp(option, "exception-policy") == 0) {
+ /* not enabled, we won't change the master exception policy,
+ for now */
+ SCLogInfo("'exception-policy' master switch not set, so ignoring it."
+ " This behavior will change in Suricata 8, so please update your"
+ " config. See ticket #5219 for more details.");
+ g_eps_master_switch = EXCEPTION_POLICY_NOT_SET;
} else {
- SCLogConfig("%s: ignore", option);
+ /* Exception Policy was not defined individually */
+ enum ExceptionPolicy master_policy = GetMasterExceptionPolicy(option);
+ if (master_policy == EXCEPTION_POLICY_NOT_SET) {
+ SCLogConfig("%s: ignore", option);
+ } else {
+ /* If the master switch was set and the Exception Policy option was not
+ individually set, use the defined master Exception Policy */
+ const char *value = ExceptionPolicyEnumToString(master_policy);
+ SCLogConfig("%s: %s (defined via 'exception-policy' master switch", option, value);
+ policy = master_policy;
+ }
}
return policy;
}