| | |
| | | private $logging = false; |
| | | private $memcache; |
| | | |
| | | |
| | | /** |
| | | * Default constructor |
| | | */ |
| | |
| | | * Read session data from database |
| | | * |
| | | * @param string Session ID |
| | | * |
| | | * @return string Session vars |
| | | */ |
| | | public function db_read($key) |
| | |
| | | * |
| | | * @param string Session ID |
| | | * @param string Serialized session vars |
| | | * |
| | | * @return boolean True on success |
| | | */ |
| | | public function db_write($key, $vars) |
| | |
| | | base64_encode($newvars), $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); |
| | | $this->db->query("UPDATE ".$this->db->table_name('session') |
| | | ." SET changed=$now WHERE sess_id=?", $key); |
| | | } |
| | | } |
| | | else { |
| | |
| | | $newvars = $this->serialize(array_merge( |
| | | (array)$a_oldvars, (array)$this->unserialize($vars))); |
| | | } |
| | | else |
| | | else { |
| | | $newvars = $vars; |
| | | } |
| | | } |
| | | |
| | | $this->unsets = array(); |
| | |
| | | public function db_destroy($key) |
| | | { |
| | | if ($key) { |
| | | $this->db->query(sprintf("DELETE FROM %s WHERE sess_id = ?", $this->db->table_name('session')), $key); |
| | | $this->db->query(sprintf("DELETE FROM %s WHERE sess_id = ?", |
| | | $this->db->table_name('session')), $key); |
| | | } |
| | | |
| | | return true; |
| | |
| | | * |
| | | * @param string Session ID |
| | | * @param string Serialized session vars |
| | | * |
| | | * @return boolean True on success |
| | | */ |
| | | public function mc_write($key, $vars) |
| | |
| | | |
| | | $newvars = $oldvars !== null ? $this->_fixvars($vars, $oldvars) : $vars; |
| | | |
| | | if ($newvars !== $oldvars || $ts - $this->changed > $this->lifetime / 2) |
| | | return $this->memcache->set($key, serialize(array('changed' => time(), 'ip' => $this->ip, 'vars' => $newvars)), MEMCACHE_COMPRESSED, $this->lifetime); |
| | | if ($newvars !== $oldvars || $ts - $this->changed > $this->lifetime / 2) { |
| | | return $this->memcache->set($key, serialize(array('changed' => time(), 'ip' => $this->ip, 'vars' => $newvars)), |
| | | MEMCACHE_COMPRESSED, $this->lifetime); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | |
| | | */ |
| | | public function remove($var=null) |
| | | { |
| | | if (empty($var)) |
| | | if (empty($var)) { |
| | | return $this->destroy(session_id()); |
| | | } |
| | | |
| | | $this->unsets[] = $var; |
| | | unset($_SESSION[$var]); |
| | |
| | | private function serialize($vars) |
| | | { |
| | | $data = ''; |
| | | if (is_array($vars)) |
| | | if (is_array($vars)) { |
| | | foreach ($vars as $var=>$value) |
| | | $data .= $var.'|'.serialize($value); |
| | | else |
| | | } |
| | | else { |
| | | $data = 'b:0;'; |
| | | } |
| | | |
| | | return $data; |
| | | } |
| | | |
| | |
| | | while ($p < $endptr) { |
| | | $q = $p; |
| | | while ($str[$q] != '|') |
| | | if (++$q >= $endptr) break 2; |
| | | if (++$q >= $endptr) |
| | | break 2; |
| | | |
| | | if ($str[$p] == '!') { |
| | | $p++; |
| | | $has_value = false; |
| | | } else { |
| | | } |
| | | else { |
| | | $has_value = true; |
| | | } |
| | | |
| | |
| | | for (;;) { |
| | | $p = $q; |
| | | switch (strtolower($str[$q])) { |
| | | case 'n': /* null */ |
| | | case 'b': /* boolean */ |
| | | case 'i': /* integer */ |
| | | case 'd': /* decimal */ |
| | | case 'n': // null |
| | | case 'b': // boolean |
| | | case 'i': // integer |
| | | case 'd': // decimal |
| | | do $q++; |
| | | while ( ($q < $endptr) && ($str[$q] != ';') ); |
| | | $q++; |
| | | $serialized .= substr($str, $p, $q - $p); |
| | | if ($level == 0) break 2; |
| | | if ($level == 0) |
| | | break 2; |
| | | break; |
| | | case 'r': /* reference */ |
| | | case 'r': // reference |
| | | $q+= 2; |
| | | for ($id = ''; ($q < $endptr) && ($str[$q] != ';'); $q++) $id .= $str[$q]; |
| | | for ($id = ''; ($q < $endptr) && ($str[$q] != ';'); $q++) |
| | | $id .= $str[$q]; |
| | | $q++; |
| | | $serialized .= 'R:' . ($id + 1) . ';'; /* increment pointer because of outer array */ |
| | | if ($level == 0) break 2; |
| | | // increment pointer because of outer array |
| | | $serialized .= 'R:' . ($id + 1) . ';'; |
| | | if ($level == 0) |
| | | break 2; |
| | | break; |
| | | case 's': /* string */ |
| | | case 's': // string |
| | | $q+=2; |
| | | for ($length=''; ($q < $endptr) && ($str[$q] != ':'); $q++) $length .= $str[$q]; |
| | | for ($length=''; ($q < $endptr) && ($str[$q] != ':'); $q++) |
| | | $length .= $str[$q]; |
| | | $q+=2; |
| | | $q+= (int)$length + 2; |
| | | $serialized .= substr($str, $p, $q - $p); |
| | | if ($level == 0) break 2; |
| | | if ($level == 0) |
| | | break 2; |
| | | break; |
| | | case 'a': /* array */ |
| | | case 'o': /* object */ |
| | | case 'a': // array |
| | | case 'o': // object |
| | | do $q++; |
| | | while ( ($q < $endptr) && ($str[$q] != '{') ); |
| | | while ($q < $endptr && $str[$q] != '{'); |
| | | $q++; |
| | | $level++; |
| | | $serialized .= substr($str, $p, $q - $p); |
| | | break; |
| | | case '}': /* end of array|object */ |
| | | case '}': // end of array|object |
| | | $q++; |
| | | $serialized .= substr($str, $p, $q - $p); |
| | | if (--$level == 0) break 2; |
| | | if (--$level == 0) |
| | | break 2; |
| | | break; |
| | | default: |
| | | return false; |
| | | } |
| | | } |
| | | } else { |
| | | } |
| | | else { |
| | | $serialized .= 'N;'; |
| | | $q += 2; |
| | | } |
| | |
| | | */ |
| | | function set_cookiename($cookiename) |
| | | { |
| | | if ($cookiename) |
| | | if ($cookiename) { |
| | | $this->cookiename = $cookiename; |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | $this->cookie = $_COOKIE[$this->cookiename]; |
| | | $result = $this->ip_check ? $_SERVER['REMOTE_ADDR'] == $this->ip : true; |
| | | |
| | | if (!$result) |
| | | if (!$result) { |
| | | $this->log("IP check failed for " . $this->key . "; expected " . $this->ip . "; got " . $_SERVER['REMOTE_ADDR']); |
| | | } |
| | | |
| | | if ($result && $this->_mkcookie($this->now) != $this->cookie) { |
| | | $this->log("Session auth check failed for " . $this->key . "; timeslot = " . date('Y-m-d H:i:s', $this->now)); |
| | |
| | | } |
| | | } |
| | | |
| | | if (!$result) |
| | | $this->log("Session authentication failed for " . $this->key . "; invalid auth cookie sent; timeslot = " . date('Y-m-d H:i:s', $prev)); |
| | | if (!$result) { |
| | | $this->log("Session authentication failed for " . $this->key |
| | | . "; invalid auth cookie sent; timeslot = " . date('Y-m-d H:i:s', $prev)); |
| | | } |
| | | |
| | | return $result; |
| | | } |
| | |
| | | */ |
| | | function log($line) |
| | | { |
| | | if ($this->logging) |
| | | if ($this->logging) { |
| | | rcube::write_log('session', $line); |
| | | } |
| | | |
| | | } |
| | | } |