mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-14 00:24:40 +00:00
Firewall: Rules - allow multiple options in source/destination address fields.
o merge src+srcmask, dst+dstmask into a single field o remove current clunky input and re-use the same javascript hooks as in MVC o re-use OPNsense\Firewall\Api\FilterController to list available options
This commit is contained in:
parent
918ba63bb5
commit
0dac1d6201
@ -86,6 +86,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
} elseif (isset($_GET['id']) && isset($a_filter[$_GET['id']])) {
|
||||
$id = $_GET['id'];
|
||||
$configId = $id;
|
||||
} elseif (isset($_GET['get_address_options'])) {
|
||||
/* XXX: no beauty contest here, we need the same valid options as MVC, just dump them... */
|
||||
echo json_encode((new OPNsense\Firewall\Api\FilterController())->listNetworkSelectOptionsAction());
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// define form fields
|
||||
@ -149,12 +153,26 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$pconfig['category'] = !empty($pconfig['category']) ? explode(",", $pconfig['category']) : [];
|
||||
|
||||
// process fields with some kind of logic
|
||||
address_to_pconfig($a_filter[$configId]['source'], $pconfig['src'],
|
||||
$pconfig['srcmask'], $pconfig['srcnot'],
|
||||
$pconfig['srcbeginport'], $pconfig['srcendport']);
|
||||
address_to_pconfig($a_filter[$configId]['destination'], $pconfig['dst'],
|
||||
$pconfig['dstmask'], $pconfig['dstnot'],
|
||||
$pconfig['dstbeginport'], $pconfig['dstendport']);
|
||||
address_to_pconfig(
|
||||
$a_filter[$configId]['source'],
|
||||
$pconfig['src'],
|
||||
$ignore, /* XXX: ignored */
|
||||
$pconfig['srcnot'],
|
||||
$pconfig['srcbeginport'],
|
||||
$pconfig['srcendport'],
|
||||
true
|
||||
);
|
||||
|
||||
address_to_pconfig(
|
||||
$a_filter[$configId]['destination'],
|
||||
$pconfig['dst'],
|
||||
$ignore, /* XXX: ignored */
|
||||
$pconfig['dstnot'],
|
||||
$pconfig['dstbeginport'],
|
||||
$pconfig['dstendport'],
|
||||
true
|
||||
);
|
||||
|
||||
if (isset($id) && isset($a_filter[$configId]['associated-rule-id'])) {
|
||||
// do not link on rule copy.
|
||||
$pconfig['associated-rule-id'] = $a_filter[$configId]['associated-rule-id'];
|
||||
@ -294,18 +312,24 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$input_errors[] = gettext('When selecting aliases for destination ports, both from and to fields must be the same');
|
||||
}
|
||||
}
|
||||
if (!is_specialnet($pconfig['src']) && !is_ipaddroralias($pconfig['src'])) {
|
||||
if (strpos($pconfig['src'], ',') > 0) {
|
||||
foreach (explode(',', $pconfig['src']) as $tmp) {
|
||||
if (!is_specialnet($tmp) && !is_alias($tmp)) {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid source alias."), $tmp);
|
||||
}
|
||||
}
|
||||
} elseif (!is_specialnet($pconfig['src']) && !is_ipaddroralias($pconfig['src']) && !is_subnet($pconfig['src'])) {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid source IP address or alias."),$pconfig['src']);
|
||||
}
|
||||
if (!empty($pconfig['srcmask']) && !is_numericint($pconfig['srcmask'])) {
|
||||
$input_errors[] = gettext("A valid source bit count must be specified.");
|
||||
}
|
||||
if (!is_specialnet($pconfig['dst']) && !is_ipaddroralias($pconfig['dst'])) {
|
||||
if (strpos($pconfig['dst'], ',') > 0) {
|
||||
foreach (explode(',', $pconfig['dst']) as $tmp) {
|
||||
if (!is_specialnet($tmp) && !is_alias($tmp)) {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid destination alias."), $tmp);
|
||||
}
|
||||
}
|
||||
} elseif (!is_specialnet($pconfig['dst']) && !is_ipaddroralias($pconfig['dst']) && !is_subnet($pconfig['dst'])) {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid destination IP address or alias."),$pconfig['dst']);
|
||||
}
|
||||
if (!empty($pconfig['dstmask']) && !is_numericint($pconfig['dstmask'])) {
|
||||
$input_errors[] = gettext("A valid destination bit count must be specified.");
|
||||
}
|
||||
|
||||
if (is_ipaddr($pconfig['src']) && is_ipaddr($pconfig['dst'])) {
|
||||
if ((is_ipaddrv4($pconfig['src']) && is_ipaddrv6($pconfig['dst'])) || (is_ipaddrv6($pconfig['src']) && is_ipaddrv4($pconfig['dst']))) {
|
||||
@ -314,21 +338,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
}
|
||||
foreach (array('src', 'dst') as $fam) {
|
||||
if (is_ipaddr($pconfig[$fam])) {
|
||||
if (is_ipaddrv6($pconfig[$fam]) && $pconfig['ipprotocol'] == "inet") {
|
||||
if ((is_ipaddrv6($pconfig[$fam]) || is_subnetv6($pconfig[$fam])) && $pconfig['ipprotocol'] == "inet") {
|
||||
$input_errors[] = gettext("You can not use IPv6 addresses in IPv4 rules.");
|
||||
} elseif (is_ipaddrv4($pconfig[$fam]) && $pconfig['ipprotocol'] == "inet6") {
|
||||
} elseif ((is_ipaddrv4($pconfig[$fam]) || is_subnetv4($pconfig[$fam])) && $pconfig['ipprotocol'] == "inet6") {
|
||||
$input_errors[] = gettext("You can not use IPv4 addresses in IPv6 rules.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_ipaddrv4($pconfig['src']) && $pconfig['srcmask'] > 32) {
|
||||
$input_errors[] = gettext("Invalid subnet mask on IPv4 source");
|
||||
}
|
||||
if (is_ipaddrv4($pconfig['dst']) && $pconfig['dstmask'] > 32) {
|
||||
$input_errors[] = gettext("Invalid subnet mask on IPv4 destination");
|
||||
}
|
||||
|
||||
if ((is_ipaddr($pconfig['src']) || is_ipaddr($pconfig['dst'])) && ($pconfig['ipprotocol'] == "inet46")) {
|
||||
$input_errors[] = gettext('You can not use an IPv4 or IPv6 address in combined IPv4 + IPv6 rules.');
|
||||
}
|
||||
@ -395,7 +412,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
if (is_numeric($pconfig['adaptivestart']) || is_numeric($pconfig['adaptiveend'])) {
|
||||
$input_errors[] = gettext("You cannot specify the adaptive timeouts (advanced option) if statetype is none.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!empty($pconfig['max']) && !is_posnumericint($pconfig['max']))
|
||||
@ -586,10 +602,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
}
|
||||
|
||||
pconfig_to_address($filterent['source'], $pconfig['src'],
|
||||
$pconfig['srcmask'] ?? '', !empty($pconfig['srcnot']),
|
||||
'', !empty($pconfig['srcnot']),
|
||||
$pconfig['srcbeginport'], $pconfig['srcendport']);
|
||||
pconfig_to_address($filterent['destination'], $pconfig['dst'],
|
||||
$pconfig['dstmask'] ?? '', !empty($pconfig['dstnot']),
|
||||
'', !empty($pconfig['dstnot']),
|
||||
$pconfig['dstbeginport'], $pconfig['dstendport']);
|
||||
|
||||
$filterent['updated'] = make_config_revision_entry();
|
||||
@ -652,10 +668,54 @@ include("head.inc");
|
||||
$(".advanced_opt_src").toggleClass("hidden visible");
|
||||
});
|
||||
|
||||
$.ajax("/firewall_rules_edit.php?get_address_options",{
|
||||
type: 'get',
|
||||
cache: false,
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
$(".net_selector_multi").each(function(){
|
||||
/* replaceInputWithSelector() replaces our input with a clean one, copy relevant attributes after construct */
|
||||
$(this).replaceInputWithSelector(data, true);
|
||||
let new_input = $("#" + $(this).attr('id'));
|
||||
new_input.attr('name', $(this).attr('id'));
|
||||
if ($(this).is(':disabled')) {
|
||||
$("select[for='" + $(this).attr('id') + "']").prop('disabled', true);
|
||||
new_input.prop('disabled', true);
|
||||
}
|
||||
$("select[for='" + $(this).attr('id') + "']").on('shown.bs.select', function(){
|
||||
$(this).data('previousValue', $(this).val());
|
||||
}).change(function(){
|
||||
let prev = Array.isArray($(this).data('previousValue')) ? $(this).data('previousValue') : [];
|
||||
let is_single = $(this).val().includes('') || $(this).val().includes('any');
|
||||
let was_single = prev.includes('') || prev.includes('any');
|
||||
let refresh = false;
|
||||
if (was_single && is_single && $(this).val().length > 1) {
|
||||
$(this).val($(this).val().filter(value => !prev.includes(value)));
|
||||
refresh = true;
|
||||
} else if (is_single && $(this).val().length > 1) {
|
||||
if ($(this).val().includes('any') && !prev.includes('any')) {
|
||||
$(this).val('any');
|
||||
} else{
|
||||
$(this).val('');
|
||||
}
|
||||
refresh = true;
|
||||
}
|
||||
if (refresh) {
|
||||
$(this).selectpicker('refresh');
|
||||
$(this).trigger('change');
|
||||
}
|
||||
$(this).data('previousValue', $(this).val());
|
||||
});
|
||||
new_input.val($(this).val()).change();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// select / input combination, link behaviour
|
||||
// when the data attribute "data-other" is selected, display related input item(s)
|
||||
// push changes from input back to selected option value
|
||||
$('[for!=""][for]').each(function(){
|
||||
$('.portselect').each(function(){
|
||||
var refObj = $("#"+$(this).attr("for"));
|
||||
if (refObj.is("select")) {
|
||||
// connect on change event to select box (show/hide)
|
||||
@ -689,7 +749,7 @@ include("head.inc");
|
||||
if ($(this).attr("name") == undefined) {
|
||||
$(this).change(function(){
|
||||
var otherOpt = $('#'+$(this).attr('for')+' > option[data-other="true"]') ;
|
||||
otherOpt.attr("value",$(this).val());
|
||||
otherOpt.attr("value", $(this).val());
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1064,51 +1124,8 @@ include("head.inc");
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Source"); ?></td>
|
||||
<td>
|
||||
<table style="max-width: 348px">
|
||||
<tr>
|
||||
<td>
|
||||
<select <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> name="src" id="src" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
|
||||
<option data-other=true value="<?=$pconfig['src'];?>" <?=!is_specialnet($pconfig['src']) ? "selected=\"selected\"" : "";?>><?=gettext("Single host or Network"); ?></option>
|
||||
<optgroup label="<?=gettext("Aliases");?>">
|
||||
<?php foreach (legacy_list_aliases("network") as $alias):
|
||||
?>
|
||||
<option value="<?=$alias['name'];?>" <?=$alias['name'] == $pconfig['src'] ? "selected=\"selected\"" : "";?>><?=htmlspecialchars($alias['name']);?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<optgroup label="<?=gettext("Networks");?>">
|
||||
<?php foreach (get_specialnets(true) as $ifent => $ifdesc):
|
||||
?>
|
||||
<option value="<?=$ifent;?>" <?= $pconfig['src'] == $ifent ? "selected=\"selected\"" : ""; ?>><?=$ifdesc;?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
<table style="max-width: 348px">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width:285px">
|
||||
<!-- updates to "other" option in src -->
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> type="text" id="src_address" for="src" value="<?=$pconfig['src'];?>" aria-label="<?=gettext("Source address");?>"/>
|
||||
</td>
|
||||
<td>
|
||||
<select <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> name="srcmask" data-network-id="src_address" class="selectpicker ipv4v6net" data-size="5" id="srcmask" data-width="70px" for="src">
|
||||
<?php for ($i = 128; $i > 0; $i--): ?>
|
||||
<option value="<?=$i;?>" <?= $i == $pconfig['srcmask'] ? "selected=\"selected\"" : ""; ?>><?=$i;?></option>
|
||||
<?php endfor ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> id="src" name="src" class="net_selector_multi" type="text" value="<?=$pconfig['src'];?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="advanced_opt_src visible">
|
||||
<td><?=gettext("Source"); ?></td>
|
||||
@ -1168,10 +1185,10 @@ include("head.inc");
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> type="text" value="<?=$pconfig['srcbeginport'];?>" for="srcbeginport"> <!-- updates to "other" option in srcbeginport -->
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> type="text" value="<?=$pconfig['srcbeginport'];?>" class="portselect" for="srcbeginport"> <!-- updates to "other" option in srcbeginport -->
|
||||
</td>
|
||||
<td>
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> type="text" value="<?=$pconfig['srcendport'];?>" for="srcendport"> <!-- updates to "other" option in srcendport -->
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> type="text" value="<?=$pconfig['srcendport'];?>" class="portselect" for="srcendport"> <!-- updates to "other" option in srcendport -->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -1192,48 +1209,7 @@ include("head.inc");
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Destination"); ?></td>
|
||||
<td>
|
||||
<table style="max-width: 348px">
|
||||
<tr>
|
||||
<td>
|
||||
<select <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> name="dst" id="dst" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
|
||||
<option data-other=true value="<?=$pconfig['dst'];?>" <?=!is_specialnet($pconfig['dst']) ? "selected=\"selected\"" : "";?>><?=gettext("Single host or Network"); ?></option>
|
||||
<optgroup label="<?=gettext("Aliases");?>">
|
||||
<?php foreach (legacy_list_aliases("network") as $alias):
|
||||
?>
|
||||
<option value="<?=$alias['name'];?>" <?=$alias['name'] == $pconfig['dst'] ? "selected=\"selected\"" : "";?>><?=htmlspecialchars($alias['name']);?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<optgroup label="<?=gettext("Networks");?>">
|
||||
<?php foreach (get_specialnets(true) as $ifent => $ifdesc):
|
||||
?>
|
||||
<option value="<?=$ifent;?>" <?= $pconfig['dst'] == $ifent ? "selected=\"selected\"" : ""; ?>><?=$ifdesc;?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table style="max-width: 348px">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width:285px">
|
||||
<!-- updates to "other" option in src -->
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> type="text" id="dst_address" for="dst" value="<?=$pconfig['dst'];?>" aria-label="<?=gettext("Destination address");?>"/>
|
||||
</td>
|
||||
<td>
|
||||
<select <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> name="dstmask" class="selectpicker ipv4v6net" data-network-id="dst_address" data-size="5" id="dstmask" data-width="70px" for="dst">
|
||||
<?php for ($i = 128; $i > 0; $i--): ?>
|
||||
<option value="<?=$i;?>" <?= $i == $pconfig['dstmask'] ? "selected=\"selected\"" : ""; ?>><?=$i;?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> id="dst" name="dst" type="text" value="<?=$pconfig['dst'];?>" class="net_selector_multi" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -1285,10 +1261,10 @@ include("head.inc");
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> type="text" value="<?=$pconfig['dstbeginport'];?>" for="dstbeginport"> <!-- updates to "other" option in dstbeginport -->
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> class="portselect" type="text" value="<?=$pconfig['dstbeginport'];?>" for="dstbeginport"> <!-- updates to "other" option in dstbeginport -->
|
||||
</td>
|
||||
<td>
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> type="text" value="<?=$pconfig['dstendport'];?>" for="dstendport"> <!-- updates to "other" option in dstendport -->
|
||||
<input <?=!empty($pconfig['associated-rule-id']) ? "disabled" : "";?> class="portselect" type="text" value="<?=$pconfig['dstendport'];?>" for="dstendport"> <!-- updates to "other" option in dstendport -->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@ -385,7 +385,7 @@ function gentitle($breadcrumbs, $navlevelsep = ': ')
|
||||
return join($navlevelsep, $output) . "$gentitle_suffix";
|
||||
}
|
||||
|
||||
function address_to_pconfig($adr, &$padr, &$pmask, &$pnot, &$pbeginport, &$pendport)
|
||||
function address_to_pconfig($adr, &$padr, &$pmask, &$pnot, &$pbeginport, &$pendport, $merge_mask=false)
|
||||
{
|
||||
if (isset($adr['any'])) {
|
||||
$padr = "any";
|
||||
@ -402,6 +402,9 @@ function address_to_pconfig($adr, &$padr, &$pmask, &$pnot, &$pbeginport, &$pendp
|
||||
$pmask = 32;
|
||||
}
|
||||
}
|
||||
if ($merge_mask && is_ipaddr($padr)) {
|
||||
$padr = $padr . '/' . $pmask;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($adr['not'])) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user