Dotclear

source: plugins/antispam/filters/class.dc.filter.ip.php @ 3:cf375f1e7b0f

Revision 3:cf375f1e7b0f, 7.5 KB checked in by Dsls <dsls@…>, 14 years ago (diff)

Ported Franck & Kozlika updates for user prefs, dedicated branch

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Antispam, a plugin for Dotclear 2.
5#
6# Copyright (c) 2003-2010 Olivier Meunier & Association Dotclear
7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14class dcFilterIP extends dcSpamFilter
15{
16     public $name = 'IP Filter';
17     public $has_gui = true;
18     
19     private $style_list = 'height: 200px; overflow: auto; margin-bottom: 1em; ';
20     private $style_p = 'margin: 1px 0 0 0; padding: 0.2em 0.5em; ';
21     private $style_global = 'background: #ccff99; ';
22     
23     private $con;
24     private $table;
25     
26     public function __construct($core)
27     {
28          parent::__construct($core);
29          $this->con =& $core->con;
30          $this->table = $core->prefix.'spamrule';
31     }
32     
33     protected function setInfo()
34     {
35          $this->description = __('IP Blacklist / Whitelist Filter');
36     }
37     
38     public function getStatusMessage($status,$comment_id)
39     {
40          return sprintf(__('Filtered by %1$s with rule %2$s.'),$this->guiLink(),$status);
41     }
42     
43     public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status)
44     {
45          if (!$ip) {
46               return;
47          }
48         
49          # White list check
50          if ($this->checkIP($ip,'white') !== false) {
51               return false;
52          }
53         
54          # Black list check
55          if (($s = $this->checkIP($ip,'black')) !== false) {
56               $status = $s;
57               return true;
58          }
59     }
60     
61     public function gui($url)
62     {
63          global $default_tab;
64          $core =& $this->core;
65         
66          # Set current type and tab
67          $ip_type = 'black';
68          if (!empty($_REQUEST['ip_type']) && $_REQUEST['ip_type'] == 'white') {
69               $ip_type = 'white';
70          }
71          $default_tab = 'tab_'.$ip_type;
72         
73          # Add IP to list
74          if (!empty($_POST['addip']))
75          {
76               try
77               {
78                    $global = !empty($_POST['globalip']) && $core->auth->isSuperAdmin();
79                   
80                    $this->addIP($ip_type,$_POST['addip'],$global);
81                    http::redirect($url.'&added=1&ip_type='.$ip_type);
82               }
83               catch (Exception $e)
84               {
85                    $core->error->add($e->getMessage());
86               }
87          }
88         
89          # Remove IP from list
90          if (!empty($_POST['delip']) && is_array($_POST['delip']))
91          {
92               try {
93                    $this->removeRule($_POST['delip']);
94                    http::redirect($url.'&removed=1&ip_type='.$ip_type);
95               } catch (Exception $e) {
96                    $core->error->add($e->getMessage());
97               }
98          }
99         
100          /* DISPLAY
101          ---------------------------------------------- */
102          $res = '';
103         
104          if (!empty($_GET['added'])) {
105               $res .= '<p class="message">'.__('IP address has been successfully added.').'</p>';
106          }
107          if (!empty($_GET['removed'])) {
108               $res .= '<p class="message">'.__('IP addresses have been successfully removed.').'</p>';
109          }
110         
111          $res .=
112          $this->displayForms($url,'black',__('Blacklist')).
113          $this->displayForms($url,'white',__('Whitelist'));
114         
115          return $res;
116     }
117     
118     private function displayForms($url,$type,$title)
119     {
120          $core =& $this->core;
121         
122          $res =
123          '<div class="multi-part" id="tab_'.$type.'" title="'.$title.'">'.
124         
125          '<form action="'.html::escapeURL($url).'" method="post">'.
126          '<fieldset><legend>'.__('Add an IP address').'</legend><p>'.
127          form::hidden(array('ip_type'),$type).
128          form::field(array('addip'),18,255).' ';
129         
130          if ($core->auth->isSuperAdmin()) {
131               $res .= '<label class="classic">'.form::checkbox(array('globalip'),1).' '.
132               __('Global IP').'</label> ';
133          }
134         
135          $res .=
136          $core->formNonce().
137          '<input type="submit" value="'.__('Add').'"/></p>'.
138          '</fieldset></form>';
139         
140          $rs = $this->getRules($type);
141         
142          if ($rs->isEmpty())
143          {
144               $res .= '<p><strong>'.__('No IP address in list.').'</strong></p>';
145          }
146          else
147          {
148               $res .=
149               '<form action="'.html::escapeURL($url).'" method="post">'.
150               '<fieldset><legend>' . __('IP list') . '</legend>'.
151               '<div style="'.$this->style_list.'">';
152               
153               while ($rs->fetch())
154               {
155                    $bits = explode(':',$rs->rule_content);
156                    $pattern = $bits[0];
157                    $ip = $bits[1];
158                    $bitmask = $bits[2];
159                   
160                    $disabled_ip = false;
161                    $p_style = $this->style_p;
162                    if (!$rs->blog_id) {
163                         $disabled_ip = !$core->auth->isSuperAdmin();
164                         $p_style .= $this->style_global;
165                    }
166                   
167                    $res .=
168                    '<p style="'.$p_style.'"><label class="classic">'.
169                    form::checkbox(array('delip[]'),$rs->rule_id,false,'','',$disabled_ip).' '.
170                    html::escapeHTML($pattern).
171                    '</label></p>';
172               }
173               $res .=
174               '</div>'.
175               '<p><input class="submit delete" type="submit" value="'.__('Delete').'"/>'.
176               $core->formNonce().
177               form::hidden(array('ip_type'),$type).
178               '</p>'.
179               '</fieldset></form>';
180          }   
181         
182          $res .= '</div>';
183         
184          return $res;
185     }
186     
187     private function ipmask($pattern,&$ip,&$mask)
188     {
189          $bits = explode('/',$pattern);
190         
191          # Set IP
192          $bits[0] .= str_repeat(".0", 3 - substr_count($bits[0], "."));
193          $ip = ip2long($bits[0]);
194         
195          if (!$ip || $ip == -1) {
196               throw new Exception('Invalid IP address');
197          }
198         
199          # Set mask
200          if (!isset($bits[1])) {
201               $mask = -1;
202          } elseif (strpos($bits[1],'.')) {
203               $mask = ip2long($bits[1]);
204               if (!$mask) {
205                    $mask = -1;
206               }
207          } else {
208               $mask = ~((1 << (32 - $bits[1])) - 1);
209          }
210     }
211     
212     private function addIP($type,$pattern,$global)
213     {
214          $this->ipmask($pattern,$ip,$mask);
215          $pattern = long2ip($ip).($mask != -1 ? '/'.long2ip($mask) : '');
216          $content = $pattern.':'.$ip.':'.$mask;
217         
218          $old = $this->getRuleCIDR($type,$global,$ip,$mask);
219          $cur = $this->con->openCursor($this->table);
220         
221          if ($old->isEmpty())
222          {
223               $id = $this->con->select('SELECT MAX(rule_id) FROM '.$this->table)->f(0) + 1;
224               
225               $cur->rule_id = $id;
226               $cur->rule_type = (string) $type;
227               $cur->rule_content = (string) $content;
228               
229               if ($global && $this->core->auth->isSuperAdmin()) {
230                    $cur->blog_id = null;
231               } else {
232                    $cur->blog_id = $this->core->blog->id;
233               }
234               
235               $cur->insert();
236          }
237          else
238          {
239               $cur->rule_type = (string) $type;
240               $cur->rule_content = (string) $content;
241               $cur->update('WHERE rule_id = '.(integer) $old->rule_id);
242          }
243     }
244     
245     private function getRules($type='all')
246     {
247          $strReq =
248          'SELECT rule_id, rule_type, blog_id, rule_content '.
249          'FROM '.$this->table.' '.
250          "WHERE rule_type = '".$this->con->escape($type)."' ".
251          "AND (blog_id = '".$this->core->blog->id."' OR blog_id IS NULL) ".
252          'ORDER BY blog_id ASC, rule_content ASC ';
253         
254          return $this->con->select($strReq);
255     }
256     
257     private function getRuleCIDR($type,$global,$ip,$mask)
258     {
259          $strReq =
260          'SELECT * FROM '.$this->table.' '.
261          "WHERE rule_type = '".$this->con->escape($type)."' ".
262          "AND rule_content LIKE '%:".(integer) $ip.":".(integer) $mask."' ".
263          'AND blog_id '.($global ? 'IS NULL ' : "= '".$this->core->blog->id."' ");
264         
265          return $this->con->select($strReq);
266     }
267     
268     private function checkIP($cip,$type)
269     {
270          $core =& $this->core;
271         
272          $strReq =
273          'SELECT DISTINCT(rule_content) '.
274          'FROM '.$this->table.' '.
275          "WHERE rule_type = '".$this->con->escape($type)."' ".
276          "AND (blog_id = '".$this->core->blog->id."' OR blog_id IS NULL) ".
277          'ORDER BY rule_content ASC ';
278         
279          $rs = $this->con->select($strReq);
280          while ($rs->fetch())
281          {
282               list($pattern,$ip,$mask) = explode(':',$rs->rule_content);
283               if ((ip2long($cip) & (integer) $mask) == ((integer) $ip & (integer) $mask)) {
284                    return $pattern;
285               }
286          }
287          return false;
288     }
289     
290     private function removeRule($ids)
291     {
292          $strReq = 'DELETE FROM '.$this->table.' ';
293         
294          if (is_array($ids)) {
295               foreach ($ids as $i => $v) {
296                    $ids[$i] = (integer) $v;
297               }
298               $strReq .= 'WHERE rule_id IN ('.implode(',',$ids).') ';
299          } else {
300               $ids = (integer) $ids;
301               $strReq .= 'WHERE rule_id = '.$ids.' ';
302          }
303         
304          if (!$this->core->auth->isSuperAdmin()) {
305               $strReq .= "AND blog_id = '".$this->core->blog->id."' ";
306          }
307         
308          $this->con->execute($strReq);
309     }
310}
311?>
Note: See TracBrowser for help on using the repository browser.

Sites map