Alternc  3.2
Alternc logiel libre pour l'hébergement
 All Data Structures Namespaces Files Functions Variables Pages
m_authip.php
Go to the documentation of this file.
1 <?php
2 /*
3  $Id: m_authip.php
4  ----------------------------------------------------------------------
5  LICENSE
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License (GPL)
9  as published by the Free Software Foundation; either version 2
10  of the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  To read the license please visit http://www.gnu.org/copyleft/gpl.html
18  ----------------------------------------------------------------------
19  Original Author of file: Fufroma
20  ----------------------------------------------------------------------
21 */
22 /**
23 * Classe de gestion des IP authorisée
24 **/
25 class m_authip {
26 
27  /*
28  * Retourne la liste des ip whitelist
29  *
30  * @return array retourne un tableau indexé des ip de l'utilisateur
31  */
32  function list_ip_whitelist() {
33  global $mem;
34  if (!$mem->checkRight()) return false;
35  return $this->list_ip(true);
36  }
37 
38  function hook_menu() {
39  $obj = array(
40  'title' => _("Access security"),
41  'ico' => 'images/ip.png',
42  'link' => 'ip_main.php',
43  'pos' => 120,
44  ) ;
45 
46  return $obj;
47  }
48 
49  /*
50  * Retourne la liste des ip spécifiées par cet utilisateur
51  *
52  * @return array retourne un tableau indexé des ip de l'utilisateur
53  */
54  function list_ip($whitelist=false) {
55  global $db, $mem;
56 
57  if ($whitelist && $mem->checkRight() ) {
58  $cuid=0;
59  } else {
60  global $cuid;
61  }
62 
63  $r = array();
64  $db->query("SELECT * FROM authorised_ip WHERE uid='$cuid' order by ip,subnet;");
65  while ($db->next_record()) {
66  $r[$db->f('id')]=$db->Record;
67  if ( (checkip($db->f('ip')) && $db->f('subnet') == 32) ||
68  (checkipv6($db->f('ip')) && $db->f('subnet') == 128) ) {
69  $r[$db->f('id')]['ip_human']=$db->f('ip');
70  } else {
71  $r[$db->f('id')]['ip_human']=$db->f('ip')."/".$db->f('subnet');
72  }
73 
74  }
75  return $r;
76  }
77 
78 
79 
80  /*
81  * Supprime une IP des IP de l'utilisateur
82  * et supprime les droits attaché en cascade
83  *
84  * @param integer $id id de la ligne à supprimer
85  * @return boolean Retourne FALSE si erreur, sinon TRUE
86  */
87  function ip_delete($id) {
88  global $db, $cuid;
89  $id=intval($id);
90 
91  $db->query("SELECT id FROM authorised_ip_affected where authorised_ip_id ='$id';");
92  while ($db->next_record()) {
93  $this->ip_affected_delete($db->f('id'));
94  }
95  if (! $db->query("delete from authorised_ip where id='$id' and ( uid='$cuid' or uid=0) limit 1;") ) {
96  echo "query failed: ".$db->Error;
97  return false;
98  }
99  return true;
100  }
101 
102  /*
103  * Liste les IP et subnet authorisés
104  * pour une classe donnée
105  *
106  * @param string $s classe concernée
107  * @return array Retourne un tableau
108  */
109  function get_allowed($s) {
110  global $db, $cuid;
111  if (! $db->query("select ai.ip, ai.subnet, ai.infos, aia.parameters from authorised_ip ai, authorised_ip_affected aia where aia.protocol='$s' and aia.authorised_ip_id = ai.id and ai.uid='$cuid';") ) {
112  echo "query failed: ".$db->Error;
113  return false;
114  }
115  $r=Array();
116  while ($db->next_record()) {
117  $r[]=Array("ip"=>$db->f("ip"), "subnet"=>$db->f("subnet"), "infos"=>$db->f("infos"), "parameters"=>$db->f("parameters"));
118  }
119  return $r;
120  }
121 
122  function is_wl($ip) {
123  global $db;
124  if (! $db->query("select ai.ip, ai.subnet from authorised_ip ai where ai.uid='0';") ) {
125  echo "query failed: ".$db->Error;
126  return false;
127  }
128  while ($db->next_record()) {
129  if ( $this->is_in_subnet($ip, $db->f('ip'), $db->f('subnet') ) ) return true;
130  }
131  return false;
132  }
133 
134  /*
135  * Retourne si l'ip appartient au subnet.
136  *
137  */
138  function is_in_subnet($o, $ip, $sub) {
139  $o = inet_pton($o);
140  $ip = inet_pton($ip);
141  $sub = pow(2, $sub);
142 
143  if ( $o >= $ip && $o <= ($ip+$sub) ) return true;
144  return false;
145  }
146 
147  /*
148  * Sauvegarde une IP dans les IP TOUJOURS authorisée
149  *
150  * @param integer $id id de la ligne à modifier. Si vide ou
151  * égal à 0, alors c'est une insertion
152  * @param string $ipsub IP (v4 ou v6), potentiellement avec un subnet ( /24)
153  * @param string $infos commentaire pour l'utilisateur
154  * @param integer $uid Si $uid=0 et qu'on est super-admin, insertion avec uid=0
155  * ce qui correspond a une ip toujours authorisée
156  * @return boolean Retourne FALSE si erreur, sinon TRUE
157  */
158  function ip_save_whitelist($id, $ipsub, $infos) {
159  global $mem;
160  if (!$mem->checkRight()) return false;
161  return $this->ip_save($id, $ipsub, $infos, 0);
162  }
163 
164  /*
165  * Sauvegarde une IP dans les IP authorisée
166  *
167  * @param integer $id id de la ligne à modifier. Si vide ou
168  * égal à 0, alors c'est une insertion
169  * @param string $ipsub IP (v4 ou v6), potentiellement avec un subnet ( /24)
170  * @param string $infos commentaire pour l'utilisateur
171  * @param integer $uid Si $uid=0 et qu'on est super-admin, insertion avec uid=0
172  * ce qui correspond a une ip toujours authorisée
173  * @return boolean Retourne FALSE si erreur, sinon TRUE
174  */
175  function ip_save($id, $ipsub, $infos, $uid=null) {
176  global $db, $mem;
177 
178  // If we ask for uid=0, we have to check to be super-user
179  // else, juste use global cuid;
180  if ($uid === 0 && $mem->checkRight() ) {
181  $cuid=0;
182  } else {
183  global $cuid;
184  }
185 
186  $id=intval($id);
187  $infos=mysql_real_escape_string($infos);
188 
189  // Extract subnet from ipsub
190  $tmp=explode('/',$ipsub);
191  $ip=$tmp[0];
192 
193  // Error if $ip not an IP
194  if ( ! checkip($ip) && ! checkipv6($ip) ) {
195  echo "Failed : not an IP address";
196  return false;
197  }
198 
199  // Check the subnet, if not defined, give a /32 or a /128
200  if (isset($tmp[1])) {
201  $subnet=intval($tmp[1]);
202  } else {
203  if ( checkip($ip) ) $subnet=32;
204  else $subnet=128;
205  }
206 
207  // An IPv4 can't have subnet > 32
208  if (checkip($ip) && $subnet > 32 ) $subnet=32;
209 
210  if ($id) { // Update
211  $list_affected = $this->list_affected($id);
212  foreach($list_affected as $k => $v) {
213  $this->call_hooks("authip_on_delete", $k );
214  }
215  if (! $db->query("update authorised_ip set ip='$ip', subnet='$subnet', infos='$infos' where id='$id' and uid='$cuid' ;") ) {
216  echo "query failed: ".$db->Error;
217  return false;
218  }
219  foreach($list_affected as $k => $v) {
220  $this->call_hooks("authip_on_create", $k );
221  }
222  } else { // Insert
223  if (! $db->query("insert into authorised_ip (uid, ip, subnet, infos) values ('$cuid', '$ip', '$subnet', '$infos' );") ) {
224  echo "query failed: ".$db->Error;
225  return false;
226  }
227  }
228  return true;
229  }
230 
231  /*
232  * Fonction appelée par Alternc lors de la suppression d'un utilisateur
233  *
234  * @return boolean Retourne TRUE
235  */
236  function alternc_del_member() {
237  global $cuid,$db;
238  $db->query("SELECT id FROM authorised_ip WHERE uid ='$cuid';");
239  while ($db->next_record()) {
240  $this->ip_delete($db->f('id'));
241  }
242  return true;
243  }
244 
245 
246  /*
247  * Analyse les classes et récupéres les informations
248  * des classes voulant de la restriction IP
249  *
250  * @return array Retourne un tableau compliqué
251  */
252  function get_auth_class() {
253  global $hooks;
254  $authclass=array();
255  $authclass = $hooks->invoke('authip_class');
256 
257  // Je rajoute la class DANS l'objet parce que
258  // ca m'interesse
259  foreach ($authclass as $k => $v) {
260  $authclass[$k]['class']=$k;
261  }
262 
263  return $authclass;
264  }
265 
266  /*
267  * Enregistre ou modifie une affectation ip<=>ressource
268  * Nota : lance des hooks sur la classe correspondante pour
269  * informer de l'édition/création
270  *
271  * @param integer $authorised_ip_id id de l'ip affecté
272  * @param string $protocol nom du protocole (définie dans la classe correspondante)
273  * @param string $parameters information propre au protocole
274  * @param integer $id présent si c'est une édition
275  * @return boolean Retourne FALSE si erreur, sinon TRUE
276  */
277  function ip_affected_save($authorised_ip_id, $protocol, $parameters, $id=null) {
278  global $db;
279  $authorised_ip_id=intval($authorised_ip_id);
280  $protocol=mysql_real_escape_string($protocol);
281  $parameters=mysql_real_escape_string($parameters);
282 
283  if ($id) {
284  $id=intval($id);
285  $this->call_hooks("authip_on_delete", $id );
286  if (! $db->query("update authorised_ip_affected set authorised_ip_id='$authorised_ip_id', protocol='$protocol', parameters='$parameters' where id ='$id' limit 1;") ) {
287  echo "query failed: ".$db->Error;
288  return false;
289  }
290  $this->call_hooks("authip_on_create", $id );
291  } else {
292  if (! $db->query("insert into authorised_ip_affected (authorised_ip_id, protocol, parameters) values ('$authorised_ip_id', '$protocol', '$parameters');") ) {
293  echo "query failed: ".$db->Error;
294  return false;
295  }
296  $this->call_hooks("authip_on_create", mysql_insert_id() );
297  }
298  return true;
299  }
300 
301  /*
302  * Supprime une affectation ip<=>ressource
303  * Nota : lance des hooks dans la classe correspondante
304  * pour informer de la suppression
305  *
306  * @param integer $id id de la ligne à supprimer
307  * @return boolean Retourne FALSE si erreur, sinon TRUE
308  */
309  function ip_affected_delete($id) {
310  global $db;
311  $id=intval($id);
312 
313  // Call hooks
314  $this->call_hooks("authip_on_delete", $id );
315 
316  if (! $db->query("delete from authorised_ip_affected where id='$id' limit 1;") ) {
317  echo "query failed: ".$db->Error;
318  return false;
319  }
320  return true;
321  }
322 
323 
324  /*
325  * Appel les hooks demandé avec en parametres les
326  * affectationt ip<=>ressource dont l'id est en parametre
327  *
328  * @param string $function nom de la fonction a rechercher et appeller dans les classes
329  * @param integer $affectation_id id de l'affectation correspondante
330  * @return boolean Retourne TRUE
331  */
332  function call_hooks($function, $affectation_id) {
333  global $hooks,$err;
334 
335  // On récure l'objet dont on parle
336  $d = $this->list_affected();
337  if (! isset($d[$affectation_id] )) {
338  $err->raise('authip', _("Object not available"));
339  return false;
340  }
341 
342  $affectation = $d[$affectation_id];
343 
344  // On en déduis la classe qui le concerne
345  $e = $this->get_auth_class();
346  if (! isset($e[$affectation['protocol']])) {
347  $err->raise('authip', sprintf(_("Can't identified class for the protocole %s"), $affectation['protocol']));
348  return false;
349  }
350  $c = $e[$affectation['protocol']]['class'];
351 
352  // On appelle le hooks de cette classe
353  $hooks->invoke($function, Array($affectation), Array($c) );
354 
355  return true;
356  }
357 
358  /*
359  * Liste les affectation ip<=>ressource d'un utilisateur
360  *
361  * @return array Retourne un tableau de valeurs
362  */
363  function list_affected($ip_id=null) {
364  global $db, $cuid;
365 
366  $r = array();
367  if ( is_null($ip_id) ) {
368  $db->query("select aia.* from authorised_ip_affected aia, authorised_ip ai where ai.uid='$cuid' and aia.authorised_ip_id = ai.id order by protocol, parameters;");
369  } else {
370  $db->query("select aia.* from authorised_ip_affected aia, authorised_ip ai where ai.uid='$cuid' and aia.authorised_ip_id = '".intval($ip_id)."' order by protocol, parameters;");
371  }
372  while ($db->next_record()) {
373  $r[$db->f('id')]=$db->Record;
374  }
375  return $r;
376  }
377 
378 }; /* Classe m_authip */
379 
380 ?>