diff options
author | Renato Botelho <renato@netgate.com> | 2017-03-27 14:20:29 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2017-03-27 14:20:29 -0300 |
commit | 74d259a6e897a49bcf728843600587bd2ea035f2 (patch) | |
tree | 609770957666e7bebf0710f5e5f96e4d4ccac7d9 | |
parent | 02c3646f36f84bfe1a65c54c38a05e100e8abd44 (diff) | |
parent | 7e50d1e7357e4b9dc8a4283971c8bfe0312c5d8b (diff) | |
download | pfsense-74d259a6e897a49bcf728843600587bd2ea035f2.zip pfsense-74d259a6e897a49bcf728843600587bd2ea035f2.tar.gz |
Merge pull request #3670 from phil-davis/handle-empty-port-alias
-rw-r--r-- | src/etc/inc/filter.inc | 67 | ||||
-rw-r--r-- | src/etc/inc/pfsense-utils.inc | 2 | ||||
-rw-r--r-- | src/etc/inc/util.inc | 12 | ||||
-rw-r--r-- | src/usr/local/www/firewall_aliases_edit.php | 2 | ||||
-rw-r--r-- | src/usr/local/www/firewall_aliases_import.php | 2 | ||||
-rw-r--r-- | src/usr/local/www/firewall_nat_out_edit.php | 6 |
6 files changed, 64 insertions, 27 deletions
diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc index c2e2a25..7f64540 100644 --- a/src/etc/inc/filter.inc +++ b/src/etc/inc/filter.inc @@ -587,7 +587,20 @@ function filter_generate_scrubing() { return $scrubrules; } -function filter_generate_nested_alias($name, $alias, &$aliasnesting, &$aliasaddrnesting, &$use_filterdns = false) { +function filter_generate_nested_alias($name) { + global $aliastable; + + $aliasnesting = array(); + $aliasaddrnesting = array(); + + if (($name == "") || !isset($aliastable[$name])) { + return ""; + } + + return filter_generate_nested_alias_recurse($name, $aliastable[$name], $aliasnesting, $aliasaddrnesting); +} + +function filter_generate_nested_alias_recurse($name, $alias, &$aliasnesting, &$aliasaddrnesting, &$use_filterdns = false) { global $aliastable, $filterdns; $addresses = explode(" ", $alias); @@ -604,7 +617,7 @@ function filter_generate_nested_alias($name, $alias, &$aliasnesting, &$aliasaddr $tmpline = ""; if (is_alias($address)) { if (alias_get_type($address) == 'urltable') { - // Feature#1603. For this type of alias we do not need to recursively call filter_generate_nested_alias. Just load IPs from the file. + // Feature#1603. For this type of alias we do not need to recursively call filter_generate_nested_alias_recurse. Just load IPs from the file. $urltable_nesting = alias_expand_urltable($address); if (!empty($urltable_nesting)) { $urlfile_as_arr = file($urltable_nesting); @@ -620,10 +633,10 @@ function filter_generate_nested_alias($name, $alias, &$aliasnesting, &$aliasaddr } /* We already expanded this alias so there is no necessity to do it again. */ else if (!isset($aliasnesting[$address])) { - $tmpline = filter_generate_nested_alias($name, $aliastable[$address], $aliasnesting, $aliasaddrnesting, $use_filterdns); + $tmpline = filter_generate_nested_alias_recurse($name, $aliastable[$address], $aliasnesting, $aliasaddrnesting, $use_filterdns); } } else if (!isset($aliasaddrnesting[$address])) { - if (!is_ipaddr($address) && !is_subnet($address) && !((($alias_type == 'port') || ($alias_type == 'url_ports')) && (is_port($address) || is_portrange($address))) && is_hostname($address)) { + if (!is_ipaddr($address) && !is_subnet($address) && !((($alias_type == 'port') || ($alias_type == 'url_ports')) && is_portorrange($address)) && is_hostname($address)) { if (!isset($filterdns["{$address}{$name}"])) { $use_filterdns = true; $filterdns["{$address}{$name}"] = "pf {$address} {$name}\n"; @@ -664,9 +677,7 @@ function filter_expand_alias($alias_name) { if (isset($config['aliases']['alias'])) { foreach ($config['aliases']['alias'] as $aliased) { if ($aliased['name'] == $alias_name) { - $aliasnesting = array(); - $aliasaddrnesting = array(); - return filter_generate_nested_alias($aliased['name'], $aliased['address'], $aliasnesting, $aliasaddrnesting); + return filter_generate_nested_alias($aliased['name']); } } } @@ -750,14 +761,12 @@ function filter_generate_aliases() { /* Setup pf groups */ if (isset($config['aliases']['alias'])) { foreach ($config['aliases']['alias'] as $aliased) { - $aliasnesting = array(); - $aliasaddrnesting = array(); if (is_numericint($aliased['name'])) { // skip aliases with numeric-only names. redmine #4289 file_notice("Filter_Reload", sprintf(gettext("Aliases with numeric-only names are not valid. Skipping alias %s"), $aliased['name'])); continue; } - $addrlist = filter_generate_nested_alias($aliased['name'], $aliased['address'], $aliasnesting, $aliasaddrnesting); + $addrlist = filter_generate_nested_alias($aliased['name']); switch ($aliased['type']) { case "host": case "network": @@ -2701,18 +2710,36 @@ function filter_generate_user_rule($rule) { return "# {$error_text}"; } if ($rule['source']['port'] - && !(is_portrange(str_replace("-", ":", $rule['source']['port'])) - || alias_expand($rule['source']['port']))) { - $error_text = sprintf(gettext("Unresolvable source port alias '%1\$s' for rule '%2\$s'"), $rule['source']['port'], $rule['descr']); - file_notice("Filter_Reload", $error_text); - return "# {$error_text}"; + && !is_portorrange(str_replace("-", ":", $rule['source']['port']))) { + $error_text = ""; + + // It is not a literal port or port range, so alias should exist, and expand to something non-empty + if (!alias_expand($rule['source']['port'])) { + $error_text = sprintf(gettext("Unresolvable source port alias '%1\$s' for rule '%2\$s'"), $rule['source']['port'], $rule['descr']); + } else if (trim(filter_generate_nested_alias($rule['source']['port'])) == "") { + $error_text = sprintf(gettext("Empty source port alias '%1\$s' for rule '%2\$s'"), $rule['source']['port'], $rule['descr']); + } + + if ($error_text) { + file_notice("Filter_Reload", $error_text); + return "# {$error_text}"; + } } if ($rule['destination']['port'] - && !(is_portrange(str_replace("-", ":", $rule['destination']['port'])) - || alias_expand($rule['destination']['port']))) { - $error_text = sprintf(gettext("Unresolvable destination port alias '%1\$s' for rule '%2\$s'"), $rule['destination']['port'], $rule['descr']); - file_notice("Filter_Reload", $error_text); - return "# {$error_text}"; + && !is_portorrange(str_replace("-", ":", $rule['destination']['port']))) { + $error_text = ""; + + // It is not a literal port or port range, so alias should exist, and expand to something non-empty + if (!alias_expand($rule['destination']['port'])) { + $error_text = sprintf(gettext("Unresolvable destination port alias '%1\$s' for rule '%2\$s'"), $rule['destination']['port'], $rule['descr']); + } else if (trim(filter_generate_nested_alias($rule['destination']['port'])) == "") { + $error_text = sprintf(gettext("Empty destination port alias '%1\$s' for rule '%2\$s'"), $rule['destination']['port'], $rule['descr']); + } + + if ($error_text) { + file_notice("Filter_Reload", $error_text); + return "# {$error_text}"; + } } update_filter_reload_status(gettext("Setting up pass/block rules")); $type = $rule['type']; diff --git a/src/etc/inc/pfsense-utils.inc b/src/etc/inc/pfsense-utils.inc index 3e9767e..83b2f5a 100644 --- a/src/etc/inc/pfsense-utils.inc +++ b/src/etc/inc/pfsense-utils.inc @@ -2153,7 +2153,7 @@ function parse_aliases_file($filename, $type = "url", $max_items = -1, $kflc = f $tmp = $tmp_str; } $valid = (($type == "url" || $type == "urltable") && (is_ipaddr($tmp) || is_subnet($tmp))) || - (($type == "url_ports" || $type == "urltable_ports") && (is_port($tmp) || is_portrange($tmp))); + (($type == "url_ports" || $type == "urltable_ports") && is_portorrange($tmp)); if ($valid) { $items[] = $tmp; if (count($items) == $max_items) { diff --git a/src/etc/inc/util.inc b/src/etc/inc/util.inc index 4440bdc..76410b4 100644 --- a/src/etc/inc/util.inc +++ b/src/etc/inc/util.inc @@ -1124,6 +1124,11 @@ function is_portrange($portrange) { return (count($ports) == 2 && is_port($ports[0]) && is_port($ports[1])); } +/* returns true if $port is a valid TCP/UDP port number or range ("<port>:<port>") */ +function is_portorrange($port) { + return (is_port($port) || is_portrange($port)); +} + /* returns true if $port is a valid port number or an alias thereof */ function is_portoralias($port) { global $config; @@ -1142,6 +1147,11 @@ function is_portoralias($port) { } } +/* returns true if $port is a valid TCP/UDP port number or range ("<port>:<port>") or an alias thereof */ +function is_portorrangeoralias($port) { + return (is_portoralias($port) || is_portrange($port)); +} + /* create ranges of sequential port numbers (200:215) and remove duplicates */ function group_ports($ports, $kflc = false) { if (!is_array($ports) || empty($ports)) { @@ -1781,7 +1791,7 @@ function alias_expand($name) { } } return "\${$name}"; - } else if (is_ipaddr($name) || is_subnet($name) || is_port($name) || is_portrange($name)) { + } else if (is_ipaddr($name) || is_subnet($name) || is_portorrange($name)) { return "{$name}"; } else { return null; diff --git a/src/usr/local/www/firewall_aliases_edit.php b/src/usr/local/www/firewall_aliases_edit.php index de2d201..c73aa3b 100644 --- a/src/usr/local/www/firewall_aliases_edit.php +++ b/src/usr/local/www/firewall_aliases_edit.php @@ -429,7 +429,7 @@ if ($_POST['save']) { } } } else if ($_POST['type'] == "port") { - if (!is_port($input_address) && !is_portrange($input_address)) { + if (!is_portorrange($input_address)) { $input_errors[] = sprintf(gettext("%s is not a valid port or alias."), $input_address); } } else if ($_POST['type'] == "host" || $_POST['type'] == "network") { diff --git a/src/usr/local/www/firewall_aliases_import.php b/src/usr/local/www/firewall_aliases_import.php index 1350eeb..a8c02aa 100644 --- a/src/usr/local/www/firewall_aliases_import.php +++ b/src/usr/local/www/firewall_aliases_import.php @@ -121,7 +121,7 @@ if ($_POST) { if ($tab == "port") { // Port alias if (!empty($impip)) { - if (is_port($impip) || is_portrange($impip)) { + if (is_portorrange($impip)) { $imported_ips[] = $impip; $imported_descs[] = $impdesc; } else { diff --git a/src/usr/local/www/firewall_nat_out_edit.php b/src/usr/local/www/firewall_nat_out_edit.php index 786188d..d4f2308 100644 --- a/src/usr/local/www/firewall_nat_out_edit.php +++ b/src/usr/local/www/firewall_nat_out_edit.php @@ -189,15 +189,15 @@ if ($_POST['save']) { $_POST['target'] = substr($_POST['target'], 1); } - if ($protocol_uses_ports && $_POST['sourceport'] <> "" && !(is_portoralias($_POST['sourceport']) || is_portrange($_POST['sourceport']))) { + if ($protocol_uses_ports && $_POST['sourceport'] <> "" && !is_portorrangeoralias($_POST['sourceport'])) { $input_errors[] = gettext("A valid port or port alias must be supplied for the source port entry."); } - if ($protocol_uses_ports && $_POST['dstport'] <> "" && !(is_portoralias($_POST['dstport']) || is_portrange($_POST['dstport']))) { + if ($protocol_uses_ports && $_POST['dstport'] <> "" && !is_portorrangeoralias($_POST['dstport'])) { $input_errors[] = gettext("A valid port or port alias must be supplied for the destination port entry."); } - if ($protocol_uses_ports && $_POST['natport'] <> "" && !(is_portoralias($_POST['natport']) || is_portrange($_POST['natport'])) && !isset($_POST['nonat'])) { + if ($protocol_uses_ports && $_POST['natport'] <> "" && !is_portorrangeoralias($_POST['natport']) && !isset($_POST['nonat'])) { $input_errors[] = gettext("A valid port must be supplied for the NAT port entry."); } |