4 * NP_Blacklist(JP) ($Revision: 1.6 $)
5 * by hsur ( http://blog.cles.jp/np_cles )
6 * $Id: NP_Blacklist.php,v 1.6 2007-02-02 16:48:25 hsur Exp $
8 * Based on NP_Blacklist 0.98
10 * http://forum.nucleuscms.org/viewtopic.php?t=5300
14 * Copyright (C) 2005-2007 cles All rights reserved.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 include_once(dirname(__FILE__)."/blacklist/blacklist_lib.php");
33 class NP_Blacklist extends NucleusPlugin {
35 return 'Blacklist(JP)';
37 function getAuthor() {
38 return 'xiffy + hsur';
41 return 'http://blog.cles.jp/np_cles/category/31/subcatid/11';
43 function getVersion() {
46 function getDescription() {
47 return '[$Revision: 1.6 $]<br />'.NP_BLACKLIST_description;
49 function supportsFeature($what) {
51 case 'SqlTablePrefix' :
59 // create some options
60 $this->createOption('enabled', NP_BLACKLIST_enabled, 'yesno', 'yes');
61 $this->createOption('redirect', NP_BLACKLIST_redirect, 'text', '');
62 $this->createOption('ipblock', NP_BLACKLIST_ipblock, 'yesno', 'yes');
63 $this->createOption('ipthreshold', NP_BLACKLIST_ipthreshold, 'text', '10');
64 $this->createOption('BulkfeedsKey', NP_BLACKLIST_BulkfeedsKey, 'text', '');
65 $this->createOption('SkipNameResolve', NP_BLACKLIST_SkipNameResolve, 'yesno', 'yes');
67 $this->_initSettings();
70 function unInstall() {
73 function getPluginOption($name) {
74 return $this->getOption($name);
77 function getEventList() {
78 $this->_initSettings();
79 return array ('QuickMenu', 'SpamCheck');
82 function hasAdminArea() {
87 // include language file for this plugin
88 $language = ereg_replace('[\\|/]', '', getLanguageName());
89 if (file_exists($this->getDirectory().'language/'.$language.'.php'))
90 @ include_once ($this->getDirectory().'language/'.$language.'.php');
92 @ include_once ($this->getDirectory().'language/english.php');
93 $this->resultCache = false;
96 function event_QuickMenu(& $data) {
97 global $member, $nucleus, $blogid;
98 // only show to admins
99 if (preg_match("/MD$/", $nucleus['version'])) {
100 $isblogadmin = $member->isBlogAdmin(-1);
102 $isblogadmin = $member->isBlogAdmin($blogid);
104 if (!($member->isLoggedIn() && ($member->isAdmin() | $isblogadmin)))
106 array_push($data['options'], array ('title' => NP_BLACKLIST_name, 'url' => $this->getAdminURL(), 'tooltip' => NP_BLACKLIST_nameTips,));
109 // handle SpamCheck event
110 function event_SpamCheck(& $data) {
112 if (isset ($data['spamcheck']['result']) && $data['spamcheck']['result'] == true) {
113 // Already checked... and is spam
117 if (!isset ($data['spamcheck']['return'])) {
118 $data['spamcheck']['return'] = true;
121 // for SpamCheck API 2.0 compatibility
122 if (!$data['spamcheck']['data']) {
123 switch (strtolower($data['spamcheck']['type'])) {
125 $data['spamcheck']['data'] = $data['spamcheck']['body']."\n";
126 $data['spamcheck']['data'] .= $data['spamcheck']['author']."\n";
127 $data['spamcheck']['data'] .= $data['spamcheck']['url']."\n";
130 $data['spamcheck']['data'] = $data['spamcheck']['title']."\n";
131 $data['spamcheck']['data'] .= $data['spamcheck']['excerpt']."\n";
132 $data['spamcheck']['data'] .= $data['spamcheck']['blogname']."\n";
133 $data['spamcheck']['data'] .= $data['spamcheck']['url'];
136 $data['spamcheck']['data'] = $data['spamcheck']['url'];
140 $ipblock = ($data['spamcheck']['ipblock']) || ($data['spamcheck']['live']);
143 $result = $this->blacklist($data['spamcheck']['type'], $data['spamcheck']['data'], $ipblock);
148 pbl_logspammer($data['spamcheck']['type'].': '.$result);
149 if (isset ($data['spamcheck']['return']) && $data['spamcheck']['return'] == true) {
151 $data['spamcheck']['result'] = true;
152 $data['spamcheck']['plugin'] = $this->getName();
153 $data['spamcheck']['message'] = 'Marked as spam by NP_Blacklist';
156 $this->_redirect($this->getOption('redirect'));
162 function event_PreAddComment(& $data) {
163 $comment = $data['comment'];
164 $result = $this->blacklist('comment', postVar('body')."\n".$comment['host']."\n".$comment['user']."\n".$comment['userid']);
166 pbl_logspammer('comment: '.$result);
167 $this->_redirect($this->getOption('redirect'));
172 function event_ValidateForm(& $data) {
173 if ($data['type'] == 'comment') {
174 $comment = $data['comment'];
175 $result = $this->blacklist('comment', postVar('body')."\n".$comment['host']."\n".$comment['user']."\n".$comment['userid']);
177 pbl_logspammer('comment: '.$result);
178 $this->_redirect($this->getOption('redirect'));
181 if ($data['type'] == 'membermail') {
182 $result = $this->blacklist('membermail', postVar('frommail')."\n".postVar('message'));
184 pbl_logspammer('membermail: '.$result);
185 $this->_redirect($this->getOption('redirect'));
192 function event_PreSkinParse(& $data) {
193 $result = $this->blacklist('PreSkinParse', '');
195 pbl_logspammer('PreSkinParse: '.$result);
196 $this->_redirect($this->getOption('redirect'));
200 function blacklist($type, $testString, $ipblock = true) {
201 global $DIR_PLUGINS, $member;
202 if ($this->resultCache)
203 return $this->resultCache.'[Cached]';
205 if ($member->isLoggedIn()) {
209 if ($this->getOption('enabled') == 'yes') {
210 // update the blacklist first file
211 //pbl_updateblacklist($this->getOption('update'),false);
213 $ipblock = ($this->getOption('ipblock') == 'yes') ? true : false;
217 if ($ipblock || $testString != '') {
218 $result = pbl_checkforspam($testString, $ipblock, $this->getOption('ipthreshold'), true);
222 $this->resultCache = $result;
229 function submitSpamToBulkfeeds($url) {
231 $url = implode("\n", $url);
233 $postData['apikey'] = $this->getOption('BulkfeedsKey');
234 if (!$postData['apikey'])
235 return "BulkfeedsKey not found. see http://bulkfeeds.net/app/register_api.html";
236 $postData['url'] = $url;
238 $data = $this->_http('http://bulkfeeds.net:80/app/submit_spam.xml', 'POST', '', $postData);
242 function _http($url, $method = "GET", $headers = "", $post = array ("")) {
243 $URL = parse_url($url);
245 if (isset ($URL['query'])) {
246 $URL['query'] = "?".$URL['query'];
251 if (!isset ($URL['port']))
254 $request = $method." ".$URL['path'].$URL['query']." HTTP/1.0\r\n";
256 $request .= "Host: ".$URL['host']."\r\n";
257 $request .= "User-Agent: NP_Blacklist/".phpversion()."\r\n";
259 if (isset ($URL['user']) && isset ($URL['pass'])) {
260 $request .= "Authorization: Basic ".base64_encode($URL['user'].":".$URL['pass'])."\r\n";
263 $request .= $headers;
265 if (strtoupper($method) == "POST") {
266 while (list ($name, $value) = each($post)) {
267 $POST[] = $name."=".urlencode($value);
269 $postdata = implode("&", $POST);
270 $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
271 $request .= "Content-Length: ".strlen($postdata)."\r\n";
273 $request .= $postdata;
278 $fp = fsockopen($URL['host'], $URL['port'], $errno, $errstr, 20);
281 socket_set_timeout($fp, 20);
282 fputs($fp, $request);
285 $response .= fgets($fp, 4096);
288 $DATA = split("\r\n\r\n", $response, 2);
291 $host = $URL['host'];
292 $port = $URL['port'];
293 ACTIONLOG :: add(WARNING, $this->getName().':'."[$errno]($host:$port) $errstr");
298 function _redirect($url) {
300 header("HTTP/1.0 403 Forbidden");
301 header("Status: 403 Forbidden");
303 include (dirname(__FILE__).'/blacklist/blocked.txt');
305 $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%]|i', '', $url);
306 header('Location: '.$url);
311 function _initSettings() {
312 $settingsDir = dirname(__FILE__).'/blacklist/settings/';
313 $settings = array ('blacklist.log', 'blockip.pbl', 'matched.pbl', 'blacklist.pbl', 'blacklist.txt', 'suspects.pbl',);
314 $personalBlacklist = $settingsDir.'personal_blacklist.pbl';
315 $personalBlacklistDist = $settingsDir.'personal_blacklist.pbl.dist';
318 if ($this->_is_writable($settingsDir)) {
319 foreach ($settings as $setting) {
320 touch($settingsDir.$setting);
322 // setup personal blacklist
323 if (!file_exists($personalBlacklist)) {
324 if (copy($personalBlacklistDist, $personalBlacklist)) {
325 $this->_warn("'$personalBlacklist' ".NP_BLACKLIST_isCreated);
327 $this->_warn("'$personalBlacklist' ".NP_BLACKLIST_canNotCreate);
333 foreach ($settings as $setting) {
334 $this->_is_writable($settingsDir.$setting);
336 $this->_is_writable($personalBlacklist);
338 // setup and check cache dir
339 $cacheDir = NP_BLACKLIST_CACHE_DIR;
340 $this->_is_writable($cacheDir);
343 function _is_writable($file) {
344 $ret = is_writable($file);
346 $this->_warn("'$file' ".NP_BLACKLIST_isNotWritable);
351 function _warn($msg) {
352 ACTIONLOG :: add(WARNING, 'Blacklist: '.$msg);