summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf.default/config.xml2
-rw-r--r--etc/inc/functions.inc1
-rw-r--r--etc/inc/itemid.inc85
-rwxr-xr-xusr/local/www/firewall_nat.php12
-rwxr-xr-xusr/local/www/firewall_nat_edit.php74
-rwxr-xr-xusr/local/www/firewall_rules.php17
-rwxr-xr-xusr/local/www/firewall_rules_edit.php12
-rw-r--r--usr/local/www/themes/pfsense_ng/images/icons/icon_chain.pngbin0 -> 281 bytes
8 files changed, 183 insertions, 20 deletions
diff --git a/conf.default/config.xml b/conf.default/config.xml
index 67d6bfe..b617b23 100644
--- a/conf.default/config.xml
+++ b/conf.default/config.xml
@@ -449,6 +449,7 @@
<target></target>
<local-port></local-port>
<descr></descr>
+ <associated-filter-rule-id></associated-filter-rule-id>
</rule>
-->
<!--
@@ -502,6 +503,7 @@
<!-- rule syntax:
<rule>
<disabled/>
+ <id>[0-9]*</id>
<type>pass|block|reject</type>
<descr>...</descr>
<interface>lan|opt[n]|wan|pptp</interface>
diff --git a/etc/inc/functions.inc b/etc/inc/functions.inc
index c7189b5..79aa19d 100644
--- a/etc/inc/functions.inc
+++ b/etc/inc/functions.inc
@@ -83,5 +83,6 @@ require_once("vpn.inc");
require_once("vslb.inc");
require_once("cmd_chain.inc");
require_once("rrd.inc");
+require_once("itemid.inc");
?>
diff --git a/etc/inc/itemid.inc b/etc/inc/itemid.inc
new file mode 100644
index 0000000..3a48e51
--- /dev/null
+++ b/etc/inc/itemid.inc
@@ -0,0 +1,85 @@
+<?php
+/* $Id$ */
+/*
+ Copyright (C) 2009 Janne Enberg <janne.enberg@lietu.net>
+ 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.
+
+ DISABLE_PHP_LINT_CHECKING
+*/
+
+/****f* itemid/delete_id
+ * NAME
+ * delete_id - delete an item with ['id'] = $id from $array
+ * INPUTS
+ * $id - int: The ID to delete
+ * $array - array to delete the item from
+ * RESULT
+ * boolean - true if item was found and deleted
+ ******/
+function delete_id($id, &$array){
+ // Index to delete
+ $delete_index = NULL;
+
+ // Search for the item in the array
+ foreach ($array as $key => $item){
+ // If this item is the one we want to delete
+ if(isset($item['id']) && $item['id']==$id ){
+ $delete_index = $key;
+ break;
+ }
+ }
+
+ // If we found the item, unset it
+ if( $delete_index!==NULL ){
+ unset($array[$delete_index]);
+ return true;
+ } else {
+ return false;
+ }
+
+}
+
+/****f* itemid/get_next_id
+ * NAME
+ * get_next_id - find the next available id from an item list
+ * INPUTS
+ * $array - array of items to get the id for
+ * RESULT
+ * integer - the next available id
+ ******/
+function get_next_id($array){
+ // Default value
+ $next_id = 1;
+
+ // Search for IDs
+ foreach ($array as $item){
+ // If this item has an ID, and it's higher or equal to the current "next ID", use that + 1 as the next ID
+ if(isset($item['id']) && $item['id']>=$next_id ){
+ $next_id = $item['id'] + 1;
+ }
+ }
+ return $next_id;
+}
+
+?> \ No newline at end of file
diff --git a/usr/local/www/firewall_nat.php b/usr/local/www/firewall_nat.php
index 741e15a..274a3f2 100755
--- a/usr/local/www/firewall_nat.php
+++ b/usr/local/www/firewall_nat.php
@@ -81,6 +81,12 @@ if (isset($_POST['del_x'])) {
if (is_array($_POST['rule']) && count($_POST['rule'])) {
foreach ($_POST['rule'] as $rulei) {
$target = $rule['target'];
+ // Check for filter rule associations
+ if (isset($a_nat[$rulei]['associated-filter-rule-id'])){
+ delete_id($a_nat[$rulei]['associated-filter-rule-id'], $config['filter']['rule']);
+
+ mark_subsystem_dirty('filter');
+ }
unset($a_nat[$rulei]);
}
write_config();
@@ -217,7 +223,11 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
?>
<tr valign="top" id="fr<?=$nnats;?>">
<td class="listt"><input type="checkbox" id="frc<?=$nnats;?>" name="rule[]" value="<?=$i;?>" onClick="fr_bgcolor('<?=$nnats;?>')" style="margin: 0; padding: 0; width: 15px; height: 15px;"></td>
- <td class="listt" align="center"></td>
+ <td class="listt" align="center">
+ <?php if(isset($natent['associated-filter-rule-id']) && $natent['associated-filter-rule-id']>0): ?>
+ <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_chain.png" width="17" height="17" title="Firewall rule ID <?=htmlspecialchars($natent['associated-filter-rule-id']); ?> is managed with this rule" border="0">
+ <?php endif; ?>
+ </td>
<td class="listlr" onClick="fr_toggle(<?=$nnats;?>)" id="frd<?=$nnats;?>" ondblclick="document.location='firewall_nat_edit.php?id=<?=$nnats;?>';">
<?php
if (!$natent['interface'] || ($natent['interface'] == "wan"))
diff --git a/usr/local/www/firewall_nat_edit.php b/usr/local/www/firewall_nat_edit.php
index 10fb84d..d8a9fb6 100755
--- a/usr/local/www/firewall_nat_edit.php
+++ b/usr/local/www/firewall_nat_edit.php
@@ -61,6 +61,7 @@ if (isset($id) && $a_nat[$id]) {
$pconfig['localbeginport'] = $a_nat[$id]['local-port'];
$pconfig['descr'] = $a_nat[$id]['descr'];
$pconfig['interface'] = $a_nat[$id]['interface'];
+ $pconfig['associated-filter-rule-id'] = $a_nat[$id]['associated-filter-rule-id'];
$pconfig['nosync'] = isset($a_nat[$id]['nosync']);
if (!$pconfig['interface'])
$pconfig['interface'] = "wan";
@@ -181,24 +182,29 @@ if ($_POST) {
$natent['local-port'] = $_POST['localbeginport'];
$natent['interface'] = $_POST['interface'];
$natent['descr'] = $_POST['descr'];
+ $natent['associated-filter-rule-id'] = $_POST['associated-filter-rule-id'];
if($_POST['nosync'] == "yes")
$natent['nosync'] = true;
else
unset($natent['nosync']);
- if (isset($id) && $a_nat[$id])
- $a_nat[$id] = $natent;
- else {
- if (is_numeric($after))
- array_splice($a_nat, $after+1, 0, array($natent));
- else
- $a_nat[] = $natent;
- }
+ $need_filter_rule = false;
+ // Updating a rule with a filter rule associated
+ if( $natent['associated-filter-rule-id']>0 )
+ $need_filter_rule = true;
+ // If creating a new rule, where we want to add the filter rule, associated or not
+ else if( isset($_POST['filter-rule-association']) &&
+ ($_POST['filter-rule-association']=='add-associated' ||
+ $_POST['filter-rule-association']=='add-unassociated') )
+ $need_filter_rule = true;
- mark_subsystem_dirty('natconf');
+ if ($need_filter_rule) {
+
+ // If we had a previous rule associated with this NAT rule, delete that
+ if( $natent['associated-filter-rule-id'] > 0 )
+ delete_id($natent['associated-filter-rule-id'], $config['filter']['rule']);
- if ($_POST['autoadd']) {
/* auto-generate a matching firewall rule */
$filterent = array();
$filterent['interface'] = $_POST['interface'];
@@ -221,11 +227,30 @@ if ($_POST) {
*/
$filterent['descr'] = substr("NAT " . $_POST['descr'], 0, 59);
+ // If we had a previous rule association, update this rule with that ID so we don't lose association
+ if ($natent['associated-filter-rule-id'] > 0)
+ $filterent['id'] = $natent['associated-filter-rule-id'];
+ // If we wanted this rule to be associated, make sure the NAT entry is updated with the same ID
+ else if($_POST['filter-rule-association']=='add-associated')
+ $natent['associated-filter-rule-id'] = $filterent['id'] = get_next_id($config['filter']['rule']);
+
$config['filter']['rule'][] = $filterent;
mark_subsystem_dirty('filter');
}
+ // Update NAT entry after creating/updating the firewall rule, so we have it's rule ID if one was created
+ if (isset($id) && $a_nat[$id])
+ $a_nat[$id] = $natent;
+ else {
+ if (is_numeric($after))
+ array_splice($a_nat, $after+1, 0, array($natent));
+ else
+ $a_nat[] = $natent;
+ }
+
+ mark_subsystem_dirty('natconf');
+
write_config();
header("Location: firewall_nat.php");
@@ -390,13 +415,34 @@ include("fbegin.inc"); ?>
HINT: This prevents the rule from automatically syncing to other CARP members.
</td>
</tr>
+ <?php if (isset($id) && $a_nat[$id] && !isset($_GET['dup'])): ?>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Filter rule association</td>
+ <td width="78%" class="vtable">
+ <select name="associated-filter-rule-id">
+ <option value="">None</option>
+ <?php foreach ($config['filter']['rule'] as $filter_rule): ?>
+ <?php if (isset($filter_rule['id']) && $filter_rule['id']>0): ?>
+ <option value="<?php echo $filter_rule['id']; ?>"<?php if($filter_rule['id']==$pconfig['associated-filter-rule-id']) echo " SELECTED"; ?>>
+ <?php echo htmlspecialchars('Rule ' . $filter_rule['id'] . ' - ' . $filter_rule['descr']); ?>
+ </option>
+ <?php endif; ?>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ </tr>
+ <?php endif; ?>
<?php if ((!(isset($id) && $a_nat[$id])) || (isset($_GET['dup']))): ?>
<tr>
- <td width="22%" valign="top">&nbsp;</td>
+ <td width="22%" valign="top">Filter rule association</td>
<td width="78%">
- <input name="autoadd" type="checkbox" id="autoadd" value="yes" CHECKED>
- <strong>Auto-add a firewall rule to permit traffic through
- this NAT rule</strong></td>
+ <select name="filter-rule-association" id="filter-rule-association">
+ <option value="">None</option>
+ <option value="add-associated" selected="selected">Add associated rule</option>
+ <option value="add-unassociated">Add unassociated rule</option>
+ <option value="pass">Pass</option>
+ </select>
+ </td>
</tr><?php endif; ?>
<tr>
<td width="22%" valign="top">&nbsp;</td>
diff --git a/usr/local/www/firewall_rules.php b/usr/local/www/firewall_rules.php
index e084e4c..a6f5b38 100755
--- a/usr/local/www/firewall_rules.php
+++ b/usr/local/www/firewall_rules.php
@@ -249,15 +249,16 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<tr id="frheader">
<td width="3%" class="list">&nbsp;</td>
<td width="5%" class="list">&nbsp;</td>
+ <td width="3%" class="listhdrr">ID</td>
<td width="6%" class="listhdrr">Proto</td>
- <td width="15%" class="listhdrr">Source</td>
+ <td width="14%" class="listhdrr">Source</td>
<td width="7%" class="listhdrr">Port</td>
- <td width="15%" class="listhdrr">Destination</td>
+ <td width="14%" class="listhdrr">Destination</td>
<td width="7%" class="listhdrr">Port</td>
<td width="5%" class="listhdrr">Gateway</td>
<td width="10%" class="listhdrr">Queue</td>
<td width="5%" class="listhdrr">Schedule</td>
- <td width="22%" class="listhdr">Description</td>
+ <td width="21%" class="listhdr">Description</td>
<td width="10%" class="list">
<table border="0" cellspacing="0" cellpadding="1">
<tr>
@@ -286,7 +287,8 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<tr valign="top" id="frrfc1918">
<td width="3%" class="list">&nbsp;</td>
<td class="listt" align="center"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_block.gif" width="11" height="11" border="0"></td>
- <td class="listlr" style="background-color: #e0e0e0">*</td>
+ <td class="listlr" style="background-color: #e0e0e0"></td>
+ <td class="listr" style="background-color: #e0e0e0">*</td>
<td class="listr" style="background-color: #e0e0e0">RFC 1918 networks</td>
<td class="listr" style="background-color: #e0e0e0">*</td>
<td class="listr" style="background-color: #e0e0e0">*</td>
@@ -313,7 +315,8 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<tr valign="top" id="frrfc1918">
<td width="3%" class="list">&nbsp;</td>
<td class="listt" align="center"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_block.gif" width="11" height="11" border="0"></td>
- <td class="listlr" style="background-color: #e0e0e0">*</td>
+ <td class="listlr" style="background-color: #e0e0e0"></td>
+ <td class="listr" style="background-color: #e0e0e0">*</td>
<td class="listr" style="background-color: #e0e0e0">Reserved/not assigned by IANA</td>
<td class="listr" style="background-color: #e0e0e0">*</td>
<td class="listr" style="background-color: #e0e0e0">*</td>
@@ -545,6 +548,9 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
}
?>
<td class="listlr" onClick="fr_toggle(<?=$nrules;?>)" id="frd<?=$nrules;?>" ondblclick="document.location='firewall_rules_edit.php?id=<?=$i;?>';">
+ <?=$textss;?><?php if (isset($filterent['id'])) echo $filterent['id']; else echo ""; ?><?=$textse;?>
+ </td>
+ <td class="listr" onClick="fr_toggle(<?=$nrules;?>)" id="frd<?=$nrules;?>" ondblclick="document.location='firewall_rules_edit.php?id=<?=$i;?>';">
<?=$textss;?><?php if (isset($filterent['protocol'])) echo strtoupper($filterent['protocol']); else echo "*"; ?><?=$textse;?>
</td>
<td class="listr" onClick="fr_toggle(<?=$nrules;?>)" id="frd<?=$nrules;?>" ondblclick="document.location='firewall_rules_edit.php?id=<?=$i;?>';">
@@ -611,6 +617,7 @@ echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript
<td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
+ <td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
<td class="list">&nbsp;</td>
diff --git a/usr/local/www/firewall_rules_edit.php b/usr/local/www/firewall_rules_edit.php
index 67e98f2..d9bc01b 100755
--- a/usr/local/www/firewall_rules_edit.php
+++ b/usr/local/www/firewall_rules_edit.php
@@ -71,6 +71,9 @@ if (isset($_GET['dup'])) {
if (isset($id) && $a_filter[$id]) {
$pconfig['interface'] = $a_filter[$id]['interface'];
+ if (isset($a_filter[$id]['id']))
+ $pconfig['ruleid'] = $a_filter[$id]['id'];
+
if (!isset($a_filter[$id]['type']))
$pconfig['type'] = "pass";
else
@@ -337,6 +340,8 @@ if ($_POST) {
else if ($dnpipe[0] == "?" && $pdnpipe[0] <> "?")
$input_errors[] = "You cannot select one queue and one virtual interface for IN and Out. both must be from the same type.";
}
+ if( !empty($_POST['ruleid']) && !ctype_digit($_POST['ruleid']))
+ $input_errors[] = 'ID must be an integer';
if($_POST['l7container'] && $_POST['l7container'] != "none") {
if(!($_POST['proto'] == "tcp" || $_POST['proto'] == "udp" || $_POST['proto'] == "tcp/udp"))
$input_errors[] = "You can only select a layer7 container for tcp and/or udp protocols";
@@ -346,6 +351,7 @@ if ($_POST) {
if (!$input_errors) {
$filterent = array();
+ $filterent['id'] = $_POST['ruleid']>0?$_POST['ruleid']:'';
$filterent['type'] = $_POST['type'];
if (isset($_POST['interface'] ))
$filterent['interface'] = $_POST['interface'];
@@ -493,6 +499,12 @@ include("head.inc");
<td colspan="2" valign="top" class="listtopic">Edit Firewall rule</td>
</tr>
<tr>
+ <td width="22%" valign="top" class="vncell">ID</td>
+ <td width="78%" class="vtable">
+ <input name="ruleid" value="<?=(isset($pconfig['ruleid'])&&$pconfig['ruleid']>0)?htmlspecialchars($pconfig['ruleid']):''?>">
+ </td>
+ </tr>
+ <tr>
<td width="22%" valign="top" class="vncellreq">Action</td>
<td width="78%" class="vtable">
<select name="type" class="formselect">
diff --git a/usr/local/www/themes/pfsense_ng/images/icons/icon_chain.png b/usr/local/www/themes/pfsense_ng/images/icons/icon_chain.png
new file mode 100644
index 0000000..cd9a7cc
--- /dev/null
+++ b/usr/local/www/themes/pfsense_ng/images/icons/icon_chain.png
Binary files differ
OpenPOWER on IntegriCloud