aboutsummaryrefslogtreecommitdiffstats
path: root/config/spamd
diff options
context:
space:
mode:
authorErmal <eri@pfsense.org>2010-03-23 14:28:16 +0000
committerErmal <eri@pfsense.org>2010-03-23 14:28:16 +0000
commit57b1446ac5fb0fead3c545264978aa7896d28654 (patch)
treeca2ff760b21918913c8ff62fa6b4303b7f0efa7f /config/spamd
parentd56b96f7f9fd1ef61aa644ddcd4da6b65759e004 (diff)
downloadpfsense-packages-57b1446ac5fb0fead3c545264978aa7896d28654.tar.gz
pfsense-packages-57b1446ac5fb0fead3c545264978aa7896d28654.tar.bz2
pfsense-packages-57b1446ac5fb0fead3c545264978aa7896d28654.zip
Move all spamd functions to its folder.
Diffstat (limited to 'config/spamd')
-rw-r--r--config/spamd/spamd.inc323
-rw-r--r--config/spamd/spamd.xml211
-rw-r--r--config/spamd/spamd_db.php457
-rw-r--r--config/spamd/spamd_db_ext.php239
-rw-r--r--config/spamd/spamd_exchexp.asp50
-rw-r--r--config/spamd/spamd_gather_stats.php82
-rw-r--r--config/spamd/spamd_outlook.xml90
-rw-r--r--config/spamd/spamd_rules.php34
-rw-r--r--config/spamd/spamd_settings.xml192
-rw-r--r--config/spamd/spamd_verify_to_address.php144
-rw-r--r--config/spamd/spamd_whitelist.xml132
11 files changed, 1954 insertions, 0 deletions
diff --git a/config/spamd/spamd.inc b/config/spamd/spamd.inc
new file mode 100644
index 00000000..8747df29
--- /dev/null
+++ b/config/spamd/spamd.inc
@@ -0,0 +1,323 @@
+<?php
+/* $Id$ */
+/*
+ spamd.inc
+ part of the SpamD package for pfSense
+ Copyright (C) 2008 Scott Ullrich
+ 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.
+
+*/
+
+if(!function_exists("filter_configure"))
+ require_once("filter.inc");
+
+function sync_package_spamd() {
+ global $config, $g;
+
+ conf_mount_rw();
+ config_lock();
+ $fd = fopen("/etc/spamd.conf","w");
+ /* all header */
+ fwrite($fd, "all:\\\n\t:whitelist:blacklist");
+ if($config['installedpackages']['spamdsources']['config']) {
+ foreach($config['installedpackages']['spamdsources']['config'] as $spamd) {
+ if($spamd['providername']) {
+ fwrite($fd, ":" . remove_spaces($spamd['providername']));
+ }
+ }
+ }
+ fwrite($fd, ":\n\n");
+ fwrite($fd, "whitelist:\\\n");
+ fwrite($fd, "\t:method=file:\\\n");
+ fwrite($fd, "\t:white:\\\n");
+ fwrite($fd, "\t:file=/var/db/whitelist.txt:\n");
+ fwrite($fd, "\n");
+ fwrite($fd, "blacklist:\\\n");
+ fwrite($fd, "\t:black:\\\n");
+ fwrite($fd, "\t:msg=\"Sorry, you spammed us before.\":\\\n");
+ fwrite($fd, "\t:method=file:\\\n");
+ fwrite($fd, "\t:file=/var/db/blacklist.txt:\n\n");
+ log_error("Looping through each item and write out its configuration");
+ /* loop through each item and write out its configuration */
+ if($config['installedpackages']['spamdsources']['config'] != "") {
+ foreach($config['installedpackages']['spamdsources']['config'] as $spamd) {
+ if(remove_spaces($spamd['providername'])) {
+ if($spamd['providername']) {
+ fwrite($fd, remove_spaces($spamd['providername']) . ":\\\n");
+ fwrite($fd, "\t:" . remove_spaces($spamd['providertype']) . ":\\\n");
+ fwrite($fd, "\t:msg=\"" . rtrim($spamd['rejectmessage']) . "\":\\\n");
+ fwrite($fd, "\t:method=" . remove_spaces($spamd['providermethod']) . ":\\\n");
+ $providerurl = $spamd['providerurl'];
+ $providerurl = str_replace("http://", "", $providerurl);
+ $providerurl = str_replace("https://", "", $providerurl);
+ fwrite($fd, "\t:file=" . remove_spaces($providerurl) . ":\n\n");
+ }
+ }
+ }
+ }
+ fclose($fd);
+ log_error("Creating /var/db/whitelist.txt");
+ $fd = fopen("/var/db/whitelist.txt","w");
+ if($config['installedpackages']['spamdwhitelist']['config'] != "") {
+ foreach($config['installedpackages']['spamdwhitelist']['config'] as $spamd) {
+ if($spamd['ip'])
+ fwrite($fd, $spamd['ip'] . "\n");
+ }
+ }
+ fclose($fd);
+ $passtime = "5";
+ $greyexp = "4";
+ $whiteexp = "864";
+ $identifier = "";
+ $maxcon = "";
+ $maxblack = "";
+ $stuttersecs = "";
+ $delaysecs = "";
+ log_error("Looping through spamdsettings");
+ if($config['installedpackages']['spamdsettings']['config']) {
+ foreach($config['installedpackages']['spamdsettings']['config'] as $ss) {
+ if($ss['nextmta'] <> "")
+ $nextmta = $ss['nextmta'];
+ if($ss['greylistingparms'] <> "")
+ $passtime = " -G " . $ss['greylistingparms'];
+ if($ss['identifier'] <> "")
+ $identifier = " -n \"" . $ss['identifier'] . "\"";
+ // Default is greylisting, turn on blacklisting if not checked.
+ if($ss['greylisting'] <> "on")
+ $greylisting = " -b";
+ if($ss['maxblack'] <> "")
+ $maxblack = " -B " . $ss['maxblack'];
+ if($ss['maxcon'] <> "")
+ $maxcon = " -c " . $ss['maxcon'];
+ if($ss['stuttersecs'] <> "")
+ $stuttersecs = " -S " . $ss['stuttersecs'];
+ if($ss['delaysecs'] <> "")
+ $delaysecs = " -s " . $ss['delaysecs'];
+ if($ss['window'] <> "")
+ $window = " -w " . $ss['window'];
+ if($ss['passtime'] <> "")
+ $passtime = $ss['passtime'];
+ if($ss['greyexp'] <> "")
+ $greyexp = $ss['greyexp'];
+ if($ss['whiteexp'] <> "")
+ $whiteexp = $ss['whiteexp'];
+ }
+ }
+ $greyparms = " -G {$passtime}:{$greyexp}:{$whiteexp}";
+ $start = "if [ `mount | grep -v grep | grep fdescfs | wc -l` -lt 1 ]; then \n" .
+ "/sbin/mount -t fdescfs fdescfs /dev/fd\n" .
+ "fi\n" .
+ "/usr/local/sbin/spamd-setup -d &\n" .
+ "/sbin/pflogd &\n" .
+ "/usr/local/libexec/spamd {$greyparms}{$identifier}{$greylisting}{$maxcon}{$maxblack}{$window}{$replysmtperror} 127.0.0.1 &\n" .
+ "/usr/local/libexec/spamlogd\n";
+ $stop = "/usr/bin/killall spamd-setup\n" .
+ "/usr/bin/killall spamlogd\n" .
+ "/usr/bin/killall spamd\n" .
+ "/usr/bin/killall pflogd\n" .
+ "sleep 2";
+ log_error("Writing rc_file");
+ write_rcfile(array(
+ "file" => "spamd.sh",
+ "start" => $start,
+ "stop" => $stop
+ )
+ );
+ log_error("Installing CRON");
+ spamd_install_cron(true);
+ log_error("Mounting RO");
+ conf_mount_ro();
+ log_error("Unlocking config");
+ config_unlock();
+ log_error("Restart cron");
+ mwexec("killall -HUP cron");
+ log_error("Setting up spamd.conf symlink");
+ mwexec("ln -s /etc/spamd.conf /usr/local/etc/spamd/spamd.conf");
+ log_error("Stopping spamd");
+ mwexec("/usr/local/etc/rc.d/spamd.sh stop");
+ sleep(1);
+ log_error("Starting spamd");
+ mwexec_bg("/usr/local/etc/rc.d/spamd.sh start");
+ log_error("Reconfiguring filter");
+ filter_configure();
+ log_error("SpamD setup completed");
+}
+
+function spamd_generate_rules($type) {
+ global $config;
+
+ $natrules = "";
+ switch($type) {
+ case 'rdr':
+ $natrules .= "\n# spam table \n";
+ $wanif = get_real_interface("wan");
+ $natrules .= "table <whitelist> persist\n";
+ $natrules .= "table <blacklist> persist\n";
+ $natrules .= "table <spamd> persist\n";
+ if(file_exists("/var/db/whitelist.txt"))
+ $natrules .= "table <spamd-white> persist file \"/var/db/whitelist.txt\"\n";
+ $natrules .= "rdr pass on {$wanif} proto tcp from <blacklist> to port smtp -> 127.0.0.1 port spamd\n";
+ $natrules .= "rdr pass on {$wanif} proto tcp from <spamd> to port smtp -> 127.0.0.1 port spamd\n";
+ $natrules .= "rdr pass on {$wanif} proto tcp from !<spamd-white> to port smtp -> 127.0.0.1 port spamd\n";
+ if($config['installedpackages']['spamdsettings']['config'])
+ foreach($config['installedpackages']['spamdsettings']['config'] as $ss)
+ $nextmta = $ss['nextmta'];
+ if($nextmta <> "") {
+ $natrules .= "rdr pass on {$wanif} proto tcp from <spamd-white> to port smtp -> {$nextmta} port smtp\n";
+ }
+
+ break;
+ }
+
+ return $natrules;
+}
+
+function remove_spaces($string) {
+ $string = str_replace(" ", "", $string);
+ return $string;
+}
+
+function sync_spamd_config_to_backup() {
+ global $g, $config;
+ if(is_array($config['installedpackages']['carpsettings']['config'])) {
+ foreach($config['installedpackages']['carpsettings']['config'] as $carp) {
+ if($carp['synchronizetoip'] != "" ) {
+ $synctoip = $carp['synchronizetoip'];
+ $password = $carp['password'];
+ if($config['system']['username'])
+ $username = $config['system']['username'];
+ else
+ $username = "admin";
+ }
+ }
+ }
+ if($synctoip and $password) {
+ if($config['system']['webgui']['protocol'] != "") {
+ $synchronizetoip = $config['system']['webgui']['protocol'];
+ $synchronizetoip .= "://";
+ }
+ $port = $config['system']['webgui']['port'];
+ /* if port is empty lets rely on the protocol selection */
+ if($port == "") {
+ if($config['system']['webgui']['protocol'] == "http") {
+ $port = "80";
+ } else {
+ $port = "443";
+ }
+ }
+ $params = array(XML_RPC_encode($password),XML_RPC_encode($xml));
+ /* create files to sync array */
+ $filetosync = array("/var/db/spamd", "/var/db/whitelist.txt");
+ /* loop through files to sync list and sync them up */
+ foreach($filetosync as $f2s) {
+ $f2c_contents = file_get_contents($f2s);
+ xmlrpc_sync_file($url, $password, $f2s, $f2c_contents, $port);
+ }
+ /* signal remote process config reload */
+ xmlrpc_exec_shell($url, $password, "/usr/bin/killall -HUP spamlogd", $port);
+ xmlrpc_exec_shell($url, $password, "/usr/bin/killall -HUP spamd", $port);
+ }
+}
+
+function custom_php_install_command() {
+ global $config, $g;
+ system("touch /var/db/whitelist.txt");
+ system("touch /var/db/blacklist.txt");
+ sync_package_spamd();
+ exec("pw user mod_spamd -u 0");
+}
+
+function custom_php_deinstall_command() {
+ global $config, $g;
+ conf_mount_rw();
+ exec("killall -9 spamd");
+ unlink_if_exists("/usr/local/pkg/pf/spamd_rules.php");
+ unlink_if_exists("/usr/local/www/spamd_rules.php");
+ unlink_if_exists("/usr/local/etc/rc.d/spamd.sh");
+ spamd_install_cron(false);
+ conf_mount_ro();
+ filter_configure();
+}
+
+function spamd_install_cron($should_install) {
+ global $config, $g;
+ $is_installed = false;
+ if(!$config['cron']['item'])
+ return;
+ $x=0;
+ foreach($config['cron']['item'] as $item) {
+ if(strstr($item['command'], "spamd-setup")) {
+ $is_installed = true;
+ break;
+ }
+ $x++;
+ }
+ switch($should_install) {
+ case true:
+ if(!$is_installed) {
+ $cron_item = array();
+ $cron_item['minute'] = "*/120";
+ $cron_item['hour'] = "*";
+ $cron_item['mday'] = "*";
+ $cron_item['month'] = "*";
+ $cron_item['wday'] = "*";
+ $cron_item['who'] = "root";
+ $cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/spamd-setup";
+ $config['cron']['item'][] = $cron_item;
+ write_config("Installed SPAMD crontab entries.");
+ configure_cron();
+ }
+ break;
+ case false:
+ if($is_installed == true) {
+ if($x > 0) {
+ unset($config['cron']['item'][$x]);
+ write_config();
+ }
+ configure_cron();
+ }
+ break;
+ }
+}
+
+function spamd_validate_input($post, $input_errors) {
+ global $config, $g;
+ $nextmta = str_replace("$", "", $post['nextmta']);
+ if(stristr($nextmta, "{")) {
+ /* item is an alias, make sure the name exists */
+ $nextmta = str_replace("$", "", $nextmta);
+ $found = false;
+ if($config['aliases']['alias']) {
+ foreach($config['aliases']['alias'] as $alias) {
+ if($alias['name'] == $nextmta) {
+ $found = true;
+ }
+ }
+ }
+ if($found == false)
+ $intput_errors = "Could not locate alias named " . htmlentities($nextmta);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/config/spamd/spamd.xml b/config/spamd/spamd.xml
new file mode 100644
index 00000000..5bbc5d71
--- /dev/null
+++ b/config/spamd/spamd.xml
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ spamd.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2008 Scott Ullrich
+ 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.
+ */
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>spamdsources</name>
+ <version>4.2</version>
+ <title>SpamD: External Sources</title>
+ <include_file>/usr/local/pkg/spamd.inc</include_file>
+ <backup_file>/var/db/spamd</backup_file>
+ <!-- Menu is where this packages menu will appear -->
+ <menu>
+ <name>SpamD</name>
+ <section>Services</section>
+ <configfile>spamd.xml</configfile>
+ </menu>
+ <service>
+ <name>spamd</name>
+ <rcfile>/usr/local/etc/rc.d/spamd.sh</rcfile>
+ </service>
+ <tabs>
+ <tab>
+ <text>SpamD External Sources</text>
+ <url>/pkg.php?xml=spamd.xml</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>SpamD Whitelist</text>
+ <url>/pkg.php?xml=spamd_whitelist.xml</url>
+ </tab>
+ <tab>
+ <text>SpamD Settings</text>
+ <url>/pkg_edit.php?xml=spamd_settings.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>SpamD Database</text>
+ <url>/spamd_db.php</url>
+ </tab>
+ </tabs>
+ <!-- configpath gets expanded out automatically and config items will be
+ stored in that location -->
+ <configpath>['installedpackages']['spamd']['config']</configpath>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fielddescr>Provider Name</fielddescr>
+ <fieldname>providername</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Provider Type</fielddescr>
+ <fieldname>providertype</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Description</fielddescr>
+ <fieldname>providerdescription</fieldname>
+ </columnitem>
+ </adddeleteeditpagefields>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/spamd_rules.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/spamd_whitelist.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/spamd_outlook.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/spamd.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/spamd_settings.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/spamd_db.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/spamd_db_ext.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/bin/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/spamd_gather_stats.php</item>
+ </additional_files_needed>
+
+ <!-- fields gets invoked when the user adds or edits a item. the following items
+ will be parsed and rendered for the user as a gui with input, and selectboxes. -->
+ <fields>
+ <field>
+ <fielddescr>Provider Name</fielddescr>
+ <fieldname>providername</fieldname>
+ <description>Enter the name of the source</description>
+ <type>input</type>
+ <size>30</size>
+ </field>
+ <field>
+ <fielddescr>Provider Type</fielddescr>
+ <fieldname>providertype</fieldname>
+ <description>Select the Provider Type</description>
+ <type>select</type>
+ <size>1</size>
+ <value>black</value>
+ <options>
+ <option><name>Black List</name><value>black</value></option>
+ <option><name>White List</name><value>white</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Provider Description</fielddescr>
+ <fieldname>providerdescription</fieldname>
+ <description>Enter the description for this item</description>
+ <type>textarea</type>
+ <size>30</size>
+ <cols>40</cols>
+ <rows>4</rows>
+ </field>
+ <field>
+ <fielddescr>Reject message</fielddescr>
+ <fieldname>rejectmessage</fieldname>
+ <description>Enter the message to display to emailing parties that are on this providers list</description>
+ <type>textarea</type>
+ <size>30</size>
+ <cols>40</cols>
+ <rows>2</rows>
+ </field>
+ <field>
+ <fielddescr>Provider Method</fielddescr>
+ <fieldname>providermethod</fieldname>
+ <description>Select the Provider Method</description>
+ <type>select</type>
+ <size>1</size>
+ <value>http</value>
+ <options>
+ <option><name>File</name><value>file</value></option>
+ <option><name>URL</name><value>http</value></option>
+ <option><name>Execute command</name><value>exec</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Provider URL or Filename</fielddescr>
+ <fieldname>providerurl</fieldname>
+ <description>Enter the URL to the provider.</description>
+ <type>textarea</type>
+ <cols>40</cols>
+ <rows>4</rows>
+ </field>
+ </fields>
+ <custom_delete_php_command>
+ sync_package_spamd();
+ </custom_delete_php_command>
+ <custom_php_resync_config_command>
+ sync_package_spamd();
+ </custom_php_resync_config_command>
+ <custom_php_install_command>
+ custom_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ custom_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <filter_rules_needed>spamd_generate_rules</filter_rules_needed>
+</packagegui>
diff --git a/config/spamd/spamd_db.php b/config/spamd/spamd_db.php
new file mode 100644
index 00000000..112fdd71
--- /dev/null
+++ b/config/spamd/spamd_db.php
@@ -0,0 +1,457 @@
+<?php
+/* $Id$ */
+/*
+ spamd_db.php
+ part of the pfSense project
+ Copyright (C) 2006, 2007, 2008 Scott Ullrich
+ 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("guiconfig.inc");
+
+if($_POST['filter'])
+ $filter = $_POST['filter'];
+if($_POST['not'])
+ $not = true;
+if($_POST['limit'])
+ $limit = intval($_POST['limit']);
+else
+ $limit = "25";
+
+/* handle AJAX operations */
+if($_GET['action'] or $_POST['action']) {
+ /* echo back buttonid so it can be turned
+ * back off when request is completed.
+ */
+ echo $_GET['buttonid'] . "|";
+ if($_GET['action'])
+ $action = escapeshellarg($_GET['action']);
+ if($_POST['action'])
+ $action = escapeshellarg($_POST['action']);
+ if($_GET['srcip'])
+ $srcip = $_GET['srcip'];
+ if($_POST['srcip'])
+ $srcip = $_POST['srcip'];
+ if($_POST['toaddress'])
+ $toaddress = escapeshellarg($_POST['toaddress']);
+ $srcip = str_replace("<","",$srcip);
+ $srcip = str_replace(">","",$srcip);
+ $srcip = str_replace(" ","",$srcip);
+ // Make input safe
+ $srcip = escapeshellarg($srcip);
+ /* execute spamdb command */
+ if($action == "'whitelist'") {
+ exec("/usr/local/sbin/spamdb -d {$srcip}");
+ exec("/usr/local/sbin/spamdb -d {$srcip} -T");
+ exec("/usr/local/sbin/spamdb -d {$srcip} -t");
+ delete_from_blacklist($srcip);
+ mwexec("/sbin/pfctl -q -t blacklist -T replace -f /var/db/blacklist.txt");
+ exec("echo spamdb -a {$srcip} > /tmp/tmp");
+ exec("/usr/local/sbin/spamdb -a {$srcip}");
+ } else if($action == "'delete'") {
+ exec("/usr/local/sbin/spamdb -d {$srcip}");
+ exec("/usr/local/sbin/spamdb -d {$srcip} -T");
+ exec("/usr/local/sbin/spamdb -d {$srcip} -t");
+ delete_from_blacklist($srcip);
+ mwexec("/sbin/pfctl -q -t spamd -T delete $srcip");
+ mwexec("/sbin/pfctl -q -t blacklist -T replace -f /var/db/blacklist.txt");
+ } else if($action == "'spamtrap'") {
+ exec("/usr/local/sbin/spamdb -d {$srcip}");
+ exec("/usr/local/sbin/spamdb -d {$srcip} -T");
+ exec("/usr/local/sbin/spamdb -d {$srcip} -t");
+ exec("/usr/local/sbin/spamdb -a {$srcip} -T");
+ } else if($action == "'trapped'") {
+ exec("/usr/local/sbin/spamdb -T -d {$toaddress}");
+ exec("/usr/local/sbin/spamdb -T -a '{$toaddress}'");
+ }
+ /* signal a reload for real time effect. */
+ mwexec("killall -HUP spamlogd");
+ exit;
+}
+
+/* spam trap e-mail address */
+if($_POST['spamtrapemail'] <> "") {
+ $spamtrapemail = escapeshellarg($_POST['spamtrapemail']);
+ exec("/usr/local/sbin/spamdb -d {$spamtrapemail}");
+ exec("/usr/local/sbin/spamdb -d -T {$spamtrapemail}");
+ exec("/usr/local/sbin/spamdb -d -t {$spamtrapemail}");
+ exec("/usr/local/sbin/spamdb -T -a '{$toaddress}'");
+
+ mwexec("killall -HUP spamlogd");
+ $savemsg = htmlentities($_POST['spamtrapemail']) . " added to spam trap database.";
+}
+
+if($_GET['getstatus'] <> "") {
+ $status = exec("/usr/local/sbin/spamdb | grep \"{$_GET['getstatus']}\"");
+ if(stristr($status, "WHITE") == true) {
+ echo "WHITE";
+ } else if(stristr($status, "TRAPPED") == true) {
+ echo "TRAPPED";
+ } else if(stristr($status, "GREY") == true) {
+ echo "GREY";
+ } else if(stristr($status, "SPAMTRAP") == true) {
+ echo "SPAMTRAP";
+ } else {
+ echo "NOT FOUND";
+ }
+ exit;
+}
+
+/* spam trap e-mail address */
+if($_GET['spamtrapemail'] <> "") {
+ $spamtrapemail = escapeshellarg($_GET['spamtrapemail']);
+ $status = exec("spamdb -T -a {$spamtrapemail}");
+ mwexec("killall -HUP spamlogd");
+ if($status)
+ echo $status;
+ else
+ echo htmlentities($_POST['spamtrapemail']) . " added to spam trap database.";
+ exit;
+}
+
+/* whitelist e-mail address */
+if($_GET['whitelist'] <> "") {
+ $spamtrapemail = escapeshellarg($_GET['spamtrapemail']);
+ $status = exec("spamdb -a {$spamtrapemail}");
+ mwexec("killall -HUP spamlogd");
+ if($status)
+ echo $status;
+ else
+ echo htmlentities($_POST['spamtrapemail']) . " added to whitelist database.";
+ exit;
+}
+
+function delete_from_blacklist($srcip) {
+ config_lock();
+ $blacklist = split("\n", file_get_contents("/var/db/blacklist.txt"));
+ $fd = fopen("/var/db/blacklist.txt", "w");
+ foreach($blacklist as $bl) {
+ if($bl <> "")
+ if(!stristr($bl, $srcip))
+ fwrite($fd, "{$bl}\n");
+ }
+ fclose($fd);
+ mwexec("/sbin/pfctl -q -t spamd -T delete {$srcip}");
+ mwexec("/sbin/pfctl -q -t blacklist -T replace -f /var/db/blacklist.txt");
+ config_unlock();
+}
+
+function delete_from_whitelist($srcip) {
+ config_lock();
+ $whitelist = split("\n", file_get_contents("/var/db/whitelist.txt"));
+ $fd = fopen("/var/db/whitelist.txt", "w");
+ foreach($whitelist as $wl) {
+ if($wl <> "")
+ if(!stristr($wl, $srcip))
+ fwrite($fd, "{$wl}\n");
+ }
+ fclose($fd);
+ mwexec("/sbin/pfctl -q -t spamd -T delete $srcip");
+ mwexec("/sbin/pfctl -q -t whitelist -T replace -f /var/db/whitelist.txt");
+ config_unlock();
+}
+
+$pgtitle = "SpamD: Database";
+include("head.inc");
+
+if(file_exists("/var/db/whitelist.txt"))
+ $whitelist_items = `cat /var/db/whitelist.txt | wc -l`;
+else
+ $whitelist_items = 0;
+
+if(file_exists("/var/db/blacklist.txt"))
+ $blacklist_items = `cat /var/db/blacklist.txt | wc -l`;
+else
+ $blacklist_items = 0;
+
+// Get an overall count of the database
+$spamdb_items = `/usr/local/sbin/spamdb | wc -l`;
+
+// Get blacklist and whitelist count from database
+$spamdb_white = `/usr/local/sbin/spamdb | grep WHITE | wc -l`;
+$spamdb_black = `/usr/local/sbin/spamdb | grep BLACK | wc -l`;
+$spamdb_grey = `/usr/local/sbin/spamdb | grep GREY | wc -l`;
+
+// Now count the user contributed whitelist and blacklist count
+$whitelist_items = $whitelist_items + $spamdb_white;
+$blacklist_items = $blacklist_items + $spamdb_black;
+
+?>
+<body link="#000000" vlink="#000000" alink="#000000">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle"><?=$pgtitle?></font></p>
+<form action="spamd_db.php" method="post" name="iform">
+<script src="/javascript/scriptaculous/prototype.js" type="text/javascript"></script>
+<script src="/javascript/scriptaculous/scriptaculous.js" type="text/javascript"></script>
+<script type="text/javascript" language="javascript" src="row_toggle.js"></script>
+<script src="/javascript/sorttable.js"></script>
+<script language="javascript">
+function outputrule(req) {
+ if(req.content != '') {
+ /* response is split by | */
+ var itemsplit = req.content.split("|");
+ /* turn back off the button */
+ toggle_off(itemsplit[0]);
+ /* uh oh, we've got an error of some sort */
+ if(itemsplit[1] != "")
+ alert('An error was detected.\n\n' + req.content);
+ }
+}
+/* toggle button to be on during AJAX request */
+function toggle_on(button, image) {
+ var item = document.getElementById(button);
+ item.src = image;
+}
+/* turn off button by stripping _p out */
+function toggle_off(button) {
+ /* no text back? thats bad. */
+ if(button == '')
+ return;
+ var item = document.getElementById(button);
+ var currentbutton = item.src;
+ currentbutton = currentbutton.replace("_p.", ".");
+ item.src = currentbutton;
+ new Effect.Shake(item);
+}
+/* delete a row */
+function delete_row_db(row) {
+ row++;
+ var el = document.getElementById('maintable');
+ el.deleteRow(row);
+}
+/* standard issue AJAX handler */
+if (typeof getURL == 'undefined') {
+ getURL = function(url, callback) {
+ if (!url)
+ throw 'No URL for getURL';
+ try {
+ if (typeof callback.operationComplete == 'function')
+ callback = callback.operationComplete;
+ } catch (e) {}
+ if (typeof callback != 'function')
+ throw 'No callback function for getURL';
+ var http_request = null;
+ if (typeof XMLHttpRequest != 'undefined') {
+ http_request = new XMLHttpRequest();
+ }
+ else if (typeof ActiveXObject != 'undefined') {
+ try {
+ http_request = new ActiveXObject('Msxml2.XMLHTTP');
+ } catch (e) {
+ try {
+ http_request = new ActiveXObject('Microsoft.XMLHTTP');
+ } catch (e) {}
+ }
+ }
+ if (!http_request)
+ throw 'Both getURL and XMLHttpRequest are undefined';
+ http_request.onreadystatechange = function() {
+ if (http_request.readyState == 4) {
+ callback( { success : true,
+ content : http_request.responseText,
+ contentType : http_request.getResponseHeader("Content-Type") } );
+ }
+ }
+ http_request.open('GET', url, true);
+ http_request.send(null);
+ }
+}
+</script>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php endif; ?>
+<table width="99%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+<?php
+ $tab_array = array();
+ $tab_array[] = array("SpamD External Sources", false, "/pkg.php?xml=spamd.xml");
+ $tab_array[] = array("SpamD Whitelist", false, "/pkg.php?xml=spamd_whitelist.xml");
+ $tab_array[] = array("SpamD Settings", false, "/pkg_edit.php?xml=spamd_settings.xml&id=0");
+ $tab_array[] = array("SpamD Database", true, "/spamd_db.php");
+ display_top_tabs($tab_array);
+?>
+ </td></tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <table id="maintable" name="maintable" class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+
+
+<table>
+<tr><td align="right">Filter by test:</td><td><input name="filter" value="<?=$filter?>"></input></td><td><input type="submit" value="Filter"></td><td>&nbsp;&nbsp;Inverse filter (NOT):</td><td><input type="checkbox" id="not" name="not" <?php if($not) echo " CHECKED"; ?>></td></tr>
+<tr><td align="right">Limit:</td><td><input name="limit" value="<?=$limit?>"></input></td></tr>
+<tr><td>&nbsp;</td></tr>
+<tr><td align="right">* Add spam trap E-mail address:</td><td><input name="spamtrapemail" value="<?=$spamtrapemail?>"></input></td><td><input type="submit" value="Add"></td></tr>
+</table><br>
+
+
+
+ <table id="sortabletable1" name="sortabletable1" class="sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr id="frheader">
+ <td class="listhdrr">Type</td>
+ <td class="listhdrr">IP</td>
+ <td class="listhdrr">From</td>
+ <td class="listhdrr">To</td>
+ <td class="listhdr">Attempts</td>
+ <td class="list"></td>
+ </tr>
+<?php
+ if($filter) {
+ if($not) {
+ $fd = fopen("/tmp/spamdb", "w");
+ $cmd = "/usr/local/sbin/spamdb | grep -v \"" . escapeshellarg($filter) . "\" | tail -n {$limit}";
+ fwrite($fd, $cmd);
+ fclose($fd);
+ $pkgdb = split("\n", `$cmd`);
+ if(file_exists("/var/db/blacklist.txt")) {
+ $cmd = "cat /var/db/blacklist.txt | grep -v \"" . escapeshellarg($filter) . "\" ";
+ $pkgdba = split("\n", `$cmd`);
+ foreach($pkgdba as $pkg) {
+ $pkgdb[] = "TRAPPED|{$pkg}|1149324397";
+ }
+ }
+ } else {
+
+ $cmd = "/usr/local/sbin/spamdb | grep " . escapeshellarg($filter) . " | tail -n {$limit}";
+
+ $pkgdb = split("\n", `$cmd`);
+ if(file_exists("/var/db/blacklist.txt")) {
+ $cmd = "cat /var/db/blacklist.txt | grep " . escapeshellarg($filter);
+ $pkgdba = split("\n", `$cmd`);
+ foreach($pkgdba as $pkg) {
+ $pkgdb[] = "TRAPPED|{$pkg}|1149324397";
+ }
+ echo "<!-- $pkgdb -->";
+ }
+ }
+ } else {
+ $pkgdb = split("\n", `/usr/local/sbin/spamdb | tail -n {$limit}`);
+ }
+ $rows = 0;
+ $lastseenip = "";
+ $srcip = "|";
+ foreach($pkgdb as $pkgdb_row) {
+
+ if($rows > $limit)
+ break;
+ $dontdisplay = false;
+ if(!$pkgdb_row)
+ continue;
+ $pkgdb_split = split("\|", $pkgdb_row);
+
+ /*
+
+ For TRAPPED entries the format is:
+
+ type|ip|expire
+
+ where type will be TRAPPED, IP will be the IP address blacklisted due to
+ hitting a spamtrap, and expire will be when the IP is due to be removed
+ from the blacklist.
+
+ For GREY entries, the format is:
+
+ type|source IP|helo|from|to|first|pass|expire|block|pass
+
+ For WHITE entries, the format is:
+
+ type|source IP|||first|pass|expire|block|pass
+
+ */
+ switch($pkgdb_split[0]) {
+ case "SPAMTRAP":
+ $recordtype = htmlentities($pkgdb_split[0]);
+ $srcip = htmlentities($pkgdb_split[1]);
+ $fromaddress = htmlentities($pkgdb_split[3]);
+ $toaddress = htmlentities($pkgdb_split[4]);
+ $attempts = htmlentities($pkgdb_split[8]);
+ break;
+ case "TRAPPED":
+ $recordtype = htmlentities($pkgdb_split[0]);
+ $srcip = htmlentities($pkgdb_split[1]);
+ $fromaddress = "";
+ $toaddress = "";
+ $attempts = "";
+ break;
+ case "GREY":
+ $recordtype = htmlentities($pkgdb_split[0]);
+ $srcip = htmlentities($pkgdb_split[1]);
+ $fromaddress = htmlentities($pkgdb_split[3]);
+ $toaddress = htmlentities($pkgdb_split[4]);
+ $attempts = htmlentities($pkgdb_split[8]);
+ break;
+ case "WHITE":
+ $recordtype = htmlentities($pkgdb_split[0]);
+ $srcip = htmlentities($pkgdb_split[1]);
+ $fromaddress = "";
+ $toaddress = "";
+ $attempts = htmlentities($pkgdb_split[8]);
+ break;
+ }
+ if($srcip == "" and $fromaddress == "" and $toaddress == "")
+ continue;
+ echo "<tr id=\"{$rows}\">";
+ echo "<td class=\"listr\">{$recordtype}</td>";
+ echo "<td class=\"listr\">{$srcip}</td>";
+ echo "<td class=\"listr\">{$fromaddress}</td>";
+ echo "<td class=\"listr\">{$toaddress}</td>";
+ echo "<td class=\"listr\">{$attempts}</td>";
+ echo "<td>";
+ $rowtext = "<NOBR><a href='javascript:toggle_on(\"w{$rows}\", \"/themes/{$g['theme']}/images/icons/icon_plus_p.gif\"); getURL(\"spamd_db.php?buttonid=w{$rows}&srcip={$srcip}&action=whitelist\", outputrule);'><img title=\"Add to whitelist\" name='w{$rows}' id='w{$rows}' border=\"0\" alt=\"Add to whitelist\" src=\"/themes/{$g['theme']}/images/icons/icon_plus.gif\"></a> ";
+ $rowtext .= "<a href='javascript:toggle_on(\"b{$rows}\", \"/themes/{$g['theme']}/images/icons/icon_trapped_p.gif\");getURL(\"spamd_db.php?buttonid=b{$rows}&srcip={$srcip}&action=trapped\", outputrule);'><img title=\"Blacklist\" name='b{$rows}' id='b{$rows}' border=\"0\" alt=\"Blacklist\" src=\"/themes/{$g['theme']}/images/icons/icon_trapped.gif\"></a> ";
+ $rowtext .= "<a href='javascript:toggle_on(\"d{$rows}\", \"/themes/{$g['theme']}/images/icons/icon_x_p.gif\");getURL(\"spamd_db.php?buttonid=d{$rows}&srcip={$srcip}&action=delete\", outputrule);'><img title=\"Delete\" border=\"0\" name='d{$rows}' id='d{$rows}' alt=\"Delete\" src=\"./themes/{$g['theme']}/images/icons/icon_x.gif\"></a>";
+ $rowtext .= "<a href='javascript:toggle_on(\"s{$rows}\", \"/themes/{$g['theme']}/images/icons/icon_plus_bl_p.gif\");getURL(\"spamd_db.php?buttonid=s{$rows}&spamtrapemail={$toaddress}&action=spamtrap\", outputrule);'><img title=\"Spamtrap\" name='s{$rows}' id='s{$rows}' border=\"0\" alt=\"Spamtrap\" src=\"./themes/{$g['theme']}/images/icons/icon_plus_bl.gif\"></a> ";
+
+ echo $rowtext;
+
+ echo "</td></tr>";
+
+ $rows++;
+ }
+?> </td></tr></table>
+ <tr><td>
+ <?php echo "<font face=\"arial\"><p><b>" . $rows . "</b> rows returned."; ?>
+ <p>
+ * NOTE: adding an e-mail address to the spamtrap automatically traps any server trying to send e-mail to this address.
+ </td></tr>
+ </table>
+ </div>
+ </td>
+ </tr>
+</table>
+</form>
+<br>
+<span class="vexpl"><strong><span class="red">Note:</span> Clicking on the action icons will invoke a AJAX query and the page will not refresh. Click refresh in you're browser if you wish to view the changes in status.</strong></span>
+<br>
+ <p><font size="-2"><b>Database totals:</b><br><font size="-3"><br>
+ <?php
+ echo "{$whitelist_items} total items in the whitelist.<br>";
+ echo "{$blacklist_items} total items in the blacklist.<br>";
+ echo "{$spamdb_grey} total items in the greylist.<br>";
+ echo "{$spamdb_items} total items in the SpamDB.<br>";
+ ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/config/spamd/spamd_db_ext.php b/config/spamd/spamd_db_ext.php
new file mode 100644
index 00000000..e029f676
--- /dev/null
+++ b/config/spamd/spamd_db_ext.php
@@ -0,0 +1,239 @@
+<?php
+/* $Id$ */
+/*
+ spamd_db_ext.php
+ Copyright (C) 2008 Scott Ullrich
+ 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("guiconfig.inc");
+
+/* this script is no longer supported */
+exit;
+
+if($_GET['loginname'])
+ $loginname = " Username: " . $_GET['loginname'];
+if($_GET['username'])
+ $username = $_GET['username'];
+if($_GET['password'])
+ $password = $_GET['password'];
+if($_POST['username'])
+ $username = $_POST['username'];
+if($_POST['password'])
+ $password = $_POST['password'];
+
+foreach($config['installedpackages']['spamdoutlook']['config'] as $outlook) {
+ if($outlook['username'] <> $username) {
+ echo "550. INVALID USERNAME {$username}.";
+ exit;
+ }
+ if($outlook['password'] <> $password) {
+ echo "550. INVALID PASSWORD {$password}.";
+ exit;
+ }
+}
+
+exec("echo {$_GET['action']} > /tmp/tmp");
+
+/* handle AJAX operations */
+if($_GET['action'] or $_POST['action']) {
+ if($_GET['action'])
+ $action = escapeshellarg(trim($_GET['action']));
+ if($_POST['action'])
+ $action = escapeshellarg(trim($_POST['action']));
+ if($_GET['srcip'])
+ $srcip = escapeshellarg(trim($_GET['srcip']));
+ if($_POST['srcip'])
+ $srcip = escapeshellarg(trim($_POST['srcip']));
+ if($_POST['email'])
+ $email = escapeshellarg(trim($_POST['email']));
+ if($_GET['email'])
+ $email = escapeshellarg(trim($_GET['email']));
+ /* execute spamdb command */
+ if($action == "whitelist") {
+ delete_from_spamd_db($srcip);
+ usleep(100);
+ exec("/usr/local/sbin/spamdb -a {$srcip}");
+ mwexec("/sbin/pfctl -q -t blacklist -T replace -f /var/db/blacklist.txt");
+ delete_from_blacklist($srcip);
+ log_error("spamd: {$srcip} has been whitelisted by {$_SERVER['REMOTE_ADDR']} {$loginname}");
+ hup_spamd();
+ exit;
+ } else if($action == "delete") {
+ delete_from_spamd_db($srcip);
+ usleep(100);
+ hup_spamd();
+ mwexec("/sbin/pfctl -q -t spamd -T delete $srcip");
+ mwexec("/sbin/pfctl -q -t blacklist -T replace -f /var/db/blacklist.txt");
+ delete_from_blacklist($srcip);
+ delete_from_whitelist($srcip);
+ log_error("spamd: {$srcip} has been deleted by {$_SERVER['REMOTE_ADDR']} {$loginname}");
+ exit;
+ } else if($action == "spamtrap") {
+ delete_from_spamd_db($email);
+ delete_from_whitelist($srcip);
+ usleep(100);
+ exec("/usr/local/sbin/spamdb -a \"{$email}\" -T");
+ hup_spamd();
+ mwexec("/sbin/pfctl -q -t blacklist -T add -f /var/db/blacklist.txt");
+ log_error("spamd: {$srcip} has been blacklisted by {$_SERVER['REMOTE_ADDR']} {$loginname}");
+ exit;
+ } else if($action == "trapped") {
+ delete_from_spamd_db($srcip);
+ delete_from_whitelist($srcip);
+ usleep(100);
+ exec("/usr/local/sbin/spamdb -a {$srcip} -t");
+ add_to_blacklist($srcip);
+ log_error("spamd: {$srcip} has been trapped by {$_SERVER['REMOTE_ADDR']} {$loginname}");
+ hup_spamd();
+ exit;
+ }
+ /* signal a reload for real time effect. */
+ hup_spamd();
+ exit;
+}
+
+/* spam trap e-mail address */
+if($_POST['spamtrapemail'] <> "") {
+ $spamtrapemail = escapeshellarg($_POST['spamtrapemail']);
+ exec("/usr/local/sbin/spamdb -d {$spamtrapemail}");
+ exec("/usr/local/sbin/spamdb -d -T \"{$spamtrapemail}\"");
+ exec("/usr/local/sbin/spamdb -d -t \"{$spamtrapemail}\"");
+ mwexec("/usr/local/sbin/spamdb -T -a \"{$spamtrapemail}\"");
+ mwexec("killall -HUP spamlogd");
+ $savemsg = htmlentities($_POST['spamtrapemail']) . " added to spam trap database.";
+}
+
+if($_GET['getstatus'] <> "") {
+ $getstatus = escapeshellarg($_GET['getstatus']);
+ $status = exec("/usr/local/sbin/spamdb | grep \"{$getstatus}\"");
+ if(stristr($status, "WHITE") == true) {
+ echo "WHITE";
+ } else if(stristr($status, "TRAPPED") == true) {
+ echo "TRAPPED";
+ } else if(stristr($status, "GREY") == true) {
+ echo "GREY";
+ } else if(stristr($status, "SPAMTRAP") == true) {
+ echo "SPAMTRAP";
+ } else {
+ echo "NOT FOUND";
+ }
+ exit;
+}
+
+/* spam trap e-mail address */
+if($_GET['spamtrapemail'] <> "") {
+ $spamtrapemail = escapeshellarg($_GET['spamtrapemail']);
+ $status = exec("spamdb -T -a \"{$spamtrapemail}\"");
+ mwexec("killall -HUP spamlogd");
+ if($status)
+ echo $status;
+ else
+ echo htmlentities($_POST['spamtrapemail']) . " added to spam trap database.";
+ exit;
+}
+
+/* spam trap e-mail address */
+if($_GET['whitelist'] <> "") {
+ $spamtrapemail = escapeshellarg($_GET['spamtrapemail']);
+ $status = exec("spamdb -a \"{$spamtrapemail}\"");
+ mwexec("killall -HUP spamlogd");
+ if($status)
+ echo $status;
+ else
+ echo htmlentities($_POST['spamtrapemail']) . " added to whitelist database.";
+ exit;
+}
+
+function delete_from_spamd_db($srcip) {
+ config_lock();
+ $fd = fopen("/tmp/execcmds", "w");
+ fwrite($fd, "#!/bin/sh\n");
+ fwrite($fd, "/usr/local/sbin/spamdb -d {$srcip}\n");
+ fwrite($fd, "/usr/local/sbin/spamdb -d {$srcip} -T\n");
+ fwrite($fd, "/usr/local/sbin/spamdb -d {$srcip} -t\n");
+ fwrite($fd, "/usr/local/sbin/spamdb -d \"{$srcip}\" -t\n");
+ fwrite($fd, "/usr/local/sbin/spamdb -d \"{$srcip}\" -T\n");
+ fclose($fd);
+ exec("/bin/chmod a+rx /tmp/execcmds");
+ system("/bin/sh /tmp/execcmds");
+ mwexec("/usr/bin/killall -HUP spamlogd");
+ mwexec("/sbin/pfctl -q -t blacklist -T replace -f /var/db/blacklist.txt");
+ config_unlock();
+}
+
+function basic_auth_prompt(){
+ header("WWW-Authenticate: Basic realm=\".\"");
+ header("HTTP/1.0 401 Unauthorized");
+ echo "You must enter valid credentials to access this resource.";
+ exit;
+}
+
+function add_to_blacklist($srcip) {
+ config_lock();
+ $fd = fopen("/var/db/blacklist.txt", "a");
+ fwrite($fd, "{$srcip}\n");
+ fclose($fd);
+ mwexec("/sbin/pfctl -q -t spamd -T add -f /var/db/blacklist.txt");
+ mwexec("/sbin/pfctl -q -t blacklist -T add -f /var/db/blacklist.txt");
+ config_unlock();
+}
+
+function delete_from_blacklist($srcip) {
+ config_lock();
+ $blacklist = split("\n", file_get_contents("/var/db/blacklist.txt"));
+ $fd = fopen("/var/db/blacklist.txt", "w");
+ foreach($blacklist as $bl) {
+ if($bl <> "")
+ if(!stristr($bl, $srcip))
+ fwrite($fd, "{$bl}\n");
+ }
+ fclose($fd);
+ mwexec("/sbin/pfctl -q -t spamd -T delete $srcip");
+ mwexec("/sbin/pfctl -q -t blacklist -T replace -f /var/db/blacklist.txt");
+ config_unlock();
+}
+
+function delete_from_whitelist($srcip) {
+ config_lock();
+ $whitelist = split("\n", file_get_contents("/var/db/whitelist.txt"));
+ $fd = fopen("/var/db/whitelist.txt", "w");
+ foreach($whitelist as $wl) {
+ if($wl <> "")
+ if(!stristr($wl, $srcip))
+ fwrite($fd, "{$wl}\n");
+ }
+ fclose($fd);
+ mwexec("/sbin/pfctl -q -t spamd -T delete $srcip");
+ mwexec("/sbin/pfctl -q -t whitelist -T replace -f /var/db/whitelist.txt");
+ config_unlock();
+}
+
+function hup_spamd() {
+ mwexec("killall -HUP spamlogd");
+}
+
+exit;
+
+?> \ No newline at end of file
diff --git a/config/spamd/spamd_exchexp.asp b/config/spamd/spamd_exchexp.asp
new file mode 100644
index 00000000..56b0c629
--- /dev/null
+++ b/config/spamd/spamd_exchexp.asp
@@ -0,0 +1,50 @@
+<%
+
+dim server
+server = "SERVERNAME"
+
+Sub ExportUsers(oObject)
+ Dim oUser
+ For Each oUser in oObject
+ Select Case oUser.Class
+ Case "user"
+ If oUser.mail <> "" then
+
+ for each email in oUser.proxyAddresses
+ If (lcase(left(email,4))="smtp") Then
+ 'userFile.WriteLine Mid(email,6)
+ document.write Mid(email,6) & vbCrLf
+ End If
+ next
+ End if
+ Case "organizationalUnit" , "container"
+ If UsersinOU (oUser) then
+ ExportUsers(oUser)
+ End if
+ End select
+ Next
+End Sub
+
+Function UsersinOU (oObject)
+ Dim oUser
+ UsersinOU = False
+ for Each oUser in oObject
+ Select Case oUser.Class
+ Case "organizationalUnit" , "container"
+ UsersinOU = UsersinOU(oUser)
+ Case "user"
+ UsersinOU = True
+
+ End select
+ Next
+End Function
+
+Dim rootDSE, domainObject
+Set rootDSE=GetObject("LDAP://" & server & "/RootDSE")
+domainContainer = rootDSE.Get("defaultNamingContext")
+Set domainObject = GetObject("LDAP://" & domainContainer)
+
+ExportUsers(domainObject)
+Set oDomain = Nothing
+
+%> \ No newline at end of file
diff --git a/config/spamd/spamd_gather_stats.php b/config/spamd/spamd_gather_stats.php
new file mode 100644
index 00000000..a95e2596
--- /dev/null
+++ b/config/spamd/spamd_gather_stats.php
@@ -0,0 +1,82 @@
+#!/usr/local/bin/php -q
+
+<?php
+/* $Id$ */
+/*
+ spamd_gather_stats.php
+ Copyright (C) 2006 Scott Ullrich
+ 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.
+*/
+
+/* read in spamd log file */
+if(file_exists("/var/log/spamd.log"))
+ $log_array = split("\n", file_get_contents("/var/log/spamd.log"));
+
+/* variable to keep track of connections */
+$connections = array();
+
+/* array to track average connection time */
+$connect_times = array();
+
+foreach($log_array as $la) {
+ /* no watson, this is not the city of angels */
+ if (preg_match("/.*spamd\[.*\]\:\s(.*)\: connected\s\((.*)\/(.*)\)/", $la, $matches)) {
+ /* we matched a connect */
+ $ip = $matches[1];
+ $current_connections = $matches[2];
+ $max_connections = $matches[2];
+ $connections[$ip] = false;
+ } else if (preg_match("/.*spamd\[.*\]\:\s(.*)\: disconnected\safter\s(.*)\sseconds\./", $la, $matches)) {
+ /* we matched a disconnect */
+ $ip = $matches[1];
+ $connect_time = $matches[2];
+ $connections[$ip] = true;
+ $connect_times[$ip] = $connect_time;
+ }
+}
+
+$open_connections = 0;
+$average_connect_time = 0;
+
+$total_connections = count($connect_times);
+
+/* loop through, how many connections are open */
+foreach($connections as $c) {
+ if($c == true)
+ $open_connections++;
+}
+
+/* loop through, how many connections are open */
+foreach($connect_times as $c) {
+ $average_connect_time = $average_connect_time + $c;
+}
+
+echo "N:";
+echo $open_connections;
+echo ":";
+echo round(($average_connect_time / $total_connections));
+
+exit;
+
+?> \ No newline at end of file
diff --git a/config/spamd/spamd_outlook.xml b/config/spamd/spamd_outlook.xml
new file mode 100644
index 00000000..5e94701f
--- /dev/null
+++ b/config/spamd/spamd_outlook.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ authng.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2007 to whom it may belong
+ All rights reserved.
+
+ Based on m0n0wall (http://m0n0.ch/wall)
+ Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.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.
+ */
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>spamdoutlook</name>
+ <version>0.1.0</version>
+ <title>SpamD Outlook</title>
+ <aftersaveredirect>pkg_edit.php?xml=spamd_outlook.xml&amp;id=0</aftersaveredirect>
+ <tabs>
+ <tab>
+ <text>SpamD External Sources</text>
+ <url>/pkg.php?xml=spamd.xml</url>
+ </tab>
+ <tab>
+ <text>SpamD Whitelist</text>
+ <url>/pkg.php?xml=spamd_whitelist.xml</url>
+ </tab>
+ <tab>
+ <text>SpamD Settings</text>
+ <url>/pkg_edit.php?xml=spamd_settings.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>SpamD Database</text>
+ <url>/spamd_db.php</url>
+ </tab>
+ </tabs>
+ <!-- configpath gets expanded out automatically and config items will be
+ stored in that location -->
+ <configpath>['installedpackages']['spamd']['config']</configpath>
+ <!-- fields gets invoked when the user adds or edits a item. the following items
+ will be parsed and rendered for the user as a gui with input, and selectboxes. -->
+ <fields>
+ <field>
+ <fielddescr>Username</fielddescr>
+ <fieldname>username</fieldname>
+ <description>Enter the username the outlook clients will use to connect with.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Password</fielddescr>
+ <fieldname>password</fieldname>
+ <description>Enter the password the outlook clients will use to connect with.</description>
+ <type>password</type>
+ </field>
+
+ </fields>
+</packagegui> \ No newline at end of file
diff --git a/config/spamd/spamd_rules.php b/config/spamd/spamd_rules.php
new file mode 100644
index 00000000..27ac850a
--- /dev/null
+++ b/config/spamd/spamd_rules.php
@@ -0,0 +1,34 @@
+
+/*
+ spamd_rules.inc
+ part of pfSense (www.pfSense.com)
+ Copyright (C) 2004 Scott Ullrich (sullrich@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.
+*/
+$wanif = get_real_wan_interface();
+$anchor = "natearly";
+$natrules .= "rdr pass on {$wanif} proto tcp from <spamd> to port smtp -> 127.0.0.1 port spamd\n";
+$natrules .= "rdr pass on {$wanif} proto tcp from !<spamd-white> to port smtp -> 127.0.0.1 port spamd\n";
+$label = "spamd";
+add_rule_to_anchor($anchor, $rule, $label);
diff --git a/config/spamd/spamd_settings.xml b/config/spamd/spamd_settings.xml
new file mode 100644
index 00000000..95c343d1
--- /dev/null
+++ b/config/spamd/spamd_settings.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ spamd_settings.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2008 Scott Ullrich
+ 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.
+ */
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>spamdsettings</name>
+ <version>0.1.0</version>
+ <title>SpamD Settings</title>
+ <aftersaveredirect>pkg_edit.php?xml=spamd_settings.xml&amp;id=0</aftersaveredirect>
+ <include_file>/usr/local/pkg/spamd.inc</include_file>
+ <!-- Menu is where this packages menu will appear -->
+ <menu>
+ <name>SpamD</name>
+ <section>Services</section>
+ <configfile>spamd.xml</configfile>
+ </menu>
+ <service>
+ <name>spamd</name>
+ <rcfile>spamd.sh</rcfile>
+ </service>
+ <tabs>
+ <tab>
+ <text>SpamD External Sources</text>
+ <url>/pkg.php?xml=spamd.xml</url>
+ </tab>
+ <tab>
+ <text>SpamD Whitelist</text>
+ <url>/pkg.php?xml=spamd_whitelist.xml</url>
+ </tab>
+ <tab>
+ <text>SpamD Settings</text>
+ <url>/pkg_edit.php?xml=spamd_settings.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>SpamD Database</text>
+ <url>/spamd_db.php</url>
+ </tab>
+ </tabs>
+ <!-- configpath gets expanded out automatically and config items will be
+ stored in that location -->
+ <configpath>['installedpackages']['spamd']['config']</configpath>
+ <!-- fields gets invoked when the user adds or edits a item. the following items
+ will be parsed and rendered for the user as a gui with input, and selectboxes. -->
+ <fields>
+ <field>
+ <fielddescr>Identifier</fielddescr>
+ <fieldname>identifier</fieldname>
+ <description>The SMTP version banner that is reported upon initial connection.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Maximum blacklisted connections</fielddescr>
+ <fieldname>maxblack</fieldname>
+ <description>The maximum number of concurrent blacklisted connections to allow in greylisting mode. This value may not be greater than maxcon (see below). The default is maxcon - 100.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Max concurrent connections</fielddescr>
+ <fieldname>maxcon</fieldname>
+ <description>The maximum number of concurrent connections to allow. The default is 800.</description>
+ <type>input</type>
+ <value>800</value>
+ </field>
+ <field>
+ <fielddescr>Grey listing</fielddescr>
+ <fieldname>greylisting</fieldname>
+ <description>Connections from addresses not blacklisted on the black lists tab will be considered for greylisting. Such connections will not be stuttered at (though see the stutter secs option) or delayed, and will receive the pleasantly innocuous temporary failure. After passtime if the host returns it will be added to the white list.</description>
+ <type>checkbox</type>
+ <value>yes</value>
+ </field>
+ <field>
+ <fielddescr>Passtime</fielddescr>
+ <fieldname>passtime</fieldname>
+ <description>Adjust the three time parameters for greylisting. Passtime defaults to 25 (minutes). After passtime minutes if spamd sees a retried attempt to deliver mail for the same tuple, spamd will whitelist the connecting address by adding it as a whitelist entry.</description>
+ <type>input</type>
+ <size>30</size>
+ <value>25:4:864</value>
+ </field>
+ <field>
+ <fielddescr>Grey Expiration</fielddescr>
+ <fieldname>greyexp</fieldname>
+ <description>Adjust the three time parameters for greylisting. Grey expiration defaults to 4. SpamD removes connection entries from the database if delivery has not been retried within greyexp hours from the initial time a connection is seen.</description>
+ <type>input</type>
+ <size>30</size>
+ <value>25:4:864</value>
+ </field>
+ <field>
+ <fielddescr>White Exp</fielddescr>
+ <fieldname>whiteexp</fieldname>
+ <description>Adjust the three time parameters for greylisting. White expiration defaults to 864 (hours, approximately 36 days). SpamD removes whitelist entries from the database if no mail delivery activity has been seen from the whitelisted address within whiteexp hours from the initial time an address is whitelisted.</description>
+ <type>input</type>
+ <size>30</size>
+ <value>25:4:864</value>
+ </field>
+ <field>
+ <fielddescr>Stutter Secs</fielddescr>
+ <fieldname>stuttersecs</fieldname>
+ <description>Stutter at greylisted connections for the specified amount of seconds, after which the connection is not stuttered at. Defaults to 10.</description>
+ <type>input</type>
+ <value>10</value>
+ </field>
+ <field>
+ <fielddescr>Delay Secs</fielddescr>
+ <fieldname>delaysecs</fieldname>
+ <description>Delay each character sent to the client by the specified amount of seconds. Defaults to 1.</description>
+ <type>input</type>
+ <value>1</value>
+ </field>
+ <field>
+ <fielddescr>Window Size</fielddescr>
+ <fieldname>window</fieldname>
+ <description>Set the socket receive buffer to this many bytes, adjusting the window size.</description>
+ <type>input</type>
+ <value></value>
+ </field>
+ <!--
+ <field>
+ <fielddescr>Reply SMTP error</fielddescr>
+ <fieldname>replysmtperror</fieldname>
+ <description>The SMTP error to return to the spammer, i.e. 450, 451, 550. This defaults to 450.</description>
+ <type>select</type>
+ <size>1</size>
+ <value>450</value>
+ <options>
+ <option><name></name><value></value></option>
+ <option><name>450</name><value>450</value></option>
+ <option><name>451</name><value>451</value></option>
+ <option><name>550</name><value>550</value></option>
+ </options>
+ </field>
+ -->
+ <field>
+ <fielddescr>NextMTA</fielddescr>
+ <fieldname>nextmta</fieldname>
+ <description>Automatically sends messages after being processed by SpamD to IP Address. You may enter an alias if you like, simply prepend $ to the alias name. example: $mailservers. Note, if you have postfix package installed enter 127.0.0.1 here.</description>
+ <type>input</type>
+ <value>1</value>
+ </field>
+ <field>
+ <fielddescr>Enable RRD graphing</fielddescr>
+ <fieldname>enablerrd</fieldname>
+ <description>Enables the graphing of SpamD connection and disconnection statistics.</description>
+ <type>checkbox</type>
+ <value></value>
+ </field>
+ </fields>
+ <custom_php_validation_command>
+ spamd_validate_input($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ sync_package_spamd();
+ </custom_php_resync_config_command>
+</packagegui> \ No newline at end of file
diff --git a/config/spamd/spamd_verify_to_address.php b/config/spamd/spamd_verify_to_address.php
new file mode 100644
index 00000000..56821370
--- /dev/null
+++ b/config/spamd/spamd_verify_to_address.php
@@ -0,0 +1,144 @@
+#!/usr/local/bin/php -q
+<?php
+/*
+ * pfSense spamd mousetrap
+ * (C)2006 Scott Ullrich
+ *
+ * Reads in an external list of c/r
+ * seperated valid e-mail addresses
+ * and then looks to see waiting grey-
+ * listed servers. if the server is
+ * sending to an invalid e-mail address
+ * then add them to spamtrap.
+ *
+ * Directions for usage:
+ * 1. Download this script to the /root/ directory on your pfSense installation.
+ * 2. chmod a+rx spamd_verify_to_address.php
+ * 3. Edit $server_to_pull_data_from to point to a location containing a list of
+ * all valid email addresses c/r seperated.
+ * 4. Add spamd_verify_to_address.php to cron or run it by invoking
+ * ./spamd_verify_to_address.php manually.
+ *
+ * XXX/TODO:
+ * * Add flag to blacklist a server after receiving X
+ * attempts at a delivery with invalid to: addresses.
+ *
+ */
+
+require("config.inc");
+require("functions.inc");
+
+/* path to script that outputs c/r seperated e-mail addresses */
+$server_to_pull_data_from = "http://10.0.0.11/spamd_exchexp.asp";
+
+/* to enable debugging, change false to true */
+$debug = true;
+
+if($debug)
+ echo "Downloading current valid email list...\n";
+/* fetch down the latest list from server */
+if($debug) {
+ /* fetch without quiet mode */
+ system("fetch -o /tmp/emaillist.txt {$server_to_pull_data_from}");
+} else {
+ /* fetch with quiet mode */
+ system("fetch -q -o /tmp/emaillist.txt {$server_to_pull_data_from}");
+}
+
+/* test if file exists, if not, bail. */
+if(!file_exists("/tmp/emaillist.txt")) {
+ if($debug)
+ echo "Could not fetch $server_to_pull_data_from\n";
+ exit;
+}
+
+/* clean up and split up results */
+$fetched_file = strtolower(file_get_contents("/tmp/emaillist.txt"));
+$valid_list = split("\n", $fetched_file);
+$grey_hosts = split("\n", `spamdb | grep GREY`);
+
+if($fetched_file == "")
+ exit(-1);
+
+if($debug) {
+ /* echo out all our valid hosts */
+ foreach($valid_list as $valid)
+ echo "VALID: ||$valid||\n";
+}
+
+/* suck custom blacklist into array */
+$current_blacklist = split("\n", `cat /var/db/blacklist.txt`);
+/* suck current spamtrap emails into array */
+$current_spamtrap = split("\n", `/usr/local/sbin/spamdb | grep SPAMTRAP | cut -d"|" -f2`);
+/* eliminate <> from email addresses */
+for($x=0; isset($current_spamtrap[$x]); $x++) {
+ $current_spamtrap[$x] = str_replace("<", "", $current_spamtrap[$x]);
+ $current_spamtrap[$x] = str_replace(">", "", $current_spamtrap[$x]);
+}
+
+/* traverse list and find the dictionary attackers, etc */
+foreach($grey_hosts as $grey) {
+ if(trim($grey) == "")
+ continue;
+ /* clean up and further break down values */
+ $grey_lower = strtolower($grey);
+ $grey_lower = str_replace("<","",$grey_lower);
+ $grey_lower = str_replace(">","",$grey_lower);
+ $grey_split = split("\|", $grey_lower);
+ $email_from = strtolower($grey_split[2]);
+ $email_to = strtolower($grey_split[3]);
+ $server_ip = strtolower($grey_split[1]);
+ if(in_array($server_ip, $current_blacklist)) {
+ if($debug)
+ echo "$server_ip already in blacklist.\n";
+ continue;
+ }
+ if(in_array($email_to, $current_spamtrap)) {
+ if($email_to)
+ echo "$email_to already in blacklist.\n";
+ continue;
+ }
+ if($debug)
+ echo "Testing $email_from | $email_to \n";
+ if (in_array($email_to, $valid_list)) {
+ if($debug)
+ echo "$email_to is in the valid list\n";
+ } else {
+ /* spammer picked the wrong person to mess with */
+ if($server_ip) {
+ if($debug)
+ echo "/usr/local/sbin/spamdb -a $server_ip -t\n";
+ exec("/usr/local/sbin/spamdb -d {$server_ip} 2>/dev/null");
+ exec("/usr/local/sbin/spamdb -d {$server_ip} -T 2>/dev/null");
+ exec("/usr/local/sbin/spamdb -d {$server_ip} -t 2>/dev/null");
+ if($debug)
+ echo "/usr/local/sbin/spamdb -a \"<$email_to>\" -T\n";
+ exec("/usr/local/sbin/spamdb -a \"<$email_to>\" -T");
+ config_lock();
+ system("echo $server_ip >> /var/db/blacklist.txt");
+ config_unlock();
+ $result = mwexec("/usr/local/sbin/spamdb -a $server_ip -t");
+ } else {
+ if($debug)
+ echo "Could not locate server ip address.";
+ }
+ if($debug)
+ echo "Script result code: {$result}\n";
+ }
+}
+
+mwexec("killall -HUP spamlogd");
+
+if($debug) {
+ echo "\nSearch completed.\n\n";
+ echo "Items trapped: ";
+ system("/usr/local/sbin/spamdb | grep TRAPPED | wc -l");
+ echo "Items spamtrapped: ";
+ system("/usr/local/sbin/spamdb | grep SPAMTRAP | wc -l");
+ echo "Items in blacklist.txt: ";
+ system("/sbin/pfctl -t blacklist -T show | wc -l");
+}
+
+mwexec("/sbin/pfctl -q -t blacklist -T replace -f /var/db/blacklist.txt");
+
+?> \ No newline at end of file
diff --git a/config/spamd/spamd_whitelist.xml b/config/spamd/spamd_whitelist.xml
new file mode 100644
index 00000000..f7b3f4fe
--- /dev/null
+++ b/config/spamd/spamd_whitelist.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ authng.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2007 to whom it may belong
+ All rights reserved.
+
+ Based on m0n0wall (http://m0n0.ch/wall)
+ Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.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.
+ */
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>spamd-whitelist</name>
+ <version>0.1.0</version>
+ <title>SpamD: Whitelist</title>
+ <!-- Menu is where this packages menu will appear -->
+ <menu>
+ <name>SpamD Whitelist</name>
+ <tooltiptext></tooltiptext>
+ <section>Services</section>
+ <configfile>spamd.xml</configfile>
+ </menu>
+ <tabs>
+ <tab>
+ <text>SpamD External Sources</text>
+ <url>/pkg.php?xml=spamd.xml</url>
+ </tab>
+ <tab>
+ <text>SpamD Whitelist</text>
+ <url>/pkg.php?xml=spamd_whitelist.xml</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>SpamD Settings</text>
+ <url>/pkg_edit.php?xml=spamd_settings.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>SpamD Database</text>
+ <url>/spamd_db.php</url>
+ </tab>
+ </tabs>
+ <!-- configpath gets expanded out automatically and config items will be
+ stored in that location -->
+ <configpath>['installedpackages']['spamdwhitelist']['config']</configpath>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fielddescr>Exempted IP</fielddescr>
+ <fieldname>ip</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Description</fielddescr>
+ <fieldname>description</fieldname>
+ </columnitem>
+ </adddeleteeditpagefields>
+ <!-- fields gets invoked when the user adds or edits a item. the following items
+ will be parsed and rendered for the user as a gui with input, and selectboxes. -->
+ <fields>
+ <field>
+ <fielddescr>Exempted IP</fielddescr>
+ <fieldname>ip</fieldname>
+ <description>Enter the IP to exempt from blacklisting</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Description</fielddescr>
+ <fieldname>description</fieldname>
+ <description>Enter the description for this item</description>
+ <type>input</type>
+ </field>
+ </fields>
+ <custom_php_command_before_form>
+ function sync_package_spamd_whitelist() {
+ global $config;
+ conf_mount_rw();
+ config_lock();
+ /* write out ip to the whitelist db */
+ $fd = fopen("/var/db/whitelist.txt","w");
+ if($config['installedpackages']['spamdwhitelist']['config'] != "") {
+ foreach($config['installedpackages']['spamdwhitelist']['config'] as $spamd) {
+ fwrite($fd, $spamd['ip'] . "\n");
+ }
+ }
+ fclose($fd);
+ /* signal a reload of all files */
+ mwexec("/usr/bin/killall -HUP spamlogd");
+ mwexec("/sbin/pfctl -t spamd-white -T add {$spamd['ip']}");
+ conf_mount_ro();
+ config_unlock();
+ }
+ </custom_php_command_before_form>
+ <custom_delete_php_command>
+ sync_package_spamd_whitelist();
+ </custom_delete_php_command>
+ <custom_php_resync_config_command>
+ sync_package_spamd_whitelist();
+ </custom_php_resync_config_command>
+</packagegui> \ No newline at end of file