X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=config%2Ffirewall%2Ffirewall-lib.pl;h=c4a19e5d80caa17b6cc0dc68b612c8814da14c59;hb=4188fbf1f0efd70cd444ddb2398d35367ddab67f;hp=8cff76bb53ac42965988b5a26b43cbc399d7d036;hpb=14bcb9a23d6d96fedaf0d5d71f65a8e7a8e6a4eb;p=ipfire-2.x.git diff --git a/config/firewall/firewall-lib.pl b/config/firewall/firewall-lib.pl index 8cff76bb53..c4a19e5d80 100755 --- a/config/firewall/firewall-lib.pl +++ b/config/firewall/firewall-lib.pl @@ -35,6 +35,7 @@ my %ipsecconf=(); my %ipsecsettings=(); my %netsettings=(); my %ovpnsettings=(); +my %aliases=(); require '/var/ipfire/general-functions.pl'; @@ -49,12 +50,12 @@ my $configipsec = "${General::swroot}/vpn/config"; my $configovpn = "${General::swroot}/ovpn/settings"; my $val; my $field; +my $netsettings = "${General::swroot}/ethernet/settings"; &General::readhash("/var/ipfire/ethernet/settings", \%netsettings); &General::readhash("${General::swroot}/ovpn/settings", \%ovpnsettings); &General::readhash("${General::swroot}/vpn/settings", \%ipsecsettings); - &General::readhasharray("$confignet", \%customnetwork); &General::readhasharray("$confighost", \%customhost); &General::readhasharray("$configgrp", \%customgrp); @@ -63,6 +64,7 @@ my $field; &General::readhasharray("$configipsec", \%ipsecconf); &General::readhasharray("$configsrv", \%customservice); &General::readhasharray("$configsrvgrp", \%customservicegrp); +&General::get_aliases(\%aliases); sub get_srv_prot { @@ -90,7 +92,10 @@ sub get_srvgrp_prot $udp=1; }elsif(&get_srv_prot($customservicegrp{$key}[2]) eq 'ICMP'){ $icmp=1; - } + }else{ + #Protocols used in servicegroups + push (@ips,$customservicegrp{$key}[2]); + } } } if ($tcp eq '1'){push (@ips,'TCP');} @@ -100,8 +105,6 @@ sub get_srvgrp_prot return $back; } - - sub get_srv_port { my $val=shift; @@ -250,5 +253,284 @@ sub get_host_ip } } } +sub get_addresses +{ + my $hash = shift; + my $key = shift; + my $type = shift; + + my @addresses = (); + my $addr_type; + my $value; + my $group_name; + + if ($type eq "src") { + $addr_type = $$hash{$key}[3]; + $value = $$hash{$key}[4]; + + } elsif ($type eq "tgt") { + $addr_type = $$hash{$key}[5]; + $value = $$hash{$key}[6]; + } + + if ($addr_type ~~ ["cust_grp_src", "cust_grp_tgt"]) { + foreach my $grp (sort {$a <=> $b} keys %customgrp) { + if ($customgrp{$grp}[0] eq $value) { + my @address = &get_address($customgrp{$grp}[3], $customgrp{$grp}[2], $type); + + if (@address) { + push(@addresses, @address); + } + } + } + } else { + my @address = &get_address($addr_type, $value, $type); + + if (@address) { + push(@addresses, @address); + } + } + + return @addresses; +} +sub get_address +{ + my $key = shift; + my $value = shift; + my $type = shift; + + my @ret = (); + + # If the user manually typed an address, we just check if it is a MAC + # address. Otherwise, we assume that it is an IP address. + if ($key ~~ ["src_addr", "tgt_addr"]) { + if (&General::validmac($value)) { + push(@ret, "-m mac --mac-source $value"); + } else { + push(@ret, $value); + } + + # If a default network interface (GREEN, BLUE, etc.) is selected, we + # try to get the corresponding address of the network. + } elsif ($key ~~ ["std_net_src", "std_net_tgt", "Standard Network"]) { + my $external_interface = &get_external_interface(); + + my $network_address = &get_std_net_ip($value, $external_interface); + if ($network_address) { + push(@ret, $network_address); + } + + # Custom networks. + } elsif ($key ~~ ["cust_net_src", "cust_net_tgt", "Custom Network"]) { + my $network_address = &get_net_ip($value); + if ($network_address) { + push(@ret, $network_address); + } + + # Custom hosts. + } elsif ($key ~~ ["cust_host_src", "cust_host_tgt", "Custom Host"]) { + my $host_address = &get_host_ip($value, $type); + if ($host_address) { + push(@ret, $host_address); + } + + # OpenVPN networks. + } elsif ($key ~~ ["ovpn_net_src", "ovpn_net_tgt", "OpenVPN static network"]) { + my $network_address = &get_ovpn_net_ip($value, 1); + if ($network_address) { + push(@ret, $network_address); + } + + # OpenVPN hosts. + } elsif ($key ~~ ["ovpn_host_src", "ovpn_host_tgt", "OpenVPN static host"]) { + my $host_address = &get_ovpn_host_ip($value, 33); + if ($host_address) { + push(@ret, $host_address); + } + + # OpenVPN N2N. + } elsif ($key ~~ ["ovpn_n2n_src", "ovpn_n2n_tgt", "OpenVPN N-2-N"]) { + my $network_address = &get_ovpn_n2n_ip($value, 11); + if ($network_address) { + push(@ret, $network_address); + } + + # IPsec networks. + } elsif ($key ~~ ["ipsec_net_src", "ipsec_net_tgt", "IpSec Network"]) { + my $network_address = &get_ipsec_net_ip($value, 11); + if ($network_address) { + push(@ret, $network_address); + } + + # The firewall's own IP addresses. + } elsif ($key ~~ ["ipfire", "ipfire_src"]) { + # ALL + if ($value eq "ALL") { + push(@ret, "0/0"); + + # GREEN + } elsif ($value eq "GREEN") { + push(@ret, $netsettings{"GREEN_ADDRESS"}); + + # BLUE + } elsif ($value eq "BLUE") { + push(@ret, $netsettings{"BLUE_ADDRESS"}); + + # ORANGE + } elsif ($value eq "ORANGE") { + push(@ret, $netsettings{"ORANGE_ADDRESS"}); + + # RED + } elsif ($value ~~ ["RED", "RED1"]) { + my $address = &get_external_address(); + if ($address) { + push(@ret, $address); + } + + # Aliases + } else { + my $alias = &get_alias($value); + if ($alias) { + push(@ret, $alias); + } + } + + # If nothing was selected, we assume "any". + } else { + push(@ret, "0/0"); + } + + return @ret; +} +sub get_external_interface() +{ + open(IFACE, "/var/ipfire/red/iface") or return ""; + my $iface = ; + close(IFACE); + + return $iface; +} +sub get_external_address() +{ + open(ADDR, "/var/ipfire/red/local-ipaddress") or return ""; + my $address = ; + close(ADDR); + + return $address; +} +sub get_alias +{ + my $id = shift; + + foreach my $alias (sort keys %aliases) { + if ($id eq $alias) { + return $aliases{$alias}{"IPT"}; + } + } +} + +sub get_nat_address { + my $zone = shift; + my $source = shift; + + # Any static address of any zone. + if ($zone eq "AUTO") { + if ($source && ($source !~ m/mac/i )) { + my $firewall_ip = &get_internal_firewall_ip_address($source, 1); + if ($firewall_ip) { + return $firewall_ip; + } + + $firewall_ip = &get_matching_firewall_address($source, 1); + if ($firewall_ip) { + return $firewall_ip; + } + } + + return &get_external_address(); + + } elsif ($zone eq "RED" || $zone eq "GREEN" || $zone eq "ORANGE" || $zone eq "BLUE") { + return $netsettings{$zone . "_ADDRESS"}; + + } elsif ($zone ~~ ["Default IP", "ALL"]) { + return &get_external_address(); + + } else { + my $alias = &get_alias($zone); + unless ($alias) { + $alias = &get_external_address(); + } + return $alias; + } + + print_error("Could not find NAT address"); +} + +sub get_internal_firewall_ip_addresses +{ + my $use_orange = shift; + + my @zones = ("GREEN", "BLUE"); + if ($use_orange) { + push(@zones, "ORANGE"); + } + + my @addresses = (); + for my $zone (@zones) { + next unless (exists $netsettings{$zone . "_ADDRESS"}); + + my $zone_address = $netsettings{$zone . "_ADDRESS"}; + push(@addresses, $zone_address); + } + + return @addresses; +} +sub get_matching_firewall_address +{ + my $addr = shift; + my $use_orange = shift; + + my ($address, $netmask) = split("/", $addr); + + my @zones = ("GREEN", "BLUE"); + if ($use_orange) { + push(@zones, "ORANGE"); + } + + foreach my $zone (@zones) { + next unless (exists $netsettings{$zone . "_ADDRESS"}); + + my $zone_subnet = $netsettings{$zone . "_NETADDRESS"}; + my $zone_mask = $netsettings{$zone . "_NETMASK"}; + + if (&General::IpInSubnet($address, $zone_subnet, $zone_mask)) { + return $netsettings{$zone . "_ADDRESS"}; + } + } + + return 0; +} +sub get_internal_firewall_ip_address +{ + my $subnet = shift; + my $use_orange = shift; + + my ($net_address, $net_mask) = split("/", $subnet); + if ((!$net_mask) || ($net_mask ~~ ["32", "255.255.255.255"])) { + return 0; + } + + # Convert net mask into correct format for &General::IpInSubnet(). + $net_mask = &General::iporsubtodec($net_mask); + + my @addresses = &get_internal_firewall_ip_addresses($use_orange); + foreach my $zone_address (@addresses) { + if (&General::IpInSubnet($zone_address, $net_address, $net_mask)) { + return $zone_address; + } + } + + return 0; +} return 1;