(filter) work in progress filter refactoring

This commit is contained in:
Ad Schellevis 2016-10-24 21:48:02 +02:00
parent 84d6d43b7a
commit aca6eb44ba
2 changed files with 199 additions and 5 deletions

View File

@ -0,0 +1,151 @@
<?php
/**
* Copyright (C) 2016 Deciso B.V.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
namespace OPNsense\Firewall;
/**
* Class FilterRule
* @package OPNsense\Firewall
*/
class FilterRule
{
private $rule = array();
private $interfaceMapping = array();
private $procorder = array(
'disabled' => '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;
}
}

View File

@ -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;
}
}