Allow NAT targets to be passed to the Event actions

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2017-09-08 09:46:03 -07:00
parent 3b373f3f21
commit 1065c2951b
No known key found for this signature in database
GPG Key ID: 96E6B3F2423A4D10

View File

@ -216,6 +216,10 @@ our %statetable;
# Tracks which of the state match actions (action.Invalid, etc.) that is currently being expanded # Tracks which of the state match actions (action.Invalid, etc.) that is currently being expanded
# #
our $statematch; our $statematch;
#
# Remembers NAT-oriented columns from top-level action invocations
#
our %nat_columns;
# #
# Action/Inline options # Action/Inline options
@ -384,6 +388,8 @@ sub initialize( $ ) {
); );
} }
%nat_columns = ( dest => '-', proto => '-', ports => '-' );
############################################################################ ############################################################################
# Initialize variables moved from the Tc module in Shorewall 5.0.7 # # Initialize variables moved from the Tc module in Shorewall 5.0.7 #
############################################################################ ############################################################################
@ -391,7 +397,7 @@ sub initialize( $ ) {
%tcdevices = (); %tcdevices = ();
%tcclasses = (); %tcclasses = ();
$sticky = 0; $sticky = 0;
$divertref = 0; $divertref = 0;
} }
# #
@ -1652,6 +1658,19 @@ sub merge_inline_source_dest( $$ ) {
$body || ''; $body || '';
} }
#
# This one is used by perl_action_helper()
#
sub merge_action_column( $$ ) {
my ( $body, $invocation ) = @_;
if ( supplied( $body ) && $body ne '-' ) {
$body;
} else {
$invocation;
}
}
sub merge_macro_column( $$ ) { sub merge_macro_column( $$ ) {
my ( $body, $invocation ) = @_; my ( $body, $invocation ) = @_;
@ -2510,6 +2529,8 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
my $exceptionrule = ''; my $exceptionrule = '';
my $usergenerated; my $usergenerated;
my $prerule = ''; my $prerule = '';
my %save_nat_columns = %nat_columns;
my $generated = 0;
# #
# Subroutine for handling MARK and CONNMARK. # Subroutine for handling MARK and CONNMARK.
# #
@ -2591,32 +2612,30 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
$current_param = $param unless $param eq '' || $param eq 'PARAM'; $current_param = $param unless $param eq '' || $param eq 'PARAM';
my $generated = process_macro( $basictarget, $generated = process_macro( $basictarget,
$chainref, $chainref,
$rule . $raw_matches, $rule . $raw_matches,
$matches1, $matches1,
$target, $target,
$current_param, $current_param,
$source, $source,
$dest, $dest,
$proto, $proto,
$ports, $ports,
$sports, $sports,
$origdest, $origdest,
$ratelimit, $ratelimit,
$user, $user,
$mark, $mark,
$connlimit, $connlimit,
$time, $time,
$headers, $headers,
$condition, $condition,
$helper, $helper,
$wildcard ); $wildcard );
$macro_nest_level--; $macro_nest_level--;
goto EXIT;
return $generated;
} elsif ( $actiontype & NFQ ) { } elsif ( $actiontype & NFQ ) {
$action = handle_nfqueue( $param, $action = handle_nfqueue( $param,
1 # Allow 'bypass' 1 # Allow 'bypass'
@ -2688,6 +2707,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
REDIRECT => sub () { REDIRECT => sub () {
my $z = $actiontype & NATONLY ? '' : firewall_zone; my $z = $actiontype & NATONLY ? '' : firewall_zone;
if ( $dest eq '-' ) { if ( $dest eq '-' ) {
if ( $family == F_IPV4 ) { if ( $family == F_IPV4 ) {
$dest = ( $inchain ) ? '' : join( '', $z, '::' , $ports =~ /[:,]/ ? '' : $ports ); $dest = ( $inchain ) ? '' : join( '', $z, '::' , $ports =~ /[:,]/ ? '' : $ports );
@ -2816,6 +2836,24 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
} }
} }
} }
if ( $actiontype & ACTION ) {
my $dst = $dest;
if ( $dst eq '-' ) {
$dst = $nat_columns{dest};
} elsif ( $inchain ) {
#
# Remove zone from destination
#
$dst =~ s/.*://;
}
@nat_columns{'dest', 'proto', 'ports' } = ( $dst,
$proto eq '-' ? $nat_columns{proto} : $proto,
$ports eq '-' ? $nat_columns{ports} : $ports );
}
# #
# Isolate and validate source and destination zones # Isolate and validate source and destination zones
# #
@ -2909,7 +2947,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
# #
if ( $destref->{type} & BPORT ) { if ( $destref->{type} & BPORT ) {
unless ( $sourceref->{bridge} eq $destref->{bridge} || single_interface( $sourcezone ) eq $destref->{bridge} ) { unless ( $sourceref->{bridge} eq $destref->{bridge} || single_interface( $sourcezone ) eq $destref->{bridge} ) {
return 0 if $wildcard; goto EXIT if $wildcard;
fatal_error "Rules with a DESTINATION Bridge Port zone must have a SOURCE zone on the same bridge"; fatal_error "Rules with a DESTINATION Bridge Port zone must have a SOURCE zone on the same bridge";
} }
} }
@ -2924,7 +2962,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
my $policy = $chainref->{policy}; my $policy = $chainref->{policy};
if ( $policy eq 'NONE' ) { if ( $policy eq 'NONE' ) {
return 0 if $wildcard; goto EXIT if $wildcard;
fatal_error "Rules may not override a NONE policy"; fatal_error "Rules may not override a NONE policy";
} }
# #
@ -2933,9 +2971,9 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
if ( $optimize == 1 && $section == NEW_SECTION ) { if ( $optimize == 1 && $section == NEW_SECTION ) {
my $loglevel = $filter_table->{$chainref->{policychain}}{loglevel}; my $loglevel = $filter_table->{$chainref->{policychain}}{loglevel};
if ( $loglevel ne '' ) { if ( $loglevel ne '' ) {
return 0 if $target eq "${policy}:${loglevel}"; goto EXIT if $target eq "${policy}:${loglevel}";
} else { } else {
return 0 if $basictarget eq $policy; goto EXIT if $basictarget eq $policy;
} }
} }
# #
@ -2980,6 +3018,15 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
my $actionchain; # Name of the action chain my $actionchain; # Name of the action chain
if ( $actiontype & ACTION ) { if ( $actiontype & ACTION ) {
#
# Push the current column array onto the column stack
#
my @savecolumns = @columns;
#
# And store the (modified) columns into the columns array for use by perl_action[_tcp]_helper. We
# only need the NAT-oriented columns
#
@columns = ( undef , undef, $dest, $proto, $ports);
# #
# Handle 'section' option # Handle 'section' option
# #
@ -3023,6 +3070,8 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
} }
$action = $basictarget; # Remove params, if any, from $action. $action = $basictarget; # Remove params, if any, from $action.
@columns = @savecolumns;
} elsif ( $actiontype & INLINE ) { } elsif ( $actiontype & INLINE ) {
# #
# process_inline() will call process_rule() recursively for each rule in the action body # process_inline() will call process_rule() recursively for each rule in the action body
@ -3039,34 +3088,34 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
$actionresult = 0; $actionresult = 0;
my $generated = process_inline( $basictarget, $generated = process_inline( $basictarget,
$chainref, $chainref,
$prerule . $rule, $prerule . $rule,
$matches1 . $raw_matches, $matches1 . $raw_matches,
$loglevel, $loglevel,
$target, $target,
$param, $param,
$source, $source,
$dest, $dest,
$proto, $proto,
$ports, $ports,
$sports, $sports,
$origdest, $origdest,
$ratelimit, $ratelimit,
$user, $user,
$mark, $mark,
$connlimit, $connlimit,
$time, $time,
$headers, $headers,
$condition, $condition,
$helper, $helper,
$wildcard ) || $actionresult; $wildcard ) || $actionresult;
( $actionresult, @columns ) = @$savecolumns;; ( $actionresult, @columns ) = @$savecolumns;;
$macro_nest_level--; $macro_nest_level--;
return $generated; goto EXIT;
} }
# #
# Generate Fixed part of the rule # Generate Fixed part of the rule
@ -3252,7 +3301,14 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) {
unless unreachable_warning( $wildcard || $section == DEFAULTACTION_SECTION, $chainref ); unless unreachable_warning( $wildcard || $section == DEFAULTACTION_SECTION, $chainref );
} }
return 1; $generated = 1;
EXIT:
{
%nat_columns = %save_nat_columns;
}
return $generated;
} }
@ -3406,27 +3462,60 @@ sub perl_action_helper($$;$$) {
'', # CurrentParam '', # CurrentParam
@columns ); @columns );
} else { } else {
$result = process_rule( $chainref, if ( ( $targets{$target} || 0 ) & NATRULE ) {
$matches, $result = process_rule( $chainref,
$matches1, $matches,
merge_target( $actions{$action}, $target ), $matches1,
'', # Current Param merge_target( $actions{$action}, $target ),
'-', # Source '', # Current Param
'-', # Dest '-', # Source
'-', # Proto merge_action_column( # Dest
'-', # Port(s) $columns[2],
'-', # Source Port(s) $nat_columns{dest}
'-', # Original Dest ),
'-', # Rate Limit merge_action_column( #Proto
'-', # User $columns[3],
'-', # Mark $nat_columns{proto}
'-', # Connlimit ),
'-', # Time merge_action_column( #Ports
'-', # Headers, $columns[4],
'-', # condition, $nat_columns{ports}),
'-', # helper, '-', # Source Port(s)
0, # Wildcard '-', # Original Dest
); '-', # Rate Limit
'-', # User
'-', # Mark
'-', # Connlimit
'-', # Time
'-', # Headers,
'-', # condition,
'-', # helper,
0, # Wildcard
);
} else {
$result = process_rule( $chainref,
$matches,
$matches1,
merge_target( $actions{$action}, $target ),
'', # Current Param
'-', # Source
'-', # Dest
'-', # Proto
'-', # Port(s)
'-', # Source Port(s)
'-', # Original Dest
'-', # Rate Limit
'-', # User
'-', # Mark
'-', # Connlimit
'-', # Time
'-', # Headers,
'-', # condition,
'-', # helper,
0, # Wildcard
);
}
allow_optimize( $chainref ); allow_optimize( $chainref );
} }
# #
@ -3492,7 +3581,8 @@ sub perl_action_tcp_helper($$) {
'-', # condition, '-', # condition,
'-', # helper, '-', # helper,
0, # Wildcard 0, # Wildcard
); );
allow_optimize( $chainref ); allow_optimize( $chainref );
} }
# #