Prevent a state action from invoking another one.

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2013-02-07 16:52:06 -08:00
parent aae6e001fe
commit b9e504683e
7 changed files with 41 additions and 34 deletions

View File

@ -95,6 +95,7 @@ our @EXPORT = ( qw(
HELPER HELPER
INLINE INLINE
TERMINATING TERMINATING
STATEMATCH
%chain_table %chain_table
%targets %targets
@ -346,22 +347,23 @@ our %nfobjects;
# #
# Target Types # Target Types
# #
use constant { STANDARD => 0x1, #defined by Netfilter use constant { STANDARD => 0x1, #defined by Netfilter
NATRULE => 0x2, #Involves NAT NATRULE => 0x2, #Involves NAT
BUILTIN => 0x4, #A built-in action BUILTIN => 0x4, #A built-in action
NONAT => 0x8, #'NONAT' or 'ACCEPT+' NONAT => 0x8, #'NONAT' or 'ACCEPT+'
NATONLY => 0x10, #'DNAT-' or 'REDIRECT-' NATONLY => 0x10, #'DNAT-' or 'REDIRECT-'
REDIRECT => 0x20, #'REDIRECT' REDIRECT => 0x20, #'REDIRECT'
ACTION => 0x40, #An action (may be built-in) ACTION => 0x40, #An action (may be built-in)
MACRO => 0x80, #A Macro MACRO => 0x80, #A Macro
LOGRULE => 0x100, #'LOG','NFLOG' LOGRULE => 0x100, #'LOG','NFLOG'
NFQ => 0x200, #'NFQUEUE' NFQ => 0x200, #'NFQUEUE'
CHAIN => 0x400, #Manual Chain CHAIN => 0x400, #Manual Chain
SET => 0x800, #SET SET => 0x800, #SET
AUDIT => 0x1000, #A_ACCEPT, etc AUDIT => 0x1000, #A_ACCEPT, etc
HELPER => 0x2000, #CT:helper HELPER => 0x2000, #CT:helper
NFLOG => 0x4000, #NFLOG or ULOG NFLOG => 0x4000, #NFLOG or ULOG
INLINE => 0x8000, #Inline action INLINE => 0x8000, #Inline action
STATEMATCH => 0x10000, #action.Invalid, action.Related, etc.
}; };
# #
# Valid Targets -- value is a combination of one or more of the above # Valid Targets -- value is a combination of one or more of the above

View File

@ -1664,7 +1664,7 @@ sub process_actions() {
} }
sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ); sub process_rule ( $$$$$$$$$$$$$$$$$$$ );
# #
# Populate an action invocation chain. As new action tuples are encountered, # Populate an action invocation chain. As new action tuples are encountered,
@ -1720,7 +1720,6 @@ sub process_action($$) {
process_rule( $chainref, process_rule( $chainref,
'', '',
0,
$nolog ? $target : merge_levels( join(':', @actparms{'chain','loglevel','logtag'}), $target ), $nolog ? $target : merge_levels( join(':', @actparms{'chain','loglevel','logtag'}), $target ),
'', '',
$source, $source,
@ -1866,7 +1865,6 @@ sub process_macro ($$$$$$$$$$$$$$$$$$$$) {
$generated |= process_rule( $generated |= process_rule(
$chainref, $chainref,
$matches, $matches,
0,
$mtarget, $mtarget,
$param, $param,
$msource, $msource,
@ -1986,7 +1984,6 @@ sub process_inline ($$$$$$$$$$$$$$$$$$$$$) {
$generated |= process_rule( $generated |= process_rule(
$chainref, $chainref,
$matches, $matches,
0,
$mtarget, $mtarget,
$param, $param,
$msource, $msource,
@ -2039,10 +2036,9 @@ sub verify_audit($;$$) {
# reference is also passed when rules are being generated during processing of a macro used as a default action. # reference is also passed when rules are being generated during processing of a macro used as a default action.
# #
sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) { sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
my ( $chainref, #reference to Action Chain if we are being called from process_action(); undef otherwise my ( $chainref, #reference to Action Chain if we are being called from process_action(); undef otherwise
$rule, #Matches $rule, #Matches
$actiontype,
$target, $target,
$current_param, $current_param,
$source, $source,
@ -2064,6 +2060,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
my ( $action, $loglevel) = split_action $target; my ( $action, $loglevel) = split_action $target;
my ( $basictarget, $param ) = get_target_param $action; my ( $basictarget, $param ) = get_target_param $action;
my $optimize = $wildcard ? ( $basictarget =~ /!$/ ? 0 : $config{OPTIMIZE} & 5 ) : 0; my $optimize = $wildcard ? ( $basictarget =~ /!$/ ? 0 : $config{OPTIMIZE} & 5 ) : 0;
my $actiontype;
my $inaction = ''; # Set to true when we are process rules in an action file my $inaction = ''; # Set to true when we are process rules in an action file
my $inchain = ''; # Set to true when a chain reference is passed. my $inchain = ''; # Set to true when a chain reference is passed.
my $normalized_target; my $normalized_target;
@ -2080,7 +2077,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
# #
# Determine the validity of the action # Determine the validity of the action
# #
$actiontype = ( $targets{$basictarget} || find_macro ( $basictarget ) ) unless $actiontype; $actiontype = ( $targets{$basictarget} || find_macro ( $basictarget ) );
if ( $config{ MAPOLDACTIONS } ) { if ( $config{ MAPOLDACTIONS } ) {
( $basictarget, $actiontype , $param ) = map_old_actions( $basictarget ) unless $actiontype || supplied $param; ( $basictarget, $actiontype , $param ) = map_old_actions( $basictarget ) unless $actiontype || supplied $param;
@ -2755,26 +2752,33 @@ sub merge_target( $$ ) {
# May be called by Perl code in action bodies (regular and inline) to generate a rule. # May be called by Perl code in action bodies (regular and inline) to generate a rule.
# #
sub perl_action_helper($$;$) { sub perl_action_helper($$;$) {
my ( $target, $matches, $actiontype ) = @_; my ( $target, $matches, $isstatematch ) = @_;
my $action = $actparms{action}; my $action = $actparms{action};
my $chainref = $actparms{0}; my $chainref = $actparms{0};
my $result; my $result;
our $statematch;
assert( $chainref ); assert( $chainref );
$matches .= ' ' unless $matches =~ /^(?:.+\s)?$/; $matches .= ' ' unless $matches =~ /^(?:.+\s)?$/;
if ( $isstatematch ) {
return if $statematch;
$statematch = 1;
}
if ( my $ref = $inlines{$action} ) { if ( my $ref = $inlines{$action} ) {
$result = &process_rule( $chainref, $result = &process_rule( $chainref,
$matches, $matches,
$actiontype || 0,
merge_target( $ref, $target ), merge_target( $ref, $target ),
'', # CurrentParam '', # CurrentParam
@columns ); @columns );
} else { } else {
assert $actions{$action};
$result = process_rule( $chainref, $result = process_rule( $chainref,
$matches, $matches,
$actiontype || 0,
merge_target( $actions{$action}, $target ), merge_target( $actions{$action}, $target ),
'', # Current Param '', # Current Param
'-', # Source '-', # Source
@ -2799,6 +2803,8 @@ sub perl_action_helper($$;$) {
# Record that we generated a rule to avoid bogus warning # Record that we generated a rule to avoid bogus warning
# #
$actionresult ||= $result; $actionresult ||= $result;
$statematch = 0 if $isstatematch;
} }
# #
@ -2822,7 +2828,6 @@ sub perl_action_tcp_helper($$) {
if ( my $ref = $inlines{$action} ) { if ( my $ref = $inlines{$action} ) {
$result = &process_rule( $chainref, $result = &process_rule( $chainref,
$proto, $proto,
0,
merge_target( $ref, $target ), merge_target( $ref, $target ),
'', '',
@columns[0,1], @columns[0,1],
@ -2832,7 +2837,6 @@ sub perl_action_tcp_helper($$) {
} else { } else {
$result = process_rule( $chainref, $result = process_rule( $chainref,
$proto, $proto,
0,
merge_target( $actions{$action}, $target ), merge_target( $actions{$action}, $target ),
'', # Current Param '', # Current Param
'-', # Source '-', # Source
@ -2991,6 +2995,8 @@ sub process_raw_rule ( ) {
my @users = split_list1 $users, 'USER/GROUP'; my @users = split_list1 $users, 'USER/GROUP';
my $generated = 0; my $generated = 0;
our $statematch = 0;
fatal_error "Invalid or missing ACTION ($target)" unless defined $action; fatal_error "Invalid or missing ACTION ($target)" unless defined $action;
if ( @protos > 1 ) { if ( @protos > 1 ) {
@ -3007,7 +3013,6 @@ sub process_raw_rule ( ) {
for my $user ( @users ) { for my $user ( @users ) {
if ( process_rule( undef, if ( process_rule( undef,
'', '',
0,
$target, $target,
'', '',
$source, $source,

View File

@ -41,7 +41,7 @@ use Shorewall::Rules;
my ( $action ) = get_action_params( 1 ); my ( $action ) = get_action_params( 1 );
if ( my $check = check_state( 'ESTABLISHED' ) ) { if ( my $check = check_state( 'ESTABLISHED' ) ) {
perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} ESTABLISHED" : '' ); perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} ESTABLISHED" : '', 1 );
} }
1; 1;

View File

@ -46,7 +46,7 @@ if ( supplied $audit ) {
} }
if ( my $check = check_state( 'INVALID' ) ) { if ( my $check = check_state( 'INVALID' ) ) {
perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} INVALID" : '' ); perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} INVALID" : '' , 1 );
} }
1; 1;

View File

@ -42,7 +42,7 @@ use Shorewall::Rules;
my ( $action ) = get_action_params( 1 ); my ( $action ) = get_action_params( 1 );
if ( my $check = check_state( 'RELATED' ) ) { if ( my $check = check_state( 'RELATED' ) ) {
perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} RELATED" : '' ); perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} RELATED" : '', 1 );
} }
1; 1;

View File

@ -41,7 +41,7 @@ use Shorewall::Rules;
my ( $action ) = get_action_params( 1 ); my ( $action ) = get_action_params( 1 );
if ( my $check = check_state( 'UNTRACKED' ) ) { if ( my $check = check_state( 'UNTRACKED' ) ) {
perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} UNTRACKED" : '' ); perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} UNTRACKED" : '' , 1 );
} }
1; 1;

View File

@ -40,4 +40,4 @@ Reject # Default Action for REJECT policy
Related inline # Handles packets in the RELATED conntrack state Related inline # Handles packets in the RELATED conntrack state
RST inline # Handle packets with RST set RST inline # Handle packets with RST set
TCPFlags # Handle bad flag combinations. TCPFlags # Handle bad flag combinations.
Untracked inline # Handles packets in the UNTRACKED conntrack state Untracked inline # Handles packets in the UNTRACKED conntrack state