diff options
author | Renato Botelho <garga@FreeBSD.org> | 2014-10-28 14:26:51 -0200 |
---|---|---|
committer | Renato Botelho <garga@FreeBSD.org> | 2014-10-28 14:26:51 -0200 |
commit | 7c1997914f44783cfdff077bf0c9e017c37cbff2 (patch) | |
tree | eef9b5aff127ed203c327c19c4525dfca62379c8 /usr | |
parent | 143c22f7719836d5decee0da0ec52e61e79fd6a2 (diff) | |
parent | 577b776e556f68234d6657b210ec2d150a66d6e6 (diff) | |
download | pfsense-7c1997914f44783cfdff077bf0c9e017c37cbff2.zip pfsense-7c1997914f44783cfdff077bf0c9e017c37cbff2.tar.gz |
Merge pull request #1297 from phil-davis/patch-23
Diffstat (limited to 'usr')
-rwxr-xr-x | usr/local/www/firewall_aliases_edit.php | 176 | ||||
-rwxr-xr-x | usr/local/www/firewall_aliases_import.php | 5 |
2 files changed, 142 insertions, 39 deletions
diff --git a/usr/local/www/firewall_aliases_edit.php b/usr/local/www/firewall_aliases_edit.php index 9748c15..01d19b1 100755 --- a/usr/local/www/firewall_aliases_edit.php +++ b/usr/local/www/firewall_aliases_edit.php @@ -63,6 +63,7 @@ if (is_array($config['load_balancer']['lbpool'])) $reserved_ifs = get_configured_interface_list(false, true); $reserved_keywords = array_merge($reserved_keywords, $reserved_ifs, $reserved_table_names); +$max_alias_addresses = 5000; if (!is_array($config['aliases']['alias'])) $config['aliases']['alias'] = array(); @@ -202,7 +203,7 @@ if ($_POST) { $desc_fmt_err_found = false; /* item is a url type */ - for($x=0; $x<4999; $x++) { + for($x=0; $x<$max_alias_addresses-1; $x++) { $_POST['address' . $x] = trim($_POST['address' . $x]); if($_POST['address' . $x]) { /* fetch down and add in */ @@ -280,53 +281,152 @@ if ($_POST) { /* item is a normal alias type */ $wrongaliases = ""; $desc_fmt_err_found = false; - for($x=0; $x<4999; $x++) { + $alias_address_count = 0; + + // First trim and expand the input data. + // Users can paste strings like "10.1.2.0/24 10.3.0.0/16 9.10.11.0/24" into an address box. + // They can also put an IP range. + // This loop expands out that stuff so it can easily be validated. + for($x=0; $x<($max_alias_addresses-1); $x++) { if($_POST["address{$x}"] <> "") { - $_POST["address{$x}"] = trim($_POST["address{$x}"]); - if (is_alias($_POST["address{$x}"])) { - if (!alias_same_type($_POST["address{$x}"], $_POST['type'])) - // But alias type network can include alias type urltable. Feature#1603. - if (!($_POST['type'] == 'network' && - preg_match("/urltable/i", alias_get_type($_POST["address{$x}"])))) - $wrongaliases .= " " . $_POST["address{$x}"]; - } else if ($_POST['type'] == "port") { - if (!is_port($_POST["address{$x}"]) && !is_portrange($_POST["address{$x}"])) - $input_errors[] = $_POST["address{$x}"] . " " . gettext("is not a valid port or alias."); - } else if ($_POST['type'] == "host" || $_POST['type'] == "network") { - if (is_subnet($_POST["address{$x}"]) || (!is_ipaddr($_POST["address{$x}"]) - && !is_hostname($_POST["address{$x}"]) - && !is_iprange($_POST["address{$x}"]))) - $input_errors[] = sprintf(gettext('%1$s is not a valid %2$s alias.'), $_POST["address{$x}"], $_POST['type']); - } - if (is_iprange($_POST["address{$x}"])) { - list($startip, $endip) = explode('-', $_POST["address{$x}"]); - $rangesubnets = ip_range_to_subnet_array($startip, $endip); - $address = array_merge($address, $rangesubnets); - } else { - $tmpaddress = $_POST["address{$x}"]; - if($_POST['type'] != "host" && is_ipaddr($_POST["address{$x}"]) && $_POST["address_subnet{$x}"] <> "") { - if (!is_subnet($_POST["address{$x}"] . "/" . $_POST["address_subnet{$x}"])) - $input_errors[] = sprintf(gettext('%s/%s is not a valid subnet.'), $_POST["address{$x}"], $_POST["address_subnet{$x}"]); - else - $tmpaddress .= "/" . $_POST["address_subnet{$x}"]; - } - $address[] = $tmpaddress; - } if ($_POST["detail{$x}"] <> "") { if ((strpos($_POST["detail{$x}"], "||") === false) && (substr($_POST["detail{$x}"], 0, 1) != "|") && (substr($_POST["detail{$x}"], -1, 1) != "|")) { - $final_address_details[] = $_POST["detail{$x}"]; + $detail_text = $_POST["detail{$x}"]; } else { /* Remove leading and trailing vertical bars and replace multiple vertical bars with single, */ /* and put in the output array so the text is at least redisplayed for the user. */ - $final_address_details[] = preg_replace('/\|\|+/', '|', trim($_POST["detail{$x}"], "|")); + $detail_text = preg_replace('/\|\|+/', '|', trim($_POST["detail{$x}"], "|")); if (!$desc_fmt_err_found) { $input_errors[] = $vertical_bar_err_text; $desc_fmt_err_found = true; } } - } else - $final_address_details[] = sprintf(gettext("Entry added %s"), date('r')); + } else { + $detail_text = sprintf(gettext("Entry added %s"), date('r')); + } + $address_items = explode(" ", trim($_POST["address{$x}"])); + foreach ($address_items as $address_item) { + $iprange_type = is_iprange($address_item); + if ($iprange_type == 4) { + list($startip, $endip) = explode('-', $address_item); + if ($_POST['type'] == "network") { + // For network type aliases, expand an IPv4 range into an array of subnets. + $rangesubnets = ip_range_to_subnet_array($startip, $endip); + foreach ($rangesubnets as $rangesubnet) { + if ($alias_address_count > $max_alias_addresses) { + break; + } + list($address_part, $subnet_part) = explode("/", $rangesubnet); + $input_addresses[] = $address_part; + $input_address_subnet[] = $subnet_part; + $final_address_details[] = $detail_text; + $alias_address_count++; + } + } else { + // For host type aliases, expand an IPv4 range into a list of individual IPv4 addresses. + $rangeaddresses = ip_range_to_address_array($startip, $endip, $max_alias_addresses - $alias_address_count); + if (is_array($rangeaddresses)) { + foreach ($rangeaddresses as $rangeaddress) { + $input_addresses[] = $rangeaddress; + $input_address_subnet[] = ""; + $final_address_details[] = $detail_text; + $alias_address_count++; + } + } else { + $input_errors[] = sprintf(gettext('Range is too large to expand into individual host IP addresses (%s)'), $address_item); + $input_errors[] = sprintf(gettext('The maximum number of entries in an alias is %s'), $max_alias_addresses); + // Put the user-entered data in the output anyway, so it will be re-displayed for correction. + $input_addresses[] = $address_item; + $input_address_subnet[] = ""; + $final_address_details[] = $detail_text; + } + } + } else if ($iprange_type == 6) { + $input_errors[] = sprintf(gettext('IPv6 address ranges are not supported (%s)'), $address_item); + // Put the user-entered data in the output anyway, so it will be re-displayed for correction. + $input_addresses[] = $address_item; + $input_address_subnet[] = ""; + $final_address_details[] = $detail_text; + } else { + $subnet_type = is_subnet($address_item); + if (($_POST['type'] == "host") && $subnet_type) { + if ($subnet_type == 4) { + // For host type aliases, if the user enters an IPv4 subnet, expand it into a list of individual IPv4 addresses. + if (subnet_size($address_item) <= ($max_alias_addresses - $alias_address_count)) { + $rangeaddresses = subnetv4_expand($address_item); + foreach ($rangeaddresses as $rangeaddress) { + $input_addresses[] = $rangeaddress; + $input_address_subnet[] = ""; + $final_address_details[] = $detail_text; + $alias_address_count++; + } + } else { + $input_errors[] = sprintf(gettext('Subnet is too large to expand into individual host IP addresses (%s)'), $address_item); + $input_errors[] = sprintf(gettext('The maximum number of entries in an alias is %s'), $max_alias_addresses); + // Put the user-entered data in the output anyway, so it will be re-displayed for correction. + $input_addresses[] = $address_item; + $input_address_subnet[] = ""; + $final_address_details[] = $detail_text; + } + } else { + $input_errors[] = sprintf(gettext('IPv6 subnets are not supported in host aliases (%s)'), $address_item); + // Put the user-entered data in the output anyway, so it will be re-displayed for correction. + $input_addresses[] = $address_item; + $input_address_subnet[] = ""; + $final_address_details[] = $detail_text; + } + } else { + list($address_part, $subnet_part) = explode("/", $address_item); + if (!empty($subnet_part)) { + if (is_subnet($address_item)) { + $input_addresses[] = $address_part; + $input_address_subnet[] = $subnet_part; + } else { + // The user typed something like "1.2.3.444/24" or "1.2.3.0/36" or similar rubbish. + // Feed it through without splitting it apart, then it will be caught by the validation loop below. + $input_addresses[] = $address_item; + $input_address_subnet[] = ""; + } + } else { + $input_addresses[] = $address_part; + $input_address_subnet[] = $_POST["address_subnet{$x}"]; + } + $final_address_details[] = $detail_text; + $alias_address_count++; + } + } + if ($alias_address_count > $max_alias_addresses) { + $input_errors[] = sprintf(gettext('The maximum number of entries in an alias has been exceeded (%s)'), $max_alias_addresses); + break; + } + } + } + } + + // Validate the input data expanded above. + foreach($input_addresses as $idx => $input_address) { + if (is_alias($input_address)) { + if (!alias_same_type($input_address, $_POST['type'])) + // But alias type network can include alias type urltable. Feature#1603. + if (!($_POST['type'] == 'network' && + preg_match("/urltable/i", alias_get_type($input_address)))) + $wrongaliases .= " " . $input_address; + } else if ($_POST['type'] == "port") { + if (!is_port($input_address) && !is_portrange($input_address)) + $input_errors[] = $input_address . " " . gettext("is not a valid port or alias."); + } else if ($_POST['type'] == "host" || $_POST['type'] == "network") { + if (is_subnet($input_address) || + (!is_ipaddr($input_address) && !is_hostname($input_address))) + $input_errors[] = sprintf(gettext('%1$s is not a valid %2$s address, FQDN or alias.'), $input_address, $_POST['type']); + } + $tmpaddress = $input_address; + if ($_POST['type'] != "host" && is_ipaddr($input_address) && $input_address_subnet[$idx] <> "") { + if (!is_subnet($input_address . "/" . $input_address_subnet[$idx])) + $input_errors[] = sprintf(gettext('%s/%s is not a valid subnet.'), $input_address, $input_address_subnet[$idx]); + else + $tmpaddress .= "/" . $input_address_subnet[$idx]; } + $address[] = $tmpaddress; } unset($desc_fmt_err_found); if ($wrongaliases <> "") @@ -491,7 +591,7 @@ $urltable_ports_str = gettext("URL Table (Ports)"); $update_freq_str = gettext("Update Freq. (days)"); $networks_help = gettext("Networks are specified in CIDR format. Select the CIDR mask that pertains to each entry. /32 specifies a single IPv4 host, /128 specifies a single IPv6 host, /24 specifies 255.255.255.0, /64 specifies a normal IPv6 network, etc. Hostnames (FQDNs) may also be specified, using a /32 mask for IPv4 or /128 for IPv6. You may also enter an IP range such as 192.168.1.1-192.168.1.254 and a list of CIDR networks will be derived to fill the range."); -$hosts_help = gettext("Enter as many hosts as you would like. Hosts must be specified by their IP address or fully qualified domain name (FQDN). FQDN hostnames are periodically re-resolved and updated. If multiple IPs are returned by a DNS query, all are used."); +$hosts_help = gettext("Enter as many hosts as you would like. Hosts must be specified by their IP address or fully qualified domain name (FQDN). FQDN hostnames are periodically re-resolved and updated. If multiple IPs are returned by a DNS query, all are used. You may also enter an IP range such as 192.168.1.1-192.168.1.10 or a small subnet such as 192.168.1.16/28 and a list of individual IP addresses will be generated."); $ports_help = gettext("Enter as many ports as you wish. Port ranges can be expressed by separating with a colon."); $url_help = sprintf(gettext("Enter as many URLs as you wish. After saving %s will download the URL and import the items into the alias. Use only with small sets of IP addresses (less than 3000)."), $g['product_name']); $url_ports_help = sprintf(gettext("Enter as many URLs as you wish. After saving %s will download the URL and import the items into the alias. Use only with small sets of Ports (less than 3000)."), $g['product_name']); @@ -703,7 +803,7 @@ if (empty($tab)) { $addresses = explode(" ", $pconfig['address']); $details = explode("||", $pconfig['detail']); while ($counter < count($addresses)): - if (is_subnet($addresses[$counter])) { + if (($pconfig['type'] != "host") && is_subnet($addresses[$counter])) { list($address, $address_subnet) = explode("/", $addresses[$counter]); } else { $address = $addresses[$counter]; diff --git a/usr/local/www/firewall_aliases_import.php b/usr/local/www/firewall_aliases_import.php index f744441..f7c259e 100755 --- a/usr/local/www/firewall_aliases_import.php +++ b/usr/local/www/firewall_aliases_import.php @@ -101,12 +101,15 @@ if($_POST['aliasimport'] <> "") { $impdesc = trim($implinea[1]); if (strlen($impdesc) < 200) { if ((strpos($impdesc, "||") === false) && (substr($impdesc, 0, 1) != "|") && (substr($impdesc, -1, 1) != "|")) { - if (is_iprange($impip)) { + $iprange_type = is_iprange($impip); + if ($iprange_type == 4) { list($startip, $endip) = explode('-', $impip); $rangesubnets = ip_range_to_subnet_array($startip, $endip); $imported_ips = array_merge($imported_ips, $rangesubnets); $rangedescs = array_fill(0, count($rangesubnets), $impdesc); $imported_descs = array_merge($imported_descs, $rangedescs); + } else if ($iprange_type == 6) { + $input_errors[] = sprintf(gettext('IPv6 address ranges are not supported (%s)'), $impip); } else if (!is_ipaddr($impip) && !is_subnet($impip) && !is_hostname($impip) && !empty($impip)) { $input_errors[] = sprintf(gettext("%s is not an IP address. Please correct the error to continue"), $impip); } elseif (!empty($impip)) { |