- 設定 MailScanner 取用 Whitelist / Blacklist Rules File
- 設定 /etc/sudoers, 讓 PHP 程式可執行 /etc/init.d/MailScanner reload
- 透過 PHP 網頁維護黑白名單
- 避免使用者回上頁、重新整理網頁造成資料錯亂
- 以 md5 函數檢查檔案是否遭到其他使用者異動
- 以 exec 函數執行 sudo /etc/init.d/MailScanner reload
環境: CentOS 5, Apache HTTP Server 2.2.3, PHP 5.1.6, MailScanner 4.71.10
cd /etc/MailScanner
vi MailScanner.conf
%rules-dir% = /etc/MailScanner/rules
Is Definitely Not Spam = %rules-dir%/spam.whitelist.rules
Is Definitely Spam = %rules-dir%/spam.blacklist.rules
touch rules/spam.blacklist.rules
chown :apache rules/spam.*list.rules
chmod 664 rules/spam.*list.rules
visudo
#Defaults requiretty
apache ALL = NOPASSWD : /etc/init.d/MailScanner
vi /var/www/html/wbmaintainer.php
<?php
if (!headers_sent()) {
session_start();
header('Cache-Control: private');
}
function fn_chkdef($str) {
$str = strtolower($str);
$str = ereg_replace("[' '|\t]","",$str);
if ($str == "fromorto:defaultno") {
return false;
} else {
return true;
}
}
$default = "FromOrTo: default no\n";
$mode = $_POST['mode'];
if ($mode == "" && isset($_COOKIE['wbmaintainer_mode'])) {
$mode = $_COOKIE['wbmaintainer_mode'];
}
if ($mode == "" || $mode == "form") {
$mode = "form";
$defaultobj = "email";
$changemodebtn = "Change to Advanced Mode";
setcookie("wbmaintainer_mode","form",time()+2592000);
} else {
$mode = "text";
$defaultobj = "textpad";
$changemodebtn = "Change to Easy Mode";
setcookie("wbmaintainer_mode","text",time()+2592000);
}
if ($_POST['dochangemode'] > "") {
$_POST['cb'] = "";
$_POST['email'] = "";
$_POST['textpad'] = "";
}
?>
<html>
<head>
<title>Whitelist / Blacklist Maintainer for MailScanner</title>
<meta name="Author" content="Jamyy Chang, http://cha.homeip.net/blog/">
<script language="JavaScript">
setTimeout("fn_forward()",1);
function fn_forward() {
history.forward();
setTimeout("fn_forward()",1);
}
function fn_reloadms() {
document.forms[0].reloadms.value = "yes";
document.forms[0].submit();
}
function fn_changemode(mode) {
objform = document.forms[0];
if (mode == "form") {
objform.mode.value = "text";
} else {
objform.mode.value = "form";
}
objform.dochangemode.value = "yes";
objform.submit();
}
//ref: http://l4x.org/261/
function insertTab(event,obj) {
var tabKeyCode = 9;
if (event.which) // mozilla
var keycode = event.which;
else // ie
var keycode = event.keyCode;
if (keycode == tabKeyCode) {
if (event.type == "keydown") {
if (obj.setSelectionRange) {
// mozilla
var s = obj.selectionStart;
var e = obj.selectionEnd;
obj.value = obj.value.substring(0, s) +
"\t" + obj.value.substr(e);
obj.setSelectionRange(s + 1, s + 1);
obj.focus();
} else if (obj.createTextRange) {
// ie
document.selection.createRange().text="\t"
obj.onblur = function() { this.focus(); this.onblur = null; };
} else {
// unsupported browsers
}
}
if (event.returnValue) // ie ?
event.returnValue = false;
if (event.preventDefault) // dom
event.preventDefault();
return false; // should work in all browsers
}
return true;
}
</script>
</head>
<body onload="history.go(1);fn_forward();document.forms[0].<?php echo $defaultobj;?>.focus()">
<form name="<?php echo $_SERVER['SCRIPT_NAME'];?>" method="POST">
<?php
if (isset($_POST['action'])) {
$strAction = $_POST['action'];
} else {
$strAction = "";
$_SESSION['action'] = "";
}
if ($_SESSION['action'] > "" && $_SESSION['action'] == $strAction) {
//Do NOT Do Refresh!
$_POST['cb'] = "";
$_POST['email'] = "";
$_POST['textpad'] = "";
} else {
if ($strAction > "") {
$_SESSION['action'] = $strAction;
}
}
$filetype = ""; //whitelist or blacklist
$whitedefault = ""; //for OPTION html tag
$blackdefault = ""; //for OPTION html tag
if ($_POST['filetype'] == "") {
$filetype = "whitelist";
$whitedefault = " selected";
} else {
$filetype = $_POST['filetype'];
if ($filetype == "whitelist") {
$whitedefault = " selected";
} else {
$blackdefault = " selected";
}
}
echo "<select name='filetype' onchange='this.form.submit()'>
<option value='whitelist'$whitedefault>Whitelist</option>
<option value='blacklist'$blackdefault>Blacklist</option>
</select>
<input type='button' value='$changemodebtn' onclick='fn_changemode(\"$mode\")'>";
$filename = "/etc/MailScanner/rules/spam.$filetype.rules";
if ($_POST['oldtype'] == $filetype) {
$md5sum = md5(file_get_contents($filename));
$filematch = true;
if ($_POST['md5sum'] > "" && $_POST['md5sum'] != $md5sum) {
$filematch = false;
echo "<p><font color='red'>WARNING: File has been changed by other user! Reloading...</font></p>";
}
}
$datachanged = false;
if ($filematch) {
if ($_POST['textpad'] > "") {
$f = fopen($filename,"w");
fwrite($f,$_POST['textpad']);
fclose($f);
$datachanged = true;
}
if ($_POST['cb'] > "") {
//Delete Data
$f = fopen($filename,"w");
$dt = $_POST['dt'];
while(list($key1,$val1) = @each($dt)) {
$flag = true;
$cb = $_POST['cb'];
if (fn_chkdef($val1)) {
while(list($key2,$val2) = @each($cb)) {
if (trim($val1) == trim($val2)) {
$flag = false;
break;
}
}
if ($flag && trim($val1) > "") {
fwrite($f,trim($val1)."\n");
}
} //endif fn_chkdef($val1)
}
if ($_POST['email'] > "") {
fwrite($f,"From: " . $_POST['email'] . " yes\n");
$_POST['email'] = "";
}
fwrite($f,$default);
fclose($f);
$datachanged = true;
} //endif $_POST['cb'] > ""
if ($_POST['email'] > "") {
//Append Data
$f = fopen($filename,"w");
$dt = $_POST['dt'];
while(list($key,$val) = @each($dt)) {
if (fn_chkdef($val) && trim($val) > "") {
fwrite($f,trim($val)."\n");
}
}
fwrite($f,"From: " . $_POST['email'] . " yes\n");
fwrite($f,$default);
fclose($f);
$datachanged = true;
} //endif $_POST['email'] > ""
} else {
$email = $_POST['email'];
} //endif $filematch
if ($datachanged) {
echo "<p><font color='blue'>Data has been modified at ". date("Y-m-d H:i:s") . "</font></p>";
}
if ($_POST['reloadms'] == "yes") {
exec("sudo /etc/init.d/MailScanner reload");
echo "<p><font color='red'>MailScanner has been reloaded at ". date("Y-m-d H:i:s") . "</font></p>";
}
$f = fopen($filename,"r");
$md5sum = md5(file_get_contents($filename));
if ($mode == "form") {
echo "<table>\n";
while (!feof($f)) {
$line = fgets($f);
if (fn_chkdef(trim($line))) {
$data = "<input type='hidden' name='dt[]' value='$line'>";
if (substr($line,0,1) == "#" || $line == "") {
$chkbox = "";
} else {
$chkbox = "<input type='checkbox' name='cb[]' value='$line'>";
}
echo "<tr><td>" . $chkbox . $line . $data . "</td></tr>\n";
} //endif fn_chkdef($line)
}
echo "</table>\n";
?>
From: <input type="text" size="20" name="email" value="<?php echo $email;?>">
<? } else {
$fr = file_get_contents($filename);
echo "<p><textarea cols='60' rows='20' name='textpad' onkeydown='return insertTab(event,this)' onkeyup='return insertTab(event,this)' onkeypress='return insertTab(event,this)'>$fr</textarea></p>";
} //endif $mode == "form"
fclose($f);
?>
<input type="hidden" name="action" value="<?php echo Time();?>">
<input type="hidden" name="md5sum" value="<?php echo $md5sum;?>">
<input type="hidden" name="oldtype" value="<?php echo $filetype;?>">
<input type="hidden" name="reloadms" value="no">
<input type="hidden" name="mode" value="<?php echo $mode;?>">
<input type="hidden" name="dochangemode" value="">
<input type="submit" value="Submit">
<input type="button" value="Submit and Reload MailScanner" onclick="fn_reloadms()">
</form>
</body>
</html>
畫面說明: