diff -ruN /tmp/spamplemousse/inc/tb.php spamplemousse/inc/tb.php
--- /tmp/spamplemousse/inc/tb.php 2005-12-27 22:01:30.000000000 +0100
+++ spamplemousse/inc/tb.php 2006-03-13 22:34:33.000000000 +0100
@@ -21,6 +21,9 @@
* ***** END LICENSE BLOCK *****
*/
+define(SUSPICIOUS_SCORE, 0);
+define(SPAM_SCORE, 8.0);
+
# on regarde si le plugin est activé
$desc = implode('', file(dirname(__FILE__).'/../desc.xml'));
if (strpos($desc, 'active="true"') || strpos($desc, 'active="1"')) {
@@ -37,7 +40,19 @@
# on teste si le trackback est du spam,
# si ce n'est pas le cas on rend la main au script initial
$spam = spamfilter::is_spam($blog_name, '', $url, $ip, $comment);
- if ($spam !== false) {
+
+ $message='';
+ if ($spam > SPAM_SCORE) {
+ $err = $blog->error(0);
+ $content =
+ '1'."\n".
+ 'Sorry no spam allowed. Listed in many RBLs our SURBLs ? Matching my adult/casino/pharmacy buzzwords ?';
+ $con->close();
+ echo $content."\n";
+ echo '';
+ exit;
+ }
+ elseif( (is_numeric($spam) && ($spam > SUSPICIOUS_SCORE) ) or (!is_numeric($spam) && ($spam !== false))) {
$moderation = new moderation($blog);
$id = $moderation->addComment($id, $blog_name, '', $url, $comment, true, dc_time_delta, dc_comments_pub, $spam, $ip);
if ($id !== false) {
diff -ruN /tmp/spamplemousse/l10n/fr/main.lang spamplemousse/l10n/fr/main.lang
--- /tmp/spamplemousse/l10n/fr/main.lang 2005-12-27 21:08:33.000000000 +0100
+++ spamplemousse/l10n/fr/main.lang 2006-03-10 22:17:07.000000000 +0100
@@ -58,3 +58,5 @@
;By
Par
+;Sorry, your messsage is a spam. I don't accept spam. Go away !
+Tu envoyes du spam ? Désolé, je n'accepte pas le spam.
diff -ruN /tmp/spamplemousse/l10n/fr-utf8/main.lang spamplemousse/l10n/fr-utf8/main.lang
--- /tmp/spamplemousse/l10n/fr-utf8/main.lang 2005-12-27 22:39:45.000000000 +0100
+++ spamplemousse/l10n/fr-utf8/main.lang 2006-03-10 22:17:38.000000000 +0100
@@ -58,3 +58,6 @@
;By
Par
+;Sorry, your messsage is a spam. I don't accept spam. Go away !
+Tu envoyes du spam ? Désolé, je n'accepte pas le spam.
+
diff -ruN /tmp/spamplemousse/lib/class.spamfilter.php spamplemousse/lib/class.spamfilter.php
--- /tmp/spamplemousse/lib/class.spamfilter.php 2005-12-26 17:31:54.000000000 +0100
+++ spamplemousse/lib/class.spamfilter.php 2006-03-13 23:17:25.000000000 +0100
@@ -22,6 +22,7 @@
*/
require_once dirname(__FILE__).'/rbl.php';
+require_once dirname(__FILE__).'/surbl.php';
/**
@class spamfilter
@@ -92,18 +93,25 @@
function chk_spamwords($str)
{
global $con;
+ $words_score = 0;
# récupération de la liste de mots spam
+ # TODO : donner un poids aux mots-spams (y compris négatif).
$req = 'SELECT * FROM '.DB_PREFIX.'spamwords';
$res = $con->select($req);
- # on compare les chaines en minuscules (strpos est sensible à la casse)
+ # on compare les chaines en minuscules (substr_count est sensible à la casse)
+ # TODO : recherche de mots-clefs spams via une regex ?
$str = strtolower($str);
while ($res->fetch()) {
- if (strpos($str, $res->f('spamwords_word'), 0) !== false)
- return true;
+ $occ = substr_count($str, $res->f('spamwords_word'));
+ if($occ) {
+ # TODO formule expérimentale
+ #echo $res->f('spamwords_word') . " $occ $words_score
";
+ $words_score += min(pow(1.2, $occ), 3);
+ }
}
- return false;
+ return $words_score;
}
/**
@@ -139,22 +147,35 @@
@param string authorURL url du site de l'auteur
@param string authorIP ip de l'auteur
@param string content contenu du commentaire
- @return mixed id du filtre qui a répondu positivement, ou false si ce n'est pas du spam
+ return integer score du message (0 neutre ; > 0 douteux ; < 0 a priori clean)
+
+ TODO : donner une réponse contenant les filtres qui nous ont heurtés ?
+ (simuler ancien fonctionnement)
*/
function is_spam($author, $authorMail, $authorURL, $authorIP, $content)
{
-
-//*
- # test de l'ip sur les rbl
- if (rbl_lookup($authorIP) != '')
- return 'RBL';
-//*/
+ $score = 0;
+
+ # Multiplie le nombre de RBL où la chose est listée par 3
+ $score += rbl_lookup($authorIP) * 3;
- # test de la présence de mots spam
- if (spamfilter::chk_spamwords($author.' '.$authorMail.' '.$authorURL.' '.$content))
- return 'spamword';
+ # score mots-clefs
+ $score += spamfilter::chk_spamwords($author.' '.$authorMail.' '.$authorURL.' '.$content) ;
- return false;
+ # Formate si nécessaire l'URL de trackback/auteur
+ if(!preg_match("/^http:\/\//i", $authorURL))
+ $authorURL = 'http://' . $authorURL;
+
+ # score des SURBLS
+ $score += surbl_lookup($content, $ur_1) * 3;
+ $score += surbl_lookup($authorURL, $ur_2) * 5.01;
+ # (une RBL + URL de trackback en SURBL -> SPAM)
+
+ # Pas d'URL ? Dans ce cas, difficile de faire un spam
+ if( ($ur_1 + $ur_2)==0)
+ $score -= 1000;
+
+ return $score;
}
}
diff -ruN /tmp/spamplemousse/lib/rbl.php spamplemousse/lib/rbl.php
--- /tmp/spamplemousse/lib/rbl.php 2005-12-27 20:27:27.000000000 +0100
+++ spamplemousse/lib/rbl.php 2006-03-11 00:06:09.000000000 +0100
@@ -14,29 +14,46 @@
/*
rbl list:
an array of RBLs to look in
+
+ TODO Spamplemousse :
+ 1. rendre cette liste configurable dans l'interface d'admin
+ 2. permettre de donner un poids aux RBL (celui-ci pouvant être, pourquoi pas, négatif)
+
+ Une liste de RBLs se trouve par ici : http://www.moensted.dk/spam/
*/
$rbls = array(
'bl.blbl.org', // blacklist de spam de commentaires
'bl.spamcop.net', // blacklist de spam de mails
//'sbl.spamhaus.org', // blacklist de spam de mails (compris dans sbl-xbl.spamhaus.org)
//'opm.blitzed.org', // blacklist d'open proxies (compris dans sbl-xbl.spamhaus.org)
- 'sbl-xbl.spamhaus.org' // blacklist généraliste : spam, open proxies, exploits
+ 'sbl-xbl.spamhaus.org', // blacklist généraliste : spam, open proxies, exploits
+
+ // Par pays (oui, c'est raciste & chauvin. De tte façon avec des commentaires
+ // en Français, vous vous attendiez à quoi ?)
+ 'cn.countries.nerd.dk', // Chine
+ 'brazil.blackholes.us',
+ 'argentina.blackholes.us',
+ 'korea.blackholes.us',
+ 'russia.blackholes.us',
+
+ 'sagonet.blackholes.us' // ISP de merde qui m'a que trop cassé les c*uilles
);
//this function does the actual lookup; it's here so it can be called externally
function rbl_lookup($ip) {
global $rbls;
+ $rbl_score=0;
if (preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/', $ip, $matches)) {
foreach ($rbls as $rbl) {
$rblhost = $matches[4] . '.' . $matches[3] . '.' . $matches[2] . '.' . $matches[1] . '.' . $rbl.'.';
$resolved = gethostbyname($rblhost);
if ($resolved != $rblhost) {
- return $rbl;
+ $rbl_score++;
}
}
}
- return '';
+ return $rbl_score;
}
diff -ruN /tmp/spamplemousse/lib/surbl.php spamplemousse/lib/surbl.php
--- /tmp/spamplemousse/lib/surbl.php 1970-01-01 01:00:00.000000000 +0100
+++ spamplemousse/lib/surbl.php 2006-03-13 22:44:29.000000000 +0100
@@ -0,0 +1,77 @@
+ http://pear.php.net/package/Net_DNSBL
+ */
+
+$surbls = array('multi.surbl.org');
+
+//this function does the actual lookup; it's here so it can be called externally
+function surbl_lookup($text, &$tested) {
+
+ global $surbls;
+ $surbl_score=0;
+ $tested = 0;
+
+ $regex_url_1 = "/(?:ftp:\/\/|http:\/\/|https:\/\/)(?:www.)?([^'\/\"<\s]*)/im";
+ preg_match_all($regex_url_1, $text, $regex_array_1);
+
+ $regex_url_2 = "/(www.)([^'\/\"<\s]*)/im";
+ preg_match_all($regex_url_2, $text, $regex_array_2);
+
+ $uri_array = array_unique(array_merge($regex_array_1[1], $regex_array_2[2]));
+
+ // Nous disposons maintenant de l'intégrale du texte donné en entrée, on va donc pouvoir lancer
+ // le check.
+
+ foreach ($uri_array as $vhost ) {
+ $virtual_host = rtrim($vhost,"\\");
+
+ // Présence d'une IP numérique ?
+ if (preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/', $virtual_host, $matches)) {
+ $domain_to_test = $matches[4] . '.' . $matches[3] . '.' . $matches[2] . '.' . $matches[1];
+ }
+ else {
+ // Sinon, choper le vhost
+ $split_array = preg_split('/\./', $virtual_host);
+ $dot_array = array_reverse($split_array);
+
+ // Pas de la regex de pédé... et pourtant ça reste approximatif
+ // on devrait checker par rapport à ça : http://spamcheck.freeapp.net/two-level-tlds
+ // mais bon
+ $double_TLD = "/([-_a-z0-9]+\.((ac|gov|org|co|com|edu|mil|biz|net)\.[a-z]{2,3}|web\.pk|(a|pp|m)\.se|(sc|go|ne)\.ug|(info|pro|name)\.tt|(ltd\.co|plc\.co|nic)\.im|[a-z]{2}\.us|(or|fi|ed|go|sa)\.cr|gouv\.fr|ath\.cx|fr\.st|[a-z]{2}\.ça|(gr|ne|or)\.jp))$/i";
+
+ if(preg_match($double_TLD, $virtual_host))
+ $domain_to_test = $dot_array[2] .'.'. $dot_array[1] .'.'. $dot_array[0];
+ else
+ $domain_to_test = $dot_array[1] .'.'. $dot_array[0];
+ }
+
+ // Le check propremeent dit.
+ if (strlen($domain_to_test) > 3) {
+ $tested++;
+ foreach ($surbls as $surbl) {
+ $dnsreq = $domain_to_test . '.' . $surbl;
+ $resolv = gethostbyname($dnsreq);
+ if( $resolv != $dnsreq ) {
+ $surbl_score++;
+ }
+ }
+ }
+ }
+
+ // URL testés : $tested
+ return $surbl_score;
+}
+
+
+?>
diff -ruN /tmp/spamplemousse/postcon.php spamplemousse/postcon.php
--- /tmp/spamplemousse/postcon.php 2005-12-27 22:01:45.000000000 +0100
+++ spamplemousse/postcon.php 2006-03-11 02:23:13.000000000 +0100
@@ -23,6 +23,9 @@
# ce script gère le filtrage des commentaires
+define(SUSPICIOUS_SCORE, 0);
+define(SPAM_SCORE, 8.0);
+
# on regarde si le plugin est activé
$desc = implode('', file(dirname(__FILE__).'/desc.xml'));
if (strpos($desc, 'active="true"') || strpos($desc, 'active="1"')) {
@@ -47,7 +50,10 @@
$ip = spamfilter::realip(@$_SERVER['REMOTE_ADDR'], @$_SERVER['HTTP_X_FORWARDED_FOR']);
# On teste assez tot si c'est du spam, si ce n'en est pas on rend la main au fonctionnement normal
$spam = spamfilter::is_spam($nom,$mail,$site, $ip, trim($_POST['c_content']));
- if ($spam !== false) {
+ if ($spam > SPAM_SCORE) {
+ $blog->setError(__("Sorry, your messsage is a spam. I don't accept spam. Go away !"));
+ }
+ elseif( (is_numeric($spam) && ($spam > SUSPICIOUS_SCORE) ) or (!is_numeric($spam) && ($spam !== false))) {
# localisation
$__lang = (!empty($lang)) ? $lang : dc_default_lang;
if (dc_encoding == 'UTF-8') {
@@ -153,8 +159,8 @@
}
# avertissement de l'utilisateur, son message est dans la file de modération
- if (!empty($_GET['mod'])) {
- $form_msg = __('Your comment has been sent '.
+ if(!empty($_GET['mod'])) {
+ $form_msg = __('Your comment has been sent '.
'successfully. It will be online soon.');
}
}