From 700f662d0419d9f8dd3a9a58a46384b49f6be087 Mon Sep 17 00:00:00 2001 From: teastep Date: Wed, 20 Jun 2007 01:12:35 +0000 Subject: [PATCH] Implement VALIDATE_PORTS git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@6609 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- Shorewall-common/changelog.txt | 2 + Shorewall-common/releasenotes.txt | 12 +++++ Shorewall-common/shorewall.conf | 6 +++ Shorewall-perl/Shorewall/Chains.pm | 9 ++-- Shorewall-perl/Shorewall/Config.pm | 77 ++++++++++++++++++++---------- 5 files changed, 78 insertions(+), 28 deletions(-) diff --git a/Shorewall-common/changelog.txt b/Shorewall-common/changelog.txt index 6e6f413c6..0a38567a1 100644 --- a/Shorewall-common/changelog.txt +++ b/Shorewall-common/changelog.txt @@ -8,6 +8,8 @@ Changes in 4.0.0 Beta 6 4) DYNAMIC_ZONES=Yes and bridges. +5) Implement VALIDATE_PORTS + Changes in 4.0.0 Beta 5 1) Fix undefined function call when both an input interface and an diff --git a/Shorewall-common/releasenotes.txt b/Shorewall-common/releasenotes.txt index 5b771d6a1..2762a6b7a 100644 --- a/Shorewall-common/releasenotes.txt +++ b/Shorewall-common/releasenotes.txt @@ -67,6 +67,18 @@ Other changes in Shorewall 4.0.0 Beta 6 are installed, the additional shorewall.conf file is read to see if it specifies a SHOREWALL_COMPILER. +3) Shorewall-perl validates protocol names and service names against + /etc/protocols and /etc/services. That's the good news. The bad + news is that this extra validation has a fixed overhead of almost + .8 seconds on my x86_64 box. This fixed cost is mostly attributable + to the cost of reading and digesting /etc/services. + + To give people the choice of whether they want to incure this fixed + cost on each compilation, I've added a VALIDATE_PORTS option in + /etc/shorewall/shorewall.conf. If you set this to 'No', you can + save the extra processing time but the script may fail at runtime + because of typing errors. + Migration Considerations: 1) You cannot simply upgrade your existing Shorewall package. You must diff --git a/Shorewall-common/shorewall.conf b/Shorewall-common/shorewall.conf index 2161ce92e..6d07d0ef4 100644 --- a/Shorewall-common/shorewall.conf +++ b/Shorewall-common/shorewall.conf @@ -32,6 +32,12 @@ VERBOSITY=1 SHOREWALL_COMPILER= +############################################################################### +# C O M P I L E R O P T I O N S +############################################################################### + +VALIDATE_PORTS=Yes + ############################################################################### # L O G G I N G ############################################################################### diff --git a/Shorewall-perl/Shorewall/Chains.pm b/Shorewall-perl/Shorewall/Chains.pm index 9933c2278..30cda9ffc 100644 --- a/Shorewall-perl/Shorewall/Chains.pm +++ b/Shorewall-perl/Shorewall/Chains.pm @@ -760,7 +760,7 @@ sub validate_proto( $ ) { return $value if defined $value; return $proto if $proto =~ /^(\d+)$/ && $proto <= 65535; return $proto if $proto eq 'all'; - fatal_error "Invalid/Unknown protocol ($proto)"; + fatal_error "Invalid/Unknown protocol ($proto)" if $config{VALIDATE_PORTS}; } sub validate_portpair( $ ) { @@ -782,9 +782,10 @@ sub validate_portpair( $ ) { $value = $port if $port =~ /^(\d+)$/ && $port <= 65535; } - fatal_error "Invalid/Unknown port/service ($port)" unless defined $value; - - $port = $value; + if ( $config{VALIDATE_PORTS} ) { + fatal_error "Invalid/Unknown port/service ($port)" unless defined $value; + $port = $value; + } } if ( @ports == 2 ) { diff --git a/Shorewall-perl/Shorewall/Config.pm b/Shorewall-perl/Shorewall/Config.pm index c35870a90..6f9243e1c 100644 --- a/Shorewall-perl/Shorewall/Config.pm +++ b/Shorewall-perl/Shorewall/Config.pm @@ -221,6 +221,10 @@ sub initialize() { EXPORTPARAMS => undef, SHOREWALL_COMPILER => undef, # + # Compiler Options + # + VALIDATE_PORTS => undef, + # # Packet Disposition # MACLIST_DISPOSITION => undef, @@ -586,6 +590,27 @@ sub read_a_line { } } +# +# Simple version of the above. Doesn't do line concatenation, shell variable expansion or INCLUDE processing +# +sub read_a_line1 { + while ( $currentfile ) { + while ( $line = <$currentfile> ) { + $currentlinenumber++; + next if $line =~ /^\s*#/; + chomp $line; + next if $line =~ /^\s*$/; + $line =~ s/#.*$//; # Remove Trailing Comments -- result might be a blank line + $line =~ s/^\s+//; # Remove Leading white space + $line =~ s/\s+$//; # Remove Trailing white space + + return 1; + } + + close_file; + } +} + # # Provide the passed default value for the passed configuration variable # @@ -971,7 +996,7 @@ sub get_capabilities( $ ) { # If we successfully called open_file above, then this loop will read the capabilities file. # Otherwise, the first call to read_a_line() below will return false # - while ( read_a_line ) { + while ( read_a_line1 ) { if ( $line =~ /^([a-zA-Z]\w*)=(.*)$/ ) { my ($var, $val) = ($1, $2); unless ( exists $capabilities{$var} ) { @@ -992,6 +1017,31 @@ sub get_capabilities( $ ) { } } +sub get_protos_and_ports() { + open_file '/etc/protocols' or fatal_error "Cannot open /etc/protocols: $!"; + + while ( read_a_line1 ) { + my ( $proto1, $number, $proto2, $proto3 ) = split_line( 2, 4, '/etc/protocols entry'); + + $protocols{ $proto1 } = $number; + $protocols{ $proto2 } = $number unless $proto2 eq '-' || $proto3 ne '-'; + } + + open_file '/etc/services' or fatal_error "Cannot open /etc/services: $!"; + + while ( read_a_line1 ) { + my ( $name1, $proto_number, @names ) = split_line( 2, 10, '/etc/services entry'); + + my ( $number, $proto ) = split '/', $proto_number; + + $services{ $name1 } = $number; + + while ( defined ( $name1 = shift @names ) && $name1 ne '-' ) { + $services{ $name1 } = $number; + } + } +} + # # - Read the shorewall.conf file # - Read the capabilities file, if any @@ -1084,6 +1134,7 @@ sub get_configuration( $ ) { default_yes_no 'EXPORTPARAMS' , ''; default_yes_no 'MARK_IN_FORWARD_CHAIN' , ''; + default_yes_no 'VALIDATE_PORTS' , 'Yes'; $capabilities{XCONNMARK} = '' unless $capabilities{XCONNMARK_MATCH} and $capabilities{XMARK}; @@ -1201,29 +1252,7 @@ sub get_configuration( $ ) { $config{LOCKFILE} = ''; } - open_file '/etc/protocols' or fatal_error "Cannot open /etc/protocols: $!"; - - while ( read_a_line ) { - my ( $proto1, $number, $proto2, $proto3 ) = split_line( 2, 4, '/etc/protocols entry'); - - $protocols{ $proto1 } = $number; - $protocols{ $proto2 } = $number unless $proto2 eq '-' || $proto3 ne '-'; - } - - - open_file '/etc/services' or fatal_error "Cannot open /etc/services: $!"; - - while ( read_a_line ) { - my ( $name1, $proto_number, @names ) = split_line( 2, 10, '/etc/services entry'); - - my ( $number, $proto ) = split '/', $proto_number; - - $services{ $name1 } = $number; - - while ( defined ( $name1 = shift @names ) && $name1 ne '-' ) { - $services{ $name1 } = $number; - } - } + get_protos_and_ports if $config{VALIDATE_PORTS}; } #