From 3eab27426aa39497d87a9fb768fd860f924e10be Mon Sep 17 00:00:00 2001 From: Daniel Stefan Haischt Date: Sat, 15 Jul 2006 22:16:04 +0000 Subject: - initial version of the DSPAM package --- packages/dspam/pkg/dspam.inc | 3916 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3916 insertions(+) create mode 100644 packages/dspam/pkg/dspam.inc (limited to 'packages/dspam/pkg/dspam.inc') diff --git a/packages/dspam/pkg/dspam.inc b/packages/dspam/pkg/dspam.inc new file mode 100644 index 00000000..e2cdad40 --- /dev/null +++ b/packages/dspam/pkg/dspam.inc @@ -0,0 +1,3916 @@ + '/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, + /* 'DATE_FORMAT' => '%d.%m.%Y %H:%M' */ + 'DATE_FORMAT' => '%b %d %H:%M' + ); + +/* + * 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 + + + Unauthorized Access + + + +

Unauthorized Access - You will be redirected shortly!

+ + +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 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'] .= "{$username}" . + " {$mailbox_display}" . + " {$sl}" . + " {$il}" . + " {$fp}" . + " {$sm}" . + " {$sc}" . + " {$ic}" . + " {$PREFS['trainingMode']}" . + " {$PREFS['spamAction']}" . + " {$PREFS['enableBNR']}" . + " {$PREFS['enableWhitelist']}" . + " {$PREFS['statisticalSedation']}" . + " {$PREFS['signatureLocation']}" . + "\n"; + } + pclose($pd); + + $mailbox_total_display = sprintf("%2.1f KB", ($mailbox_total / 1024)); + + $b = "listhdrr"; + $DATA['TABLE'] .= "Total". + " {$mailbox_total_display}". + " {$sl_total}". + " {$il_total}". + " {$sm_total}". + " {$fp_total}". + " {$sc_total}". + " {$ic_total}". + "  ". + "  ". + "  ". + "  ". + "  ". + "  ". + "\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)"; + } + + 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 (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", "'>'", $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 , 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 == "") { $from = $rec[$messageid]['from']; } + if ($subject == "") { $subject = $rec[$messageid]['subject']; } + + + if ($rec[$messageid]['from'] == "") { $rec[$messageid]['from'] = $from; } + if ($rec[$messageid]['subject'] == "") { $rec[$messageid]['subject'] = $subject; } + } + + if ($from == "") { $from = ""; } + if ($subject == "") { $subject = ""; } + + $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", "'>'", $from); + $subject = preg_replace('//e', "'>'", $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 = "Retrained"; + } + + if ($retrain == "") { + $retrain = "As " . ucfirst($rclass) . ""; + } else { + $retrain .= "(Undo)"; + } + + $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 = "{$from}"; + } + + $entry = << + {$cllabel} + + + + + + + {$ctime} + {$from} + {$subject} + {$info} + + +EOD; + + $retrain_checked_msg_no++; + array_push($history, $entry); + + if ($rowclass == "qrowEven") { + $rowclass = "qrowOdd"; + } else { + $rowclass = "qrowEven"; + } + $hurtz++; + } // end while + + $entry = << + +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; + + $historyFooterEnd = <<>  + >| + + + +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 .= "{$i} \n"; + } else { + $historyFooter .= "{$i} \n"; + } + } + } + } + } + + $DATA['HISTORY_FOOTER'] = $historyFooterBegin . $historyFooter .$historyFooterEnd; + $DATA['HPAGES'] = $pages; + $DATA['HPAGE'] = $currentPage; + +/* + $DATA['HISTORY'] .= "
["; + if (($history_pages > 1) && ($history_page > 1)) { + $i = $history_page - 1; + $DATA['HISTORY'] .= " < "; + } + for($i = 1; $i <= $history_pages; $i++) { + if ($i == $history_page) { + $DATA['HISTORY'] .= " $i "; + } else { + $DATA['HISTORY'] .= " {$i} "; + } + } + if (($history_pages > 1) && ($history_page < $history_pages)) { + $i = $history_page + 1; + $DATA['HISTORY'] .= " > "; + } + $DATA['HISTORY'] .= "]
"; +*/ + } // 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 = << 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 ProcessFalsePositive."; + } + } + } + + /* 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 'An error occured while parsing the message (no message).'; + } + if ($sigID == "") { + return 'An error occured while parsing the message (no signature).'; + } + + 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 = << + Message Infos + + + Date: + %MSGDATE% + + + From: + %MSGFROM% + + + Subject: + %MSGSUB% + + + To: + %MSGTO% + + +   + + + Message Part + Part Type + Part Encoding + + + +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 .= "" . + "{$st}" . + "\n"; + } else { + $htmlstr .= "" . + "{$st}" . + "\n"; + } + + $htmlstr .= <<{$info["content-type"]} + {$info["charset"]} + + +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 .= << +   + + + Section {$showpart} + + + +EOD; + + ob_start(); + mailparse_msg_extract_part($sec, $msgbuffer); + $contents = ob_get_contents(); + ob_end_clean(); + $contents = wordwrap( str_replace(">", ">\n", $contents), 100, "\n" ); + /* quote the message for safe display in a browser */ + if ($ctype = 1) { + /* a html email message */ + $htmlstr .= "
" . $contents . "
\n\n"; + } else { + /* an ASCII (text) email message */ + $htmlstr .= htmlentities($contents) . "\n\n"; + } + } + + return $htmlstr; + } else { + return 'Could not load mailparse extension.'; + } +} + +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", "'>'", $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'] = ""; + } + + //$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('//', '/\>\;/', $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); + } + + /* + + +   + Rating + Date + From + Subject + + + */ + + $DATA['SORTBY'] = $sortBy; + $DATA['SORT_SELECTOR'] .= << +   + +EOD; + + if ($sortBy == "Rating") { + $DATA{'SORT_SELECTOR'} .= "Rating  ◊"; + } else { + $DATA{'SORT_SELECTOR'} .= "Rating"; + } + if ($sortBy == "Date") { + $DATA{'SORT_SELECTOR'} .= "Date  ◊"; + } else { + $DATA{'SORT_SELECTOR'} .= "Date"; + } + if ($sortBy == "Subject") { + $DATA{'SORT_SELECTOR'} .= "Subject  ◊"; + } else { + $DATA{'SORT_SELECTOR'} .= "Subject"; + } + if ($sortBy == "From") { + $DATA{'SORT_SELECTOR'} .= "From  ◊"; + } else { + $DATA{'SORT_SELECTOR'} .= "From"; + } + + $DATA{'SORT_SELECTOR'} .= "\n "; + + 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}"; + } + + /* + + + + + + + 50% + + Apr 1 05:59a + Mar 30 11:08a + + Last chance to register for Frankfurt, 4 April BEA... + + + + + + + + + {$rating} + + {$ptime} + {$row['From']} + + {$row['Subject']} + + + */ + + $DATA['QUARANTINE'] .= << + + + + + {$rating} + + {$ptime} + {$sender} + + {$rsubject} + + + +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; + + $quarantineFooterEnd = <<>  + >| + + + +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 .= "{$i} \n"; + } else { + $quarantineFooter .= "{$i} \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; +} + +/* ========================================================================== */ +/* = G L O B A L F U N C T I O N S = */ +/* ========================================================================== */ + +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; +} + +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 "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 = << 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 .= << "") { + $dspamconf .= << "") { + $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(); +} +?> \ No newline at end of file -- cgit v1.2.3