From 58b44880696316c046b99723ea4d36edfcf5b2ba Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Sun, 5 Mar 2017 19:05:10 +0100 Subject: [PATCH] (firewall) add port/address parsing to FilterRule(), should be backwards compatible with current config settings --- .../library/OPNsense/Firewall/FilterRule.php | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php b/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php index 6702afc1c..79efa40b7 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php +++ b/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php @@ -1,7 +1,7 @@ 'parseReplaceSimple,tcp/udp:{tcp udp},proto ', 'from' => 'parsePlain,from {,}', 'from_port' => 'parsePlain, port {,}', + 'os' => 'parsePlain, os {","}', 'to' => 'parsePlain,to {,}', 'to_port' => 'parsePlain, port {,}', 'icmp-type' => 'parsePlain,icmp-type {,}', @@ -176,6 +177,64 @@ class FilterRule return $retval; } + /** + * convert source/destination address entries as used by the gui + * @param array $rule rule + */ + private function convertAddress(&$rule) + { + $fields = array(); + $fields['source'] = 'from'; + $fields['destination'] = 'to'; + $interfaces = $this->interfaceMapping; + foreach ($fields as $tag => $target) { + if (!empty($rule[$tag])) { + if (isset($rule[$tag]['any'])) { + $rule[$target] = 'any'; + } elseif (!empty($rule[$tag]['network'])) { + $network_name = $rule[$tag]['network']; + $matches = ""; + if ($network_name == '(self)') { + $rule[$target] = "(self)"; + } elseif (preg_match("/^(wan|lan|opt[0-9]+)ip$/", $network_name, $matches)) { + if (!empty($interfaces[$matches[1]]['if'])) { + $rule[$target] = "({$interfaces["{$matches[1]}"]['if']})"; + } + } else { + if (!empty($interfaces[$network_name]['if'])) { + $rule[$target] = "({$interfaces[$network_name]['if']}:network)"; + } + } + } elseif (!empty($rule[$tag]['address'])) { + if (Util::isIpAddress($rule[$tag]['address']) || Util::isSubnet($rule[$tag]['address']) || + Util::isPort($rule[$tag]['address']) + ) { + $rule[$target] = $rule[$tag]['address']; + } elseif (Util::isAlias($rule[$tag]['address'])) { + $rule[$target] = '$'.$rule[$tag]['address']; + } + } + if (!empty($rule[$target]) && $rule[$target] != 'any' && isset($rule[$tag]['not'])) { + $rule[$target] = "!" . $rule[$target]; + } + if (isset($rule['protocol']) && in_array(strtolower($rule['protocol']), array("tcp","udp","tcp/udp"))) { + $port = str_replace('-', ':', $rule[$tag]['port']); + if (Util::isPort($port)) { + $rule[$target."_port"] = $port; + } elseif (Util::isAlias($port)) { + $rule[$target."_port"] = '$'.$port; + } + } + if (!isset($rule[$target])) { + // couldn't convert address, disable rule + // dump all tag contents in target (from/to) for reference + $rule['disabled'] = true; + $rule[$target] = json_encode($rule[$tag]); + } + } + } + } + /** * preprocess internal rule data to detail level of actual ruleset * handles shortcuts, like inet46 and multiple interfaces @@ -198,6 +257,7 @@ class FilterRule $tmp = $this->rule; $tmp['interface'] = $interface; $tmp['ipprotocol'] = $ipproto; + $this->convertAddress($tmp); $tmp['from'] = empty($tmp['from']) ? "any" : $tmp['from']; $tmp['to'] = empty($tmp['to']) ? "any" : $tmp['to']; // disable rule when interface not found