Skip to content

Commit

Permalink
Rewrite functions for toggle & delete NAT. Fixes #13545
Browse files Browse the repository at this point in the history
  • Loading branch information
ccope-netgate committed Nov 11, 2022
1 parent 599742b commit 0e6c4d6
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 125 deletions.
17 changes: 7 additions & 10 deletions src/etc/inc/itemid.inc
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@
* RESULT
* boolean - true if item was found and deleted
******/
function delete_id($id, &$array) {
function delete_id($id) {
global $config;

if (!is_array($array)) {
return false;
}
$array = config_get_path('filter/rule', []);

// Search for the item in the array
$delete_index = get_id($id, $array);
Expand All @@ -57,6 +55,7 @@ function delete_id($id, &$array) {
$mvnrows = -1;
move_separators($a_separators, $ridx, $mvnrows);

config_set_path('filter/rule', $array);
return true;
}

Expand All @@ -70,12 +69,8 @@ function delete_id($id, &$array) {
* RESULT
* boolean - true if item was found and set
******/
function toggle_id($id, &$array, $status) {
global $config;

if (!is_array($array)) {
return false;
}
function toggle_id($id, $status) {
$array = config_get_path('filter/rule', []);

// Search for the item in the array
$toggle_index = get_id($id, $array);
Expand All @@ -91,6 +86,8 @@ function toggle_id($id, &$array, $status) {
$array[$toggle_index]['disabled'] = true;
}

config_set_path('filter/rule', $array);

return true;
}

Expand Down
159 changes: 57 additions & 102 deletions src/usr/local/pfSense/include/www/firewall_nat.inc
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ function saveNATrule($post, $id, $json = false) {
// If we used to have an associated filter rule, but no-longer should have one
if (!empty($a_nat[$id]) && (empty($natent['associated-rule-id']) || $natent['associated-rule-id'] != $a_nat[$id]['associated-rule-id'])) {
// Delete the previous rule
delete_id($a_nat[$id]['associated-rule-id'], $config['filter']['rule']);
delete_id($a_nat[$id]['associated-rule-id']);
if (!$json) {
mark_subsystem_dirty('filter');
}
Expand Down Expand Up @@ -655,9 +655,7 @@ function saveNATrule($post, $id, $json = false) {
if (isset($natent['associated-rule-id']) &&
(isset($a_nat[$id]['disabled']) !== isset($natent['disabled']))) {
// Check for filter rule associations
toggle_id($natent['associated-rule-id'],
$config['filter']['rule'],
!isset($natent['disabled']));
toggle_id($natent['associated-rule-id'], !isset($natent['disabled']));

if (!$json) {
mark_subsystem_dirty('filter');
Expand Down Expand Up @@ -695,92 +693,77 @@ function saveNATrule($post, $id, $json = false) {
}

function toggleNATrule($post, $json = false) {
global $config;

init_config_arr(array('nat', 'rule'));
$a_nat = &$config['nat']['rule'];
init_config_arr(array('nat', 'separator'));
$a_separators = &$config['nat']['separator'];

if (isset($a_nat[$post['id']]['disabled'])) {
unset($a_nat[$post['id']]['disabled']);
$rule_status = true;
} else {
$a_nat[$post['id']]['disabled'] = true;
$rule_status = false;
// Check for single rule
if (!(is_array($post['rule']) && count($post['rule']))) {
$post['rule'] = array( $post['id'] => $post['id'] );
}

// Check for filter rule associations
if (isset($a_nat[$post['id']]['associated-rule-id'])) {
toggle_id($a_nat[$post['id']]['associated-rule-id'],
$config['filter']['rule'], $rule_status);
unset($rule_status);

if(!$json) {
mark_subsystem_dirty('filter');
foreach ($post['rule'] as $rulei) {
if (config_path_enabled("nat/rule/{$rulei}", 'disabled')) {
config_del_path("nat/rule/{$rulei}/disabled");
$rule_status = true;
} else {
config_set_path("nat/rule/{$rulei}/disabled", true);
$rule_status = false;
}
}

if (write_config(gettext("Firewall: NAT: Port forward, enable/disable NAT rule"))) {
if (!$json) {
mark_subsystem_dirty('natconf');
}
}
// Check for filter rule associations
$associated_rule_id = config_get_path("nat/rule/{$rulei}/associated-rule-id");

if(!$json) {
header("Location: firewall_nat.php");
exit;
} else {
$a_nat = &$config['nat']['rule'];
return isset($a_nat[$post['id']]['disabled']) ? "disabled":"enabled";
if ($associated_rule_id != null) {
toggle_id($associated_rule_id, $rule_status);
unset($rule_status);
$want_dirty_filter = true;
}
}
}

function toggleMultipleNATrules($post, $json = false) {
global $config;

init_config_arr(array('nat', 'rule'));
$a_nat = &$config['nat']['rule'];

foreach ($post['rule'] as $rulei) {
if (isset($a_nat[$rulei]['disabled'])) {
unset($a_nat[$rulei]['disabled']);
} else {
$a_nat[$rulei]['disabled'] = true;
}
if (count($post['rule']) == 1) {
$action = config_path_enabled("nat/rule/{$post['rule'][0]}", "disabled") ? "disabled":"enabled";
$write_ret = write_config(gettext("Firewall: NAT: Port forward - {$action} a NAT rule"));
} else if (count($post['rule']) > 1) {
$write_ret = write_config(gettext("Firewall: NAT: Port forward - enable/disable for selected NAT rules"));
}

if (write_config(gettext("Firewall: NAT: Port forward, enable/disable multiple NAT rule"))) {
if ($json) {
filter_configure();
} else {
if ($write_ret) {
if (!$json) {
mark_subsystem_dirty('natconf');
if ($want_dirty_filter) {
mark_subsystem_dirty('filter');
}
header("Location: firewall_nat.php");
exit;
} else {
if (isset($post['id'])) {
return $action;
} else {
filter_configure();
}
}
}
}

function deleteMultipleNATrules($post, $json = false) {
function deleteNATrule($post, $json = false) {
global $config;

init_config_arr(array('nat', 'rule'));
$a_nat = &$config['nat']['rule'];
init_config_arr(array('nat', 'separator'));
$a_separators = &$config['nat']['separator'];

// Check for single rule
if (!(is_array($post['rule']) && count($post['rule']))) {
$post['rule'] = array( $post['id'] => $post['id'] );
}

$num_deleted = 0;

foreach ($post['rule'] as $rulei) {
// Check for filter rule associations
if (isset($a_nat[$rulei]['associated-rule-id'])) {
delete_id($a_nat[$rulei]['associated-rule-id'], $config['filter']['rule']);
if (!$json) {
mark_subsystem_dirty('filter');
}
$associated_rule_id = config_get_path("nat/rule/{$rulei}/associated-rule-id");

if ($associated_rule_id != null) {
delete_id($associated_rule_id);
$want_dirty_filter = true;
}

unset($a_nat[$rulei]);
config_del_path("/nat/rule/{$rulei}");

// Update the separators
// As rules are deleted, $ridx has to be decremented or separator position will break
Expand All @@ -797,48 +780,20 @@ function deleteMultipleNATrules($post, $json = false) {
}

if ($num_deleted) {
if (write_config("NAT: Rule deleted")) {
if ($num_deleted == 1) {
$write_ret = write_config("Firewall: NAT: Port forward - rule deleted");
} else {
$write_ret = write_config("Firewall: NAT: Port forward - Multiple rules deleted");
}

if ($write_ret) {
if ($json) {
filter_configure();
} else {
mark_subsystem_dirty('natconf');
}
}
}

if(!$json) {
header("Location: firewall_nat.php");
exit;
}
}

function deleteNATrule($post, $json = false) {
global $config;

init_config_arr(array('nat', 'rule'));
$a_nat = &$config['nat']['rule'];
init_config_arr(array('nat', 'separator'));
$a_separators = &$config['nat']['separator'];

if (isset($a_nat[$post['id']]['associated-rule-id'])) {
delete_id($a_nat[$post['id']]['associated-rule-id'], $config['filter']['rule']);
$want_dirty_filter = true;
}

unset($a_nat[$post['id']]);

// Update the separators
$ridx = $post['id'];
$mvnrows = -1;
move_separators($a_separators, $ridx, $mvnrows);

if (write_config("NAT: Rule deleted")) {
if ($json) {
filter_configure();
} else {
mark_subsystem_dirty('natconf');
if ($want_dirty_filter) {
mark_subsystem_dirty('filter');
if ($want_dirty_filter) {
mark_subsystem_dirty('filter');
}
}
}
}
Expand Down
17 changes: 4 additions & 13 deletions src/usr/local/www/firewall_nat.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,12 @@
reorderNATrules($_POST);
} else if ($_POST['apply'] && have_natpfruleint_access($natent['interface'])) {
$retval = applyNATrules();
} else if (($_POST['act'] == "del") && have_natpfruleint_access($natent['interface'])) {
if ($a_nat[$_POST['id']]) {
} else if (($_POST['act'] == "del" || isset($_POST['del_x'])) && have_natpfruleint_access($natent['interface'])) {
if ($a_nat[$_POST['id']] || (is_array($_POST['rule']) && count($_POST['rule']))) {
deleteNATrule($_POST);
}
} else if (isset($_POST['del_x']) && have_natpfruleint_access($natent['interface'])) {
/* delete selected rules */
if (is_array($_POST['rule']) && count($_POST['rule'])) {
deleteMultipleNATrules($_POST);
}
} else if (isset($_POST['toggle_x']) && have_natpfruleint_access($natent['interface'])) {
if (is_array($_POST['rule']) && count($_POST['rule'])) {
toggleMultipleNATrules($_POST);
}
} elseif (($_POST['act'] == "toggle") && have_natpfruleint_access($natent['interface'])) {
if ($a_nat[$_POST['id']]) {
} elseif (($_POST['act'] == "toggle" || isset($_POST['toggle_x'])) && have_natpfruleint_access($natent['interface'])) {
if ($a_nat[$_POST['id']] || (is_array($_POST['rule']) && count($_POST['rule']))) {
toggleNATrule($_POST);
}
}
Expand Down

0 comments on commit 0e6c4d6

Please sign in to comment.