timing log on Challenges semaphore
[brisk.git] / web / Obj / auth.phh
1 <?php
2   /*
3    *  brisk - auth.phh
4    *
5    *  Copyright (C) 2006-2011 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 require_once("${G_base}Obj/dbase_${G_dbasetype}.phh");
26
27 define(CHAL_SHM_DIMS_MIN, 16384);
28 define(CHAL_SHM_DIMS_MAX, 65536);
29 define(CHAL_SHM_DIMS_DLT, 16384);
30 define(CHAL_VALID_TIME,      15);
31 define(CHAL_GARBAGE_TIMEOUT,  5);
32
33
34 class Challenge {
35     var $login;
36     var $token;
37     var $ip;
38     var $tstamp;
39     
40     function Challenge($login, $token, $ip, $tstamp)
41     {
42         $this->login  = $login;
43         $this->token  = $token;
44         $this->ip     = $ip;
45         $this->tstamp = $tstamp + CHAL_VALID_TIME;
46     }
47 }
48
49 class Challenges {
50     static $delta_t;
51
52     var $item;
53     var $item_n;
54     var $mod;
55     var $shm_sz;
56     
57     var $garbage_timeout;
58     
59     
60     function Challenges()
61     {
62         $this->item = array();
63         $this->item_n = 0;
64         $this->garbage_timeout = 0;
65         $this->mod = FALSE;
66     }
67     
68     function add($login, $token, $ip, $tstamp) 
69     {
70         $chal = null;
71         
72         log_auth("xxx", sprintf("Challenges::add [%s]\n", $login));
73         // FIXME Checks here
74         if ($login == '') {
75             return (FALSE);
76         }
77         
78         // log_auth("xxx", "LOOPI tstamp: ".$this->item[$i]->tstamp."  curtime: ".$curtime);
79         
80         if (($chal = new Challenge($login, $token, $ip, $tstamp)) == FALSE) {
81             return (FALSE);
82         }
83         
84         $this->item[$this->item_n] = $chal;
85         $this->item_n++;
86
87         $this->mod = TRUE;
88
89         return ($chal);
90     }
91
92
93     /* remove all istances related to $login */
94
95     function rem($login)
96     {
97         $ismod  = FALSE;
98
99         for ($i = 0 ; $i < $this->item_n ; $i++) {
100             if ($this->item[$i]->login == $login) {
101                 $ismod = TRUE;
102                 for ($e = $i ; $e  < ($this->item_n - 1) ; $e++) {
103                     $this->item[$e] = $this->item[$e + 1];
104                 }
105         
106                 $i--;
107                 $this->item_n--;
108                 unset($this->item[$this->item_n]);
109                 $this->mod = TRUE;
110             }
111         }
112
113         return ($ismod);
114     }
115
116     function garbage_manager()
117     {
118         $curtime = time();
119
120         // FIXME remove set to 0
121         $this->garbage_timeout = 0;
122         if ($this->garbage_timeout > $curtime)
123             return (FALSE);
124
125         $ismod = FALSE;
126     
127         for ($i = 0 ; $i < $this->item_n ; $i++) {
128             log_auth("xxx", "LOOPI item: ".$i." tstamp: ".$this->item[$i]->tstamp."  curtime: ".$curtime);
129             if ($this->item[$i]->tstamp < $curtime) {
130                 for ($e = $i ; $e  < ($this->item_n - 1) ; $e++) {
131                     $this->item[$e] = $this->item[$e + 1];
132                 }
133         
134                 $i--;
135                 $this->item_n--;
136                 log_auth("xxx", "LOOPI unset: ".$this->item_n);
137                 unset($this->item[$this->item_n]);
138                 $ismod = TRUE;
139                 $this->mod = TRUE;
140             }
141         }
142     
143         log_auth("xxx", "LOOPI AFTER: ".count($this->item)." _n:" .$this->item_n );
144     
145         $this->garbage_timeout = $curtime + CHAL_GARBAGE_TIMEOUT;
146     
147         return ($ismod);
148     }
149   
150     function ismod()
151     {
152         return ($this->mod);
153     }
154
155     // Static functions
156     static function create()
157         {
158             $chal =& new Challenges();
159     
160             $chal->mod = TRUE;
161
162             return $chal;
163         }
164
165     function load_data() 
166         {
167             GLOBAL $sess;
168             $doexit = FALSE;
169             do {
170                 if (($tok = @ftok(FTOK_PATH."/challenges", "B")) == -1) {
171                     log_main("ftok failed");
172                     $doexit = TRUE;
173                     break;
174                 }
175     
176                 if (($shm_sz = sharedmem_sz($tok)) == -1) {
177                     log_main("shmop_open failed");
178                 }
179         
180                 if ($shm_sz == -1)
181                     $shm_sz = CHAL_SHM_DIMS_MIN;
182
183                 if ($shm = shm_attach($tok, $shm_sz)) {
184                     $chals = @shm_get_var($shm, $tok);
185         
186                     log_only("challenges ==  ".($chals == FALSE ?   "FALSE" : "TRUE")."  challenges ===  ".($chals === FALSE ? "FALSE" : "TRUE")."  challenges isset ".(isset($chals) ?   "TRUE" : "FALSE"));
187         
188                     if ($chals == FALSE) {
189                         log_only("INIT CHALLENGES DATA");
190           
191                         $chals =& Challenges::create();
192                         if (@shm_put_var($shm, $tok, $chals) == FALSE) {
193                             log_only("PUT_VAR FALLITA ".strlen(serialize($chals)));
194                             log_only(serialize($chals));
195                         }
196                     }
197                     $chals->shm_sz = $shm_sz;
198         
199                     shm_detach($shm);
200                 }
201
202                 $chals->garbage_manager();
203
204                 return ($chals);
205             } while (0);
206     
207             if ($doexit)
208                 exit();
209     
210             return (FALSE);
211         }
212   
213
214     function save_data($chals) 
215     {
216         $shm =   FALSE;
217         $oldmod = $chals->mod;
218
219         if (($tok = @ftok(FTOK_PATH."/challenges", "B")) == -1) 
220             return (FALSE);
221     
222         while ($chals->shm_sz < CHAL_SHM_DIMS_MAX) {
223             if (($shm = shm_attach($tok, $chals->shm_sz)) == FALSE)
224                 break;
225       
226             if (isset($chals)) 
227                 log_only("challenges count ".count($chals->item)."  _n: ".$chals->item_n);
228
229             $chals->mod = FALSE;
230             if (shm_put_var($shm, $tok, $chals) != FALSE) {
231                 shm_detach($shm);
232                 return (TRUE);
233             }
234             $chals->mod = $oldmod;
235
236             if (shm_remove($shm) === FALSE) {
237                 log_only("REMOVE FALLITA");
238                 break;
239             }
240             shm_detach($shm);
241             $chals->shm_sz += CHAL_SHM_DIMS_DLT;
242         } 
243
244         if ($shm)
245             shm_detach($shm);
246     
247         return (FALSE);
248     }
249
250     function lock_data()
251     {
252         if (($tok = @ftok(FTOK_PATH."/challenges", "B")) == -1) {
253             return (FALSE);
254         }
255         // echo "FTOK ".$tok."<br>";
256         if (($res = sem_get($tok)) == FALSE) {
257             return (FALSE);
258         }
259         if (sem_acquire($res)) {   
260             self::$delta_t = microtime(TRUE);
261             log_lock("LOCK   challenges   [".self::$delta_t."]");
262             return ($res);
263         }
264         else
265             return (FALSE);
266     }
267   
268     function unlock_data($res)
269     {
270         GLOBAL $sess; 
271     
272         log_lock("UNLOCK challenges   [".(microtime(TRUE) - (self::$delta_t))."]");
273
274         return (sem_release($res));
275     }
276 } // End CLASS Challenges
277
278 ?>