From 1f1d31163c347ace7b8e288363235ea22651916f Mon Sep 17 00:00:00 2001 From: Bob Gilligan Date: Fri, 23 Jan 2009 13:59:37 -0800 Subject: Bugfix 4062: Don't reference parameters outside the config tree. The AddressFilter module was reaching up the config tree to find a config parameter that was used to determine whether the address type was IPv4 or IPv6. This breaks when the functions are called from some locations in the config tree. I added explicity function calls to allow the caller to to set the IP version, obviating the need to reference a config parameter to determin the IP version. --- lib/Vyatta/IpTables/AddressFilter.pm | 21 ++++++++++++++------- lib/Vyatta/IpTables/Rule.pm | 14 ++++++++++++++ scripts/firewall/vyatta-firewall.pl | 13 +++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/lib/Vyatta/IpTables/AddressFilter.pm b/lib/Vyatta/IpTables/AddressFilter.pm index 3689ee2..6a74002 100755 --- a/lib/Vyatta/IpTables/AddressFilter.pm +++ b/lib/Vyatta/IpTables/AddressFilter.pm @@ -44,7 +44,7 @@ my %fields = ( _port => undef, _protocol => undef, _src_mac => undef, - _name => undef, + _ip_version => undef, ); sub new { @@ -58,13 +58,20 @@ sub new { return $self; } +sub set_ip_version($$) { + my ($self, $ip_version) = @_; + + $self->{_ip_version} = $ip_version; +} + sub setup { my ($self, $level) = @_; my $config = new Vyatta::Config; $config->setLevel("$level"); - $self->{_name} = $config->returnParent(".. .. .. .. .."); + # Default to IPv4. + $self->{_ip_version} = "ipv4"; # setup needed parent nodes $self->{_srcdst} = $config->returnParent(".."); @@ -98,7 +105,8 @@ sub setupOrig { $config->setLevel("$level"); - $self->{_name} = $config->returnParent(".. .. .. .. .."); + # Default to IPv4. + $self->{_ip_version} = "ipv4"; # setup needed parent nodes $self->{_srcdst} = $config->returnParent(".."); @@ -151,15 +159,14 @@ sub rule { my $ip_term; my $prefix_term; - if (($self->{_name} eq "name") || ($self->{_name} eq "modify")) { + if ($self->{_ip_version} eq "ipv4") { # This is an IPv4 rule $addr_checker = 'ipv4_negate'; $prefix_checker = 'ipv4net_negate'; $ip_term = "IPv4"; $prefix_term = "subnet"; - } elsif (($self->{_name} eq "ipv6-name") || - ($self->{_name} eq "ipv6-modify")) { + } elsif ($self->{_ip_version} eq "ipv6") { # This is an IPv6 rule $addr_checker = 'ipv6_negate'; @@ -167,7 +174,7 @@ sub rule { $ip_term = "IPv6"; $prefix_term = "prefix" } else { - return (undef, "Invalid firewall tree: $self->{_name}"); + return (undef, "Invalid IP version: $self->{_ip_version}"); } if (!defined($self->{_protocol}) diff --git a/lib/Vyatta/IpTables/Rule.pm b/lib/Vyatta/IpTables/Rule.pm index 449b32b..d55cf64 100644 --- a/lib/Vyatta/IpTables/Rule.pm +++ b/lib/Vyatta/IpTables/Rule.pm @@ -51,6 +51,7 @@ my %fields = ( _burst => undef, }, _disable => undef, + _ip_version => undef, ); my %dummy_rule = ( @@ -97,6 +98,7 @@ my %dummy_rule = ( _burst => undef, }, _disable => undef, + _ip_version => undef, ); sub new { @@ -171,6 +173,8 @@ sub setup { $src->setup("$level source"); $dst->setup("$level destination"); + # Default to IPv4 + $self->{_ip_version} = "ipv4"; return 0; } @@ -229,9 +233,19 @@ sub setupOrig { $src->setupOrig("$level source"); $dst->setupOrig("$level destination"); + # Default to IPv4 + $self->{_ip_version} = "ipv4"; return 0; } +sub set_ip_version { + my ($self, $ip_version) = @_; + + $self->{_ip_version} = $ip_version; + $src->set_ip_version($ip_version); + $dst->set_ip_version($ip_version); +} + sub print { my ( $self ) = @_; diff --git a/scripts/firewall/vyatta-firewall.pl b/scripts/firewall/vyatta-firewall.pl index 9625c43..058e9cf 100755 --- a/scripts/firewall/vyatta-firewall.pl +++ b/scripts/firewall/vyatta-firewall.pl @@ -41,6 +41,13 @@ my %cmd_hash = ( 'name' => 'iptables', 'modify' => 'iptables', 'ipv6-modify' => 'ip6tables'); +# mapping from config node to IP version string. +my %ip_version_hash = ( 'name' => 'ipv4', + 'ipv6-name' => 'ipv6', + 'modify' => 'ipv4', + 'ipv6-modify' => 'ipv6'); + + sub other_table { my $this = shift; return (($this eq 'filter') ? 'mangle' : 'filter'); @@ -195,6 +202,7 @@ sub update_rules($) { foreach (sort numerically @rules) { my $node = new Vyatta::IpTables::Rule; $node->setupOrig("firewall $tree $name rule $_"); + $node->set_ip_version($ip_version_hash{$tree}); if ($node->is_stateful()) { $stateful = 1; last; @@ -252,6 +260,7 @@ sub update_rules($) { if ("$rulehash{$rule}" eq "static") { my $node = new Vyatta::IpTables::Rule; $node->setupOrig("firewall $tree $name rule $rule"); + $node->set_ip_version($ip_version_hash{$tree}); if ($node->is_stateful()) { $stateful = 1; } @@ -261,6 +270,7 @@ sub update_rules($) { # create a new iptables object of the current rule my $node = new Vyatta::IpTables::Rule; $node->setup("firewall $tree $name rule $rule"); + $node->set_ip_version($ip_version_hash{$tree}); if ($node->is_stateful()) { $stateful = 1; } @@ -286,8 +296,10 @@ sub update_rules($) { # create a new iptables object of the current rule my $oldnode = new Vyatta::IpTables::Rule; $oldnode->setupOrig("firewall $tree $name rule $rule"); + $oldnode->set_ip_version($ip_version_hash{$tree}); my $node = new Vyatta::IpTables::Rule; $node->setup("firewall $tree $name rule $rule"); + $node->set_ip_version($ip_version_hash{$tree}); if ($node->is_stateful()) { $stateful = 1; } @@ -321,6 +333,7 @@ sub update_rules($) { } elsif ("$rulehash{$rule}" eq "deleted") { my $node = new Vyatta::IpTables::Rule; $node->setupOrig("firewall $tree $name rule $rule"); + $node->set_ip_version($ip_version_hash{$tree}); my $ipt_rules = $node->get_num_ipt_rules(); for (1 .. $ipt_rules) { -- cgit v1.2.3