Store IP as uint instead of strings.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 2 Mar 2008 19:40:03 +0000 (20:40 +0100)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 2 Mar 2008 19:40:03 +0000 (20:40 +0100)
Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
classes/corelogger.php
include/xorg.misc.inc.php
modules/admin.php
modules/search/classes.inc.php
plugins/modifier.uint_to_ip.php [new file with mode: 0644]
templates/admin/logger-view.tpl
upgrade/0.9.16/04_ip.sql [new file with mode: 0644]

index baadf79..8d06056 100644 (file)
@@ -77,7 +77,7 @@ class CoreLogger
 
         XDB::execute("INSERT INTO logger.sessions
                          SET uid={?}, host={?}, ip={?}, forward_ip={?}, forward_host={?}, browser={?}, suid={?}, flags={?}",
-                     $uid, $host, $ip, $forward_ip, $forward_host, $browser, $suid, $proxy);
+                     $uid, $host, ip_to_uint($ip), ip_to_uint($forward_ip), $forward_host, $browser, $suid, $proxy);
         if ($forward_ip) {
             $this->proxy_ip = $ip;
             $this->proxy_host = $host;
index 5c72a2a..c0afbad 100644 (file)
@@ -228,6 +228,35 @@ function make_forlife($prenom, $nom, $promo)
     return $forlife;
 }
 
+/** Convert ip to uint (to store it in a database)
+ */
+function ip_to_uint($ip)
+{
+    $part = explode('.', $ip);
+    $v = 0;
+    $fact = 0x1000000;
+    for ($i = 0 ; $i < 4 ; ++$i) {
+        $v += $fact * $part[$i];
+        $fact >>= 8;
+    }
+    return $v;
+}
+
+/** Convert uint to ip (to build a human understandable ip)
+ */
+function uint_to_ip($uint)
+{
+    return sprintf('%d.%d.%d.%d', ($uint / 16777216) % 0xff,
+                                  ($uint / 65536) & 0xff,
+                                  ($uint / 256)  & 0xff,
+                                  ($uint / 1.0) & 0xff);
+}
+
+
+/******************************************************************************
+ * Security functions
+ *****************************************************************************/
+
 function check_ip($level)
 {
     if (empty($_SERVER['REMOTE_ADDR'])) {
@@ -240,7 +269,7 @@ function check_ip($level)
         }
         $ips[] = $_SERVER['REMOTE_ADDR'];
         foreach ($ips as &$ip) {
-            $ip = "ip LIKE " . XDB::escape($ip);
+            $ip = "ip = " . ip_to_uint($ip);
         }
         $res = XDB::query('SELECT  state
                              FROM  ip_watch
@@ -301,6 +330,11 @@ function send_warning_mail($title)
     $mailer->send();
 }
 
+
+/******************************************************************************
+ * Dynamic configuration update/edition stuff
+ *****************************************************************************/
+
 function update_NbIns()
 {
     global $globals;
index 47f996d..c2eceb7 100644 (file)
@@ -1039,19 +1039,20 @@ class AdminModule extends PLModule
             if (trim(Post::v('ipN')) != '') {
                 Xdb::execute('INSERT IGNORE INTO ip_watch (ip, state, detection, last, uid, description)
                                           VALUES ({?}, {?}, CURDATE(), NOW(), {?}, {?})',
-                             trim(Post::v('ipN')), Post::v('stateN'), S::i('uid'), Post::v('descriptionN'));
+                             ip_to_uint(trim(Post::v('ipN'))), Post::v('stateN'), S::i('uid'), Post::v('descriptionN'));
             };
             break;
 
         case 'edit':
             Xdb::execute('UPDATE ip_watch
                              SET state = {?}, last = NOW(), uid = {?}, description = {?}
-                           WHERE ip = {?}', Post::v('stateN'), S::i('uid'), Post::v('descriptionN'), Post::v('ipN'));
+                           WHERE ip = {?}', Post::v('stateN'), S::i('uid'), Post::v('descriptionN'),
+                          ip_to_uint(Post::v('ipN')));
             break;
 
         default:
             if ($action == 'delete' && !is_null($ip)) {
-                Xdb::execute('DELETE FROM emails_watch WHERE ip = {?}', $ip);
+                Xdb::execute('DELETE FROM ip_watch WHERE ip = {?}', ip_to_uint($ip));
             }
         }
         if ($action != 'create' && $action != 'edit') {
@@ -1060,10 +1061,14 @@ class AdminModule extends PLModule
         $page->assign('action', $action);
 
         if ($action == 'list') {
-            $sql = "SELECT  w.ip, IF(w.ip = s.ip, s.host, s.forward_host), w.detection, w.state, a.alias AS forlife
+            $sql = "SELECT  w.ip, IF(s.ip IS NULL,
+                                     IF(w.ip = s2.ip, s2.host, s2.forward_host),
+                                     IF(w.ip = s.ip, s.host, s.forward_host)),
+                             w.detection, w.state, a.alias AS forlife
                       FROM  ip_watch        AS w
-                 LEFT JOIN  logger.sessions AS s ON (s.ip = w.ip OR s.forward_ip = w.ip)
-                 LEFT JOIN  aliases         AS a ON (a.id = s.uid AND a.type = 'a_vie')
+                 LEFT JOIN  logger.sessions AS s  ON (s.ip = w.ip)
+                 LEFT JOIN  logger.sessions AS s2 ON (s2.forward_ip = w.ip)
+                 LEFT JOIN  aliases         AS a  ON (a.id = s.uid AND a.type = 'a_vie')
                   GROUP BY  w.ip, a.alias
                   ORDER BY  w.state, w.ip, a.alias";
             $it = Xdb::iterRow($sql);
@@ -1071,6 +1076,7 @@ class AdminModule extends PLModule
             $table = array();
             $props = array();
             while (list($ip, $host, $date, $state, $forlife) = $it->next()) {
+                $ip = uint_to_ip($ip);
                 if (count($props) == 0 || $props['ip'] != $ip) {
                     if (count($props) > 0) {
                         $table[] = $props;
@@ -1098,7 +1104,7 @@ class AdminModule extends PLModule
                      WHERE  w.ip = {?}
                   GROUP BY  a2.alias
                   ORDER BY  a2.alias";
-            $it = Xdb::iterRow($sql, $ip);
+            $it = Xdb::iterRow($sql, ip_to_uint($ip));
 
             $props = array();
             while (list($detection, $state, $last, $description, $edit, $forlife, $host) = $it->next()) {
index a1fc847..f6922bd 100644 (file)
@@ -307,7 +307,7 @@ class QuickSearch extends SField
             $where[] = 'ems.email = ' . XDB::escape($this->email);
         }
         if (!empty($this->ip)) {
-            $ip = XDB::escape($this->ip);
+            $ip = ip_to_uint($this->ip);
             $where[] = "( ls.ip = $ip OR ls.forward_ip = $ip )";
         }
 
diff --git a/plugins/modifier.uint_to_ip.php b/plugins/modifier.uint_to_ip.php
new file mode 100644 (file)
index 0000000..a7076fa
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2008 Polytechnique.org                              *
+ *  http://opensource.polytechnique.org/                                   *
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program; if not, write to the Free Software            *
+ *  Foundation, Inc.,                                                      *
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
+ ***************************************************************************/
+
+function smarty_modifier_uint_to_ip($string)
+{
+    return uint_to_ip($string);
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index 631f269..aefc855 100644 (file)
 {if $session.forward_ip}
 <tr class="pair">
   <td class="titre">Hôte</td>
-  <td><em>{$session.forward_host}</em> <tt>IP: {$session.forward_ip}</tt></td>
+  <td><em>{$session.forward_host}</em> <tt>IP: {$session.forward_ip|uint_to_ip}</tt></td>
 </tr>
 <tr class="pair">
   <td class="titre">Proxy</td>
-  <td><em>{$session.host}</em> <tt>IP: {$session.ip}</tt></td>
+  <td><em>{$session.host}</em> <tt>IP: {$session.ip|uint_to_ip}</tt></td>
 </tr>
 {else}
 <tr class="pair">
   <td class="titre">{if $session.flags}Proxy{else}Hôte{/if}</td>
-  <td><em>{$session.host}</em> <tt>IP: {$session.ip}</tt></td>
+  <td><em>{$session.host}</em> <tt>IP: {$session.ip|uint_to_ip}</tt></td>
 </tr>
 {/if}
 <tr class="impair">
diff --git a/upgrade/0.9.16/04_ip.sql b/upgrade/0.9.16/04_ip.sql
new file mode 100644 (file)
index 0000000..4fcd93a
--- /dev/null
@@ -0,0 +1,42 @@
+USE logger;
+
+ALTER TABLE sessions
+ADD COLUMN ip2 INT(11) UNSIGNED NOT NULL,
+ADD COLUMN forward_ip2 INT(11) UNSIGNED DEFAULT NULL;
+
+UPDATE sessions
+   SET ip2 = SUBSTRING_INDEX(ip, ".", 1) * 256 * 256 * 256
+           + SUBSTRING_INDEX(SUBSTRING_INDEX(ip, ".", 2), ".", -1) * 256 * 256
+           + SUBSTRING_INDEX(SUBSTRING_INDEX(ip, ".", 3), ".", -1) * 256
+           + SUBSTRING_INDEX(ip, ".", -1),
+       forward_ip2 = SUBSTRING_INDEX(forward_ip, ".", 1) * 256 * 256 * 256
+                   + SUBSTRING_INDEX(SUBSTRING_INDEX(forward_ip, ".", 2), ".", -1) * 256 * 256
+                   + SUBSTRING_INDEX(SUBSTRING_INDEX(forward_ip, ".", 3), ".", -1) * 256
+                   + SUBSTRING_INDEX(forward_ip, ".", -1);
+
+ALTER TABLE sessions
+DROP COLUMN ip,
+DROP COLUMN forward_ip,
+CHANGE COLUMN ip2 ip INT(11) UNSIGNED NOT NULL,
+CHANGE COLUMN forward_ip2 forward_ip INT(11) UNSIGNED DEFAULT NULL,
+ADD INDEX ip (ip),
+ADD INDEX forward_ip (forward_ip);
+
+USE x4dat;
+
+ALTER TABLE ip_watch
+ADD COLUMN ip2 INT(11) UNSIGNED NOT NULL;
+
+UPDATE ip_watch
+   SET ip2 = SUBSTRING_INDEX(ip, ".", 1) * 256 * 256 * 256
+           + SUBSTRING_INDEX(SUBSTRING_INDEX(ip, ".", 2), ".", -1) * 256 * 256
+           + SUBSTRING_INDEX(SUBSTRING_INDEX(ip, ".", 3), ".", -1) * 256
+           + SUBSTRING_INDEX(ip, ".", -1);
+
+ALTER TABLE ip_watch
+DROP PRIMARY KEY,
+DROP COLUMN ip,
+CHANGE COLUMN ip2 ip INT(11) UNSIGNED NOT NULL,
+ADD PRIMARY KEY ip (ip);
+
+# vim:set syntax=mysql: