Merge branch 'ipclass-ban' into certified_ipclass-ban
authorMatteo Nastasi (mop) <nastasi@alternativeoutput.it>
Mon, 14 Jul 2014 16:29:31 +0000 (18:29 +0200)
committerMatteo Nastasi (mop) <nastasi@alternativeoutput.it>
Mon, 14 Jul 2014 16:29:31 +0000 (18:29 +0200)
1  2 
web/Obj/brisk.phh
web/index.php

diff --combined web/Obj/brisk.phh
@@@ -28,8 -28,7 +28,8 @@@ define('FTOK_PATH', "/var/lib/brisk")
  define('LEGAL_PATH', "/tmp/legal_brisk");
  define('PROXY_PATH', "/var/lib/brisk_proxy");
  define('TABLES_N', 36);
 -define('TABLES_AUTH_N', 4);
 +define('TABLES_AUTH_N', 8);
 +define('TABLES_CERT_N', 4);
  define('PLAYERS_N', 3);
  define('MAX_POINTS', 5);
  define('MAX_PLAYERS', (20 + (PLAYERS_N * TABLES_N)));
@@@ -151,10 -150,10 +151,10 @@@ $mlang_brisk = array( 'btn_backstand'=
  $G_lng = langtolng($G_lang);
  
  $G_all_points = array( 11,10,4,3,2, 0,0,0,0,0 );
- $G_brisk_version = "4.14.2";
+ $G_brisk_version = "4.14.3";
  
  /* MLANG: ALL THE INFO STRINGS IN brisk.phh */
- $root_wellarr = array( 'it' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: nuovo sistema di registrazione degli utenti, aggiunto reinvio dell\' email di verifica',
+ $root_wellarr = array( 'it' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: nuovo sistema di registrazione degli utenti, aggiunto reinvio dell\' email di verifica, ban con classi di IP',
                                         'Se vuoi iscriverti alla <a target="_blank" href="mailto:ml-briscola+subscribe@milug.org">Mailing List</a>, cliccala!' ),
                         'en' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NEWS</b>: new users subscription system.',
                                         'If you want to subscribe our <a target="_blank" href="ml-briscola+subscribe@milug.org">Mailing List</a>, click it!' ) );
@@@ -578,6 -577,33 +578,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)
      {
@@@ -751,6 -777,11 +778,6 @@@ class Table 
      }
    }
  
 -
 -
 -  //      $ret .= table_act_content(($user->subst == 'standup'), $this->table[$i]->player_n, $i, $user->table, 
 -  //                              ($this->table[$i]->auth_only == FALSE ? TRUE : $user->flags & USER_FLAG_AUTH));
 -
    // function act_content($isstanding, $sitted, $table, $cur_table, $allowed)
    function act_content($user)
    {
@@@ -945,35 -976,185 +972,185 @@@ class Bris
      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;
  
-     function Brisk($crystal_filename) {
-         $this->crystal_filename = $crystal_filename;
-         $this->user  = array();
-         $this->table = array();
-         $this->match = array();
-         
+     function Brisk()
+     {
+     }
+     // constructor
+     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);
+             }
+         }
+         fprintf(STDERR, "NEW ROOM\n");
+         $thiz = new Brisk();
+         $thiz->crystal_filename = $crystal_filename;
+         $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++) {
-             $this->user[$i] = User::create($this, $i, "", "");
+             $thiz->user[$i] = User::create($thiz, $i, "", "");
          }
          
          for ($i = 0 ; $i < TABLES_N ; $i++) {
-             $this->table[$i] = Table::create($i);
+             $thiz->table[$i] = Table::create($i);
+             /* OLD METHOD
+                if ($i < 12) {
+                $row = ( (((int)($i / 4)) % 2) == 0 );
+                $col = ($i % 2 == 0);
+                $thiz->table[$i]->auth_only = (($row && $col) || (!$row && !$col));
+                }
+                else {
+                $thiz->table[$i]->auth_only = FALSE;
+                }
+             */
              if ($i < TABLES_AUTH_N) 
-                 $this->table[$i]->auth_only = TRUE;
+                 $thiz->table[$i]->auth_only = TRUE;
              else
-                 $this->table[$i]->auth_only = FALSE;
+                 $thiz->table[$i]->auth_only = FALSE;
          }
-         $this->garbage_timeout = 0;
-         $this->shm_sz = SHM_DIMS_MIN;
+         $thiz->garbage_timeout = 0;
+         $thiz->shm_sz = SHM_DIMS_MIN;
  
-         $this->delay_mgr = new Delay_Manager(1.5);
+         $thiz->delay_mgr = new Delay_Manager(1.5);
  
          static::$sess_cur = FALSE;
+         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)
      for ($i = 0 ; $i < TABLES_N ; $i++) {
  
        $ret .= $this->table_content($user, $i);
 -      // $ret .= table_act_content(($user->subst == 'standup'), $this->table[$i]->player_n, $i, $user->table, 
 -      //                          ($this->table[$i]->auth_only == FALSE ? TRUE : $user->flags & USER_FLAG_AUTH));
 +
        $ret .=  $this->table[$i]->act_content($user);
        if ($this->table[$i]->wag_own != -1) 
          $ret .= sprintf('tra.add(%d, "%s: %s"); ', $i,  $this->user[$this->table[$i]->wag_own]->name, $this->table[$i]->wag_com);
          // clean the action buttons in other tables
          for ($e = 0 ; $e < TABLES_N ; $e++) {
            if ($this->table[$e]->player_n < PLAYERS_N) {
 -            // $ret .= table_act_content(TRUE, 0, $e, $user->table, 
 -              //                           ($this->table[$e]->auth_only == FALSE ? TRUE : $user->flags & USER_FLAG_AUTH));
                $ret .= $this->table[$e]->act_content($user);
              }
          }
        }
        else {
 -        // $ret .= table_act_content(($user_cur->subst == 'standup'), $table->player_n, $table_idx, $user_cur->table,
 -          //                           ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
            $ret .= $table->act_content($user_cur);
        }
        }
        $ret .= $this->table_content($user_cur, $table_idx);
        $ret .= $this->standup_content($user_cur);
        
 -      // $ret .= table_act_content(FALSE, 0, $table_idx, $user_cur->table,
 -        //                           ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
          $ret .= $table->act_content($user_cur);
  
  
        log_main("JOIN_WAKEUP wup_idx ".$wup_idx."  wup_n ".$user_wup_n);
  
        log_main("JOIN_WAKEUP more");
 -      // $ret .= table_act_content(($user_cur->subst == 'standup'), $table->player_n, $table_idx, $user_cur->table,
 -        //                           ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
 +
          $ret .= $table->act_content($user_cur);
  
        log_main("JOIN_WAKEUP end more");
            }
            else if ($table_idx > -1) {
                if ($table->player_n == PLAYERS_N) {
 -                  // $ret .= table_act_content(($user_cur->subst == 'standup'), PLAYERS_N, $table_idx, $user_cur->table,
 -                  ///                      ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
 +
                    $ret .= $table->act_content($user_cur);
                }
            }
        $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);
      }
    }
  
-   // Static functions
-   static function create($crystal_filename)
-   {
-       if (($brisk_ser = @file_get_contents($crystal_filename)) == FALSE ||
-           ($brisk = unserialize($brisk_ser)) == FALSE) {
-           fprintf(STDERR, "NEW ROOM\n");
-           $brisk = new Brisk($crystal_filename);
-       }
-       else {
-           fprintf(STDERR, "ROOM FROM FILE\n");
-           rename($crystal_filename, $crystal_filename.".old");
-       }
-     return $brisk;
-   }
-   
-   
-   function load_data() 
-   {
-     GLOBAL $sess;
-     do {
-       if (($tok = @ftok(FTOK_PATH."/main", "C")) == -1) {
-       log_main("ftok failed");
-       break;
-       }
-     
-       if (($shm_sz = sharedmem_sz($tok)) == -1) {
-       log_main("shmop_open failed");
-       }
-       
-       if ($shm_sz == -1)
-       $shm_sz = SHM_DIMS_MIN;
-       if ($shm = shm_attach($tok, $shm_sz)) {
-           $brisk = @shm_get_var($shm, $tok); // CHECKED BELOW
-           
-           log_only("bri ==  ".($brisk == FALSE ?   "FALSE" : "TRUE")."  bri ===  ".($brisk === FALSE ? "FALSE" : "TRUE")."  bri isset ".(isset($brisk) ?   "TRUE" : "FALSE"));
-           if (isset($brisk))
-               log_only("bri count ".count($brisk));
-           
-           if ($brisk == FALSE) {
-               log_only("INIT MAIN DATA");
-               shm_detach($shm);
-               
-               $brisk = Brisk::create();
-               
-               log_shme("Brisk::create");
-               if (Brisk::save_data($brisk) == FALSE)
-                   return FALSE;
-               return $brisk;
-           }
-           $brisk->shm_sz = $shm_sz;
-           
-           shm_detach($shm);
-           for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
-               if (($brisk->user[$i] = User::load_data($i, FALSE)) == FALSE) {
-                   log_crit("User::load_data failed");
-                   break;
-               }
-           }
-           if ($i < MAX_PLAYERS) {
-               break;
-           }
-       }
-       
-       //  
-       // SHSPLIT: load users from the shared memory
-       //
-       return ($brisk);
-     } while (0);
-     
-     return (FALSE);
-   }
-   
-   function save_data_orig($brisk) 
-   {
-     GLOBAL $sess;
-     
-     $shm =   FALSE;
-     
-     // var_dump($brisk);
-     
-     if (($tok = @ftok(FTOK_PATH."/main", "C")) == -1) 
-       return (FALSE);
-     
-     while ($brisk->shm_sz < SHM_DIMS_MAX) {
-       if (($shm = shm_attach($tok, $brisk->shm_sz)) == FALSE)
-       break;
-       
-       // log_only("PUT_VAR DI ".strlen(serialize($brisk)));
-       if (@shm_put_var($shm, $tok, $brisk) != FALSE) {
-       shm_detach($shm);
-       return (TRUE);
-       }
-       if (shm_remove($shm) === FALSE) {
-       log_only("REMOVE FALLITA");
-       break;
-       }
-       shm_detach($shm);
-       $brisk->shm_sz += SHM_DIMS_DLT;
-     } 
-     if ($shm)
-       shm_detach($shm);
-     
-     return (FALSE);
-   }
    function dump_data()
    {
        $brisk_ser = serialize($this);
        return (FALSE);
    }
  
-   function save_data($brisk) 
-   {
-       GLOBAL $sess;
-     
-       $ret =   FALSE;
-       $shm =   FALSE;
-     
-       if (($tok = @ftok(FTOK_PATH."/main", "C")) == -1) 
-           return (FALSE);
-     
-       // SHSPLIT: before save the $brisk you must save users, 
-       //          detach from main struct and (then) reattach
-       $user_park = array();
-       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
-           $user_park[$i]  = $brisk->user[$i];
-           $brisk->user[$i] = FALSE;
-       }
-       while ($brisk->shm_sz < SHM_DIMS_MAX) {
-           if (($shm = shm_attach($tok, $brisk->shm_sz)) == FALSE)
-               break;
-       
-           // log_only("PUT_VAR DI ".strlen(serialize($brisk)));
-           if (@shm_put_var($shm, $tok, $brisk) != FALSE) {
-               log_shme("Brisk::save_data");
-               $ret = TRUE;
-               break;
-           }
-           if (shm_remove($shm) === FALSE) {
-               log_only("REMOVE FALLITA");
-               break;
-           }
-           shm_detach($shm);
-           $brisk->shm_sz += SHM_DIMS_DLT;
-       } 
-       if ($shm)
-           shm_detach($shm);
-     
-       // SHSPLIT: reattach users to the room class
-       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
-           User::save_data($user_park[$i], $i);
-           $brisk->user[$i] = $user_park[$i];
-       }
-       log_load("FINISH: ".($ret == TRUE ? "TRUE" : "FALSE"));
-       return ($ret);
-   }
-   static function lock_data($is_exclusive)
-   {
-       if (($res = file_lock(FTOK_PATH."/main", $is_exclusive)) != FALSE) {
-           self::$delta_t = microtime(TRUE);
-           log_lock("LOCK   room         [".self::$delta_t."]");
-           
-           return ($res);
-       }
-       return (FALSE);
-   }
-   
-   static function unlock_data($res)
-   {
-     GLOBAL $sess; 
-     
-     log_lock("UNLOCK room         [".(microtime(TRUE) - (self::$delta_t))."]");
-     file_unlock($res);
-   }
    function standup_content($user)
    {
      $ret = "";
  
    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'])) {
diff --combined web/index.php
@@@ -237,7 -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;
      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;
      }
  
        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) {
                    $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") {
        $tables .= '<table class="room_tab">';
        for ($ii = 0 ; $ii < TABLES_N ; $ii++) {
            if ($user->flags & USER_FLAG_AUTH)
 -        $i = $ii;
 +              $i = $ii;
            else
                $i = TABLES_N - $ii - 1;
  
@@@ -888,7 -897,6 +897,7 @@@ supported by:<br
     var g_lng = "<? echo $G_lng; ?>";
     var g_tables_n = <? echo TABLES_N; ?>;
     var g_tables_auth_n = <? echo TABLES_AUTH_N; ?>;
 +   var g_tables_cert_n = <? echo TABLES_CERT_N; ?>;
     var g_prefs, g_prefs_new = null;
     var g_listen;
     var g_withflash = false;
@@@ -1047,7 -1055,6 +1056,7 @@@ echo "$body"; ?
     var g_lng = "<? echo $G_lng; ?>";
     var g_tables_n = <? echo TABLES_N; ?>;
     var g_tables_auth_n = <? echo TABLES_AUTH_N; ?>;
 +   var g_tables_cert_n = <? echo TABLES_CERT_N; ?>;
     var g_prefs, g_prefs_new = null;
     var g_listen;
     var g_is_spawn = 0;