Firewall: Rules: Floating - add "Interface / Invert" to the list, which will invert the "on" clause of the rule. To prevent future tickets when selecting multiple interfaces and invert, we'll add a validation to only allow single inverts.

When multiple interfaces are selected, these will render into separate rules in which case it might not be clear what the outcome would be, specifically when choosing something else than "pass" (pass lan,wan would lead to two rules which match either lan or wan, block lan, wan would lead to random behavior for example).

For https://github.com/opnsense/core/issues/6902
This commit is contained in:
Ad Schellevis 2023-10-02 14:36:28 +02:00
parent a10cf1c402
commit be0b18930f
3 changed files with 34 additions and 1 deletions

View File

@ -326,6 +326,9 @@ abstract class Rule
*/
protected function parseInterface($value, $prefix = "on ", $suffix = "")
{
if (!empty($this->rule['interfacenot'])) {
$prefix = "{$prefix} ! ";
}
if (empty($value)) {
return "";
} elseif (empty($this->interfaceMapping[$value]['if'])) {

View File

@ -757,12 +757,17 @@ $( document ).ready(function() {
if (empty($ifgroups) && $rule->ruleOrigin() == 'group'){
// group view, skip group section (groups can't be nested)
$is_selected = false;
} elseif ($rule->getInterface() == $selected_if) {
} elseif ($rule->getInterface() == $selected_if && empty($rule->getRawRule()['interfacenot'])) {
// interface view and this interface is selected
$is_selected = true;
} elseif ($selected_if == "FloatingRules" && $rule->ruleOrigin() == 'floating') {
// floating view, skip floating
$is_selected = false;
} elseif (!empty($rule->getRawRule()['interfacenot'])) {
// inverted interface, all but selected
if (!in_array($selected_if, explode(',', $rule->getInterface()))) {
$is_selected = true;
}
} elseif (($rule->getInterface() == "" || strpos($rule->getInterface(), ",") !== false) && $selected_if == "FloatingRules") {
// floating type of rule and "floating" view
$is_selected = true;
@ -832,6 +837,7 @@ $( document ).ready(function() {
<?=$intf_count;?>
</a>
<?php elseif ($intf_count != '1' || $selected_if == 'FloatingRules'): ?>
<?= !empty($rule->getRawRule()['interfacenot']) ? '!' : '';?>
<a style="cursor: pointer;" class='interface_tooltip' data-interfaces="<?=$rule->getInterface();?>">
<?=$intf_count;?>
</a>
@ -970,6 +976,7 @@ $( document ).ready(function() {
<?=$intf_count;?>
</a>
<?php elseif ($intf_count != '1' || $selected_if == 'FloatingRules'): ?>
<?= !empty($filterent['interfacenot']) ? '!' : '';?>
<a style="cursor: pointer;" class='interface_tooltip' data-interfaces="<?=$filterent['interface'];?>">
<?=$intf_count;?>
</a>

View File

@ -102,6 +102,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
'gateway',
'icmptype',
'icmp6-type',
'interfacenot',
'interface',
'ipprotocol',
'log',
@ -217,6 +218,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if (!empty($pconfig['interfacenot']) && (
(is_array($pconfig['interface']) && count($pconfig['interface']) != 1 ) || empty($pconfig['interface']))
) {
$input_errors[] = gettext("Inverting interfaces is only allowed for single targets to avoid mis-interpretations");
}
if ($pconfig['ipprotocol'] == "inet46" && !empty($pconfig['gateway'])) {
$input_errors[] = gettext("You can not assign a gateway to a rule that applies to IPv4 and IPv6");
}
@ -475,6 +482,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
}
$filterent['interfacenot'] = !empty($pconfig['interfacenot']);
// allow 0 in adaptive timeouts
if (is_numericint($pconfig['adaptivestart']) && is_numericint($pconfig['adaptiveend'])) {
$filterent['adaptivestart'] = $pconfig['adaptivestart'];
@ -851,6 +860,20 @@ include("head.inc");
</tr>
<?php
endif; ?>
<?php
if (!empty($pconfig['floating'])): ?>
<tr>
<td><a id="help_for_interfacenot" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Interface / Invert");?></td>
<td>
<input name="interfacenot" type="checkbox" <?= !empty($pconfig['interfacenot']) ? "checked=\"checked\"" : "";?> />
<?= gettext('Use this option to invert the sense of the match.') ?>
<div class="hidden" data-for="help_for_interfacenot">
<?=gettext('Use all but selected interfaces');?>
</div>
</td>
</tr>
<?php
endif;?>
<tr>
<td><a id="help_for_interface" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Interface");?></td>
<td>