@ -27,59 +27,101 @@
# include "stream-tcp-reassemble.h"
# include "action-globals.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 ) ;
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 " ) ;
}
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 ;
@ -88,7 +130,7 @@ enum ExceptionPolicy ExceptionPolicyParse(const char *option, const bool support
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 ;
@ -97,7 +139,10 @@ enum ExceptionPolicy ExceptionPolicyParse(const char *option, const bool support
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 (
@ -110,12 +155,29 @@ enum ExceptionPolicy ExceptionPolicyParse(const char *option, const bool support
if ( policy = = EXCEPTION_POLICY_DROP_FLOW | | policy = = EXCEPTION_POLICY_PASS_FLOW | |
policy = = EXCEPTION_POLICY_BYPASS_FLOW ) {
SCLogWarning ( " flow actions not supported for %s, defaulting to \" ignore \" " , option ) ;
policy = EXCEPTION_POLICY_ IGNORE ;
policy = EXCEPTION_POLICY_ NOT_SET ;
}
}
} else if ( strcmp ( option , " exception-policy " ) = = 0 ) {
/* not enabled, we won't change the master exception policy,
for now */
SCLogWarning ( " '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 ;
}