(firewall) add port/address parsing to FilterRule(), should be backwards compatible with current config settings

This commit is contained in:
Ad Schellevis 2017-03-05 19:05:10 +01:00
parent 3e47ec946a
commit 58b4488069

View File

@ -1,7 +1,7 @@
<?php
/**
* Copyright (C) 2016 Deciso B.V.
* Copyright (C) 2016-2017 Deciso B.V.
*
* All rights reserved.
*
@ -49,6 +49,7 @@ class FilterRule
'protocol' => '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