mirror of
https://gitlab.com/shorewall/code.git
synced 2024-11-28 02:23:20 +01:00
Move more code from Rules.pm to Actions.pm
This commit is contained in:
parent
5b0d8922e7
commit
9e684a80c1
@ -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;
|
||||
|
@ -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
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user