diff --git a/doc/userguide/configuration/exception-policies.rst b/doc/userguide/configuration/exception-policies.rst index 10af446e5874..5944f529428a 100644 --- a/doc/userguide/configuration/exception-policies.rst +++ b/doc/userguide/configuration/exception-policies.rst @@ -45,10 +45,13 @@ also defined in the yaml file. Auto '''' -**In IPS mode**, the default behavior for all exception policies is to drop -the flow, or the packet, when the flow action is not supported. It is possible -to disable this default, by setting the exception policies' "master switch" yaml -config option to ``ignore``. +**In IPS mode**, the default behavior for most of the exception policies is to +fail close. This means droping the flow, or the packet, when the flow action is +not supported. The default policy for the midstream exception will be ignore if +midstream flows are accepted. + +It is possible to disable this default, by setting the exception policies' +"master switch" yaml config option to ``ignore``. **In IDS mode**, setting ``auto`` mode actually means disabling the ``master-switch``, or ignoring the exception policies. diff --git a/rust/src/rfb/rfb.rs b/rust/src/rfb/rfb.rs index 940417e8311b..8c3381345012 100644 --- a/rust/src/rfb/rfb.rs +++ b/rust/src/rfb/rfb.rs @@ -240,6 +240,15 @@ impl RFBState { current = rem; let chosen_security_type = request.security_type; + + if let Some(current_transaction) = self.get_current_tx() { + current_transaction.ts_security_type_selection = Some(request); + current_transaction.chosen_security_type = + Some(chosen_security_type as u32); + } else { + debug_validate_fail!("no transaction set at security type stage"); + } + match chosen_security_type { 2 => self.state = parser::RFBGlobalState::TCVncChallenge, 1 => self.state = parser::RFBGlobalState::TSClientInit, @@ -256,14 +265,6 @@ impl RFBState { return AppLayerResult::ok(); } } - - if let Some(current_transaction) = self.get_current_tx() { - current_transaction.ts_security_type_selection = Some(request); - current_transaction.chosen_security_type = - Some(chosen_security_type as u32); - } else { - debug_validate_fail!("no transaction set at security type stage"); - } } Err(Err::Incomplete(_)) => { return AppLayerResult::incomplete( @@ -274,6 +275,7 @@ impl RFBState { Err(_) => { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::MalformedMessage); + current_transaction.complete = true; } // We failed to parse the security type. // Continue the flow but stop trying to map the protocol. @@ -312,6 +314,7 @@ impl RFBState { Err(_) => { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::MalformedMessage); + current_transaction.complete = true; } // Continue the flow but stop trying to map the protocol. self.state = parser::RFBGlobalState::Skip; @@ -348,6 +351,7 @@ impl RFBState { Err(_) => { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::MalformedMessage); + current_transaction.complete = true; } // We failed to parse the client init. // Continue the flow but stop trying to map the protocol. @@ -371,6 +375,7 @@ impl RFBState { SCLogDebug!("Invalid state for request: {}", self.state); if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::ConfusedState); + current_transaction.complete = true; } self.state = parser::RFBGlobalState::Skip; return AppLayerResult::ok(); @@ -479,6 +484,7 @@ impl RFBState { Err(_) => { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::MalformedMessage); + current_transaction.complete = true; } // Continue the flow but stop trying to map the protocol. self.state = parser::RFBGlobalState::Skip; @@ -511,6 +517,7 @@ impl RFBState { if let Some(current_transaction) = self.get_current_tx() { current_transaction .set_event(RFBEvent::UnimplementedSecurityType); + current_transaction.complete = true; } else { debug_validate_fail!( "no transaction set at security type stage" @@ -542,6 +549,7 @@ impl RFBState { Err(_) => { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::MalformedMessage); + current_transaction.complete = true; } // Continue the flow but stop trying to map the protocol. self.state = parser::RFBGlobalState::Skip; @@ -579,6 +587,7 @@ impl RFBState { Err(_) => { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::MalformedMessage); + current_transaction.complete = true; } // Continue the flow but stop trying to map the protocol. self.state = parser::RFBGlobalState::Skip; @@ -614,6 +623,7 @@ impl RFBState { } else { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::UnknownSecurityResult); + current_transaction.complete = true; } // Continue the flow but stop trying to map the protocol. self.state = parser::RFBGlobalState::Skip; @@ -629,6 +639,7 @@ impl RFBState { Err(_) => { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::MalformedMessage); + current_transaction.complete = true; } // Continue the flow but stop trying to map the protocol. self.state = parser::RFBGlobalState::Skip; @@ -655,6 +666,7 @@ impl RFBState { Err(_) => { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::MalformedMessage); + current_transaction.complete = true; } // Continue the flow but stop trying to map the protocol. self.state = parser::RFBGlobalState::Skip; @@ -695,6 +707,7 @@ impl RFBState { Err(_) => { if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::MalformedMessage); + current_transaction.complete = true; } // Continue the flow but stop trying to map the protocol. self.state = parser::RFBGlobalState::Skip; @@ -718,6 +731,7 @@ impl RFBState { SCLogDebug!("Invalid state for response: {}", self.state); if let Some(current_transaction) = self.get_current_tx() { current_transaction.set_event(RFBEvent::ConfusedState); + current_transaction.complete = true; } self.state = parser::RFBGlobalState::Skip; return AppLayerResult::ok(); diff --git a/src/util-exception-policy.c b/src/util-exception-policy.c index d346f0179576..6c8ba0fba975 100644 --- a/src/util-exception-policy.c +++ b/src/util-exception-policy.c @@ -174,6 +174,7 @@ static enum ExceptionPolicy ExceptionPolicyConfigValueParse( return policy; } +/* Select an exception policy in case the configuration value was set to 'auto' */ static enum ExceptionPolicy ExceptionPolicyPickAuto(bool midstream_enabled, bool support_flow) { enum ExceptionPolicy policy = EXCEPTION_POLICY_NOT_SET; @@ -190,10 +191,8 @@ static enum ExceptionPolicy ExceptionPolicyPickAuto(bool midstream_enabled, bool static enum ExceptionPolicy ExceptionPolicyMasterParse(const char *value) { enum ExceptionPolicy policy = ExceptionPolicyConfigValueParse("exception-policy", value); - if (policy == EXCEPTION_POLICY_AUTO) { - policy = ExceptionPolicyPickAuto(false, true); - } else if (!EngineModeIsIPS() && - (policy == EXCEPTION_POLICY_DROP_PACKET || policy == EXCEPTION_POLICY_DROP_FLOW)) { + if (!EngineModeIsIPS() && + (policy == EXCEPTION_POLICY_DROP_PACKET || policy == EXCEPTION_POLICY_DROP_FLOW)) { policy = EXCEPTION_POLICY_NOT_SET; } g_eps_have_exception_policy = true; @@ -209,6 +208,11 @@ static enum ExceptionPolicy ExceptionPolicyGetDefault( enum ExceptionPolicy p = EXCEPTION_POLICY_NOT_SET; if (g_eps_have_exception_policy) { p = GetMasterExceptionPolicy(option); + + if (p == EXCEPTION_POLICY_AUTO) { + p = ExceptionPolicyPickAuto(midstream, support_flow); + } + if (!support_flow) { p = PickPacketAction(option, p); } @@ -277,7 +281,7 @@ enum ExceptionPolicy ExceptionPolicyMidstreamParse(bool midstream_enabled) } } } else { - policy = ExceptionPolicyPickAuto(midstream_enabled, true); + policy = ExceptionPolicyGetDefault("stream.midstream-policy", true, midstream_enabled); } if (policy == EXCEPTION_POLICY_PASS_PACKET || policy == EXCEPTION_POLICY_DROP_PACKET) {