diff options
Diffstat (limited to 'program/lib/Roundcube/rcube_session.php')
-rw-r--r-- | program/lib/Roundcube/rcube_session.php | 142 |
1 files changed, 50 insertions, 92 deletions
diff --git a/program/lib/Roundcube/rcube_session.php b/program/lib/Roundcube/rcube_session.php index 67072df41..ee4db6e86 100644 --- a/program/lib/Roundcube/rcube_session.php +++ b/program/lib/Roundcube/rcube_session.php @@ -32,7 +32,6 @@ class rcube_session private $ip; private $start; private $changed; - private $time_diff = 0; private $reloaded = false; private $unsets = array(); private $gc_handlers = array(); @@ -43,7 +42,6 @@ class rcube_session private $secret = ''; private $ip_check = false; private $logging = false; - private $storage; private $memcache; @@ -54,21 +52,18 @@ class rcube_session { $this->db = $db; $this->start = microtime(true); - $this->ip = rcube_utils::remote_addr(); + $this->ip = $_SERVER['REMOTE_ADDR']; $this->logging = $config->get('log_session', false); $lifetime = $config->get('session_lifetime', 1) * 60; $this->set_lifetime($lifetime); // use memcache backend - $this->storage = $config->get('session_storage', 'db'); - if ($this->storage == 'memcache') { + if ($config->get('session_storage', 'db') == 'memcache') { $this->memcache = rcube::get_instance()->get_memcache(); // set custom functions for PHP session management if memcache is available if ($this->memcache) { - ini_set('session.serialize_handler', 'php'); - session_set_save_handler( array($this, 'open'), array($this, 'close'), @@ -84,9 +79,7 @@ class rcube_session true, true); } } - else if ($this->storage != 'php') { - ini_set('session.serialize_handler', 'php'); - + else { // set custom functions for PHP session management session_set_save_handler( array($this, 'open'), @@ -94,23 +87,7 @@ class rcube_session array($this, 'db_read'), array($this, 'db_write'), array($this, 'db_destroy'), - array($this, 'gc')); - } - } - - - /** - * Wrapper for session_start() - */ - public function start() - { - session_start(); - - // copy some session properties to object vars - if ($this->storage == 'php') { - $this->key = session_id(); - $this->ip = $_SESSION['__IP']; - $this->changed = $_SESSION['__MTIME']; + array($this, 'db_gc')); } } @@ -139,25 +116,6 @@ class rcube_session /** - * Wrapper for session_write_close() - */ - public function write_close() - { - if ($this->storage == 'php') { - $_SESSION['__IP'] = $this->ip; - $_SESSION['__MTIME'] = time(); - } - - session_write_close(); - - // write_close() is called on script shutdown, see rcube::shutdown() - // execute cleanup functionality if enabled by session gc handler - // we do this after closing the session for better performance - $this->gc_shutdown(); - } - - - /** * Read session data from database * * @param string Session ID @@ -167,16 +125,14 @@ class rcube_session public function db_read($key) { $sql_result = $this->db->query( - "SELECT vars, ip, changed, " . $this->db->now() . " AS ts" - . " FROM " . $this->db->table_name('session') - . " WHERE sess_id = ?", $key); + "SELECT vars, ip, changed FROM ".$this->db->table_name('session') + ." WHERE sess_id = ?", $key); if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) { - $this->time_diff = time() - strtotime($sql_arr['ts']); - $this->changed = strtotime($sql_arr['changed']); - $this->ip = $sql_arr['ip']; - $this->vars = base64_decode($sql_arr['vars']); - $this->key = $key; + $this->changed = strtotime($sql_arr['changed']); + $this->ip = $sql_arr['ip']; + $this->vars = base64_decode($sql_arr['vars']); + $this->key = $key; return !empty($this->vars) ? (string) $this->vars : ''; } @@ -196,9 +152,8 @@ class rcube_session */ public function db_write($key, $vars) { - $now = $this->db->now(); - $table = $this->db->table_name('session'); - $ts = microtime(true); + $ts = microtime(true); + $now = $this->db->fromunixtime((int)$ts); // no session row in DB (db_read() returns false) if (!$this->key) { @@ -216,19 +171,22 @@ class rcube_session $newvars = $this->_fixvars($vars, $oldvars); if ($newvars !== $oldvars) { - $this->db->query("UPDATE $table " - . "SET changed = $now, vars = ? WHERE sess_id = ?", - base64_encode($newvars), $key); + $this->db->query( + sprintf("UPDATE %s SET vars=?, changed=%s WHERE sess_id=?", + $this->db->table_name('session'), $now), + base64_encode($newvars), $key); } - else if ($ts - $this->changed + $this->time_diff > $this->lifetime / 2) { - $this->db->query("UPDATE $table SET changed = $now" - . " WHERE sess_id = ?", $key); + else if ($ts - $this->changed > $this->lifetime / 2) { + $this->db->query("UPDATE ".$this->db->table_name('session') + ." SET changed=$now WHERE sess_id=?", $key); } } else { - $this->db->query("INSERT INTO $table (sess_id, vars, ip, created, changed)" - . " VALUES (?, ?, ?, $now, $now)", - $key, base64_encode($vars), (string)$this->ip); + $this->db->query( + sprintf("INSERT INTO %s (sess_id, vars, ip, created, changed) ". + "VALUES (?, ?, ?, %s, %s)", + $this->db->table_name('session'), $now, $now), + $key, base64_encode($vars), (string)$this->ip); } return true; @@ -288,6 +246,25 @@ class rcube_session /** + * Garbage collecting function + * + * @param string Session lifetime in seconds + * @return boolean True on success + */ + public function db_gc($maxlifetime) + { + // just delete all expired sessions + $this->db->query( + sprintf("DELETE FROM %s WHERE changed < %s", + $this->db->table_name('session'), $this->db->fromunixtime(time() - $maxlifetime))); + + $this->gc(); + + return true; + } + + + /** * Read session data from memcache * * @param string Session ID @@ -363,11 +340,11 @@ class rcube_session /** * Execute registered garbage collector routines */ - public function gc($maxlifetime) + public function gc() { - // move gc execution to the script shutdown function - // see rcube::shutdown() and rcube_session::write_close() - return $this->gc_enabled = $maxlifetime; + foreach ($this->gc_handlers as $fct) { + call_user_func($fct); + } } @@ -389,25 +366,6 @@ class rcube_session /** - * Garbage collector handler to run on script shutdown - */ - protected function gc_shutdown() - { - if ($this->gc_enabled) { - // just delete all expired sessions - if ($this->storage == 'db') { - $this->db->query("DELETE FROM " . $this->db->table_name('session') - . " WHERE changed < " . $this->db->now(-$this->gc_enabled)); - } - - foreach ($this->gc_handlers as $fct) { - call_user_func($fct); - } - } - } - - - /** * Generate and set new session id * * @param boolean $destroy If enabled the current session will be destroyed @@ -480,7 +438,7 @@ class rcube_session public function kill() { $this->vars = null; - $this->ip = rcube_utils::remote_addr(); // update IP (might have changed) + $this->ip = $_SERVER['REMOTE_ADDR']; // update IP (might have changed) $this->destroy(session_id()); rcube_utils::setcookie($this->cookiename, '-del-', time() - 60); } @@ -694,10 +652,10 @@ class rcube_session function check_auth() { $this->cookie = $_COOKIE[$this->cookiename]; - $result = $this->ip_check ? rcube_utils::remote_addr() == $this->ip : true; + $result = $this->ip_check ? $_SERVER['REMOTE_ADDR'] == $this->ip : true; if (!$result) { - $this->log("IP check failed for " . $this->key . "; expected " . $this->ip . "; got " . rcube_utils::remote_addr()); + $this->log("IP check failed for " . $this->key . "; expected " . $this->ip . "; got " . $_SERVER['REMOTE_ADDR']); } if ($result && $this->_mkcookie($this->now) != $this->cookie) { |