Alternc  latest
Alternc logiel libre pour l'hébergement
m_authip.php
Go to the documentation of this file.
1 <?php
2 
3 /*
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 */
20 
21 /**
22  * Authorized-ip class
23  *
24  * @copyright AlternC-Team 2000-2017 https://alternc.com/
25  */
26 class m_authip {
27 
28 
29  /**
30  * Retourne la liste des ip whitelist
31  *
32  * @global m_mem $mem
33  * @return array retourne un tableau indexé des ip de l'utilisateur
34  */
35  function list_ip_whitelist() {
36  global $mem;
37  if (!$mem->checkRight()) {
38  return false;
39  }
40  return $this->list_ip(true);
41  }
42 
43 
44  /**
45  *
46  * @return array
47  */
48  function hook_menu() {
49  $obj = array(
50  'title' => _("FTP Access Security"),
51  'link' => 'ip_main.php',
52  'pos' => 120,
53  );
54 
55  return $obj;
56  }
57 
58 
59  /**
60  * Retourne la liste des ip spécifiées par cet utilisateur
61  *
62  *
63  * @global m_mysql $db
64  * @global m_mem $mem
65  * @global int $cuid
66  * @param boolean $whitelist
67  * @return array Retourne un tableau indexé des ip de l'utilisateur
68  */
69  function list_ip($whitelist = false) {
70  global $db, $mem;
71 
72  if ($whitelist && $mem->checkRight()) {
73  $cuid = 0;
74  } else {
75  global $cuid;
76  }
77 
78  $r = array();
79  $db->query("SELECT * FROM authorised_ip WHERE uid= ? order by ip,subnet;", array($cuid));
80  while ($db->next_record()) {
81  $r[$db->f('id')] = $db->Record;
82  if ((checkip($db->f('ip')) && $db->f('subnet') == 32) ||
83  (checkipv6($db->f('ip')) && $db->f('subnet') == 128)) {
84  $r[$db->f('id')]['ip_human'] = $db->f('ip');
85  } else {
86  $r[$db->f('id')]['ip_human'] = $db->f('ip') . "/" . $db->f('subnet');
87  }
88  }
89  return $r;
90  }
91 
92 
93  /**
94  * Supprime une IP des IP de l'utilisateur
95  * et supprime les droits attaché en cascade
96  *
97  * @param integer $id
98  * @return boolean
99  *
100  * @global m_mysql $db
101  * @global int $cuid
102  * @param int $id id de la ligne à supprimer
103  * @return boolean Retourne FALSE si erreur, sinon TRUE
104  */
105  function ip_delete($id) {
106  global $db, $cuid, $msg;
107  $id = intval($id);
108 
109  $db->query("SELECT id FROM authorised_ip_affected where authorised_ip_id = ?;", array($id));
110  while ($db->next_record()) {
111  $this->ip_affected_delete($db->f('id'));
112  }
113  if (!$db->query("delete from authorised_ip where id= ? and ( uid= ? or uid=0) limit 1;", array($id, $cuid))) {
114  $msg->raise("ERROR", 'authip', _("query failed: " . $db->Error));
115  return false;
116  }
117  return true;
118  }
119 
120 
121  /**
122  * Liste les IP et subnet authorisés
123  * pour une classe donnée
124  *
125  * @global m_mysql $db
126  * @global int $cuid
127  * @param string $s Classe concernée
128  * @return array
129  */
130  function get_allowed($s) {
131  global $db, $cuid, $msg;
132  if (!$db->query("select ai.ip, ai.subnet, ai.infos, aia.parameters from authorised_ip ai, authorised_ip_affected aia where aia.protocol= ? and aia.authorised_ip_id = ai.id and ai.uid= ?;", array($s, $cuid))) {
133  $msg->raise("ERROR", 'authip', _("query failed: " . $db->Error));
134  return false;
135  }
136  $r = Array();
137  while ($db->next_record()) {
138  $r[] = Array("ip" => $db->f("ip"), "subnet" => $db->f("subnet"), "infos" => $db->f("infos"), "parameters" => $db->f("parameters"));
139  }
140  return $r;
141  }
142 
143 
144  /**
145  *
146  * @global m_mysql $db
147  * @param string $ip
148  * @return boolean
149  */
150  function is_wl($ip) {
151  global $db, $msg;
152  if (!$db->query("select ai.ip, ai.subnet from authorised_ip ai where ai.uid='0';")) {
153  $msg->raise("ERROR", 'authip', _("query failed: " . $db->Error));
154  return false;
155  }
156  while ($db->next_record()) {
157  if ($this->is_in_subnet($ip, $db->f('ip'), $db->f('subnet')))
158  return true;
159  }
160  return false;
161  }
162 
163 
164  /**
165  * Retourne si l'ip appartient au subnet.
166  *
167  * @param string $o
168  * @param string $ip
169  * @param string $sub
170  * @return boolean
171  */
172  function is_in_subnet($o, $ip, $sub) {
173  $o = inet_pton($o);
174  $ip = inet_pton($ip);
175  $sub = pow(2, $sub);
176 
177  if ($o >= $ip && $o <= ($ip + $sub)) {
178  return true;
179  }
180  return false;
181  }
182 
183 
184  /**
185  * Sauvegarde une IP dans les IP TOUJOURS authorisée
186  *
187  * @global m_mem $mem
188  */
189  function ip_save_whitelist($id, $ipsub, $infos) {
190  global $mem;
191  if (!$mem->checkRight()) {
192  return false;
193  }
194  return $this->ip_save($id, $ipsub, $infos, 0);
195  }
196 
197 
198  /**
199  * Sauvegarde une IP dans les IP authorisée
200  *
201  * @global m_mysql $db
202  * @global m_mem $mem
203  * @global int $cuid
204  * @param int $id id de la ligne à modifier. Si vide ou
205  * égal à 0, alors c'est une insertion
206  * @param string $ipsub IP (v4 ou v6), potentiellement avec un subnet ( /24)
207  * @param string $infos Commentaire pour l'utilisateur
208  * @param int $uid Si $uid=0 et qu'on est super-admin, insertion avec uid=0
209  * ce qui correspond a une ip toujours authorisée
210  * @return boolean Retourne FALSE si erreur, sinon TRUE
211  *
212  */
213  function ip_save($id, $ipsub, $infos, $uid = null) {
214  global $db, $mem, $msg;
215 
216  // If we ask for uid=0, we have to check to be super-user
217  // else, juste use global cuid;
218  if ($uid === 0 && $mem->checkRight()) {
219  $cuid = 0;
220  } else {
221  global $cuid;
222  }
223 
224  $id = intval($id);
225  $infos = $db->quote(trim($infos));
226 
227  // Extract subnet from ipsub
228  $tmp = explode('/', $ipsub);
229  $ip = $tmp[0];
230 
231  // Error if $ip not an IP
232  if (!checkip($ip) && !checkipv6($ip)) {
233  $msg->raise("ERROR", 'authip', _("Failed : not an IP address"));
234  return false;
235  }
236 
237  // Check the subnet, if not defined, give a /32 or a /128
238  if (isset($tmp[1])) {
239  $subnet = intval($tmp[1]);
240  } else {
241  if (checkip($ip)) {
242  $subnet = 32;
243  } else {
244  $subnet = 128;
245  }
246  }
247 
248  // An IPv4 can't have subnet > 32
249  if (checkip($ip) && $subnet > 32) {
250  $subnet = 32;
251  }
252 
253  if ($id) { // Update
254  $list_affected = $this->list_affected($id);
255  foreach ($list_affected as $k => $v) {
256  $this->call_hooks("authip_on_delete", $k);
257  }
258  if (!$db->query("update authorised_ip set ip= ?, subnet= ?, infos= ? where id= ? and uid=? ;", array($ip, $subnet, $infos, $id, $cuid))) {
259  $msg->raise("ERROR", 'authip', _("query failed: " . $db->Error));
260  return false;
261  }
262  foreach ($list_affected as $k => $v) {
263  $this->call_hooks("authip_on_create", $k);
264  }
265  } else { // Insert
266  if (!$db->query("insert into authorised_ip (uid, ip, subnet, infos) values (?, ?, ?, ?);", array($cuid, $ip, $subnet, $infos))) {
267  $msg->raise("ERROR", 'authip', _("query failed: " . $db->Error));
268  return false;
269  }
270  }
271  return true;
272  }
273 
274 
275  /**
276  * Fonction appelée par Alternc lors de la suppression d'un utilisateur
277  *
278  * @global int $cuid
279  * @global m_mysql $db
280  * @return boolean Retourne TRUE
281  */
282  function alternc_del_member() {
283  global $cuid, $db;
284  $db->query("SELECT id FROM authorised_ip WHERE uid = ?;", array($cuid));
285  while ($db->next_record()) {
286  $this->ip_delete($db->f('id'));
287  }
288  return true;
289  }
290 
291 
292  /**
293  * Analyse les classes et récupéres les informations
294  * des classes voulant de la restriction IP
295  *
296  * @return array Retourne un tableau compliqué
297  */
298  function get_auth_class() {
299  global $hooks;
300  $authclass = $hooks->invoke('authip_class');
301 
302  // Je rajoute la class DANS l'objet parce que
303  // ca m'interesse
304  foreach ($authclass as $k => $v) {
305  $authclass[$k]['class'] = $k;
306  }
307 
308  return $authclass;
309  }
310 
311 
312  /**
313  * Enregistre ou modifie une affectation ip<=>ressource
314  * Nota : lance des hooks sur la classe correspondante pour
315  * informer de l'édition/création
316  *
317  * @global m_mysql $db
318  * @param int $authorised_ip_id id de l'ip affecté
319  * @param string $protocol nom du protocole (définie dans la classe correspondante)
320  * @param string $parameters information propre au protocole
321  * @param int $id $id présent si c'est une édition
322  * @return boolean Retourne FALSE si erreur, sinon TRUE
323  */
324  function ip_affected_save($authorised_ip_id, $protocol, $parameters, $id = null) {
325  global $db, $msg;
326  $authorised_ip_id = intval($authorised_ip_id);
327 
328  if ($id) {
329  $id = intval($id);
330  $this->call_hooks("authip_on_delete", $id);
331  if (!$db->query("update authorised_ip_affected set authorised_ip_id= ?, protocol= ?, parameters= ? where id = ? limit 1;", array($authorised_ip_id, $protocol, $parameters, $id))) {
332  $msg->raise("ERROR", 'authip', _("query failed: " . $db->Error));
333  return false;
334  }
335  $this->call_hooks("authip_on_create", $id);
336  } else {
337  if (!$db->query("insert into authorised_ip_affected (authorised_ip_id, protocol, parameters) values (?, ?, ?);", array($authorised_ip_id, $protocol, $parameters))) {
338  $msg->raise("ERROR", 'authip', _("query failed: " . $db->Error));
339  return false;
340  }
341  $this->call_hooks("authip_on_create", $db->lastid());
342  }
343  return true;
344  }
345 
346 
347  /**
348  * Supprime une affectation ip<=>ressource
349  * Nota : lance des hooks dans la classe correspondante
350  * pour informer de la suppression
351  *
352  * @global m_mysql $db
353  * @param int $id id de la ligne à supprimer
354  * @return boolean Retourne FALSE si erreur, sinon TRUE
355  */
357  global $db, $msg;
358  $id = intval($id);
359 
360  // Call hooks
361  $this->call_hooks("authip_on_delete", $id);
362 
363  if (!$db->query("delete from authorised_ip_affected where id= ? limit 1;", array($id))) {
364  $msg->raise("ERROR", 'authip', _("query failed: " . $db->Error));
365  return false;
366  }
367  return true;
368  }
369 
370 
371  /**
372  * Appel les hooks demandé avec en parametres les
373  * affectationt ip<=>ressource dont l'id est en parametre
374  *
375  * @global m_hooks $hooks
376  * @global m_messages $msg
377  * @param string $function Nom de la fonction a rechercher et appeller dans les classes
378  * @param integer $affectation_id Id de l'affectation correspondante
379  * @return boolean Retourne TRUE
380  */
381  function call_hooks($function, $affectation_id) {
382  global $hooks, $msg;
383 
384  // On récure l'objet dont on parle
385  $d = $this->list_affected();
386  if (!isset($d[$affectation_id])) {
387  $msg->raise("ERROR", 'authip', _("Object not available"));
388  return false;
389  }
390 
391  $affectation = $d[$affectation_id];
392 
393  // On en déduis la classe qui le concerne
394  $e = $this->get_auth_class();
395  if (!isset($e[$affectation['protocol']])) {
396  $msg->raise("ERROR", 'authip', sprintf(_("Can't identified class for the protocole %s"), $affectation['protocol']));
397  return false;
398  }
399  $c = $e[$affectation['protocol']]['class'];
400 
401  // On appelle le hooks de cette classe
402  $hooks->invoke($function, Array($affectation), Array($c));
403 
404  return true;
405  }
406 
407 
408  /**
409  * Liste les affectation ip<=>ressource d'un utilisateur
410  *
411  * @global m_mysql $db
412  * @global int $cuid
413  * @param int $ip_id
414  * @return array Retourne un tableau de valeurs
415  */
416  function list_affected($ip_id = null) {
417  global $db, $cuid;
418 
419  $r = array();
420  if (is_null($ip_id)) {
421  $db->query("select aia.* from authorised_ip_affected aia, authorised_ip ai where ai.uid= ? and aia.authorised_ip_id = ai.id order by protocol, parameters;", array($cuid));
422  } else {
423  $db->query("select aia.* from authorised_ip_affected aia, authorised_ip ai where ai.uid= ? and aia.authorised_ip_id = ? order by protocol, parameters;", array($cuid, intval($ip_id)));
424  }
425  while ($db->next_record()) {
426  $r[$db->f('id')] = $db->Record;
427  }
428  return $r;
429  }
430 
431 } /* Class m_authip */
432 
$hooks
Definition: bootstrap.php:74
global $db
Definition: bootstrap.php:26
$mem
Definition: bootstrap.php:71
$msg
Definition: bootstrap.php:75
$c
Definition: bootstrap.php:47
$cuid
Definition: bootstrap.php:43
$r
Definition: aws_add.php:75
$d
Authorized-ip class.
Definition: m_authip.php:26
ip_delete($id)
Supprime une IP des IP de l'utilisateur et supprime les droits attaché en cascade.
Definition: m_authip.php:105
get_auth_class()
Analyse les classes et récupéres les informations des classes voulant de la restriction IP.
Definition: m_authip.php:298
call_hooks($function, $affectation_id)
Appel les hooks demandé avec en parametres les affectationt ip<=>ressource dont l'id est en parametre...
Definition: m_authip.php:381
list_ip($whitelist=false)
Retourne la liste des ip spécifiées par cet utilisateur.
Definition: m_authip.php:69
ip_save_whitelist($id, $ipsub, $infos)
Sauvegarde une IP dans les IP TOUJOURS authorisée.
Definition: m_authip.php:189
ip_affected_delete($id)
Supprime une affectation ip<=>ressource Nota : lance des hooks dans la classe correspondante pour inf...
Definition: m_authip.php:356
list_ip_whitelist()
Retourne la liste des ip whitelist.
Definition: m_authip.php:35
is_wl($ip)
Definition: m_authip.php:150
ip_save($id, $ipsub, $infos, $uid=null)
Sauvegarde une IP dans les IP authorisée.
Definition: m_authip.php:213
is_in_subnet($o, $ip, $sub)
Retourne si l'ip appartient au subnet.
Definition: m_authip.php:172
alternc_del_member()
Fonction appelée par Alternc lors de la suppression d'un utilisateur.
Definition: m_authip.php:282
get_allowed($s)
Liste les IP et subnet authorisés pour une classe donnée.
Definition: m_authip.php:130
list_affected($ip_id=null)
Liste les affectation ip<=>ressource d'un utilisateur.
Definition: m_authip.php:416
hook_menu()
Definition: m_authip.php:48
ip_affected_save($authorised_ip_id, $protocol, $parameters, $id=null)
Enregistre ou modifie une affectation ip<=>ressource Nota : lance des hooks sur la classe corresponda...
Definition: m_authip.php:324
$sub
checkipv6($ip)
Check that $ip is a correct ipv6 ip.
Definition: functions.php:221
checkip($ip)
Check that $ip is a correct 4 Dotted ip.
Definition: functions.php:210
$uid
if(!isset($is_include)) if(! $key &&! $crt) $id
if(in_array($action, array('start', 'stop', 'monit'))) switch($action) if($lxc->error &&! $script) $infos
Definition: vm.php:32