OSDN Git Service

0803f9a420e178b770cce94f3a988b463ad47ccd
[nucleus-jp/nucleus-plugins.git] / trunk / NP_Blacklist / NP_Blacklist.php
1 <?php
2
3 /**
4   * NP_Blacklist(JP) ($Revision: 1.10 $)
5   * by hsur ( http://blog.cles.jp/np_cles )
6   * $Id: NP_Blacklist.php,v 1.10 2007-03-06 20:54:37 hsur Exp $
7   *
8   * Based on NP_Blacklist 0.98
9   * by xiffy
10   * http://forum.nucleuscms.org/viewtopic.php?t=5300
11 */
12
13 /*
14   * Copyright (C) 2005-2007 cles All rights reserved.
15   *
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.
20   * 
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.
25   * 
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
29 */
30
31 include_once(dirname(__FILE__)."/blacklist/blacklist_lib.php");
32
33 class NP_Blacklist extends NucleusPlugin {
34         function getName() {
35                 return 'Blacklist(JP)';
36         }
37         function getAuthor() {
38                 return 'xiffy + hsur';
39         }
40         function getURL() {
41                 return 'http://blog.cles.jp/np_cles/category/31/subcatid/11';
42         }
43         function getVersion() {
44                 return '1.1.0';
45         }
46         function getDescription() {
47                 return '[$Revision: 1.10 $]<br />'.NP_BLACKLIST_description;
48         }
49         function supportsFeature($what) {
50                 switch ($what) {
51                         case 'SqlTablePrefix' :
52                                 return 1;
53                         default :
54                                 return 0;
55                 }
56         }
57
58         function install() {
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');
66
67                 $this->_initSettings();
68         }
69
70         function unInstall() {
71         }
72
73         function getPluginOption($name) {
74                 return $this->getOption($name);
75         }
76
77         function getEventList() {
78                 $this->_initSettings();
79                 return array ('QuickMenu', 'SpamCheck');
80         }
81
82         function hasAdminArea() {
83                 return 1;
84         }
85
86         function init() {
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');
91                 else
92                         @ include_once ($this->getDirectory().'language/english.php');
93                 $this->resultCache = false;
94         }
95
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);
101                 } else {
102                         $isblogadmin = $member->isBlogAdmin($blogid);
103                 }
104                 if (!($member->isLoggedIn() && ($member->isAdmin() | $isblogadmin)))
105                         return;
106                 array_push($data['options'], array ('title' => NP_BLACKLIST_name, 'url' => $this->getAdminURL(), 'tooltip' => NP_BLACKLIST_nameTips,));
107         }
108
109         // handle SpamCheck event
110         function event_SpamCheck(& $data) {
111                 global $DIR_PLUGINS;
112                 if (isset ($data['spamcheck']['result']) && $data['spamcheck']['result'] == true) {
113                         // Already checked... and is spam
114                         return;
115                 }
116
117                 if (!isset ($data['spamcheck']['return'])) {
118                         $data['spamcheck']['return'] = true;
119                 }
120
121                 // for SpamCheck API 2.0 compatibility
122                 if (!$data['spamcheck']['data']) {
123                         switch (strtolower($data['spamcheck']['type'])) {
124                                 case 'comment' :
125                                         $data['spamcheck']['data'] = $data['spamcheck']['body']."\n";
126                                         $data['spamcheck']['data'] .= $data['spamcheck']['author']."\n";
127                                         $data['spamcheck']['data'] .= $data['spamcheck']['url']."\n";
128                                         break;
129                                 case 'trackback' :
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'];
134                                         break;
135                                 case 'referer' :
136                                         $data['spamcheck']['data'] = $data['spamcheck']['url'];
137                                         break;
138                         }
139                 }
140                 $ipblock = ($data['spamcheck']['ipblock']) || ($data['spamcheck']['live']);
141
142                 // Check for spam
143                 $result = $this->blacklist($data['spamcheck']['type'], $data['spamcheck']['data'], $ipblock);
144
145                 if ($result) {
146                         // Spam found
147                         // logging !
148                         pbl_logspammer($data['spamcheck']['type'].': '.$result);
149                         if (isset ($data['spamcheck']['return']) && $data['spamcheck']['return'] == true) {
150                                 // Return to caller
151                                 $data['spamcheck']['result'] = true;
152                                 $data['spamcheck']['plugin'] = $this->getName();
153                                 $data['spamcheck']['message'] = 'Marked as spam by NP_Blacklist';
154                                 return;
155                         } else {
156                                 $this->_redirect($this->getOption('redirect'));
157                         }
158                 }
159         }
160
161         function blacklist($type, $testString, $ipblock = true) {
162                 global $DIR_PLUGINS, $member;
163                 if ($this->resultCache)
164                         return $this->resultCache.'[Cached]';
165
166                 if ($member->isLoggedIn()) {
167                         return '';
168                 }
169
170                 if ($this->getOption('enabled') == 'yes') {
171                         // update the blacklist first file
172                         //pbl_updateblacklist($this->getOption('update'),false);
173                         if ($ipblock) {
174                                 $ipblock = ($this->getOption('ipblock') == 'yes') ? true : false;
175                         }
176
177                         $result = '';
178                         if ($ipblock || $testString != '') {
179                                 $result = pbl_checkforspam($testString, $ipblock, $this->getOption('ipthreshold'), true);
180                         }
181
182                         if ($result) {
183                                 $this->resultCache = $result;
184                         }
185
186                         return $result;
187                 }
188         }
189
190         function submitSpamToBulkfeeds($url) {
191                 if (is_array($url))
192                         $url = implode("\n", $url);
193
194                 $postData['apikey'] = $this->getOption('BulkfeedsKey');
195                 if (!$postData['apikey'])
196                         return "BulkfeedsKey not found. see http://bulkfeeds.net/app/register_api.html";
197                 $postData['url'] = $url;
198
199                 $data = $this->_http('http://bulkfeeds.net:80/app/submit_spam.xml', 'POST', '', $postData);
200                 return $data;
201         }
202
203         function _http($url, $method = "GET", $headers = "", $post = array ("")) {
204                 $URL = parse_url($url);
205
206                 if (isset ($URL['query'])) {
207                         $URL['query'] = "?".$URL['query'];
208                 } else {
209                         $URL['query'] = "";
210                 }
211
212                 if (!isset ($URL['port']))
213                         $URL['port'] = 80;
214
215                 $request = $method." ".$URL['path'].$URL['query']." HTTP/1.0\r\n";
216
217                 $request .= "Host: ".$URL['host']."\r\n";
218                 $request .= "User-Agent: NP_Blacklist/".phpversion()."\r\n";
219
220                 if (isset ($URL['user']) && isset ($URL['pass'])) {
221                         $request .= "Authorization: Basic ".base64_encode($URL['user'].":".$URL['pass'])."\r\n";
222                 }
223
224                 $request .= $headers;
225
226                 if (strtoupper($method) == "POST") {
227                         while (list ($name, $value) = each($post)) {
228                                 $POST[] = $name."=".urlencode($value);
229                         }
230                         $postdata = implode("&", $POST);
231                         $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
232                         $request .= "Content-Length: ".strlen($postdata)."\r\n";
233                         $request .= "\r\n";
234                         $request .= $postdata;
235                 } else {
236                         $request .= "\r\n";
237                 }
238
239                 $fp = fsockopen($URL['host'], $URL['port'], $errno, $errstr, 20);
240
241                 if ($fp) {
242                         socket_set_timeout($fp, 20);
243                         fputs($fp, $request);
244                         $response = "";
245                         while (!feof($fp)) {
246                                 $response .= fgets($fp, 4096);
247                         }
248                         fclose($fp);
249                         $DATA = split("\r\n\r\n", $response, 2);
250                         return $DATA[1];
251                 } else {
252                         $host = $URL['host'];
253                         $port = $URL['port'];
254                         ACTIONLOG :: add(WARNING, $this->getName().':'."[$errno]($host:$port) $errstr");
255                         return "";
256                 }
257         }
258
259         function _redirect($url) {
260                 if (!$url) {
261                         header("HTTP/1.0 403 Forbidden");
262                         header("Status: 403 Forbidden");
263
264                         include (dirname(__FILE__).'/blacklist/blocked.txt');
265                 } else {
266                         $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%]|i', '', $url);
267                         header('Location: '.$url);
268                 }
269                 exit;
270         }
271
272         function _initSettings() {
273                 $settingsDir = dirname(__FILE__).'/blacklist/settings/';
274                 $settings = array (
275                         'blacklist.log', 
276                         'blockip.pbl', 
277                         'whiteip.pbl',
278                         'matched.pbl', 
279                         'blacklist.pbl', 
280                         'blacklist.txt', 
281                         'suspects.pbl',
282                         'personal_blacklist.pbl',
283                 );
284
285                 // setup settings
286                 if ($this->_is_writable($settingsDir)) {
287                         // setup distfile\r                      foreach (glob($settingsDir.'*.dist') as $distfile) {
288                                 $userFile = substr($distfile, 0, strlen($distfile)-5);
289                                 if (!file_exists($userFile)) {
290                                         if (copy($distfile, $userFile)) {
291                                                 @chmod($userFile, 0666);
292                                                 $this->_warn("'$userFile' ".NP_BLACKLIST_isCreated);
293                                         } else {
294                                                 $this->_warn("'$userFile' ".NP_BLACKLIST_canNotCreate);
295                                         }
296                                 }
297                         }
298                         
299                         foreach ($settings as $setting) {
300                                 @touch($settingsDir.$setting);
301                         }
302                 }
303
304                 // check settings       
305                 foreach ($settings as $setting) {
306                         $this->_is_writable($settingsDir.$setting);
307                 }
308
309                 // setup and check cache dir
310                 $cacheDir = NP_BLACKLIST_CACHE_DIR;
311                 $this->_is_writable($cacheDir);
312         }
313
314         function _is_writable($file) {
315                 $ret = is_writable($file);
316                 if (!$ret) {
317                         $this->_warn("'$file' ".NP_BLACKLIST_isNotWritable);
318                 }
319                 return $ret;
320         }
321
322         function _warn($msg) {
323                 ACTIONLOG :: add(WARNING, 'Blacklist: '.$msg);
324         }
325
326 }