aboutsummaryrefslogtreecommitdiffstats
path: root/config/dspam/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'config/dspam/pkg')
-rw-r--r--config/dspam/pkg/000.mysql.sh68
-rw-r--r--config/dspam/pkg/010.clamav-clamd.sh56
-rw-r--r--config/dspam/pkg/020.clamav-freshclam.sh33
-rw-r--r--config/dspam/pkg/030.p3scan.sh60
-rw-r--r--config/dspam/pkg/clamd.conf299
-rw-r--r--config/dspam/pkg/default.prefs.sample43
-rw-r--r--config/dspam/pkg/dspam-config.inc42
-rw-r--r--config/dspam/pkg/dspam-guifunc.inc2606
-rw-r--r--config/dspam/pkg/dspam-pkgfunc.inc548
-rw-r--r--config/dspam/pkg/dspam-utilfunc.inc458
-rw-r--r--config/dspam/pkg/dspam.inc360
-rw-r--r--config/dspam/pkg/dspam.xml342
-rw-r--r--config/dspam/pkg/dspam_alerts.xml147
-rw-r--r--config/dspam/pkg/freshclam.conf110
-rw-r--r--config/dspam/pkg/p3scan-pf-emer.xml127
-rw-r--r--config/dspam/pkg/p3scan-pf-msg.xml198
-rw-r--r--config/dspam/pkg/p3scan-pf-spam.xml119
-rw-r--r--config/dspam/pkg/p3scan-pf-vir.xml162
-rw-r--r--config/dspam/pkg/p3scan-pf.xml211
-rw-r--r--config/dspam/pkg/p3scan.inc277
-rw-r--r--config/dspam/pkg/verdana.ttfbin0 -> 139640 bytes
21 files changed, 6266 insertions, 0 deletions
diff --git a/config/dspam/pkg/000.mysql.sh b/config/dspam/pkg/000.mysql.sh
new file mode 100644
index 00000000..9c25c370
--- /dev/null
+++ b/config/dspam/pkg/000.mysql.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+# This file was automatically generated
+# by the pfSense service handler
+
+rc_start() {
+test_mysql_user=`cat /etc/passwd | grep mysql`
+test_mysql_group=`cat /etc/group | grep mysql`
+mysql_user="mysql"
+mysql_limits_args="-e -U ${mysql_user}"
+pidfile="/var/db/mysql/`/bin/hostname`.pid"
+command="/usr/local/bin/mysqld_safe"
+command_args="--user=${mysql_user} --datadir=/var/db/mysql --pid-file=${pidfile} --bind-address=127.0.0.1 --set-variable=max_connections=500"
+procname="/usr/local/libexec/mysqld"
+mysql_install_db="/usr/local/bin/mysql_install_db"
+mysql_install_db_args="--ldata=/var/db/mysql"
+
+/sbin/mount_fdescfs fdescfs /dev/fd
+
+if [ -z "${test_mysql_group}" ]; then
+ pw groupadd mysql -g 88
+fi
+
+if [ -z "${test_mysql_user}" ]; then
+ pw useradd mysql -u 88 -g 88 -d /nonexistent -s /sbin/nologin -c 'MySQL Daemon'
+fi
+
+if [ ! -d "/var/db/mysql" ]; then
+ mkdir /var/db/mysql && chown mysql:mysql /var/db/mysql
+fi
+
+if [ ! -d "/var/db/mysql/mysql/." ]; then
+ eval $mysql_install_db $mysql_install_db_args >/dev/null
+ [ $? -eq 0 ] && chown -R ${mysql_user}:${mysql_user} /var/db/mysql
+fi
+
+#if checkyesno mysql_limits; then
+# eval `/usr/bin/limits ${mysql_limits_args}` 2>/dev/null
+#else
+# return 0
+#fi
+
+${command} ${command_args} > /dev/null &
+}
+
+rc_stop() {
+/usr/bin/killall mysqld
+sleep 2
+}
+
+rc_restart() {
+ rc_stop
+ rc_start
+}
+
+case $1 in
+ start)
+ rc_start
+ ;;
+ stop)
+ rc_stop
+ ;;
+ restart)
+ rc_restart
+ ;;
+ *)
+ echo "Usage: $0 <start|stop|restart>"
+ ;;
+esac
diff --git a/config/dspam/pkg/010.clamav-clamd.sh b/config/dspam/pkg/010.clamav-clamd.sh
new file mode 100644
index 00000000..aeb23b04
--- /dev/null
+++ b/config/dspam/pkg/010.clamav-clamd.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+# This file was automatically generated
+# by the pfSense service handler
+
+rc_start() {
+test_clamav_group=`cat /etc/group | grep clam`
+test_clamav_user=`cat /etc/passwd | grep clam`
+
+if [ -z "${test_clamav_group}" ]; then
+ pw groupadd clamav -g 106
+fi
+
+if [ -z "${test_clamav_user}" ]; then
+ pw useradd clamav -u 106 -g 106 -d /nonexistent -s /sbin/nologin -c 'Clam Antivirus'
+fi
+
+if [ ! -d "/usr/local/share/clamav" ]; then
+ mkdir /usr/local/share/clamav && chown clamav:clamav /usr/local/share/clamav
+fi
+
+if [ ! -d "/var/log/clamav" ]; then
+ mkdir /var/log/clamav && chown clamav:clamav /var/log/clamav
+fi
+
+if [ ! -d "/var/run/clamav" ]; then
+ mkdir /var/run/clamav && chown clamav:clamav /var/run/clamav
+fi
+
+ /sbin/mount_fdescfs fdescfs /dev/fd
+ /usr/local/sbin/clamd
+}
+
+rc_stop() {
+ /usr/bin/killall clamd
+ sleep 2
+}
+
+rc_restart() {
+ rc_stop
+ rc_start
+}
+
+case $1 in
+ start)
+ rc_start
+ ;;
+ stop)
+ rc_stop
+ ;;
+ restart)
+ rc_restart
+ ;;
+ *)
+ echo "Usage: $0 <start|stop|restart>"
+ ;;
+esac
diff --git a/config/dspam/pkg/020.clamav-freshclam.sh b/config/dspam/pkg/020.clamav-freshclam.sh
new file mode 100644
index 00000000..4332d757
--- /dev/null
+++ b/config/dspam/pkg/020.clamav-freshclam.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+# This file was automatically generated
+# by the pfSense service handler
+
+rc_start() {
+ /sbin/mount_fdescfs fdescfs /dev/fd
+ /usr/local/bin/freshclam --daemon
+}
+
+rc_stop() {
+ /usr/bin/killall freshclam
+ sleep 2
+}
+
+rc_restart() {
+ rc_stop
+ rc_start
+}
+
+case $1 in
+ start)
+ rc_start
+ ;;
+ stop)
+ rc_stop
+ ;;
+ restart)
+ rc_restart
+ ;;
+ *)
+ echo "Usage: $0 <start|stop|restart>"
+ ;;
+esac
diff --git a/config/dspam/pkg/030.p3scan.sh b/config/dspam/pkg/030.p3scan.sh
new file mode 100644
index 00000000..ffd08abf
--- /dev/null
+++ b/config/dspam/pkg/030.p3scan.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+# This file was automatically generated
+# by the pfSense service handler
+
+rc_start() {
+test_p3scan_user=`cat /etc/passwd | grep p3scan`
+test_p3scan_group=`cat /etc/passwd | grep p3scan`
+
+if [ -z "${test_p3scan_group}" ]; then
+ pw groupadd p3scan -g 108
+fi
+
+if [ -z "${test_p3scan_user}" ]; then
+ pw useradd p3scan -u 108 -g p3scan -d /var/spool/p3scan -s /sbin/nologin -c 'P3Scan Daemon'
+fi
+
+if [ ! -d "/var/spool/p3scan" ]; then
+ mkdir /var/spool/p3scan && chown p3scan:p3scan /var/spool/p3scan
+fi
+
+if [ ! -d "/var/spool/p3scan/children" ]; then
+ mkdir /var/spool/p3scan/children && chown p3scan:p3scan /var/spool/p3scan/children
+fi
+
+if [ ! -d "/var/spool/p3scannotify" ]; then
+ mkdir /var/spool/p3scannotify && chown p3scan:p3scan /var/spool/p3scannotify
+fi
+
+if [ ! -d "/var/run/p3scan" ]; then
+ mkdir /var/run/p3scan && chown p3scan:p3scan /var/run/p3scan
+fi
+
+ /sbin/mount_fdescfs fdescfs /dev/fd
+ /usr/local/sbin/p3scan --configfile=/usr/local/etc/p3scan/p3scan.conf &
+}
+
+rc_stop() {
+ /usr/bin/killall p3scan
+ sleep 2
+}
+
+rc_restart() {
+ rc_stop
+ rc_start
+}
+
+case $1 in
+ start)
+ rc_start
+ ;;
+ stop)
+ rc_stop
+ ;;
+ restart)
+ rc_restart
+ ;;
+ *)
+ echo "Usage: $0 <start|stop|restart>"
+ ;;
+esac
diff --git a/config/dspam/pkg/clamd.conf b/config/dspam/pkg/clamd.conf
new file mode 100644
index 00000000..3ce0402f
--- /dev/null
+++ b/config/dspam/pkg/clamd.conf
@@ -0,0 +1,299 @@
+##
+## Example config file for the Clam AV daemon
+## Please read the clamd.conf(5) manual before editing this file.
+##
+
+
+# Comment or remove the line below.
+#Example
+
+# Uncomment this option to enable logging.
+# LogFile must be writable for the user running daemon.
+# A full path is required.
+# Default: disabled
+#LogFile /tmp/clamd.log
+LogFile /var/log/clamav/clamd.log
+
+# By default the log file is locked for writing - the lock protects against
+# running clamd multiple times (if want to run another clamd, please
+# copy the configuration file, change the LogFile variable, and run
+# the daemon with --config-file option).
+# This option disables log file locking.
+# Default: no
+#LogFileUnlock yes
+
+# Maximal size of the log file.
+# Value of 0 disables the limit.
+# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)
+# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size
+# in bytes just don't use modifiers.
+# Default: 1M
+#LogFileMaxSize 2M
+
+# Log time with each message.
+# Default: no
+#LogTime yes
+
+# Also log clean files. Useful in debugging but drastically increases the
+# log size.
+# Default: no
+#LogClean yes
+
+# Use system logger (can work together with LogFile).
+# Default: no
+#LogSyslog yes
+LogSyslog yes
+
+# Specify the type of syslog messages - please refer to 'man syslog'
+# for facility names.
+# Default: LOG_LOCAL6
+#LogFacility LOG_MAIL
+
+# Enable verbose logging.
+# Default: no
+#LogVerbose yes
+
+# This option allows you to save a process identifier of the listening
+# daemon (main thread).
+# Default: disabled
+#PidFile /var/run/clamd.pid
+PidFile /var/run/clamav/clamd.pid
+
+# Optional path to the global temporary directory.
+# Default: system specific (usually /tmp or /var/tmp).
+#TemporaryDirectory /var/tmp
+
+# Path to the database directory.
+# Default: hardcoded (depends on installation options)
+#DatabaseDirectory /var/lib/clamav
+DatabaseDirectory /usr/local/share/clamav
+
+# The daemon works in a local OR a network mode. Due to security reasons we
+# recommend the local mode.
+
+# Path to a local socket file the daemon will listen on.
+# Default: disabled (must be specified by a user)
+#LocalSocket /tmp/clamd
+
+# Remove stale socket after unclean shutdown.
+# Default: no
+FixStaleSocket yes
+
+# TCP port address.
+# Default: no
+TCPSocket 3310
+
+# TCP address.
+# By default we bind to INADDR_ANY, probably not wise.
+# Enable the following to provide some degree of protectiyes
+# from the outside world.
+# Default: no
+TCPAddr 127.0.0.1
+
+# Maximum length the queue of pending connections may grow to.
+# Default: 15
+#MaxConnectionQueueLength 30
+
+# Clamd uses FTP-like protocol to receive data from remote clients.
+# If you are using clamav-milter to balance load between remote clamd daemons
+# on firewall servers you may need to tune the options below.
+
+# Close the connection when the data size limit is exceeded.
+# The value should match your MTA's limit for a maximal attachment size.
+# Default: 10M
+#StreamMaxLength 20M
+
+# Limit port range.
+# Default: 1024
+#StreamMinPort 30000
+# Default: 2048
+#StreamMaxPort 32000
+
+# Maximal number of threads running at the same time.
+# Default: 10
+#MaxThreads 20
+
+# Waiting for data from a client socket will timeout after this time (seconds).
+# Value of 0 disables the timeout.
+# Default: 120
+#ReadTimeout 300
+
+# Waiting for a new job will timeout after this time (seconds).
+# Default: 30
+#IdleTimeout 60
+
+# Maximal depth directories are scanned at.
+# Default: 15
+#MaxDirectoryRecursion 20
+
+# Follow directory symlinks.
+# Default: no
+#FollowDirectorySymlinks yes
+
+# Follow regular file symlinks.
+# Default: no
+#FollowFileSymlinks yes
+
+# Perform internal sanity check (database integrity and freshness).
+# Default: 1800 (30 min)
+#SelfCheck 600
+
+# Execute a command when virus is found. In the command string %v will
+# be replaced by a virus name.
+# Default: no
+#VirusEvent /usr/local/bin/send_sms 123456789 "VIRUS ALERT: %v"
+
+# Run as a selected user (clamd must be started by root).
+# Default: don't drop privileges
+User clamav
+
+# Initialize supplementary group access (clamd must be started by root).
+# Default: no
+AllowSupplementaryGroups yes
+
+# Stop daemon when libclamav reports out of memory condition.
+#ExitOnOOM yes
+
+# Don't fork into background.
+# Default: no
+#Foreground yes
+
+# Enable debug messages in libclamav.
+# Default: no
+#Debug yes
+
+# Do not remove temporary files (for debug purposes).
+# Default: no
+#LeaveTemporaryFiles yes
+
+##
+## Executable files
+##
+
+# PE stands for Portable Executable - it's an executable file format used
+# in all 32-bit versions of Windows operating systems. This option allows
+# ClamAV to perform a deeper analysis of executable files and it's also
+# required for decompression of popular executable packers such as UPX, FSG,
+# and Petite.
+# Default: yes
+#ScanPE yes
+
+# With this option clamav will try to detect broken executables and mark
+# them as Broken.Executable
+# Default: no
+#DetectBrokenExecutables yes
+
+
+##
+## Documents
+##
+
+# This option enables scanning of Microsoft Office document macros.
+# Default: yes
+#ScanOLE2 yes
+
+##
+## Mail files
+##
+
+# Enable internal e-mail scanner.
+# Default: yes
+#ScanMail yes
+
+# If an email contains URLs ClamAV can download and scan them.
+# WARNING: This option may open your system to a DoS attack.
+# Never use it on loaded servers.
+# Default: no
+#MailFollowURLs no
+
+
+##
+## HTML
+##
+
+# Perform HTML normalisation and decryption of MS Script Encoder code.
+# Default: yes
+#ScanHTML yes
+
+
+##
+## Archives
+##
+
+# ClamAV can scan within archives and compressed files.
+# Default: yes
+#ScanArchive yes
+
+# The options below protect your system against Denial of Service attacks
+# using archive bombs.
+
+# Files in archives larger than this limit won't be scanned.
+# Value of 0 disables the limit.
+# Default: 10M
+#ArchiveMaxFileSize 15M
+
+# Nested archives are scanned recursively, e.g. if a Zip archive contains a RAR
+# file, all files within it will also be scanned. This options specifies how
+# deep the process should be continued.
+# Value of 0 disables the limit.
+# Default: 8
+#ArchiveMaxRecursion 10
+
+# Number of files to be scanned within an archive.
+# Value of 0 disables the limit.
+# Default: 1000
+#ArchiveMaxFiles 1500
+
+# If a file in an archive is compressed more than ArchiveMaxCompressionRatio
+# times it will be marked as a virus (Oversized.ArchiveType, e.g. Oversized.Zip)
+# Value of 0 disables the limit.
+# Default: 250
+#ArchiveMaxCompressionRatio 300
+
+# Use slower but memory efficient decompression algorithm.
+# only affects the bzip2 decompressor.
+# Default: no
+#ArchiveLimitMemoryUsage yes
+
+# Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).
+# Default: no
+#ArchiveBlockEncrypted no
+
+# Mark archives as viruses (e.g. RAR.ExceededFileSize, Zip.ExceededFilesLimit)
+# if ArchiveMaxFiles, ArchiveMaxFileSize, or ArchiveMaxRecursion limit is
+# reached.
+# Default: no
+#ArchiveBlockMax no
+
+
+##
+## Clamuko settings
+## WARNING: This is experimental software. It is very likely it will hang
+## up your system!!!
+##
+
+# Enable Clamuko. Dazuko (/dev/dazuko) must be configured and running.
+# Default: no
+#ClamukoScanOnAccess yes
+
+# Set access mask for Clamuko.
+# Default: no
+#ClamukoScanOnOpen yes
+#ClamukoScanOnClose yes
+#ClamukoScanOnExec yes
+
+# Set the include paths (all files in them will be scanned). You can have
+# multiple ClamukoIncludePath directives but each directory must be added
+# in a seperate line.
+# Default: disabled
+#ClamukoIncludePath /home
+#ClamukoIncludePath /students
+
+# Set the exclude paths. All subdirectories are also excluded.
+# Default: disabled
+#ClamukoExcludePath /home/bofh
+
+# Don't scan files larger than ClamukoMaxFileSize
+# Value of 0 disables the limit.
+# Default: 5M
+#ClamukoMaxFileSize 10M
diff --git a/config/dspam/pkg/default.prefs.sample b/config/dspam/pkg/default.prefs.sample
new file mode 100644
index 00000000..d9be27ed
--- /dev/null
+++ b/config/dspam/pkg/default.prefs.sample
@@ -0,0 +1,43 @@
+# $Id$
+# default.prefs v3.2
+# Default preferences for DSPAM
+
+# This file serves two purposes. First, it sets the default preferences each
+# user will see when using the preferences section of the DSPAM Control
+# Center. Second, it may be symbolically linked (or copied) into DSPAM_HOME to
+# set the system-wide default preferences, overriding any commandline or
+# dspam.conf parameters. If symlinked, an administrator can edit these options
+# in the DSPAM Administrative Suite.
+
+# Training Mode: TEFT, TOE, TUM, NOTRAIN
+trainingMode=TEFT
+
+# Spam Action: quarantine, tag
+spamAction=quarantine
+
+# Spam Subject: the text to be prepended onto the subject line of tagged spams
+spamSubject=[SPAM]
+
+# Bayesian Noise Reduction: on/off
+enableBNR=on
+
+# Automatic Whitelisting: on/off
+enableWhitelist=on
+
+# Statistical Sedation: 0-10
+statisticalSedation=5
+
+# Signature Location: message, headers, attachment
+signatureLocation=message
+
+# Whitelist Threshold: the minimum number of innocent hits from a recipient to
+# be automatically whitelisted. Do not set this value too low!
+whitelistThreshold=10
+
+# showFactors: when set to on, the determining factors for each message will
+# be added to a X-DSPAM-Factors message header.
+showFactors=off
+
+# optIn/optOut: Depending on the opt mode set, you can also use one of these.
+#optIn=on
+#optOut=off
diff --git a/config/dspam/pkg/dspam-config.inc b/config/dspam/pkg/dspam-config.inc
new file mode 100644
index 00000000..211bee51
--- /dev/null
+++ b/config/dspam/pkg/dspam-config.inc
@@ -0,0 +1,42 @@
+<?php
+/* $Id$ */
+/* Copyright (C) 2006 Daniel S. Haischt */
+
+$CONFIG = array('DSPAM_HOME' => '/var/db/dspam',
+ 'DSPAM_BIN' => '/usr/local/bin',
+ 'DSPAM' => '/usr/local/bin/dspam',
+ 'DSPAM_STATS' => '/usr/local/bin/dspam_stats',
+ 'DSPAM_WWW' => '/usr/local/pkg',
+ 'DSPAM_ARGS' => '--deliver=innocent --class=innocent ' .
+ '--source=error --user %CURRENT_USER% -d %u',
+ 'DSPAM_ADMIN_GROUP' => 'dspam_admins',
+ 'ALL_PROCS' => 'ps auxw',
+ 'MAIL_QUEUE' => 'mailq | grep \'^[0-9,A-F]\' | wc -l',
+ 'HISTORY_SIZE' => 799,
+ 'HISTORY_PER_PAGE' => 100,
+ 'QUARANTINE_PER_PAGE' => 100,
+ 'HISTORY_DUPLICATES' => 'yes',
+ 'MAX_COL_LEN' => 26,
+ 'QNAV_BUTTONS' => 20,
+ 'HNAV_BUTTONS' => 22,
+ 'SORT_DEFAULT' => 'Rating',
+ '3D_GRAPHS' => 1,
+ 'USE_MAILPARSE' => 1,
+ 'OPTMODE' => 'NONE',
+ 'LOCAL_DOMAIN' => 'localhost',
+ 'AUTODETECT' => 1,
+ 'OPENSOURCE' => 0,
+ /* Is there a website which provides dedicated infos? */
+ 'PACKAGE_WEBSITE' => 'http://www.pfsense.com/',
+ /* Is there a forum which provides dedicated infos? */
+ 'PACKAGE_FORUM' => 'http://www.pfsense.com/',
+ /*
+ * Is there a issue tracker which allows to fill a
+ * support request or a bug report?
+ */
+ 'PACKAGE_TRACKER' => 'http://www.pfsense.com/',
+ /* 'DATE_FORMAT' => '%d.%m.%Y %H:%M' */
+ 'DATE_FORMAT' => '%b %d %H:%M'
+ );
+
+?>
diff --git a/config/dspam/pkg/dspam-guifunc.inc b/config/dspam/pkg/dspam-guifunc.inc
new file mode 100644
index 00000000..121bc8b5
--- /dev/null
+++ b/config/dspam/pkg/dspam-guifunc.inc
@@ -0,0 +1,2606 @@
+<?php
+/* $Id$ */
+/* Copyright (C) 2006 Daniel S. Haischt */
+require_once("functions.inc");
+require_once("dspam.inc");
+
+/* ========================================================================== */
+/* = A D M I N S T A T U S F U N C T I O N S = */
+/* ========================================================================== */
+
+function DisplayAdminPreferences(&$statusmsg) {
+ return DisplayPreferences("admin", $statusmsg);
+}
+
+function DisplayUserStatistics() {
+ global $CONFIG, $DATA;
+ $b = "rowEven";
+
+ $sl_total = 0;
+ $il_total = 0;
+ $sm_total = 0;
+ $fp_total = 0;
+ $sc_total = 0;
+ $ic_total = 0;
+ $mailbox_total = 0;
+
+ $pd = popen("{$CONFIG['DSPAM_STATS']} 2>&1", "r");
+
+ while (!feof($pd)) {
+ $line = chop( fgets($pd, 4096) );
+
+ if ($b == "qrowEven") {
+ $b = "qrowOdd";
+ } else {
+ $b = "qrowEven";
+ }
+
+ $line = preg_replace('/:/', ' ', $line);
+
+ list($username, , $sl, , $il, , $fp, , $sm, , $sc, , $ic)
+ = (preg_split('/\s+/', $line));
+ if ($username == "" && $sl == "") {
+ /* we do not want to display data that
+ * does not bleong to any user
+ */
+ continue;
+ } else if ($sl == "") {
+ $line = fgets($pd, 4096);
+ $line = preg_replace('/:/', ' ', $line);
+ list(, , $sl, , $il, , $fp, , $sm, , $sc, , $ic)
+ = (preg_split('/\s+/', $line));
+ }
+
+ $PREFS =& GetPrefs($username, GetPath($username).".prefs");
+ if ($PREFS['enableBNR'] == "on") { $PREFS['enableBNR'] = "OFF"; }
+ if ($PREFS['enableWhitelist'] == "on") { $PREFS['enableWhitelist'] = "OFF"; }
+ $PREFS['spamAction'] = ucfirst($PREFS['spamAction']);
+ $PREFS['enableBNR'] = strtoupper($PREFS['enableBNR']);
+ $PREFS['enableWhitelist'] = strtoupper($PREFS['enableWhitelist']);
+
+ $mailbox = GetPath($username).".mbox";
+ if ( file_exists($mailbox) ) {
+ $mailbox_size = filesize($mailbox);
+ $mailbox_display = sprintf("%2.1f KB", ($mailbox_size / 1024));
+ $mailbox_total += $mailbox_size;
+ }
+ else {
+ $mailbox_display = "--";
+ }
+
+ $sl_total += $sl;
+ $il_total += $il;
+ $sm_total += $sm;
+ $fp_total += $fp;
+ $sc_total += $sc;
+ $ic_total += $ic;
+
+ $DATA['TABLE'] .= "<tr><td class=\"{$b}\"><a href=\"{$CONFIG['DSPAM_CGI']}?user={$username}\">{$username}</A></td>" .
+ " <td class=\"{$b} rowDivider\" align=\"right\" nowrap=\"nowrap\">{$mailbox_display}</td>" .
+ " <td class=\"{$b} rowDivider\">{$sl}</td>" .
+ " <td class=\"{$b}\">{$il}</td>" .
+ " <td class=\"{$b}\">{$fp}</td>" .
+ " <td class=\"{$b}\">{$sm}</td>" .
+ " <td class=\"{$b}\">{$sc}</td>" .
+ " <td class=\"{$b}\">{$ic}</td>" .
+ " <td class=\"{$b} rowDivider\">{$PREFS['trainingMode']}</td>" .
+ " <td class=\"{$b}\">{$PREFS['spamAction']}</td>" .
+ " <td class=\"{$b}\">{$PREFS['enableBNR']}</td>" .
+ " <td class=\"{$b}\">{$PREFS['enableWhitelist']}</td>" .
+ " <td class=\"{$b}\">{$PREFS['statisticalSedation']}</td>" .
+ " <td class=\"{$b}\">{$PREFS['signatureLocation']}</td>" .
+ "</tr>\n";
+ }
+ pclose($pd);
+
+ $mailbox_total_display = sprintf("%2.1f KB", ($mailbox_total / 1024));
+
+ $b = "listhdrr";
+ $DATA['TABLE'] .= "<tr><td class=\"{$b}\">Total</td>".
+ " <td class=\"{$b} rowDivider\" align=\"right\" nowrap=\"nowrap\">{$mailbox_total_display}</td>".
+ " <td class=\"{$b} rowDivider\">{$sl_total}</td>".
+ " <td class=\"{$b}\">{$il_total}</td>".
+ " <td class=\"{$b}\">{$sm_total}</td>".
+ " <td class=\"{$b}\">{$fp_total}</td>".
+ " <td class=\"{$b}\">{$sc_total}</td>".
+ " <td class=\"{$b}\">{$ic_total}</td>".
+ " <td class=\"{$b} rowDivider\">&nbsp;</td>".
+ " <td class=\"{$b}\">&nbsp;</td>".
+ " <td class=\"{$b}\">&nbsp;</td>".
+ " <td class=\"{$b}\">&nbsp;</td>".
+ " <td class=\"{$b}\">&nbsp;</td>".
+ " <td class=\"{$b}\">&nbsp;</td>".
+ "</tr>\n";
+}
+
+function &DisplayStatus() {
+ global $CONFIG, $DATA;
+
+ $LOG = "{$CONFIG['DSPAM_HOME']}/system.log";
+ $spam_daily = array();
+ $nonspam_daily = array();
+ $period_daily = array();
+ $fp_daily = array();
+ $sm_daily = array();
+ $inoc_daily = array();
+ $whitelist_daily = array();
+ $spam_weekly = array();
+ $nonspam_weekly = array();
+ $period_weekly = array();
+ $fp_weekly = array();
+ $sm_weekly = array();
+ $inoc_weekly = array();
+ $$whitelist_weekly = array();
+ $msgpersecond = array();
+ $classes = array();
+
+ list (, $min, $hour, $mday, $mon, $year, , ,) = (localtime(time()));
+ $hmstart = time() - 60;
+ $daystart = mktime(0, 0, 0, $mon, $mday, $year);
+ $periodstart = $daystart - (3600*24*24); /* 2 Weeks ago */
+ $dailystart = time() - (3600*23);
+ $c_weekly = 0; /* Cursor to most recent time slot */
+ $c_daily = 0;
+
+ if (! file_exists($LOG)) {
+ return $input_errors[] = "No historical data is available (log file »{$LOG}« does not exist).";
+ }
+
+ /* Initialize each individual time period */
+
+ for ($i = 0; $i <= 23; $i++) {
+ $h = To12Hour($hour - (23-$i));
+ $period_daily[$i] = $h;
+ $spam_daily[$i] = 0;
+ $nonspam_daily[$i] = 0;
+ $sm_daily[$i] = 0;
+ $fp_daily[$i] = 0;
+ $inoc_daily[$i] = 0;
+ }
+
+ for ($i = 0; $i <= 23; $i++) {
+ $d = $daystart - (3600 * 24 * (24 - $i));
+ list (, , , $lday, $lmon, $lyear, , ,) = (localtime($d));
+ $lmon++;
+ $lyear += 1900;
+ $period_weekly[$i] = "{$lmon}/{$lday}/{$lyear}";
+ $spam_weekly[$i] = 0;
+ $nonspam_weekly[$i] = 0;
+ $sm_weekly[$i] = 0;
+ $fp_weekly[$i] = 0;
+ $inoc_weekly[$i] = 0;
+ }
+
+ if($fd = @fopen("{$LOG}", "r")) {
+ while (!feof($fd)) {
+ $line = fgets($fd, 4096);
+ list ($t_log, $c_log, , $signature, , $e_log) = preg_split('/\t/', $line);
+ if ($t_log > time()) { continue; }
+
+ $last_message = $t_log;
+
+ /* Only Parse Log Data in our Time Period */
+ if ($t_log >= $periodstart) {
+ list (, $tmin, $thour, $tday, $tmon, $tyear) = (localtime($t_log));
+ $tmon++;
+ $tyear += 1900;
+
+ /* Weekly Graph */
+ $c_weekly = 0;
+ while($period_weekly[$c_weekly] <> "{$tmon}/{$tday}/{$tyear}" && $c_weekly < 24) {
+ $c_weekly++;
+ }
+
+ if ($c_log == "E") {
+ if ($classes[$signature] == "S") {
+ $spam_weekly[$c_weekly]--;
+ if ($spam_weekly[$c_weekly] < 0) { $spam_weekly[$c_weekly] = 0; }
+ } else if ($classes[$signature] == "I") {
+ $nonspam_weekly[$c_weekly]--;
+ if ($nonspam_weekly[$c_weekly] < 0) { $nonspam_weekly[$c_weekly] = 0; }
+ } else if ($classes[$signature] == "W") {
+ $whitelist_weekly[$c_weekly]--;
+ if ($whitelist_weekly[$c_weekly] < 0) { $whitelist_weekly[$c_weekly] = 0; }
+ } else if ($classes[$signature] == "F") {
+ $spam_weekly[$c_weekly]++; $fp_weekly[$c_weekly]--;
+ if ($fp_weekly[$c_weekly] < 0) { $fp_weekly[$c_weekly] = 0; }
+ } else if ($classes[$signature] == "M") {
+ $sm_weekly[$c_weekly]--; $nonspam_weekly[$c_weekly]++;
+ if ($sm_weekly[$c_weekly] < 0) { $sm_weekly[$c_weekly] = 0; }
+ } else if ($classes[$signature] == "N") {
+ $inoc_weekly[$c_weekly]--;
+ if ($inoc_weekly[$c_weekly] < 0) { $inoc_weekly[$c_weekly] = 0; }
+ }
+ } else {
+ $classes[$signature] = $c_log;
+ }
+
+ if ($c_log == "S") { $spam_weekly[$c_weekly]++; }
+ if ($c_log == "I") { $nonspam_weekly[$c_weekly]++; }
+ if ($c_log == "W") { $whitelist_weekly[$c_weekly]++; }
+ if ($c_log == "F")
+ { $spam_weekly[$c_weekly]--; $fp_weekly[$c_weekly]++;
+ if ($spam_weekly[$c_weekly] < 0) { $spam_weekly[$c_weekly] = 0; }
+ }
+ if ($c_log == "M")
+ { $sm_weekly[$c_weekly]++; $nonspam_weekly[$c_weekly]--;
+ if ($nonspam_weekly[$c_weekly] < 0) { $nonspam_weekly[$c_weekly] = 0; }
+ }
+ if ($c_log == "N") { $inoc_weekly[$c_weekly]++; }
+
+
+ /* Daily Graph */
+ if ($t_log >= $dailystart) {
+ while($period_daily[$c_daily] <> To12Hour($thour) && $c_daily < 24) {
+ $c_daily++;
+ }
+
+ if ($c_log == "E") {
+ if ($classes[$signature] == "S") {
+ $spam_daily[$c_daily]--;
+ if ($spam_daily[$c_daily] < 0) { $spam_daily[$c_daily] = 0; }
+ } else if ($classes[$signature] == "I") {
+ $nonspam_daily[$c_daily]--;
+ if ($nonspam_daily[$c_daily] < 0) { $nonspam_daily[$c_daily] = 0; }
+ } else if ($classes[$signature] == "W") {
+ $whitelist_daily[$c_daily]--;
+ if ($whitelist_daily[$c_daily] < 0) { $whitelist_daily[$c_daily] = 0; }
+ } else if ($classes[$signature] == "F") {
+ $spam_daily[$c_daily]++; $fp_daily[$c_daily]--;
+ if ($fp_daily[$c_daily] < 0) { $fp_daily[$c_daily] = 0; }
+ } else if ($classes[$signature] == "M") {
+ $sm_daily[$c_daily]--; $nonspam_daily[$c_daily]++;
+ if ($sm_daily[$c_daily] < 0) { $sm_daily[$c_daily] = 0; }
+ } else if ($classes[$signature] == "N") {
+ $inoc_daily[$c_daily]--;
+ if ($inoc_daily[$c_daily] < 0) { $inoc_daily[$c_daily] = 0; }
+ }
+ }
+
+ if ($c_log == "S") { $spam_daily[$c_daily]++; }
+ if ($c_log == "I") { $nonspam_daily[$c_daily]++; }
+ if ($c_log == "W") { $whitelist_daily[$c_daily]++; }
+ if ($c_log == "F")
+ { $spam_daily[$c_daily]--; $fp_daily[$c_daily]++;
+ if ($spam_daily[$c_daily] < 0) { $spam_daily[$c_daily] = 0; }
+ }
+ if ($c_log == "M")
+ { $sm_daily[$c_daily]++; $nonspam_daily[$c_daily]--;
+ if ($nonspam_daily[$c_daily] < 0) { $nonspam_daily[$c_daily] = 0; }
+ }
+ if ($c_log == "N") { $inoc_daily[$c_daily]++; }
+ }
+
+ /* Last Half-Minute */
+ if ($t_log >= $hmstart) {
+ $msgpersecond[$t_log]++;
+ $DATA['AVG_PROCESSING_TIME'] += $e_log;
+ $keycount_exectime++;
+ }
+ }
+ } // end while
+
+ fclose($fd);
+ } else {
+ return $input_errors[] = "Unable to open logfile: {$LOG}.";
+ } // end if
+
+ /* Calculate Avg. Messages Per Second */
+ foreach(array_values($msgpersecond) as $el) {
+ $DATA['AVG_MSG_PER_SECOND'] += $el;
+ }
+ $DATA['AVG_MSG_PER_SECOND'] /= 60;
+ $DATA['AVG_MSG_PER_SECOND'] = sprintf("%2.2f", $DATA['AVG_MSG_PER_SECOND']);
+
+ /* Calculate Avg. Processing Time */
+ if ($keycount_exectime == 0) {
+ $DATA['AVG_PROCESSING_TIME'] = 0;
+ } else {
+ $DATA['AVG_PROCESSING_TIME'] /= $keycount_exectime;
+ }
+ $DATA['AVG_PROCESSING_TIME'] = sprintf("%01.6f", $DATA['AVG_PROCESSING_TIME']);
+
+ /* Calculate Number of processes, Uptime and Mail Queue length */
+ $pd = popen("{$CONFIG['ALL_PROCS']} | grep dspam | grep -v grep | grep -v cgi | grep -v sock | wc -l", "r");
+ $DATA['DSPAM_PROCESSES'] = fgets($pd, 4096);
+ pclose($pd);
+
+ $pd = popen("uptime", "r");
+ $DATA['UPTIME'] = fgets($pd, 4096);
+ pclose($pd);
+
+ $pd = popen("{$CONFIG['MAIL_QUEUE']}", "r");
+ $DATA['MAIL_QUEUE'] = fgets($pd, 4096);
+ pclose($pd);
+
+ /* Calculate Graphs */
+ $DATA['SPAM_TODAY'] = $spam_weekly[24];
+ $DATA['NONSPAM_TODAY'] = $nonspam_weekly[24];
+ $DATA['SM_TODAY'] = $sm_weekly[24];
+ $DATA['FP_TODAY'] = $fp_weekly[24];
+ $DATA['INOC_TODAY'] = $inoc_weekly[24];
+ $DATA['TOTAL_TODAY'] = $DATA['SPAM_TODAY'] + $DATA['NONSPAM_TODAY'] + $DATA['SM_TODAY']
+ + $DATA['FP_TODAY'] + $DATA['INOC_TODAY'];
+
+ $DATA['SPAM_THIS_HOUR'] = $spam_daily[23];
+ $DATA['NONSPAM_THIS_HOUR'] = $nonspam_daily[23];
+ $DATA['SM_THIS_HOUR'] = $sm_daily[23];
+ $DATA['FP_THIS_HOUR'] = $fp_daily[23];
+ $DATA['INOC_THIS_HOUR'] = $inoc_daily[23];
+ $DATA['TOTAL_THIS_HOUR'] = $DATA['SPAM_THIS_HOUR'] +
+ + $DATA['NONSPAM_THIS_HOUR']
+ + $DATA['SM_THIS_HOUR']
+ + $DATA['FP_THIS_HOUR']
+ + $DATA['INOC_THIS_HOUR'];
+
+ if (is_array($spam_daily) &&
+ is_array($nonspam_daily) &&
+ is_array($sm_daily) &&
+ is_array($fp_daily) &&
+ is_array($inoc_daily) &&
+ is_array($whitelist_daily) &&
+ is_array($period_daily)) {
+ $DATA['DATA_DAILY'] = join(",", $spam_daily)
+ . "_"
+ . join(",", $nonspam_daily)
+ . "_"
+ . join(",", $sm_daily)
+ . "_"
+ . join(",", $fp_daily)
+ . "_"
+ . join(",", $inoc_daily)
+ . "_"
+ . join(",", $whitelist_daily)
+ . "_"
+ . join(",", $period_daily);
+
+ foreach($spam_daily as $el){ $DATA['TS_DAILY'] += $el; };
+ foreach($nonspam_daily as $el){ $DATA['TI_DAILY'] += $el; }
+ foreach($sm_daily as $el){ $DATA['SM_DAILY'] += $el; }
+ foreach($fp_daily as $el){ $DATA['FP_DAILY'] += $el; }
+ foreach($inoc_daily as $el){ $DATA['INOC_DAILY'] += $el; }
+ foreach($whitelist_daily as $el){ $DATA['TI_DAILY'] += $el; }
+ }
+
+ if (is_array($spam_weekly) &&
+ is_array($nonspam_weekly) &&
+ is_array($sm_weekly) &&
+ is_array($fp_weekly) &&
+ is_array($inoc_weekly) &&
+ is_array($whitelist_weekly) &&
+ is_array($period_weekly)) {
+ $DATA['DATA_WEEKLY'] = join(",", $spam_weekly)
+ . "_"
+ . join(",", $nonspam_weekly)
+ . "_"
+ . join(",", $sm_weekly)
+ . "_"
+ . join(",", $fp_weekly)
+ . "_"
+ . join(",", $inoc_weekly)
+ . "_"
+ . join(",", $whitelist_weekly)
+ . "_"
+ . join(",", $period_weekly);
+
+ foreach($spam_weekly as $el){ $DATA['TS_WEEKLY'] += $el; }
+ foreach($nonspam_weekly as $el){ $DATA['TI_WEEKLY'] += $el; }
+ foreach($sm_weekly as $el){ $DATA['SM_WEEKLY'] += $el; }
+ foreach($fp_weekly as $el){ $DATA['FP_WEEKLY'] += $el; }
+ foreach($inoc_weekly as $el){ $DATA['INOC_WEEKLY'] += $el; }
+ foreach($whitelist_weekly as $el){ $DATA['TI_WEEKLY'] += $el; }
+ }
+}
+
+function &DisplayInfos() {
+ global $CONFIG, $DATA, $g;
+ $validity = "valide";
+
+ $pd = @popen("{$CONFIG['DSPAM']} --version", "r");
+ fgets($pd, 4096); // ignore 1st line
+ $DATA['DSPAM_VERSION'] = fgets($pd, 4096);
+ fgets($pd, 4096); // ignore next line
+ $DATA['DSPAM_COPYRIGHT'] = fgets($pd, 4096);
+ $DATA['DSPAM_WEBSITE'] = fgets($pd, 4096);
+ fgets($pd, 4096); // ignore next line
+ $DATA['DSPAM_COPYRIGHT_TEXT'] = fgets($pd, 4096);
+ $DATA['DSPAM_COPYRIGHT_TEXT'] .= " " . fgets($pd, 4096);
+ fgets($pd, 4096); // ignore next line
+ $DATA['DSPAM_CONFIGURE_ARGS'] = str_replace("Configuration parameters: ", "", fgets($pd, 4096));
+
+ pclose($pd);
+
+ if (file_exists("{$g['conf_path']}/nione.lic") &&
+ file_exists("{$g['conf_path']}/nione.lic.sha1")) {
+ if ($fd = @fopen("{$g['conf_path']}/nione.lic", "r")) {
+ $owneru = str_replace("Licensed User: ", "", fgets($fd, 4096));
+ if ($owneru == "") { $validity = "invalide (owner data not found)"; }
+ $ownerc = str_replace("Company: ", "", fgets($fd, 4096));
+ if ($ownerc == "") { $validity = "invalide (company not found)"; }
+ $lkey = str_replace("License Key: ", "", fgets($fd, 4096));
+ if ($lkey == "") { $validity = "invalide (license key not found)"; }
+ $pdate = strtotime( str_replace("Purchase Date: ", "", fgets($fd, 4096)) );
+ if ($pdate == "") { $validity = "invalide (purchase date not found)"; }
+
+ fclose($fd);
+ } else {
+ $validity = "invalide (license files not found)";
+ }
+
+ if(! extension_loaded( 'bcompiler' )) {
+ if(@dl( 'bcompiler.so' )) {
+ require_once ("knione");
+ $gen_lkey = getNIONEKey(trim($owneru), trim($ownerc));
+ if (trim($lkey) <> $gen_lkey) { $validity = "invalide (wrong license key)"; }
+
+ $cdate = mktime(0, 0, 0, date("m"),
+ date("d"),
+ date("Y"));
+
+ $edate = mktime(0, 0, 0, date("m", $pdate),
+ date("d", $pdate),
+ date("Y", $pdate)+1);
+
+ if ($edate < $cdate ||
+ $pdate > $cdate) {
+ $validity = "invalide (license expired)";
+ }
+
+ if ($fd = @fopen("{$g['conf_path']}/nione.lic.sha1", "r")) {
+ $chksum = str_replace("SHA1 (nione.lic) = ", "", fgets($fd, 4096));
+ $chksum_new = sha1_file("{$g['conf_path']}/nione.lic");
+
+ if (trim($chksum) !== trim($chksum_new)) {
+ $validity = "invalide (wrong license file checksum)";
+ }
+
+ fclose($fd);
+ } else {
+ $validity = "invalide (license files not found)";
+ }
+ } else {
+ $validity = "invalide (extension missing, which is necessary to validate license data.)";
+ }
+ }
+ } else {
+ $validity = "invalide (license files not found)";
+ }
+
+ $DATA['OWNER'] = $owneru;
+ $DATA['COMPANY'] = $ownerc;
+ $DATA['LICENSE_KEY'] = $lkey;
+ $DATA['LICENSE_VALIDITY'] = $validity;
+ $DATA['PURCHASE_DATE'] = date("F j, Y", $pdate);
+ $DATA['EXPIRY_DATE'] = date("F j, Y", $edate);
+}
+
+/* ========================================================================== */
+/* = H I S T O R Y F U N C T I O N S = */
+/* ========================================================================== */
+
+function &DisplayFragment($sigID = "",
+ $from = "",
+ $subject = "",
+ $info = "",
+ $time = "") {
+ global $DATA, $USER;
+
+ $sigID = preg_replace('/\/', '///', $sigID);
+
+ $DATA['FROM'] = $from;
+ $DATA['SUBJECT'] = $subject;
+ $DATA['INFO'] = $info;
+ $DATA['TIME'] = $time;
+
+ if($fd = @fopen("{$USER}.frag/{$sigID}.frag", "r")) {
+ while (!feof($fd)) {
+ /* sanitize HTML markup */
+ $line = preg_replace("/</e", "'&lt;'", fgets($fd, 4096));
+ $line = preg_replace("/>/e", "'&gt;'", $line);
+ $DATA['MESSAGE'] .= $line;
+ }
+ fclose($fd);
+ } else {
+ return $input_errors[] = "Unable to open file {$USER}.frag/{$sigID}.frag.";
+ }
+}
+
+function &DisplayHistory($command = "",
+ $sigID= "",
+ $retrainChecked = array(),
+ $username = "",
+ $retrainParam = "",
+ $currentPage = 1,
+ $hPerPage = 0) {
+ global $CONFIG, $USER, $CURRENT_USER, $DATA;
+
+ $buffer = array();
+ $history = array();
+ $rec = array();
+ $rowclass = "rowEven";
+
+ if ($command == "retrainChecked" && count ($retrainChecked) > 0) {
+ foreach($retrainChecked as $el) {
+ list ($retrain, $signature) = split(":", $el);
+ if ($retrain == "innocent") {
+ ProcessFalsePositive(quotemeta($signature));
+ } else if ($retrain == "innocent" || $retrain == "spam") {
+ system("{$CONFIG['DSPAM']} --source=error --class=" . quotemeta($retrain) .
+ " --signature=" . quotemeta($signature) .
+ " --user " . quotemeta($CURRENT_USER));
+ }
+ }
+ // TODO: Do we need the other params which were submited during the current
+ // POS/GET request?
+ pfSenseHeader("/dspam-history.php?user={$username}&page={$currentPage}&hperpage={$hPerPage}");
+ } else {
+ if ($retrainParam <> "") {
+ if ($retrainParam == "innocent") {
+ ProcessFalsePositive();
+ } else {
+ system("{$CONFIG['DSPAM']} --source=error --class=" . quotemeta($retrainParam) .
+ " --signature=" . quotemeta($sigID) .
+ " --user " . quotemeta($CURRENT_USER));
+ }
+ // TODO: Do we need the other params which were submited during the current
+ // POS/GET request?
+ pfSenseHeader("/dspam-history.php?user={$username}&page={$currentPage}&hperpage={$hPerPage}");
+ }
+ }
+
+ $LOG = "{$USER}.log";
+ if (! file_exists($LOG)) {
+ return $input_errors[] = "No historical data is available (log file »{$USER}.log« does not exist).";
+ }
+
+ /* Preseed retraining information and delivery errors */
+
+ $fd = fopen($LOG, "r");
+ while (!feof($fd)) {
+ /* TODO: If the subject line contains a <TAB>, the below array would
+ * contain more then seven elements and thus would be invalide.
+ *
+ * The below code is some kind of a bug fix.
+ */
+ $cline = fgets($fd, 4096);
+ $log_columns = preg_split("/\t/", $cline);
+ list($time, $class, $from, $signature, $subject, $info, $messageid) = $log_columns;
+ if (count ($log_columns) > 7) {
+ /* get values from the array beginning */
+ $time = array_shift($log_columns);
+ $class = array_shift($log_columns);
+ $from = array_shift($log_columns);
+ $signature = array_shift($log_columns);
+ /* get msgid and info from the array end */
+ $messageid = array_pop($log_columns);
+ $info = array_pop($log_columns);
+ /* the remaining parts are belonging to the subject */
+ $subject = implode(" ", $log_columns);
+ }
+
+ if ($signature == "") { continue; }
+ if ($class == "M" || $class == "F" || $class == "E") {
+ if ($class == "E") {
+ $rec[$signature]['info'] = $info;
+ } else if ($class == "F" || $class == "M") {
+ $rec[$signature]['class'] = $class;
+ $rec[$signature]['count']++;
+ if ($rec[$signature]['info'] == "")
+ { $rec[$signature]['info'] = $info; }
+ }
+ /* filter out resents if there are any. Since it's the same
+ * message we only allow retraining on the 1st occurence of it.
+ */
+ } else if ($messageid == "" ||
+ $rec[$signature]['messageid'] != $messageid ||
+ $CONFIG['HISTORY_DUPLICATES'] <> "no") {
+ $rec[$signature]['time'] = $time;
+ $rec[$signature]['class'] = $class;
+ $rec[$signature]['from'] = $from;
+ $rec[$signature]['signature'] = $signature;
+ $rec[$signature]['subject'] = $subject;
+ $rec[$signature]['info'] = $info;
+ $rec[$signature]['messageid'] = $messageid;
+
+ array_unshift($buffer, $rec[$signature]);
+ }
+ } // end while
+ fclose($fd);
+
+ /* if the page size wasn't specified, set a default one */
+ if ($CONFIG['HISTORY_PER_PAGE'] == 0) {
+ $CONFIG['HISTORY_PER_PAGE'] = 50;
+ }
+
+ if (isset($hPerPage) && $hPerPage > 0) {
+ $CONFIG['HISTORY_PER_PAGE'] = $hPerPage;
+ }
+
+ if (isset($currentPage) && isset($CONFIG['HISTORY_PER_PAGE'])) {
+ $pages = ceil( (count ($buffer) / $CONFIG['HISTORY_PER_PAGE']) );
+ $begin = (($currentPage - 1) * $CONFIG['HISTORY_PER_PAGE']);
+ $ranges = ceil ($pages / $CONFIG['HNAV_BUTTONS']);
+
+ /* Now lets just keep the information that we really need. */
+ $buffer = array_splice($buffer, $begin, $CONFIG['HISTORY_PER_PAGE']);
+ }
+
+ $retrain_checked_msg_no = 0;
+ while ($rec = array_pop($buffer)) {
+ $time = $rec['time'];
+ $class = $rec['class'];
+ $from = $rec['from'];
+ $signature = $rec['signature'];
+ $subject = $rec['subject'];
+ $info = $rec['info'];
+ $messageid = $rec['messageid'];
+
+ if ($signature == "") { continue; }
+ if ($rec[$signature]['displayed'] <> "") { continue; }
+ if ($class == "E") { continue; }
+ $rec[$signature]['displayed'] = 1;
+
+ /* Resends of retrained messages will need the original from/subject line */
+ if ($messageid <> "") {
+ if ($from == "<None Specified>") { $from = $rec[$messageid]['from']; }
+ if ($subject == "<None Specified>") { $subject = $rec[$messageid]['subject']; }
+
+
+ if ($rec[$messageid]['from'] == "") { $rec[$messageid]['from'] = $from; }
+ if ($rec[$messageid]['subject'] == "") { $rec[$messageid]['subject'] = $subject; }
+ }
+
+ if ($from == "") { $from = "<None Specified>"; }
+ if ($subject == "") { $subject = "<None Specified>"; }
+
+ $ctime = "";
+ if(isset($CONFIG["DATE_FORMAT"])) {
+ $ctime = strftime($CONFIG["DATE_FORMAT"], localtime($time));
+ } else {
+ /* date format was taken from ctime.pl */
+ $ctime = date ("D M d H:i:s TY",$time);
+ $ttmp = preg_split("/\s+/", $ctime);
+ $t = preg_split("/\:/", $ttmp[3]);
+ $xtmp = preg_split("/\s+/", $ctime);
+ $x = $xtmp[0];
+ $m = "a";
+ if ($t[0] > 12) { $t[0] -= 12; $m = "p"; }
+ if ($t[0] == 0) { $t[0] = 12; }
+ $ctime = "{$x} {$t[0]}:{$t[1]}{$m}";
+ }
+
+ /* Set the appropriate type and label for this message */
+
+ $cl = "";
+ $cllabel = "";
+ if ($rec[$signature]['class'] <> "") { $class = $rec[$signature]['class']; }
+ if ($class == "S") { $cl = "spam"; $cllabel="SPAM"; }
+ else if ($class == "I") { $cl = "innocent"; $cllabel="Good"; }
+ else if ($class == "F") {
+ if (fmod($rec[$signature]['count'], 2) != 0) {
+ $cl = "false"; $cllabel="Miss";
+ } else {
+ $cl = "innocent"; $cllabel="Good";
+ }
+ }
+ else if ($class == "M") {
+ if (fmod($rec[$signature]['count'], 2) != 0) {
+ $cl = "missed"; $cllabel="Miss";
+ } else {
+ $cl = "spam"; $cllabel="SPAM";
+ }
+ }
+ else if ($class == "N") { $cl = "inoculation"; $cllabel="Spam"; }
+ else if ($class == "C") { $cl = "blacklisted"; $cllabel="RBL"; }
+ else if ($class == "W") { $cl = "whitelisted"; $cllabel="Whitelist"; }
+ if ($messageid <> "") {
+ if ($rec[$messageid]['resend'] <> "") {
+ $cl = "relay";
+ $cllabel = "Resend";
+ }
+ $rec[$messageid]['resend'] = $signature;
+ }
+
+ if ($rec[$signature]['info'] <> "") { $info = $rec[$signature]['info']; }
+
+ /* sanitize HTML markup */
+ $from = preg_replace("/</e", "'&lt;'", $from);
+ $from = preg_replace("/>/e", "'&gt;'", $from);
+ $subject = preg_replace('/</e', "'&lt;'", $subject);
+ $subject = preg_replace('/>/e', "'&gt;'", $subject);
+
+ if (strlen($from) > $CONFIG['MAX_COL_LEN']) { $from = substr($from, 0, $CONFIG['MAX_COL_LEN']) . "..."; }
+ if (strlen($subject) > $CONFIG['MAX_COL_LEN']) { $subject = substr($subject, 0, $CONFIG['MAX_COL_LEN']) . "..."; }
+
+ $rclass = "";
+ if ($class == "I" || $class == "W" || $class == "F") { $rclass = "spam"; }
+ if ($class == "S" || $class == "M") { $rclass = "innocent"; }
+
+ $retrain = "";
+ if (preg_match('/^(M|F)$/', $rec[$signature]['class']) > 0 &&
+ fmod($rec[$signature]['count'], 2) != 0) {
+ $retrain = "<b>Retrained</b>";
+ }
+
+ if ($retrain == "") {
+ $retrain = "<A HREF=\"/dspam-history.php?page={$currentPage}&hperpage={$hPerPage}&user={$username}&retrain={$rclass}&signatureID={$signature}\">As " . ucfirst($rclass) . "</A>";
+ } else {
+ $retrain .= "(<A HREF=\"/dspam-history.php?page={$currentPage}&hperpage={$hPerPage}&user={$username}&retrain={$rclass}&signatureID={$signature}\">Undo</A>)";
+ }
+
+ $path = "{$USER}.frag/{$signature}.frag";
+ if (file_exists($path)) {
+ $pairs = array();
+ $pairs['template'] = "fragment";
+ $pairs['signatureID'] = $signature;
+ $sub = $subject;
+ $sub = preg_replace('/#/e', '//', $sub);
+ $sub = preg_replace("/(['])/e", '/\\$1/', $sub);
+ $pairs['subject'] = $sub;
+ $pairs['from'] = $from;
+ $pairs['info'] = $info;
+ $pairs['time'] = $ctime;
+ $pairs['user'] = $username;
+ $pairs['page'] = $currentPage;
+ $pairs['hperpage'] = $hPerPage;
+ $url = SafeVars($pairs);
+ $from = "<a href=\"javascript:openwin(580,400,1,'/dspam-hfragment.php?{$url}')\">{$from}</a>";
+ }
+
+ $entry = <<<EOD
+ <tr>
+ <td align="left" valign="top" class="{$rowclass} {$cl}" nowrap="true"><small>{$cllabel}</small></td>
+ <td align="left" valign="top" class="{$rowclass}" nowrap="true">
+ <small>
+ <input class="formfld" name="msgid{$retrain_checked_msg_no}" id="msgid{$retrain_checked_msg_no}" title="Check/Uncheck" type="checkbox" value="{$rclass}:{$signature}">
+ <label for="msgid{$retrain_checked_msg_no}">{$retrain}</label>
+ </small>
+ </td>
+ <td align="left" valign="top" class="{$rowclass}" nowrap="true"><small>{$ctime}</small></td>
+ <td align="left" valign="top" class="{$rowclass}" nowrap="true"><small>{$from}</small></td>
+ <td align="left" valign="top" class="{$rowclass}" nowrap="true"><small>{$subject}</small></td>
+ <td align="left" valign="top" class="{$rowclass}" nowrap="true"><small>{$info}</small></td>
+ </tr>
+
+EOD;
+
+ $retrain_checked_msg_no++;
+ array_push($history, $entry);
+
+ if ($rowclass == "qrowEven") {
+ $rowclass = "qrowOdd";
+ } else {
+ $rowclass = "qrowEven";
+ }
+ $hurtz++;
+ } // end while
+
+ $entry = <<<EOD
+ <input name="history_page" type="hidden" value="{$history_page}">
+
+EOD;
+ array_push($history, $entry);
+
+ while($line = array_pop($history)) { $DATA['HISTORY'] .= $line; }
+
+ if ($CONFIG['HISTORY_PER_PAGE'] > 0) {
+ /* prepare quarantine navbar */
+ if (($currentPage - 1) >= 1) { $previousPage = $currentPage - 1; }
+ else { $previousPage = 1; }
+
+ if (($currentPage + 1) <= $pages) { $nextPage = $currentPage + 1; }
+ else { $nextPage = $pages; }
+
+ $historyFooterBegin = <<<EOD
+ <tr>
+ <td align="right" valign="middle" class="listtopic" colspan="6">
+ <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="First Page (1)"><a href="/dspam-history.php?page=1&qperpage={$CONFIG['HISTORY_PER_PAGE']}" title="First Page (1)">|&lt;</a></span>&nbsp;
+ <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Page {$previousPage}"><a href="/dspam-history.php?page={$previousPage}&qperpage={$CONFIG['HISTORY_PER_PAGE']}" title="Page {$previousPage}">&lt;</a></span>&nbsp;
+
+EOD;
+
+ $historyFooterEnd = <<<EOD
+ <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Page {$nextPage}"><a href="/dspam-history.php?page={$nextPage}&qperpage={$CONFIG['HISTORY_PER_PAGE']}" title="Page {$nextPage}">&gt;</a></span>&nbsp;
+ <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Last Page ({$pages})"><a href="/dspam-history.php?page={$pages}&qperpage={$CONFIG['HISTORY_PER_PAGE']}" title="Last Page ({$pages})">&gt;|</a></span>
+ </td>
+ </tr>
+
+EOD;
+
+ $ranges_array = array();
+ $rpages = $pages;
+ for ($i = 0; $i < $ranges; $i++) {
+ $range = array();
+ $range['start'] = (($i + 1)* $CONFIG['HNAV_BUTTONS']) - ($CONFIG['HNAV_BUTTONS'] - 1);
+
+ if (($i + 1) == $ranges) {
+ $range['end'] = ($range['start'] + $rpages) - 1;
+ } else {
+ $range['end'] = (($i + 1)* $CONFIG['HNAV_BUTTONS']);
+ $rpages -= $CONFIG['HNAV_BUTTONS'];
+ }
+
+ $ranges_array[$i] = $range;
+ }
+
+ /* generate nav buttons */
+ foreach($ranges_array as $range){
+ if ($currentPage >= $range['start'] && $currentPage <= $range['end']) {
+ for ($i = $range['start']; ; $i++) {
+ if ($i > $range['end']) {
+ break;
+ } else {
+ if ($i == $currentPage) {
+ $historyFooter .= "<span class=\"qnavbtnhl\">{$i}</span>&nbsp\n";
+ } else {
+ $historyFooter .= "<span class=\"qnavbtn\" onmouseover=\"this.style.backgroundColor='#A5B9E1;'\" onmouseout=\"this.style.backgroundColor='#507DCD;'\" title=\"Page {$i}\"><a href=\"/dspam-history.php?page={$i}&hperpage={$CONFIG['HISTORY_PER_PAGE']}\" title=\"Page {$i}\">{$i}</a></span>&nbsp\n";
+ }
+ }
+ }
+ }
+ }
+
+ $DATA['HISTORY_FOOTER'] = $historyFooterBegin . $historyFooter .$historyFooterEnd;
+ $DATA['HPAGES'] = $pages;
+ $DATA['HPAGE'] = $currentPage;
+
+/*
+ $DATA['HISTORY'] .= "<tr><td align=\"left\" valign=\"top\" colspan=\"6\"><center>[";
+ if (($history_pages > 1) && ($history_page > 1)) {
+ $i = $history_page - 1;
+ $DATA['HISTORY'] .= "<a href=\"/dspam-history.php?user={$username}&history_page={$i}\">&nbsp;&lt;&nbsp;</a>";
+ }
+ for($i = 1; $i <= $history_pages; $i++) {
+ if ($i == $history_page) {
+ $DATA['HISTORY'] .= "<a href=\"/dspam-history.php?user={$username}&history_page={$i}\"><big><strong>&nbsp;$i&nbsp;</strong></big></a>";
+ } else {
+ $DATA['HISTORY'] .= "<a href=\"/dspam-history.php?user={$username}&history_page={$i}\">&nbsp;{$i}&nbsp;</a>";
+ }
+ }
+ if (($history_pages > 1) && ($history_page < $history_pages)) {
+ $i = $history_page + 1;
+ $DATA['HISTORY'] .= "<a href=\"/dspam-history.php?user={$username}&history_page={$i}\">&nbsp;&gt;&nbsp;</a>";
+ }
+ $DATA['HISTORY'] .= "]</center></td></tr>";
+*/
+ } // end if
+}
+
+/* ========================================================================== */
+/* = A N A L Y S I S F U N C T I O N S = */
+/* ========================================================================== */
+
+function &DisplayAnalysis() {
+ global $USER, $CURRENT_USER, $CONFIG, $DATA;
+ $LOG = "{$USER}.log";
+
+ $Stats = array(
+ "daily" => array(),
+ "weekly" => array()
+ );
+
+ list(, $min, $hour, $mday, $mon, $year, , ,) = (localtime(time()));
+ $daystart = mktime(0, 0, 0, $mon, $mday, $year);
+ $periodstart = $daystart - (3600 * 24 * 13); /* 2 Weeks ago */
+ $dailystart = time() - (3600 * 23);
+
+ /* TODO: There's an issue that the Perl timelocal returns
+ * different values compared to PHP's mktime. There's a
+ * difference of 2678400, which will be added manually below.
+ */
+ $daystart += 2678400;
+ $periodstart += 2678400;
+
+ if (file_exists($LOG)) {
+ if ($fd = @fopen($LOG, "r")) {
+ $scount = 0;
+ $icount = 0;
+ $wcount = 0;
+ $fcount = 0;
+ $mcount = 0;
+
+ while(!feof($fd)) {
+ $buffer = fgets($fd, 4096);
+ /* drop blank lines */
+ if (strlen($buffer) == 0) { continue; }
+ list($t_log, $c_log) = preg_split("/\t/", $buffer);
+
+ /* Only Parse Log Data in our Time Period */
+ /* TODO: The below if should evaluate to true at least for some data */
+ if ($t_log >= $periodstart) {
+ list(, $tmin, $thour, $tday, $tmon, , , ,) = (localtime($t_log));
+ $tmon++;
+
+ foreach (array('weekly', 'daily') as $period) {
+ $idx = 0;
+ if ($period == "weekly") {
+ $idx= "{$tmon}/{$tday}";
+ } else {
+ if ($t_log <= $dailystart) { continue; }
+ $idx = To12Hour($thour);
+ }
+ if (is_array($Stats[$period]) && ! array_key_exists ($idx, $Stats[$period])) {
+ $Stats[$period][$idx] = array(
+ 'nonspam' => 0,
+ 'spam' => 0,
+ 'title' => $idx,
+ 'idx' => $t_log);
+ }
+ /* TODO: Is passing by reference here correct? */
+ $hr =& $Stats[$period][$idx];
+ /* S => spam */
+ if ($c_log== "S") {
+ $hr['spam']++;
+ $scount++;
+ }
+ /* I => innocent W => whitelisted */
+ if ($c_log == "I" || $c_log == "W") {
+ $hr['nonspam']++;
+ if ($c_log == "I") { $icount++; }
+ else { $wcount++; }
+ }
+ /* F => false positive */
+ if ($c_log == "F") {
+ $hr['spam']--;
+ if ($hr['spam'] < 0) { $hr['spam'] = 0; }
+ $hr['nonspam']++;
+ $fcount++;
+ }
+ /* M => spam miss */
+ if ($c_log == "M") {
+ $hr['nonspam']--;
+ if ($hr['nonspam'] < 0) { $hr['nonspam'] = 0; }
+ $hr['spam']++;
+ $mcount++;
+ }
+ }
+ }
+ }
+
+ fclose($fd);
+ } else {
+ return $input_errors[] = "Unable to open log file: {$LOG}.";
+ }
+
+ usort ((array_values ($Stats[$period])), "cmpArrayValues");
+
+ foreach (array('weekly', 'daily') as $period) {
+ $uc_period = strtoupper($period);
+ $hk = "DATA_{$uc_period}";
+ $lst = array();
+
+ foreach (array_values($Stats[$period]) as $hr) {
+ foreach (array('spam', 'nonspam', 'title') as $type ) {
+
+ if (empty($lst[$type])) {
+ $lst[$type] = array();
+ }
+
+ /* populate (newly) created array */
+ $lst[$type][] = $hr[$type];
+
+ $totk="";
+
+ if ($type == "spam") { $totk="S"; }
+ else if ($type == "nonspam") { $totk="I"; }
+
+ if ($totk == "") { continue; }
+
+ $sk="T{$totk}_{$uc_period}";
+ if (empty($DATA[$sk])) { $DATA[$sk] = 0; }
+
+ $DATA[$sk] += $hr[$type];
+ }
+ } // end foreach
+ $DATA[$hk] =
+ @join(",",$lst['spam']) . "_" .
+ @join(",",$lst['nonspam']) . "_" .
+ @join(",",$lst['title']);
+ } // end foreach
+ } else {
+ return $input_errors[] = "No historical data is available (log file »{$LOG}« does not exist).";
+ } // end if
+}
+
+function cmpArrayValues($a, $b) {
+ if ($a['idx'] == $b['idx'])
+ return 0;
+
+ return ($a['idx'] < $b['idx']) ? -1 : 1;
+}
+
+/* ========================================================================== */
+/* = P E R E F E R E N C E S F U N C T I O N S = */
+/* ========================================================================== */
+
+function &DisplayPreferences($mode = "", &$statusmsg){
+ global $USER, $CURRENT_USER, $CONFIG, $DATA;
+ $FILE = "{$USER}.prefs";
+ $username = $CURRENT_USER;
+
+ if ($_POST) {
+ $pconfig = $_POST;
+
+ if ($pconfig['chk_feature_nr'] <> "on") {
+ $pconfig['chk_feature_nr'] = "off";
+ }
+
+ if ($pconfig['chk_feature_optin'] <> "on") {
+ $pconfig['chk_feature_optin'] = "off";
+ }
+
+ if ($pconfig['chk_feature_optout'] <> "on") {
+ $pconfig['chk_feature_optout'] = "off";
+ }
+
+ if ($pconfig['chk_feature_at'] <> "on") {
+ $pconfig['chk_feature_at'] = "off";
+ }
+
+ if ($pconfig['chk_feature_aw'] <> "on") {
+ $pconfig['chk_feature_aw'] = "off";
+ }
+
+ if ($CONFIG['PREFERENCES_EXTENSION'] == 1) {
+ if ($pconfig['msgtag'] == "") {
+ $pconfig['msgtag'] = "''";
+ } else {
+ $pconfig['msgtag'] = quotemeta($pconfig['msgtag']);
+ }
+
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " trainingMode " . quotemeta($pconfig['rad_train']) . " > /dev/null");
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " spamAction " . quotemeta($pconfig['rad_train_action']) . " > /dev/null");
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " signatureLocation " . quotemeta($pconfig['signatureLocation']) . " > /dev/null");
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " spamSubject " . quotemeta($pconfig['msgtag']) . " > /dev/null");
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " statisticalSedation " . quotemeta($pconfig['rad_filter_sens']) . " > /dev/null");
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " enableBNR " . quotemeta($pconfig['chk_feature_nr']) . " > /dev/null");
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " optOut " . quotemeta($pconfig['chk_feature_optout']) . " >/dev/null");
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " optIn " . quotemeta($pconfig['chk_feature_optin']) . " >/dev/null");
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " showFactors " . quotemeta($pconfig['chk_feature_at']) . " > /dev/null");
+ exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) .
+ " enableWhitelist " . quotemeta($pconfig['chk_feature_aw']) . " > /dev/null");
+ } else {
+ $prefsstr = <<<EOD
+trainingMode={$pconfig['rad_train']}
+spamAction={$pconfig['rad_ident_action']}
+spamSubject={$pconfig['msgtag']}
+statisticalSedation={$pconfig['rad_filter_sens']}
+enableBNR={$pconfig['chk_feature_nr']}
+optIn={$pconfig['chk_feature_optin']}
+optOut={$pconfig['chk_feature_optout']}
+showFactors={$pconfig['chk_feature_at']}
+enableWhitelist={$pconfig['chk_feature_aw']}
+signatureLocation={$pconfig['rad_train_action']}
+
+EOD;
+
+ if ($fd = @fopen("{$FILE}","w")) {
+ fwrite($fd, $prefsstr);
+ fclose($fd);
+ } else {
+ return $input_errors[] = "Unable to write preferences to file: {$FILE}";
+ }
+ }
+
+ $statusmsg = "DSPAM preferences have been written to: {$FILE}.";
+ }
+
+ $PREFS =& GetPrefs($username);
+
+ $DATA["SEDATION_{$PREFS['statisticalSedation']}"] = 'checked="checked"';
+ $DATA["S_{$PREFS['trainingMode']}"] = 'checked="checked"';
+ $DATA["S_ACTION_" . strtoupper($PREFS['spamAction'])] = 'checked="checked"';
+ $DATA["S_LOC_" . strtoupper($PREFS['signatureLocation'])] = 'checked="checked"';
+ $DATA["SPAM_SUBJECT"] = $PREFS['spamSubject'];
+ if ($PREFS['optIn'] == "on") {
+ $DATA['C_OPTIN'] = 'checked="checked"';
+ }
+ if ($PREFS['optOut'] == "on") {
+ $DATA['C_OPTOUT'] = 'checked="checked"';
+ }
+ if ($PREFS['enableBNR'] == "on") {
+ $DATA['C_BNR'] = 'checked="checked"';
+ }
+ if ($PREFS['showFactors'] == "on") {
+ $DATA['C_FACTORS'] = 'checked="checked"';
+ }
+ if ($PREFS['enableWhitelist'] == "on") {
+ $DATA['C_WHITELIST'] = 'checked="checked"';
+ }
+}
+
+function sortByRating($a, $b){
+ if ($a['rating'] == $b['rating']) {
+ return 0;
+ }
+
+ return ($a['rating'] < $b['rating']) ? -1 : 1;
+}
+
+/* ========================================================================== */
+/* = Q U A R A N T I N E F U N C T I O N S = */
+/* ========================================================================== */
+
+function &ProcessQuarantine($signatures = array(),
+ $action = "None",
+ $sortBy = "Rating",
+ $currentPage = 1,
+ $qPerPage = 0){
+ switch($action){
+ case "None":
+ $input_errors =& DisplayQuarantine($sortBy, $currentPage, $qPerPage);
+ break;
+ case "manyNotSpam":
+ $input_errors =& QuarantineManyNotSpam($signatures, $sortBy, $currentPage, $qPerPage);
+ break;
+ case "deleteAll":
+ QuarantineDeleteSpam($action, $signatures, $sortBy, $currentPage, $qPerPage);
+ break;
+ default:
+ QuarantineDeleteSpam();
+ } // switch
+
+ CheckQuarantine();
+
+ return $input_errors;
+}
+
+function &ProcessFalsePositive($sigID = "",
+ $sortBy = "Rating",
+ $currentPage = 1,
+ $qPerPage = 0) {
+ global $MAILBOX, $CONFIG, $TMPFILE, $CURRENT_USER;
+ $buffer = array();
+ $head = array();
+ $singatures = array();
+ $found = 0;
+ $error = false;
+
+ if ($sigID == "") {
+ return $input_errors[] = "No Message ID Specified.";
+ }
+
+ /* read the user's mailbox line by line into a buffer */
+ $fd = fopen("{$MAILBOX}", "r");
+ while (!feof($fd)) {
+ $line = chop(fgets($fd, 4096));
+ array_push($buffer, $line);
+ }
+ fclose ($fd);
+
+ /* iterate over the mailbox buffer */
+ reset($buffer);
+ $i = 0;
+ while ($i < count($buffer)) {
+ $temp = array();
+ $head = array();
+ $mode = 0;
+ $buff = "";
+
+ /* this while tries to iterate over one single mesage including
+ * the message header and the message body.
+ */
+ while((preg_match('/^From /', $buff) == 0) && ($i < count($buffer))) {
+ $buff = $buffer[0];
+
+ /* switch mode if we are hitting DSPAMs
+ * pseudo From QUARANTINE line (without a
+ * colon after the From).
+ */
+ if (preg_match('/^From /', $buff) > 0) {
+ if ($mode == 0) { $mode = 1; }
+ else { continue; }
+ }
+
+ $buff = array_shift($buffer);
+ if (preg_match('/^From /', $buff) == 0) {
+ array_push($temp, $buff);
+ }
+
+ continue;
+ }
+
+ foreach($temp as $tempel) {
+ if ($tempel == "") { break; }
+ list($key, $val) = preg_split('/\: ?/', $tempel, 2);
+ $head[$key] = $val;
+ }
+ if ($head['X-DSPAM-Signature'] == $sigID) {
+ $found = 1;
+ $old_erep = error_reporting(E_ALL);
+ if ($pd = @popen("|{$CONFIG['DSPAM']} {$CONFIG['DSPAM_ARGS']} >{$TMPFILE} 2>&1", "w")) {
+ $pdresult = fread($handle, 2096);
+
+ foreach($temp as $tempel) {
+ fwrite($pd, "{$tempel}\n");
+ }
+
+ pclose($pd);
+ error_reporting($old_erep);
+ } else {
+ $error = true;
+ $input_errors[] = "Unable to ope process pipe in function <code>ProcessFalsePositive</code>.";
+ }
+ }
+ }
+
+ /* Couldn't find the message, so just retrain on signature */
+ if (!$found) {
+ system("$CONFIG{'DSPAM'} --source=error --class=innocent --signature=" . quotemeta($sigID) .
+ " --user " . quotemeta($CURRENT_USER));
+ }
+
+ if ($error) {
+ $log = array();
+ $fd = fopen("{$TMPFILE}", "r");
+ while (!feof($handle)) {
+ $log .= fgets($fd, 4096);
+ }
+ fclose($fd);
+ unlink("{$TMPFILE}");
+ return $input_errors[] = $log;
+ }
+
+ unlink("{$TMPFILE}");
+ $signatures[$sigID] = "on";
+ return QuarantineDeleteSpam("", $signatures, $sortBy, $currentPage, $qPerPage);
+}
+
+function &QuarantineManyNotSpam($signatures = array(), $sortBy = "Rating", $currentPage = 1, $qPerPage = 0){
+ global $MAILBOX, $USER;
+ $buffer = array();
+ $errors = array();
+
+ /* read the user's mailbox line by line into a buffer */
+ $fd = fopen("{$MAILBOX}", "r");
+ while (!feof($fd)) {
+ $line = chop(fgets($fd, 4096));
+ array_push($buffer, $line);
+ }
+ fclose ($fd);
+
+ if ($fd_FILE = @fopen("{$MAILBOX}", "w")) {
+ $fd_RETRAIN = fopen("{$USER}.retrain.log", "a");
+
+ /* iterate over the mailbox buffer */
+ reset($buffer);
+ $i = 0;
+ while ($i < count($buffer)) {
+ $temp = array();
+ $head = array();
+ $mode = 0;
+ $buff = "";
+
+ /* this while tries to iterate over one single mesage including
+ * the message header and the message body.
+ */
+ while((preg_match('/^From /', $buff) == 0) && ($i < count($buffer))) {
+ $buff = $buffer[0];
+
+ /* switch mode if we are hitting DSPAMs
+ * pseudo From QUARANTINE line (without a
+ * colon after the From).
+ */
+ if (preg_match('/^From /', $buff) > 0) {
+ if ($mode == 0) {
+ $mode = 1;
+ $buff = array_shift($buffer);
+ array_push($temp, $buff);
+ $buff = "";
+ continue;
+ } else {
+ continue;
+ }
+ }
+
+ $buff = array_shift($buffer);
+ array_push($temp, $buff);
+
+ continue;
+ }
+
+ /* populate the header array with header fields */
+ foreach($temp as $tempel) {
+ if ($tempel == "") { break; }
+ list($key, $val) = preg_split('/\: ?/', $tempel, 2);
+ $head[$key] = $val;
+ }
+
+ $delivered = 0;
+ if ($signatures["chkmsg-{$head['X-DSPAM-Signature']}"] <> "") {
+ $err = Deliver($temp);
+ if ($err == "") {
+ $delivered = 1;
+ } else {
+ array_push($errors, $err);
+ }
+ }
+ if (!$delivered) {
+ foreach($temp as $tempel) {
+ fwrite($fd_FILE, "{$tempel}\n");
+ }
+ } else {
+ fwrite($fd_RETRAIN, strval(time()) . "\t{$head['X-DSPAM-Signature']}\tinnocent\n");
+ }
+
+ $i++;
+ } // end while
+
+ fclose($fd_FILE);
+ fclose($fd_RETRAIN);
+ } else {
+ return $input_errors[] = "Unable to open mailbox file: {$MAILBOX}.";
+ }
+
+ if (count($errors) > 0) {
+ return $errors;
+ }
+
+ return DisplayQuarantine($sortBy, $currentPage, $qPerPage);
+}
+
+function Deliver($temp = array()) {
+ global $CONFIG;
+
+ if (! file_exists("/tmp/dspam-error-output.txt")) {
+ touch("/tmp/dspam-error-output.txt");
+ }
+ $descriptorspec = array(
+ 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
+ 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
+ 2 => array("file", "/tmp/dspam-error-output.txt", "a") // stderr is a file to write to
+ );
+
+ list($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizeb,
+ $atime,$mtimeb,$ctime,$blksize,$blocks)
+ = stat("/tmp/dspam-error-output.txt");
+ clearstatcache();
+
+ $cwd = '/tmp';
+ $process = @proc_open("{$CONFIG['DSPAM']} {$CONFIG['DSPAM_ARGS']}",
+ $descriptorspec,
+ $pipes);
+
+ if (is_resource($process)) {
+ foreach($temp as $tempel) {
+ if (! @fwrite($pipes[0], "{$tempel}\n")) {
+ return "error while writting to pipe.";
+ }
+ }
+
+ fclose($pipes[0]);
+ fclose($pipes[1]);
+ $return_value = proc_close($process);
+
+ /* this isn't an elegant solution to determine whether
+ * DSPAM did report some errors, but it works for now
+ */
+ list($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizea,
+ $atime,$mtimea,$ctime,$blksize,$blocks)
+ = stat("/tmp/dspam-error-output.txt");
+
+ if ($mtimeb <> $mtimea) { return "DSPAM did report some errors to /tmp/dspam-error-output.txt.\n" .
+ "Please check this particular file."; }
+ } else {
+ return "process is not a resource type.";
+ }
+
+ return "";
+}
+
+function getLayoutedMessage($msgbuffer = "", $sigID = "", $showpart = 0, $ctype = 0){
+
+ if ($msgbuffer == "") {
+ return '<span class="errmsg">An error occured while parsing the message (no message).</span>';
+ }
+ if ($sigID == "") {
+ return '<span class="errmsg">An error occured while parsing the message (no signature).</span>';
+ }
+
+ if( extension_loaded( 'mailparse' ) ) {
+ $msgdate = "N/A";
+ $msgfrom = "N/A";
+ $msgsub = "N/A";
+ $msgto = "N/A";
+
+ $mime = mailparse_msg_create();
+ mailparse_msg_parse($mime, $msgbuffer);
+ /* return an array of message parts - this contsists of the
+ * names of the parts only.
+ */
+ $struct = mailparse_msg_get_structure($mime);
+ $htmlstr = <<<EOD
+ <tr>
+ <td align="left" valign="top" class="listtopic" colspan="3">Message Infos</td>
+ </tr>
+ <tr>
+ <td valign="baseline" class="vncell" colspan="1">Date:</td>
+ <td class="vtable" colspan="2">%MSGDATE%</td>
+ </tr>
+ <tr>
+ <td valign="baseline" class="vncell" colspan="1">From:</td>
+ <td class="vtable" colspan="2">%MSGFROM%</td>
+ </tr>
+ <tr>
+ <td valign="baseline" class="vncell" colspan="1">Subject:</td>
+ <td class="vtable" colspan="2">%MSGSUB%</td>
+ </tr>
+ <tr>
+ <td valign="baseline" class="vncell" colspan="1">To:</td>
+ <td class="vtable" colspan="2">%MSGTO%</td>
+ </tr>
+ <tr>
+ <td class="list" height="12" colspan="3">&nbsp;</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top" class="listtopic">Message Part</td>
+ <td align="left" valign="top" class="listtopic">Part Type</td>
+ <td align="left" valign="top" class="listtopic">Part Encoding</td>
+ </tr>
+ <tr>
+
+EOD;
+
+ /* print a choice of sections */
+ foreach($struct as $st) {
+
+ /* get a handle on the message resource for a subsection */
+ $section = mailparse_msg_get_part($mime, $st);
+ /* get content-type, encoding and header information for that section */
+ $info = mailparse_msg_get_part_data($section);
+
+ /* replace placeholder with real data */
+ if ($info['headers']['date'] <> "") {
+ $htmlstr = str_replace("%MSGDATE%", $info['headers']['date'], $htmlstr);
+ }
+ if ($info['headers']['from'] <> "") {
+ $htmlstr = str_replace("%MSGFROM%", $info['headers']['from'], $htmlstr);
+ }
+ if ($info['headers']['subject'] <> "") {
+ $htmlstr = str_replace("%MSGSUB%", $info['headers']['subject'], $htmlstr);
+ }
+ if ($info['headers']['to'] <> "") {
+ $htmlstr = str_replace("%MSGTO%", $info['headers']['to'], $htmlstr);
+ }
+
+ $fontStyle = "";
+ if ($showpart && $showpart == $st) { $fontStyle = " style=\"font-weight: bolder;\""; }
+
+ if ($info["content-type"] == "text/html") {
+ $htmlstr .= "<td align=\"left\" valign=\"top\" class=\"vncell\"{$fontStyle}>" .
+ "<a href=\"/dspam-viewmsg.php?ctype=1&showpart={$st}&signatureID={$sigID}&command=viewMessage\">{$st}</a>" .
+ "</td>\n";
+ } else {
+ $htmlstr .= "<td align=\"left\" valign=\"top\" class=\"vncell\"{$fontStyle}>" .
+ "<a href=\"/dspam-viewmsg.php?showpart={$st}&signatureID={$sigID}&command=viewMessage\">{$st}</a>" .
+ "</td>\n";
+ }
+
+ $htmlstr .= <<<EOD
+ <td align="left" valign="top" class="vtable"{$fontStyle}>{$info["content-type"]}</td>
+ <td align="left" valign="top" class="vtable"{$fontStyle}>{$info["charset"]}</td>
+ </tr>
+
+EOD;
+ } // end foreach
+
+ /* if we were called to display a part, do so now */
+ if ($showpart) {
+ /* get a handle on the message resource for the desired part */
+ $sec = mailparse_msg_get_part($mime, $showpart);
+
+ $htmlstr .= <<<EOD
+ <tr>
+ <td class="list" height="12" colspan="3">&nbsp;</td>
+ </tr>
+ <tr>
+ <td align="left" valign="top" class="listtopic" colspan="3">Section {$showpart}</td>
+ </tr>
+ <tr>
+ <td align="top" valign="left" colspan="3" class="vncell">
+EOD;
+
+ ob_start();
+ mailparse_msg_extract_part($sec, $msgbuffer);
+ $contents = ob_get_contents();
+ ob_end_clean();
+ $contents = wordwrap( str_replace("&gt;", "&gt;\n", $contents), 100, "\n" );
+ /* quote the message for safe display in a browser */
+ if ($ctype = 1) {
+ /* a html email message */
+ $htmlstr .= "<pre style=\"font-size: 1.4em;\">" . $contents . "</pre></td>\n</tr>\n";
+ } else {
+ /* an ASCII (text) email message */
+ $htmlstr .= htmlentities($contents) . "</td>\n</tr>\n";
+ }
+ }
+
+ return $htmlstr;
+ } else {
+ return '<span class="errmsg">Could not load mailparse extension.</span>';
+ }
+}
+
+function &QuarantineViewMessage($sigID = "",
+ $showpart = 0,
+ $ctype = 0,
+ $sortBy = "Rating",
+ $currentPage = 1,
+ $qPerPage = 0) {
+ global $MAILBOX, $DATA;
+ $buffer = array(); // mailbox buffer
+
+ if ($sigID == "") {
+ return $input_errors[] = "No Message ID Specified.";
+ }
+
+ /* save data to be displayed as HTML form data */
+ $DATA['MESSAGE_ID'] = $sigID;
+ $DATA['SHOWPART'] = $showpart;
+ $DATA['CONTENT_TYPE'] = $ctype;
+ $DATA['QPAGE'] = $currentPage;
+ $DATA['SORTBY'] = $sortBy;
+
+ if ($qPerPage > 0) { $CONFIG['QUARANTINE_PER_PAGE'] = $qPerPage; }
+
+ /* read the user's mailbox line by line into a buffer */
+ $fd = fopen("{$MAILBOX}", "r");
+ while (!feof($fd)) {
+ $line = chop(fgets($fd, 4096));
+ array_push($buffer, $line);
+ }
+ fclose ($fd);
+
+ /* iterate over the mailbox buffer */
+ reset($buffer);
+ $i = 0;
+ while ($i < count($buffer)) {
+ $temp = array();
+ $head = array();
+ $mode = 0;
+ $buff = "";
+
+ /* this while tries to iterate over one single mesage including
+ * the message header and the message body.
+ */
+ while((preg_match('/^From /', $buff) == 0) && ($i < count($buffer))) {
+ $buff = $buffer[0];
+
+ /* switch mode if we are hitting DSPAMs
+ * pseudo From QUARANTINE line (without a
+ * colon after the From).
+ */
+ if (preg_match('/^From /', $buff) > 0) {
+ if ($mode == 0) { $mode = 1; }
+ else { continue; }
+ }
+
+ $buff = array_shift($buffer);
+ if (preg_match('/^From /', $buff) == 0) {
+ array_push($temp, $buff);
+ }
+
+ continue;
+ }
+
+ /* populate the header array with header fields */
+ foreach($temp as $tempel) {
+ if ($tempel == "") { break; }
+ list($key, $val) = preg_split('/\: ?/', $tempel, 2);
+ $head[$key] = $val;
+ }
+ if ($head['X-DSPAM-Signature'] == $sigID) {
+ foreach($temp as $tempel) {
+ $tempel = preg_replace("/</e", "'&lt;'", $tempel);
+ $tempel = preg_replace("/>/e", "'&gt;'", $tempel);
+ $DATA['MESSAGE'] .= "{$tempel}\n";
+ }
+ }
+
+ $i ++;
+ } // end while
+}
+
+function QuarantineDeleteSpam($deleteAll = "", $signatures = array(), $sortBy = "Rating", $currentPage = 1, $qPerPage = 0){
+ global $USER, $MAILBOX;
+ $buffer = array();
+
+ /* this is the most easiest operation: If the user wants
+ * to completly delete any quarantined message, simply
+ * open his mailbox in write mode, which empties the
+ * user's mailbox file.
+ */
+ if ($deleteAll <> "") {
+
+ list($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+ $atime,$mtime,$ctime,$blksize,$blocks) = stat("{$USER}.mbox");
+
+ $fd = fopen("{$USER}.mbox.size", "r");
+ $sz = chop(fgets($fd, 4096));
+ fclose($fd);
+
+ if ($sz == $size) {
+ $fd = fopen("{$MAILBOX}", "w");
+ fclose($fd);
+ unlink("{$USER}.mbox.size");
+ unlink("{$USER}.mboxwarn");
+ } else {
+ return DisplayQuarantine($sortBy, $currentPage, $qPerPage);
+ }
+
+ //$FORM{'template'} = "performance";
+ CheckQuarantine();
+ return DisplayIndex();
+ }
+
+ /* iterate over the user's mailbox and store its contents in a buffer */
+ $fd = fopen("{$MAILBOX}", "r");
+ while (!feof($fd)) {
+ $line = chop(fgets($fd, 4096));
+ array_push($buffer, $line);
+ }
+ fclose($fd);
+
+ /* open the user's mailbox in write mode. This empties the mailbox! */
+ fopen("{$MAILBOX}", "w");
+
+ /* iterate over the mailbox buffer */
+ reset($buffer);
+ $i = 0;
+ while ($i < count($buffer)) {
+ $temp = array();
+ $head = array();
+ $mode = 0;
+
+ /* this while tries to iterate over one single mesage including
+ * the message header and the message body.
+ */
+ while((preg_match('/^From /', $buff) == 0) && ($i < count($buffer))) {
+ $buff = $buffer[0];
+
+ /* switch mode if we are hitting DSPAMs
+ * pseude From QUARANTINE line (without a
+ * colon after the From).
+ */
+ if (preg_match('/^From /', $buff) > 0) {
+ if ($mode == 0) {
+ $mode = 1;
+ $buff = array_shift($buffer);
+ array_push($temp, $buff);
+ $buff = "";
+ continue;
+ } else {
+ continue;
+ }
+ }
+ $buff = array_shift($buffer);
+ array_push($temp, $buff);
+
+ continue;
+ }
+
+ /* populate the header array with header fields */
+ foreach($temp as $tempel) {
+ if ($tempel == "") { break; }
+ list($key, $val) = preg_split('/\: ?/', $tempel, 2);
+ $head[$key] = $val;
+ }
+
+ /* if the current DSPAM signature wasn't selected by the
+ * user to be deleted, write it back to the user's mailbox.
+ */
+ if ($signatures["chkmsg-{$head['X-DSPAM-Signature']}"] == "") {
+ foreach($temp as $tempel) {
+ fwrite($fd, "{$tempel}\n");
+ }
+ }
+
+ $i++;
+ } // end while
+ fclose($fd);
+
+ return;
+}
+
+function sortBySubject($a, $b){
+ $lca = strtolower ($a['Subject']);
+ $lcb = strtolower ($b['Subject']);
+
+ return strcmp($lca, $lcb);
+}
+
+function sortByFrom($a, $b){
+ $lca = strtolower ($a['From']);
+ $lcb = strtolower ($b['From']);
+
+ return strcmp($lca, $lcb);
+}
+
+function &DisplayQuarantine($sortBy = "Rating", $currentPage = 1, $qPerPage = 0) {
+ global $USER, $CURRENT_USER, $CONFIG, $DATA, $MAILBOX;
+ $alertcfg = &$config['installedpackages']['dspamalerts']['config'];
+ $alerts = array();
+
+ if (file_exists("{$USER}.mbox")) {
+ list($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+ $atime,$mtime,$ctime,$blksize,$blocks) = stat("{$USER}.mbox");
+
+ $fd = fopen("{$USER}.mbox.size", "w");
+ fwrite($fd, "{$size}");
+ fclose($fd);
+
+ $fd = fopen("{$MAILBOX}.stamp", "a+");
+ fclose($fd);
+ chmod("{$MAILBOX}.stamp", 0660);
+
+ /* process alert names */
+ if (is_array($alertcfg)) {
+ $alert_counter = 0;
+
+ foreach ($alertcfg as $alert) {
+ $alerts[$alert_counter] = $alert['alertname'];
+ $alert_counter++;
+ }
+ }
+
+ $mode = "";
+ $buffer = array();
+ $headings = array();
+ $rowclass = "qrowEven";
+ $fd = fopen("{$MAILBOX}", "r");
+
+ while (!feof($fd)) {
+ $mbxline = chop(fgets($fd, 4096));
+
+ if ($mbxline <> "") {
+ if (($mode == "")) {
+ if (preg_match('/^From /', $mbxline) > 0) {
+ $mode = 1;
+ } else {
+ continue;
+ }
+ }
+
+ array_push($buffer, $mbxline);
+ continue;
+ }
+
+ if ($mode == "") { continue; }
+
+ $alert = 0;
+ $new = array();
+
+ foreach($buffer as $buf_element){
+ foreach($alerts as $al){
+ if (preg_match("/{$al}/i", $buf_element) > 0) {
+ $alert = 1;
+ }
+ }
+
+ if (preg_match('/^From /', $buf_element) > 0) {
+ $a = split(' ', $buf_element);
+ $x = 2;
+
+ for ($i = 0; $i < count ($a); $i++) {
+ if ((preg_match('/\@|>/', $a[$i]) > 0) && $i > $x) {
+ $x = $i + 1;
+ }
+ }
+
+ for ($i = 1; $i < $x; $i++) { array_shift($a); }
+ $start = join(" ", $a);
+ } else {
+ list($key, $val) = preg_split('/\: ?/', $buf_element, 2);
+ $new[$key] = $val;
+ }
+ }
+
+ if ($rowclass == "qrowEven") {
+ $rowclass = "qrowOdd";
+ } else {
+ $rowclass = "qrowEven";
+ }
+
+ $new['alert'] = $alert;
+
+ if ($alert) { $rowclass="qrowAlert"; }
+
+ $new['Sub2'] = $new['X-DSPAM-Signature'];
+ if (strlen($new['Subject']) > $CONFIG['MAX_COL_LEN']) {
+ $new['Subject'] = substr($new['Subject'], 0, $CONFIG['MAX_COL_LEN']) . "...";
+ }
+
+ if (strlen($new['From']) > $CONFIG['MAX_COL_LEN']) {
+ $new['From'] = substr($new['From'], 0, $CONFIG['MAX_COL_LEN']) . "...";
+ }
+
+ if ($new['Subject'] == "") {
+ $new['Subject'] = "<None Specified>";
+ }
+
+ //$new->{'rating'} = $new->{'X-DSPAM-Probability'} * $new->{'X-DSPAM-Confidence'};
+ $new['rating'] = $new['X-DSPAM-Confidence'];
+
+ foreach(array_keys($new) as $key) {
+ if ($key == "X-DSPAM-Signature") { continue; }
+ preg_replace('/</', '/\&lt\;/', $new[$key]);
+ preg_replace('/>/', '/\&gt\;/', $new[$key]);
+ }
+
+ array_push($headings, $new);
+
+ $buffer = array();
+ $mode = "";
+ continue;
+ } // end while (!feof($fd))
+
+ if (! isset($sortBy) || $sortBy == "") {
+ $sortBy = $CONFIG['SORT_DEFAULT'];
+ }
+ if ($sortBy == "Rating") {
+ usort($headings, "sortByRating");
+ }
+ if ($sortBy == "Subject") {
+ usort($headings, "sortBySubject");
+ }
+ if ($sortBy == "From") {
+ usort($headings, "sortByFrom");
+ }
+ if ($sortBy == "Date") {
+ array_reverse ($headings);
+ }
+
+ /*
+
+ <tr>
+ <td align="left" valign="top" class="listtopic" width="8%">&nbsp;</td>
+ <td align="left" valign="top" class="listtopic" width="5%" onclick="sortmsg('Rating');" style="cursor: pointer;">Rating</td>
+ <td align="left" valign="top" class="listtopic" width="20%" onclick="sortmsg('Date');" style="cursor: pointer;">Date</td>
+ <td align="left" valign="top" class="listtopic" width="25%" onclick="sortmsg('From');" style="cursor: pointer;">From</td>
+ <td align="left" valign="top" class="listtopic" width="42%" onclick="sortmsg('Subject');" style="cursor: pointer;">Subject</td>
+ </tr>
+
+ */
+
+ $DATA['SORTBY'] = $sortBy;
+ $DATA['SORT_SELECTOR'] .= <<<EOD
+ <tr>
+ <td align="left" valign="top" class="listtopic" width="10%">&nbsp;</td>
+
+EOD;
+
+ if ($sortBy == "Rating") {
+ $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"5%\" onclick=\"sortmsg('Rating');\" style=\"cursor: pointer;\">Rating&nbsp;&nbsp;&loz;</td>";
+ } else {
+ $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"5%\" onclick=\"sortmsg('Rating');\" style=\"cursor: pointer;\">Rating</td>";
+ }
+ if ($sortBy == "Date") {
+ $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"20%\" onclick=\"sortmsg('Date');\" style=\"cursor: pointer;\">Date&nbsp;&nbsp;&loz;</td>";
+ } else {
+ $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"20%\" onclick=\"sortmsg('Date');\" style=\"cursor: pointer;\">Date</td>";
+ }
+ if ($sortBy == "Subject") {
+ $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"40%\" onclick=\"sortmsg('Subject');\" style=\"cursor: pointer;\">Subject&nbsp;&nbsp;&loz;</td>";
+ } else {
+ $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"40%\" onclick=\"sortmsg('Subject');\" style=\"cursor: pointer;\">Subject</td>";
+ }
+ if ($sortBy == "From") {
+ $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"25%\" onclick=\"sortmsg('From');\" style=\"cursor: pointer;\">From&nbsp;&nbsp;&loz;</td>";
+ } else {
+ $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"25%\" onclick=\"sortmsg('From');\" style=\"cursor: pointer;\">From</td>";
+ }
+
+ $DATA{'SORT_SELECTOR'} .= "\n </tr>";
+
+ if (isset($qPerPage) && $qPerPage > 0) {
+ $CONFIG['QUARANTINE_PER_PAGE'] = $qPerPage;
+ }
+
+ if (isset($currentPage) && isset($CONFIG['QUARANTINE_PER_PAGE'])) {
+ $pages = ceil( (count ($headings) / $CONFIG['QUARANTINE_PER_PAGE']) );
+ $begin = (($currentPage - 1) * $CONFIG['QUARANTINE_PER_PAGE']);
+ $ranges = ceil ($pages / $CONFIG['QNAV_BUTTONS']);
+
+ /* Now lets just keep the information that we really need. */
+ $headings = array_splice ($headings, $begin, $CONFIG['QUARANTINE_PER_PAGE']);
+ }
+
+ $rowclass = "qrowEven";
+ foreach ($headings as $row) {
+ $rating = sprintf("%3.0f%%", $row['rating'] * 100.0);
+ if ($row['rating'] > 0.8) {
+ $markclass = "high";
+ } else {
+ if ($row['rating'] < 0.7) {
+ $markclass = "low";
+ } else {
+ $markclass = "medium";
+ }
+ }
+
+ $PAIRS = array();
+
+ $PAIRS['signatureID'] = $row['X-DSPAM-Signature'];
+ $PAIRS['command'] = "viewMessage";
+ $PAIRS['user'] = $CURRENT_USER;
+ $PAIRS['page'] = $currentPage;
+ $PAIRS['sortby'] = $sortBy;
+ $PAIRS['qperpage'] = $CONFIG['QUARANTINE_PER_PAGE'];
+ // $PAIRS['template'] = "quarantine";
+
+ $url = SafeVars($PAIRS);
+ $sender = htmlentities ($row['From']);
+ $rsubject = htmlentities ($row['Subject']);
+
+ if ($row['alert']) {
+ $outclass = "qrowAlert";
+ } else {
+ $outclass = $rowclass;
+ }
+
+ $ptfields = preg_split('/\s+/', $row['X-DSPAM-Processed']);
+ $times = preg_split('/\:/', $ptfields[3]);
+ $ptime = "";
+ if($CONFIG["DATE_FORMAT"]) {
+ $month = array();
+ $month['Jan'] = 0;
+ $month['Feb'] = 1;
+ $month['Mar'] = 2;
+ $month['Apr'] = 3;
+ $month['May'] = 4;
+ $month['Jun'] = 5;
+ $month['Jul'] = 6;
+ $month['Aug'] = 7;
+ $month['Sep'] = 8;
+ $month['Oct'] = 9;
+ $month['Nov'] = 10;
+ $month['Dec'] = 11;
+ $ptime = strftime($CONFIG["DATE_FORMAT"],
+ mktime($times[2],
+ $times[1],
+ $times[0],
+ $ptfields[2],
+ $month[$ptfields[1]],
+ $ptfields[4] - 1900));
+ } else {
+ $mer = "a";
+ if ($times[0] > 12) { $times[0] -= 12; $mer = "p"; }
+ if ($times[0] == 0) { $times[0] = "12"; }
+ $ptime = "{$ptfields[1]} {$ptfields[2]} {$times[0]}:{$times[1]}{$mer}";
+ }
+
+ /*
+
+ <tr>
+ <td align="left" valign="top" class="vncell">
+ <input type="checkbox" class="formfld" title="check" alt="check" name="chkmsg" id="" />
+ </td>
+ <td align="left" valign="top" class="vncell">
+ <span style="color: darkblue; font-weight: bold;">50%</span>
+ </td>
+ <td align="left" valign="top" class="vncell">Apr 1 05:59a</td>
+ <td align="left" valign="top" class="vncell">Mar 30 11:08a</td>
+ <td align="left" valign="top" class="vncell">
+ <u>Last chance to register for Frankfurt, 4 April BEA...</u>
+ </td>
+ </tr>
+
+ <tr>
+ <td align="left" valign="top" class="{$outclass}" nowrap="true">
+ <input type="checkbox" class="formfld" title="check" alt="check" name="{$row['X-DSPAM-Signature']}" id="{$row['X-DSPAM-Signature']}" />
+ </td>
+ <td align="left" valign="top" class="{$outclass} {$markclass}" nowrap="true">
+ {$rating}
+ </td>
+ <td align="left" valign="top" class="{$outclass}" nowrap="true">{$ptime}</td>
+ <td align="left" valign="top" class="{$outclass}" nowrap="true">{$row['From']}</td>
+ <td align="left" valign="top" class="{$outclass}" nowrap="true">
+ <a href="{$CONFIG['ME']}?{$url}">{$row['Subject']}</a>
+ </td>
+ </tr>
+ */
+
+ $DATA['QUARANTINE'] .= <<<EOD
+ <tr>
+ <td align="left" valign="top" class="{$outclass}" nowrap="true">
+ <input type="checkbox" class="formfld" title="check" alt="check" name="chkmsg-{$row['X-DSPAM-Signature']}" id="{$row['X-DSPAM-Signature']}" />
+ </td>
+ <td align="left" valign="top" class="{$outclass} {$markclass}" nowrap="true">
+ {$rating}
+ </td>
+ <td align="left" valign="top" class="{$outclass}" nowrap="true">{$ptime}</td>
+ <td align="left" valign="top" class="{$outclass}" nowrap="true">{$sender}</td>
+ <td align="left" valign="top" class="{$outclass}" nowrap="true">
+ <a href="/dspam-viewmsg.php?{$url}">{$rsubject}</a>
+ </td>
+ </tr>
+
+EOD;
+
+ if ($rowclass == "qrowEven") {
+ $rowclass = "qrowOdd";
+ } else {
+ $rowclass = "qrowEven";
+ }
+ } // end foreach ($headings as $row)
+
+ /* prepare quarantine navbar */
+ if (($currentPage - 1) >= 1) { $previousPage = $currentPage - 1; }
+ else { $previousPage = 1; }
+
+ if (($currentPage + 1) <= $pages) { $nextPage = $currentPage + 1; }
+ else { $nextPage = $pages; }
+
+ $quarantineFooterBegin = <<<EOD
+ <tr>
+ <td align="left" valign="top" class="listtopic">
+ <input type="checkbox" class="formfld" title="check all" alt="check all" name="checkall" id="checkall" onClick="checkallmsgs();" />
+ <label for="checkall">All</label>
+ </td>
+ <td align="right" valign="middle" class="listtopic" colspan="4">
+ <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="First Page (1)"><a href="/dspam-quarantine.php?page=1&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}" title="First Page (1)">|&lt;</a></span>&nbsp;
+ <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Page {$previousPage}"><a href="/dspam-quarantine.php?page={$previousPage}&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}" title="Page {$previousPage}">&lt;</a></span>&nbsp;
+
+EOD;
+
+ $quarantineFooterEnd = <<<EOD
+ <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Page {$nextPage}"><a href="/dspam-quarantine.php?page={$nextPage}&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}" title="Page {$nextPage}">&gt;</a></span>&nbsp;
+ <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Last Page ({$pages})"><a href="/dspam-quarantine.php?page={$pages}&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}" title="Last Page ({$pages})">&gt;|</a></span>
+ </td>
+ </tr>
+
+EOD;
+
+ $ranges_array = array();
+ $rpages = $pages;
+ for ($i = 0; $i < $ranges; $i++) {
+ $range = array();
+ $range['start'] = (($i + 1)* $CONFIG['QNAV_BUTTONS']) - ($CONFIG['QNAV_BUTTONS'] - 1);
+
+ if (($i + 1) == $ranges) {
+ $range['end'] = ($range['start'] + $rpages) - 1;
+ } else {
+ $range['end'] = (($i + 1)* $CONFIG['QNAV_BUTTONS']);
+ $rpages -= $CONFIG['QNAV_BUTTONS'];
+ }
+
+ $ranges_array[$i] = $range;
+ }
+
+ /* generate nav buttons */
+ foreach($ranges_array as $range){
+ if ($currentPage >= $range['start'] && $currentPage <= $range['end']) {
+ for ($i = $range['start']; ; $i++) {
+ if ($i > $range['end']) {
+ break;
+ } else {
+ if ($i == $currentPage) {
+ $quarantineFooter .= "<span class=\"qnavbtnhl\">{$i}</span>&nbsp\n";
+ } else {
+ $quarantineFooter .= "<span class=\"qnavbtn\" onmouseover=\"this.style.backgroundColor='#A5B9E1;'\" onmouseout=\"this.style.backgroundColor='#507DCD;'\" title=\"Page {$i}\"><a href=\"/dspam-quarantine.php?page={$i}&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}\" title=\"Page {$i}\">{$i}</a></span>&nbsp\n";
+ }
+ }
+ }
+ }
+ }
+
+ $DATA['QUARANTINE_FOOTER'] = $quarantineFooterBegin . $quarantineFooter .$quarantineFooterEnd;
+ $DATA['QPAGES'] = $pages;
+ $DATA['QPAGE'] = $currentPage;
+ } else {
+ $input_errors[] = "Unable to open DSPAM quarantine mailbox at »{$USER}.mbox«. " .
+ "If you are a DSPAM admin user you can savely " .
+ "ignore this error because such users usually do not " .
+ "have a DSPAM mailbox/quarantine.";
+ }
+
+ return $input_errors;
+}
+
+/* ========================================================================== */
+/* = P E R F O R M A N C E F U N C T I O N S = */
+/* ========================================================================== */
+
+function ResetStats() {
+ global $USER;
+
+ $fd = fopen("{$USER}.stats", "r");
+ $ts = chop(fgets($fd, 4096));
+ $group = chop(fgets($fd, 4096));
+ fclose($fd);
+ list($ts, $ti, $tm, $fp, $sc, $ic) = split(",", $ts);
+
+ if ($group <> "") {
+ $GROUP = GetPath($group) . ".stats";
+ $fd = fopen("{$GROUP}", "r");
+ $gts = chop(fgets($fd, 4096));
+ fclose($fd);
+ list ($gts, $gti, $gtm, $gfp, $gsc, $gic) = split(",", $gts);
+ $ts -= $gts;
+ $ti -= $gti;
+ $tm -= $gtm;
+ $fp -= $gfp;
+ $sc -= $gsc;
+ $ic -= $gic;
+ }
+
+ $fd = fopen("{$USER}.rstats", "w");
+ fputs($fd, "{$ts}" . "," . "{$ti}" . "," . "{$tm}" . "," .
+ "{$fp}" . "," . "{$sc}" . "," . "{$ic}\n");
+ fclose($fd);
+}
+
+function Tweak() {
+ global $USER;
+
+ $fd = fopen("{$USER}.rstats", "r");
+ $ts = chop(fgets($fd, 4096));
+ $group = chop($fgets($fd, 4096));
+ fclose($fd);
+ list($ts, $ti, $tm, $fp, $sc, $ic) = split(",", $ts);
+ $tm++;
+
+ $fd = fopen("{$USER}.rstats", "w");
+ fputs($fd, "{$ts},{$ti},{$tm},{$fp},{$sc},{$ic}\n");
+ fclose($fd);
+}
+
+function &DisplayIndex() {
+ global $USER, $CONFIG, $DATA, $CURRENT_STORE, $CURRENT_USER;
+
+ if (strpos ($CURRENT_USER, "@") === false) {
+ if (GetDomain($CURRENT_STORE) <> "")
+ $domain = GetDomain($CURRENT_STORE);
+ else
+ $domain = $config['system']['domain'];
+
+ $spamalias = "spam-{$CURRENT_USER}@{$domain}";
+ } else {
+ $spamalias = "spam-{$CURRENT_USER}";
+ }
+
+ if ($handle = @fopen ("{$USER}.stats", "r")) {
+ $spam .= chop(fgets($handle, 4096));
+ $group .= chop(fgets($handle, 4096));
+ fclose($handle);
+ list($spam, $innocent, $misses, $fp, $sc, $ic) = split(",", $spam);
+
+ if ($group <> "") {
+ $GROUP = GetPath($group) . ".stats";
+ $fd = fopen("{$GROUP}", "r");
+ $gspam = chop(fgets($fd, 4096));
+ fclose($fd);
+
+ list($gspam, $ginnocent, $gfp, $gmisses, $gsc, $gic) = preg_split('/\,/', $gspam);
+ $spam -= $gspam;
+ $innocent -= $ginnocent;
+ $misses -= $gmisses;
+ $fp -= $gfp;
+ $sc -= $gsc;
+ $ic -= $gic;
+ }
+
+ if ($spam + $innocent > 0) {
+ $ratio = sprintf("%2.3f",
+ (($spam+$misses)/($spam+$misses+$fp+$innocent)*100));
+ } else {
+ $ratio = 0;
+ }
+
+ if (file_exists("{$USER}.rstats")) {
+ $handle = fopen ("{$USER}.rstats", "r");
+ $buffer = chop(fgets($handle, 4096));
+
+ fclose ($handle);
+
+ list($rts, $rti, $rtm, $rfp) = split(",", $buffer);
+
+ $real_missed = $misses - $rtm;
+ $real_caught = $spam - $rts;
+ $real_fp = $fp - $rfp;
+
+ if ($real_fp < 0) { $real_fp = 0; }
+
+ $real_innocent = $innocent - $rti;
+
+ if (($spam - $rts > 0) && ($spam - $rts + $misses - $rtm != 0) &&
+ ($real_caught + $real_missed > 0) && ($real_fp + $real_innocent > 0)) {
+ $monthly = sprintf("%2.3f",
+ (100.0-(($real_missed)/($real_caught+$real_missed))*100.0));
+ $overall = sprintf("%2.3f",
+ (100-((($real_missed+$real_fp) /
+ ($real_fp+$real_innocent+$real_caught+$real_missed))*100)));
+ } else {
+ if ($real_caught == 0 && $real_missed > 0) {
+ $monthly = 0;
+ $overall = 0;
+ } else {
+ $monthly = 100;
+ $overall = 100;
+ }
+ }
+
+ if ($real_fp + $real_innocent > 0) {
+ $fpratio = sprintf("%2.3f", ($real_fp/($real_fp+$real_innocent)*100));
+ } else {
+ $fpratio = 0;
+ }
+
+ } else {
+ $rts = $spam + $misses;
+ $rti = $innocent;
+ $rtm = $misses;
+ $rfp = $fp;
+
+ $handle = fopen ("{$USER}.rstats", "w");
+ fwrite("{$rts},{$rti},{$rtm},{$rfp}\n");
+ fclose($handle);
+
+ $monthly = "N/A";
+ $fpratio = "N/A";
+ $overall = "N/A";
+ }
+
+ $DATA['TIME'] = $time;
+ $DATA['TOTAL_SPAM_SCANNED'] = $spam;
+ $DATA['TOTAL_SPAM_LEARNED'] = $misses;
+ $DATA['TOTAL_NONSPAM_SCANNED'] = $innocent;
+ $DATA['TOTAL_NONSPAM_LEARNED'] = $fp;
+ $DATA['SPAM_RATIO'] = $ratio;
+ $DATA['SPAM_ACCURACY'] = $monthly;
+ $DATA['NONSPAM_ERROR_RATE'] = $fpratio;
+ $DATA['OVERALL_ACCURACY'] = $overall;
+ $DATA['TOTAL_SPAM_CORPUSFED'] = $sc;
+ $DATA['TOTAL_NONSPAM_CORPUSFED'] = $ic;
+ $DATA['TOTAL_SPAM_MISSED'] = $real_missed;
+ $DATA['TOTAL_SPAM_CAUGHT'] = $real_caught;
+ $DATA['TOTAL_NONSPAM_MISSED'] = $real_fp;
+ $DATA['TOTAL_NONSPAM_CAUGHT'] = $real_innocent;
+ $DATA['SPAM_ALIAS'] = $spamalias;
+
+ $DATA['LOCAL_DOMAIN'] = $CONFIG['LOCAL_DOMAIN'];
+ } else {
+ $DATA['SPAM_ACCURACY'] = "N/A";
+ $DATA['NONSPAM_ERROR_RATE'] = "N/A";
+ $DATA['OVERALL_ACCURACY'] = "N/A";
+ $DATA['SPAM_RATIO'] = "N/A";
+ $DATA['TOTAL_SPAM_MISSED'] = 0;
+ $DATA['TOTAL_SPAM_CAUGHT'] = 0;
+ $DATA['SPAM_RATIO'] = "N/A";
+ $DATA['TOTAL_NONSPAM_MISSED'] = 0;
+ $DATA['TOTAL_NONSPAM_CAUGHT'] = 0;
+ $DATA['NONSPAM_ERROR_RATE'] = "N/A";
+ $DATA['TOTAL_SPAM_LEARNED'] = 0;
+ $DATA['TOTAL_SPAM_SCANNED'] = 0;
+ $DATA['TOTAL_NONSPAM_LEARNED'] = 0;
+ $DATA['TOTAL_NONSPAM_SCANNED'] = 0;
+ $DATA['TOTAL_SPAM_CORPUSFED'] = 0;
+ $DATA['TOTAL_NONSPAM_CORPUSFED'] = 0;
+ $DATA['SPAM_ALIAS'] = $spamalias;
+
+ $input_errors[] = "Unable to open DSPAM stats at »{$USER}.stats«. " .
+ "If you are a DSPAM admin user you can savely " .
+ "ignore this error because such users usually do not " .
+ "have a DSPAM mailbox/quarantine.";
+ }
+
+ return $input_errors;
+}
+
+function getJScriptFunction($whichOne = 0) {
+ $changeuser_msg = gettext("Do you realy want to change the current user?") . "\\n" .
+ gettext("This requires a logout followed by a login.");
+
+ switch ($whichOne) {
+ case 0:
+ $scriptstr = '
+
+ /* applicable for almost any dspam related page */
+ function changeuser() {
+ check = confirm("' . $changeuser_msg . '");
+
+ if (check == true)
+ window.location.href = "/index.php?logout=true";
+ }
+ ';
+
+ break;
+ case 1:
+ $scriptstr = '
+
+ /* applicable for dspam-quarantine.php */
+ function checkallmsgs(enable) {
+ var endis = (document.iform.checkall.checked || enable);
+ var elem = document.iform.elements.length;
+
+ for (i = 0; i < elem; i++) {
+ if (document.iform.elements[i].name.indexOf("chkmsg") >= 0) {
+ document.iform.elements[i].checked = endis;
+ }
+ }
+ }
+ ';
+
+ break;
+ case 2:
+ $scriptstr = '
+
+ /* applicable for dspam-quarantine.php */
+ function sortmsg(criterion) {
+ var baseURL = "/dspam-quarantine.php?page=" + document.iform.qpage.value;
+ var qperpage = document.getElementsByName("qperpage")[0].value;
+
+ window.location.href = baseURL + "&qperpage=" + qperpage + "&sortby=" + criterion;
+ }
+ ';
+
+ break;
+ case 3:
+ $scriptstr = '
+
+ /* applicable for dspam-quarantine.php */
+ function processmsg(what) {
+ var elem = document.iform.elements.length;
+ var checked = false;
+
+ switch (what) {
+ case 0:
+ for (i = 0; i < elem; i++) {
+ if (document.iform.elements[i].name.indexOf("chkmsg") >= 0 &&
+ document.iform.elements[i].checked == true) {
+ checked = true;
+ break;
+ }
+ }
+
+ if (checked) {
+ document.iform.processAction.value = "manyNotSpam";
+ } else {
+ alert("You did not select any message that should be processed as not beeing Spam.");
+ return false;
+ }
+ break;
+ case 1:
+ for (i = 0; i < elem; i++) {
+ if (document.iform.elements[i].name.indexOf("chkmsg") >= 0 &&
+ document.iform.elements[i].checked == true) {
+ checked = true;
+ break;
+ }
+ }
+
+ if (checked) {
+ if (confirm("Are you sure you want to delete SELECTED messages in quarantine?") == false) {
+ return false;
+ } else {
+ document.iform.processAction.value = "manySpam";
+ }
+ } else {
+ alert("You did not select any message that should be processed as beeing Spam.");
+ return false;
+ }
+ break;
+ case 2:
+ if (confirm("Are you sure you want to delete ALL messages in quarantine?") == false) {
+ return false;
+ } else {
+ document.iform.processAction.value = "deleteAll";
+ }
+ break;
+ }
+
+ document.iform.submit();
+ }
+ ';
+
+ break;
+ case 4:
+ $scriptstr = '
+
+ /* applicable for dspam-quarantine.php nad dspam-history.php */
+ function changeQPerPage(originator) {
+ var elementName = "";
+ var baseURL = "";
+
+ if (originator.name == "qperpage") {
+ baseURL = "/dspam-quarantine.php?page=" + document.iform.qpage.value;
+ elementName = "qperpage";
+ } else {
+ baseURL = "/dspam-history.php?page=" + document.iform.hpage.value;
+ elementName = "hperpage";
+ }
+
+ for (var i = 0; i < 2; i++) {
+ document.getElementsByName(elementName)[i].value = originator.value;
+ }
+
+ if (originator.name == "qperpage")
+ window.location.href = baseURL + "&qperpage=" + originator.value;
+ else
+ window.location.href = baseURL + "&hperpage=" + originator.value;
+ }
+ ';
+
+ break;
+ case 5:
+ $scriptstr = '
+
+ /* applicable for dspam-settings.php */
+
+ function fadeTableRow(rowid, fadeType, opts){
+ if(!opts){
+ opts = {};
+ }
+
+ var row = $(rowid);
+ var cells= row.childNodes;
+ for(i=0;i<cells.length;i++){
+ if(cells[i].tagName == "TD"){
+ if (fadeType == 0)
+ new Effect.Fade(cells[i],opts);
+ else
+ new Effect.Appear(cells[i],opts);
+ }
+ }
+ if (fadeType == 0)
+ new Effect.Fade(row,opts);
+ else
+ new Effect.Appear(row,opts);
+ }
+
+ function toggleDSPAMDomain(enable_over, originator) {
+ var endis = !(originator.checked || enable_over);
+
+ if (endis) {
+ fadeTableRow("emailnotitb", 1);
+ } else {
+ fadeTableRow("emailnotitb", 0);
+ }
+ }
+
+ function toggleDBSettings(idx) {
+ if (idx)
+ idx = idx;
+ else
+ idx = document.iform.sdriver.selectedIndex;
+
+ switch (idx) {
+ case 0:
+ fadeTableRow("DBmysql", 1);
+ fadeTableRow("DBsqlite", 0);
+ fadeTableRow("DBbdb", 0);
+ fadeTableRow("DBpgsql", 0);
+ fadeTableRow("DBoracle", 0);
+ fadeTableRow("DBhash", 0);
+ break;
+ case 1:
+ fadeTableRow("DBmysql", 0);
+ fadeTableRow("DBsqlite", 1);
+ fadeTableRow("DBbdb", 0);
+ fadeTableRow("DBpgsql", 0);
+ fadeTableRow("DBoracle", 0);
+ fadeTableRow("DBhash", 0);
+ break;
+ case 2:
+ fadeTableRow("DBmysql", 0);
+ fadeTableRow("DBsqlite", 0);
+ fadeTableRow("DBbdb", 1);
+ fadeTableRow("DBpgsql", 0);
+ fadeTableRow("DBoracle", 0);
+ fadeTableRow("DBhash", 0);
+ break;
+ case 3:
+ fadeTableRow("DBmysql", 0);
+ fadeTableRow("DBsqlite", 0);
+ fadeTableRow("DBbdb", 0);
+ fadeTableRow("DBpgsql", 1);
+ fadeTableRow("DBoracle", 0);
+ fadeTableRow("DBhash", 0);
+ break;
+ case 4:
+ fadeTableRow("DBmysql", 0);
+ fadeTableRow("DBsqlite", 0);
+ fadeTableRow("DBbdb", 0);
+ fadeTableRow("DBpgsql", 0);
+ fadeTableRow("DBoracle", 1);
+ fadeTableRow("DBhash", 0);
+ break;
+ case 5:
+ fadeTableRow("DBmysql", 0);
+ fadeTableRow("DBsqlite", 0);
+ fadeTableRow("DBbdb", 0);
+ fadeTableRow("DBpgsql", 0);
+ fadeTableRow("DBoracle", 0);
+ fadeTableRow("DBhash", 1);
+ break;
+ }
+ }
+
+ function enable_change(enable_over, originator) {
+ var endis;
+
+ switch (originator) {
+ case 0:
+ endis = !(document.iform.enabledbg.checked || enable_over);
+ endis ? document.iform.debug.style.backgroundColor = "#D4D0C8" : document.iform.debug.style.backgroundColor = "#FFFFFF";
+ document.iform.debug.disabled = endis;
+ endis ? document.iform.dopt.style.backgroundColor = "#D4D0C8" : document.iform.dopt.style.backgroundColor = "#FFFFFF";
+ document.iform.dopt.disabled = endis;
+ case 1:
+ endis = !(document.iform.enableldap.checked || enable_over);
+ document.iform.ldapmode.disabled = endis;
+ endis ? document.iform.ldaphost.style.backgroundColor = "#D4D0C8" : document.iform.ldaphost.style.backgroundColor = "#FFFFFF";
+ document.iform.ldaphost.disabled = endis;
+ endis ? document.iform.ldapfilter.style.backgroundColor = "#D4D0C8" : document.iform.ldapfilter.style.backgroundColor = "#FFFFFF";
+ document.iform.ldapfilter.disabled = endis;
+ endis ? document.iform.ldapbase.style.backgroundColor = "#D4D0C8" : document.iform.ldapbase.style.backgroundColor = "#FFFFFF";
+ document.iform.ldapbase.disabled = endis;
+ case 2:
+ endis = !(document.iform.enablesbl.checked || enable_over);
+ endis ? document.iform.sblhost.style.backgroundColor = "#D4D0C8" : document.iform.sblhost.style.backgroundColor = "#FFFFFF";
+ document.iform.sblhost.disabled = endis;
+ case 3:
+ endis = !(document.iform.enableclam.checked || enable_over);
+ endis ? document.iform.clamport.style.backgroundColor = "#D4D0C8" : document.iform.clamport.style.backgroundColor = "#FFFFFF";
+ document.iform.clamport.disabled = endis;
+ endis ? document.iform.clamhost.style.backgroundColor = "#D4D0C8" : document.iform.clamhost.style.backgroundColor = "#FFFFFF";
+ document.iform.clamhost.disabled = endis;
+ document.iform.clamresp.disabled = endis;
+ case 4:
+ endis = !(document.iform.enabledsclient.checked || enable_over);
+ endis ? document.iform.dsclhost.style.backgroundColor = "#D4D0C8" : document.iform.dsclhost.style.backgroundColor = "#FFFFFF";
+ document.iform.dsclhost.disabled = endis;
+ endis ? document.iform.dsclport.style.backgroundColor = "#D4D0C8" : document.iform.dsclport.style.backgroundColor = "#FFFFFF";
+ document.iform.dsclport.disabled = endis;
+ endis ? document.iform.dsclident.style.backgroundColor = "#D4D0C8" : document.iform.dsclident.style.backgroundColor = "#FFFFFF";
+ document.iform.dsclident.disabled = endis;
+ case 5:
+ endis = !(document.iform.tcpipdel.checked || enable_over);
+ endis ? document.iform.dhost.style.backgroundColor = "#D4D0C8" : document.iform.dhost.style.backgroundColor = "#FFFFFF";
+ document.iform.dhost.disabled = endis;
+ endis ? document.iform.dport.style.backgroundColor = "#D4D0C8" : document.iform.dport.style.backgroundColor = "#FFFFFF";
+ document.iform.dport.disabled = endis;
+ endis ? document.iform.dident.style.backgroundColor = "#D4D0C8" : document.iform.dident.style.backgroundColor = "#FFFFFF";
+ document.iform.dident.disabled = endis;
+ document.iform.delproto.disabled = endis;
+ case 6:
+ endis = !(document.iform.enablenoti.checked || enable_over);
+ document.iform.whichdomain.disabled = endis;
+ endis ? document.iform.dspamdomain.style.backgroundColor = "#D4D0C8" : document.iform.dspamdomain.style.backgroundColor = "#FFFFFF";
+ document.iform.dspamdomain.disabled = endis;
+ endis ? document.iform.dspamcontact.style.backgroundColor = "#D4D0C8" : document.iform.dspamcontact.style.backgroundColor = "#FFFFFF";
+ document.iform.dspamcontact.disabled = endis;
+ }
+ }
+ ';
+
+ break;
+ case 6:
+ $scriptstr = '
+
+ function checkDisabledState(form) {
+ for (i = 0; i < form.elements.length; i++) {
+ if (form.elements[i].disabled && form.elements[i].type == "text")
+ form.elements[i].style.backgroundColor = "#D4D0C8";
+ else if (form.elements[i].type == "text")
+ form.elements[i].style.backgroundColor = "#FFFFFF";
+ }
+ }
+ ';
+
+ break;
+ }
+
+ return $scriptstr;
+}
+
+?>
diff --git a/config/dspam/pkg/dspam-pkgfunc.inc b/config/dspam/pkg/dspam-pkgfunc.inc
new file mode 100644
index 00000000..31a7fa06
--- /dev/null
+++ b/config/dspam/pkg/dspam-pkgfunc.inc
@@ -0,0 +1,548 @@
+<?php
+/* $Id$ */
+/* Copyright (C) 2006 Daniel S. Haischt */
+require_once("functions.inc");
+require_once("dspam.inc");
+
+function sync_package_dspam() {
+ global $config, $g;
+ conf_mount_rw();
+ config_lock();
+ $fd = fopen("/etc/dspam.conf","w");
+
+ $dspamcfg = <<<EOD
+## dspam.conf -- DSPAM configuration file
+## Generated by pfSense
+Home /var/db/dspam
+## Database Settings
+StorageDriver /usr/local/lib/libmysql_drv.so
+MySQLServer /tmp/mysql.sock
+MySQLPort
+MySQLUser dspam
+MySQLPass dspam
+MySQLDb dspam
+MySQLCompress true
+MySQLSupressQuote off
+MySQLConnectionCache 10
+MySQLUIDInSignature on
+## Delivery Settings
+TrustedDeliveryAgent "/usr/bin/mail"
+DeliveryHost 192.168.1.6
+DeliveryPort 24
+DeliveryIdent localhost
+DeliveryProto smtp
+OnFail error
+## DSPAM Privileges
+Trust root
+Trust mail
+Trust mailnull
+Trust smmsp
+Trust daemon
+## DSPAM Engine Settings
+TrainingMode teft
+TestConditionalTraining on
+Feature chained
+Feature whitelist
+Algorithm graham burton
+PValue graham
+ImprobabilityDrive on
+Preference "spamAction=quarantine"
+Preference "signatureLocation=message"
+Preference "showFactors=on"
+AllowOverride trainingMode
+AllowOverride spamAction spamSubject
+AllowOverride statisticalSedation
+AllowOverride enableBNR
+AllowOverride enableWhitelist
+AllowOverride signatureLocation
+AllowOverride showFactors
+AllowOverride optIn optOut
+AllowOverride whitelistThreshold
+## Miscellaneous Settings
+FailoverAttempts 1
+IgnoreHeader X-Spam-Scanned
+IgnoreHeader X-Spam-Status
+IgnoreHeader X-Virus-Scanner-Result
+RBLInoculate on
+Notifications on
+## Maintainance Settings
+PurgeSignatures 14
+PurgeNeutral 90
+PurgeUnused 90
+PurgeHapaxes 30
+PurgeHits1S 15
+PurgeHits1I 15
+## System Settings
+LocalMX 127.0.0.1
+SystemLog on
+UserLog on
+Opt out
+ParseToHeaders on
+ChangeModeOnParse on
+ChangeUserOnParse on
+Broken returnCodes
+Broken case
+Broken lineStripping
+MaxMessageSize 307200
+ProcessorBias on
+## ClamAV Engine Settings
+ClamAVPort 3310
+ClamAVHost 127.0.0.1
+ClamAVResponse accept
+## DSPAM Daemon Settings (Server)
+ServerPort 24
+ServerQueueSize 32
+ServerPID /var/run/dspam/dspam.pid
+ServerMode standard
+ServerParameters "--deliver=innocent -d %u"
+ServerIdent "abysseleven.abyssworld.de"
+ServerDomainSocketPath "/var/run/dspam/dspam.sock"
+## EOF
+
+EOD;
+
+ /* flush the default config to the file */
+ fwrite($fd, $dspamcfg);
+ fclose($fd);
+
+ $fd = fopen("/usr/local/bin/dspam_spamfeed","w");
+
+ $spamfeed = <<<EOD
+#!/bin/sh
+#
+# automatically generated by pfSense
+
+cat \${2} | dspam --mode=teft --source=corpus --class=spam --feature=chained,noise --user \${1}
+
+EOD;
+
+ fwrite($fd, $spamfeed);
+ fclose($fd);
+ mwexec("chmod a+x /usr/local/bin/dspam_spamfeed");
+
+ $fd = fopen("/usr/local/bin/dspam_innocentfeed","w");
+
+ $innocentfeed = <<<EOD
+#!/bin/sh
+#
+# automatically generated by pfSense
+
+cat \${2} | dspam --mode=teft --source=corpus --class=innocent --feature=chained,noise --user \${1}
+
+EOD;
+
+ fwrite($fd, $innocentfeed);
+ fclose($fd);
+ mwexec("chmod a+x /usr/local/bin/dspam_innocentfeed");
+
+ $start = <<<EOD
+test_dspam_user=`cat /etc/passwd | grep dspam`
+test_dspam_db=`mysql information_schema -e "select schema_name from schemata" | grep dspam`
+test_dspam_db_user=`mysql mysql -e "select User from user" | grep dspam`
+
+if [ -z "\${test_dspam_user}" ]; then
+ pw useradd dspam -u 107 -g mail -d /var/db/dspam -s /bin/csh -c 'DSPAM Daemon User'
+fi
+
+if [ ! -d "/var/run/dspam" ]; then
+ mkdir /var/run/dspam && chown dspam:mail /var/run/dspam
+fi
+
+if [ -z "\${test_dspam_db}" ]; then
+ mysql -D mysql -e "create database dspam"
+ if [ -z "\${test_dspam_db_user}" ]; then
+ mysql -D mysql -e "GRANT ALL PRIVILEGES ON dspam.* TO dspam@localhost IDENTIFIED BY 'dspam'"
+ fi
+ mysql -udspam -pdspam dspam < /usr/local/share/examples/dspam/mysql/mysql_objects-space.sql && \
+ mysql -udspam -pdspam dspam < /usr/local/share/examples/dspam/mysql/virtual_users.sql
+fi
+
+/sbin/mount_fdescfs fdescfs /dev/fd
+/usr/local/bin/dspam --daemon &
+
+EOD;
+
+ $stop = "/usr/bin/killall dspam\n" .
+ "sleep 2";
+ write_rcfile(array(
+ "file" => "dspam.sh",
+ "start" => $start,
+ "stop" => $stop
+ )
+ );
+ conf_mount_ro();
+ config_unlock();
+
+ if (! file_exists("/usr/local/etc/dspam.conf")) {
+ mwexec("ln -s /etc/dspam.conf /usr/local/etc/dspam.conf");
+ }
+
+ mwexec("/usr/local/etc/rc.d/dspam.sh stop");
+ mwexec("/usr/local/etc/rc.d/dspam.sh start");
+
+ return 0;
+}
+
+function dspam_configure() {
+ global $config, $g;
+
+ $dspamcfg = $config['installedpackages']['dspam']['config'][0];
+
+ if ($g['booting'])
+ echo "Starting DSPAM service... ";
+ else
+ sleep(1);
+
+ /* write dhcpd.conf */
+ $fd = fopen("/usr/local/etc/dspam.conf", "w");
+ if (!$fd) {
+ printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n");
+ return 1;
+ }
+
+ $dspamconf = <<<EOD
+## dspam.conf -- DSPAM configuration file
+## Generated by pfSense
+Home /var/db/dspam
+## Database Settings
+
+EOD;
+
+ if ($dspamcfg['storage-driver'] == "mysql") {
+ $dspamconf .= "StorageDriver\t\t/usr/local/lib/libmysql_drv.so\n";
+ $dspamconf .= <<<EOD
+MySQLServer {$dspamcfg['dbsettings'][0]['mysql-server']}
+MySQLPort {$dspamcfg['dbsettings'][0]['mysql-port']}
+MySQLUser {$dspamcfg['dbsettings'][0]['mysql-user']}
+MySQLPass {$dspamcfg['dbsettings'][0]['mysql-password']}
+MySQLDb {$dspamcfg['dbsettings'][0]['mysql-database']}
+
+EOD;
+ isset($dspamcfg['dbsettings'][0]['mysql-compress']) ? $dspamconf .= "MySQLCompress\t\ttrue\n" : $dspamconf .= "MySQLCompress\tfalse\n";
+ isset($dspamcfg['dbsettings'][0]['mysql-squote']) ? $dspamconf .= "MySQLSupressQuote\ton\n" : $dspamconf .= "MySQLSupressQuote\toff\n";
+ isset($dspamcfg['dbsettings'][0]['mysql-ccache']) ? $dspamconf .= "MySQLConnectionCache\t{$dspamcfg['dbsettings'][0]['mysql-ccache']}\n" : $dspamconf .= "MySQLConnectionCache\t10\n";
+ isset($dspamcfg['dbsettings'][0]['mysql-uid']) ? $dspamconf .= "MySQLUIDInSignature\ton\n" : $dspamconf .= "MySQLUIDInSignature\toff\n";
+ } else if ($dspamcfg['storage-driver'] == "sqlite") {
+ $dspamconf .= "StorageDriver\t\t/usr/local/lib/libsqlite3_drv.so\n";
+ if (isset($dspamcfg['dbsettings'][0]['sqlite-pragma'])) $dspamconf .= "SQLitePragma\t\t{$dspamcfg['dbsettings'][0]['sqlite-pragma']}\n";
+ } else if ($dspamcfg['storage-driver'] == "pgsql") {
+ $dspamconf .= "StorageDriver\t\t/usr/local/lib/libpgsql_drv.so\n";
+ $dspamconf .= <<<EOD
+PgSQLServer {$dspamcfg['dbsettings'][0]['pgsql-server']}
+PgSQLPort {$dspamcfg['dbsettings'][0]['pgsql-port']}
+PgSQLUser {$dspamcfg['dbsettings'][0]['pgsql-user']}
+PgSQLPass {$dspamcfg['dbsettings'][0]['pgsql-password']}
+PgSQLDb {$dspamcfg['dbsettings'][0]['pgsql-database']}
+
+EOD;
+ isset($dspamcfg['dbsettings'][0]['pgsql-ccache']) ? $dspamconf .= "PgSQLConnectionCache\t{$dspamcfg['dbsettings'][0]['pgsql-ccache']}\n" : $dspamconf .= "PgSQLConnectionCache\t3\n";
+ isset($dspamcfg['dbsettings'][0]['pgsql-uid']) ? $dspamconf .= "PgSQLUIDInSignature\ton\n" : $dspamconf .= "PgSQLUIDInSignature\toff\n";
+ } else if ($dspamcfg['storage-driver'] == "oracle") {
+ $dspamconf .= "StorageDriver\t/usr/local/lib/libora_drv.so\n";
+ $dspamconf .= <<<EOD
+OraServer {$dspamcfg['dbsettings'][0]['ora-server']}
+OraUser {$dspamcfg['dbsettings'][0]['ora-user']}
+OraPass {$dspamcfg['dbsettings'][0]['ora-password']}
+OraSchema {$dspamcfg['dbsettings'][0]['ora-schema']}
+
+EOD;
+ } else if ($dspamcfg['storage-driver'] == "hash") {
+ $dspamconf .= "StorageDriver\t\t/usr/local/lib/libhash_drv.so\n";
+ $dspamconf .= <<<EOD
+HashRecMax {$dspamcfg['dbsettings'][0]['hash-rec-max']}
+HashMaxExtents {$dspamcfg['dbsettings'][0]['hash-max-ext']}
+HashExtentSize {$dspamcfg['dbsettings'][0]['hash-ext-size']}
+HashMaxSeek {$dspamcfg['dbsettings'][0]['hash-max-seek']}
+HashConnectionCache {$dspamcfg['dbsettings'][0]['hash-co-cache']}
+
+EOD;
+ isset($dspamcfg['dbsettings'][0]['hash-auto-ex']) ? $dspamconf .= "HashAutoExtend\t\ton\n" : $dspamconf .= "HashAutoExtend\toff\n";
+ if (isset($dspamcfg['dbsettings'][0]['hash-co-user'])) $dspamconf .= "HashConcurrentUser\t{$dspamcfg['dbsettings'][0]['hash-co-user']}\n";
+ }
+
+ $dspamconf .= "## Delivery Settings\n";
+
+ if ($dspamcfg['tdelivery-agent'] == "procmail") {
+ $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/bin/procmail\"\n";
+ } else if ($dspamcfg['tdelivery-agent'] == "mail") {
+ $dspamconf .= "TrustedDeliveryAgent\t\"/usr/bin/mail\"\n";
+ } else if ($dspamcfg['tdelivery-agent'] == "mail.local") {
+ $dspamconf .= "TrustedDeliveryAgent\t\"/usr/libexec/mail.local\"\n";
+ } else if ($dspamcfg['tdelivery-agent'] == "deliver") {
+ $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/cyrus/bin/deliver\"\n";
+ } else if ($dspamcfg['tdelivery-agent'] == "maildrop") {
+ $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/bin/maildrop\"\n";
+ } else if ($dspamcfg['tdelivery-agent'] == "exim") {
+ $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/sbin/exim -oMr spam-scanned\"\n";
+ }
+
+ if (isset($dspamcfg['tcpip-delivery'])) {
+ $dspamconf .= <<<EOD
+DeliveryHost {$dspamcfg['tcpip-delivery-host']}
+DeliveryPort {$dspamcfg['tcpip-delivery-port']}
+DeliveryIdent {$dspamcfg['tcpip-delivery-ident']}
+DeliveryProto {$dspamcfg['tcpip-delivery-proto']}
+
+EOD;
+ }
+
+ /* TODO: If required add the following, currently
+ missing options:
+
+ - QuarantineAgent
+ - EnablePlusedDetail
+ - QuarantineMailbox
+ */
+
+ $dspamconf .= "OnFail\t\t\t{$dspamcfg['delivery-onfail']}\n";
+ $dspamconf .= "## DSPAM Privileges\n";
+
+ $t_users = &$dspamcfg['tuser'];
+
+ foreach ($t_users as $user) {
+ $dspamconf .= "Trust\t\t\t{$user['name']}\n";
+ }
+
+ if (isset($dspamcfg['debug-enable'])) {
+ $dspamconf .= "## DSPAM Debugging Options\n";
+ $dspamconf .= "Debug\t\t\t{$dspamcfg['debug-whom']}\n";
+ $dspamconf .= "DebugOpt\t\t{$dspamcfg['debug-options']}\n";
+ }
+
+ $dspamconf .= "## DSPAM Engine Settings\n";
+ $dspamconf .= "TrainingMode\t\t{$dspamcfg['training-mode']}\n";
+ isset($dspamcfg['test-cond-training']) ? $dspamconf .= "TestConditionalTraining\ton\n" : $dspamconf .= "TestConditionalTraining\toff\n";
+
+ $t_features = &$dspamcfg['feature'];
+
+ foreach ($t_features as $feature) {
+ $dspamconf .= "Feature\t\t\t{$feature['name']}\n";
+ }
+
+ $t_algos = &$dspamcfg['algorithm'];
+
+ if (count($t_algos) > 0) {
+ $dspamconf .= "Algorithm\t\t";
+
+ foreach ($t_algos as $algo) {
+ $dspamconf .= "{$algo['name']} ";
+ }
+
+ $dspamconf .= "\n";
+ }
+
+ $dspamconf .= "PValue\t\t\t{$dspamcfg['pvalue']}\n";
+ isset($dspamcfg['improbability-drive']) ? $dspamconf .= "ImprobabilityDrive\ton\n" : $dspamconf .= "ImprobabilityDrive\toff\n";
+
+ $t_prefs = &$dspamcfg['preference'];
+
+ foreach ($t_prefs as $pref) {
+ $dspamconf .= "Preference\t\t{$pref['value']}\n";
+ }
+
+ $t_overr = &$dspamcfg['override'];
+
+ foreach ($t_overr as $over) {
+ $dspamconf .= "AllowOverride\t\t{$over['value']}\n";
+ }
+
+ if (isset($dspamcfg['ldap-enable'])) {
+ $dspamconf .= <<<EOD
+## LDAP Settings
+LDAPMode {$dspamcfg['ldap-mode']}
+LDAPHost {$dspamcfg['ldap-host']}
+LDAPFilter {$dspamcfg['ldap-filter']}
+LDAPBase {$dspamcfg['ldap-base']}
+
+EOD;
+ }
+
+ $dspamconf .= "## Miscellaneous Settings\n";
+ if (isset($dspamcfg['failover-attempts'])) $dspamconf .= "FailoverAttempts\t{$dspamcfg['failover-attempts']}\n";
+
+ $t_headers = &$dspamcfg['header'];
+
+ if (is_array($t_headers)) {
+ foreach ($t_headers as $header) {
+ $dspamconf .= "IgnoreHeader\t\t{$header['name']}\n";
+ }
+ }
+
+ if (isset($dspamcfg['sbl-enable'])) {
+ $dspamconf .= "Lookup\t\t\t\"{$dspamcfg['sbl-host']}\"\n";
+ }
+
+ isset($dspamcfg['rbl-inoculate']) ? $dspamconf .= "RBLInoculate\t\ton\n" : $dspamconf .= "RBLInoculate\toff\n";
+ isset($dspamcfg['notification-email']) ? $dspamconf .= "Notifications\t\ton\n" : $dspamconf .= "Notifications\toff\n";
+
+ $dspamconf .= <<<EOD
+## Maintainance Settings
+PurgeSignatures {$dspamcfg['purge-signatures']}
+PurgeNeutral {$dspamcfg['purge-neutral']}
+PurgeUnused {$dspamcfg['purge-unused']}
+PurgeHapaxes {$dspamcfg['purge-hapaxes']}
+PurgeHits1S {$dspamcfg['purge-hits-1s']}
+PurgeHits1I {$dspamcfg['purge-hits-1s']}
+
+EOD;
+
+ $dspamconf .= "## System Settings\n";
+ $dspamconf .= "LocalMX\t\t\t{$dspamcfg['local-mx']}\n";
+ isset($dspamcfg['system-log']) ? $dspamconf .= "SystemLog\t\ton\n" : $dspamconf .= "SystemLog\toff\n";
+ isset($dspamcfg['user-log']) ? $dspamconf .= "UserLog\t\t\ton\n" : $dspamconf .= "UserLog\toff\n";
+ $dspamconf .= "Opt\t\t\t{$dspamcfg['filter-opt']}\n";
+ isset($dspamcfg['parse-to-headers']) ? $dspamconf .= "ParseToHeaders\t\ton\n" : $dspamconf .= "ParseToHeaders\toff\n";
+ isset($dspamcfg['change-mode-on-parse']) ? $dspamconf .= "ChangeModeOnParse\ton\n" : $dspamconf .= "ChangeModeOnParse\toff\n";
+ isset($dspamcfg['change-user-on-parse']) ? $dspamconf .= "ChangeUserOnParse\ton\n" : $dspamconf .= "ChangeUserOnParse\toff\n";
+
+ if (isset($dspamcfg['broken-mta-settings'])) {
+ $t_bmtas = &$dspamcfg['bmta'];
+
+ foreach ($t_bmtas as $bmta) {
+ $dspamconf .= "Broken\t\t\t{$bmta['name']}\n";
+ }
+ }
+
+ $dspamconf .= "MaxMessageSize\t\t{$dspamcfg['max-message-size']}\n";
+ isset($dspamcfg['processor-bias']) ? $dspamconf .= "ProcessorBias\t\ton\n" : $dspamconf .= "ProcessorBias\toff\n";
+
+ if (isset($dspamcfg['clamav-enable'])) {
+ $dspamconf .= <<<EOD
+## ClamAV Engine Settings
+ClamAVPort {$dspamcfg['clamav-port']}
+ClamAVHost {$dspamcfg['clamav-host']}
+ClamAVResponse {$dspamcfg['clamav-response']}
+
+EOD;
+ }
+
+ $dspamconf .= <<<EOD
+## DSPAM Daemon Settings (Server)
+ServerPort {$dspamcfg['dspam-server-port']}
+ServerQueueSize {$dspamcfg['dspam-server-queue-size']}
+ServerPID {$dspamcfg['dspam-server-pid']}
+ServerMode {$dspamcfg['dspam-server-mode']}
+
+EOD;
+
+ if ($dspamcfg['dspam-server-mode'] == "dspam") {
+ $t_spwds = &$dspamcfg['server-pwd'];
+ $i = 1;
+
+ if (is_array($t_spwds)) {
+ foreach ($t_spwds as $spwd) {
+ $dspamconf .= "ServerPass.Relay{$i}\t\"{$spwd['value']}\"\n";
+ $i++;
+ }
+ }
+ } else if ($dspamcfg['dspam-server-mode'] == "standard") {
+ $dspamconf .= <<<EOD
+ServerParameters "{$dspamcfg['dspam-server-params']}"
+ServerIdent "{$dspamcfg['dspam-server-id']}"
+
+EOD;
+ }
+
+ if (isset($dspamcfg['dspam-server-socket'])) {
+ $dspamconf .= "ServerDomainSocketPath\t\"{$dspamcfg['dspam-server-socket']}\"\n";
+ }
+
+ if (isset($dspamcfg['dspam-client-enable']) && $dspamcfg['dspam-client-enable'] <> "") {
+ $dspamconf .= <<<EOD
+## DSPAM Daemon Settings (Client)
+ClientHost {$dspamcfg['dspam-client-host']}
+ClientIdent {$dspamcfg['dspam-client-id']}
+
+EOD;
+
+ if (isset($dspamcfg['dspam-client-port']) && $dspamcfg['dspam-client-port'] <> "") {
+ $dspamconf .= "ClientPort\t\t{$dspamcfg['dspam-client-port']}\n";
+ }
+ }
+
+ $dspamconf .= "## EOF\n";
+
+ fwrite($fd, $dspamconf);
+ fclose($fd);
+
+ /* fire up dspam --daemon */
+ mwexec("/usr/local/etc/rc.d/dspam.sh stop");
+ mwexec("/usr/local/etc/rc.d/dspam.sh start");
+
+ if ($g['booting']) {
+ print "done.\n";
+ }
+
+ return 0;
+}
+
+function custom_php_install_command() {
+ global $config, $g;
+ /* create a default config */
+ sync_package_dspam();
+}
+
+function custom_php_deinstall_command() {
+ global $config, $g;
+ conf_mount_rw();
+ unlink_if_exists("/usr/local/etc/rc.d/dspam.sh");
+ unlink_if_exists("/usr/local/etc/dspam.conf");
+ unlink_if_exists("/usr/local/bin/dspam_spamfeed");
+ unlink_if_exists("/usr/local/bin/dspam_innocentfeed");
+ conf_mount_ro();
+}
+
+function checkForLDAPSupport() {
+ $pd = popen("ldd /usr/local/bin/dspam", "r");
+ while (!feof($pd)) {
+ $dspamstr .= fgets($pd, 4096);
+ }
+ pclose($pd);
+
+ if (strpos($dspamstr, "libldap") !== false &&
+ file_exists("/usr/local/lib/libldap.so") &&
+ file_exists("/usr/local/lib/liblber.so")) {
+ return true;
+ }
+
+ return false;
+}
+
+function checkForPgSQLSupport() {
+ if (file_exists("/usr/local/lib/libpgsql_drv.so") &&
+ file_exists("/usr/local/lib/libpq.so")) {
+ return true;
+ }
+
+ return false;
+}
+
+function checkForMySQLSupport() {
+ if (file_exists("/usr/local/lib/libmysql_drv.so") &&
+ file_exists("/usr/local/lib/mysql/libmysqlclient.so")) {
+ return true;
+ }
+
+ return false;
+}
+
+function checkForSQLiteSupport() {
+ if (file_exists("/usr/local/lib/libsqlite3_drv.so") &&
+ file_exists("/usr/local/lib/mysql/libsqlite3.so")) {
+ return true;
+ }
+
+ return false;
+}
+
+function checkForClamAVSupport() {
+ if (file_exists("/usr/local/bin/clamdscan") &&
+ file_exists("/usr/local/bin/clamscan") &&
+ file_exists("/usr/local/sbin/clamd")) {
+ return true;
+ }
+
+ return false;
+}
+
+?>
diff --git a/config/dspam/pkg/dspam-utilfunc.inc b/config/dspam/pkg/dspam-utilfunc.inc
new file mode 100644
index 00000000..903790b8
--- /dev/null
+++ b/config/dspam/pkg/dspam-utilfunc.inc
@@ -0,0 +1,458 @@
+<?php
+/* $Id$ */
+/* Copyright (C) 2006 Daniel S. Haischt */
+require_once("functions.inc");
+require_once("dspam.inc");
+
+function &GetPrefs($user) {
+ global $CONFIG, $USER;
+ $prefs = array();
+ $FILE = "{$USER}.prefs";
+
+ if ($CONFIG['PREFERENCES_EXTENSION'] == 1) {
+ $handle = popen ("{$CONFIG['DSPAM_BIN']}/dspam_admin agg pref " . quotemeta($user));
+
+ while (!feof($handle)) {
+ $buffer = chop(fgets($handle, 4096));
+ list($key, $value) = split("=", $buffer);
+ $prefs[$key] = $value;
+ }
+
+ pclose($handle);
+
+ }
+
+ if (count(array_keys($prefs)) == 0 || $CONFIG['PREFERENCES_EXTENSION'] != 1) {
+
+ /* This step is only required if the user
+ * wants to use the legacy DSPAm CGI app.
+ */
+ if (! file_exists("{$CONFIG['DSPAM_WWW']}/default.prefs")) {
+ /* try to copy the sample file */
+ if (file_exists("{$CONFIG['DSPAM_WWW']}/default.prefs.sample")) {
+ copy("{$CONFIG['DSPAM_WWW']}/default.prefs.sample",
+ "{$CONFIG['DSPAM_WWW']}/default.prefs");
+ }
+ }
+ $handle = fopen ("{$CONFIG['DSPAM_WWW']}/default.prefs", "r");
+
+ while (!feof($handle)) {
+ $buffer = chop(fgets($handle, 4096));
+ list($key, $value) = split("=", $buffer);
+ $prefs[$key] = $value;
+ }
+
+ fclose($handle);
+
+ if(file_exists($FILE)) {
+ $handle = fopen ($FILE, "r");
+
+ while (!feof($handle)) {
+ $buffer = chop(fgets($handle, 4096));
+ list($key, $value) = split("=", $buffer);
+ $prefs[$key] = $value;
+ }
+ }
+ }
+ return $prefs;
+}
+
+function CheckQuarantine() {
+ global $MAILBOX, $DATA;
+ $f = 0;
+
+ if (file_exists($MAILBOX)) {
+ $handle = fopen($MAILBOX, "r");
+
+ while (!feof($handle)) {
+ $buffer = fgets($handle, 4096);
+ if (preg_match('/^From /', $buffer) <= 0) {continue;}
+ $f++;
+ }
+
+ fclose ($handle);
+ }
+
+ if ($f == 0) {
+ $f = "Empty";
+ }
+
+ $DATA['TOTAL_QUARANTINED_MESSAGES'] = $f;
+}
+
+function http_parse_query( $array = NULL, $convention = '%s' ) {
+ if( count( $array ) == 0 ) {
+ return '';
+ } else {
+ if( function_exists( 'http_build_query' ) ){
+ $query = http_build_query( $array );
+ } else {
+ $query = '';
+
+ foreach( $array as $key => $value ) {
+ if( is_array( $value ) ){
+ $new_convention = sprintf( $convention, $key ) . '[%s]';
+ $query .= http_parse_query( $value, $new_convention );
+ } else {
+ $key = urlencode( $key );
+ $value = urlencode( $value );
+ $query .= sprintf( $convention, $key ) . "=$value&";
+ }
+ }
+ }
+
+ return $query;
+ }
+}
+
+/* just a wrapper function */
+function SafeVars($PAIRS) {
+ $url = http_parse_query($PAIRS);
+ return $url;
+}
+
+function To12Hour($h) {
+ if ($h < 0) { $h += 24; }
+ if ($h > 11) { if ($h > 12) { $h -= 12; } $h .= "p"; }
+ else { if ($h == 0) { $h = "12"; } $h .= "a"; }
+ return $h;
+}
+
+function GetPath($store) {
+ global $CONFIG, $USER;
+ $PATH = "";
+
+ /* Domain-scalen */
+ if ($CONFIG['DOMAIN_SCALE'] == 1) {
+ $splittmp = (split('@', $store));
+ $VPOPUSERNAME = $splittmp[0];
+ $VPOPDOMAIN = $splittmp[1];
+ if ($VPOPDOMAIN == "") {$VPOPDOMAIN = "local";}
+
+ $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$VPOPDOMAIN}/{$VPOPUSERNAME}/" .
+ "{$VPOPUSERNAME}";
+ return $PATH;
+
+ /* Normal scale */
+ } else if ($CONFIG['LARGE_SCALE'] == 0) {
+ $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$USER}/{$USER}";
+ return $PATH;
+
+ /* Large-scale */
+ } else {
+ if (strlen($USER) > 1) {
+ $PATH = "{$CONFIG['DSPAM_HOME']}/data/" . substr($USER, 0, 1) .
+ "/". substr($USER, 1, 1) . "/{$USER}/{$USER}";
+ } else {
+ $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$USER}/{$USER}";
+ }
+ return $PATH;
+ }
+}
+
+function GetUserDir($store) {
+ global $CONFIG, $USER;
+ $PATH = "";
+
+ /* Domain-scalen */
+ if ($CONFIG['DOMAIN_SCALE'] == 1) {
+ $splittmp = (split('@', $store));
+ $VPOPUSERNAME = $splittmp[0];
+ $VPOPDOMAIN = $splittmp[1];
+ if ($VPOPDOMAIN == "") {$VPOPDOMAIN = "local";}
+
+ $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$VPOPDOMAIN}/{$VPOPUSERNAME}";
+ return $PATH;
+
+ /* Normal scale */
+ } else if ($CONFIG['LARGE_SCALE'] == 0) {
+ $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$USER}/";
+ return $PATH;
+
+ /* Large-scale */
+ } else {
+ if (strlen($USER) > 1) {
+ $PATH = "{$CONFIG['DSPAM_HOME']}/data/" . substr($USER, 0, 1) .
+ "/". substr($USER, 1, 1) . "/{$USER}/{$USER}";
+ } else {
+ $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$USER}";
+ }
+ return $PATH;
+ }
+}
+
+function GetDomain($store) {
+ global $CONFIG, $USER;
+ $PATH = "";
+
+ /* Domain-scalen */
+ if ($CONFIG['DOMAIN_SCALE'] == 1) {
+ $splittmp = (split('@', $store));
+ $VPOPUSERNAME = $splittmp[0];
+ $VPOPDOMAIN = $splittmp[1];
+ if ($VPOPDOMAIN == "") {$VPOPDOMAIN = "local";}
+
+ return $VPOPDOMAIN;
+ }
+}
+
+function isDSPAMAdmin($username = "") {
+ global $config, $CONFIG;
+
+ $groupindex = index_groups();
+ $userindex = index_users();
+
+ if ($username == "") { return 0; }
+
+ $gname = $config['system']['group'][$groupindex[$config['system']['user'][$userindex[$username]]['groupname']]]['name'];
+
+ if (isset($gname)) {
+ return ($gname === $CONFIG['DSPAM_ADMIN_GROUP']);
+ }
+
+ return 0;
+}
+
+function createUserNotificationMessages() {
+ global $config, $CONFIG, $USER, $CURRENT_USER, $CURRENT_STORE;
+
+ $firstrun = "{$USER}.firstrun";
+ $firstspam = "{$USER}.firstspam";
+ $quarantinefull = "{$USER}.quarantinefull";
+ $savemsg = "";
+
+ if (isset($config['installedpackages']['dspam']['config'][0]['dspam-domain']))
+ $domain = $config['installedpackages']['dspam']['config'][0]['dspam-domain'];
+ else
+ $domain = $config['system']['domain'];
+
+ if (GetDomain($CURRENT_STORE) <> "")
+ $user_domain = GetDomain($CURRENT_STORE);
+ else
+ $user_domain = $config['system']['domain'];
+
+ $userdir = GetUserDir($CURRENT_STORE);
+ $hostname = $config['system']['hostname'];
+ $support_user = $config['installedpackages']['dspam']['config'][0]['dspam-contact'];
+
+ /* return if there are no sample files */
+ if (! file_exists("{$CONFIG['DSPAM_HOME']}/firstrun.txt.sample") ||
+ ! file_exists("{$CONFIG['DSPAM_HOME']}/firstspam.txt.sample") ||
+ ! file_exists("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt.sample") ||
+ ! file_exists($userdir)) {
+ return;
+ }
+
+ /* create firstrun.txt */
+ if (! file_exists("{$firstrun}")) {
+ $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/firstrun.txt.sample");
+
+ $sample_msg = str_replace("support", $support_user, $sample_msg);
+ $sample_msg = str_replace("configureme.com", $user_domain, $sample_msg);
+ $sample_msg = str_replace("http://www.yourdomain.com/dspam/",
+ "http://{$hostname}.{$domain}/dspam.php",
+ $sample_msg);
+
+ @file_put_contents("{$firstrun}", $sample_msg);
+ $savemsg .= " »{$firstrun}«, ";
+ }
+
+ /* create firstspam.txt */
+ if (! file_exists("{$firstspam}")) {
+ $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/firstspam.txt.sample");
+
+ $sample_msg = str_replace("support", $support_user, $sample_msg);
+ $sample_msg = str_replace("configureme.com", $user_domain, $sample_msg);
+ $sample_msg = str_replace("http://www.yourdomain.com/dspam/",
+ "http://{$hostname}.{$domain}/dspam.php",
+ $sample_msg);
+
+ @file_put_contents("{$firstspam}", $sample_msg);
+ $savemsg .= " »{$firstspam}«, ";
+ }
+
+ /* create quarantinefull.txt */
+ if (! file_exists("{$quarantinefull}")) {
+ $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt.sample");
+
+ $sample_msg = str_replace("support", $support_user, $sample_msg);
+ $sample_msg = str_replace("configureme.com", $user_domain, $sample_msg);
+ $sample_msg = str_replace("http://www.yourdomain.com/dspam/",
+ "http://{$hostname}.{$domain}/dspam.php",
+ $sample_msg);
+
+ @file_put_contents("{$quarantinefull}", $sample_msg);
+ $savemsg .= " »{$quarantinefull}«.";
+ }
+
+ if ($savemsg <> "") {
+ $savemsg = gettext("The following files were created: ") . $savemsg;
+ return $savemsg;
+ }
+
+ return;
+}
+
+function createNotificationMessages() {
+ global $config, $CONFIG, $USER, $CURRENT_USER;
+
+ $firstrun = "{$CONFIG['DSPAM_HOME']}/firstrun.txt";
+ $firstspam = "{$CONFIG['DSPAM_HOME']}/firstspam.txt";
+ $quarantinefull = "{$CONFIG['DSPAM_HOME']}/quarantinefull.txt";
+ $savemsg = "";
+
+ if (isset($config['installedpackages']['dspam']['config'][0]['dspam-domain']))
+ $domain = $config['installedpackages']['dspam']['config'][0]['dspam-domain'];
+ else
+ $domain = $config['system']['domain'];
+
+ $hostname = $config['system']['hostname'];
+ $support_user = $config['installedpackages']['dspam']['config'][0]['dspam-contact'];
+
+ /* return if there are no sample files */
+ if (! file_exists("{$CONFIG['DSPAM_HOME']}/firstrun.txt.sample") ||
+ ! file_exists("{$CONFIG['DSPAM_HOME']}/firstspam.txt.sample") ||
+ ! file_exists("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt.sample")) {
+ return;
+ }
+
+ /* create firstrun.txt */
+ if (! file_exists("{$CONFIG['DSPAM_HOME']}/firstrun.txt")) {
+ $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/firstrun.txt.sample");
+
+ $sample_msg = str_replace("support", $support_user, $sample_msg);
+ $sample_msg = str_replace("configureme.com", $domain, $sample_msg);
+ $sample_msg = str_replace("http://www.yourdomain.com/dspam/",
+ "http://{$hostname}.{$domain}/dspam.php",
+ $sample_msg);
+
+ @file_put_contents("{$firstrun}", $sample_msg);
+ $savemsg .= " »{$firstrun}«, ";
+ }
+
+ /* create firstspam.txt */
+ if (! file_exists("{$CONFIG['DSPAM_HOME']}/firstspam.txt")) {
+ $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/firstspam.txt.sample");
+
+ $sample_msg = str_replace("support", $support_user, $sample_msg);
+ $sample_msg = str_replace("configureme.com", $domain, $sample_msg);
+ $sample_msg = str_replace("http://www.yourdomain.com/dspam/",
+ "http://{$hostname}.{$domain}/dspam.php",
+ $sample_msg);
+
+ @file_put_contents("{$firstspam}", $sample_msg);
+ $savemsg .= " »{$firstspam}«, ";
+ }
+
+ /* create quarantinefull.txt */
+ if (! file_exists("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt")) {
+ $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt.sample");
+
+ $sample_msg = str_replace("support", $support_user, $sample_msg);
+ $sample_msg = str_replace("configureme.com", $domain, $sample_msg);
+ $sample_msg = str_replace("http://www.yourdomain.com/dspam/",
+ "http://{$hostname}.{$domain}/dspam.php",
+ $sample_msg);
+
+ @file_put_contents("{$quarantinefull}", $sample_msg);
+ $savemsg .= " »{$quarantinefull}«.";
+ }
+
+ if ($savemsg <> "") {
+ $savemsg = gettext("The following files were created: ") . $savemsg;
+ return $savemsg;
+ }
+
+ return;
+}
+
+function &check_dspam_installation() {
+ global $config;
+
+ /* create RC files if necessary */
+ if (! file_exists("/usr/local/etc/rc.d")) {
+ @mkdir("/usr/local/etc/rc.d");
+ }
+ if (! file_exists("/usr/local/etc/rc.d/000.mysql.sh")) {
+ @copy("/usr/local/pkg/000.mysql.sh", "/usr/local/etc/rc.d/000.mysql.sh");
+ @chmod("/usr/local/etc/rc.d/000.mysql.sh", 0755);
+ }
+ if (! file_exists("/usr/local/etc/rc.d/010.clamav-clamd.sh")) {
+ @copy("/usr/local/pkg/010.clamav-clamd.sh",
+ "/usr/local/etc/rc.d/010.clamav-clamd.sh");
+ @chmod("/usr/local/etc/rc.d/010.clamav-clamd.sh", 0755);
+ }
+ if (! file_exists("/usr/local/etc/rc.d/020.clamav-freshclam.sh")) {
+ @copy("/usr/local/pkg/020.clamav-freshclam.sh",
+ "/usr/local/etc/rc.d/020.clamav-freshclam.sh");
+ @chmod("/usr/local/etc/rc.d/020.clamav-freshclam.sh", 0755);
+ }
+ if (! file_exists("/usr/local/etc/rc.d/030.p3scan.sh")) {
+ @copy("/usr/local/pkg/030.p3scan.sh",
+ "/usr/local/etc/rc.d/030.p3scan.sh");
+ @chmod("/usr/local/etc/rc.d/030.p3scan.sh", 0755);
+ }
+
+ /* create conf files for those packages DSPAM depends on */
+ if (! file_exists("/usr/local/etc/clamd.conf")) {
+ @copy("/usr/local/pkg/clamd.conf",
+ "/usr/local/etc/clamd.conf");
+ }
+ if (! file_exists("/usr/local/etc/freshclam.conf")) {
+ @copy("/usr/local/pkg/freshclam.conf",
+ "/usr/local/etc/freshclam.conf");
+ }
+
+ if (! is_service_running("dspam")) {
+ $input_errors[] = "The DSPAM daemon process is not running. " .
+ "If you are certain that you did configure DSPAM " .
+ "appropriatly, you can start the corresponding process " .
+ "using the service control panel which is part of the " .
+ "»Status« menu item.";
+ }
+ if (! is_service_running("p3scan")) {
+ $input_errors[] = "The POP3 proxy process is not running. " .
+ "If you are certain that you did configure the POP3 proxy " .
+ "appropriatly, you can start the corresponding process " .
+ "using the service control panel which is part of the " .
+ "»Status« menu item.";
+ }
+ if (! is_service_running("clamd")) {
+ $input_errors[] = "The ClamAV daemon process is not running. " .
+ "If you are certain that you did configure DSPAM " .
+ "appropriatly, you can start the corresponding process " .
+ "using the service control panel which is part of the " .
+ "»Status« menu item (ClamAV does not need any configuration).";
+ }
+ if (! is_service_running("freshclam")) {
+ $input_errors[] = "The freshclam daemon process is not running. " .
+ "If you are certain that you did configure DSPAM " .
+ "appropriatly, you can start the corresponding process " .
+ "using the service control panel which is part of the " .
+ "»Status« menu item (freshclam does not need any configuration).";
+ }
+ if (! is_service_running("mysql")) {
+ $input_errors[] = "The MySQL daemon process is not running. " .
+ "If you are certain that you did configure DSPAM " .
+ "appropriatly, you can start the corresponding process " .
+ "using the service control panel which is part of the " .
+ "»Status« menu item (MySQL does not need any configuration).";
+ }
+
+ if (empty($config['installedpackages']['dspam']['config']) ||
+ empty($config['installedpackages']['dspam']['config'][0]['storage-driver']) ||
+ (file_exists('/usr/local/etc/dspam.conf') == false)) {
+ /* create default config files etc. */
+ sync_package_dspam();
+
+ $input_errors[] = "It seems that you are using DSPAM for the very first time. " .
+ "Please run the DSPAM wizard from the »Services« menu " .
+ "if you would like to configure DSPAM right now. " .
+ "If you are not eligible to administer DSPAM you may contact " .
+ "your local DSPAM admin personal to solve this issue.";
+ }
+
+ return $input_errors;
+}
+
+?>
diff --git a/config/dspam/pkg/dspam.inc b/config/dspam/pkg/dspam.inc
new file mode 100644
index 00000000..9a821e6a
--- /dev/null
+++ b/config/dspam/pkg/dspam.inc
@@ -0,0 +1,360 @@
+<?php
+/* $Id$ */
+/* Copyright (C) 2006 Daniel S. Haischt */
+
+/* include all configuration functions */
+require_once ("functions.inc");
+require_once ("dspam-config.inc");
+require_once ("dspam-guifunc.inc");
+require_once ("dspam-pkgfunc.inc");
+require_once ("dspam-utilfunc.inc");
+
+/* General TODO(s):
+ *
+ * - Use quotemeta where applicable
+ * - Issue a change message after a successful GET/POST
+ * - Issue an error message if something went wrong during a GET/POST
+ * - Revise user management (CURENT_USER, SESSION_USER etc.)
+ */
+
+$DATA = array();
+
+/*
+ * Determine which extensions are available
+ */
+if ($CONFIG['AUTODETECT'] == 1 || $CONFIG['AUTODETECT'] == "") {
+ $CONFIG['PREFERENCES_EXTENSION'] = 0;
+ $CONFIG['LARGE_SCALE'] = 0;
+ $CONFIG['DOMAIN_SCALE'] = 0;
+
+ $buffer = "";
+ $handle = popen ("/usr/local/bin/dspam --version", "r");
+
+ while (!feof($handle)) {
+ $buffer .= fgets($handle, 4096);
+ }
+
+ pclose($handle);
+
+ if (strpos($buffer, '--enable-preferences-extension') !== false) {
+ $CONFIG['PREFERENCES_EXTENSION'] = 1;
+ }
+ if (strpos($buffer, '--enable-large-scale') !== false) {
+ $CONFIG['LARGE_SCALE'] = 1;
+ }
+ if (strpos($buffer, '--enable-domain-scale') !== false) {
+ $CONFIG['DOMAIN_SCALE'] = 1;
+ }
+}
+
+/*
+ * Determine admin status
+ */
+
+$CONFIG['ADMIN'] = isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER']);
+
+/*
+ * Determine which user should be used to display DSPAm related data
+ */
+$CURRENT_USER = $HTTP_SERVER_VARS['AUTH_USER'];
+
+if (empty($CONFIG['ADMIN']) &&
+ strpos($_SERVER['SCRIPT_NAME'], "wizard.php") !== false) {
+
+ $group = $config['system']['user'][$userindex[$HTTP_SERVER_VARS['AUTH_USER']]]['groupname'];
+ $home = "/" . getGroupHomePage($group);
+ if ($home == "/") { $home = "/index.php"; }
+
+ if (! headers_sent()) {
+ pfSenseHeader($home);
+ exit;
+ } else {
+ $htmlstr = <<< EOD
+<html>
+ <head>
+ <title>Unauthorized Access</title>
+ <meta http-equiv="refresh" content="2; URL={$home}">
+ </head>
+ <body>
+ <h3>Unauthorized Access - You will be redirected shortly!</h3>
+ </body>
+</html>
+EOD;
+ print $htmlstr;
+ exit;
+ }
+}
+
+/*
+ * only DSPAM admins can change the current user without logging out
+ * and logging in as another user again.
+ */
+if ($_POST) {
+ if (! empty($_POST['username']) && $CONFIG['ADMIN'] == 1) {
+ $CURRENT_USER = $_POST['username'];
+ }
+}
+if ($_GET) {
+ if (! empty($_GET['user']) && $CONFIG['ADMIN'] == 1) {
+ $CURRENT_USER = $_GET['user'];
+ }
+}
+
+if ($CURRENT_USER == "") {
+ $input_errors[] = "System Error. I was unable to determine your identity.";
+}
+
+preg_replace('/%CURRENT_USER%/', $CURRENT_USER, $CONFIG['DSPAM_ARGS']);
+
+/* current store */
+$PREF =& GetPrefs($CURRENT_USER);
+$CURRENT_STORE = $PREF['localStore'];
+if ($CURRENT_STORE == "") {$CURRENT_STORE = $CURRENT_USER; }
+
+$USER = GetPath($CURRENT_STORE);
+$MAILBOX = $USER . ".mbox";
+$TMPFILE = $USER . ".tmp";
+
+/*
+ * Set up initial display variables
+ */
+CheckQuarantine();
+$DATA['REMOTE_USER'] = $CURRENT_USER;
+
+/*
+ * Check whether DSPAM is already configured.
+ */
+$install_errors =& check_dspam_installation();
+$input_errors = array_merge($input_errors, $install_errors);
+
+/*
+ * Check whether we should generate notification messages
+ */
+if (isset($config['installedpackages']['dspam']['config'][0]['notification-email'])) {
+ $tmpmsg = createNotificationMessages();
+ if (! empty($tmpmsg))
+ $tmpmsg .= "\n" . createUserNotificationMessages();
+ else
+ $tmpmsg = createUserNotificationMessages();
+
+ $savemsg =& $tmpmsg;
+}
+
+/*
+ * Process Commands
+ */
+if (isset($pgtitle) && is_array($pgtitle)) {
+ /* Performance */
+ if (basename($_SERVER['SCRIPT_NAME']) == "dspam-perf.php") {
+ if ($_GET) {
+ if ($GET['command'] == "resetStats") {
+ ResetStats();
+ } else if ($GET['command'] == "tweak") {
+ Tweak();
+ }
+ }
+
+ $display_errors =& DisplayIndex();
+ $input_errors = array_merge($input_errors, $display_errors);
+ }
+
+ /* Preferences */
+ else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-prefs.php") {
+ $savemsg = "";
+ $prefs_errors =& DisplayPreferences(NULL, $savemsg);
+ $input_errors = array_merge($input_errors, $prefs_errors);
+ }
+
+ /* Quarantine */
+ else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-quarantine.php") {
+ if ($_GET) {
+ if ($_GET['command'] == "viewMessage") {
+ $showpart = 0;
+ $ctype = 0;
+ $sortby = "Rating";
+ $currentPage = 1;
+ $qPerPage = 0;
+
+ if (isset($_GET['showpart'])) { $showpart = $_GET['showpart']; }
+ if (isset($_GET['ctype'])) { $ctype = intval($_GET['ctype']); }
+ if (isset($_GET['sortby'])) { $sortby = $_GET['sortby']; }
+ if (isset($_GET['page'])) { $currentPage = $_GET['page']; }
+ if (isset($_GET['qperpage'])) { $qPerPage = $_GET['qperpage']; }
+
+ $quarantine_errors =& QuarantineViewMessage($_GET['signatureID'],
+ $showpart,
+ $ctype,
+ $sortby,
+ $currentPage,
+ $qPerPage);
+ $input_errors = array_merge($input_errors, $quarantine_errors);
+ } else if (isset($_GET['sortby'])) {
+ $qperpage = $CONFIG['QUARANTINE_PER_PAGE'];
+ if (isset($_GET['qperpage'])) { $qperpage = $_GET['qperpage']; }
+ $page = 1;
+ if (isset($_GET['page'])) { $page = $_GET['page']; }
+
+ $quarantine_errors =& DisplayQuarantine($_GET['sortby'],
+ intval($page),
+ intval($qperpage));
+ $input_errors = array_merge($input_errors, $quarantine_errors);
+ } else if (isset($_GET['qperpage'])) {
+ if (isset($_GET['page'])) {
+ $quarantine_errors =& DisplayQuarantine($CONFIG['SORT_DEFAULT'],
+ intval($_GET['page']),
+ intval($_GET['qperpage']));
+ $input_errors = array_merge($input_errors, $quarantine_errors);
+ } else {
+ $quarantine_errors =& DisplayQuarantine($CONFIG['SORT_DEFAULT'],
+ 1,
+ intval($_GET['qperpage']));
+ $input_errors = array_merge($input_errors, $quarantine_errors);
+ }
+ } else {
+ $displayq_errors =& DisplayQuarantine($CONFIG['SORT_DEFAULT'], 1);
+ $input_errors = array_merge($input_errors, $displayq_errors);
+ }
+ } else if ($_POST) {
+ if ($_POST['command'] == "processQuarantine") {
+ $signatures = array();
+
+ while (list($key, $val) = each($_POST)) {
+ if (strpos($key, "chkmsg") !== false) {
+ $signatures[$key] = $val;
+ }
+ }
+ if ($_POST['processAction']) {
+ $processq_errors =& ProcessQuarantine($signatures,
+ $_POST['processAction'],
+ $_POST['sortby'],
+ intval($_POST['qpage']),
+ intval($_POST['qperpage']));
+ $input_errors = array_merge($input_errors, $processq_errors);
+ } else {
+ $processq_errors =& ProcessQuarantine($signatures,
+ "None",
+ $_POST['sortby'],
+ intval($_POST['qpage']),
+ intval($_POST['qperpage']));
+ $input_errors = array_merge($input_errors, $processq_errors);
+ }
+ } else if ($_POST['command'] == "processFalsePositive") {
+ $processfp_errors =& ProcessFalsePositive($_POST['signatureID'],
+ $_POST['sortby'],
+ intval($_POST['qpage']),
+ intval($_POST['qperpage']));
+ $input_errors = array_merge($input_errors, $processfp_errors);
+ $displayq_errors =& DisplayQuarantine($_POST['sortby'],
+ intval($_POST['qpage']),
+ intval($_POST['qperpage']));
+ $input_errors = array_merge($input_errors, $displayq_errors);
+ }
+ } else {
+ /* usually this particular line of code should not be hit because
+ * the user always triggers a GET or POST action. Unfortunatly at
+ * the time, the alerts page is implemented in a way that neither
+ * triggers a GET nor a POST action if initially accessed via the
+ * tab. Hence this final catch all else.
+ */
+ $displayq_errors =& DisplayQuarantine($CONFIG['SORT_DEFAULT'], 1);
+ $input_errors = array_merge($input_errors, $displayq_errors);
+ }
+ }
+
+ /* Analysis */
+ else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-analysis.php") {
+ $displaya_errors =& DisplayAnalysis();
+ $input_errors = array_merge($input_errors, $displaya_errors);
+ }
+
+ /* History */
+ else if (in_array(gettext("History"), $pgtitle)) {
+ if ($_POST) {
+ /* Form fields that may be submited via POST:
+ * - command
+ * - username
+ * - msgid$retrain_checked_msg_no (checkbox, multible times)
+ */
+ $checked = array();
+
+ while (list($key, $val) = each($_POST)) {
+ if (strpos($key, "msgid") !== false) {
+ $checked[] = $val;
+ }
+ }
+
+ $displayh_errors =& DisplayHistory($_POST['command'],
+ "",
+ $checked,
+ $_POST['username'],
+ "",
+ $_POST['hpage'],
+ $_POST['hperpage']);
+ $input_errors = array_merge($input_errors, $displayh_errors);
+ } else if ($_GET) {
+ /* Form fields that may be submited via GET:
+ * - history_page
+ * - command
+ * - signatureID
+ * - retrain
+ * - user
+ */
+ $displayh_errors =& DisplayHistory($_GET['command'],
+ $_GET['signatureID'],
+ NULL,
+ $_GET['user'],
+ $_GET['retrain'],
+ isset($_GET['page']) ? intval($_GET['page']) : 1,
+ isset($_GET['hperpage']) ? $_GET['hperpage'] : $CONFIG['QUARANTINE_PER_PAGE']);
+ $input_errors = array_merge($input_errors, $displayh_errors);
+ } else {
+ $displayh_errors =& DisplayHistory("", // command
+ "", // signature ID
+ NULL, // signatures to be retrained
+ $CURRENT_USER);
+ $input_errors = array_merge($input_errors, $displayh_errors);
+ }
+ } else if (in_array(gettext("Fragment"), $pgtitle)) {
+ if ($_GET) {
+ $displayf_errors =& DisplayFragment($_GET['signatureID'],
+ $_GET['from'],
+ $_GET['subject'],
+ $_GET['info'],
+ $_GET['time']);
+ $input_errors = array_merge($input_errors, $displayf_errors);
+ }
+ }
+
+ /* Info Page */
+ else if (basename($_SERVER['SCRIPT_NAME']) == "dspam.php") {
+ $info_errors =& DisplayInfos();
+ $input_errors = array_merge($input_errors, $info_errors);
+ }
+
+/* ========================================================================== */
+/* = A D M I N R E L A T E D F U N C T I O N C A L L S = */
+/* ========================================================================== */
+
+ /* Status */
+ else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-admin.php" && $CONFIG['ADMIN']) {
+ $displays_errors =& DisplayStatus();
+ $input_errors = array_merge($input_errors, $displays_errors);
+ }
+
+ /* User Statistics */
+ else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-admin-stats.php" && $CONFIG['ADMIN']) {
+ $displayus_errors =& DisplayUserStatistics();
+ $input_errors = array_merge($input_errors, $displayus_errors);
+ }
+
+ /* Preferences */
+ else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-admin-prefs.php" && $CONFIG['ADMIN']) {
+ $savemsg = "";
+ $displayap_errors =& DisplayAdminPreferences($savemsg);
+ $input_errors = array_merge($input_errors, $displayap_errors);
+ }
+} else {
+ $input_errors[] = "The page you did request can't be processed by <code>dspam.inc</code>.";
+}
+
+?> \ No newline at end of file
diff --git a/config/dspam/pkg/dspam.xml b/config/dspam/pkg/dspam.xml
new file mode 100644
index 00000000..59740ae1
--- /dev/null
+++ b/config/dspam/pkg/dspam.xml
@@ -0,0 +1,342 @@
+<?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 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ 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>dspam</name>
+ <version>1.0</version>
+ <title>Services: DSPAM: Main</title>
+ <include_file>/usr/local/pkg/dspam.inc</include_file>
+ <!-- Menu is where this packages menu will appear -->
+ <menu>
+ <name>dspam</name>
+ <section>Services</section>
+ <configfile>dspam.xml</configfile>
+ <url>/dspam-perf.php</url>
+ </menu>
+ <menu>
+ <name>DSPAM Legacy WebGUI</name>
+ <tooltiptext>Original Perl-based GUI</tooltiptext>
+ <section>Services</section>
+ <url>/vhosts/dspam/dspam.cgi</url>
+ </menu>
+ <service>
+ <name>dspam</name>
+ <rcfile>/usr/local/etc/rc.d/dspam.sh</rcfile>
+ </service>
+ <tabs>
+ <tab>
+ <text>Overview</text>
+ <url>/dspam.php</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Performance</text>
+ <url>/dspam-perf.php</url>
+ </tab>
+ <tab>
+ <text>Preferences</text>
+ <url>/dspam-prefs.php</url>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/pkg.php?xml=dspam_alerts.xml</url>
+ </tab>
+ <tab>
+ <text>Quarantine</text>
+ <url>/dspam-quarantine.php</url>
+ </tab>
+ <tab>
+ <text>Analysis</text>
+ <url>/dspam-analysis.php</url>
+ </tab>
+ <tab>
+ <text>History</text>
+ <url>/dspam-history.php</url>
+ </tab>
+ </tabs>
+ <!--
+ configpath gets expanded out automatically and config items
+ will be stored in that location
+ -->
+ <configpath>['installedpackages']['dspam']['config']</configpath>
+ <!-- PHP files -->
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-perf.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-admin.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-admin-graph.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-admin-prefs.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-admin-stats.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam_settings.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-settings.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-settings-algo.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-settings-bmta.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-settings-feat.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-header.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-overr.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-settings-prefs.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-spwd.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-tuser.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-train.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam-viewmsg.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/verdana.ttf</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-prefs.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-quarantine.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-analysis.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-analysis-graph.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-hfragment.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/dspam-history.php</item>
+ </additional_files_needed>
+ <!-- package files -->
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.abyssworld.de/packages/config/dspam_alerts.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam-config.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam-guifunc.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam-pkgfunc.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam-utilfunc.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/000.mysql.sh</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/010.clamav-clamd.sh</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/020.clamav-freshclam.sh</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/030.p3scan.sh</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/clamd.conf</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/default.prefs.sample</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/freshclam.conf</item>
+ </additional_files_needed>
+ <!-- misc files -->
+ <additional_files_needed>
+ <prefix>/usr/local/www/wizards/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/wizards/dspam_wizard.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/wizards/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/wizards/dspam-lda-proxy.png</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/wizards/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/wizards/dspam-pop-proxy.png</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/wizards/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/wizards/dspam-smtp-relay.png</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/pkg/verdana.ttf</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/themes/metallic/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/dspam/www/themes/metallic/dspam.css</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.
+ -->
+ <!--
+ Arbitrary PHP Code, that gets executed if a certain event gets triggered.
+ -->
+ <custom_php_resync_config_command>
+ sync_package_dspam();
+ </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>
+</packagegui>
diff --git a/config/dspam/pkg/dspam_alerts.xml b/config/dspam/pkg/dspam_alerts.xml
new file mode 100644
index 00000000..ea59cfd2
--- /dev/null
+++ b/config/dspam/pkg/dspam_alerts.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "../../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../../xsl/package.xsl"?>
+<!--
+ Tags which can be used to exec arbitrary PHP code:
+
+ <custom_php_global_functions />
+ <custom_php_command_before_form />
+ <custom_delete_php_command /> if $_POST && act == del
+ <custom_add_php_command /> if $_POST && act == add
+ <custom_php_resync_config_command />
+ <custom_php_validation_command />
+ <custom_add_php_command_late />
+ <start_command /> shell exec
+ <restart_command /> shell exec
+ <custom_php_after_form_command />
+-->
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ authng.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ 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>dspamalerts</name>
+ <version>1.0</version>
+ <title>Services: DSPAM: Alerts</title>
+ <include_file>/usr/local/pkg/dspam.inc</include_file>
+ <!-- Menu is where this packages menu will appear -->
+ <tabs>
+ <tab>
+ <text>Performance</text>
+ <url>/dspam-perf.php</url>
+ </tab>
+ <tab>
+ <text>Preferences</text>
+ <url>/dspam-prefs.php</url>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/pkg.php?xml=dspam_alerts.xml</url>
+ <active />
+ </tab>
+ <tab>
+ <text>Quarantine</text>
+ <url>/dspam-quarantine.php</url>
+ </tab>
+ <tab>
+ <text>Analysis</text>
+ <url>/dspam-analysis.php</url>
+ </tab>
+ <tab>
+ <text>History</text>
+ <url>/dspam-history.php</url>
+ </tab>
+ <tab>
+ <text>Train Filter</text>
+ <url>/dspam-train.php</url>
+ </tab>
+ <tab>
+ <text>Admin Suite</text>
+ <url>/dspam-admin.php</url>
+ </tab>
+ </tabs>
+ <!--
+ configpath gets expanded out automatically and config items
+ will be stored in that location
+ -->
+ <configpath>['installedpackages']['dspam']['config']['alerts']</configpath>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fielddescr>Alert Name</fielddescr>
+ <fieldname>alertname</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>Alert Name</fielddescr>
+ <fieldname>alertname</fieldname>
+ <description>Name of an alert that should be raised</description>
+ <type>input</type>
+ <size>30</size>
+ <required />
+ </field>
+ <field>
+ <fielddescr>Description</fielddescr>
+ <fieldname>description</fieldname>
+ <description>You may enter a description here for your reference (not parsed).</description>
+ <type>input</type>
+ <size>30</size>
+ </field>
+ </fields>
+ <!--
+ Arbitrary PHP Code, that gets executed if a certain event gets triggered.
+ -->
+ <custom_delete_php_command>
+ dspam_configure();
+ </custom_delete_php_command>
+ <custom_php_resync_config_command>
+ dspam_configure();
+ </custom_php_resync_config_command>
+</packagegui> \ No newline at end of file
diff --git a/config/dspam/pkg/freshclam.conf b/config/dspam/pkg/freshclam.conf
new file mode 100644
index 00000000..173d97bf
--- /dev/null
+++ b/config/dspam/pkg/freshclam.conf
@@ -0,0 +1,110 @@
+##
+## Example config file for freshclam
+## Please read the freshclam.conf(5) manual before editing this file.
+## This file may be optionally merged with clamd.conf.
+##
+
+
+# Comment or remove the line below.
+#Example
+
+# Path to the database directory.
+# WARNING: It must match clamd.conf's directive!
+# Default: hardcoded (depends on installation options)
+#DatabaseDirectory /var/lib/clamav
+DatabaseDirectory /var/db/clamav
+
+# Path to the log file (make sure it has proper permissions)
+# Default: disabled
+#UpdateLogFile /var/log/freshclam.log
+UpdateLogFile /var/log/clamav/freshclam.log
+
+# Enable verbose logging.
+# Default: no
+#LogVerbose yes
+
+# Use system logger (can work together with UpdateLogFile).
+# Default: no
+#LogSyslog yes
+
+# Specify the type of syslog messages - please refer to 'man syslog'
+# for facility names.
+# Default: LOG_LOCAL6
+#LogFacility LOG_MAIL
+
+# This option allows you to save the process identifier of the daemyes
+# Default: disabled
+#PidFile /var/run/freshclam.pid
+PidFile /var/run/clamav/freshclam.pid
+
+# By default when started freshclam drops privileges and switches to the
+# "clamav" user. This directive allows you to change the database owner.
+# Default: clamav (may depend on installation options)
+DatabaseOwner clamav
+
+# Initialize supplementary group access (freshclam must be started by root).
+# Default: no
+AllowSupplementaryGroups yes
+
+# Use DNS to verify virus database version. Freshclam uses DNS TXT records
+# to verify database and software versions. With this directive you can change
+# the database verification domain.
+# WARNING: Do not touch it unless you're configuring freshclam to use your
+# own database verification domain.
+# Default: current.cvd.clamav.net
+#DNSDatabaseInfo current.cvd.clamav.net
+
+# Uncomment the following line and replace XY with your country
+# code. See http://www.iana.org/cctld/cctld-whois.htm for the full list.
+#DatabaseMirror db.XY.clamav.net
+
+# database.clamav.net is a round-robin record which points to our most
+# reliable mirrors. It's used as a fall back in case db.XY.clamav.net is
+# not working. DO NOT TOUCH the following line unless you know what you
+# are doing.
+DatabaseMirror database.clamav.net
+
+# How many attempts to make before giving up.
+# Default: 3 (per mirror)
+#MaxAttempts 5
+
+# Number of database checks per day.
+# Default: 12 (every two hours)
+#Checks 24
+
+# Proxy settings
+# Default: disabled
+#HTTPProxyServer myproxy.com
+#HTTPProxyPort 1234
+#HTTPProxyUsername myusername
+#HTTPProxyPassword mypass
+
+# Use aaa.bbb.ccc.ddd as client address for downloading databases. Useful for
+# multi-homed systems.
+# Default: Use OS'es default outgoing IP address.
+#LocalIPAddress aaa.bbb.ccc.ddd
+
+# Send the RELOAD command to clamd.
+# Default: no
+NotifyClamd /usr/local/etc/clamd.conf
+
+# Run command after successful database update.
+# Default: disabled
+#OnUpdateExecute command
+
+# Run command when database update process fails.
+# Default: disabled
+#OnErrorExecute command
+
+# Run command when freshclam reports outdated version.
+# In the command string %v will be replaced by the new version number.
+# Default: disabled
+#OnOutdatedExecute command
+
+# Don't fork into background.
+# Default: no
+#Foreground yes
+
+# Enable debug messages in libclamav.
+# Default: no
+#Debug yes
diff --git a/config/dspam/pkg/p3scan-pf-emer.xml b/config/dspam/pkg/p3scan-pf-emer.xml
new file mode 100644
index 00000000..7475e23c
--- /dev/null
+++ b/config/dspam/pkg/p3scan-pf-emer.xml
@@ -0,0 +1,127 @@
+<?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 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ 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>
+ <!-- change this if configpath works -->
+ <name>p3scanpfemer</name>
+ <version>1.0</version>
+ <title>Services: POP3 Proxy: Emergency Contact</title>
+ <include_file>/usr/local/pkg/p3scan.inc</include_file>
+ <tabs>
+ <tab>
+ <text>Daemon Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Message Processing</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-msg.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Emergency Contact</text>
+ <url>/pkg.php?xml=p3scan-pf-emer.xml</url>
+ <active />
+ </tab>
+ <tab>
+ <text>Virus Scanner Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>SPAM Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&amp;id=0</url>
+ </tab>
+ </tabs>
+ <!--
+ configpath gets expanded out automatically and config items
+ will be stored in that location
+ -->
+ <configpath>['installedpackages']['p3scanpf']['config']['contacts']</configpath>
+ <!--
+ adddeleteeditpagefields items will appear on the first page where you can
+ add / delete or edit items. An example of this would be the nat page where
+ you add new nat redirects
+ -->
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fielddescr>Email Address</fielddescr>
+ <fieldname>emailaddress</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>Email Address</fielddescr>
+ <fieldname>emailaddress</fieldname>
+ <description>
+ In the event p3scan encounters a catastrophic problem and has to terminate,
+ it will send an email to these email addresses just before setting up to
+ close down on the next iteration of a child process.
+ </description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Description</fielddescr>
+ <fieldname>description</fieldname>
+ <description>Description.</description>
+ <type>input</type>
+ </field>
+ </fields>
+ <!--
+ Arbitrary PHP Code, that gets executed if a certain event gets triggered.
+ -->
+ <custom_delete_php_command>
+ sync_package_p3scan();
+ </custom_delete_php_command>
+ <custom_php_resync_config_command>
+ sync_package_p3scan();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/config/dspam/pkg/p3scan-pf-msg.xml b/config/dspam/pkg/p3scan-pf-msg.xml
new file mode 100644
index 00000000..b2144fe6
--- /dev/null
+++ b/config/dspam/pkg/p3scan-pf-msg.xml
@@ -0,0 +1,198 @@
+<?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 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ 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>
+ <!-- change this if configpath works -->
+ <name>p3scanpfmsg</name>
+ <version>1.0</version>
+ <title>Services: POP3 Proxy: Message Processing</title>
+ <note>
+ This &lt;acronym title=&quot;Hypertext Markup Language&quot;&gt;HTML&lt;/acronym&gt; page uses default values, hence even if each field is
+ set, you are still required to save this page if you are editing this page
+ for the very first time!
+ </note>
+ <aftersaveredirect>pkg_edit.php?xml=p3scan-pf-msg.xml&amp;id=0</aftersaveredirect>
+ <include_file>/usr/local/pkg/p3scan.inc</include_file>
+ <tabs>
+ <tab>
+ <text>Daemon Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Message Processing</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-msg.xml&amp;id=0</url>
+ <active />
+ </tab>
+ <tab>
+ <text>Emergency Contact</text>
+ <url>/pkg.php?xml=p3scan-pf-emer.xml</url>
+ </tab>
+ <tab>
+ <text>Virus Scanner Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>SPAM Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&amp;id=0</url>
+ </tab>
+ </tabs>
+ <!--
+ configpath gets expanded out automatically and config items
+ will be stored in that location
+ -->
+ <configpath>['installedpackages']['p3scanpf']['config']['messaging']</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>Just Delete</fielddescr>
+ <fieldname>justdelete</fieldname>
+ <description>
+ Instead of keeping an infected message in the Virus Directory, delete it
+ after reporting it to the user.
+ </description>
+ <type>checkbox</type>
+ <donotdisable>true</donotdisable>
+ </field>
+ <field>
+ <fielddescr>Bytes Free</fielddescr>
+ <fieldname>bytesfree</fieldname>
+ <description>The number of KB's there must be free before processing any mail.</description>
+ <type>input</type>
+ <required />
+ <default_value>10000</default_value>
+ </field>
+ <field>
+ <fielddescr>Broken Email Clients</fielddescr>
+ <fieldname>brokenec</fieldname>
+ <description>
+ Some email clients may require special processing.
+ </description>
+ <type>checkbox</type>
+ <donotdisable>true</donotdisable>
+ </field>
+ <field>
+ <fielddescr>ISP Spam</fielddescr>
+ <fieldname>ispspam</fieldname>
+ <description>
+ This option allows you to set the string your &lt;acronym title=&quot;Internet Service Provider&quot;&gt;ISP&lt;/acronym&gt; uses if it processes
+ your email for SPAM. Leave this field blank if you are not going to use
+ this option.
+ </description>
+ <type>input</type>
+ <default_value>-- Spam --</default_value>
+ </field>
+ <field>
+ <fielddescr>Subject</fielddescr>
+ <fieldname>subject</fieldname>
+ <description>
+ This option can be used to change the default subject line when
+ reporting a virus infected message.
+ </description>
+ <type>input</type>
+ <size>60</size>
+ <required />
+ <default_value>Subject: "[Virus] found in a mail to you:" &lt;virus name&gt;</default_value>
+ </field>
+ <field>
+ <fielddescr>Notify</fielddescr>
+ <fieldname>notify</fieldname>
+ <description>
+ This option can be used to change the default file deleted notification
+ that is displayed in the virus notification message when the
+ &quot;justdelete&quot; option is used.
+ </description>
+ <type>input</type>
+ <size>60</size>
+ <required />
+ <default_value>Per instruction, the message has been deleted.</default_value>
+ </field>
+ <field>
+ <fielddescr>SMTP Reject</fielddescr>
+ <fieldname>smtpreject</fieldname>
+ <description>
+ This option can be used to change the default lt;acronym title=&quot;Simple Mail Transfer Protocol&quot;&gt;SMTP&lt;/acronym&gt; Reject message that
+ is sent to the client in the event a message is rejected due to a virus.
+ The error message will have a prefix of &quot;554&quot;.
+ </description>
+ <type>input</type>
+ <size>60</size>
+ <required />
+ <default_value>Virus detected! P3scan rejected message!</default_value>
+ </field>
+ <field>
+ <fielddescr>Check SMTP size</fielddescr>
+ <fieldname>checksize</fieldname>
+ <description>
+ This option can be used to set the maximum message size (in KBytes)
+ that p3scan will use to determine if it should scan an smtp submission.
+ Leave this field blank if you are not going to use this option.
+ </description>
+ <type>input</type>
+ <default_value>1024</default_value>
+ </field>
+ <field>
+ <fielddescr>Footer</fielddescr>
+ <fieldname>footer</fieldname>
+ <description>
+ This option is used to add the virus definition info from your scanner
+ to an SMTP message. Leave this field blank if you are not going to use
+ this option.
+ </description>
+ <type>input</type>
+ <size>40</size>
+ <default_value>/usr/local/bin/clamdscan -V</default_value>
+ </field>
+ </fields>
+ <!--
+ Arbitrary PHP Code, that gets executed if a certain event gets triggered.
+ -->
+ <custom_php_resync_config_command>
+ sync_package_p3scan();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/config/dspam/pkg/p3scan-pf-spam.xml b/config/dspam/pkg/p3scan-pf-spam.xml
new file mode 100644
index 00000000..eae78a0f
--- /dev/null
+++ b/config/dspam/pkg/p3scan-pf-spam.xml
@@ -0,0 +1,119 @@
+<?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 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ 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>
+ <!-- change this if configpath works -->
+ <name>p3scanpfspam</name>
+ <version>1.0</version>
+ <title>Services: POP3 Proxy: SPAM Settings</title>
+ <note>
+ This &lt;acronym title=&quot;Hypertext Markup Language&quot;&gt;HTML&lt;/acronym&gt; page uses default values, hence even if each field is
+ set, you are still required to save this page if you are editing this page
+ for the very first time!
+ </note>
+ <aftersaveredirect>pkg_edit.php?xml=p3scan-pf-spam.xml&amp;id=0</aftersaveredirect>
+ <include_file>/usr/local/pkg/p3scan.inc</include_file>
+ <tabs>
+ <tab>
+ <text>Daemon Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Message Processing</text>
+ <url>pkg_edit.php?xml=p3scan-pf-msg.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Emergency Contact</text>
+ <url>/pkg.php?xml=p3scan-pf-emer.xml</url>
+ </tab>
+ <tab>
+ <text>Virus Scanner Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>SPAM Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&amp;id=0</url>
+ <active />
+ </tab>
+ </tabs>
+ <!--
+ configpath gets expanded out automatically and config items
+ will be stored in that location
+ -->
+ <configpath>['installedpackages']['p3scanpf']['config']['spam']</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>Enable Spam Checking</fielddescr>
+ <fieldname>checkspam</fieldname>
+ <description>
+ If set, will scan for Spam before scanning for a virus.
+ </description>
+ <type>checkbox</type>
+ <donotdisable>true</donotdisable>
+ <enablefields>spamcheck</enablefields>
+ </field>
+ <field>
+ <fielddescr>SPAM Executable Command</fielddescr>
+ <fieldname>spamcheck</fieldname>
+ <description>The command (plus arguments) that should be invoked to check for SPAM messages.</description>
+ <type>input</type>
+ <size>70</size>
+ <default_value>
+ /usr/local/bin/dspam --user dspamuser --mode=teft --stdout --deliver=innocent,spam --feature=ch,no,wh
+ </default_value>
+ </field>
+ </fields>
+ <!--
+ Arbitrary PHP Code, that gets executed if a certain event gets triggered.
+ -->
+ <custom_php_resync_config_command>
+ sync_package_p3scan();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/config/dspam/pkg/p3scan-pf-vir.xml b/config/dspam/pkg/p3scan-pf-vir.xml
new file mode 100644
index 00000000..ed68b8cf
--- /dev/null
+++ b/config/dspam/pkg/p3scan-pf-vir.xml
@@ -0,0 +1,162 @@
+<?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 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ 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>
+ <!-- change this if configpath works -->
+ <name>p3scanpfvir</name>
+ <version>1.0</version>
+ <title>Services: POP3 Proxy: Virus Scanner Settings</title>
+ <note>
+ This &lt;acronym title=&quot;Hypertext Markup Language&quot;&gt;HTML&lt;/acronym&gt; page uses default values, hence even if each field is
+ set, you are still required to save this page if you are editing this page
+ for the very first time!
+ </note>
+ <aftersaveredirect>pkg_edit.php?xml=p3scan-pf-vir.xml&amp;id=0</aftersaveredirect>
+ <include_file>/usr/local/pkg/p3scan.inc</include_file>
+ <tabs>
+ <tab>
+ <text>Daemon Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Message Processing</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-msg.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Emergency Contact</text>
+ <url>/pkg.php?xml=p3scan-pf-emer.xml</url>
+ </tab>
+ <tab>
+ <text>Virus Scanner Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&amp;id=0</url>
+ <active />
+ </tab>
+ <tab>
+ <text>SPAM Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&amp;id=0</url>
+ </tab>
+ </tabs>
+ <!--
+ configpath gets expanded out automatically and config items
+ will be stored in that location
+ -->
+ <configpath>['installedpackages']['p3scanpf']['config']['virus']</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>Scanner Type</fielddescr>
+ <fieldname>scannertype</fieldname>
+ <description>Select here which type of scanner you want to use.</description>
+ <type>select</type>
+ <size>1</size>
+ <default_value>clamd</default_value>
+ <options>
+ <option><name>Kaspersky Anti-Virus for Linux</name><value>avpd</value></option>
+ <option><name>Kaspersky Anti-Virus for Linux (New)</name><value>avpd_new</value></option>
+ <option><name>Shell Script</name><value>bash</value></option>
+ <option><name>Default Scanner Type</name><value>basic</value></option>
+ <option><name>Clam Anti-Virus</name><value>clamd</value></option>
+ <option><name>Trophie Daemon</name><value>trophie</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Virusscanner</fielddescr>
+ <fieldname>scanner</fieldname>
+ <description>Depends on scannertype.</description>
+ <type>input</type>
+ <required />
+ <default_value>127.0.0.1:3310</default_value>
+ </field>
+ <field>
+ <fielddescr>Scanner Returncode</fielddescr>
+ <fieldname>viruscode</fieldname>
+ <description>
+ Specify the returncode(s) which the scanner returns when
+ the mail is infected.
+ </description>
+ <type>input</type>
+ <default_value>1</default_value>
+ </field>
+ <field>
+ <fielddescr>Good Scanner return codes</fielddescr>
+ <fieldname>goodcode</fieldname>
+ <description>
+ Some scanners can report more than good or infected. Place valid return
+ codes here that will enable the message to be delivered without a warning.
+ </description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Regular Expression for Virusname</fielddescr>
+ <fieldname>virusregexp</fieldname>
+ <description>
+ Specify here a regular expression which describes where the name of
+ the virus can be found.
+ </description>
+ <type>input</type>
+ <default_value>.*: (.*) FOUND</default_value>
+ </field>
+ <field>
+ <fielddescr>deMIME Setting</fielddescr>
+ <fieldname>demime</fieldname>
+ <description>
+ Tick this if we should parse all lt;acronym title=&quot;Multipurpose Internet Mail Extensions&quot;&gt;MIME&lt;/acronym&gt;-sections instead of passing the
+ message as-is to the scanner.
+ </description>
+ <type>checkbox</type>
+ <donotdisable>true</donotdisable>
+ </field>
+ </fields>
+ <!--
+ Arbitrary PHP Code, that gets executed if a certain event gets triggered.
+ -->
+ <custom_php_resync_config_command>
+ sync_package_p3scan();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/config/dspam/pkg/p3scan-pf.xml b/config/dspam/pkg/p3scan-pf.xml
new file mode 100644
index 00000000..f78c3912
--- /dev/null
+++ b/config/dspam/pkg/p3scan-pf.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$ */
+/* ========================================================================== */
+/*
+ authng.xml
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name>
+ 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>p3scanpf</name>
+ <version>1.0</version>
+ <title>Services: POP3 Proxy: Main</title>
+ <note>
+ This &lt;acronym title=&quot;Hypertext Markup Language&quot;&gt;HTML&lt;/acronym&gt; page uses default values, hence even if each field is
+ set, you are still required to save this page if you are editing this page
+ for the very first time!
+ </note>
+ <aftersaveredirect>pkg_edit.php?xml=p3scan-pf.xml&amp;id=0</aftersaveredirect>
+ <include_file>/usr/local/pkg/p3scan.inc</include_file>
+ <!-- Menu is where this packages menu will appear -->
+ <menu>
+ <name>p3scan</name>
+ <tooltiptext>A transparent POP3-Proxy with virus-scanning capabilities</tooltiptext>
+ <section>Services</section>
+ <configfile>p3scan.xml</configfile>
+ </menu>
+ <service>
+ <name>p3scan-pf</name>
+ <rcfile>/usr/local/etc/rc.d/030.p3scan.sh</rcfile>
+ </service>
+ <tabs>
+ <tab>
+ <text>Daemon Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf.xml&amp;id=0</url>
+ <active />
+ </tab>
+ <tab>
+ <text>Message Processing</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-msg.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Emergency Contact</text>
+ <url>/pkg.php?xml=p3scan-pf-emer.xml</url>
+ </tab>
+ <tab>
+ <text>Virus Scanner Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>SPAM Settings</text>
+ <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&amp;id=0</url>
+ </tab>
+ </tabs>
+ <!--
+ configpath gets expanded out automatically and config items
+ will be stored in that location
+ -->
+ <configpath>['installedpackages']['p3scanpf']['config']</configpath>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/p3scan-pf-msg.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/p3scan-pf-emer.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/p3scan-pf-vir.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/p3scan-pf-spam.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/p3scan_rules.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ <item>http://www.pfsense.com/packages/config/p3scan.inc</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>Max Child's</fielddescr>
+ <fieldname>maxchilds</fieldname>
+ <description>The maximum number of connections we will handle at once.</description>
+ <type>input</type>
+ <default_value>10</default_value>
+ </field>
+ <field>
+ <fielddescr>IP Address</fielddescr>
+ <fieldname>ipaddr</fieldname>
+ <description>The &lt;acronym title=&quot;Internet Protocol&quot;&gt;IP&lt;/acronym&gt; Address we listen on.</description>
+ <type>input</type>
+ <required />
+ <default_value>0.0.0.0</default_value>
+ </field>
+ <field>
+ <fielddescr>Port</fielddescr>
+ <fieldname>port</fieldname>
+ <description>The &lt;acronym title=&quot;Transmission Control Protocol&quot;&gt;TCP&lt;/acronym&gt; port on we should listen.</description>
+ <type>input</type>
+ <required />
+ <default_value>8110</default_value>
+ </field>
+ <field>
+ <fielddescr>SSL Port</fielddescr>
+ <fieldname>sslport</fieldname>
+ <description>The TCP &lt;acronym title=&quot;Secure Sockets Layer&quot;&gt;SSL&lt;/acronym&gt; port on we should listen.</description>
+ <type>input</type>
+ <required />
+ <default_value>995</default_value>
+ </field>
+ <field>
+ <fielddescr>Target IP</fielddescr>
+ <fieldname>targetip</fieldname>
+ <description>Target IP is the IP to connect (0.0.0.0 enables transparent mode).</description>
+ <type>input</type>
+ <required />
+ <default_value>0.0.0.0</default_value>
+ </field>
+ <field>
+ <fielddescr>Target Port</fielddescr>
+ <fieldname>targetport</fieldname>
+ <description>Target Port is the port to connect.</description>
+ <type>input</type>
+ <required />
+ <default_value>8110</default_value>
+ </field>
+ <field>
+ <fielddescr>Email Port</fielddescr>
+ <fieldname>emailport</fieldname>
+ <description>The port we should listen on to scan outgoing email messages.</description>
+ <type>input</type>
+ <required />
+ <default_value>25</default_value>
+ </field>
+ <field>
+ <fielddescr>Daemon User</fielddescr>
+ <fieldname>daemonuser</fieldname>
+ <description>The username the daemon should run as.</description>
+ <type>input</type>
+ <required />
+ <default_value>root</default_value>
+ </field>
+ </fields>
+ <!--
+ Arbitrary PHP Code, that gets executed if a certain event gets triggered.
+ -->
+ <custom_delete_php_command>
+ sync_package_p3scan();
+ </custom_delete_php_command>
+ <custom_php_resync_config_command>
+ sync_package_p3scan();
+ </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>
+</packagegui>
diff --git a/config/dspam/pkg/p3scan.inc b/config/dspam/pkg/p3scan.inc
new file mode 100644
index 00000000..7d675050
--- /dev/null
+++ b/config/dspam/pkg/p3scan.inc
@@ -0,0 +1,277 @@
+<?php
+/* $Id$ */
+/* Copyright (C) 2006 Daniel S. Haischt */
+
+/* include all configuration functions */
+require_once("functions.inc");
+
+function sync_package_p3scan() {
+ global $config, $g;
+ conf_mount_rw();
+ config_lock();
+ $fd = fopen("/etc/p3scan.conf","w");
+
+ /* shorten the config path */
+ $cfg = $config['installedpackages']['p3scanpf']['config'][0];
+ $cfgmsg = $config['installedpackages']['p3scanpfmsg']['config'][0];
+ $cfgemer = $config['installedpackages']['p3scanpfemer']['config'];
+ $cfgvir = $config['installedpackages']['p3scanpfvir']['config'][0];
+ $cfgspam = $config['installedpackages']['p3scanpfspam']['config'][0];
+
+ fwrite($fd, "## p3scan-pf config file - generated by pfSense.\n##\n");
+ fwrite($fd, "## at: " . date("l dS of F Y h:i:s A") . "\n##\n");
+ /* ================================================================ */
+ /* == Tab: Daemon Settings == */
+ /* ================================================================ */
+ fwrite($fd, "## Daemon Settings.\n");
+ fwrite($fd, "pidfile = /var/run/p3scan/p3scan.pid\n");
+ if (isset($cfg['maxchilds']) && $cfg['maxchilds'] <> "")
+ fwrite($fd, "maxchilds = {$cfg['maxchilds']}\n");
+ else
+ fwrite($fd, "maxchilds = 10\n");
+ if (isset($cfg['ipaddr']) && $cfg['ipaddr'] <> "")
+ fwrite($fd, "ip = {$cfg['ipaddr']}\n");
+ else
+ fwrite($fd, "ip = 0.0.0.0\n");
+ /* TODO: Even if the port is configurable, it is
+ hardcoded in p3scan.c. This needs to be
+ changed for the sake of flexebility.
+ */
+ if (isset($cfg['port']) && $cfg['port'] <> "")
+ fwrite($fd, "port = {$cfg['port']}\n");
+ else
+ fwrite($fd, "port = 8110\n");
+ if (isset($cfg['sslport']) && $cfg['sslport'] <> "")
+ fwrite($fd, "sslport = {$cfg['sslport']}\n");
+ else
+ fwrite($fd, "sslport = 995\n");
+ if (isset($cfg['targetip']) && $cfg['targetip'] <> "")
+ fwrite($fd, "targetip = {$cfg['targetip']}\n");
+ else
+ fwrite($fd, "targetip = 0.0.0.0\n");
+ if (isset($cfg['targetport']) && $cfg['targetport'] <> "")
+ fwrite($fd, "targetport = {$cfg['targetport']}\n");
+ else
+ fwrite($fd, "targetport = 8110\n");
+ if (isset($cfg['emailport']) && $cfg['emailport'] <> "")
+ fwrite($fd, "emailport = {$cfg['emailport']}\n");
+ else
+ fwrite($fd, "emailport = 25\n");
+ if (isset($cfg['daemonuser']) && $cfg['daemonuser'] <> "")
+ fwrite($fd, "user = {$cfg['daemonuser']}\n");
+ else
+ fwrite($fd, "user = root\n");
+ fwrite($fd, "notifydir = /var/spool/p3scan/notify\n");
+ fwrite($fd, "virusdir = /var/spool/p3scan\n");
+ fwrite($fd, "template = /usr/local/etc/p3scan/p3scan.mail\n");
+
+ /* ================================================================ */
+ /* == Tab: Message Processing == */
+ /* ================================================================ */
+ fwrite($fd, "## Message Processing Settings.\n");
+ if (isset($cfgmsg['justdelete']) && $cfgmsg['justdelete'] <> "")
+ fwrite($fd, "justdelete\n");
+ if (isset($cfgmsg['bytesfree']) && $cfgmsg['bytesfree'] <> "")
+ fwrite($fd, "bytesfree = {$cfgmsg['bytesfree']}\n");
+ else
+ fwrite($fd, "bytesfree = 10000\n");
+ if (isset($cfgmsg['broken']) && $cfgmsg['broken'] <> "")
+ fwrite($fd, "broken\n");
+ if (isset($cfgmsg['timeout']) && $cfgmsg['timeout'] <> "")
+ fwrite($fd, "timeout = {$cfgmsg['timeout']}\n");
+ else
+ fwrite($fd, "timeout = 30\n");
+ if (isset($cfgmsg['ispspam']) && $cfgmsg['ispspam'] <> "")
+ fwrite($fd, "ispspam = {$cfg['ispspam']}\n");
+ if (file_exists("/usr/local/bin/renattach"))
+ fwrite($fd, "renattach = /usr/local/bin/renattach\n");
+ if (isset($cfgmsg['subject']) && $cfgmsg['subject'] <> "")
+ fwrite($fd, "subject = {$cfgmsg['subject']}\n");
+ else
+ fwrite($fd, "subject = Subject: \"[Virus] found in a mail to you:\" <virus name>\n");
+ if (isset($cfgmsg['notify']) && $cfgmsg['notify'] <> "")
+ fwrite($fd, "notify = {$cfgmsg['notify']}\n");
+ else
+ fwrite($fd, "notify = Per instruction, the message has been deleted.\n");
+ if (isset($cfgmsg['smtpreject']) && $cfgmsg['smtpreject'] <> "")
+ fwrite($fd, "smtprset = {$cfgmsg['smtpreject']}\n");
+ else
+ fwrite($fd, "smtprset = Virus detected! P3scan rejected message!\n");
+ if (isset($cfgmsg['checksize']) && $cfgmsg['checksize'] <> "")
+ fwrite($fd, "checksize = {$cfgmsg['checksize']}\n");
+ if (isset($cfgmsg['footer']) && $cfgmsg['footer'] <> "")
+ fwrite($fd, "footer = {$cfgmsg['footer']}\n");
+
+ /* ================================================================ */
+ /* == Tab: Emergency Contact == */
+ /* ================================================================ */
+ fwrite($fd, "## Emergency Contacts.\n");
+ if (is_array($cfgemer)) {
+ foreach ($cfgemer as $addr) {
+ $contact .= "{$addr['emailaddress']} ";
+ }
+ if (isset($contact) && $contact <> "")
+ fwrite($fd, "emergcon = {$contact}\n");
+ }
+
+ /* ================================================================ */
+ /* == Tab: Virus Scanner Settings == */
+ /* ================================================================ */
+ fwrite($fd, "## Virus Scanner Settings.\n");
+ if (isset($cfgvir['scannertype']) && $cfgvir['scannertype'] <> "")
+ fwrite($fd, "scannertype = {$cfgvir['scannertype']}\n");
+ else
+ fwrite($fd, "scannertype = clamd\n");
+ if (isset($cfgvir['scanner']) && $cfgvir['scanner'] <> "")
+ fwrite($fd, "scanner = {$cfgvir['scanner']}\n");
+ else
+ fwrite($fd, "scanner = 127.0.0.1:3310\n");
+ if (isset($cfgvir['viruscode']) && $cfgvir['viruscode'] <> "")
+ fwrite($fd, "viruscode = {$cfgvir['viruscode']}\n");
+ else
+ fwrite($fd, "viruscode = 1\n");
+ if (isset($cfgvir['goodcode']) && $cfgvir['goodcode'] <> "")
+ fwrite($fd, "goodcode = {$cfgvir['goodcode']}\n");
+ if (isset($cfgvir['virusregexp']) && $cfgvir['virusregexp'] <> "")
+ fwrite($fd, "virusregexp = {$cfgvir['virusregexp']}\n");
+ if (isset($cfgvir['demime']) && $cfgvir['demime'] <> "")
+ fwrite($fd, "demime\n");
+
+ /* ================================================================ */
+ /* == Tab: SPAM Settings == */
+ /* ================================================================ */
+ if (isset($cfgspam['checkspam']) && $cfgpam['checkspam'] <> "") {
+ fwrite($fd, "## SPAM Settings.\n");
+ fwrite($fd, "checkspam\n");
+ if (isset($cfgvir['spamcheck']) && $cfgvir['spamcheck'] <> "")
+ fwrite($fd, "spamcheck = {$cfgspam['spamcheck']}\n");
+ else
+ fwrite($fd, "spamcheck = /usr/local/bin/dspam --user dspamuser --mode=teft --stdout --deliver=innocent,spam --feature=ch,no,wh\n");
+ }
+
+ fclose($fd);
+
+ /* NOTE: The following code requires the p3scan.inc file to be saved with
+ UNIX Linefeeds. LF that is and NOT CR LF.
+ */
+ $start = <<<EOD
+test_p3scan_user=`cat /etc/passwd | grep p3scan`
+test_p3scan_group=`cat /etc/passwd | grep p3scan`
+
+if [ -z "\${test_p3scan_group}" ]; then
+ pw groupadd p3scan -g 108
+fi
+
+if [ -z "\${test_p3scan_user}" ]; then
+ pw useradd p3scan -u 108 -g p3scan -d /var/spool/p3scan -s /sbin/nologin -c 'P3Scan Daemon'
+fi
+
+if [ ! -d "/var/spool/p3scan" ]; then
+ mkdir /var/spool/p3scan && chown p3scan:p3scan /var/spool/p3scan
+fi
+
+if [ ! -d "/var/spool/p3scan/children" ]; then
+ mkdir /var/spool/p3scan/children && chown p3scan:p3scan /var/spool/p3scan/children
+fi
+
+if [ ! -d "/var/spool/p3scannotify" ]; then
+ mkdir /var/spool/p3scannotify && chown p3scan:p3scan /var/spool/p3scannotify
+fi
+
+if [ ! -d "/var/run/p3scan" ]; then
+ mkdir /var/run/p3scan && chown p3scan:p3scan /var/run/p3scan
+fi
+
+/sbin/mount_fdescfs fdescfs /dev/fd
+/usr/local/sbin/p3scan --configfile=/usr/local/etc/p3scan/p3scan.conf &
+
+EOD;
+
+ $stop = "/usr/bin/killall p3scan\n" .
+ "sleep 2";
+
+ write_rcfile(array(
+ "file" => "030.p3scan.sh",
+ "start" => $start,
+ "stop" => $stop
+ )
+ );
+
+ conf_mount_ro();
+ config_unlock();
+
+ if (! file_exists("/usr/local/etc/p3scan")) {
+ mkdir("/usr/local/etc/p3scan");
+ }
+ if (! file_exists("/usr/local/etc/p3scan/p3scan.conf")) {
+ mwexec("ln -s /etc/p3scan.conf /usr/local/etc/p3scan/p3scan.conf");
+ }
+ if (! file_exists("/usr/local/etc/p3scan/p3scan.mail")) {
+ $fd = fopen("/usr/local/etc/p3scan/p3scan.mail","w");
+
+ $p3scanmail = <<<EOD
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+Content-Type: text/plain;
+ charset="iso-8859-1"
+
+Hello %USERNAME%.
+This message body was generated automatically from P3Scan, which runs on
+%HOSTNAME%.%DOMAINNAME% for scanning all incoming email.
+
+It replaces the body of a message sent to you that contained a VIRUS!
+
+Instead of the infected email this message has been sent to you.
+
+You may look at the message header of this message for the complete
+email header information of the infected message.
+
+Virus name:
+ %VIRUSNAME%
+(Supposed) Sender of the email:
+ %MAILFROM%
+Sent To:
+ %MAILTO%
+On Date:
+ %MAILDATE%
+Subject:
+ %SUBJECT%
+Connection data:
+ %PROTOCOL% from %CLIENTIP%:%CLIENTPORT% to %SERVERIP%:%SERVERPORT%
+Message File:
+ %P3SCANID%
+Virus Definition Info:
+ %VDINFO%
+--
+%PROGNAME% %VERSION%
+by Jack S. Lai <laitcg@cox.net>
+
+EOD;
+
+ fwrite($fd, $p3scanmail);
+ fclose($fd);
+ }
+
+ mwexec("/usr/local/etc/rc.d/030.p3scan.sh stop");
+ mwexec("/usr/local/etc/rc.d/030.p3scan.sh start");
+
+ return 0;
+}
+
+function custom_php_install_command() {
+ global $config, $g;
+ sync_package_p3scan();
+}
+
+function custom_php_deinstall_command() {
+ global $config, $g;
+ conf_mount_rw();
+ unlink_if_exists("/usr/local/pkg/pf/p3scan_rules.php");
+ unlink_if_exists("/usr/local/www/p3scan_rules.php");
+ unlink_if_exists("/usr/local/etc/p3scan/p3scan.conf");
+ unlink_if_exists("/usr/local/etc/p3scan/p3scan.mail");
+ unlink_if_exists("/usr/local/etc/rc.d/030.p3scan.sh");
+ rmdir("/usr/local/etc/p3scan");
+ conf_mount_ro();
+}
+?> \ No newline at end of file
diff --git a/config/dspam/pkg/verdana.ttf b/config/dspam/pkg/verdana.ttf
new file mode 100644
index 00000000..754a9b7b
--- /dev/null
+++ b/config/dspam/pkg/verdana.ttf
Binary files differ