forked from extern/shorewall_code
Improve @CALLER fix to create unique chains per caller
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
9aa915a5e0
commit
742c15b289
@ -185,6 +185,9 @@ our %EXPORT_TAGS = ( internal => [ qw( create_temp_script
|
||||
%helpers_aliases
|
||||
|
||||
%actparms
|
||||
|
||||
PARMSMODIFIED
|
||||
USEDCALLER
|
||||
|
||||
F_IPV4
|
||||
F_IPV6
|
||||
@ -546,6 +549,7 @@ our %compiler_params;
|
||||
#
|
||||
our %actparms;
|
||||
our $parmsmodified;
|
||||
our $usedcaller;
|
||||
our $inline_matches;
|
||||
|
||||
our $currentline; # Current config file line image
|
||||
@ -596,6 +600,9 @@ use constant { MIN_VERBOSITY => -1,
|
||||
F_IPV6 => 6,
|
||||
};
|
||||
|
||||
use constant { PARMSMODIFIED => 1,
|
||||
USEDCALLER => 2 };
|
||||
|
||||
our %validlevels; # Valid log levels.
|
||||
|
||||
#
|
||||
@ -1045,6 +1052,7 @@ sub initialize( $;$$) {
|
||||
|
||||
%actparms = ( 0 => 0, loglevel => '', logtag => '', chain => '', disposition => '', caller => '' );
|
||||
$parmsmodified = 0;
|
||||
$usedcaller = 0;
|
||||
|
||||
%helpers_enabled = (
|
||||
amanda => 1,
|
||||
@ -2502,7 +2510,7 @@ sub evaluate_expression( $$$ ) {
|
||||
my ( $first, $var, $rest ) = ( $1, $3, $4);
|
||||
$var = numeric_value( $var ) if $var =~ /^\d/;
|
||||
$val = $var ? $actparms{$var} : $chain;
|
||||
$parmsmodified ||= $var eq 'caller';
|
||||
$usedcaller = USEDCALLER if $var eq 'caller';
|
||||
$expression = join_parts( $first, $val, $rest );
|
||||
directive_error( "Variable Expansion Loop" , $filename, $linenumber ) if ++$count > 100;
|
||||
}
|
||||
@ -2639,7 +2647,7 @@ sub process_compiler_directive( $$$$ ) {
|
||||
my $val = $actparms{$var} = evaluate_expression ( $expression,
|
||||
$filename,
|
||||
$linenumber );
|
||||
$parmsmodified = 1;
|
||||
$parmsmodified = PARMSMODIFIED;
|
||||
} else {
|
||||
$variables{$2} = evaluate_expression( $expression,
|
||||
$filename,
|
||||
@ -3174,11 +3182,13 @@ sub push_action_params( $$$$$$ ) {
|
||||
my ( $action, $chainref, $parms, $loglevel, $logtag, $caller ) = @_;
|
||||
my @parms = ( undef , split_list3( $parms , 'parameter' ) );
|
||||
|
||||
$actparms{modified} = $parmsmodified;
|
||||
$actparms{modified} = $parmsmodified;
|
||||
$actparms{usedcaller} = $usedcaller;
|
||||
|
||||
my %oldparms = %actparms;
|
||||
|
||||
$parmsmodified = 0;
|
||||
$usedcaller = 0;
|
||||
|
||||
%actparms = ();
|
||||
|
||||
@ -3204,13 +3214,16 @@ sub push_action_params( $$$$$$ ) {
|
||||
|
||||
#
|
||||
# Pop the action parameters using the passed hash reference
|
||||
# Return true of the popped parameters were modified
|
||||
# Return:
|
||||
# 1 if the popped parameters were modified
|
||||
# 2 if the action used @CALLER
|
||||
#
|
||||
sub pop_action_params( $ ) {
|
||||
my $oldparms = shift;
|
||||
%actparms = %$oldparms;
|
||||
my $return = $parmsmodified;
|
||||
my $return = $parmsmodified ? $parmsmodified : ( $usedcaller || 0 );
|
||||
( $parmsmodified ) = delete $actparms{modified};
|
||||
( $usedcaller ) = delete $actparms{usedcaller};
|
||||
$return;
|
||||
}
|
||||
|
||||
@ -3305,7 +3318,7 @@ sub expand_variables( \$ ) {
|
||||
$val = $variables{$var};
|
||||
} elsif ( exists $actparms{$var} ) {
|
||||
$val = $actparms{$var};
|
||||
$parmsmodified = 1 if $var eq 'caller';
|
||||
$usedcaller = USEDCALLER if $var eq 'caller';
|
||||
} else {
|
||||
fatal_error "Undefined shell variable (\$$var)" unless $config{IGNOREUNKNOWNVARIABLES} || exists $config{$var};
|
||||
}
|
||||
@ -3324,7 +3337,7 @@ sub expand_variables( \$ ) {
|
||||
while ( $$lineref =~ m( ^(.*?) \@({)? (\d+|[a-zA-Z_]\w*) (?(2)}) (.*)$ )x ) {
|
||||
my ( $first, $var, $rest ) = ( $1, $3, $4);
|
||||
my $val = $var ? $actparms{$var} : $actparms{chain};
|
||||
$parmsmodified = 1 if $var eq 'caller';
|
||||
$usedcaller = USEDCALLER if $var eq 'caller';
|
||||
$val = '' unless defined $val;
|
||||
$$lineref = join( '', $first , $val , $rest );
|
||||
fatal_error "Variable Expansion Loop" if ++$count > 100;
|
||||
|
@ -560,7 +560,7 @@ sub process_a_policy() {
|
||||
|
||||
require_capability 'AUDIT_TARGET', ":audit", "s" if $audit;
|
||||
|
||||
my ( $policy, $default, $level, $remainder ) = split( /:/, $originalpolicy, 4 );
|
||||
my ( $policy, $default, $level, undef, $remainder ) = split( /:/, $originalpolicy, 5 );
|
||||
|
||||
fatal_error "Invalid or missing POLICY ($originalpolicy)" unless $policy;
|
||||
|
||||
@ -944,7 +944,7 @@ sub complete_standard_chain ( $$$$ ) {
|
||||
( $policy, $loglevel, $defaultaction ) = @{$policychainref}{'policy', 'loglevel', 'default' };
|
||||
$stdchainref->{origin} = $policychainref->{origin};
|
||||
} elsif ( $defaultaction !~ /:/ ) {
|
||||
$defaultaction = join(":", $defaultaction, 'none', '', '' );
|
||||
$defaultaction = join(":", $defaultaction, 'none', '', '', '' );
|
||||
}
|
||||
|
||||
|
||||
@ -1169,14 +1169,15 @@ sub finish_section ( $ ) {
|
||||
#
|
||||
# Create a normalized action name from the passed pieces.
|
||||
#
|
||||
# Internally, action invocations are uniquely identified by a 4-tuple that
|
||||
# includes the action name, log level, log tag and params. The pieces of the tuple
|
||||
# are separated by ":".
|
||||
# Internally, action invocations are uniquely identified by a 5-tuple that
|
||||
# includes the action name, log level, log tag, calling chain and params.
|
||||
# The pieces of the tuple are separated by ":".
|
||||
#
|
||||
sub normalize_action( $$$ ) {
|
||||
my $action = shift;
|
||||
my $level = shift;
|
||||
my $param = shift;
|
||||
my $caller = ''; #We assume that the function doesn't use @CALLER
|
||||
|
||||
( $level, my $tag ) = split ':', $level;
|
||||
|
||||
@ -1185,13 +1186,23 @@ sub normalize_action( $$$ ) {
|
||||
$param = '' unless defined $param;
|
||||
$param = '' if $param eq '-';
|
||||
|
||||
join( ':', $action, $level, $tag, $param );
|
||||
join( ':', $action, $level, $tag, $caller, $param );
|
||||
}
|
||||
|
||||
#
|
||||
# Add the actual caller into an existing normalised name
|
||||
#
|
||||
sub insert_caller($$) {
|
||||
my ( $normalized, $caller ) = @_;
|
||||
|
||||
my ( $action, $level, $tag, undef, $param ) = split /:/, $normalized;
|
||||
|
||||
join( ':', $action, $level, $tag, $caller, $param );
|
||||
}
|
||||
|
||||
#
|
||||
# Accepts a rule target and returns a normalized tuple
|
||||
#
|
||||
|
||||
sub normalize_action_name( $ ) {
|
||||
my $target = shift;
|
||||
my ( $action, $loglevel) = split_action $target;
|
||||
@ -1203,7 +1214,7 @@ sub normalize_action_name( $ ) {
|
||||
# Produce a recognizable target from a normalized action
|
||||
#
|
||||
sub external_name( $ ) {
|
||||
my ( $target, $level, $tag, $params ) = split /:/, shift, 4;
|
||||
my ( $target, $level, $tag, undef, $params ) = split /:/, shift, 5;
|
||||
|
||||
$target = join( '', $target, '(', $params , ')' ) if $params;
|
||||
$target .= ":$level" if $level && $level ne 'none';
|
||||
@ -1333,7 +1344,7 @@ sub createsimpleactionchain( $ ) {
|
||||
sub createactionchain( $ ) {
|
||||
my $normalized = shift;
|
||||
|
||||
my ( $target, $level, $tag, $param ) = split /:/, $normalized, 4;
|
||||
my ( $target, $level, $tag, $caller, $param ) = split /:/, $normalized, 5;
|
||||
|
||||
assert( defined $param );
|
||||
|
||||
@ -1693,7 +1704,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ );
|
||||
sub process_action($$) {
|
||||
my ( $chainref, $caller ) = @_;
|
||||
my $wholeaction = $chainref->{action};
|
||||
my ( $action, $level, $tag, $param ) = split /:/, $wholeaction, 4;
|
||||
my ( $action, $level, $tag, undef, $param ) = split /:/, $wholeaction, 5;
|
||||
|
||||
if ( $targets{$action} & BUILTIN ) {
|
||||
$level = '' if $level =~ /none!?/;
|
||||
@ -1909,7 +1920,7 @@ sub process_actions() {
|
||||
sub use_policy_action( $$ ) {
|
||||
my $ref = use_action( $_[0] );
|
||||
if ( $ref ) {
|
||||
delete $usedactions{$ref->{action}} if process_action( $ref, $_[1] );
|
||||
delete $usedactions{$ref->{action}} if process_action( $ref, $_[1] ) & PARMSMODIFIED;
|
||||
} else {
|
||||
$ref = $usedactions{$_[0]};
|
||||
}
|
||||
@ -2661,7 +2672,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
|
||||
#
|
||||
# Handle actions
|
||||
#
|
||||
my $delete_action;
|
||||
my $delete_action = 0;
|
||||
|
||||
if ( $actiontype & ACTION ) {
|
||||
#
|
||||
@ -2678,7 +2689,41 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
|
||||
my $savestatematch = $statematch;
|
||||
$statematch = '';
|
||||
|
||||
$delete_action = process_action( $ref, $chain );
|
||||
if ( ( $delete_action = process_action( $ref, $chain ) ) & USEDCALLER ) {
|
||||
#
|
||||
# The chain uses @CALLER but doesn't modify the action parameters.
|
||||
# We need to see if this chain has already called this action
|
||||
#
|
||||
my $renormalized_target = insert_caller( $normalized_target, $chain );
|
||||
my $ref1 = $usedactions{$renormalized_target};
|
||||
|
||||
if ( $ref1 ) {
|
||||
#
|
||||
# It has -- use the prior chain
|
||||
#
|
||||
$ref = $ref1;
|
||||
#
|
||||
# We leave the new chain in place but delete it from %usedactions below
|
||||
#
|
||||
} else {
|
||||
#
|
||||
# This is the first time that the current chain has invoked this action
|
||||
#
|
||||
$usedactions{$renormalized_target} = $ref;
|
||||
#
|
||||
# Swap the action member
|
||||
#
|
||||
$ref->{action} = $renormalized_target;
|
||||
}
|
||||
#
|
||||
# Delete the usedactions entry with the original normalized key
|
||||
#
|
||||
delete $usedactions{$normalized_target};
|
||||
#
|
||||
# New normalized target
|
||||
#
|
||||
$normalized_target = $renormalized_target;
|
||||
}
|
||||
#
|
||||
# Processing the action may determine that the action or one of it's dependents does NAT or HELPER, so:
|
||||
#
|
||||
@ -2918,7 +2963,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
|
||||
unless unreachable_warning( $wildcard || $section == DEFAULTACTION_SECTION, $chainref );
|
||||
}
|
||||
|
||||
delete $usedactions{$normalized_target} if $delete_action;
|
||||
delete $usedactions{$normalized_target} if $delete_action & PARMSMODIFIED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user