From 642ff1be15e2cf7dee3228afc7c5e1f0773dda9b Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Tue, 2 Oct 2012 10:09:23 -0700 Subject: [PATCH] Correct handling of dash characters in interface/ipset names. Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 10 +++--- Shorewall/Perl/Shorewall/Rules.pm | 2 +- Shorewall/Perl/Shorewall/Zones.pm | 57 ++++++++++++++++++++++++++++-- 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index e8954da65..2c66c22b6 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -4779,7 +4779,7 @@ sub get_set_flags( $$ ) { } } - fatal_error "Invalid ipset name ($setname)" unless $setname =~ /^(6_)?[a-zA-Z]\w*/; + fatal_error "Invalid ipset name ($setname)" unless $setname =~ /^(6_)?[a-zA-Z][-\w]*/; have_capability 'OLD_IPSET_MATCH' ? "--set $setname $options " : "--match-set $setname $options "; @@ -4900,7 +4900,7 @@ sub match_source_net( $;$\$ ) { fatal_error "Multiple ipset matches require the Repeat Match capability in your kernel and iptables" unless $globals{KLUDGEFREE}; for $net ( @sets ) { - fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; + fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)(6_)?[a-zA-Z][-\w]*(\[.*\])?/; $result .= join( '', '-m set ', $1 ? '! ' : '', get_set_flags( $net, 'src' ) ); } @@ -4973,7 +4973,7 @@ sub imatch_source_net( $;$\$ ) { fatal_error "Multiple ipset matches requires the Repeat Match capability in your kernel and iptables" unless $globals{KLUDGEFREE}; for $net ( @sets ) { - fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; + fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)(6_)?[a-zA-Z][-\w]*(\[.*\])?/; push @result , ( set => join( '', $1 ? '! ' : '', get_set_flags( $net, 'src' ) ) ); } @@ -5042,7 +5042,7 @@ sub match_dest_net( $;$ ) { fatal_error "Multiple ipset matches requires the Repeat Match capability in your kernel and iptables" unless $globals{KLUDGEFREE}; for $net ( @sets ) { - fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; + fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)(6_)?[a-zA-Z][-\w]*(\[.*\])?/; $result .= join( '', '-m set ', $1 ? '! ' : '', get_set_flags( $net, 'dst' ) ); } @@ -5109,7 +5109,7 @@ sub imatch_dest_net( $;$ ) { fatal_error "Multiple ipset matches requires the Repeat Match capability in your kernel and iptables" unless $globals{KLUDGEFREE}; for $net ( @sets ) { - fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; + fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)(6_)?[a-zA-Z][-\w]*(\[.*\])?/; push @result , ( set => join( '', $1 ? '! ' : '', get_set_flags( $net, 'dst' ) ) ); } diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 94450f6a3..68dc1c010 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -1868,7 +1868,7 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) { my ( $setname, $flags, $rest ) = split ':', $param, 3; fatal_error "Invalid ADD/DEL parameter ($param)" if $rest; - fatal_error "Expected ipset name ($setname)" unless $setname =~ s/^\+// && $setname =~ /^[a-zA-Z]\w*$/; + fatal_error "Expected ipset name ($setname)" unless $setname =~ s/^\+// && $setname =~ /^(6_)?[a-zA-Z][-\w]*$/; fatal_error "Invalid flags ($flags)" unless defined $flags && $flags =~ /^(dst|src)(,(dst|src)){0,5}$/; $action = join( ' ', 'SET --' . $xlate{$basictarget} , $setname , $flags ); } diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index d09e4b350..f28463ac9 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -195,7 +195,9 @@ my @bport_zones; my %ipsets; my %physical; my %basemap; +my %basemap1; my %mapbase; +my %mapbase1; my $family; my $upgrade; my $have_ipsec; @@ -281,7 +283,9 @@ sub initialize( $$ ) { %ipsets = (); %physical = (); %basemap = (); + %basemap1 = (); %mapbase = (); + %mapbase1 = (); $baseseq = 0; $minroot = 0; @@ -780,7 +784,7 @@ sub add_group_to_zone($$$$$) } if ( substr( $host, 0, 1 ) eq '+' ) { - fatal_error "Invalid ipset name ($host)" unless $host =~ /^\+(6_)?[a-zA-Z]\w*$/; + fatal_error "Invalid ipset name ($host)" unless $host =~ /^\+(6_)?[a-zA-Z][-\w]*$/; require_capability( 'IPSET_MATCH', 'Ipset names in host lists', ''); } else { validate_host $host, 0; @@ -937,6 +941,55 @@ sub chain_base($) { $basemap{$key} = $name; } +# +# This is a slightly relaxed version of the above that allows '-' in the generated name. +# +sub chain_base1($) { + my $chain = $_[0]; + my $name = $basemap1{$chain}; + # + # Return existing mapping, if any + # + return $name if $name; + # + # Remember initial value + # + my $key = $chain; + # + # Handle VLANs and wildcards + # + $chain =~ s/\+$//; + $chain =~ tr/./_/; + + if ( $chain eq '' || $chain =~ /^[0-9]/ || $chain =~ /[^-\w]/ ) { + # + # Must map. Remove all illegal characters + # + $chain =~ s/[^\w]//g; + # + # Prefix with if_ if it begins with a digit + # + $chain = join( '' , 'if_', $chain ) if $chain =~ /^[0-9]/; + # + # Create a new unique name + # + 1 while $mapbase1{$name = join ( '_', $chain, ++$baseseq )}; + } else { + # + # We'll store the identity mapping if it is unique + # + $chain = join( '_', $key , ++$baseseq ) while $mapbase1{$name = $chain}; + } + # + # Store the reverse mapping + # + $mapbase1{$name} = $key; + # + # Store the mapping + # + $basemap1{$key} = $name; +} + # # Process a record in the interfaces file # @@ -1839,7 +1892,7 @@ sub process_host( ) { if ( $hosts eq 'dynamic' ) { fatal_error "Vserver zones may not be dynamic" if $type & VSERVER; require_capability( 'IPSET_MATCH', 'Dynamic nets', ''); - my $physical = chain_base( physical_name $interface ); + my $physical = chain_base1( physical_name $interface ); my $set = $family == F_IPV4 ? "${zone}_${physical}" : "6_${zone}_${physical}"; $hosts = "+$set"; $optionsref->{dynamic} = 1;