homogenized $remote_addr and $remote_addr_full usage, add ban_list, reload() method...
authorMatteo Nastasi (mop) <nastasi@alternativeoutput.it>
Mon, 14 Jul 2014 16:10:30 +0000 (18:10 +0200)
committerMatteo Nastasi (mop) <nastasi@alternativeoutput.it>
Mon, 14 Jul 2014 16:10:30 +0000 (18:10 +0200)
web/Obj/brisk.conf-templ.pho
web/Obj/brisk.phh
web/Obj/sac-a-push.phh
web/briskin5/Obj/briskin5.phh
web/briskin5/index_wr.php
web/index.php
web/index_wr.php
web/spush/brisk-spush.php

index a9d26ba..034dee7 100644 (file)
@@ -83,7 +83,8 @@ $G_poll_entries = array( array( 'id' => 'din', 'cont' => 'Dinner room'),
                          array( 'id' => 'bat', 'cont' => 'Bath room'),
                          array( 'id' => 'coo', 'cont' => 'Cooking room') );
 
-$G_black_list = array();
+$G_ban_list = array();   // each element in the form "IP/<MSBs_number>" i.e. "192.15.21.4/24"
+$G_black_list = array(); // each element in the form "IP/<MSBs_number>" i.e. "192.15.21.4/24"
 
 
 // this is the prefix path to remove from backtrace
index 437389a..d9c270c 100644 (file)
@@ -577,6 +577,33 @@ function xcapemesg($s)
 }
 
 
+class IPClass {
+    var $addr;
+    var $mask;
+
+    function IPClass($ipset)
+    {
+        //split
+        $elem = split("/", $ipset, 2);
+        $addr = $elem[0];
+        $mask = (int)$elem[1];
+
+        //convert mask
+
+        $this->mask = ((1<<($mask))-1) << (32 - $mask);
+        $this->addr = ip2long($addr) & $this->mask;
+
+        fprintf(STDERR, "New ipclass: %x (%x)\n", $this->addr, $this->mask);
+    }
+
+    function match($ip)
+    {
+        fprintf(STDERR, "IP: %x, ADDR: %x, MASK: %x -> (%d)\n",
+                $ip, $this->addr, $this->mask, ((ip2long($ip) & $this->mask) == $this->addr));
+        return (($ip & $this->mask) == $this->addr);
+    }
+}
+
 class Vect {
     function Vect($a)
     {
@@ -949,7 +976,10 @@ class Brisk
     var $step; // current step of the comm array
     var $garbage_timeout;
     var $shm_sz;
-    
+
+    var $ban_list;  // ban list (authized allowed)
+    var $black_list;  // black list (anti-dos, noone allowed)
+
     var $delay_mgr;
 
     public static $sess_cur;
@@ -959,13 +989,14 @@ class Brisk
     }
 
     // constructor
-    static function create($crystal_filename)
-    {
+    static function create($crystal_filename, $ban_list, $black_list) {
         if (($brisk_ser = @file_get_contents($crystal_filename)) != FALSE) {
             if (($brisk = unserialize($brisk_ser)) != FALSE) {
                 fprintf(STDERR, "ROOM FROM FILE\n");
                 rename($crystal_filename, $crystal_filename.".old");
 
+                $brisk->reload();
+
                 return($brisk);
             }
         }
@@ -977,7 +1008,15 @@ class Brisk
         $thiz->user  = array();
         $thiz->table = array();
         $thiz->match = array();
-        
+
+        $thiz->ban_list = NULL;
+        $thiz->black_list = NULL;
+
+        fprintf(STDERR, "PRE IPCLASS_UPDATE (%d, %d)\n", count($ban_list), count($black_list));
+        $thiz->ipclass_update('ban_list', $ban_list);
+        $thiz->ipclass_update('black_list', $black_list);
+        fprintf(STDERR, "POST IPCLASS_UPDATE %d %d\n", count($thiz->ban_list), count($thiz->black_list));
+
         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
             $thiz->user[$i] = User::create($thiz, $i, "", "");
         }
@@ -1009,6 +1048,115 @@ class Brisk
         return ($thiz);
     }
 
+    function ipclass_update($ip_out_s, $ip_in)
+    {
+        fprintf(STDERR, "N_IN: %d\n", count($ip_in));
+
+        $ip_out = &$this->$ip_out_s;
+
+        // if already set clean the ban_list property
+        if ($ip_out) {
+            $ct = count($ip_out);
+            for ($i = 0 ; $i < $ct ; $i++) {
+                unset($ip_out[$i]);
+            }
+            unset($ip_out);
+        }
+
+        $ip_out = array();
+        for ($i = 0 ; $i < count($ip_in) ; $i++) {
+            $ip_out[$i] = new IPClass($ip_in[$i]);
+        }
+    }
+
+    function reload($ban_list, $black_list)
+    {
+        fprintf(STDERR, "RELOAD STUFF (%d)(%d)\n", count($ban_list), count($black_list));
+
+        $this->ipclass_update("ban_list", $ban_list);
+        $this->ipclass_update("black_list", $black_list);
+
+        $this->banned_kickoff();
+        $this->garbage_manager(TRUE);
+    }
+
+    function banned_kickoff()
+    {
+        $is_ban = FALSE;
+
+        for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
+            $table_cur = $this->table[$table_idx];
+            // if the table is complete and exists we check users IP
+
+            if ($table_cur->player_n == PLAYERS_N) {
+                if (isset($this->match[$table_idx]) &&
+                    $table_cur->table_token == $bin5->table_token) {
+                    log_main("PLAYERS == N TABLE ".$table_idx);
+
+                    $bin5 = $this->match[$table_idx];
+
+                    $is_ban |= $bin5->banned_kickoff();
+                }
+            }
+        }
+
+        for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
+            $user_cur = $this->user[$i];
+
+            if ($user_cur->sess == "")
+                continue;
+
+            // check if the IP is blacklisted
+            if ($this->black_check($user_cur->ip)) {
+                $user_cur->lacc = 0;
+                $is_ban = TRUE;
+                continue;
+            }
+
+            // if authorized not check if banlisted
+            if ($user_cur->flags & USER_FLAG_AUTH) {
+                continue;
+            }
+
+            if ($this->ban_check($user_cur->ip)) {
+                $user_cur->lacc = 0;
+                $is_ban = TRUE;
+            }
+        }
+
+        return $is_ban;
+    }
+
+    function ban_check($ip_str)
+    {
+        $ip = ip2long($ip_str);
+        fprintf(STDERR, "Brisk::ban_check %d\n", count($this->ban_list));
+        for ($i = 0 ; $i < count($this->ban_list) ; $i++) {
+            fprintf(STDERR, "ban_list[%d] = %x (%x)\n", $i,
+                    $this->ban_list[$i]->addr, $this->ban_list[$i]->mask);
+            if ($this->ban_list[$i]->match($ip)) {
+                fprintf(STDERR, "\n\nMATCHA!\n\n");
+                return(TRUE);
+            }
+        }
+        return (FALSE);
+    }
+
+    function black_check($ip_str)
+    {
+        $ip = ip2long($ip_str);
+        fprintf(STDERR, "Brisk::black_check %d\n", count($this->black_list));
+        for ($i = 0 ; $i < count($this->black_list) ; $i++) {
+            fprintf(STDERR, "black_list[%d] = %x (%x)\n", $i,
+                   $this->black_list[$i]->addr, $this->black_list[$i]->mask);
+            if ($this->black_list[$i]->match($ip)) {
+                fprintf(STDERR, "\n\nMATCHA!\n\n");
+                return(TRUE);
+            }
+        }
+        return (FALSE);
+    }
+
   function garbage_manager($force)
   {
     GLOBAL $G_lang, $mlang_brisk, $G_base;
@@ -2140,7 +2288,6 @@ class Brisk
       $this->user[$idx]->ip = $ip;
 
       $this->user[$idx]->rec = $authenticate;
-      fprintf(STDERR, "MOP: [%s]\n", $authenticate->supp_comp);
       $this->user[$idx]->flags = $user_type;
       $this->user[$idx]->flags |= ($authenticate != FALSE ? USER_FLAG_AUTH : 0x00);
       $this->user[$idx]->flags |= ( ($pass != FALSE && $bdb == FALSE) ? USER_FLAG_DBFAILED : 0x00);
@@ -2347,9 +2494,17 @@ class Brisk
 
   function request_mgr(&$s_a_p, $header, &$header_out, &$new_socket, $path, $addr, $get, $post, $cookie)
   {
-      GLOBAL $G_black_list;
+      GLOBAL $G_ban_list, $G_black_list;
 
       printf("NEW_SOCKET (root): %d PATH [%s]\n", intval($new_socket), $path);
+      $remote_addr = addrtoipv4($addr);
+
+          fprintf(STDERR, "\n\n\n PRE_BLACK_CHECK \n\n\n");
+      if ($this->black_check($remote_addr)) {
+          // TODO: waiting async 5 sec before close
+          fprintf(STDERR, "\n\n\n BLACK_CHECK \n\n\n");
+          return (FALSE);
+      }
 
       $enc = get_encoding($header);
       if (isset($header['User-Agent'])) {
index b184fb4..44ef8ad 100644 (file)
@@ -2,7 +2,7 @@
 /*
  *  brisk - Obj/sac-a-push.phh
  *
- *  Copyright (C) 2012 Matteo Nastasi
+ *  Copyright (C) 2012-2014 Matteo Nastasi
  *                          mailto: nastasi@alternativeoutput.it 
  *                                  matteo.nastasi@milug.org
  *                          web: http://www.alternativeoutput.it
@@ -32,7 +32,7 @@ declare(ticks = 1);
 
 function global_dump()
 {
-    GLOBAL $G_alarm_passwd, $G_black_list, $G_btrace_pref_sub, $G_dbauth;
+    GLOBAL $G_alarm_passwd, $G_ban_list, $G_black_list, $G_btrace_pref_sub, $G_dbauth;
     GLOBAL $G_dbpfx, $G_donors_all, $G_donors_cur, $G_is_local, $G_lang;
     GLOBAL $G_poll_entries, $G_poll_name, $G_poll_title, $G_proxy_white_list;
     GLOBAL $G_room_roadmap, $G_shutdown, $G_sidebanner, $G_sidebanner2;
@@ -43,6 +43,7 @@ function global_dump()
     GLOBAL $G_with_topbanner;
 
     fprintf(STDERR, "G_alarm_passwd = [%s]\n", print_r($G_alarm_passwd, TRUE));
+    fprintf(STDERR, "G_ban_list = [%s]\n", print_r($G_ban_list, TRUE));
     fprintf(STDERR, "G_black_list = [%s]\n", print_r($G_black_list, TRUE));
     fprintf(STDERR, "G_btrace_pref_sub = [%s]\n", print_r($G_btrace_pref_sub, TRUE));
     fprintf(STDERR, "G_dbauth = [%s]\n", print_r($G_dbauth, TRUE));
@@ -621,7 +622,7 @@ class Sac_a_push {
     {
         GLOBAL $DOCUMENT_ROOT, $HTTP_HOST;
 
-        GLOBAL $G_alarm_passwd, $G_black_list, $G_btrace_pref_sub, $G_dbauth;
+        GLOBAL $G_alarm_passwd, $G_ban_list, $G_black_list, $G_btrace_pref_sub, $G_dbauth;
         GLOBAL $G_dbpfx, $G_donors_all, $G_donors_cur, $G_is_local, $G_lang;
         GLOBAL $G_poll_entries, $G_poll_name, $G_poll_title, $G_proxy_white_list;
         GLOBAL $G_room_roadmap, $G_shutdown, $G_sidebanner, $G_sidebanner2;
@@ -797,7 +798,7 @@ class Sac_a_push {
                                 $line = trim($buf);
                                 if ($line == "reload") {
                                     require("$DOCUMENT_ROOT/Etc/".BRISK_CONF);
-
+                                    $this->app->reload($G_ban_list, $G_black_list);
                                     global_dump();
                                 }
                                 else if ($line == "shutdown" || $line == "sd") {
index 46fb944..ee69b35 100644 (file)
@@ -1228,7 +1228,32 @@ class Bin5 {
 
         return (FALSE);
     }
+    function banned_kickoff()
+    {
+        $is_ban = FALSE;
+
+        for ($i = 0 ; $i < BIN5_MAX_PLAYERS ; $i++) {
+            $user_cur = $this->user[$i];
+
+            // check if the IP is blacklisted
+            if ($this->brisk->black_check($user_cur->ip)) {
+                $user_cur->lacc = 0;
+                $is_ban = TRUE;
+                continue;
+            }
 
+            // if authorized not check if banlisted
+            if ($user_cur->flags & USER_FLAG_AUTH) {
+                continue;
+            }
+
+            if ($this->brisk->ban_check($user_cur->ip)) {
+                $user_cur->lacc = 0;
+                $is_ban = TRUE;
+            }
+        }
+        return ($is_ban);
+    }
 
     function garbage_manager($force)
     {
@@ -1449,7 +1474,7 @@ class Bin5 {
 
     static function request_mgr(&$s_a_p, $header, &$header_out, &$new_socket, $path, $addr, $get, $post, $cookie)
     {
-        GLOBAL $G_black_list;
+        GLOBAL $G_ban_list, $G_black_list;
 
         printf("NEW_SOCKET (root): %d\n", intval($new_socket));
 
index 3391a55..7a6e6ad 100644 (file)
@@ -40,15 +40,10 @@ require_once("Obj/briskin5.phh");
  */
 function bin5_index_wr_main(&$bin5, $remote_addr_full, $get, $post, $cookie)
 {
-    GLOBAL $G_base, $G_dbasetype, $G_black_list;
+    GLOBAL $G_base, $G_dbasetype, $G_ban_list, $G_black_list;
 
     $remote_addr = addrtoipv4($remote_addr_full);
 
-    if (array_search($remote_addr, $G_black_list) !== FALSE) {
-        // TODO: waiting async 5 sec before close
-        return (FALSE);
-    }
-
     $curtime = time();
     if ($bin5 == NULL) {
         return FALSE;
@@ -77,7 +72,8 @@ function bin5_index_wr_main(&$bin5, $remote_addr_full, $get, $post, $cookie)
         return FALSE;
     }
     $bin5->brisk->sess_cur_set($user->sess);
-    if (array_search($user->ip, $G_black_list) !== FALSE) {
+    if (!($user->flags & USER_FLAG_AUTH) &&
+        $bin5->brisk->ban_check($user->ip)) {
         // TODO: waiting async 5 sec before close
         return (FALSE);
     }
index 6ee1d74..feaa28e 100644 (file)
@@ -237,7 +237,7 @@ function poll_dom() {
     return '';
 }
 
-function index_main(&$brisk, $transp_type, &$header_out, $addr, $get, $post, $cookie)
+function index_main(&$brisk, $transp_type, &$header_out, $remote_addr_full, $get, $post, $cookie)
 {
     GLOBAL $G_with_donors, $G_donors_cur, $G_donors_all;
     GLOBAL $G_with_topbanner, $G_topbanner, $G_is_local;
@@ -258,8 +258,10 @@ function index_main(&$brisk, $transp_type, &$header_out, $addr, $get, $post, $co
     if (($table_token = gpcs_var('table_idx', $get, $post, $cookie)) === FALSE)
         unset ($table_token);
 
+    $remote_addr = addrtoipv4($remote_addr_full);
+
     // Use of proxies isn't allowed.
-    if (!$G_is_local && is_proxy($addr)) {
+    if (!$G_is_local && is_proxy($remote_addr)) {
         return FALSE;
     }
 
@@ -298,15 +300,22 @@ function index_main(&$brisk, $transp_type, &$header_out, $addr, $get, $post, $co
       if ($ACTION == "login" && isset($name)) {
           log_main("pre garbage_manager DUE");
 
-          if (isset($pass_private) == FALSE) {
+          if (isset($pass_private) == FALSE || $pass_private == "") {
               $pass_private = FALSE;
+
+              $banned = FALSE;
+              if ($brisk->ban_check($remote_addr)) {
+                  // TODO: find a way to add a nonblocking sleep(5) here
+                  $banned = TRUE;
+                  $idx = -1;
+              }
           }
 
           $brisk->garbage_manager(TRUE);
           /* try login */
 
-          $ipv4addr = addrtoipv4($addr);
-          if (($user = $brisk->add_user(&$sess, &$idx, $name, $pass_private, $ipv4addr, $cookie)) != FALSE) {
+          if ($banned == FALSE &&
+              ($user = $brisk->add_user(&$sess, &$idx, $name, $pass_private, $remote_addr, $cookie)) != FALSE) {
               $brisk->sess_cur_set($user->sess);
               $ACTION = "room";
               if ($idx < 0) {
@@ -314,7 +323,7 @@ function index_main(&$brisk, $transp_type, &$header_out, $addr, $get, $post, $co
                   $is_login = TRUE;
               }
 
-              log_legal($curtime, $ipv4addr, $user, "STAT:LOGIN", '');
+              log_legal($curtime, $remote_addr, $user, "STAT:LOGIN", '');
 
               // recovery lost game
               if ($user->stat == "table") {
index 9fed7de..6d5484b 100644 (file)
@@ -120,12 +120,12 @@ define('LICMGR_CHO_AFTER',  2);
 function index_wr_main(&$brisk, $remote_addr_full, $get, $post, $cookie)
 {
     GLOBAL $G_domain, $G_webbase, $G_mail_seed;
-    GLOBAL $G_shutdown, $G_alarm_passwd, $G_black_list, $G_lang, $G_room_help, $G_room_about;
+    GLOBAL $G_shutdown, $G_alarm_passwd, $G_ban_list, $G_black_list, $G_lang, $G_room_help, $G_room_about;
     GLOBAL $G_room_passwdhowto, $mlang_indwr;
     GLOBAL $G_tos_vers;
-    $remote_addr = addrtoipv4($remote_addr_full);
 
     log_load("index_wr.php");
+    $remote_addr = addrtoipv4($remote_addr_full);
 
     if (($mesg = gpcs_var('mesg', $get, $post, $cookie)) === FALSE) 
         unset($mesg);
@@ -142,13 +142,6 @@ function index_wr_main(&$brisk, $remote_addr_full, $get, $post, $cookie)
     /*
      *  MAIN
      */
-
-    /* if the IP is banned, exit without do nothing */
-    if (array_search($remote_addr, $G_black_list) !== FALSE) {
-        // TODO: find a way to add a nonblocking sleep(5) here
-        return (FALSE);
-    }
-
     $is_spawn = FALSE;
 
     log_wr(0, 'index_wr.php: COMM: '.xcapemesg($mesg));
@@ -240,7 +233,8 @@ function index_wr_main(&$brisk, $remote_addr_full, $get, $post, $cookie)
     // LACC UPDATED
     $user->lacc = $curtime;
 
-    if (array_search($user->ip, $G_black_list) !== FALSE) {
+    if (!($user->flags & USER_FLAG_AUTH) &&
+        $brisk->ban_check($user->ip)) {
         // TODO: find a way to add a nonblocking sleep(5) here
         return (FALSE);
     }
index 5a318dc..cbbce76 100755 (executable)
@@ -42,9 +42,11 @@ require_once($G_base."briskin5/index_wr.php");
 
 function main($argv)
 {
+    GLOBAL $G_ban_list, $G_black_list;
+
     pid_save();
     do {
-        if (($brisk = Brisk::create(LEGAL_PATH."/brisk-crystal.data")) == FALSE) {
+        if (($brisk = Brisk::create(LEGAL_PATH."/brisk-crystal.data", $G_ban_list, $G_black_list)) == FALSE) {
             log_crit("Brisk::create failed");
             $ret = 1;
             break;