summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/inc/easyrule.inc79
-rw-r--r--usr/local/bin/easyrule140
-rw-r--r--usr/local/www/easyrule.php68
3 files changed, 219 insertions, 68 deletions
diff --git a/etc/inc/easyrule.inc b/etc/inc/easyrule.inc
index 2aa4357..c23cf6c 100644
--- a/etc/inc/easyrule.inc
+++ b/etc/inc/easyrule.inc
@@ -33,6 +33,10 @@
*/
$blockaliasname = 'EasyRuleBlockHosts';
+$protocols_with_ports = array('tcp', 'udp');
+require_once("functions.inc");
+require_once("util.inc");
+require_once("config.inc");
function easyrule_find_rule_interface($int) {
global $config;
@@ -212,8 +216,12 @@ function easyrule_block_host_add($host, $int = 'wan') {
if ($dirty) {
write_config();
$retval = filter_configure();
- header("Location: firewall_aliases.php");
- exit;
+ if (!empty($_SERVER['DOCUMENT_ROOT'])) {
+ header("Location: firewall_aliases.php");
+ exit;
+ } else {
+ return true;
+ }
} else {
return false;
}
@@ -253,7 +261,70 @@ function easyrule_pass_rule_add($int, $proto, $srchost, $dsthost, $dstport) {
write_config($filterent['descr']);
$retval = filter_configure();
- header("Location: firewall_rules.php?if={$int}");
- exit;
+ if (!empty($_SERVER['DOCUMENT_ROOT'])) {
+ header("Location: firewall_rules.php?if={$int}");
+ exit;
+ } else {
+ return true;
+ }
+}
+
+function easyrule_parse_block($int, $src) {
+ if (!empty($src) && !empty($int)) {
+ if (!is_ipaddr($src)) {
+ return "Tried to block invalid IP: " . htmlspecialchars($src);
+ }
+ $int = easyrule_find_rule_interface($int);
+ if ($int === false) {
+ return "Invalid interface for block rule: " . htmlspecialchars($int);
+ }
+ if (easyrule_block_host_add($src, $int)) {
+ return "Host added successfully";
+ } else {
+ return "Failed to create block rule, alias, or add host.";
+ }
+ } else {
+ return "Tried to block but had no host IP or interface";
+ }
+ return "Unknown block error.";
+}
+function easyrule_parse_pass($int, $proto, $src, $dst, $dstport = 0) {
+ /* Check for valid int, srchost, dsthost, dstport, and proto */
+ global $protocols_with_ports;
+
+ if (!empty($int) && !empty($proto) && !empty($src) && !empty($dst)) {
+ $int = easyrule_find_rule_interface($int);
+ if ($int === false) {
+ return "Invalid interface for pass rule: " . htmlspecialchars($int);
+ }
+ if (getprotobyname($proto) == -1) {
+ return "Invalid protocol for pass rule: " . htmlspecialchars($proto);
+ }
+ if (!is_ipaddr($src)) {
+ return "Tried to pass invalid source IP: " . htmlspecialchars($src);
+ }
+ if (!is_ipaddr($dst)) {
+ return "Tried to pass invalid destination IP: " . htmlspecialchars($dst);
+ }
+ if (in_array($proto, $protocols_with_ports)) {
+ if (empty($dstport)) {
+ return "Missing destination port: " . htmlspecialchars($dstport);
+ }
+ if (!is_port($dstport)) {
+ return "Tried to pass invalid destination port: " . htmlspecialchars($dstport);
+ }
+ } else {
+ $dstport = 0;
+ }
+ /* Should have valid input... */
+ if (easyrule_pass_rule_add($int, $proto, $src, $dst, $dstport)) {
+ return "Successfully added pass rule!";
+ } else {
+ return "Failed to add pass rule.";
+ }
+ } else {
+ return "Missing parameters for pass rule.";
+ }
+ return "Unknown pass error.";
}
?>
diff --git a/usr/local/bin/easyrule b/usr/local/bin/easyrule
new file mode 100644
index 0000000..60f5fb1
--- /dev/null
+++ b/usr/local/bin/easyrule
@@ -0,0 +1,140 @@
+#!/usr/local/bin/php -q
+<?php
+/*
+ easyrule CLI Program
+
+ Copyright (C) 2010 Jim Pingle (jpingle@gmail.com)
+ 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.
+*/
+
+require_once("pfsense-utils.inc");
+require_once("easyrule.inc");
+require_once("filter.inc");
+require_once("shaper.inc");
+
+$message = "";
+$specialsrcdst = explode(" ", "any pptp pppoe l2tp openvpn");
+
+/* Borrow this function from guiconfig.inc since we can't include it for use at the CLI
+
+ - Maybe these need to be moved to util.inc or pfsense-utils.inc?
+
+*/
+function pconfig_to_address(&$adr, $padr, $pmask, $pnot=false, $pbeginport=0, $pendport=0) {
+
+ $adr = array();
+
+ if ($padr == "any")
+ $adr['any'] = true;
+ else if (is_specialnet($padr))
+ $adr['network'] = $padr;
+ else {
+ $adr['address'] = $padr;
+ if ($pmask != 32)
+ $adr['address'] .= "/" . $pmask;
+ }
+
+ if ($pnot)
+ $adr['not'] = true;
+ else
+ unset($adr['not']);
+
+ if (($pbeginport != 0) && ($pbeginport != "any")) {
+ if ($pbeginport != $pendport)
+ $adr['port'] = $pbeginport . "-" . $pendport;
+ else
+ $adr['port'] = $pbeginport;
+ }
+
+ if(is_alias($pbeginport)) {
+ $adr['port'] = $pbeginport;
+ }
+}
+
+/* Borrow this one from guiconfig.inc also */
+function is_specialnet($net) {
+ global $specialsrcdst;
+
+ if(!$net)
+ return false;
+ if (in_array($net, $specialsrcdst))
+ return true;
+ else
+ return false;
+}
+
+/* Another one we need from guiconfig.inc but can't include... */
+function filter_rules_sort() {
+ global $config;
+
+ /* mark each rule with the sequence number (to retain the order while sorting) */
+ for ($i = 0; isset($config['filter']['rule'][$i]); $i++)
+ $config['filter']['rule'][$i]['seq'] = $i;
+
+ function filtercmp($a, $b) {
+ if ($a['interface'] == $b['interface'])
+ return $a['seq'] - $b['seq'];
+ else
+ return -strcmp($a['interface'], $b['interface']);
+ }
+
+ usort($config['filter']['rule'], "filtercmp");
+
+ /* strip the sequence numbers again */
+ for ($i = 0; isset($config['filter']['rule'][$i]); $i++)
+ unset($config['filter']['rule'][$i]['seq']);
+}
+
+
+if (($argc > 1) && !empty($argv[1])) {
+ $message = "";
+ switch ($argv[1]) {
+ case 'block':
+ $message = easyrule_parse_block($argv[2], $argv[3]);
+ break;
+ case 'pass':
+ $message = easyrule_parse_pass($argv[2], $argv[3], $argv[4], $argv[5], $argv[6]);
+ break;
+ }
+ echo $message . "\n";
+} else {
+ // Print usage:
+ echo "usage:\n";
+ echo " Blocking only requires an IP to block\n";
+ echo " " . basename($argv[0]) . " block <interface> <source IP>\n";
+ echo "\n";
+ echo " Passing requires more detail, as it must be as specific as possible. The destination port is optional if you're using a protocol without a port (e.g. ICMP, OSPF, etc).\n";
+ echo " " . basename($argv[0]) . " pass <interface> <protocol> <source IP> <destination ip> [destination port]\n";
+ echo "\n";
+ echo " Block example:\n";
+ echo " " . basename($argv[0]) . " block wan 1.2.3.4\n";
+ echo "\n";
+ echo " Pass example (protocol with port):\n";
+ echo " " . basename($argv[0]) . " pass wan tcp 1.2.3.4 192.168.0.4 80\n";
+ echo "\n";
+ echo " Block example (protocol without port):\n";
+ echo " " . basename($argv[0]) . " pass wan icmp 1.2.3.4 192.168.0.4\n";
+ echo "\n";
+}
+?> \ No newline at end of file
diff --git a/usr/local/www/easyrule.php b/usr/local/www/easyrule.php
index 69420d8..3055616 100644
--- a/usr/local/www/easyrule.php
+++ b/usr/local/www/easyrule.php
@@ -40,75 +40,15 @@ require_once("shaper.inc");
$retval = 0;
$message = "";
$specialsrcdst = explode(" ", "any pptp pppoe l2tp openvpn");
-$protocols_with_ports = array('tcp', 'udp');
if ($_GET && isset($_GET['action'])) {
switch ($_GET['action']) {
case 'block':
/* Check that we have a valid host */
- if (isset($_GET['src']) && isset($_GET['int'])) {
- if (!is_ipaddr($_GET['src'])) {
- $message .= "Tried to block invalid IP: " . htmlspecialchars($_GET['src']) . "<br/>";
- break;
- }
- $_GET['int'] = easyrule_find_rule_interface($_GET['int']);
- if ($_GET['int'] === false) {
- $message .= "Invalid interface for block rule: " . htmlspecialchars($_GET['int']) . "<br/>";
- break;
- }
- if (easyrule_block_host_add($_GET['src'], $_GET['int'])) {
- /* shouldn't get here, the function will redirect */
- $message .= "Host added successfully" . "<br/>";
- } else {
- $message .= "Failed to create block rule, alias, or add host." . "<br/>";
- }
- } else {
- $message .= "Tried to block but had no host IP or interface<br/>";
- }
+ easyrule_parse_block($_GET['int'], $_GET['src']);
break;
case 'pass':
- /* Check for valid int, srchost, dsthost, dstport, and proto */
- if (isset($_GET['int']) && isset($_GET['proto']) && isset($_GET['src']) && isset($_GET['dst'])) {
- $_GET['int'] = easyrule_find_rule_interface($_GET['int']);
- if ($_GET['int'] === false) {
- $message .= "Invalid interface for pass rule: " . htmlspecialchars($_GET['int']) . "<br/>";
- break;
- }
- if (getprotobyname($_GET['proto']) == -1) {
- $message .= "Invalid protocol for pass rule: " . htmlspecialchars($_GET['proto']) . "<br/>";
- break;
- }
- if (!is_ipaddr($_GET['src'])) {
- $message .= "Tried to pass invalid source IP: " . htmlspecialchars($_GET['src']) . "<br/>";
- break;
- }
- if (!is_ipaddr($_GET['dst'])) {
- $message .= "Tried to pass invalid destination IP: " . htmlspecialchars($_GET['dst']) . "<br/>";
- break;
- }
- if (in_array($_GET['proto'], $protocols_with_ports)) {
- if (!isset($_GET['dstport'])) {
- $message .= "Missing destination port: " . htmlspecialchars($_GET['dstport']) . "<br/>";
- break;
- }
- if (!is_port($_GET['dstport'])) {
- $message .= "Tried to pass invalid destination port: " . htmlspecialchars($_GET['dstport']) . "<br/>";
- break;
- }
- } else {
- $_GET['dstport'] = 0;
- }
- /* Should have valid input... */
- if (easyrule_pass_rule_add($_GET['int'], $_GET['proto'], $_GET['src'], $_GET['dst'], $_GET['dstport'])) {
- /* Shouldn't get here, the function should redirect. */
- $message .= "Successfully added pass rule!" . "<br/>";
- } else {
- $message .= "Failed to add pass rule." . "<br/>";
- }
- } else {
- $message = "Missing parameters for pass rule";
- break;
- }
+ easyrule_parse_pass($_GET['int'], $_GET['proto'], $_GET['src'], $_GET['dst'], $_GET['dstport']);
break;
}
}
@@ -129,12 +69,12 @@ include("head.inc"); ?>
Message: <?php echo $message; ?>
<br/>
<? } else { ?>
-This is the Easy Rule status page, mainly used to display errors when adding rules.
+This is the Easy Rule status page, mainly used to display errors when adding rules.
If you are seeing this, there apparently was not an error, and you navigated to the
page directly without telling it what to do.<br/><br/>
This page is meant to be called from the block/pass buttons on the Firewall Logs page, <a href="diag_logs_filter.php">Status &gt; System Logs,
Firewall Tab</a>.
-<br />
+<br />
<? } ?>
</td></tr></table>
<?php include("fend.inc"); ?>
OpenPOWER on IntegriCloud