diff --git a/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php b/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php new file mode 100644 index 000000000..b42751a4e --- /dev/null +++ b/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php @@ -0,0 +1,151 @@ + 'parseIsComment', + 'type' => 'parseType', + 'ipprotocol' => 'parsePlain', + 'interface' => 'parseInterface' + ); + + /** + * output parsing + * @param string $value field value + * @return string + */ + private function parseIsComment($value) + { + return !empty($value) ? "#" : ""; + } + + /** + * parse plain data + * @param string $value field value + * @return string + */ + private function parsePlain($value) + { + return empty($value) ? "" : $value . " "; + } + + /** + * parse type + * @param string $value field value + * @return string + */ + private function parseType($value) + { + switch ($value) { + case 'reject': + $type = 'block return'; + break; + default: + $type = $value; + } + return empty($type) ? "pass " : $type . " "; + } + + /** + * parse interface (name to interface) + * @param string $value field value + * @return string + */ + private function parseInterface($value) + { + if (empty($this->interfaceMapping[$value]['if'])) { + return "##{$value}##"; + } else { + return $this->interfaceMapping[$value]['if']." "; + } + } + + /** + * preprocess internal rule data to detail level of actual ruleset + * handles shortcuts, like inet46 and multiple interfaces + * @return array + */ + private function fetchActualRules() + { + $result = array(); + $interfaces = empty($this->rule['interface']) ? array(null) : explode(',', $this->rule['interface']); + foreach ($interfaces as $interface) { + if (isset($this->rule['ipprotocol']) && $this->rule['ipprotocol'] == 'inet46') { + foreach (array('inet', 'inet6') as $ipproto) { + $tmp = $this->rule; + $tmp['interface'] = $interface; + $tmp['ipprotocol'] = $ipproto; + $result[] = $tmp; + } + } else { + $tmp = $this->rule; + $tmp['interface'] = $interface; + $result[] = $this->rule; + } + } + return $result; + } + + /** + * init FilterRule + * @param array $interfaceMapping internal interface mapping + * @param array $conf rule configuration + */ + public function __construct(&$interfaceMapping, $conf) + { + $this->interfaceMapping = $interfaceMapping; + $this->rule = $conf; + } + + /** + * output rule as string + * @return string ruleset + */ + public function __toString() + { + $ruleTxt = ''; + foreach ($this->fetchActualRules() as $rule) { + foreach ($this->procorder as $tag => $handle) { + $ruleTxt .= $this->$handle(isset($rule[$tag]) ? $rule[$tag] : null); + } + $ruleTxt .= "\n"; + } + return $ruleTxt; + } +} diff --git a/src/opnsense/mvc/app/library/OPNsense/Firewall/Plugin.php b/src/opnsense/mvc/app/library/OPNsense/Firewall/Plugin.php index 31309b0bc..c130eb0c4 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Firewall/Plugin.php +++ b/src/opnsense/mvc/app/library/OPNsense/Firewall/Plugin.php @@ -36,19 +36,32 @@ namespace OPNsense\Firewall; class Plugin { private $anchors = array(); + private $filterRules = array(); + private $interfaceMapping ; /** * init firewall plugin component */ public function __construct() { + $this->interfaceMapping = array(); + } + + /** + * set interface mapping to USE + * @param array $mapping named array + */ + public function setInterfaceMapping(&$mapping) + { + $this->interfaceMapping = $mapping; } /** * register anchor - * @param $name anchor name - * @param $type anchor type (fw for filter, other options are nat,rdr,binat) - * @param $priority sort order from low to high + * @param string $name anchor name + * @param string $type anchor type (fw for filter, other options are nat,rdr,binat) + * @param string $priority sort order from low to high + * @param string $placement placement head,tail * @return null */ public function registerAnchor($name, $type="fw", $priority=0, $placement="tail") @@ -60,8 +73,8 @@ class Plugin /** * fetch anchors as text (pf ruleset part) - * @param $types anchor types (fw for filter, other options are nat,rdr,binat. comma seperated) - * @param $priority sort order from low to high + * @param string $types anchor types (fw for filter, other options are nat,rdr,binat. comma seperated) + * @param string $placement placement head,tail * @return string */ public function anchorToText($types="fw", $placement="tail") @@ -77,4 +90,34 @@ class Plugin } return $result; } + + /** + * register a filter rule + * @param int $prio priority + * @param array $conf configuration + */ + public function registerFilterRule($prio, $conf) + { + $rule = new FilterRule($this->interfaceMapping, $conf); + if (empty($this->filterRules[$prio])) { + $this->filterRules[$prio] = array(); + } + $this->filterRules[$prio][] = $rule; + } + + /** + * filter rules to text + * @return string + */ + public function outputFilterRules() + { + $output = ""; + ksort($this->filterRules); + foreach ($this->filterRules as $prio => $ruleset) { + foreach ($ruleset as $rule) { + $output .= (string)$rule; + } + } + return $output; + } }