239ed7ddfe2aab17b6102f542a585a5d6fca9b3e
[brisk.git] / web / Obj / hardban.phh
1 <?php
2 /*
3  *  brisk - auth.phh
4  *
5  *  Copyright (C) 2006-2008 Matteo Nastasi
6  *                          mailto: nastasi@alternativeoutput.it 
7  *                                  matteo.nastasi@milug.org
8  *                          web: http://www.alternativeoutput.it
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details. You should have received a
19  * copy of the GNU General Public License along with this program; if
20  * not, write to the Free Software Foundation, Inc, 59 Temple Place -
21  * Suite 330, Boston, MA 02111-1307, USA.
22  *
23  */
24
25 define(HBAN_SHM_DIMS_MIN, 16384);
26 define(HBAN_SHM_DIMS_MAX, 65536);
27 define(HBAN_SHM_DIMS_DLT, 16384);
28 define(HBAN_VALID_TIME,      15);
29 define(HBAN_GARBAGE_TIMEOUT,  5);
30
31 class Hardban {
32   var $login;
33   var $ip;
34   var $session;
35   var $timeout;
36
37   function Hardban($login, $ip, $session, $timeout)
38   {
39     $this->login  = $login;
40     $this->ip     = $ip;
41     $this->session  = $session;
42     $this->timeout = $timeout;
43   }
44 }
45
46 class Hardbans {
47   var $item;
48   var $item_n;
49   var $mod;
50   var $shm_sz;
51
52   var $garbage_timeout;
53
54
55   function Hardbans()
56   {
57     $this->item = array();
58     $this->item_n = 0;
59     $this->garbage_timeout = 0;
60     $this->mod = FALSE;
61   }
62
63   function add_item($login, $ip, $session, $timeout)
64   {
65     $chal = null;
66
67     log_auth("xxx", sprintf("Hardbans::add [%s]\n", $login));
68
69     if (($chal = new Hardban($login, $ip, $session, $timeout)) == null) {
70       return ($G_false);
71     }
72
73     $this->item[$this->item_n] = $chal;
74     $this->item_n++;
75
76     $this->mod = TRUE;
77
78     return ($chal);
79   }
80
81
82   /* remove all istances related to $login */
83
84   function rem($login)
85   {
86     $ismod  = FALSE;
87     $curtime = time();
88
89     for ($i = 0 ; $i < $this->item_n ; $i++) {
90       if ($this->item[$i]->timeout < $curtime || strcasecmp($this->item[$i]->login, $login) == 0) {
91         $ismod = TRUE;
92         for ($e = $i ; $e  < ($this->item_n - 1) ; $e++) {
93           $this->item[$e] = $this->item[$e + 1];
94         }
95         
96         $i--;
97         $this->item_n--;
98         unset($this->item[$this->item_n]);
99         $this->mod = TRUE;
100       }
101     }
102
103     return ($ismod);
104   }
105
106   function garbage_manager($force)
107   {
108     $curtime = time();
109
110     // FIXME remove set to 0
111     $this->garbage_timeout = 0;
112     if ($this->garbage_timeout > $curtime && $force == FALSE)
113       return (FALSE);
114
115     $ismod = FALSE;
116     
117     for ($i = 0 ; $i < $this->item_n ; $i++) {
118       log_auth("xxx", "LOOPI item: ".$i." timeout: ".$this->item[$i]->timeout."  curtime: ".$curtime);
119       if ($this->item[$i]->timeout < $curtime) {
120         for ($e = $i ; $e  < ($this->item_n - 1) ; $e++) {
121           $this->item[$e] = $this->item[$e + 1];
122         }
123         
124         $i--;
125         $this->item_n--;
126         log_auth("xxx", "LOOPI unset: ".$this->item_n);
127         unset($this->item[$this->item_n]);
128         $ismod = TRUE;
129         $this->mod = TRUE;
130       }
131     }
132     
133     log_auth("xxx", "LOOPI AFTER: ".count($this->item)." _n:" .$this->item_n );
134     
135     $this->garbage_timeout = $curtime + HBAN_GARBAGE_TIMEOUT;
136     
137     return ($ismod);
138   }
139   
140   function ismod()
141   {
142     return ($this->mod);
143   }
144
145   // Static functions
146   function &init_data()
147   {
148     $chal =& new Hardbans();
149     
150     $chal->mod = TRUE;
151
152     return $chal;
153   }
154
155   function &load_data() 
156   {
157     GLOBAL $G_false, $sess;
158     $doexit = FALSE;
159     do {
160       if (($tok = @ftok(FTOK_PATH."/hardbans", "B")) == -1) {
161         log_main("ftok failed");
162         $doexit = TRUE;
163         break;
164       }
165     
166       if (($shm_sz = sharedmem_sz($tok)) == -1) {
167         log_main("shmop_open failed");
168       }
169         
170       if ($shm_sz == -1)
171         $shm_sz = HBAN_SHM_DIMS_MIN;
172
173       if ($shm = shm_attach($tok, $shm_sz)) {
174         $hban = @shm_get_var($shm, $tok);
175         
176         log_only("hardban ==  ".($hban == FALSE ?   "FALSE" : "TRUE")."  hardban ===  ".($hban === FALSE ? "FALSE" : "TRUE")."  hardban isset ".(isset($hban) ?   "TRUE" : "FALSE"));
177         
178         if ($hban == FALSE) {
179           log_only("INIT HARDBAN DATA");
180           
181           $hban =& Hardbans::init_data();
182           if (@shm_put_var($shm, $tok, $hban) == FALSE) {
183             log_only("PUT_VAR FALLITA ".strlen(serialize($hban)));
184             log_only(serialize($hban));
185           }
186         }
187         $hban->shm_sz = $shm_sz;
188         
189         shm_detach($shm);
190       }
191
192       $hban->garbage_manager(TRUE);
193
194       $ret = &$hban;
195       return ($ret);
196     } while (0);
197     
198     if ($doexit)
199       exit();
200     
201     return ($G_false);
202   }
203   
204
205   function save_data(&$hban) 
206   {
207     $shm =   FALSE;
208     $oldmod = $hban->mod;
209
210     if (($tok = @ftok(FTOK_PATH."/hardbans", "B")) == -1) 
211       return (FALSE);
212     
213     while ($hban->shm_sz < HBAN_SHM_DIMS_MAX) {
214       if (($shm = shm_attach($tok, $hban->shm_sz)) == FALSE)
215         break;
216       
217       if (isset($hban)) 
218         log_only("hardban count ".count($hban->item)."  _n: ".$hban->item_n);
219
220       $hban->mod = FALSE;
221       if (shm_put_var($shm, $tok, $hban) != FALSE) {
222         shm_detach($shm);
223         return (TRUE);
224       }
225       $hban->mod = $oldmod;
226
227       if (shm_remove($shm) === FALSE) {
228         log_only("REMOVE FALLITA");
229         break;
230       }
231       shm_detach($shm);
232       $hban->shm_sz += HBAN_SHM_DIMS_DLT;
233     } 
234
235     if ($shm)
236       shm_detach($shm);
237     
238     return (FALSE);
239   }
240
241   function lock_data()
242   {
243     if (($tok = @ftok(FTOK_PATH."/hardbans", "B")) == -1) {
244       return (FALSE);
245     }
246     // echo "FTOK ".$tok."<br>";
247     if (($res = sem_get($tok)) == FALSE) {
248       return (FALSE);
249     }
250     if (sem_acquire($res)) {   
251       log_lock("LOCK hardbans");
252       return ($res);
253     }
254     else
255       return (FALSE);
256   }
257   
258   function unlock_data($res)
259   {
260     GLOBAL $sess; 
261     
262     log_lock("UNLOCK hardbans");
263
264     return (sem_release($res));
265   }
266
267
268   function check($login, $ip, $session)
269   {
270     $bantime = -1;
271     /* if it exists check for a valid challenge */
272     if (($a_sem = Hardbans::lock_data()) != FALSE) { 
273       
274       if (($hban = &Hardbans::load_data()) != FALSE) {
275         for ($e = 0 ; $e < $hban->item_n ; $e++) {
276           if ($login != FALSE) {
277             if (strcasecmp($login, $hban->item[$e]->login) == 0 || $hban->item[$e]->session == $session) {
278               $bantime = $hban->item[$e]->timeout;
279               break;
280             }
281           }
282           else {
283             /* check on ip and sess */
284             if ($hban->item[$e]->ip == $ip || $hban->item[$e]->session == $session) {
285               $bantime = $hban->item[$e]->timeout;
286               break;
287             }
288           }
289         } // for (...
290         if ($hban->ismod()) {
291           Hardbans::save_data(&$hban);
292         }
293       } // if (load_data
294       Hardbans::unlock_data($a_sem);
295     } // if (lock_data
296     
297     return ($bantime);
298   } // func
299
300
301
302   function add($login, $ip, $session, $timeout)
303   {
304     $found = FALSE;
305     /* if it exists check for a valid challenge */
306     if (($a_sem = Hardbans::lock_data()) != FALSE) { 
307       
308       if (($hban = &Hardbans::load_data()) != FALSE) {
309
310         $hban->add_item($login, $ip, $session, $timeout);
311
312         if ($hban->ismod()) {
313           Hardbans::save_data(&$hban);
314         }
315       } // if (load_data
316       Hardbans::unlock_data($a_sem);
317     } // if (lock_data
318     
319     return ($found);
320   } // func
321
322 } // End CLASS Hardbans
323
324 ?>