Add logic for parameterized actions

This commit is contained in:
Tom Eastep 2010-12-18 16:16:29 -08:00
parent 4573b5ba8e
commit 4b22bbd90d
3 changed files with 59 additions and 38 deletions

View File

@ -170,15 +170,13 @@ sub normalize_action_name( $$$ ) {
# this function truncates the original chain name where necessary before
# it adds the leading "%" and trailing sequence number.
#
sub createlogactionchain( $$ ) {
my ( $action, $level ) = @_;
sub createlogactionchain( $$$$$ ) {
my ( $normalized, $action, $level, $tag, $param ) = @_;
my $chain = $action;
my $actionref = $actions{$action};
my $chainref;
my ($lev, $tag) = split ':', $level;
validate_level $lev;
validate_level $level;
$actionref = new_action $action unless $actionref;
@ -190,7 +188,7 @@ sub createlogactionchain( $$ ) {
$chain = substr( $chain, 0, 27 ), redo CHECKDUP if ( $actionref->{actchain} || 0 ) >= 10 and length $chain == 28;
}
$logactionchains{"$action:$level"} = $chainref = new_standard_chain '%' . $chain . $actionref->{actchain}++;
$logactionchains{$normalized} = $chainref = new_standard_chain '%' . $chain . $actionref->{actchain}++;
fatal_error "Too many invocations of Action $action" if $actionref->{actchain} > 99;
@ -203,9 +201,7 @@ sub createlogactionchain( $$ ) {
if ( -f $file ) {
progress_message "Processing $file...";
( $level, my $tag ) = split /:/, $level;
$tag = $tag || '';
my @params = split /,/, $param;
unless ( my $return = eval `cat $file` ) {
fatal_error "Couldn't parse $file: $@" if $@;
@ -222,7 +218,7 @@ sub createsimpleactionchain( $ ) {
my $action = shift;
my $chainref = new_standard_chain $action;
$logactionchains{"$action:none"} = $chainref;
$logactionchains{"$action:none::"} = $chainref;
unless ( $targets{$action} & BUILTIN ) {
@ -250,18 +246,18 @@ sub createsimpleactionchain( $ ) {
# Create an action chain and run its associated user exit
#
sub createactionchain( $ ) {
my ( $action , $level ) = split_action $_[0];
my $normalized = shift;
my ( $target, $level, $tag, $param ) = split /:/, $normalized;
assert( defined $param );
my $chainref;
if ( defined $level && $level ne '' ) {
if ( $level eq 'none' ) {
createsimpleactionchain $action;
} else {
createlogactionchain $action , $level;
}
if ( $level eq 'none' && $tag eq '' && $param eq '' ) {
createsimpleactionchain $target;
} else {
createsimpleactionchain $action;
createlogactionchain $normalized, $target , $level , $tag, $param;
}
}

View File

@ -169,17 +169,18 @@ sub process_a_policy() {
fatal_error "Invalid default action ($default:$remainder)" if defined $remainder;
( $policy , my $queue ) = get_target_param $policy;
if ( $default ) {
if ( "\L$default" eq 'none' ) {
$default = 'none';
} else {
my $defaulttype = $targets{$default} || 0;
if ( $defaulttype & ACTION ) {
unless ( $usedactions{$default} ) {
$usedactions{$default} = 1;
createactionchain $default;
my $normalized = "$default:none::";
unless ( $usedactions{$normalized} ) {
$usedactions{$normalized} = 1;
createactionchain $normalized;
}
} else {
fatal_error "Unknown Default Action ($default)";
@ -310,20 +311,22 @@ sub validate_policy()
my $firewall = firewall_zone;
our @zonelist = $config{EXPAND_POLICIES} ? all_zones : ( all_zones, 'all' );
for my $option qw/DROP_DEFAULT REJECT_DEFAULT ACCEPT_DEFAULT QUEUE_DEFAULT NFQUEUE_DEFAULT/ {
for my $option qw( DROP_DEFAULT REJECT_DEFAULT ACCEPT_DEFAULT QUEUE_DEFAULT NFQUEUE_DEFAULT) {
my $action = $config{$option};
next if $action eq 'none';
my $actiontype = $targets{$action};
if ( defined $actiontype ) {
fatal_error "Invalid setting ($action) for $option" unless $actiontype & ACTION;
} else {
fatal_error "Default Action $option=$action not found";
}
unless ( $usedactions{$action} ) {
$usedactions{$action} = 1;
createactionchain $action;
my $normalized = "$action:none::";
unless ( $usedactions{$normalized} ) {
$usedactions{$normalized} = 1;
createactionchain $normalized;
}
$default_actions{$map{$option}} = $action;

View File

@ -247,11 +247,8 @@ sub map_old_actions( $ ) {
#
sub find_logactionchain( $ ) {
my $fullaction = $_[0];
my ( $action, $level ) = split_action $fullaction;
$level = 'none' unless $level;
fatal_error "Fatal error in find_logactionchain" unless $logactionchains{"$action:$level"};
fatal_error "Fatal error in find_logactionchain" unless $logactionchains{$fullaction};
}
#
@ -352,6 +349,31 @@ sub process_actions1() {
}
}
sub merge_action_levels( $$ ) {
my $superior = shift;
my $subordinate = shift;
my ( $unused, $suplevel, $suptag, $supparam ) = split /:/, $superior;
my ( $action, $sublevel, $subtag, $subparam ) = split /:/, $subordinate;
assert defined $supparam;
if ( $suplevel =~ /!$/ ) {
( $sublevel, $subtag ) = ( $suplevel, $subtag );
} else {
$sublevel = 'none' unless defined $sublevel && $sublevel ne '';
if ( $sublevel =~ /^none~/ ) {
$subtag = '';
} else {
$subtag = '' unless defined $subtag;
}
}
$subparam = $supparam unless defined $subparam && $subparam ne '';
join ':', $action, $sublevel, $subtag, $subparam;
}
sub process_actions2 () {
progress_message2 'Generating Transitive Closure of Used-action List...';
@ -360,11 +382,11 @@ sub process_actions2 () {
while ( $changed ) {
$changed = 0;
for my $target (keys %usedactions) {
my ( $action, $level, $tag, $param ) = split_action $target;
my ( $action, $level, $tag, $param ) = split ':', $target;
my $actionref = $actions{$action};
assert( $actionref );
for my $action1 ( keys %{$actionref->{requires}} ) {
my $action2 = merge_levels $target, $action1;
my $action2 = merge_action_levels $target, $action1;
unless ( $usedactions{ $action2 } ) {
$usedactions{ $action2 } = 1;
createactionchain $action2;
@ -813,9 +835,9 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) {
if ( $inaction1 ) {
add_requiredby( $target , $inaction1 );
} else {
unless ( $usedactions{$target} ) {
$usedactions{$target} = 1;
my $ref = createactionchain $target;
unless ( $usedactions{$normalized_target} ) {
$usedactions{$normalized_target} = 1;
my $ref = createactionchain $normalized_target;
new_nat_chain $ref->{name} if $actiontype & ( NATRULE | NONAT );
}
}
@ -1253,7 +1275,7 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) {
unless ( $actiontype & NATONLY ) {
if ( $actiontype & ACTION ) {
$action = (find_logactionchain $target)->{name};
$action = (find_logactionchain $normalized_target)->{name};
$loglevel = '';
}