From 0f1892ba28cdcad63a71889d671c6682d6fc9eb2 Mon Sep 17 00:00:00 2001 From: teastep Date: Wed, 14 Mar 2007 03:27:29 +0000 Subject: [PATCH] Add host file parsing to Zones module git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@5519 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- New/Shorewall/Zones.pm | 202 ++++++++++++++++++++++++++++++++++++++++- New/compiler.pl | 199 ---------------------------------------- 2 files changed, 201 insertions(+), 200 deletions(-) diff --git a/New/Shorewall/Zones.pm b/New/Shorewall/Zones.pm index 93816f466..c960f4f99 100644 --- a/New/Shorewall/Zones.pm +++ b/New/Shorewall/Zones.pm @@ -4,7 +4,7 @@ use Shorewall::Common; use Shorewall::Config; our @ISA = qw(Exporter); -our @EXPORT = qw( determine_zones add_group_to_zone @zones %zones $firewall_zone ); +our @EXPORT = qw( determine_zones validate_hosts_file add_group_to_zone dump_zone_info zone_report @zones %zones $firewall_zone ); our @EXPORT_OK = (); our @VERSION = 1.00; @@ -257,4 +257,204 @@ sub add_group_to_zone($$$$$) push @{$arrayref}, \%h; } +# +# Dump out all information about zones. +# +sub dump_zone_info() +{ + print "\n"; + + for my $zone ( @zones ) + { + my $zoneref = $zones{$zone}; + my $typeref = $zoneref->{hosts}; + my $optionref = $zoneref->{options}; + my $zonetype = $zoneref->{type}; + + print "Zone: $zone\n"; + + print " Type: $zonetype\n"; + print " Parents:\n"; + + my $parentsref = $zoneref->{parents}; + + for my $parent ( @$parentsref ) { + print " $parent\n"; + } + + if ( %$optionref ) { + print " Options:\n"; + + for my $opttype ( keys %$optionref ) { + if ( $opttype eq 'complex' ) { + print " Complex: $optionref->{$opttype}\n"; + } else { + print " $opttype:\n"; + while ( my ( $option, $val ) = each %{$optionref->{$opttype}} ) { print " $option=$val\n"; } + } + } + } + + if ( $typeref ) { + print " Host Groups:\n"; + while ( my ( $type, $interfaceref ) = ( each %$typeref ) ) { + print " Type: $type\n"; + + for my $interface ( sort keys %$interfaceref ) { + my $arrayref = $interfaceref->{$interface}; + + print " Interface: $interface\n"; + + for my $groupref ( @$arrayref ) { + my $hosts = $groupref->{hosts}; + my $options = $groupref->{options}; + my $ipsec = $groupref->{ipsec}; + + if ( $ipsec ) { + print " Ipsec: $ipsec\n" ; + } + + if ( $hosts ) { + my $space = ''; + print " Hosts: " ; + for my $host ( @{$hosts} ) { + print "${space}${host}\n"; + $space = ' '; + } + } + + if ( $options ) { + print " Options: "; + for my $option (sort keys %$options ) { + print "$option "; + } + print "\n"; + } + } + } + } + } else { + # + # Empty ? + # + print " ***Empty***\n" if $zonetype ne 'firewall'; + } + } + + print "\n"; +} + +# +# Report about zones. +# +sub zone_report() +{ + for my $zone ( @zones ) + { + my $zoneref = $zones{$zone}; + my $hostref = $zoneref->{hosts}; + my $type = $zoneref->{type}; + my $optionref = $zoneref->{options}; + + progress_message " $zone ($type)"; + + my $printed = 0; + + if ( $hostref ) { + for my $type ( sort keys %$hostref ) { + my $interfaceref = $hostref->{$type}; + + for my $interface ( sort keys %$interfaceref ) { + my $arrayref = $interfaceref->{$interface}; + for my $groupref ( @$arrayref ) { + my $hosts = $groupref->{hosts}; + if ( $hosts ) { + my $grouplist = join ',', ( @$hosts ); + progress_message " $interface:$grouplist"; + $printed = 1; + } + } + + } + } + } + + print STDERR " *** $zone is an EMPTY ZONE ***\n" unless $printed || $type eq 'firewall'; + } +} + +# +# Validates the hosts file. Generates entries in %zone{..}{hosts} +# +sub validate_hosts_file() +{ + my %validoptions = ( + blacklist => 1, + maclist => 1, + norfc1918 => 1, + nosmurfs => 1, + routeback => 1, + routefilter => 1, + tcpflags => 1, + ); + + open HOSTS, "$ENV{TMP_DIR}/hosts" or fatal_error "Unable to open stripped hosts file: $!"; + + while ( $line = ) { + + chomp $line; + $line =~ s/\s+/ /g; + + my ($zone, $hosts, $options, $extra) = split /\s+/, $line; + + fatal_error "Invalid hosts file entry: $line" if $extra; + + my $zoneref = $zones{$zone}; + my $type = $zoneref->{type}; + + fatal_error "Unknown ZONE ($zone)" unless $type; + fatal_error 'Firewall zone not allowed in ZONE column of hosts record' if $type eq 'firewall'; + + my $interface; + + if ( $hosts =~ /^([\w.@%-]+):(.*)$/ ) { + $interface = $1; + $hosts = $2; + $zoneref->{options}{complex} = 1 if $hosts =~ /^\+/; + fatal_error "Unknown interface ($interface)" unless $interfaces{$interface}{root}; + } else { + fatal_error "Invalid HOSTS(S) column contents: $hosts"; + } + + my $optionsref; + + if ( $options && $options ne '-' ) { + my @options = split ',', $options; + my %options; + + for my $option ( @options ) + { + if ( $option eq 'ipsec' ) { + $type = 'ipsec'; + $zoneref->{options}{complex} = 1; + } elsif ( $validoptions{$option}) { + $options{$option} = 1; + } else { + fatal_error "Invalid option ($option)"; + } + } + + $optionsref = \%options; + } + + my @h = split ',', $hosts; + + add_group_to_zone( $zone, $type , $interface, \@h , $optionsref); + + progress_message " Host \"$line\" validated"; + } + + close HOSTS; +} + 1; diff --git a/New/compiler.pl b/New/compiler.pl index 439464392..9ed19db48 100755 --- a/New/compiler.pl +++ b/New/compiler.pl @@ -133,205 +133,6 @@ my %default_actions = ( DROP => 'none' , ACCEPT => 'none' , QUEUE => 'none' ); -# -# Validates the hosts file. Generates entries in %zone{..}{hosts} -# -sub validate_hosts_file() -{ - my %validoptions = ( - blacklist => 1, - maclist => 1, - norfc1918 => 1, - nosmurfs => 1, - routeback => 1, - routefilter => 1, - tcpflags => 1, - ); - - open HOSTS, "$ENV{TMP_DIR}/hosts" or fatal_error "Unable to open stripped hosts file: $!"; - - while ( $line = ) { - - chomp $line; - $line =~ s/\s+/ /g; - - my ($zone, $hosts, $options, $extra) = split /\s+/, $line; - - fatal_error "Invalid hosts file entry: $line" if $extra; - - my $zoneref = $zones{$zone}; - my $type = $zoneref->{type}; - - fatal_error "Unknown ZONE ($zone)" unless $type; - fatal_error 'Firewall zone not allowed in ZONE column of hosts record' if $type eq 'firewall'; - - my $interface; - - if ( $hosts =~ /^([\w.@%-]+):(.*)$/ ) { - $interface = $1; - $hosts = $2; - $zoneref->{options}{complex} = 1 if $hosts =~ /^\+/; - fatal_error "Unknown interface ($interface)" unless $interfaces{$interface}{root}; - } else { - fatal_error "Invalid HOSTS(S) column contents: $hosts"; - } - - my $optionsref; - - if ( $options && $options ne '-' ) { - my @options = split ',', $options; - my %options; - - for my $option ( @options ) - { - if ( $option eq 'ipsec' ) { - $type = 'ipsec'; - $zoneref->{options}{complex} = 1; - } elsif ( $validoptions{$option}) { - $options{$option} = 1; - } else { - fatal_error "Invalid option ($option)"; - } - } - - $optionsref = \%options; - } - - my @h = split ',', $hosts; - - add_group_to_zone( $zone, $type , $interface, \@h , $optionsref); - - progress_message " Host \"$line\" validated"; - } - - close HOSTS; -} - -# -# Dump out all information about zones. -# -sub dump_zone_info() -{ - print "\n"; - - for my $zone ( @zones ) - { - my $zoneref = $zones{$zone}; - my $typeref = $zoneref->{hosts}; - my $optionref = $zoneref->{options}; - my $zonetype = $zoneref->{type}; - - print "Zone: $zone\n"; - - print " Type: $zonetype\n"; - print " Parents:\n"; - - my $parentsref = $zoneref->{parents}; - - for my $parent ( @$parentsref ) { - print " $parent\n"; - } - - if ( %$optionref ) { - print " Options:\n"; - - for my $opttype ( keys %$optionref ) { - if ( $opttype eq 'complex' ) { - print " Complex: $optionref->{$opttype}\n"; - } else { - print " $opttype:\n"; - while ( my ( $option, $val ) = each %{$optionref->{$opttype}} ) { print " $option=$val\n"; } - } - } - } - - if ( $typeref ) { - print " Host Groups:\n"; - while ( my ( $type, $interfaceref ) = ( each %$typeref ) ) { - print " Type: $type\n"; - - for my $interface ( sort keys %$interfaceref ) { - my $arrayref = $interfaceref->{$interface}; - - print " Interface: $interface\n"; - - for my $groupref ( @$arrayref ) { - my $hosts = $groupref->{hosts}; - my $options = $groupref->{options}; - my $ipsec = $groupref->{ipsec}; - - if ( $ipsec ) { - print " Ipsec: $ipsec\n" ; - } - - if ( $hosts ) { - my $space = ''; - print " Hosts: " ; - for my $host ( @{$hosts} ) { - print "${space}${host}\n"; - $space = ' '; - } - } - - if ( $options ) { - print " Options: "; - for my $option (sort keys %$options ) { - print "$option "; - } - print "\n"; - } - } - } - } - } else { - # - # Empty ? - # - print " ***Empty***\n" if $zonetype ne 'firewall'; - } - } - - print "\n"; -} - -# -# Report about zones. -# -sub zone_report() -{ - for my $zone ( @zones ) - { - my $zoneref = $zones{$zone}; - my $hostref = $zoneref->{hosts}; - my $type = $zoneref->{type}; - my $optionref = $zoneref->{options}; - - progress_message " $zone ($type)"; - - my $printed = 0; - - if ( $hostref ) { - for my $type ( sort keys %$hostref ) { - my $interfaceref = $hostref->{$type}; - - for my $interface ( sort keys %$interfaceref ) { - my $arrayref = $interfaceref->{$interface}; - for my $groupref ( @$arrayref ) { - my $hosts = $groupref->{hosts}; - if ( $hosts ) { - my $grouplist = join ',', ( @$hosts ); - progress_message " $interface:$grouplist"; - $printed = 1; - } - } - - } - } - } - - print STDERR " *** $zone is an EMPTY ZONE ***\n" unless $printed || $type eq 'firewall'; - } -} # # Create a new chain and return a reference to it.