login = $login; $this->ip = $ip; $this->session = $session; $this->timeout = $timeout; } } class Hardbans { static $delta_t; var $item; var $item_n; var $mod; var $shm_sz; var $garbage_timeout; function Hardbans() { $this->item = array(); $this->item_n = 0; $this->garbage_timeout = 0; $this->mod = FALSE; } function add_item($login, $ip, $session, $timeout) { $chal = null; log_auth("xxx", sprintf("Hardbans::add [%s]\n", $login)); if (($chal = new Hardban($login, $ip, $session, $timeout)) == FALSE) { return (FALSE); } $this->item[$this->item_n] = $chal; $this->item_n++; $this->mod = TRUE; return ($chal); } /* remove all istances related to $login */ function rem($login) { $ismod = FALSE; $curtime = time(); for ($i = 0 ; $i < $this->item_n ; $i++) { if ($this->item[$i]->timeout < $curtime || strcasecmp($this->item[$i]->login, $login) == 0) { $ismod = TRUE; for ($e = $i ; $e < ($this->item_n - 1) ; $e++) { $this->item[$e] = $this->item[$e + 1]; } $i--; $this->item_n--; unset($this->item[$this->item_n]); $this->mod = TRUE; } } return ($ismod); } function garbage_manager($force) { $curtime = time(); // FIXME remove set to 0 $this->garbage_timeout = 0; if ($this->garbage_timeout > $curtime && $force == FALSE) return (FALSE); $ismod = FALSE; for ($i = 0 ; $i < $this->item_n ; $i++) { log_auth("xxx", "LOOPI item: ".$i." timeout: ".$this->item[$i]->timeout." curtime: ".$curtime); if ($this->item[$i]->timeout < $curtime) { for ($e = $i ; $e < ($this->item_n - 1) ; $e++) { $this->item[$e] = $this->item[$e + 1]; } $i--; $this->item_n--; log_auth("xxx", "LOOPI unset: ".$this->item_n); unset($this->item[$this->item_n]); $ismod = TRUE; $this->mod = TRUE; } } log_auth("xxx", "LOOPI AFTER: ".count($this->item)." _n:" .$this->item_n ); $this->garbage_timeout = $curtime + HBAN_GARBAGE_TIMEOUT; return ($ismod); } function ismod() { return ($this->mod); } // Static functions static function create() { $chal =& new Hardbans(); $chal->mod = TRUE; return $chal; } function load_data() { GLOBAL $sess; do { if (($tok = @ftok(FTOK_PATH."/hardbans", "C")) == -1) { log_main("ftok failed"); break; } // fprintf(STDERR, "hardpans: %x\n", $tok); if (($shm_sz = sharedmem_sz($tok)) == -1) { log_main("shmop_open failed"); } if ($shm_sz == -1) $shm_sz = HBAN_SHM_DIMS_MIN; if ($shm = shm_attach($tok, $shm_sz)) { $hban = @shm_get_var($shm, $tok); // CHECKED BELOW log_only("hardban == ".($hban == FALSE ? "FALSE" : "TRUE")." hardban === ".($hban === FALSE ? "FALSE" : "TRUE")." hardban isset ".(isset($hban) ? "TRUE" : "FALSE")); if ($hban == FALSE) { log_only("INIT HARDBAN DATA"); $hban =& Hardbans::create(); if (@shm_put_var($shm, $tok, $hban) == FALSE) { log_only("PUT_VAR FALLITA ".strlen(serialize($hban))); log_only(serialize($hban)); } log_shme("Hardban::save_data2"); } $hban->shm_sz = $shm_sz; shm_detach($shm); } $hban->garbage_manager(TRUE); return ($hban); } while (0); return (FALSE); } function save_data($hban) { $shm = FALSE; $oldmod = $hban->mod; if (($tok = @ftok(FTOK_PATH."/hardbans", "C")) == -1) return (FALSE); while ($hban->shm_sz < HBAN_SHM_DIMS_MAX) { if (($shm = shm_attach($tok, $hban->shm_sz)) == FALSE) break; if (isset($hban)) log_only("hardban count ".count($hban->item)." _n: ".$hban->item_n); $hban->mod = FALSE; if (@shm_put_var($shm, $tok, $hban) != FALSE) { shm_detach($shm); log_shme("Hardban::save_data"); return (TRUE); } $hban->mod = $oldmod; if (shm_remove($shm) === FALSE) { log_only("REMOVE FALLITA"); break; } shm_detach($shm); $hban->shm_sz += HBAN_SHM_DIMS_DLT; } if ($shm) shm_detach($shm); return (FALSE); } static function lock_data($is_exclusive) { if (($res = file_lock(FTOK_PATH."/hardbans", $is_exclusive)) != FALSE) { self::$delta_t = microtime(TRUE); log_lock("LOCK hardbans [".self::$delta_t."]"); return ($res); } return (FALSE); } static function unlock_data($res) { GLOBAL $sess; log_lock("UNLOCK hardbans [".(microtime(TRUE) - (self::$delta_t))."]"); file_unlock($res); } function check($login, $ip, $session) { $bantime = -1; /* if it exists check for a valid challenge */ if (($a_sem = Hardbans::lock_data(TRUE)) != FALSE) { if (($hban = &Hardbans::load_data()) != FALSE) { for ($e = 0 ; $e < $hban->item_n ; $e++) { if ($login != FALSE) { if (strcasecmp($login, $hban->item[$e]->login) == 0 || $hban->item[$e]->session == $session) { $bantime = $hban->item[$e]->timeout; break; } } else { /* check on ip and sess */ if ($hban->item[$e]->ip == $ip || $hban->item[$e]->session == $session) { $bantime = $hban->item[$e]->timeout; break; } } } // for (... if ($hban->ismod()) { Hardbans::save_data($hban); } } // if (load_data Hardbans::unlock_data($a_sem); } // if (lock_data return ($bantime); } // func function add($login, $ip, $session, $timeout) { $found = FALSE; /* if it exists check for a valid challenge */ if (($a_sem = Hardbans::lock_data(TRUE)) != FALSE) { if (($hban = &Hardbans::load_data()) != FALSE) { $hban->add_item($login, $ip, $session, $timeout); if ($hban->ismod()) { Hardbans::save_data($hban); } } // if (load_data Hardbans::unlock_data($a_sem); } // if (lock_data return ($found); } // func } // End CLASS Hardbans ?>