summaryrefslogtreecommitdiffstats
path: root/system/libraries/Session.php
diff options
context:
space:
mode:
authorJoel Kallman <jkallman@eclarian.com>2012-03-12 23:10:44 +0100
committerJoel Kallman <jkallman@eclarian.com>2012-03-12 23:10:44 +0100
commit7c4870c3741e165bc7bc06624c816e66db474ee2 (patch)
treea96962212cb012be32ab09545dcd5c4dbdac05e2 /system/libraries/Session.php
parent10aa8e660c6f439958b79fce5d85ce7e8eecf028 (diff)
parent6b535f51fcb94e0a645fda0d0356f4748076877e (diff)
Merge branch 'develop' into feature/db_toString_support
Diffstat (limited to 'system/libraries/Session.php')
-rw-r--r--system/libraries/Session.php305
1 files changed, 147 insertions, 158 deletions
diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 08d2ba4ba..0b9d45b2a 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -1,13 +1,13 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
*
* NOTICE OF LICENSE
- *
+ *
* Licensed under the Open Software License version 3.0
- *
+ *
* This source file is subject to the Open Software License (OSL 3.0) that is
* bundled with this package in the files license.txt / license.rst. It is
* also available through the world wide web at this URL:
@@ -18,15 +18,13 @@
*
* @package CodeIgniter
* @author EllisLab Dev Team
- * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* @link http://codeigniter.com
* @since Version 1.0
* @filesource
*/
-// ------------------------------------------------------------------------
-
/**
* Session Class
*
@@ -38,26 +36,26 @@
*/
class CI_Session {
- var $sess_encrypt_cookie = FALSE;
- var $sess_use_database = FALSE;
- var $sess_table_name = '';
- var $sess_expiration = 7200;
- var $sess_expire_on_close = FALSE;
- var $sess_match_ip = FALSE;
- var $sess_match_useragent = TRUE;
- var $sess_cookie_name = 'ci_session';
- var $cookie_prefix = '';
- var $cookie_path = '';
- var $cookie_domain = '';
- var $cookie_secure = FALSE;
- var $sess_time_to_update = 300;
- var $encryption_key = '';
- var $flashdata_key = 'flash';
- var $time_reference = 'time';
- var $gc_probability = 5;
- var $userdata = array();
- var $CI;
- var $now;
+ public $sess_encrypt_cookie = FALSE;
+ public $sess_use_database = FALSE;
+ public $sess_table_name = '';
+ public $sess_expiration = 7200;
+ public $sess_expire_on_close = FALSE;
+ public $sess_match_ip = FALSE;
+ public $sess_match_useragent = TRUE;
+ public $sess_cookie_name = 'ci_session';
+ public $cookie_prefix = '';
+ public $cookie_path = '';
+ public $cookie_domain = '';
+ public $cookie_secure = FALSE;
+ public $sess_time_to_update = 300;
+ public $encryption_key = '';
+ public $flashdata_key = 'flash';
+ public $time_reference = 'time';
+ public $gc_probability = 5;
+ public $userdata = array();
+ public $CI;
+ public $now;
/**
* Session Constructor
@@ -67,7 +65,7 @@ class CI_Session {
*/
public function __construct($params = array())
{
- log_message('debug', "Session Class Initialized");
+ log_message('debug', 'Session Class Initialized');
// Set the super object to a local variable for use throughout the class
$this->CI =& get_instance();
@@ -93,14 +91,14 @@ class CI_Session {
$this->CI->load->library('encrypt');
}
- // Are we using a database? If so, load it
- if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')
+ // Are we using a database? If so, load it
+ if ($this->sess_use_database === TRUE && $this->sess_table_name != '')
{
$this->CI->load->database();
}
- // Set the "now" time. Can either be GMT or server time, based on the
- // config prefs. We use this to set the "last activity" time
+ // Set the "now" time. Can either be GMT or server time, based on the
+ // config prefs. We use this to set the "last activity" time
$this->now = $this->_get_time();
// Set the session length. If the session expiration is
@@ -109,12 +107,12 @@ class CI_Session {
{
$this->sess_expiration = (60*60*24*365*2);
}
-
+
// Set the cookie name
$this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;
// Run the Session routine. If a session doesn't exist we'll
- // create a new one. If it does, we'll update it.
+ // create a new one. If it does, we'll update it.
if ( ! $this->sess_read())
{
$this->sess_create();
@@ -133,7 +131,7 @@ class CI_Session {
// Delete expired sessions if necessary
$this->_sess_gc();
- log_message('debug', "Session routines successfully run");
+ log_message('debug', 'Session routines successfully run');
}
// --------------------------------------------------------------------
@@ -141,10 +139,9 @@ class CI_Session {
/**
* Fetch the current session data if it exists
*
- * @access public
* @return bool
*/
- function sess_read()
+ public function sess_read()
{
// Fetch the cookie
$session = $this->CI->input->cookie($this->sess_cookie_name);
@@ -167,7 +164,7 @@ class CI_Session {
$hash = substr($session, strlen($session)-32); // get last 32 chars
$session = substr($session, 0, strlen($session)-32);
- // Does the md5 hash match? This is to prevent manipulation of session data in userspace
+ // Does the md5 hash match? This is to prevent manipulation of session data in userspace
if ($hash !== md5($session.$this->encryption_key))
{
log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
@@ -180,7 +177,7 @@ class CI_Session {
$session = $this->_unserialize($session);
// Is the session data we unserialized an array with the correct format?
- if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
+ if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity']))
{
$this->sess_destroy();
return FALSE;
@@ -193,15 +190,15 @@ class CI_Session {
return FALSE;
}
- // Does the IP Match?
- if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())
+ // Does the IP match?
+ if ($this->sess_match_ip == TRUE && $session['ip_address'] !== $this->CI->input->ip_address())
{
$this->sess_destroy();
return FALSE;
}
// Does the User Agent Match?
- if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 120)))
+ if ($this->sess_match_useragent == TRUE && trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120)))
{
$this->sess_destroy();
return FALSE;
@@ -222,10 +219,10 @@ class CI_Session {
$this->CI->db->where('user_agent', $session['user_agent']);
}
- $query = $this->CI->db->get($this->sess_table_name);
+ $query = $this->CI->db->limit(1)->get($this->sess_table_name);
- // No result? Kill it!
- if ($query->num_rows() == 0)
+ // No result? Kill it!
+ if ($query->num_rows() === 0)
{
$this->sess_destroy();
return FALSE;
@@ -233,7 +230,7 @@ class CI_Session {
// Is there custom data? If so, add it to the main session array
$row = $query->row();
- if (isset($row->user_data) AND $row->user_data != '')
+ if (isset($row->user_data) && $row->user_data != '')
{
$custom_data = $this->_unserialize($row->user_data);
@@ -259,10 +256,9 @@ class CI_Session {
/**
* Write the session data
*
- * @access public
* @return void
*/
- function sess_write()
+ public function sess_write()
{
// Are we saving custom data to the DB? If not, all we do is update the cookie
if ($this->sess_use_database === FALSE)
@@ -284,7 +280,7 @@ class CI_Session {
$cookie_userdata[$val] = $this->userdata[$val];
}
- // Did we find any custom data? If not, we turn the empty array into a string
+ // Did we find any custom data? If not, we turn the empty array into a string
// since there's no reason to serialize and store an empty array in the DB
if (count($custom_userdata) === 0)
{
@@ -300,7 +296,7 @@ class CI_Session {
$this->CI->db->where('session_id', $this->userdata['session_id']);
$this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata));
- // Write the cookie. Notice that we manually pass the cookie data array to the
+ // Write the cookie. Notice that we manually pass the cookie data array to the
// _set_cookie() function. Normally that function will store $this->userdata, but
// in this case that array contains custom data, which we do not want in the cookie.
$this->_set_cookie($cookie_userdata);
@@ -311,28 +307,27 @@ class CI_Session {
/**
* Create a new session
*
- * @access public
* @return void
*/
- function sess_create()
+ public function sess_create()
{
$sessid = '';
- while (strlen($sessid) < 32)
+ do
{
$sessid .= mt_rand(0, mt_getrandmax());
}
+ while (strlen($sessid) < 32);
// To make the session ID even more secure we'll combine it with the user's IP
$sessid .= $this->CI->input->ip_address();
$this->userdata = array(
- 'session_id' => md5(uniqid($sessid, TRUE)),
- 'ip_address' => $this->CI->input->ip_address(),
- 'user_agent' => substr($this->CI->input->user_agent(), 0, 120),
- 'last_activity' => $this->now,
- 'user_data' => ''
- );
-
+ 'session_id' => md5(uniqid($sessid, TRUE)),
+ 'ip_address' => $this->CI->input->ip_address(),
+ 'user_agent' => substr($this->CI->input->user_agent(), 0, 120),
+ 'last_activity' => $this->now,
+ 'user_data' => ''
+ );
// Save the data to the DB if needed
if ($this->sess_use_database === TRUE)
@@ -349,10 +344,9 @@ class CI_Session {
/**
* Update an existing session
*
- * @access public
* @return void
*/
- function sess_update()
+ public function sess_update()
{
// We only update the session every five minutes by default
if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
@@ -360,29 +354,52 @@ class CI_Session {
return;
}
+ // _set_cookie() will handle this for us if we aren't using database sessions
+ // by pushing all userdata to the cookie.
+ $cookie_data = NULL;
+
+ /* Changing the session ID during an AJAX call causes problems,
+ * so we'll only update our last_activity
+ */
+ if ($this->CI->input->is_ajax_request())
+ {
+ $this->userdata['last_activity'] = $this->now;
+
+ // Update the session ID and last_activity field in the DB if needed
+ if ($this->sess_use_database === TRUE)
+ {
+ // set cookie explicitly to only have our session data
+ $cookie_data = array();
+ foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
+ {
+ $cookie_data[$val] = $this->userdata[$val];
+ }
+
+ $this->CI->db->query($this->CI->db->update_string($this->sess_table_name,
+ array('last_activity' => $this->userdata['last_activity']),
+ array('session_id' => $this->userdata['session_id'])));
+ }
+
+ return $this->_set_cookie($cookie_data);
+ }
+
// Save the old session id so we know which record to
// update in the database if we need it
$old_sessid = $this->userdata['session_id'];
$new_sessid = '';
- while (strlen($new_sessid) < 32)
+ do
{
$new_sessid .= mt_rand(0, mt_getrandmax());
}
+ while (strlen($new_sessid) < 32);
// To make the session ID even more secure we'll combine it with the user's IP
$new_sessid .= $this->CI->input->ip_address();
- // Turn it into a hash
- $new_sessid = md5(uniqid($new_sessid, TRUE));
-
- // Update the session data in the session data array
- $this->userdata['session_id'] = $new_sessid;
+ // Turn it into a hash and update the session data array
+ $this->userdata['session_id'] = $new_sessid = md5(uniqid($new_sessid, TRUE));
$this->userdata['last_activity'] = $this->now;
- // _set_cookie() will handle this for us if we aren't using database sessions
- // by pushing all userdata to the cookie.
- $cookie_data = NULL;
-
// Update the session ID and last_activity field in the DB if needed
if ($this->sess_use_database === TRUE)
{
@@ -405,13 +422,12 @@ class CI_Session {
/**
* Destroy the current session
*
- * @access public
* @return void
*/
- function sess_destroy()
+ public function sess_destroy()
{
// Kill the session DB row
- if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id']))
+ if ($this->sess_use_database === TRUE && isset($this->userdata['session_id']))
{
$this->CI->db->where('session_id', $this->userdata['session_id']);
$this->CI->db->delete($this->sess_table_name);
@@ -419,13 +435,13 @@ class CI_Session {
// Kill the cookie
setcookie(
- $this->sess_cookie_name,
- addslashes(serialize(array())),
- ($this->now - 31500000),
- $this->cookie_path,
- $this->cookie_domain,
- 0
- );
+ $this->sess_cookie_name,
+ addslashes(serialize(array())),
+ ($this->now - 31500000),
+ $this->cookie_path,
+ $this->cookie_domain,
+ 0
+ );
}
// --------------------------------------------------------------------
@@ -433,13 +449,12 @@ class CI_Session {
/**
* Fetch a specific item from the session array
*
- * @access public
* @param string
* @return string
*/
- function userdata($item)
+ public function userdata($item)
{
- return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item];
+ return isset($this->userdata[$item]) ? $this->userdata[$item] : FALSE;
}
// --------------------------------------------------------------------
@@ -447,10 +462,9 @@ class CI_Session {
/**
* Fetch all session data
*
- * @access public
* @return array
*/
- function all_userdata()
+ public function all_userdata()
{
return $this->userdata;
}
@@ -460,12 +474,11 @@ class CI_Session {
/**
* Add or change data in the "userdata" array
*
- * @access public
* @param mixed
* @param string
* @return void
*/
- function set_userdata($newdata = array(), $newval = '')
+ public function set_userdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
@@ -488,10 +501,9 @@ class CI_Session {
/**
* Delete a session variable from the "userdata" array
*
- * @access array
* @return void
*/
- function unset_userdata($newdata = array())
+ public function unset_userdata($newdata = array())
{
if (is_string($newdata))
{
@@ -515,12 +527,11 @@ class CI_Session {
* Add or change flashdata, only available
* until the next request
*
- * @access public
* @param mixed
* @param string
* @return void
*/
- function set_flashdata($newdata = array(), $newval = '')
+ public function set_flashdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
@@ -531,8 +542,7 @@ class CI_Session {
{
foreach ($newdata as $key => $val)
{
- $flashdata_key = $this->flashdata_key.':new:'.$key;
- $this->set_userdata($flashdata_key, $val);
+ $this->set_userdata($this->flashdata_key.':new:'.$key, $val);
}
}
}
@@ -542,21 +552,18 @@ class CI_Session {
/**
* Keeps existing flashdata available to next request.
*
- * @access public
* @param string
* @return void
*/
- function keep_flashdata($key)
+ public function keep_flashdata($key)
{
- // 'old' flashdata gets removed. Here we mark all
+ // 'old' flashdata gets removed. Here we mark all
// flashdata as 'new' to preserve it from _flashdata_sweep()
// Note the function will return FALSE if the $key
// provided cannot be found
- $old_flashdata_key = $this->flashdata_key.':old:'.$key;
- $value = $this->userdata($old_flashdata_key);
+ $value = $this->userdata($this->flashdata_key.':old:'.$key);
- $new_flashdata_key = $this->flashdata_key.':new:'.$key;
- $this->set_userdata($new_flashdata_key, $value);
+ $this->set_userdata($this->flashdata_key.':new:'.$key, $value);
}
// ------------------------------------------------------------------------
@@ -564,14 +571,12 @@ class CI_Session {
/**
* Fetch a specific flashdata item from the session array
*
- * @access public
* @param string
* @return string
*/
- function flashdata($key)
+ public function flashdata($key)
{
- $flashdata_key = $this->flashdata_key.':old:'.$key;
- return $this->userdata($flashdata_key);
+ return $this->userdata($this->flashdata_key.':old:'.$key);
}
// ------------------------------------------------------------------------
@@ -580,10 +585,9 @@ class CI_Session {
* Identifies flashdata as 'old' for removal
* when _flashdata_sweep() runs.
*
- * @access private
* @return void
*/
- function _flashdata_mark()
+ protected function _flashdata_mark()
{
$userdata = $this->all_userdata();
foreach ($userdata as $name => $value)
@@ -591,8 +595,7 @@ class CI_Session {
$parts = explode(':new:', $name);
if (is_array($parts) && count($parts) === 2)
{
- $new_name = $this->flashdata_key.':old:'.$parts[1];
- $this->set_userdata($new_name, $value);
+ $this->set_userdata($this->flashdata_key.':old:'.$parts[1], $value);
$this->unset_userdata($name);
}
}
@@ -603,11 +606,9 @@ class CI_Session {
/**
* Removes all flashdata marked as 'old'
*
- * @access private
* @return void
*/
-
- function _flashdata_sweep()
+ protected function _flashdata_sweep()
{
$userdata = $this->all_userdata();
foreach ($userdata as $key => $value)
@@ -625,22 +626,13 @@ class CI_Session {
/**
* Get the "now" time
*
- * @access private
* @return string
*/
- function _get_time()
+ protected function _get_time()
{
- if (strtolower($this->time_reference) == 'gmt')
- {
- $now = time();
- $time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));
- }
- else
- {
- $time = time();
- }
-
- return $time;
+ return (strtolower($this->time_reference) === 'gmt')
+ ? mktime(gmdate('H'), gmdate('i'), gmdate('s'), gmdate('m'), gmdate('d'), gmdate('Y'))
+ : time();
}
// --------------------------------------------------------------------
@@ -648,10 +640,9 @@ class CI_Session {
/**
* Write the session cookie
*
- * @access public
* @return void
*/
- function _set_cookie($cookie_data = NULL)
+ protected function _set_cookie($cookie_data = NULL)
{
if (is_null($cookie_data))
{
@@ -675,13 +666,13 @@ class CI_Session {
// Set the cookie
setcookie(
- $this->sess_cookie_name,
- $cookie_data,
- $expire,
- $this->cookie_path,
- $this->cookie_domain,
- $this->cookie_secure
- );
+ $this->sess_cookie_name,
+ $cookie_data,
+ $expire,
+ $this->cookie_path,
+ $this->cookie_domain,
+ $this->cookie_secure
+ );
}
// --------------------------------------------------------------------
@@ -692,34 +683,32 @@ class CI_Session {
* This function first converts any slashes found in the array to a temporary
* marker, so when it gets unserialized the slashes will be preserved
*
- * @access private
* @param array
* @return string
*/
- function _serialize($data)
+ protected function _serialize($data)
{
if (is_array($data))
{
array_walk_recursive($data, array(&$this, '_escape_slashes'));
}
- else
+ elseif (is_string($data))
{
- if (is_string($data))
- {
- $data = str_replace('\\', '{{slash}}', $data);
- }
+ $data = str_replace('\\', '{{slash}}', $data);
}
return serialize($data);
}
-
+
/**
* Escape slashes
*
* This function converts any slashes found into a temporary marker
*
- * @access private
+ * @param string
+ * @param string
+ * @return void
*/
- function _escape_slashes(&$val, $key)
+ protected function _escape_slashes(&$val, $key)
{
if (is_string($val))
{
@@ -735,13 +724,12 @@ class CI_Session {
* This function unserializes a data string, then converts any
* temporary slash markers back to actual slashes
*
- * @access private
* @param array
* @return string
*/
- function _unserialize($data)
+ protected function _unserialize($data)
{
- $data = @unserialize(strip_slashes($data));
+ $data = @unserialize(strip_slashes(trim($data)));
if (is_array($data))
{
@@ -749,17 +737,21 @@ class CI_Session {
return $data;
}
- return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data;
+ return is_string($data) ? str_replace('{{slash}}', '\\', $data) : $data;
}
-
+
+ // --------------------------------------------------------------------
+
/**
* Unescape slashes
*
* This function converts any slash markers back into actual slashes
*
- * @access private
+ * @param string
+ * @param string
+ * @return void
*/
- function _unescape_slashes(&$val, $key)
+ protected function _unescape_slashes(&$val, $key)
{
if (is_string($val))
{
@@ -775,10 +767,9 @@ class CI_Session {
* This deletes expired session rows from database
* if the probability percentage is met
*
- * @access public
* @return void
*/
- function _sess_gc()
+ protected function _sess_gc()
{
if ($this->sess_use_database != TRUE)
{
@@ -790,16 +781,14 @@ class CI_Session {
{
$expire = $this->now - $this->sess_expiration;
- $this->CI->db->where("last_activity < {$expire}");
+ $this->CI->db->where('last_activity < '.$expire);
$this->CI->db->delete($this->sess_table_name);
log_message('debug', 'Session garbage collection performed.');
}
}
-
}
-// END Session Class
/* End of file Session.php */
-/* Location: ./system/libraries/Session.php */ \ No newline at end of file
+/* Location: ./system/libraries/Session.php */