diff options
Diffstat (limited to 'lib/Vyatta/Zone.pm')
-rwxr-xr-x | lib/Vyatta/Zone.pm | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/lib/Vyatta/Zone.pm b/lib/Vyatta/Zone.pm new file mode 100755 index 0000000..b23bc74 --- /dev/null +++ b/lib/Vyatta/Zone.pm @@ -0,0 +1,216 @@ +# Module: Zone.pm +# +# **** License **** +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2009 Vyatta, Inc. +# All Rights Reserved. +# +# Author: Mohit Mehta +# Date: 2009 +# Description: vyatta zone management +# +# **** End License **** +# + +package Vyatta::Zone; + +use Vyatta::Config; +use Vyatta::Misc; +use Vyatta::Interface; + +use strict; +use warnings; + +my $debug="false"; +my $syslog="false"; +my $logger = 'sudo logger -t zone.pm -p local0.warn --'; + +sub run_cmd { + my $cmd = shift; + my $error = system("$cmd"); + + if ($syslog eq "true") { + my $func = (caller(1))[3]; + system("$logger [$func] [$cmd] = [$error]"); + } + if ($debug eq "true") { + my $func = (caller(1))[3]; + print "[$func] [$cmd] = [$error]\n"; + } + return $error; +} + +sub is_fwruleset_active { + my ($value_func, $ruleset_type, $fw_ruleset) = @_; + my $config = new Vyatta::Config; + return $config->$value_func("firewall $ruleset_type $fw_ruleset"); +} + +sub get_all_zones { + my $value_func = shift; + my $config = new Vyatta::Config; + return $config->$value_func("zone-policy zone"); +} + +sub get_zone_interfaces { + my ($value_func, $zone_name) = @_; + my $config = new Vyatta::Config; + return $config->$value_func("zone-policy zone $zone_name interface"); +} + +sub get_from_zones { + my ($value_func, $zone_name) = @_; + my $config = new Vyatta::Config; + return $config->$value_func("zone-policy zone $zone_name from"); +} + +sub get_firewall_ruleset { + my ($value_func, $zone_name, $from_zone, $firewall_type) = @_; + my $config = new Vyatta::Config; + return $config->$value_func("zone-policy zone $zone_name from $from_zone + firewall $firewall_type"); +} + +sub is_local_zone { + my ($value_func, $zone_name) = @_; + my $config = new Vyatta::Config; + return $config->$value_func("zone-policy zone $zone_name local-zone"); +} + +sub get_zone_default_policy { + my ($value_func, $zone_name) = @_; + my $config = new Vyatta::Config; + return $config->$value_func("zone-policy zone $zone_name default-action"); +} + +sub rule_exists { + my ($command, $table, $chain_name, $target, $interface) = @_; + my $cmd = + "sudo $command -t $table -L " . + "$chain_name -v 2>/dev/null | grep \" $target \" "; + if (defined $interface) { + $cmd .= "| grep \" $interface \" "; + } + $cmd .= "| wc -l"; + my $result = `$cmd`; + return $result; +} + +sub get_zone_chain { + my ($value_func, $zone, $localout) = @_; + my $chain = "VZONE_$zone"; + if (defined(is_local_zone($value_func, $zone))) { + # local zone + if (defined $localout) { + # local zone out chain + $chain .= "_OUT"; + } else { + # local zone in chain + $chain .= "_IN"; + } + } + return $chain; +} + +sub validity_checks { + my @all_zones = get_all_zones("listNodes"); + my @all_interfaces = (); + my $num_local_zones = 0; + my $returnstring; + foreach my $zone (@all_zones) { + # get all from zones, see if they exist in config, if not display error + my @from_zones = get_from_zones("listNodes", $zone); + foreach my $from_zone (@from_zones) { + if (scalar(grep(/^$from_zone$/, @all_zones)) == 0) { + $returnstring = "$from_zone is a from zone under zone $zone\n" . + "It is either not defined or deleted from config"; + return ($returnstring, ); + } + } + my @zone_intfs = get_zone_interfaces("returnValues", $zone); + if (scalar(@zone_intfs) == 0) { + # no interfaces defined for this zone + if (!defined(is_local_zone("exists", $zone))) { + $returnstring = "Zone $zone has no interfaces defined " . + "and it's not a local-zone"; + return($returnstring, ); + } + # zone defined as a local-zone + my @zone_intfs_orig = get_zone_interfaces("returnOrigValues", $zone); + if (scalar(@zone_intfs_orig) != 0) { + # can't change change transit zone to local-zone on the fly + $returnstring = "Zone $zone is a transit zone. " . + "Cannot convert it to local-zone.\n" . + "Please define another zone to create local-zone"; + return($returnstring, ); + } + $num_local_zones++; + # make sure only one zone is a local-zone + if ($num_local_zones > 1) { + return ("Only one zone can be defined as a local-zone", ); + } + } else { + # zone has interfaces, make sure it is not set as a local-zone + if (defined(is_local_zone("exists", $zone))) { + $returnstring = "local-zone cannot have interfaces defined"; + return($returnstring, ); + } + # make sure you're not converting local-zone to transit zone either + if (defined(is_local_zone("existsOrig", $zone))) { + $returnstring = "Cannot convert local-zone $zone to transit zone" . + "\nPlease define another zone for it"; + return($returnstring, ); + } + foreach my $interface (@zone_intfs) { + # make sure zone features are not being used on zone interface + my $intf = new Vyatta::Interface($interface); + if ($intf) { + my $config = new Vyatta::Config; + $config->setLevel($intf->path()); + # make sure firewall is not applied to this interface + if ($config->exists("firewall in name") || + $config->exists("firewall out name") || + $config->exists("firewall local name") || + $config->exists("firewall in ipv6-name") || + $config->exists("firewall out ipv6-name") || + $config->exists("firewall local ipv6-name")) { + $returnstring = + "interface $interface has firewall rule-set " . + "configured, cannot be defined under a zone"; + return($returnstring, ); + } + # make sure content-inspection is not applied to this interface + if ($config->exists("content-inspection in enable") || + $config->exists("content-inspection out enable") || + $config->exists("content-inspection local enable") || + $config->exists("content-inspection in ipv6-enable") || + $config->exists("content-inspection out ipv6-enable") || + $config->exists("content-inspection local ipv6-enable")) { + $returnstring = + "interface $interface has content-inspection " . + "configured, cannot be defined under a zone"; + return($returnstring, ); + } + } + # make sure an interface is not defined under two zones + if (scalar(grep(/^$interface$/, @all_interfaces)) > 0) { + return ("$interface defined under two zones", ); + } else { + push(@all_interfaces, $interface); + } + } + } + } + return; +} + +1; |