diff --git a/Shorewall/Perl/Shorewall/Actions.pm b/Shorewall/Perl/Shorewall/Actions.pm index e24f5c34c..d254a1114 100644 --- a/Shorewall/Perl/Shorewall/Actions.pm +++ b/Shorewall/Perl/Shorewall/Actions.pm @@ -40,7 +40,7 @@ our @EXPORT = qw( process_actions1 process_actions2 process_actions3 - process_rule_common + process_rule $rule_commands %usedactions @@ -1495,4 +1495,155 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) { return 1; } +# +# Helper functions for process_rule(). That function deals with the ugliness of wildcard zones ('all' and 'any') and zone lists. +# +# Process a SECTION header +# +sub process_section ($) { + my $sect = shift; + # + # read_a_line has already verified that there are exactly two tokens on the line + # + fatal_error "Invalid SECTION ($sect)" unless defined $sections{$sect}; + fatal_error "Duplicate or out of order SECTION $sect" if $sections{$sect}; + $sections{$sect} = 1; + + if ( $sect eq 'RELATED' ) { + $sections{ESTABLISHED} = 1; + finish_section 'ESTABLISHED'; + } elsif ( $sect eq 'NEW' ) { + @sections{'ESTABLISHED','RELATED'} = ( 1, 1 ); + finish_section ( ( $section eq 'RELATED' ) ? 'RELATED' : 'ESTABLISHED,RELATED' ); + } + + $section = $sect; +} + +# +# Build a source or destination zone list +# +sub build_zone_list( $$$\$\$ ) { + my ($fw, $input, $which, $intrazoneref, $wildref ) = @_; + my $any = ( $input =~ s/^any/all/ ); + my $exclude; + my $rest; + my %exclude; + my @result; + # + # Handle Wildcards + # + if ( $input =~ /^(all[-+]*)(![^:]+)?(:.*)?/ ) { + $input = $1; + $exclude = $2; + $rest = $3; + + $$wildref = 1; + + if ( defined $exclude ) { + $exclude =~ s/!//; + fatal_error "Invalid exclusion list (!$exclude)" if $exclude =~ /^,|!|,,|,$/; + for ( split /,/, $exclude ) { + fatal_error "Unknown zone ($_)" unless defined_zone $_; + $exclude{$_} = 1; + } + } + + unless ( $input eq 'all' ) { + if ( $input eq 'all+' ) { + $$intrazoneref = 1; + } elsif ( ( $input eq 'all+-' ) || ( $input eq 'all-+' ) ) { + $$intrazoneref = 1; + $exclude{$fw} = 1; + } elsif ( $input eq 'all-' ) { + $exclude{$fw} = 1; + } else { + fatal_error "Invalid $which ($input)"; + } + } + + @result = grep ! $exclude{$_}, $any ? all_parent_zones : non_firewall_zones; + + unshift @result, $fw unless $exclude{$fw}; + + } elsif ( $input =~ /^([^:]+,[^:]+)(:.*)?$/ ) { + $input = $1; + $rest = $2; + $$wildref = 1; + + $$intrazoneref = ( $input =~ s/\+$// ); + + @result = split_list $input, 'zone'; + } else { + @result = ( $input ); + } + + if ( defined $rest ) { + $_ .= $rest for @result; + } + + @result; +} + +# +# Process a Record in the rules file +# +sub process_rule ( ) { + my ( $target, $source, $dest, $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark, $connlimit, $time, $headers ) = split_line1 1, 13, 'rules file', $rule_commands; + + process_comment, return 1 if $target eq 'COMMENT'; + process_section( $source ), return 1 if $target eq 'SECTION'; + # + # Section Names are optional so once we get to an actual rule, we need to be sure that + # we close off any missing sections. + # + process_section( 'NEW' ) unless $section; + + if ( $source =~ /^none(:.*)?$/i || $dest =~ /^none(:.*)?$/i ) { + progress_message "Rule \"$currentline\" ignored."; + return 1; + } + + my $intrazone = 0; + my $wild = 0; + my $thisline = $currentline; #We must save $currentline because it is overwritten by macro expansion + my $action = isolate_basic_target $target; + my $fw = firewall_zone; + my @source = build_zone_list ( $fw, $source, 'SOURCE', $intrazone, $wild ); + my @dest = build_zone_list ( $fw, $dest, 'DEST' , $intrazone, $wild ); + my $generated = 0; + + fatal_error "Invalid or missing ACTION ($target)" unless defined $action; + + for $source ( @source ) { + for $dest ( @dest ) { + my $sourcezone = (split( /:/, $source, 2 ) )[0]; + my $destzone = (split( /:/, $dest, 2 ) )[0]; + $destzone = $action =~ /^REDIRECT/ ? $fw : '' unless defined_zone $destzone; + if ( ! $wild || $intrazone || ( $sourcezone ne $destzone ) ) { + $generated |= process_rule_common( undef, + $target, + '', + $source, + $dest, + $proto, + $ports, + $sports, + $origdest, + $ratelimit, + $user, + $mark, + $connlimit, + $time, + $headers, + $wild ); + } + } + } + + warning_message qq(Entry generated no $toolname rules) unless $generated; + + progress_message qq( Rule "$thisline" $done); +} + 1; diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 7dbd71a24..3d2c48b74 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -874,158 +874,6 @@ sub setup_mac_lists( $ ) { } } - -# -# Helper functions for process_rule(). That function deals with the ugliness of wildcard zones ('all' and 'any') and zone lists. -# -# Process a SECTION header -# -sub process_section ($) { - my $sect = shift; - # - # read_a_line has already verified that there are exactly two tokens on the line - # - fatal_error "Invalid SECTION ($sect)" unless defined $sections{$sect}; - fatal_error "Duplicate or out of order SECTION $sect" if $sections{$sect}; - $sections{$sect} = 1; - - if ( $sect eq 'RELATED' ) { - $sections{ESTABLISHED} = 1; - finish_section 'ESTABLISHED'; - } elsif ( $sect eq 'NEW' ) { - @sections{'ESTABLISHED','RELATED'} = ( 1, 1 ); - finish_section ( ( $section eq 'RELATED' ) ? 'RELATED' : 'ESTABLISHED,RELATED' ); - } - - $section = $sect; -} - -# -# Build a source or destination zone list -# -sub build_zone_list( $$$\$\$ ) { - my ($fw, $input, $which, $intrazoneref, $wildref ) = @_; - my $any = ( $input =~ s/^any/all/ ); - my $exclude; - my $rest; - my %exclude; - my @result; - # - # Handle Wildcards - # - if ( $input =~ /^(all[-+]*)(![^:]+)?(:.*)?/ ) { - $input = $1; - $exclude = $2; - $rest = $3; - - $$wildref = 1; - - if ( defined $exclude ) { - $exclude =~ s/!//; - fatal_error "Invalid exclusion list (!$exclude)" if $exclude =~ /^,|!|,,|,$/; - for ( split /,/, $exclude ) { - fatal_error "Unknown zone ($_)" unless defined_zone $_; - $exclude{$_} = 1; - } - } - - unless ( $input eq 'all' ) { - if ( $input eq 'all+' ) { - $$intrazoneref = 1; - } elsif ( ( $input eq 'all+-' ) || ( $input eq 'all-+' ) ) { - $$intrazoneref = 1; - $exclude{$fw} = 1; - } elsif ( $input eq 'all-' ) { - $exclude{$fw} = 1; - } else { - fatal_error "Invalid $which ($input)"; - } - } - - @result = grep ! $exclude{$_}, $any ? all_parent_zones : non_firewall_zones; - - unshift @result, $fw unless $exclude{$fw}; - - } elsif ( $input =~ /^([^:]+,[^:]+)(:.*)?$/ ) { - $input = $1; - $rest = $2; - $$wildref = 1; - - $$intrazoneref = ( $input =~ s/\+$// ); - - @result = split_list $input, 'zone'; - } else { - @result = ( $input ); - } - - if ( defined $rest ) { - $_ .= $rest for @result; - } - - @result; -} - -# -# Process a Record in the rules file -# -sub process_rule ( ) { - my ( $target, $source, $dest, $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark, $connlimit, $time, $headers ) = split_line1 1, 13, 'rules file', $rule_commands; - - process_comment, return 1 if $target eq 'COMMENT'; - process_section( $source ), return 1 if $target eq 'SECTION'; - # - # Section Names are optional so once we get to an actual rule, we need to be sure that - # we close off any missing sections. - # - process_section( 'NEW' ) unless $section; - - if ( $source =~ /^none(:.*)?$/i || $dest =~ /^none(:.*)?$/i ) { - progress_message "Rule \"$currentline\" ignored."; - return 1; - } - - my $intrazone = 0; - my $wild = 0; - my $thisline = $currentline; #We must save $currentline because it is overwritten by macro expansion - my $action = isolate_basic_target $target; - my $fw = firewall_zone; - my @source = build_zone_list ( $fw, $source, 'SOURCE', $intrazone, $wild ); - my @dest = build_zone_list ( $fw, $dest, 'DEST' , $intrazone, $wild ); - my $generated = 0; - - fatal_error "Invalid or missing ACTION ($target)" unless defined $action; - - for $source ( @source ) { - for $dest ( @dest ) { - my $sourcezone = (split( /:/, $source, 2 ) )[0]; - my $destzone = (split( /:/, $dest, 2 ) )[0]; - $destzone = $action =~ /^REDIRECT/ ? $fw : '' unless defined_zone $destzone; - if ( ! $wild || $intrazone || ( $sourcezone ne $destzone ) ) { - $generated |= process_rule_common( undef, - $target, - '', - $source, - $dest, - $proto, - $ports, - $sports, - $origdest, - $ratelimit, - $user, - $mark, - $connlimit, - $time, - $headers, - $wild ); - } - } - } - - warning_message qq(Entry generated no $toolname rules) unless $generated; - - progress_message qq( Rule "$thisline" $done); -} - # # Process the Rules File #