From c4e266b87f39d521ff1002fefa9df809c6b9bd61 Mon Sep 17 00:00:00 2001 From: Darren Hill Date: Tue, 30 Aug 2011 15:40:27 -0400 Subject: Added Session driver with native PHP sessions and original-flavor CI cookie sessions --- system/libraries/Session/Session.php | 601 +++++++++++++++++++++ .../libraries/Session/drivers/Session_cookie.php | 583 ++++++++++++++++++++ .../libraries/Session/drivers/Session_native.php | 190 +++++++ 3 files changed, 1374 insertions(+) create mode 100755 system/libraries/Session/Session.php create mode 100755 system/libraries/Session/drivers/Session_cookie.php create mode 100755 system/libraries/Session/drivers/Session_native.php (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php new file mode 100755 index 000000000..7aaf706a1 --- /dev/null +++ b/system/libraries/Session/Session.php @@ -0,0 +1,601 @@ +session or $this->session). + * In keeping with the CI_Driver methodology, multiple drivers may be loaded, although this might be a bit confusing. + * The Session library class keeps track of the most recently loaded driver as "current" to call for driver methods. + * Ideally, one driver is loaded and all calls go directly through the main library interface. However, any methods + * called through the specific driver will switch the "current" driver to itself before invoking the library method + * (which will then call back into the driver for low-level operations). So, alternation between two drivers can be + * achieved by specifying which driver to use for each call (e.g.: $this->session->native->set_userdata('foo', 'bar'); + * $this->session->cookie->userdata('foo'); $this->session->native->unset_userdata('foo');). Notice in the previous + * example that the _native_ userdata value 'foo' would be set to 'bar', which would NOT be returned by the call for + * the _cookie_ userdata 'foo', nor would the _cookie_ value be unset by the call to unset the _native_ 'foo' value. + * + * @package CodeIgniter + * @subpackage Libraries + * @category Sessions + * @author Darren Hill (DChill) + * @link http://codeigniter.com/user_guide/libraries/sessions.html + */ +final class Session extends CI_Driver_Library { + public $params = array(); + private $current = null; + private $userdata = array(); + + const FLASHDATA_KEY = 'flash'; + const FLASHDATA_NEW = ':new:'; + const FLASHDATA_OLD = ':old:'; + const FLASHDATA_EXP = ':exp:'; + const EXPIRATION_KEY = '__expirations'; + const TEMP_EXP_DEF = 300; + + /** + * Session constructor + * + * The constructor loads the configured driver ('sess_driver' in config.php or as a parameter), running + * routines in its constructor, and manages flashdata aging. + * + * @param array Configuration parameters + */ + public function __construct(array $params = array()) + { + log_message('debug', 'Session Class Initialized'); + + // Get valid drivers list + $CI =& get_instance(); + $this->valid_drivers = array('Session_Native', 'Session_Cookie'); + $key = 'sess_valid_drivers'; + $drivers = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); + if ($drivers) + { + if (!is_array($drivers)) $drivers = array($drivers); + + // Add driver names to valid list + foreach ($drivers as $driver) + { + if (!in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers))) + { + $this->valid_drivers[] = $driver; + } + } + } + + // Get driver to load + $key = 'sess_driver'; + $driver = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); + if (!$driver) $driver = 'Native'; + if (!in_array('session_'.strtolower($driver), array_map('strtolower', $this->valid_drivers))) + { + $this->valid_drivers[] = 'Session_'.$driver; + } + + // Save a copy of parameters in case drivers need access + $this->params = $params; + + // Load driver and get array reference + $this->load_driver($driver); + $this->userdata =& $this->current->get_userdata(); + + // Delete 'old' flashdata (from last request) + $this->_flashdata_sweep(); + + // Mark all new flashdata as old (data will be deleted before next request) + $this->_flashdata_mark(); + + // Delete expired tempdata + $this->_tempdata_sweep(); + + log_message('debug', 'Session routines successfully run'); + } + + /** + * Loads session storage driver + * + * @param string Driver classname + * @return object Loaded driver object + */ + public function load_driver($driver) + { + // Save reference to most recently loaded driver as library default + $this->current = parent::load_driver($driver); + return $this->current; + } + + /** + * Select default session storage driver + * + * @param string Driver classname + * @return void + */ + public function select_driver($driver) + { + // Validate driver name + $lowername = strtolower($driver); + if (in_array($lowername, array_map('strtolower', $this->valid_drivers))) + { + // See if regular or lowercase variant is loaded + if (class_exists($driver)) + { + $this->current = $this->$driver; + } + else if (class_exists($lowername)) + { + $this->current = $this->$lowername; + } + else + { + $this->load_driver($driver); + } + } + } + + /** + * Destroy the current session + * + * @return void + */ + public function sess_destroy() + { + // Just call destroy on driver + $this->current->sess_destroy(); + } + + /** + * Regenerate the current session + * + * @param boolean Destroy session data flag (default: false) + * @return void + */ + public function sess_regenerate($destroy = false) + { + // Just call regenerate on driver + $this->current->sess_regenerate($destroy); + } + + /** + * Fetch a specific item from the session array + * + * @param string Item key + * @return string Item value + */ + public function userdata($item) + { + // Return value or FALSE if not found + return (!isset($this->userdata[$item])) ? FALSE : $this->userdata[$item]; + } + + /** + * Fetch all session data + * + * @return array User data array + */ + public function all_userdata() + { + // Return entire array + return (!isset($this->userdata)) ? FALSE : $this->userdata; + } + + /** + * Add or change data in the "userdata" array + * + * @param mixed Item name or array of items + * @param string Item value or empty string + * @return void + */ + public function set_userdata($newdata = array(), $newval = '') + { + // Wrap params as array if singular + if (is_string($newdata)) + { + $newdata = array($newdata => $newval); + } + + // Set each name/value pair + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + $this->userdata[$key] = $val; + } + } + + // Tell driver data changed + $this->current->sess_save(); + } + + /** + * Delete a session variable from the "userdata" array + * + * @param mixed Item name or array of item names + * @return void + */ + public function unset_userdata($newdata = array()) + { + // Wrap single name as array + if (is_string($newdata)) + { + $newdata = array($newdata => ''); + } + + // Unset each item name + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + unset($this->userdata[$key]); + } + } + + // Tell driver data changed + $this->current->sess_save(); + } + + /** + * Determine if an item exists + * + * @param string Item name + * @return boolean + */ + public function has_userdata($item) + { + // Check for item name + return isset($this->userdata[$item]); + } + + /** + * Add or change flashdata, only available until the next request + * + * @param mixed Item name or array of items + * @param string Item value or empty string + * @return void + */ + public function set_flashdata($newdata = array(), $newval = '') + { + // Wrap item as array if singular + if (is_string($newdata)) + { + $newdata = array($newdata => $newval); + } + + // Prepend each key name and set value + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key; + $this->set_userdata($flashdata_key, $val); + } + } + } + + /** + * Keeps existing flashdata available to next request. + * + * @param string Item key + * @return void + */ + public function keep_flashdata($key) + { + // 'old' flashdata gets removed. Here we mark all + // flashdata as 'new' to preserve it from _flashdata_sweep() + $old_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; + $value = $this->userdata($old_flashdata_key); + + $new_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key; + $this->set_userdata($new_flashdata_key, $value); + } + + /** + * Fetch a specific flashdata item from the session array + * + * @param string Item key + * @return string + */ + public function flashdata($key) + { + // Prepend key and retrieve value + $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; + return $this->userdata($flashdata_key); + } + + /** + * Add or change tempdata, only available + * until expiration + * + * @param mixed Item name or array of items + * @param string Item value or empty string + * @param int Item lifetime in seconds or 0 for default + * @return void + */ + public function set_tempdata($newdata = array(), $newval = '', $expire = 0) + { + // Set expiration time + $expire = time() + ($expire ? $expire : self::TEMP_EXP_DEF); + + // Wrap item as array if singular + if (is_string($newdata)) + { + $newdata = array($newdata => $newval); + } + + // Get or create expiration list + $expirations = $this->userdata(self::EXPIRATION_KEY); + if (!$expirations) + { + $expirations = array(); + } + + // Prepend each key name and set value + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key; + $expirations[$tempdata_key] = $expire; + $this->set_userdata($tempdata_key, $val); + } + } + + // Update expiration list + $this->set_userdata(self::EXPIRATION_KEY, $expirations); + } + + /** + * Delete a temporary session variable from the "userdata" array + * + * @param mixed Item name or array of item names + * @return void + */ + public function unset_tempdata($newdata = array()) + { + // Get expirations list + $expirations = $this->userdata(self::EXPIRATION_KEY); + if (!$expirations || !count($expirations)) + { + // Nothing to do + return; + } + + // Wrap single name as array + if (is_string($newdata)) + { + $newdata = array($newdata => ''); + } + + // Prepend each item name and unset + if (count($newdata) > 0) + { + foreach ($newdata as $key => $val) + { + $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key; + unset($expirations[$tempdata_key]); + $this->unset_userdata($tempdata_key); + } + } + + // Update expiration list + $this->set_userdata(self::EXPIRATION_KEY, $expirations); + } + + /** + * Fetch a specific tempdata item from the session array + * + * @param string Item key + * @return string + */ + public function tempdata($key) + { + // Prepend key and return value + $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key; + return $this->userdata($tempdata_key); + } + + /** + * Identifies flashdata as 'old' for removal + * when _flashdata_sweep() runs. + * + * @access private + * @return void + */ + private function _flashdata_mark() + { + $userdata = $this->all_userdata(); + foreach ($userdata as $name => $value) + { + $parts = explode(self::FLASHDATA_NEW, $name); + if (is_array($parts) && count($parts) === 2) + { + $new_name = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1]; + $this->set_userdata($new_name, $value); + $this->unset_userdata($name); + } + } + } + + /** + * Removes all flashdata marked as 'old' + * + * @access private + * @return void + */ + private function _flashdata_sweep() + { + $userdata = $this->all_userdata(); + foreach ($userdata as $key => $value) + { + if (strpos($key, self::FLASHDATA_OLD)) + { + $this->unset_userdata($key); + } + } + } + + /** + * Removes all expired tempdata + * + * @access private + * @return void + */ + private function _tempdata_sweep() + { + // Get expirations list + $expirations = $this->userdata(self::EXPIRATION_KEY); + if (!$expirations || !count($expirations)) + { + // Nothing to do + return; + } + + // Unset expired elements + $now = time(); + $userdata = $this->all_userdata(); + foreach ($userdata as $key => $value) + { + if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now) + { + unset($expirations[$key]); + $this->unset_userdata($key); + } + } + + // Update expiration list + $this->set_userdata(self::EXPIRATION_KEY, $expirations); + } +} +// END Session Class + + +/** + * SessionDriver Class + * + * Extend this class to make a new Session driver. + * A Session driver basically manages an array of name/value pairs with some sort of storage mechanism. + * To make a new driver, derive from (extend) SessionDriver. Overload the initialize method and read or create + * session data. Then implement a save handler to write changed data to storage (sess_save), a destroy handler + * to remove deleted data (sess_destroy), and an access handler to expose the data (get_userdata). + * Put your driver in the libraries/Session/drivers folder anywhere in the loader paths. This includes the application + * directory, the system directory, or any path you add with $CI->load->add_package_path(). + * Your driver must be named Session_, where is capitalized, and your filename must be Session_.EXT, + * preferably also capitalized. (e.g.: Session_Foo in libraries/Session/drivers/Session_Foo.php) + * Then specify the driver by setting 'sess_driver' in your config file or as a parameter when loading the Session + * object. (e.g.: $config['sess_driver'] = 'foo'; OR $CI->load->driver('session', array('sess_driver' => 'foo')); ) + * Already provided are the Native driver, which manages the native PHP $_SESSION array, and + * the Cookie driver, which manages the data in a browser cookie, with optional extra storage in a database table. + * + * @package CodeIgniter + * @subpackage Libraries + * @category Sessions + * @author Darren Hill (DChill) + */ +abstract class SessionDriver extends CI_Driver { + /** + * Decorate + * + * Decorates the child with the parent driver lib's methods and properties + * + * @param object Parent library object + * @return void + */ + public function decorate($parent) + { + // Call base class decorate first + parent::decorate($parent); + + // Call initialize method now that driver has access to $this->parent + $this->initialize(); + } + + /** + * __call magic method + * + * Handles access to the parent driver library's methods + * + * @param string Library method name + * @param array Method arguments (default: none) + * @return mixed + */ + public function __call($method, $args = array()) + { + // Make sure the parent library uses this driver + $this->parent->select_driver(get_class($this)); + return parent::__call($method, $args); + } + + /** + * Initialize driver + * + * @return void + */ + protected function initialize() + { + // Overload this method to implement initialization + } + + /** + * Save the session data + * + * Data in the array has changed - perform any storage synchronization necessary + * The child class MUST implement this abstract method! + * + * @return void + */ + abstract public function sess_save(); + + /** + * Destroy the current session + * + * Clean up storage for this session - it has been terminated + * The child class MUST implement this abstract method! + * + * @return void + */ + abstract public function sess_destroy(); + + /** + * Regenerate the current session + * + * Regenerate the session id + * The child class MUST implement this abstract method! + * + * @param boolean Destroy session data flag (default: false) + * @return void + */ + abstract public function sess_regenerate($destroy = false); + + /** + * Get a reference to user data array + * + * Give array access to the main Session object + * The child class MUST implement this abstract method! + * + * @return array Reference to userdata + */ + abstract public function &get_userdata(); +} +// END SessionDriver Class + + +/* End of file Session.php */ +/* Location: ./system/libraries/Session/Session.php */ +?> diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php new file mode 100755 index 000000000..0982b1e01 --- /dev/null +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -0,0 +1,583 @@ +CI =& get_instance(); + + // Set all the session preferences, which can either be set + // manually via the $params array above or via the config file + foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', + 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', + 'cookie_domain', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key) + { + $this->$key = (isset($this->parent->params[$key])) ? $this->parent->params[$key] : $this->CI->config->item($key); + } + + if ($this->encryption_key == '') + { + show_error('In order to use the Cookie Session driver you are required to set an encryption key '. + 'in your config file.'); + } + + // Load the string helper so we can use the strip_slashes() function + $this->CI->load->helper('string'); + + // Do we need encryption? If so, load the encryption class + if ($this->sess_encrypt_cookie == TRUE) + { + $this->CI->load->library('encrypt'); + } + + // 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 + $this->now = $this->_get_time(); + + // Set the session length. If the session expiration is + // set to zero we'll set the expiration two years from now. + if ($this->sess_expiration == 0) + { + $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. + if ( ! $this->_sess_read()) + { + $this->_sess_create(); + } + else + { + $this->_sess_update(); + } + + // Delete expired sessions if necessary + $this->_sess_gc(); + } + + /** + * Write the session data + * + * @return void + */ + public function sess_save() + { + // Are we saving custom data to the DB? If not, all we do is update the cookie + if ($this->sess_use_database === FALSE) + { + $this->_set_cookie(); + return; + } + + // set the custom userdata, the session data we will set in a second + $custom_userdata = $this->all_userdata(); + $cookie_userdata = array(); + + // Before continuing, we need to determine if there is any custom data to deal with. + // Let's determine this by removing the default indexes to see if there's anything left in the array + // and set the session data while we're at it + foreach (array('session_id','ip_address','user_agent','last_activity') as $val) + { + unset($custom_userdata[$val]); + $cookie_userdata[$val] = $this->userdata($val); + } + + // 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) + { + $custom_userdata = ''; + } + else + { + // Serialize the custom data array so we can store it + $custom_userdata = $this->_serialize($custom_userdata); + } + + // Run the update query + $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 + // _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); + } + + /** + * Destroy the current session + * + * @return void + */ + public function sess_destroy() + { + // Kill the session DB row + if ($this->sess_use_database === TRUE && $this->has_userdata('session_id')) + { + $this->CI->db->where('session_id', $this->userdata['session_id']); + $this->CI->db->delete($this->sess_table_name); + } + + // Kill the cookie + setcookie($this->sess_cookie_name, addslashes(serialize(array())), ($this->now - 31500000), + $this->cookie_path, $this->cookie_domain, 0); + } + + /** + * Regenerate the current session + * + * Regenerate the session id + * + * @param boolean Destroy session data flag (default: false) + * @return void + */ + public function sess_regenerate($destroy = false) + { + // Check destroy flag + if ($destroy) + { + // Destroy old session and create new one + $this->sess_destroy(); + $this->_sess_create(); + } + else + { + // Just force an update to recreate the id + $this->_sess_update(true); + } + } + + /** + * Get a reference to user data array + * + * @return array - Reference to userdata + */ + public function &get_userdata() + { + // Return reference to array + return $this->userdata; + } + + /** + * Fetch the current session data if it exists + * + * @access private + * @return bool + */ + private function _sess_read() + { + // Fetch the cookie + $session = $this->CI->input->cookie($this->sess_cookie_name); + + // No cookie? Goodbye cruel world!... + if ($session === FALSE) + { + log_message('debug', 'A session cookie was not found.'); + return FALSE; + } + + // Decrypt the cookie data + if ($this->sess_encrypt_cookie == TRUE) + { + $session = $this->CI->encrypt->decode($session); + } + else + { + // encryption was not used, so we need to check the md5 hash + $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 + 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.'); + $this->sess_destroy(); + return FALSE; + } + } + + // Unserialize the session array + $session = $this->_unserialize($session); + + // Is the session data we unserialized an array with the correct format? + if ( ! is_array($session) || ! isset($session['session_id']) || ! isset($session['ip_address']) || + ! isset($session['user_agent']) || ! isset($session['last_activity'])) + { + $this->sess_destroy(); + return FALSE; + } + + // Is the session current? + if (($session['last_activity'] + $this->sess_expiration) < $this->now()) + { + $this->sess_destroy(); + return FALSE; + } + + // 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 && + trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50))) + { + $this->sess_destroy(); + return FALSE; + } + + // Is there a corresponding session in the DB? + if ($this->sess_use_database === TRUE) + { + $this->CI->db->where('session_id', $session['session_id']); + + if ($this->sess_match_ip == TRUE) + { + $this->CI->db->where('ip_address', $session['ip_address']); + } + + if ($this->sess_match_useragent == TRUE) + { + $this->CI->db->where('user_agent', $session['user_agent']); + } + + $query = $this->CI->db->get($this->sess_table_name); + + // No result? Kill it! + if ($query->num_rows() == 0) + { + $this->sess_destroy(); + return FALSE; + } + + // Is there custom data? If so, add it to the main session array + $row = $query->row(); + if (isset($row->user_data) && $row->user_data != '') + { + $custom_data = $this->_unserialize($row->user_data); + + if (is_array($custom_data)) + { + foreach ($custom_data as $key => $val) + { + $session[$key] = $val; + } + } + } + } + + // Session is valid! + $this->userdata = $session; + unset($session); + + return TRUE; + } + + /** + * Create a new session + * + * @access private + * @return void + */ + private function _sess_create() + { + $sessid = ''; + while (strlen($sessid) < 32) + { + $sessid .= mt_rand(0, mt_getrandmax()); + } + + // To make the session ID even more secure we'll combine it with the user's IP + $sessid .= $this->CI->input->ip_address(); + + $this->set_userdata('session_id', md5(uniqid($sessid, TRUE))); + $this->set_userdata('ip_address', $this->CI->input->ip_address()); + $this->set_userdata('user_agent', substr($this->CI->input->user_agent(), 0, 50)); + $this->set_userdata('last_activity',$this->now()); + + + // Save the data to the DB if needed + if ($this->sess_use_database === TRUE) + { + $this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->all_userdata())); + } + + // Write the cookie + $this->_set_cookie(); + } + + /** + * Update an existing session + * + * @access private + * @param boolean Force update flag (default: false) + * @return void + */ + private function _sess_update($force = false) + { + // We only update the session every five minutes by default (unless forced) + if (!$force && ($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now()) + { + return; + } + + // 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) + { + $new_sessid .= mt_rand(0, mt_getrandmax()); + } + + // 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->set_userdata('session_id', $new_sessid); + $this->set_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) + { + // 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->now(), 'session_id' => $new_sessid), + array('session_id' => $old_sessid))); + } + + // Write the cookie + $this->_set_cookie($cookie_data); + } + + /** + * Get the "now" time + * + * @access private + * @return int + */ + private 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; + } + + /** + * Write the session cookie + * + * @access private + * @param array Cookie name/value pairs + * @return void + */ + private function _set_cookie(array $cookie_data = NULL) + { + if (is_null($cookie_data)) + { + $cookie_data = $this->all_userdata(); + } + + // Serialize the userdata for the cookie + $cookie_data = $this->_serialize($cookie_data); + + if ($this->sess_encrypt_cookie == TRUE) + { + $cookie_data = $this->CI->encrypt->encode($cookie_data); + } + else + { + // if encryption is not used, we provide an md5 hash to prevent userside tampering + $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key); + } + + $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time(); + + // Set the cookie + setcookie($this->sess_cookie_name, $cookie_data, $expire, $this->cookie_path, $this->cookie_domain, 0); + } + + /** + * Serialize an array + * + * 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 mixed Data to serialize + * @return string + */ + private function _serialize($data) + { + if (is_array($data)) + { + foreach ($data as $key => $val) + { + if (is_string($val)) + { + $data[$key] = str_replace('\\', '{{slash}}', $val); + } + } + } + else + { + if (is_string($data)) + { + $data = str_replace('\\', '{{slash}}', $data); + } + } + + return serialize($data); + } + + /** + * Unserialize + * + * This function unserializes a data string, then converts any + * temporary slash markers back to actual slashes + * + * @access private + * @param string Data to unserialize + * @return mixed + */ + private function _unserialize($data) + { + $data = @unserialize(strip_slashes($data)); + + if (is_array($data)) + { + foreach ($data as $key => $val) + { + if (is_string($val)) + { + $data[$key] = str_replace('{{slash}}', '\\', $val); + } + } + + return $data; + } + + return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data; + } + + /** + * Garbage collection + * + * This deletes expired session rows from database + * if the probability percentage is met + * + * @access private + * @return void + */ + private function _sess_gc() + { + if ($this->sess_use_database != TRUE) + { + return; + } + + srand(time()); + if ((rand() % 100) < self::gc_probability) + { + $expire = $this->now() - $this->sess_expiration; + + $this->CI->db->where('last_activity < '.$expire); + $this->CI->db->delete($this->sess_table_name); + + log_message('debug', 'Session garbage collection performed.'); + } + } +} +// END Session_Cookie Class + +/* End of file Session_cookie.php */ +/* Location: ./system/libraries/Session/Session.php */ +?> diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php new file mode 100755 index 000000000..df588175f --- /dev/null +++ b/system/libraries/Session/drivers/Session_native.php @@ -0,0 +1,190 @@ +parent->params[$key]) ? $this->parent->params[$key] : $CI->config->item($key); + } + + // Set session name, if specified + if ($config['sess_cookie_name']) + { + $name = $config['sess_cookie_name']; + if ($config['cookie_prefix']) + { + // Prepend cookie prefix + $name = $config['cookie_prefix'].$name; + } + session_name($name); + } + + // Set expiration, path, and domain + $expire = 7200; + $path = '/'; + $domain = ''; + if ($config['sess_expiration'] !== FALSE) + { + // Default to 2 years if expiration is "0" + $expire = ($config['sess_expiration'] == 0) ? (60*60*24*365*2) : $config['sess_expiration']; + } + if ($config['cookie_path']) + { + // Use specified path + $path = $config['cookie_path']; + } + if ($config['cookie_domain']) + { + // Use specified domain + $domain = $config['cookie_domain']; + } + session_set_cookie_params($config['sess_expire_on_close'] ? 0 : $expire, $path, $domain); + + // Start session + session_start(); + + // Check session expiration, ip, and agent + $now = time(); + $destroy = FALSE; + if (isset($_SESSION['last_activity']) && ($_SESSION['last_activity'] + $expire) < $now) + { + // Expired - destroy + $destroy = TRUE; + } + else if ($config['sess_match_ip'] == TRUE && isset($_SESSION['ip_address']) && + $_SESSION['ip_address'] != $CI->input->ip_address()) + { + // IP doesn't match - destroy + $destroy = TRUE; + } + else if ($config['sess_match_useragent'] == TRUE && isset($_SESSION['user_agent']) && + $_SESSION['user_agent'] != trim(substr($CI->input->user_agent(), 0, 50))) + { + // Agent doesn't match - destroy + $destroy = TRUE; + } + + // Destroy expired or invalid session + if ($destroy) + { + // Clear old session and start new + $this->sess_destroy(); + session_start(); + } + + // Set activity time + $_SESSION['last_activity'] = $now; + + // Set matching values as required + if ($config['sess_match_ip'] == TRUE && !isset($_SESSION['ip_address'])) + { + // Store user IP address + $_SESSION['ip_address'] = $CI->input->ip_address(); + } + if ($config['sess_match_useragent'] == TRUE && !isset($_SESSION['user_agent'])) + { + // Store user agent string + $_SESSION['user_agent'] = trim(substr($CI->input->user_agent(), 0, 50)); + } + } + + /** + * Save the session data + * + * @access public + * @return void + */ + public function sess_save() + { + // Nothing to do - changes to $_SESSION are automatically saved + } + + /** + * Destroy the current session + * + * @access public + * @return void + */ + public function sess_destroy() + { + // Cleanup session + $_SESSION = array(); + $name = session_name(); + if (isset($_COOKIE[$name])) + { + // Clear session cookie + $params = session_get_cookie_params(); + setcookie($name, '', time() - 42000, $params['path'], $params['domain']); + unset($_COOKIE[$name]); + } + session_destroy(); + } + + /** + * Regenerate the current session + * + * Regenerate the session id + * + * @access public + * @param boolean Destroy session data flag (default: false) + * @return void + */ + public function sess_regenerate($destroy = false) + { + // Just regenerate id, passing destroy flag + session_regenerate_id($destroy); + } + + /** + * Get a reference to user data array + * + * @access public + * @return array Reference to userdata + */ + public function &get_userdata() + { + // Just return reference to $_SESSION + return $_SESSION; + } +} +// END Session_Native Class + + +/* End of file Session_native.php */ +/* Location: ./system/libraries/Session/Session.php */ +?> -- cgit v1.2.3-24-g4f1b From 5073a375951f09b654f6b991df7ca04e1f88d93c Mon Sep 17 00:00:00 2001 From: Darren Hill Date: Wed, 31 Aug 2011 13:54:19 -0400 Subject: Better style guide compliance --- system/libraries/Session/Session.php | 136 ++++++++++----------- .../libraries/Session/drivers/Session_cookie.php | 8 +- .../libraries/Session/drivers/Session_native.php | 8 +- 3 files changed, 76 insertions(+), 76 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 7aaf706a1..dacc249c5 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -15,15 +15,15 @@ /** - * Session Class + * CI_Session Class * * The user interface defined by EllisLabs, now with puggable drivers to manage different storage mechanisms. - * By default, the Native PHP session driver will load, but the 'sess_driver' config/param item (see above) can be - * used to specify the 'Cookie' driver, or any other you might create. + * By default, the native PHP session driver will load, but the 'sess_driver' config/param item (see above) can be + * used to specify the 'cookie' driver, or any other you might create. * Once loaded, this driver setup is a drop-in replacement for the former CI_Session library, taking its place as the * 'session' member of the global controller framework (e.g.: $CI->session or $this->session). * In keeping with the CI_Driver methodology, multiple drivers may be loaded, although this might be a bit confusing. - * The Session library class keeps track of the most recently loaded driver as "current" to call for driver methods. + * The CI_Session library class keeps track of the most recently loaded driver as "current" to call for driver methods. * Ideally, one driver is loaded and all calls go directly through the main library interface. However, any methods * called through the specific driver will switch the "current" driver to itself before invoking the library method * (which will then call back into the driver for low-level operations). So, alternation between two drivers can be @@ -35,10 +35,10 @@ * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author Darren Hill (DChill) + * @author ExpressionEngine Dev Team * @link http://codeigniter.com/user_guide/libraries/sessions.html */ -final class Session extends CI_Driver_Library { +final class CI_Session extends CI_Driver_Library { public $params = array(); private $current = null; private $userdata = array(); @@ -51,20 +51,20 @@ final class Session extends CI_Driver_Library { const TEMP_EXP_DEF = 300; /** - * Session constructor + * CI_Session constructor * * The constructor loads the configured driver ('sess_driver' in config.php or as a parameter), running * routines in its constructor, and manages flashdata aging. * - * @param array Configuration parameters + * @param array Configuration parameters */ public function __construct(array $params = array()) { - log_message('debug', 'Session Class Initialized'); + log_message('debug', 'CI_Session Class Initialized'); // Get valid drivers list $CI =& get_instance(); - $this->valid_drivers = array('Session_Native', 'Session_Cookie'); + $this->valid_drivers = array('CI_Session_native', 'CI_Session_cookie'); $key = 'sess_valid_drivers'; $drivers = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); if ($drivers) @@ -84,7 +84,7 @@ final class Session extends CI_Driver_Library { // Get driver to load $key = 'sess_driver'; $driver = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); - if (!$driver) $driver = 'Native'; + if (!$driver) $driver = 'native'; if (!in_array('session_'.strtolower($driver), array_map('strtolower', $this->valid_drivers))) { $this->valid_drivers[] = 'Session_'.$driver; @@ -106,14 +106,14 @@ final class Session extends CI_Driver_Library { // Delete expired tempdata $this->_tempdata_sweep(); - log_message('debug', 'Session routines successfully run'); + log_message('debug', 'CI_Session routines successfully run'); } /** * Loads session storage driver * - * @param string Driver classname - * @return object Loaded driver object + * @param string Driver classname + * @return object Loaded driver object */ public function load_driver($driver) { @@ -125,8 +125,8 @@ final class Session extends CI_Driver_Library { /** * Select default session storage driver * - * @param string Driver classname - * @return void + * @param string Driver classname + * @return void */ public function select_driver($driver) { @@ -153,7 +153,7 @@ final class Session extends CI_Driver_Library { /** * Destroy the current session * - * @return void + * @return void */ public function sess_destroy() { @@ -164,8 +164,8 @@ final class Session extends CI_Driver_Library { /** * Regenerate the current session * - * @param boolean Destroy session data flag (default: false) - * @return void + * @param boolean Destroy session data flag (default: false) + * @return void */ public function sess_regenerate($destroy = false) { @@ -176,8 +176,8 @@ final class Session extends CI_Driver_Library { /** * Fetch a specific item from the session array * - * @param string Item key - * @return string Item value + * @param string Item key + * @return string Item value */ public function userdata($item) { @@ -199,9 +199,9 @@ final class Session extends CI_Driver_Library { /** * Add or change data in the "userdata" array * - * @param mixed Item name or array of items - * @param string Item value or empty string - * @return void + * @param mixed Item name or array of items + * @param string Item value or empty string + * @return void */ public function set_userdata($newdata = array(), $newval = '') { @@ -227,8 +227,8 @@ final class Session extends CI_Driver_Library { /** * Delete a session variable from the "userdata" array * - * @param mixed Item name or array of item names - * @return void + * @param mixed Item name or array of item names + * @return void */ public function unset_userdata($newdata = array()) { @@ -254,8 +254,8 @@ final class Session extends CI_Driver_Library { /** * Determine if an item exists * - * @param string Item name - * @return boolean + * @param string Item name + * @return boolean */ public function has_userdata($item) { @@ -266,9 +266,9 @@ final class Session extends CI_Driver_Library { /** * Add or change flashdata, only available until the next request * - * @param mixed Item name or array of items - * @param string Item value or empty string - * @return void + * @param mixed Item name or array of items + * @param string Item value or empty string + * @return void */ public function set_flashdata($newdata = array(), $newval = '') { @@ -292,12 +292,12 @@ final class Session extends CI_Driver_Library { /** * Keeps existing flashdata available to next request. * - * @param string Item key - * @return void + * @param string Item key + * @return void */ 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() $old_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; $value = $this->userdata($old_flashdata_key); @@ -309,8 +309,8 @@ final class Session extends CI_Driver_Library { /** * Fetch a specific flashdata item from the session array * - * @param string Item key - * @return string + * @param string Item key + * @return string */ public function flashdata($key) { @@ -323,10 +323,10 @@ final class Session extends CI_Driver_Library { * Add or change tempdata, only available * until expiration * - * @param mixed Item name or array of items - * @param string Item value or empty string - * @param int Item lifetime in seconds or 0 for default - * @return void + * @param mixed Item name or array of items + * @param string Item value or empty string + * @param int Item lifetime in seconds or 0 for default + * @return void */ public function set_tempdata($newdata = array(), $newval = '', $expire = 0) { @@ -364,8 +364,8 @@ final class Session extends CI_Driver_Library { /** * Delete a temporary session variable from the "userdata" array * - * @param mixed Item name or array of item names - * @return void + * @param mixed Item name or array of item names + * @return void */ public function unset_tempdata($newdata = array()) { @@ -401,8 +401,8 @@ final class Session extends CI_Driver_Library { /** * Fetch a specific tempdata item from the session array * - * @param string Item key - * @return string + * @param string Item key + * @return string */ public function tempdata($key) { @@ -483,32 +483,32 @@ final class Session extends CI_Driver_Library { $this->set_userdata(self::EXPIRATION_KEY, $expirations); } } -// END Session Class +// END CI_Session Class /** - * SessionDriver Class + * CI_Session_driver Class * - * Extend this class to make a new Session driver. - * A Session driver basically manages an array of name/value pairs with some sort of storage mechanism. - * To make a new driver, derive from (extend) SessionDriver. Overload the initialize method and read or create + * Extend this class to make a new CI_Session driver. + * A CI_Session driver basically manages an array of name/value pairs with some sort of storage mechanism. + * To make a new driver, derive from (extend) CI_Session_driver. Overload the initialize method and read or create * session data. Then implement a save handler to write changed data to storage (sess_save), a destroy handler * to remove deleted data (sess_destroy), and an access handler to expose the data (get_userdata). - * Put your driver in the libraries/Session/drivers folder anywhere in the loader paths. This includes the application - * directory, the system directory, or any path you add with $CI->load->add_package_path(). - * Your driver must be named Session_, where is capitalized, and your filename must be Session_.EXT, - * preferably also capitalized. (e.g.: Session_Foo in libraries/Session/drivers/Session_Foo.php) - * Then specify the driver by setting 'sess_driver' in your config file or as a parameter when loading the Session + * Put your driver in the libraries/Session/drivers folder anywhere in the loader paths. This includes the + * application directory, the system directory, or any path you add with $CI->load->add_package_path(). + * Your driver must be named CI_Session_, and your filename must be Session_.php, + * preferably also capitalized. (e.g.: CI_Session_foo in libraries/Session/drivers/Session_foo.php) + * Then specify the driver by setting 'sess_driver' in your config file or as a parameter when loading the CI_Session * object. (e.g.: $config['sess_driver'] = 'foo'; OR $CI->load->driver('session', array('sess_driver' => 'foo')); ) * Already provided are the Native driver, which manages the native PHP $_SESSION array, and * the Cookie driver, which manages the data in a browser cookie, with optional extra storage in a database table. * - * @package CodeIgniter - * @subpackage Libraries + * @package CodeIgniter + * @subpackage Libraries * @category Sessions - * @author Darren Hill (DChill) + * @author ExpressionEngine Dev Team */ -abstract class SessionDriver extends CI_Driver { +abstract class CI_Session_driver extends CI_Driver { /** * Decorate * @@ -531,8 +531,8 @@ abstract class SessionDriver extends CI_Driver { * * Handles access to the parent driver library's methods * - * @param string Library method name - * @param array Method arguments (default: none) + * @param string Library method name + * @param array Method arguments (default: none) * @return mixed */ public function __call($method, $args = array()) @@ -545,7 +545,7 @@ abstract class SessionDriver extends CI_Driver { /** * Initialize driver * - * @return void + * @return void */ protected function initialize() { @@ -558,7 +558,7 @@ abstract class SessionDriver extends CI_Driver { * Data in the array has changed - perform any storage synchronization necessary * The child class MUST implement this abstract method! * - * @return void + * @return void */ abstract public function sess_save(); @@ -568,7 +568,7 @@ abstract class SessionDriver extends CI_Driver { * Clean up storage for this session - it has been terminated * The child class MUST implement this abstract method! * - * @return void + * @return void */ abstract public function sess_destroy(); @@ -578,22 +578,22 @@ abstract class SessionDriver extends CI_Driver { * Regenerate the session id * The child class MUST implement this abstract method! * - * @param boolean Destroy session data flag (default: false) - * @return void + * @param boolean Destroy session data flag (default: false) + * @return void */ abstract public function sess_regenerate($destroy = false); /** * Get a reference to user data array * - * Give array access to the main Session object + * Give array access to the main CI_Session object * The child class MUST implement this abstract method! * - * @return array Reference to userdata + * @return array Reference to userdata */ abstract public function &get_userdata(); } -// END SessionDriver Class +// END CI_Session_driver Class /* End of file Session.php */ diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 0982b1e01..d26ab0432 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -24,9 +24,9 @@ * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author ExpressionEngine Dev Team and Darren Hill (DChill42) + * @author ExpressionEngine Dev Team */ -class Session_Cookie extends SessionDriver { +class CI_Session_cookie extends CI_Session_driver { private $sess_encrypt_cookie = FALSE; private $sess_use_database = FALSE; private $sess_table_name = ''; @@ -576,8 +576,8 @@ class Session_Cookie extends SessionDriver { } } } -// END Session_Cookie Class +// END CI_Session_cookie Class /* End of file Session_cookie.php */ -/* Location: ./system/libraries/Session/Session.php */ +/* Location: ./system/libraries/Session/drivers/Session_cookie.php */ ?> diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index df588175f..37da3445a 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -22,9 +22,9 @@ * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author Darren Hill (DChill) + * @author ExpressionEngine Dev Team */ -class Session_Native extends SessionDriver { +class CI_Session_native extends CI_Session_driver { /** * Initialize session driver object * @@ -182,9 +182,9 @@ class Session_Native extends SessionDriver { return $_SESSION; } } -// END Session_Native Class +// END CI_Session_native Class /* End of file Session_native.php */ -/* Location: ./system/libraries/Session/Session.php */ +/* Location: ./system/libraries/Session/drivers/Session_native.php */ ?> -- cgit v1.2.3-24-g4f1b From a2ae6571e55d5a3d23645e96929eea996e9f0499 Mon Sep 17 00:00:00 2001 From: Darren Hill Date: Thu, 1 Sep 2011 07:36:26 -0400 Subject: Made private members protected for inheritance --- system/libraries/Session/Session.php | 18 +++--- .../libraries/Session/drivers/Session_cookie.php | 66 +++++++++++----------- .../libraries/Session/drivers/Session_native.php | 28 ++++----- 3 files changed, 56 insertions(+), 56 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index dacc249c5..7c340ccca 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -38,10 +38,10 @@ * @author ExpressionEngine Dev Team * @link http://codeigniter.com/user_guide/libraries/sessions.html */ -final class CI_Session extends CI_Driver_Library { +class CI_Session extends CI_Driver_Library { public $params = array(); - private $current = null; - private $userdata = array(); + protected $current = null; + protected $userdata = array(); const FLASHDATA_KEY = 'flash'; const FLASHDATA_NEW = ':new:'; @@ -415,10 +415,10 @@ final class CI_Session extends CI_Driver_Library { * Identifies flashdata as 'old' for removal * when _flashdata_sweep() runs. * - * @access private + * @access protected * @return void */ - private function _flashdata_mark() + protected function _flashdata_mark() { $userdata = $this->all_userdata(); foreach ($userdata as $name => $value) @@ -436,10 +436,10 @@ final class CI_Session extends CI_Driver_Library { /** * Removes all flashdata marked as 'old' * - * @access private + * @access protected * @return void */ - private function _flashdata_sweep() + protected function _flashdata_sweep() { $userdata = $this->all_userdata(); foreach ($userdata as $key => $value) @@ -454,10 +454,10 @@ final class CI_Session extends CI_Driver_Library { /** * Removes all expired tempdata * - * @access private + * @access protected * @return void */ - private function _tempdata_sweep() + protected function _tempdata_sweep() { // Get expirations list $expirations = $this->userdata(self::EXPIRATION_KEY); diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index d26ab0432..334218ec2 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -27,23 +27,23 @@ * @author ExpressionEngine Dev Team */ class CI_Session_cookie extends CI_Session_driver { - private $sess_encrypt_cookie = FALSE; - private $sess_use_database = FALSE; - private $sess_table_name = ''; - private $sess_expiration = 7200; - private $sess_expire_on_close = FALSE; - private $sess_match_ip = FALSE; - private $sess_match_useragent = TRUE; - private $sess_cookie_name = 'ci_session'; - private $cookie_prefix = ''; - private $cookie_path = ''; - private $cookie_domain = ''; - private $sess_time_to_update = 300; - private $encryption_key = ''; - private $time_reference = 'time'; - private $userdata = array(); - private $CI = null; - private $now = 0; + protected $sess_encrypt_cookie = FALSE; + protected $sess_use_database = FALSE; + protected $sess_table_name = ''; + protected $sess_expiration = 7200; + protected $sess_expire_on_close = FALSE; + protected $sess_match_ip = FALSE; + protected $sess_match_useragent = TRUE; + protected $sess_cookie_name = 'ci_session'; + protected $cookie_prefix = ''; + protected $cookie_path = ''; + protected $cookie_domain = ''; + protected $sess_time_to_update = 300; + protected $encryption_key = ''; + protected $time_reference = 'time'; + protected $userdata = array(); + protected $CI = null; + protected $now = 0; const gc_probability = 5; @@ -224,10 +224,10 @@ class CI_Session_cookie extends CI_Session_driver { /** * Fetch the current session data if it exists * - * @access private + * @access protected * @return bool */ - private function _sess_read() + protected function _sess_read() { // Fetch the cookie $session = $this->CI->input->cookie($this->sess_cookie_name); @@ -343,10 +343,10 @@ class CI_Session_cookie extends CI_Session_driver { /** * Create a new session * - * @access private + * @access protected * @return void */ - private function _sess_create() + protected function _sess_create() { $sessid = ''; while (strlen($sessid) < 32) @@ -376,11 +376,11 @@ class CI_Session_cookie extends CI_Session_driver { /** * Update an existing session * - * @access private + * @access protected * @param boolean Force update flag (default: false) * @return void */ - private function _sess_update($force = false) + protected function _sess_update($force = false) { // We only update the session every five minutes by default (unless forced) if (!$force && ($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now()) @@ -433,10 +433,10 @@ class CI_Session_cookie extends CI_Session_driver { /** * Get the "now" time * - * @access private + * @access protected * @return int */ - private function _get_time() + protected function _get_time() { if (strtolower($this->time_reference) == 'gmt') { @@ -455,11 +455,11 @@ class CI_Session_cookie extends CI_Session_driver { /** * Write the session cookie * - * @access private + * @access protected * @param array Cookie name/value pairs * @return void */ - private function _set_cookie(array $cookie_data = NULL) + protected function _set_cookie(array $cookie_data = NULL) { if (is_null($cookie_data)) { @@ -491,11 +491,11 @@ class CI_Session_cookie extends CI_Session_driver { * 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 + * @access protected * @param mixed Data to serialize * @return string */ - private function _serialize($data) + protected function _serialize($data) { if (is_array($data)) { @@ -524,11 +524,11 @@ class CI_Session_cookie extends CI_Session_driver { * This function unserializes a data string, then converts any * temporary slash markers back to actual slashes * - * @access private + * @access protected * @param string Data to unserialize * @return mixed */ - private function _unserialize($data) + protected function _unserialize($data) { $data = @unserialize(strip_slashes($data)); @@ -554,10 +554,10 @@ class CI_Session_cookie extends CI_Session_driver { * This deletes expired session rows from database * if the probability percentage is met * - * @access private + * @access protected * @return void */ - private function _sess_gc() + protected function _sess_gc() { if ($this->sess_use_database != TRUE) { diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 37da3445a..c7130b688 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -5,11 +5,11 @@ * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter - * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com - * @since Version 2.0 + * @since Version 2.0 * @filesource */ @@ -22,13 +22,13 @@ * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author ExpressionEngine Dev Team + * @author ExpressionEngine Dev Team */ class CI_Session_native extends CI_Session_driver { /** * Initialize session driver object * - * @access protected + * @access protected * @return void */ protected function initialize() @@ -126,8 +126,8 @@ class CI_Session_native extends CI_Session_driver { /** * Save the session data * - * @access public - * @return void + * @access public + * @return void */ public function sess_save() { @@ -137,8 +137,8 @@ class CI_Session_native extends CI_Session_driver { /** * Destroy the current session * - * @access public - * @return void + * @access public + * @return void */ public function sess_destroy() { @@ -160,9 +160,9 @@ class CI_Session_native extends CI_Session_driver { * * Regenerate the session id * - * @access public - * @param boolean Destroy session data flag (default: false) - * @return void + * @access public + * @param boolean Destroy session data flag (default: false) + * @return void */ public function sess_regenerate($destroy = false) { @@ -173,8 +173,8 @@ class CI_Session_native extends CI_Session_driver { /** * Get a reference to user data array * - * @access public - * @return array Reference to userdata + * @access public + * @return array Reference to userdata */ public function &get_userdata() { -- cgit v1.2.3-24-g4f1b From 42b77a9a1a5d4ec7ceb94b421b12af9c442769ba Mon Sep 17 00:00:00 2001 From: dchill42 Date: Mon, 23 Jul 2012 11:28:42 -0400 Subject: Made cookie driver default and did miniscule code cleanup on drivers --- system/libraries/Session/Session.php | 2 +- system/libraries/Session/drivers/Session_cookie.php | 9 ++------- system/libraries/Session/drivers/Session_native.php | 3 --- 3 files changed, 3 insertions(+), 11 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 94fb4b10a..474ca9c7a 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -84,7 +84,7 @@ class CI_Session extends CI_Driver_Library { // Get driver to load $key = 'sess_driver'; $driver = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); - if (!$driver) $driver = 'native'; + if (!$driver) $driver = 'cookie'; if (!in_array('session_'.strtolower($driver), array_map('strtolower', $this->valid_drivers))) { $this->valid_drivers[] = 'Session_'.$driver; diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 0dc109bd1..255a1ae3e 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -39,7 +39,6 @@ * @link http://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_cookie extends CI_Session_driver { - /** * Whether to encrypt the session cookie * @@ -152,7 +151,6 @@ class CI_Session_cookie extends CI_Session_driver { */ public $time_reference = 'local'; - /** * Session data * @@ -186,7 +184,7 @@ class CI_Session_cookie extends CI_Session_driver { $this->CI =& get_instance(); // Set all the session preferences, which can either be set - // manually via the $params array above or via the config file + // manually via the $params array or via the config file foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'cookie_secure', 'cookie_httponly', 'sess_time_to_update', 'time_reference', 'cookie_prefix', @@ -527,9 +525,7 @@ class CI_Session_cookie extends CI_Session_driver { // 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 - */ + // 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; @@ -752,7 +748,6 @@ class CI_Session_cookie extends CI_Session_driver { log_message('debug', 'Session garbage collection performed.'); } } - } /* End of file Session_cookie.php */ diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 09fb7f999..7fbe9f89e 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -182,9 +182,6 @@ class CI_Session_native extends CI_Session_driver { return $_SESSION; } } -// END CI_Session_native Class - /* End of file Session_native.php */ /* Location: ./system/libraries/Session/drivers/Session_native.php */ -?> -- cgit v1.2.3-24-g4f1b From 77ee3fdac34d317b600a269e0b845588c88fa4c5 Mon Sep 17 00:00:00 2001 From: dchill42 Date: Tue, 24 Jul 2012 11:50:01 -0400 Subject: Cleaned up bangs and lowercase booleans, and fixed userdata return on not found to NULL --- system/libraries/Session/Session.php | 18 +++++++++--------- system/libraries/Session/drivers/Session_cookie.php | 2 +- system/libraries/Session/drivers/Session_native.php | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 474ca9c7a..9c887d88e 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -69,12 +69,12 @@ class CI_Session extends CI_Driver_Library { $drivers = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); if ($drivers) { - if (!is_array($drivers)) $drivers = array($drivers); + if ( ! is_array($drivers)) $drivers = array($drivers); // Add driver names to valid list foreach ($drivers as $driver) { - if (!in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers))) + if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers))) { $this->valid_drivers[] = $driver; } @@ -84,8 +84,8 @@ class CI_Session extends CI_Driver_Library { // Get driver to load $key = 'sess_driver'; $driver = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); - if (!$driver) $driver = 'cookie'; - if (!in_array('session_'.strtolower($driver), array_map('strtolower', $this->valid_drivers))) + if ( ! $driver) $driver = 'cookie'; + if ( ! in_array('session_'.strtolower($driver), array_map('strtolower', $this->valid_drivers))) { $this->valid_drivers[] = 'Session_'.$driver; } @@ -182,7 +182,7 @@ class CI_Session extends CI_Driver_Library { public function userdata($item) { // Return value or FALSE if not found - return (!isset($this->userdata[$item])) ? FALSE : $this->userdata[$item]; + return ( ! isset($this->userdata[$item])) ? NULL : $this->userdata[$item]; } /** @@ -193,7 +193,7 @@ class CI_Session extends CI_Driver_Library { public function all_userdata() { // Return entire array - return (!isset($this->userdata)) ? FALSE : $this->userdata; + return ( ! isset($this->userdata)) ? NULL : $this->userdata; } /** @@ -362,7 +362,7 @@ class CI_Session extends CI_Driver_Library { // Get or create expiration list $expirations = $this->userdata(self::EXPIRATION_KEY); - if (!$expirations) + if ( ! $expirations) { $expirations = array(); } @@ -392,7 +392,7 @@ class CI_Session extends CI_Driver_Library { { // Get expirations list $expirations = $this->userdata(self::EXPIRATION_KEY); - if (!$expirations || !count($expirations)) + if ( ! $expirations || ! count($expirations)) { // Nothing to do return; @@ -482,7 +482,7 @@ class CI_Session extends CI_Driver_Library { { // Get expirations list $expirations = $this->userdata(self::EXPIRATION_KEY); - if (!$expirations || !count($expirations)) + if ( ! $expirations || ! count($expirations)) { // Nothing to do return; diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 255a1ae3e..e39ada052 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -516,7 +516,7 @@ class CI_Session_cookie extends CI_Session_driver { protected function _sess_update($force = FALSE) { // We only update the session every five minutes by default (unless forced) - if (!$force && ($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now) + if ( ! $force && ($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now) { return; } diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 7fbe9f89e..8388e06b5 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -161,10 +161,10 @@ class CI_Session_native extends CI_Session_driver { * Regenerate the session id * * @access public - * @param boolean Destroy session data flag (default: false) + * @param boolean Destroy session data flag (default: FALSE) * @return void */ - public function sess_regenerate($destroy = false) + public function sess_regenerate($destroy = FALSE) { // Just regenerate id, passing destroy flag session_regenerate_id($destroy); -- cgit v1.2.3-24-g4f1b From c58722535e0358367f351c168480ef98a033264c Mon Sep 17 00:00:00 2001 From: dchill42 Date: Mon, 30 Jul 2012 14:53:11 -0400 Subject: Fixed _parent references and several minor bugs --- system/libraries/Session/Session.php | 14 +++++----- .../libraries/Session/drivers/Session_cookie.php | 30 +++++++++++++++++++--- .../libraries/Session/drivers/Session_native.php | 2 +- 3 files changed, 34 insertions(+), 12 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 9c887d88e..734334249 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -64,7 +64,7 @@ class CI_Session extends CI_Driver_Library { // Get valid drivers list $CI =& get_instance(); - $this->valid_drivers = array('CI_Session_native', 'CI_Session_cookie'); + $this->valid_drivers = array('Session_native', 'Session_cookie'); $key = 'sess_valid_drivers'; $drivers = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); if ($drivers) @@ -131,7 +131,7 @@ class CI_Session extends CI_Driver_Library { public function select_driver($driver) { // Validate driver name - $lowername = strtolower($driver); + $lowername = strtolower(str_replace('CI_', '', $driver)); if (in_array($lowername, array_map('strtolower', $this->valid_drivers))) { // See if regular or lowercase variant is loaded @@ -177,11 +177,11 @@ class CI_Session extends CI_Driver_Library { * Fetch a specific item from the session array * * @param string Item key - * @return string Item value + * @return string Item value or NULL if not found */ public function userdata($item) { - // Return value or FALSE if not found + // Return value or NULL if not found return ( ! isset($this->userdata[$item])) ? NULL : $this->userdata[$item]; } @@ -208,7 +208,7 @@ class CI_Session extends CI_Driver_Library { // loop through all userdata foreach ($this->all_userdata() as $key => $val) { - // if it contains flashdata, add it + // if it contains flashdata, add it if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE) { $out[$key] = $val; @@ -543,7 +543,7 @@ abstract class CI_Session_driver extends CI_Driver { // Call base class decorate first parent::decorate($parent); - // Call initialize method now that driver has access to $this->parent + // Call initialize method now that driver has access to $this->_parent $this->initialize(); } @@ -559,7 +559,7 @@ abstract class CI_Session_driver extends CI_Driver { public function __call($method, $args = array()) { // Make sure the parent library uses this driver - $this->parent->select_driver(get_class($this)); + $this->_parent->select_driver(get_class($this)); return parent::__call($method, $args); } diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index e39ada052..19ccd417d 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -190,13 +190,13 @@ class CI_Session_cookie extends CI_Session_driver { 'cookie_domain', 'cookie_secure', 'cookie_httponly', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key) { - $this->$key = isset($this->parent->params[$key]) ? $this->parent->params[$key] : + $this->$key = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] : $this->CI->config->item($key); } if ($this->encryption_key === '') { - show_error('In order to use the Session Cookie driver you are required to set an encryption key '. + show_error('In order to use the Cookie Session driver you are required to set an encryption key '. 'in your config file.'); } @@ -309,7 +309,7 @@ class CI_Session_cookie extends CI_Session_driver { } // Kill the cookie - setcookie($this->sess_cookie_name, addslashes(serialize(array())), ($this->now - 31500000), + $this->_setcookie($this->sess_cookie_name, addslashes(serialize(array())), ($this->now - 31500000), $this->cookie_path, $this->cookie_domain, 0); // Kill session data @@ -632,10 +632,32 @@ class CI_Session_cookie extends CI_Session_driver { $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time(); // Set the cookie - setcookie($this->sess_cookie_name, $cookie_data, $expire, $this->cookie_path, $this->cookie_domain, + $this->_setcookie($this->sess_cookie_name, $cookie_data, $expire, $this->cookie_path, $this->cookie_domain, $this->cookie_secure, $this->cookie_httponly); } + /** + * Set a cookie with the system + * + * This abstraction of the setcookie call allows overriding for unit testing + * + * @access protected + * @param string Cookie name + * @param string Cookie value + * @param int Expiration time + * @param string Cookie path + * @param string Cookie domain + * @param bool Secure connection flag + * @param bool HTTP protocol only flag + * @return void + */ + protected function _setcookie($name, $value = '', $expire = 0, $path = '', $domain = '', $secure = false, + $httponly = false) + { + // Set the cookie + setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); + } + /** * Serialize an array * diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 8388e06b5..27db942eb 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -39,7 +39,7 @@ class CI_Session_native extends CI_Session_driver { foreach (array('sess_cookie_name', 'sess_expire_on_close', 'sess_expiration', 'sess_match_ip', 'sess_match_useragent', 'cookie_prefix', 'cookie_path', 'cookie_domain') as $key) { - $config[$key] = isset($this->parent->params[$key]) ? $this->parent->params[$key] : $CI->config->item($key); + $config[$key] = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] : $CI->config->item($key); } // Set session name, if specified -- cgit v1.2.3-24-g4f1b From b185537938061bf9b8f132f9f3c3992e12902be8 Mon Sep 17 00:00:00 2001 From: dchill42 Date: Tue, 31 Jul 2012 09:32:23 -0400 Subject: Fixed userdata synchronization, loaded driver check, and all_flashdata keys --- system/libraries/Session/Session.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 734334249..68819a665 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -95,7 +95,6 @@ class CI_Session extends CI_Driver_Library { // Load driver and get array reference $this->load_driver($driver); - $this->userdata =& $this->current->get_userdata(); // Delete 'old' flashdata (from last request) $this->_flashdata_sweep(); @@ -119,6 +118,7 @@ class CI_Session extends CI_Driver_Library { { // Save reference to most recently loaded driver as library default $this->current = parent::load_driver($driver); + $this->userdata =& $this->current->get_userdata(); return $this->current; } @@ -134,14 +134,12 @@ class CI_Session extends CI_Driver_Library { $lowername = strtolower(str_replace('CI_', '', $driver)); if (in_array($lowername, array_map('strtolower', $this->valid_drivers))) { - // See if regular or lowercase variant is loaded - if (class_exists($driver)) - { - $this->current = $this->$driver; - } - else if (class_exists($lowername)) + // See if driver is loaded + $child = str_replace($this->lib_name.'_', '', $driver); + if (isset($this->$child)) { - $this->current = $this->$lowername; + $this->current = $this->$child; + $this->userdata =& $this->current->get_userdata(); } else { @@ -211,6 +209,7 @@ class CI_Session extends CI_Driver_Library { // if it contains flashdata, add it if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE) { + $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key); $out[$key] = $val; } } -- cgit v1.2.3-24-g4f1b From 2642920e4781db091309ab97d0ff43c22e7c7e44 Mon Sep 17 00:00:00 2001 From: dchill42 Date: Tue, 31 Jul 2012 10:55:07 -0400 Subject: Damn, missed files on last commit --- system/libraries/Session/Session.php | 16 ++++-- .../libraries/Session/drivers/Session_cookie.php | 61 +++++++++++++++++----- .../libraries/Session/drivers/Session_native.php | 16 ++++-- 3 files changed, 72 insertions(+), 21 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 68819a665..41539a598 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -64,7 +64,10 @@ class CI_Session extends CI_Driver_Library { // Get valid drivers list $CI =& get_instance(); - $this->valid_drivers = array('Session_native', 'Session_cookie'); + $this->valid_drivers = array( + 'Session_native', + 'Session_cookie' + ); $key = 'sess_valid_drivers'; $drivers = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); if ($drivers) @@ -116,7 +119,7 @@ class CI_Session extends CI_Driver_Library { */ public function load_driver($driver) { - // Save reference to most recently loaded driver as library default + // Save reference to most recently loaded driver as library default and sync userdata $this->current = parent::load_driver($driver); $this->userdata =& $this->current->get_userdata(); return $this->current; @@ -138,11 +141,13 @@ class CI_Session extends CI_Driver_Library { $child = str_replace($this->lib_name.'_', '', $driver); if (isset($this->$child)) { + // Make driver current and sync userdata $this->current = $this->$child; - $this->userdata =& $this->current->get_userdata(); + $this->userdata =& $this->current->get_userdata(); } else { + // Load new driver $this->load_driver($driver); } } @@ -167,8 +172,9 @@ class CI_Session extends CI_Driver_Library { */ public function sess_regenerate($destroy = false) { - // Just call regenerate on driver + // Call regenerate on driver and resync userdata $this->current->sess_regenerate($destroy); + $this->userdata =& $this->current->get_userdata(); } /** @@ -209,7 +215,7 @@ class CI_Session extends CI_Driver_Library { // if it contains flashdata, add it if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE) { - $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key); + $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key); $out[$key] = $val; } } diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 19ccd417d..8ac92e432 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -72,7 +72,7 @@ class CI_Session_cookie extends CI_Session_driver { * * @var bool */ - public $sess_expire_on_close = FALSE; + public $sess_expire_on_close = FALSE; /** * Whether to match session on ip address @@ -86,7 +86,7 @@ class CI_Session_cookie extends CI_Session_driver { * * @var bool */ - public $sess_match_useragent = TRUE; + public $sess_match_useragent = TRUE; /** * Name of session cookie @@ -107,7 +107,7 @@ class CI_Session_cookie extends CI_Session_driver { * * @var string */ - public $cookie_path = ''; + public $cookie_path = ''; /** * Session cookie domain @@ -156,7 +156,7 @@ class CI_Session_cookie extends CI_Session_driver { * * @var array */ - public $userdata = array(); + public $userdata = array(); /** * Reference to CodeIgniter instance @@ -185,10 +185,25 @@ class CI_Session_cookie extends CI_Session_driver { // Set all the session preferences, which can either be set // manually via the $params array or via the config file - foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', - 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', - 'cookie_domain', 'cookie_secure', 'cookie_httponly', 'sess_time_to_update', 'time_reference', 'cookie_prefix', - 'encryption_key') as $key) + $prefs = array( + 'sess_encrypt_cookie', + 'sess_use_database', + 'sess_table_name', + 'sess_expiration', + 'sess_expire_on_close', + 'sess_match_ip', + 'sess_match_useragent', + 'sess_cookie_name', + 'cookie_path', + 'cookie_domain', + 'cookie_secure', + 'cookie_httponly', + 'sess_time_to_update', + 'time_reference', + 'cookie_prefix', + 'encryption_key' + ); + foreach ($prefs as $key) { $this->$key = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] : $this->CI->config->item($key); @@ -265,7 +280,13 @@ class CI_Session_cookie extends CI_Session_driver { // Before continuing, we need to determine if there is any custom data to deal with. // Let's determine this by removing the default indexes to see if there's anything left in the array // and set the session data while we're at it - foreach (array('session_id','ip_address','user_agent','last_activity') as $val) + $defaults = array( + 'session_id', + 'ip_address', + 'user_agent', + 'last_activity' + ); + foreach ($defaults as $val) { unset($custom_userdata[$val]); $cookie_userdata[$val] = $this->userdata[$val]; @@ -285,8 +306,10 @@ class CI_Session_cookie extends CI_Session_driver { // Run the update query $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)); + $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 // _set_cookie() function. Normally that function will store $this->userdata, but @@ -535,7 +558,13 @@ class CI_Session_cookie extends CI_Session_driver { { // set cookie explicitly to only have our session data $cookie_data = array(); - foreach (array('session_id','ip_address','user_agent','last_activity') as $val) + $defaults = array( + 'session_id', + 'ip_address', + 'user_agent', + 'last_activity' + ); + foreach ($defaults as $val) { $cookie_data[$val] = $this->userdata[$val]; } @@ -570,7 +599,13 @@ class CI_Session_cookie extends CI_Session_driver { { // set cookie explicitly to only have our session data $cookie_data = array(); - foreach (array('session_id','ip_address','user_agent','last_activity') as $val) + $defaults = array( + 'session_id', + 'ip_address', + 'user_agent', + 'last_activity' + ); + foreach ($defaults as $val) { $cookie_data[$val] = $this->userdata[$val]; } diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 27db942eb..356deb4dc 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -36,10 +36,20 @@ class CI_Session_native extends CI_Session_driver { // Get config parameters $config = array(); $CI =& get_instance(); - foreach (array('sess_cookie_name', 'sess_expire_on_close', 'sess_expiration', 'sess_match_ip', - 'sess_match_useragent', 'cookie_prefix', 'cookie_path', 'cookie_domain') as $key) + $prefs = array( + 'sess_cookie_name', + 'sess_expire_on_close', + 'sess_expiration', + 'sess_match_ip', + 'sess_match_useragent', + 'cookie_prefix', + 'cookie_path', + 'cookie_domain' + ); + foreach ($prefs as $key) { - $config[$key] = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] : $CI->config->item($key); + $config[$key] = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] : + $CI->config->item($key); } // Set session name, if specified -- cgit v1.2.3-24-g4f1b From f79afb57b7f7bac62a79638f195560739e4a80ef Mon Sep 17 00:00:00 2001 From: dchill42 Date: Wed, 8 Aug 2012 12:03:46 -0400 Subject: Added session_id to userdata and applied sess_time_to_update --- system/libraries/Session/drivers/Session_native.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 356deb4dc..04c985574 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -42,6 +42,7 @@ class CI_Session_native extends CI_Session_driver { 'sess_expiration', 'sess_match_ip', 'sess_match_useragent', + 'sess_time_to_update', 'cookie_prefix', 'cookie_path', 'cookie_domain' @@ -117,6 +118,14 @@ class CI_Session_native extends CI_Session_driver { session_start(); } + // Check for update time + if ($config['sess_time_to_update'] && isset($_SESSION['last_activity']) && + ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now) + { + // Regenerate ID, but don't destroy session + $this->sess_regenerate(FALSE); + } + // Set activity time $_SESSION['last_activity'] = $now; @@ -131,6 +140,9 @@ class CI_Session_native extends CI_Session_driver { // Store user agent string $_SESSION['user_agent'] = trim(substr($CI->input->user_agent(), 0, 50)); } + + // Make session ID available + $_SESSION['session_id'] = session_id(); } /** @@ -178,6 +190,7 @@ class CI_Session_native extends CI_Session_driver { { // Just regenerate id, passing destroy flag session_regenerate_id($destroy); + $_SESSION['session_id'] = session_id(); } /** -- cgit v1.2.3-24-g4f1b From 0e88408d0965ee539d9af3ff7eca5415d3276c74 Mon Sep 17 00:00:00 2001 From: dchill42 Date: Sat, 11 Aug 2012 20:10:17 -0400 Subject: Updated comments about default driver --- system/libraries/Session/Session.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 41539a598..97eab803f 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -18,8 +18,8 @@ * CI_Session Class * * The user interface defined by EllisLabs, now with puggable drivers to manage different storage mechanisms. - * By default, the native PHP session driver will load, but the 'sess_driver' config/param item (see above) can be - * used to specify the 'cookie' driver, or any other you might create. + * By default, the cookie session driver will load, but the 'sess_driver' config/param item (see above) can be + * used to specify the 'native' driver, or any other you might create. * Once loaded, this driver setup is a drop-in replacement for the former CI_Session library, taking its place as the * 'session' member of the global controller framework (e.g.: $CI->session or $this->session). * In keeping with the CI_Driver methodology, multiple drivers may be loaded, although this might be a bit confusing. -- cgit v1.2.3-24-g4f1b From aee9265602c3bb30a1f7f3dfd562b9b36cc612a4 Mon Sep 17 00:00:00 2001 From: dchill42 Date: Sun, 26 Aug 2012 21:45:35 -0400 Subject: Fixed select_driver(), cookie sess_destroy(), and native cookie name conflict --- system/libraries/Session/Session.php | 11 +++++++---- system/libraries/Session/drivers/Session_cookie.php | 2 +- system/libraries/Session/drivers/Session_native.php | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 97eab803f..1f24456a4 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -141,14 +141,17 @@ class CI_Session extends CI_Driver_Library { $child = str_replace($this->lib_name.'_', '', $driver); if (isset($this->$child)) { - // Make driver current and sync userdata - $this->current = $this->$child; - $this->userdata =& $this->current->get_userdata(); + // See if driver is already current + if ($this->$child !== $this->current) { + // Make driver current and sync userdata + $this->current = $this->$child; + $this->userdata =& $this->current->get_userdata(); + } } else { // Load new driver - $this->load_driver($driver); + $this->load_driver($child); } } } diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 8ac92e432..89e81386f 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -325,7 +325,7 @@ class CI_Session_cookie extends CI_Session_driver { public function sess_destroy() { // Kill the session DB row - if ($this->sess_use_database === TRUE && $this->has_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); diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 04c985574..8ba8e749a 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -56,7 +56,8 @@ class CI_Session_native extends CI_Session_driver { // Set session name, if specified if ($config['sess_cookie_name']) { - $name = $config['sess_cookie_name']; + // Differentiate name from cookie driver with '_id' suffix + $name = $config['sess_cookie_name'].'_id'; if ($config['cookie_prefix']) { // Prepend cookie prefix -- cgit v1.2.3-24-g4f1b From 3cecd8234d3bb9045e9cc41e15f603a6e87c5fac Mon Sep 17 00:00:00 2001 From: dchill42 Date: Tue, 28 Aug 2012 21:37:27 -0400 Subject: Extracted cookie database saves to shutdown and cleaned up code Signed-off-by: dchill42 --- system/libraries/Session/Session.php | 35 +++ .../libraries/Session/drivers/Session_cookie.php | 269 ++++++++++----------- 2 files changed, 169 insertions(+), 135 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 1f24456a4..1195ed955 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -42,6 +42,7 @@ class CI_Session extends CI_Driver_Library { public $params = array(); protected $current = null; protected $userdata = array(); + protected $loaded = array(); const FLASHDATA_KEY = 'flash'; const FLASHDATA_NEW = ':new:'; @@ -111,6 +112,22 @@ class CI_Session extends CI_Driver_Library { log_message('debug', 'CI_Session routines successfully run'); } + /** + * CI_Session destructor + * + * The destructor calls shutdown() on each loaded driver + */ + public function __destruct() + { + // Call shutdown for each loaded driver + foreach ($this->loaded as $driver) + { + $this->$driver->shutdown(); + } + + log_message('debug', 'CI_Session Class Shutdown'); + } + /** * Loads session storage driver * @@ -122,6 +139,14 @@ class CI_Session extends CI_Driver_Library { // Save reference to most recently loaded driver as library default and sync userdata $this->current = parent::load_driver($driver); $this->userdata =& $this->current->get_userdata(); + + // Mark driver as loaded + if (!in_array($driver, $this->loaded)) + { + $this->loaded[] = $driver; + } + + // Return driver object return $this->current; } @@ -581,6 +606,16 @@ abstract class CI_Session_driver extends CI_Driver { // Overload this method to implement initialization } + /** + * Shut down driver + * + * @return void + */ + public function shutdown() + { + // Overload this method to implement shutdown + } + /** * Save the session data * diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 89e81386f..df3282cee 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -28,9 +28,7 @@ /** * Cookie-based session management driver * - * This is the CI_Session functionality, as written by EllisLab, abstracted out to a driver. - * I have done a little updating for PHP5, and made minor changes to extract this functionality from - * the public interface (now in the Session Library), but effectively this code is unchanged. + * This is the classic CI_Session functionality, as written by EllisLab, abstracted out to a driver. * * @package CodeIgniter * @subpackage Libraries @@ -172,6 +170,25 @@ class CI_Session_cookie extends CI_Session_driver { */ public $now; + /** + * Default userdata keys + * + * @var array + */ + protected $defaults = array( + 'session_id', + 'ip_address', + 'user_agent', + 'last_activity' + ); + + /** + * Data needs DB update flag + * + * @var bool + */ + protected $data_dirty = FALSE; + /** * Initialize session driver object * @@ -224,10 +241,14 @@ class CI_Session_cookie extends CI_Session_driver { $this->CI->load->library('encrypt'); } - // Are we using a database? If so, load it + // Check for database if ($this->sess_use_database === TRUE && $this->sess_table_name !== '') { + // Load database driver $this->CI->load->database(); + + // Register shutdown function + register_shutdown_function(array($this, '_update_db')); } // Set the "now" time. Can either be GMT or server time, based on the config prefs. @@ -259,6 +280,17 @@ class CI_Session_cookie extends CI_Session_driver { $this->_sess_gc(); } + /** + * Shutdown session driver object + * + * @return void + */ + public function shutdown() + { + // Just update the DB + $this->_update_db(); + } + /** * Write the session data * @@ -266,55 +298,15 @@ class CI_Session_cookie extends CI_Session_driver { */ public function sess_save() { - // Are we saving custom data to the DB? If not, all we do is update the cookie + // Check for database if ($this->sess_use_database === FALSE) { - $this->_set_cookie(); - return; - } - - // set the custom userdata, the session data we will set in a second - $custom_userdata = $this->all_userdata(); - $cookie_userdata = array(); - - // Before continuing, we need to determine if there is any custom data to deal with. - // Let's determine this by removing the default indexes to see if there's anything left in the array - // and set the session data while we're at it - $defaults = array( - 'session_id', - 'ip_address', - 'user_agent', - 'last_activity' - ); - foreach ($defaults as $val) - { - unset($custom_userdata[$val]); - $cookie_userdata[$val] = $this->userdata[$val]; + // Mark custom data as dirty so we know to update the DB + $this->data_dirty = TRUE; } - // 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) - { - $custom_userdata = ''; - } - else - { - // Serialize the custom data array so we can store it - $custom_userdata = $this->_serialize($custom_userdata); - } - - // Run the update query - $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 - // _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); + // Write the cookie + $this->_set_cookie(); } /** @@ -327,8 +319,7 @@ class CI_Session_cookie extends CI_Session_driver { // Kill the session DB row 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); + $this->CI->db->delete($this->sess_table_name, array('session_id' => $this->userdata['session_id'])); } // Kill the cookie @@ -392,16 +383,18 @@ class CI_Session_cookie extends CI_Session_driver { return FALSE; } - // Decrypt the cookie data + // Check for encryption if ($this->sess_encrypt_cookie === TRUE) { + // Decrypt the cookie data $session = $this->CI->encrypt->decode($session); } else { - // encryption was not used, so we need to check the md5 hash - $hash = substr($session, strlen($session)-32); // get last 32 chars - $session = substr($session, 0, strlen($session)-32); + // Encryption was not used, so we need to check the md5 hash in the last 32 chars + $len = strlen($session)-32; + $hash = substr($session, $len); + $session = substr($session, 0, $len); // Does the md5 hash match? This is to prevent manipulation of session data in userspace if ($hash !== md5($session.$this->encryption_key)) @@ -478,18 +471,13 @@ class CI_Session_cookie extends CI_Session_driver { if (is_array($custom_data)) { - foreach ($custom_data as $key => $val) - { - $session[$key] = $val; - } + $session = $session + $custom_data; } } } // Session is valid! $this->userdata = $session; - unset($session); - return TRUE; } @@ -501,28 +489,19 @@ class CI_Session_cookie extends CI_Session_driver { */ protected function _sess_create() { - $sessid = ''; - 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(); - + // Initialize userdata $this->userdata = array( - 'session_id' => md5(uniqid($sessid, TRUE)), + 'session_id' => $this->_make_sess_id(), '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 + // Check for database if ($this->sess_use_database === TRUE) { - $this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata)); + // Add empty user_data field and save the data to the DB + $this->CI->db->set('user_data', '')->insert($this->sess_table_name, $this->userdata); } // Write the cookie @@ -544,42 +523,84 @@ class CI_Session_cookie extends CI_Session_driver { 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; + // Update last activity to now + $this->userdata['last_activity'] = $this->now; + + // Save the old session id so we know which DB record to update + $old_sessid = $this->userdata['session_id']; + + // Changing the session ID during an AJAX call causes problems + if ( ! $this->CI->input->is_ajax_request()) + { + // Get new id + $this->userdata['session_id'] = $this->_make_sess_id(); + } - // 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()) + // Check for database + if ($this->sess_use_database === TRUE) { - $this->userdata['last_activity'] = $this->now; + // Update the session ID and last_activity field in the DB + $this->CI->db->update($this->sess_table_name, array( + 'last_activity' => $this->now, + 'session_id' => $this->userdata['session_id'] + ), array('session_id' => $old_sessid)); + } - // 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(); - $defaults = array( - 'session_id', - 'ip_address', - 'user_agent', - 'last_activity' - ); - foreach ($defaults as $val) - { - $cookie_data[$val] = $this->userdata[$val]; - } + // Write the cookie + $this->_set_cookie(); + } - $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']))); + /** + * Update database with current data + * + * This gets called from the shutdown function and also + * registered with PHP to run at the end of the request + * so it's guaranteed to update even when a fatal error + * occurs. The first call makes the update and clears the + * dirty flag so it won't happen twice. + */ + public function _update_db() + { + // Check for database and dirty flag and unsaved + if ($this->sess_use_database === TRUE && $this->data_dirty === TRUE) + { + // Set up activity and data fields to be set + // If we don't find custom data, user_data will remain an empty string + $set = array( + 'last_activity' => $this->userdata['last_activity'], + 'user_data' => '' + ); + + // Get the custom userdata, leaving out the defaults + // (which get stored in the cookie) + $userdata = array_diff_key($this->userdata, $this->defaults); + + // Did we find any custom data? + if ( ! empty($userdata)) + { + // Serialize the custom data array so we can store it + $set['user_data'] = $this->_serialize($userdata); } - return $this->_set_cookie($cookie_data); + // Run the update query + // Any time we change the session id, it gets updated immediately, + // so our where clause below is always safe + $this->CI->db->update($this->sess_table_name, $set, array('session_id' => $this->userdata['session_id'])); + + // Clear dirty flag to prevent double updates + $this->data_dirty = FALSE; + + log_message('debug', 'CI_Session Data Saved To DB'); } + } - // 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']; + /** + * Generate a new session id + * + * @return string Hashed session id + */ + protected function _make_sess_id() + { $new_sessid = ''; do { @@ -590,32 +611,8 @@ class CI_Session_cookie extends CI_Session_driver { // 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 and update the session data array - $this->userdata['session_id'] = $new_sessid = md5(uniqid($new_sessid, TRUE)); - $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(); - $defaults = array( - 'session_id', - 'ip_address', - 'user_agent', - 'last_activity' - ); - foreach ($defaults 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->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid))); - } - - // Write the cookie - $this->_set_cookie($cookie_data); + // Turn it into a hash and return + return md5(uniqid($new_sessid, TRUE)); } /** @@ -641,12 +638,16 @@ class CI_Session_cookie extends CI_Session_driver { * Write the session cookie * * @access protected - * @param array Cookie name/value pairs * @return void */ - protected function _set_cookie(array $cookie_data = NULL) + protected function _set_cookie() { - if (is_null($cookie_data)) + // Get userdata (only defaults if database) + if ($this->sess_use_database === TRUE) + { + $cookie_data = array_intersect_key($this->userdata, $this->defaults); + } + else { $cookie_data = $this->userdata; } @@ -798,9 +799,7 @@ class CI_Session_cookie extends CI_Session_driver { if ((mt_rand(0, $divisor) / $divisor) < $probability) { $expire = $this->now - $this->sess_expiration; - - $this->CI->db->where('last_activity < '.$expire); - $this->CI->db->delete($this->sess_table_name); + $this->CI->db->delete($this->sess_table_name, 'last_activity < '.$expire); log_message('debug', 'Session garbage collection performed.'); } -- cgit v1.2.3-24-g4f1b From 88b636b06dd91807706e2d442d910fe8b6a3b50c Mon Sep 17 00:00:00 2001 From: dchill42 Date: Wed, 29 Aug 2012 08:47:05 -0400 Subject: Fixed defaults and database check, reverted redundant shutdown feature Signed-off-by: dchill42 --- system/libraries/Session/Session.php | 35 ---------------------- .../libraries/Session/drivers/Session_cookie.php | 21 ++++--------- 2 files changed, 5 insertions(+), 51 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 1195ed955..1f24456a4 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -42,7 +42,6 @@ class CI_Session extends CI_Driver_Library { public $params = array(); protected $current = null; protected $userdata = array(); - protected $loaded = array(); const FLASHDATA_KEY = 'flash'; const FLASHDATA_NEW = ':new:'; @@ -112,22 +111,6 @@ class CI_Session extends CI_Driver_Library { log_message('debug', 'CI_Session routines successfully run'); } - /** - * CI_Session destructor - * - * The destructor calls shutdown() on each loaded driver - */ - public function __destruct() - { - // Call shutdown for each loaded driver - foreach ($this->loaded as $driver) - { - $this->$driver->shutdown(); - } - - log_message('debug', 'CI_Session Class Shutdown'); - } - /** * Loads session storage driver * @@ -139,14 +122,6 @@ class CI_Session extends CI_Driver_Library { // Save reference to most recently loaded driver as library default and sync userdata $this->current = parent::load_driver($driver); $this->userdata =& $this->current->get_userdata(); - - // Mark driver as loaded - if (!in_array($driver, $this->loaded)) - { - $this->loaded[] = $driver; - } - - // Return driver object return $this->current; } @@ -606,16 +581,6 @@ abstract class CI_Session_driver extends CI_Driver { // Overload this method to implement initialization } - /** - * Shut down driver - * - * @return void - */ - public function shutdown() - { - // Overload this method to implement shutdown - } - /** * Save the session data * diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index df3282cee..69e5fde14 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -176,10 +176,10 @@ class CI_Session_cookie extends CI_Session_driver { * @var array */ protected $defaults = array( - 'session_id', - 'ip_address', - 'user_agent', - 'last_activity' + 'session_id' => NULL, + 'ip_address' => NULL, + 'user_agent' => NULL, + 'last_activity' => NULL ); /** @@ -280,17 +280,6 @@ class CI_Session_cookie extends CI_Session_driver { $this->_sess_gc(); } - /** - * Shutdown session driver object - * - * @return void - */ - public function shutdown() - { - // Just update the DB - $this->_update_db(); - } - /** * Write the session data * @@ -299,7 +288,7 @@ class CI_Session_cookie extends CI_Session_driver { public function sess_save() { // Check for database - if ($this->sess_use_database === FALSE) + if ($this->sess_use_database === TRUE) { // Mark custom data as dirty so we know to update the DB $this->data_dirty = TRUE; -- cgit v1.2.3-24-g4f1b From 97b0d8331eecd7f3efe3a1c9a93de55a2f26e877 Mon Sep 17 00:00:00 2001 From: dchill42 Date: Tue, 4 Sep 2012 10:09:00 -0400 Subject: Fixed issues #1756 and #1711 Signed-off-by: dchill42 --- system/libraries/Session/drivers/Session_cookie.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 69e5fde14..ce63b976f 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -309,6 +309,7 @@ class CI_Session_cookie extends CI_Session_driver { if ($this->sess_use_database === TRUE && isset($this->userdata['session_id'])) { $this->CI->db->delete($this->sess_table_name, array('session_id' => $this->userdata['session_id'])); + $this->data_dirty = FALSE; } // Kill the cookie @@ -571,11 +572,22 @@ class CI_Session_cookie extends CI_Session_driver { $set['user_data'] = $this->_serialize($userdata); } + // Is caching in effect? Turn it off + $db_cache = $this->CI->db->cache_on; + $this->CI->db->cache_off(); + // Run the update query // Any time we change the session id, it gets updated immediately, // so our where clause below is always safe $this->CI->db->update($this->sess_table_name, $set, array('session_id' => $this->userdata['session_id'])); + // Was caching in effect? + if ($db_cache) + { + // Turn it back on + $this->CI->db->cache_on(); + } + // Clear dirty flag to prevent double updates $this->data_dirty = FALSE; -- cgit v1.2.3-24-g4f1b From cd436e92ec5f9a5d0361fb186bccacb908dbea22 Mon Sep 17 00:00:00 2001 From: dchill42 Date: Tue, 4 Sep 2012 10:15:14 -0400 Subject: That doesn't go there. Put cache fix around correct query. Signed-off-by: dchill42 --- .../libraries/Session/drivers/Session_cookie.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index ce63b976f..52eeddbc4 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -444,8 +444,19 @@ class CI_Session_cookie extends CI_Session_driver { $this->CI->db->where('user_agent', $session['user_agent']); } + // Is caching in effect? Turn it off + $db_cache = $this->CI->db->cache_on; + $this->CI->db->cache_off(); + $query = $this->CI->db->limit(1)->get($this->sess_table_name); + // Was caching in effect? + if ($db_cache) + { + // Turn it back on + $this->CI->db->cache_on(); + } + // No result? Kill it! if ($query->num_rows() === 0) { @@ -572,22 +583,11 @@ class CI_Session_cookie extends CI_Session_driver { $set['user_data'] = $this->_serialize($userdata); } - // Is caching in effect? Turn it off - $db_cache = $this->CI->db->cache_on; - $this->CI->db->cache_off(); - // Run the update query // Any time we change the session id, it gets updated immediately, // so our where clause below is always safe $this->CI->db->update($this->sess_table_name, $set, array('session_id' => $this->userdata['session_id'])); - // Was caching in effect? - if ($db_cache) - { - // Turn it back on - $this->CI->db->cache_on(); - } - // Clear dirty flag to prevent double updates $this->data_dirty = FALSE; -- cgit v1.2.3-24-g4f1b From 9ffcee60140b20ca3ec4e7688f83a039c7c080f7 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 5 Sep 2012 16:25:16 +0300 Subject: Cleanup and optimize new Session classes --- system/libraries/Session/Session.php | 155 ++++++++++++++------- .../libraries/Session/drivers/Session_cookie.php | 125 +++++++++-------- .../libraries/Session/drivers/Session_native.php | 69 +++++---- 3 files changed, 221 insertions(+), 128 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 1f24456a4..e6f6050c0 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -2,20 +2,31 @@ /** * 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: + * http://opensource.org/licenses/OSL-3.0 + * If you did not receive a copy of the license and are unable to obtain it + * through the world wide web, please send an email to + * licensing@ellislab.com so we can send you a copy immediately. * * @package CodeIgniter - * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html + * @author EllisLab Dev Team + * @copyright Copyright (c) 2006 - 2012 EllisLab, Inc. + * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) * @link http://codeigniter.com * @since Version 2.0 * @filesource */ - /** - * CI_Session Class + * CodeIgniter Session Class * * The user interface defined by EllisLabs, now with puggable drivers to manage different storage mechanisms. * By default, the cookie session driver will load, but the 'sess_driver' config/param item (see above) can be @@ -35,12 +46,13 @@ * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author ExpressionEngine Dev Team + * @author EllisLab Dev Team * @link http://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session extends CI_Driver_Library { + public $params = array(); - protected $current = null; + protected $current = NULL; protected $userdata = array(); const FLASHDATA_KEY = 'flash'; @@ -69,10 +81,10 @@ class CI_Session extends CI_Driver_Library { 'Session_cookie' ); $key = 'sess_valid_drivers'; - $drivers = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); + $drivers = isset($params[$key]) ? $params[$key] : $CI->config->item($key); if ($drivers) { - if ( ! is_array($drivers)) $drivers = array($drivers); + is_array($drivers) OR $drivers = array($drivers); // Add driver names to valid list foreach ($drivers as $driver) @@ -86,8 +98,12 @@ class CI_Session extends CI_Driver_Library { // Get driver to load $key = 'sess_driver'; - $driver = (isset($params[$key])) ? $params[$key] : $CI->config->item($key); - if ( ! $driver) $driver = 'cookie'; + $driver = isset($params[$key]) ? $params[$key] : $CI->config->item($key); + if ( ! $driver) + { + $driver = 'cookie'; + } + if ( ! in_array('session_'.strtolower($driver), array_map('strtolower', $this->valid_drivers))) { $this->valid_drivers[] = 'Session_'.$driver; @@ -111,6 +127,8 @@ class CI_Session extends CI_Driver_Library { log_message('debug', 'CI_Session routines successfully run'); } + // ------------------------------------------------------------------------ + /** * Loads session storage driver * @@ -125,6 +143,8 @@ class CI_Session extends CI_Driver_Library { return $this->current; } + // ------------------------------------------------------------------------ + /** * Select default session storage driver * @@ -142,7 +162,8 @@ class CI_Session extends CI_Driver_Library { if (isset($this->$child)) { // See if driver is already current - if ($this->$child !== $this->current) { + if ($this->$child !== $this->current) + { // Make driver current and sync userdata $this->current = $this->$child; $this->userdata =& $this->current->get_userdata(); @@ -156,6 +177,8 @@ class CI_Session extends CI_Driver_Library { } } + // ------------------------------------------------------------------------ + /** * Destroy the current session * @@ -167,19 +190,23 @@ class CI_Session extends CI_Driver_Library { $this->current->sess_destroy(); } + // ------------------------------------------------------------------------ + /** * Regenerate the current session * - * @param boolean Destroy session data flag (default: false) + * @param bool Destroy session data flag (default: false) * @return void */ - public function sess_regenerate($destroy = false) + public function sess_regenerate($destroy = FALSE) { // Call regenerate on driver and resync userdata $this->current->sess_regenerate($destroy); $this->userdata =& $this->current->get_userdata(); } + // ------------------------------------------------------------------------ + /** * Fetch a specific item from the session array * @@ -188,10 +215,11 @@ class CI_Session extends CI_Driver_Library { */ public function userdata($item) { - // Return value or NULL if not found - return ( ! isset($this->userdata[$item])) ? NULL : $this->userdata[$item]; + return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL; } + // ------------------------------------------------------------------------ + /** * Fetch all session data * @@ -199,10 +227,11 @@ class CI_Session extends CI_Driver_Library { */ public function all_userdata() { - // Return entire array - return ( ! isset($this->userdata)) ? NULL : $this->userdata; + return isset($this->userdata) ? $this->userdata : NULL; } + // ------------------------------------------------------------------------ + /** * Fetch all flashdata * @@ -225,6 +254,8 @@ class CI_Session extends CI_Driver_Library { return $out; } + // ------------------------------------------------------------------------ + /** * Add or change data in the "userdata" array * @@ -253,6 +284,8 @@ class CI_Session extends CI_Driver_Library { $this->current->sess_save(); } + // ------------------------------------------------------------------------ + /** * Delete a session variable from the "userdata" array * @@ -270,7 +303,7 @@ class CI_Session extends CI_Driver_Library { // Unset each item name if (count($newdata) > 0) { - foreach ($newdata as $key => $val) + foreach (array_keys($newdata) as $key) { unset($this->userdata[$key]); } @@ -280,18 +313,21 @@ class CI_Session extends CI_Driver_Library { $this->current->sess_save(); } + // ------------------------------------------------------------------------ + /** * Determine if an item exists * * @param string Item name - * @return boolean + * @return bool */ public function has_userdata($item) { - // Check for item name return isset($this->userdata[$item]); } + // ------------------------------------------------------------------------ + /** * Add or change flashdata, only available until the next request * @@ -318,6 +354,8 @@ class CI_Session extends CI_Driver_Library { } } + // ------------------------------------------------------------------------ + /** * Keeps existing flashdata available to next request. * @@ -335,6 +373,8 @@ class CI_Session extends CI_Driver_Library { $this->set_userdata($new_flashdata_key, $value); } + // ------------------------------------------------------------------------ + /** * Fetch a specific flashdata item from the session array * @@ -348,13 +388,14 @@ class CI_Session extends CI_Driver_Library { return $this->userdata($flashdata_key); } + // ------------------------------------------------------------------------ + /** - * Add or change tempdata, only available - * until expiration + * Add or change tempdata, only available until expiration * * @param mixed Item name or array of items * @param string Item value or empty string - * @param int Item lifetime in seconds or 0 for default + * @param int Item lifetime in seconds or 0 for default * @return void */ public function set_tempdata($newdata = array(), $newval = '', $expire = 0) @@ -390,6 +431,8 @@ class CI_Session extends CI_Driver_Library { $this->set_userdata(self::EXPIRATION_KEY, $expirations); } + // ------------------------------------------------------------------------ + /** * Delete a temporary session variable from the "userdata" array * @@ -400,7 +443,7 @@ class CI_Session extends CI_Driver_Library { { // Get expirations list $expirations = $this->userdata(self::EXPIRATION_KEY); - if ( ! $expirations || ! count($expirations)) + if (empty($expirations)) { // Nothing to do return; @@ -415,7 +458,7 @@ class CI_Session extends CI_Driver_Library { // Prepend each item name and unset if (count($newdata) > 0) { - foreach ($newdata as $key => $val) + foreach (array_keys($newdata) as $key) { $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key; unset($expirations[$tempdata_key]); @@ -427,6 +470,8 @@ class CI_Session extends CI_Driver_Library { $this->set_userdata(self::EXPIRATION_KEY, $expirations); } + // ------------------------------------------------------------------------ + /** * Fetch a specific tempdata item from the session array * @@ -440,17 +485,17 @@ class CI_Session extends CI_Driver_Library { return $this->userdata($tempdata_key); } + // ------------------------------------------------------------------------ + /** * Identifies flashdata as 'old' for removal * when _flashdata_sweep() runs. * - * @access protected * @return void */ protected function _flashdata_mark() { - $userdata = $this->all_userdata(); - foreach ($userdata as $name => $value) + foreach ($this->all_userdata() as $name => $value) { $parts = explode(self::FLASHDATA_NEW, $name); if (is_array($parts) && count($parts) === 2) @@ -462,16 +507,17 @@ class CI_Session extends CI_Driver_Library { } } + // ------------------------------------------------------------------------ + /** * Removes all flashdata marked as 'old' * - * @access protected * @return void */ protected function _flashdata_sweep() { $userdata = $this->all_userdata(); - foreach ($userdata as $key => $value) + foreach (array_keys($userdata) as $key) { if (strpos($key, self::FLASHDATA_OLD)) { @@ -480,17 +526,18 @@ class CI_Session extends CI_Driver_Library { } } + // ------------------------------------------------------------------------ + /** * Removes all expired tempdata * - * @access protected * @return void */ protected function _tempdata_sweep() { // Get expirations list $expirations = $this->userdata(self::EXPIRATION_KEY); - if ( ! $expirations || ! count($expirations)) + if (empty($expirations)) { // Nothing to do return; @@ -499,7 +546,7 @@ class CI_Session extends CI_Driver_Library { // Unset expired elements $now = time(); $userdata = $this->all_userdata(); - foreach ($userdata as $key => $value) + foreach (array_keys($userdata) as $key) { if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now) { @@ -511,9 +558,10 @@ class CI_Session extends CI_Driver_Library { // Update expiration list $this->set_userdata(self::EXPIRATION_KEY, $expirations); } + } -// END CI_Session Class +// ------------------------------------------------------------------------ /** * CI_Session_driver Class @@ -535,9 +583,10 @@ class CI_Session extends CI_Driver_Library { * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author ExpressionEngine Dev Team + * @author EllisLab Dev Team */ abstract class CI_Session_driver extends CI_Driver { + /** * Decorate * @@ -555,6 +604,8 @@ abstract class CI_Session_driver extends CI_Driver { $this->initialize(); } + // ------------------------------------------------------------------------ + /** * __call magic method * @@ -571,6 +622,8 @@ abstract class CI_Session_driver extends CI_Driver { return parent::__call($method, $args); } + // ------------------------------------------------------------------------ + /** * Initialize driver * @@ -581,50 +634,56 @@ abstract class CI_Session_driver extends CI_Driver { // Overload this method to implement initialization } + // ------------------------------------------------------------------------ + /** * Save the session data * - * Data in the array has changed - perform any storage synchronization necessary - * The child class MUST implement this abstract method! + * Data in the array has changed - perform any storage synchronization + * necessary. The child class MUST implement this abstract method! * * @return void */ abstract public function sess_save(); + // ------------------------------------------------------------------------ + /** * Destroy the current session * - * Clean up storage for this session - it has been terminated + * Clean up storage for this session - it has been terminated. * The child class MUST implement this abstract method! * * @return void */ abstract public function sess_destroy(); + // ------------------------------------------------------------------------ + /** * Regenerate the current session * - * Regenerate the session id + * Regenerate the session ID. * The child class MUST implement this abstract method! * - * @param boolean Destroy session data flag (default: false) + * @param bool Destroy session data flag (default: false) * @return void */ - abstract public function sess_regenerate($destroy = false); + abstract public function sess_regenerate($destroy = FALSE); + + // ------------------------------------------------------------------------ /** * Get a reference to user data array * - * Give array access to the main CI_Session object + * Give array access to the main CI_Session object. * The child class MUST implement this abstract method! * * @return array Reference to userdata */ abstract public function &get_userdata(); -} -// END CI_Session_driver Class +} /* End of file Session.php */ -/* Location: ./system/libraries/Session/Session.php */ -?> +/* Location: ./system/libraries/Session/Session.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 52eeddbc4..6d931c16c 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -37,6 +37,7 @@ * @link http://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_cookie extends CI_Session_driver { + /** * Whether to encrypt the session cookie * @@ -192,7 +193,6 @@ class CI_Session_cookie extends CI_Session_driver { /** * Initialize session driver object * - * @access protected * @return void */ protected function initialize() @@ -220,16 +220,17 @@ class CI_Session_cookie extends CI_Session_driver { 'cookie_prefix', 'encryption_key' ); + foreach ($prefs as $key) { - $this->$key = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] : - $this->CI->config->item($key); + $this->$key = isset($this->_parent->params[$key]) + ? $this->_parent->params[$key] + : $this->CI->config->item($key); } if ($this->encryption_key === '') { - show_error('In order to use the Cookie Session driver you are required to set an encryption key '. - 'in your config file.'); + show_error('In order to use the Cookie Session driver you are required to set an encryption key in your config file.'); } // Load the string helper so we can use the strip_slashes() function @@ -280,6 +281,8 @@ class CI_Session_cookie extends CI_Session_driver { $this->_sess_gc(); } + // ------------------------------------------------------------------------ + /** * Write the session data * @@ -298,6 +301,8 @@ class CI_Session_cookie extends CI_Session_driver { $this->_set_cookie(); } + // ------------------------------------------------------------------------ + /** * Destroy the current session * @@ -320,15 +325,17 @@ class CI_Session_cookie extends CI_Session_driver { $this->userdata = array(); } + // ------------------------------------------------------------------------ + /** * Regenerate the current session * * Regenerate the session id * - * @param boolean Destroy session data flag (default: false) + * @param bool Destroy session data flag (default: false) * @return void */ - public function sess_regenerate($destroy = false) + public function sess_regenerate($destroy = FALSE) { // Check destroy flag if ($destroy) @@ -344,21 +351,23 @@ class CI_Session_cookie extends CI_Session_driver { } } + // ------------------------------------------------------------------------ + /** * Get a reference to user data array * - * @return array - Reference to userdata + * @return array Reference to userdata */ public function &get_userdata() { - // Return reference to array return $this->userdata; } + // ------------------------------------------------------------------------ + /** * Fetch the current session data if it exists * - * @access protected * @return bool */ protected function _sess_read() @@ -389,8 +398,7 @@ class CI_Session_cookie extends CI_Session_driver { // 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.'); + log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.'); $this->sess_destroy(); return FALSE; } @@ -400,8 +408,7 @@ class CI_Session_cookie extends CI_Session_driver { $session = $this->_unserialize($session); // Is the session data we unserialized an array with the correct format? - if ( ! is_array($session) || ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], - $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; @@ -423,7 +430,7 @@ class CI_Session_cookie extends CI_Session_driver { // Does the User Agent Match? if ($this->sess_match_useragent === TRUE && - trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120))) + trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120))) { $this->sess_destroy(); return FALSE; @@ -482,10 +489,11 @@ class CI_Session_cookie extends CI_Session_driver { return TRUE; } + // ------------------------------------------------------------------------ + /** * Create a new session * - * @access protected * @return void */ protected function _sess_create() @@ -509,11 +517,12 @@ class CI_Session_cookie extends CI_Session_driver { $this->_set_cookie(); } + // ------------------------------------------------------------------------ + /** * Update an existing session * - * @access protected - * @param boolean Force update flag (default: false) + * @param bool Force update flag (default: false) * @return void */ protected function _sess_update($force = FALSE) @@ -551,6 +560,8 @@ class CI_Session_cookie extends CI_Session_driver { $this->_set_cookie(); } + // ------------------------------------------------------------------------ + /** * Update database with current data * @@ -559,6 +570,8 @@ class CI_Session_cookie extends CI_Session_driver { * so it's guaranteed to update even when a fatal error * occurs. The first call makes the update and clears the * dirty flag so it won't happen twice. + * + * @return void */ public function _update_db() { @@ -595,6 +608,8 @@ class CI_Session_cookie extends CI_Session_driver { } } + // ------------------------------------------------------------------------ + /** * Generate a new session id * @@ -616,15 +631,16 @@ class CI_Session_cookie extends CI_Session_driver { return md5(uniqid($new_sessid, TRUE)); } + // ------------------------------------------------------------------------ + /** * Get the "now" time * - * @access protected * @return int Time */ protected function _get_time() { - if ($this->time_reference === 'local' || $this->time_reference === date_default_timezone_get()) + if ($this->time_reference === 'local' OR $this->time_reference === date_default_timezone_get()) { return time(); } @@ -635,36 +651,27 @@ class CI_Session_cookie extends CI_Session_driver { return mktime($hour, $minute, $second, $month, $day, $year); } + // ------------------------------------------------------------------------ + /** * Write the session cookie * - * @access protected * @return void */ protected function _set_cookie() { // Get userdata (only defaults if database) - if ($this->sess_use_database === TRUE) - { - $cookie_data = array_intersect_key($this->userdata, $this->defaults); - } - else - { - $cookie_data = $this->userdata; - } + $cookie_data = ($this->sess_use_database === TRUE) + ? array_intersect_key($this->userdata, $this->defaults) + : $this->userdata; // Serialize the userdata for the cookie $cookie_data = $this->_serialize($cookie_data); - if ($this->sess_encrypt_cookie === TRUE) - { - $cookie_data = $this->CI->encrypt->encode($cookie_data); - } - else - { + $cookie_data = ($this->sess_encrypt_cookie === TRUE) + ? $this->CI->encrypt->encode($cookie_data) // if encryption is not used, we provide an md5 hash to prevent userside tampering - $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key); - } + : $cookie_data.md5($cookie_data.$this->encryption_key); $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time(); @@ -673,35 +680,35 @@ class CI_Session_cookie extends CI_Session_driver { $this->cookie_secure, $this->cookie_httponly); } + // ------------------------------------------------------------------------ + /** * Set a cookie with the system * * This abstraction of the setcookie call allows overriding for unit testing * - * @access protected - * @param string Cookie name - * @param string Cookie value - * @param int Expiration time - * @param string Cookie path - * @param string Cookie domain - * @param bool Secure connection flag - * @param bool HTTP protocol only flag - * @return void - */ - protected function _setcookie($name, $value = '', $expire = 0, $path = '', $domain = '', $secure = false, - $httponly = false) + * @param string Cookie name + * @param string Cookie value + * @param int Expiration time + * @param string Cookie path + * @param string Cookie domain + * @param bool Secure connection flag + * @param bool HTTP protocol only flag + * @return void + */ + protected function _setcookie($name, $value = '', $expire = 0, $path = '', $domain = '', $secure = FALSE, $httponly = FALSE) { - // Set the cookie setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); } + // ------------------------------------------------------------------------ + /** * Serialize an array * * 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 protected * @param mixed Data to serialize * @return string Serialized data */ @@ -715,15 +722,17 @@ class CI_Session_cookie extends CI_Session_driver { { $data = str_replace('\\', '{{slash}}', $data); } + return serialize($data); } + // ------------------------------------------------------------------------ + /** * Escape slashes * * This function converts any slashes found into a temporary marker * - * @access protected * @param string Value * @param string Key * @return void @@ -736,13 +745,14 @@ class CI_Session_cookie extends CI_Session_driver { } } + // ------------------------------------------------------------------------ + /** * Unserialize * * This function unserializes a data string, then converts any * temporary slash markers back to actual slashes * - * @access protected * @param mixed Data to unserialize * @return mixed Unserialized data */ @@ -759,12 +769,13 @@ class CI_Session_cookie extends CI_Session_driver { return is_string($data) ? str_replace('{{slash}}', '\\', $data) : $data; } + // ------------------------------------------------------------------------ + /** * Unescape slashes * * This function converts any slash markers back into actual slashes * - * @access protected * @param string Value * @param string Key * @return void @@ -777,13 +788,14 @@ class CI_Session_cookie extends CI_Session_driver { } } + // ------------------------------------------------------------------------ + /** * Garbage collection * * This deletes expired session rows from database * if the probability percentage is met * - * @access protected * @return void */ protected function _sess_gc() @@ -805,7 +817,8 @@ class CI_Session_cookie extends CI_Session_driver { log_message('debug', 'Session garbage collection performed.'); } } + } /* End of file Session_cookie.php */ -/* Location: ./system/libraries/Session/drivers/Session_cookie.php */ +/* Location: ./system/libraries/Session/drivers/Session_cookie.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 8ba8e749a..c97e15356 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -2,18 +2,29 @@ /** * 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: + * http://opensource.org/licenses/OSL-3.0 + * If you did not receive a copy of the license and are unable to obtain it + * through the world wide web, please send an email to + * licensing@ellislab.com so we can send you a copy immediately. * * @package CodeIgniter - * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html + * @author EllisLab Dev Team + * @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 2.0 + * @since Version 1.0 * @filesource */ - /** * Native PHP session management driver * @@ -22,13 +33,13 @@ * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author ExpressionEngine Dev Team + * @author EllisLab Dev Team */ class CI_Session_native extends CI_Session_driver { + /** * Initialize session driver object * - * @access protected * @return void */ protected function initialize() @@ -47,10 +58,12 @@ class CI_Session_native extends CI_Session_driver { 'cookie_path', 'cookie_domain' ); + foreach ($prefs as $key) { - $config[$key] = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] : - $CI->config->item($key); + $config[$key] = isset($this->_parent->params[$key]) + ? $this->_parent->params[$key] + : $CI->config->item($key); } // Set session name, if specified @@ -75,11 +88,13 @@ class CI_Session_native extends CI_Session_driver { // Default to 2 years if expiration is "0" $expire = ($config['sess_expiration'] == 0) ? (60*60*24*365*2) : $config['sess_expiration']; } + if ($config['cookie_path']) { // Use specified path $path = $config['cookie_path']; } + if ($config['cookie_domain']) { // Use specified domain @@ -98,14 +113,14 @@ class CI_Session_native extends CI_Session_driver { // Expired - destroy $destroy = TRUE; } - else if ($config['sess_match_ip'] == TRUE && isset($_SESSION['ip_address']) && - $_SESSION['ip_address'] != $CI->input->ip_address()) + elseif ($config['sess_match_ip'] === TRUE && isset($_SESSION['ip_address']) + && $_SESSION['ip_address'] !== $CI->input->ip_address()) { // IP doesn't match - destroy $destroy = TRUE; } - else if ($config['sess_match_useragent'] == TRUE && isset($_SESSION['user_agent']) && - $_SESSION['user_agent'] != trim(substr($CI->input->user_agent(), 0, 50))) + elseif ($config['sess_match_useragent'] === TRUE && isset($_SESSION['user_agent']) + && $_SESSION['user_agent'] !== trim(substr($CI->input->user_agent(), 0, 50))) { // Agent doesn't match - destroy $destroy = TRUE; @@ -120,8 +135,8 @@ class CI_Session_native extends CI_Session_driver { } // Check for update time - if ($config['sess_time_to_update'] && isset($_SESSION['last_activity']) && - ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now) + if ($config['sess_time_to_update'] && isset($_SESSION['last_activity']) + && ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now) { // Regenerate ID, but don't destroy session $this->sess_regenerate(FALSE); @@ -131,12 +146,13 @@ class CI_Session_native extends CI_Session_driver { $_SESSION['last_activity'] = $now; // Set matching values as required - if ($config['sess_match_ip'] == TRUE && !isset($_SESSION['ip_address'])) + if ($config['sess_match_ip'] === TRUE && ! isset($_SESSION['ip_address'])) { // Store user IP address $_SESSION['ip_address'] = $CI->input->ip_address(); } - if ($config['sess_match_useragent'] == TRUE && !isset($_SESSION['user_agent'])) + + if ($config['sess_match_useragent'] === TRUE && ! isset($_SESSION['user_agent'])) { // Store user agent string $_SESSION['user_agent'] = trim(substr($CI->input->user_agent(), 0, 50)); @@ -146,10 +162,11 @@ class CI_Session_native extends CI_Session_driver { $_SESSION['session_id'] = session_id(); } + // ------------------------------------------------------------------------ + /** * Save the session data * - * @access public * @return void */ public function sess_save() @@ -157,10 +174,11 @@ class CI_Session_native extends CI_Session_driver { // Nothing to do - changes to $_SESSION are automatically saved } + // ------------------------------------------------------------------------ + /** * Destroy the current session * - * @access public * @return void */ public function sess_destroy() @@ -178,13 +196,14 @@ class CI_Session_native extends CI_Session_driver { session_destroy(); } + // ------------------------------------------------------------------------ + /** * Regenerate the current session * * Regenerate the session id * - * @access public - * @param boolean Destroy session data flag (default: FALSE) + * @param bool Destroy session data flag (default: FALSE) * @return void */ public function sess_regenerate($destroy = FALSE) @@ -194,10 +213,11 @@ class CI_Session_native extends CI_Session_driver { $_SESSION['session_id'] = session_id(); } + // ------------------------------------------------------------------------ + /** * Get a reference to user data array * - * @access public * @return array Reference to userdata */ public function &get_userdata() @@ -205,7 +225,8 @@ class CI_Session_native extends CI_Session_driver { // Just return reference to $_SESSION return $_SESSION; } + } /* End of file Session_native.php */ -/* Location: ./system/libraries/Session/drivers/Session_native.php */ +/* Location: ./system/libraries/Session/drivers/Session_native.php */ \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 3f3f135ed5b47fd87a59d31fb3d1a4c773dcc3b3 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 5 Sep 2012 16:39:28 +0300 Subject: Misc. style changes --- system/libraries/Session/drivers/Session_cookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 6d931c16c..4f415cc0d 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -347,7 +347,7 @@ class CI_Session_cookie extends CI_Session_driver { else { // Just force an update to recreate the id - $this->_sess_update(true); + $this->_sess_update(TRUE); } } -- cgit v1.2.3-24-g4f1b From 2e3e23053d9748c68fa2c0e11f43af67da8743e8 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 9 Oct 2012 15:52:34 +0300 Subject: Disable Session library under CLI and create a CI singleton to be used by its drivers --- system/libraries/Session/Session.php | 27 +++++++++++++++++++++- .../libraries/Session/drivers/Session_cookie.php | 10 -------- .../libraries/Session/drivers/Session_native.php | 11 ++++----- 3 files changed, 31 insertions(+), 17 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index e6f6050c0..978506062 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -69,13 +69,21 @@ class CI_Session extends CI_Driver_Library { * routines in its constructor, and manages flashdata aging. * * @param array Configuration parameters + * @return void */ public function __construct(array $params = array()) { + $CI =& get_instance(); + + // No sessions under CLI + if ($CI->input->is_cli_request()) + { + return; + } + log_message('debug', 'CI_Session Class Initialized'); // Get valid drivers list - $CI =& get_instance(); $this->valid_drivers = array( 'Session_native', 'Session_cookie' @@ -587,6 +595,23 @@ class CI_Session extends CI_Driver_Library { */ abstract class CI_Session_driver extends CI_Driver { + protected $CI; + + /** + * Constructor + * + * Gets the CI singleton, so that individual drivers + * don't have to do it separately. + * + * @return void + */ + public function __construct() + { + $this->CI =& get_instance(); + } + + // ------------------------------------------------------------------------ + /** * Decorate * diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 4f415cc0d..fb62c7ec4 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -157,13 +157,6 @@ class CI_Session_cookie extends CI_Session_driver { */ public $userdata = array(); - /** - * Reference to CodeIgniter instance - * - * @var object - */ - public $CI; - /** * Current time * @@ -197,9 +190,6 @@ class CI_Session_cookie extends CI_Session_driver { */ protected function initialize() { - // Set the super object to a local variable for use throughout the class - $this->CI =& get_instance(); - // Set all the session preferences, which can either be set // manually via the $params array or via the config file $prefs = array( diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index c97e15356..8d5e51546 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -46,7 +46,6 @@ class CI_Session_native extends CI_Session_driver { { // Get config parameters $config = array(); - $CI =& get_instance(); $prefs = array( 'sess_cookie_name', 'sess_expire_on_close', @@ -63,7 +62,7 @@ class CI_Session_native extends CI_Session_driver { { $config[$key] = isset($this->_parent->params[$key]) ? $this->_parent->params[$key] - : $CI->config->item($key); + : $this->CI->config->item($key); } // Set session name, if specified @@ -114,13 +113,13 @@ class CI_Session_native extends CI_Session_driver { $destroy = TRUE; } elseif ($config['sess_match_ip'] === TRUE && isset($_SESSION['ip_address']) - && $_SESSION['ip_address'] !== $CI->input->ip_address()) + && $_SESSION['ip_address'] !== $this->CI->input->ip_address()) { // IP doesn't match - destroy $destroy = TRUE; } elseif ($config['sess_match_useragent'] === TRUE && isset($_SESSION['user_agent']) - && $_SESSION['user_agent'] !== trim(substr($CI->input->user_agent(), 0, 50))) + && $_SESSION['user_agent'] !== trim(substr($this->CI->input->user_agent(), 0, 50))) { // Agent doesn't match - destroy $destroy = TRUE; @@ -149,13 +148,13 @@ class CI_Session_native extends CI_Session_driver { if ($config['sess_match_ip'] === TRUE && ! isset($_SESSION['ip_address'])) { // Store user IP address - $_SESSION['ip_address'] = $CI->input->ip_address(); + $_SESSION['ip_address'] = $this->CI->input->ip_address(); } if ($config['sess_match_useragent'] === TRUE && ! isset($_SESSION['user_agent'])) { // Store user agent string - $_SESSION['user_agent'] = trim(substr($CI->input->user_agent(), 0, 50)); + $_SESSION['user_agent'] = trim(substr($this->CI->input->user_agent(), 0, 50)); } // Make session ID available -- cgit v1.2.3-24-g4f1b From 02117680c8a3a4c7da2b10e25fc6c29fd5fa9bd2 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 15 Oct 2012 11:12:37 +0300 Subject: Partially fix #1702 --- system/libraries/Session/drivers/Session_cookie.php | 2 +- system/libraries/Session/drivers/Session_native.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index fb62c7ec4..5bb1f7aa6 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -405,7 +405,7 @@ class CI_Session_cookie extends CI_Session_driver { } // Is the session current? - if (($session['last_activity'] + $this->sess_expiration) < $this->now) + if (($session['last_activity'] + $this->sess_expiration) < $this->now OR $session['last_activity'] > $this->now) { $this->sess_destroy(); return FALSE; diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 8d5e51546..6529d4c36 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -107,7 +107,7 @@ class CI_Session_native extends CI_Session_driver { // Check session expiration, ip, and agent $now = time(); $destroy = FALSE; - if (isset($_SESSION['last_activity']) && ($_SESSION['last_activity'] + $expire) < $now) + if (isset($_SESSION['last_activity']) && (($_SESSION['last_activity'] + $expire) < $now OR $_SESSION['last_activity'] > $now)) { // Expired - destroy $destroy = TRUE; -- cgit v1.2.3-24-g4f1b From 19cd88799f27bef8d502250c86eddcd72789bdb3 Mon Sep 17 00:00:00 2001 From: GDmac Date: Tue, 16 Oct 2012 14:19:57 +0200 Subject: Session Native, respect cookie settings Respect config settings for cookie_secure and cookie_httponly Signed-off-by: GDmac --- .../libraries/Session/drivers/Session_native.php | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 6529d4c36..d7b9e8410 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -55,7 +55,9 @@ class CI_Session_native extends CI_Session_driver { 'sess_time_to_update', 'cookie_prefix', 'cookie_path', - 'cookie_domain' + 'cookie_domain', + 'cookie_secure', + 'cookie_httponly' ); foreach ($prefs as $key) @@ -82,6 +84,9 @@ class CI_Session_native extends CI_Session_driver { $expire = 7200; $path = '/'; $domain = ''; + $secure = FALSE; + $http_only = FALSE; + if ($config['sess_expiration'] !== FALSE) { // Default to 2 years if expiration is "0" @@ -99,7 +104,20 @@ class CI_Session_native extends CI_Session_driver { // Use specified domain $domain = $config['cookie_domain']; } - session_set_cookie_params($config['sess_expire_on_close'] ? 0 : $expire, $path, $domain); + + if ($config['cookie_secure']) + { + // Send over SSL / HTTPS only? + $secure = $config['cookie_secure']; + } + + if ($config['cookie_httponly']) + { + // only available to HTTP(S)? + $http_only = $config['http_only']; + } + + session_set_cookie_params($config['sess_expire_on_close'] ? 0 : $expire, $path, $domain, $secure, $http_only); // Start session session_start(); @@ -189,7 +207,7 @@ class CI_Session_native extends CI_Session_driver { { // Clear session cookie $params = session_get_cookie_params(); - setcookie($name, '', time() - 42000, $params['path'], $params['domain']); + setcookie($name, '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']); unset($_COOKIE[$name]); } session_destroy(); -- cgit v1.2.3-24-g4f1b From 28616da32bcf72f37c0e61e304a1799b90ceec3f Mon Sep 17 00:00:00 2001 From: GDmac Date: Tue, 16 Oct 2012 15:01:14 +0200 Subject: Native PHP Session, don't regenerate session_id during ajax Signed-off-by: GDmac --- system/libraries/Session/drivers/Session_native.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index d7b9e8410..fb3b638a0 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -155,8 +155,12 @@ class CI_Session_native extends CI_Session_driver { if ($config['sess_time_to_update'] && isset($_SESSION['last_activity']) && ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now) { - // Regenerate ID, but don't destroy session - $this->sess_regenerate(FALSE); + // Changing the session ID amidst a series of AJAX calls causes problems + if( ! $this->CI->input->is_ajax_request()) + { + // Regenerate ID, but don't destroy session + $this->sess_regenerate(FALSE); + } } // Set activity time -- cgit v1.2.3-24-g4f1b From f69f0e8f02815d44e218b013c8da92cebabbdcb1 Mon Sep 17 00:00:00 2001 From: Pascal Kriete Date: Tue, 16 Oct 2012 11:54:49 -0400 Subject: Updating the cookie driver to use HMAC authentication on all cookie data. Signed-off-by: Pascal Kriete --- .../libraries/Session/drivers/Session_cookie.php | 45 +++++++++++++--------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 5bb1f7aa6..b44c8330e 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -372,27 +372,31 @@ class CI_Session_cookie extends CI_Session_driver { return FALSE; } + $len = strlen($session) - 40; + + if ($len < 0) + { + log_message('debug', 'The session cookie was not signed.'); + return FALSE; + } + + // Check cookie authentication + $hmac = substr($session, $len); + $session = substr($session, 0, $len); + + if ($hmac !== hash_hmac('sha1', $session, $this->encryption_key)) + { + log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.'); + $this->sess_destroy(); + return FALSE; + } + // Check for encryption if ($this->sess_encrypt_cookie === TRUE) { // Decrypt the cookie data $session = $this->CI->encrypt->decode($session); } - else - { - // Encryption was not used, so we need to check the md5 hash in the last 32 chars - $len = strlen($session)-32; - $hash = substr($session, $len); - $session = substr($session, 0, $len); - - // 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.'); - $this->sess_destroy(); - return FALSE; - } - } // Unserialize the session array $session = $this->_unserialize($session); @@ -658,10 +662,13 @@ class CI_Session_cookie extends CI_Session_driver { // Serialize the userdata for the cookie $cookie_data = $this->_serialize($cookie_data); - $cookie_data = ($this->sess_encrypt_cookie === TRUE) - ? $this->CI->encrypt->encode($cookie_data) - // if encryption is not used, we provide an md5 hash to prevent userside tampering - : $cookie_data.md5($cookie_data.$this->encryption_key); + if ($this->sess_encrypt_cookie === TRUE) + { + $this->CI->encrypt->encode($cookie_data); + } + + // Require message authentication + $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key); $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time(); -- cgit v1.2.3-24-g4f1b From ff5ffdf7fa3b458510a95788ac3baa6fba3178cc Mon Sep 17 00:00:00 2001 From: GDmac Date: Tue, 16 Oct 2012 19:22:12 +0200 Subject: session native, fix cookie settings Signed-off-by: GDmac --- system/libraries/Session/drivers/Session_native.php | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index fb3b638a0..da744f39b 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -84,8 +84,8 @@ class CI_Session_native extends CI_Session_driver { $expire = 7200; $path = '/'; $domain = ''; - $secure = FALSE; - $http_only = FALSE; + $secure = (bool) $config['cookie_secure']; + $http_only = (bool) $config['cookie_httponly']; if ($config['sess_expiration'] !== FALSE) { @@ -105,18 +105,6 @@ class CI_Session_native extends CI_Session_driver { $domain = $config['cookie_domain']; } - if ($config['cookie_secure']) - { - // Send over SSL / HTTPS only? - $secure = $config['cookie_secure']; - } - - if ($config['cookie_httponly']) - { - // only available to HTTP(S)? - $http_only = $config['http_only']; - } - session_set_cookie_params($config['sess_expire_on_close'] ? 0 : $expire, $path, $domain, $secure, $http_only); // Start session -- cgit v1.2.3-24-g4f1b From 28dc2023d32e1d997e2b90052f1960f98a255d2c Mon Sep 17 00:00:00 2001 From: Pascal Kriete Date: Wed, 17 Oct 2012 11:27:29 -0400 Subject: Changing session error logging verbiage to be a little less unsettling. Signed-off-by: Pascal Kriete --- system/libraries/Session/drivers/Session_cookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index b44c8330e..51d94da4e 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -386,7 +386,7 @@ class CI_Session_cookie extends CI_Session_driver { if ($hmac !== hash_hmac('sha1', $session, $this->encryption_key)) { - log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.'); + log_message('error', 'The session cookie data did not match what was expected.'); $this->sess_destroy(); return FALSE; } -- cgit v1.2.3-24-g4f1b From cf264e0d165647f30efdef1b2d944849bebf4c72 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 18 Oct 2012 16:14:51 +0300 Subject: Fix Session cookies not being encrypted on creation and sess_destroy() not actually deleting cookies --- system/libraries/Session/drivers/Session_cookie.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 51d94da4e..8617aec2d 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -308,7 +308,7 @@ class CI_Session_cookie extends CI_Session_driver { } // Kill the cookie - $this->_setcookie($this->sess_cookie_name, addslashes(serialize(array())), ($this->now - 31500000), + $this->_setcookie($this->sess_cookie_name, '', ($this->now - 31500000), $this->cookie_path, $this->cookie_domain, 0); // Kill session data @@ -664,7 +664,7 @@ class CI_Session_cookie extends CI_Session_driver { if ($this->sess_encrypt_cookie === TRUE) { - $this->CI->encrypt->encode($cookie_data); + $cookie_data = $this->CI->encrypt->encode($cookie_data); } // Require message authentication -- cgit v1.2.3-24-g4f1b From ca20d8445312e49e1e974c5ed8cf04400929e615 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 27 Oct 2012 03:02:38 +0300 Subject: Fix #50 --- system/libraries/Session/drivers/Session_cookie.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 8617aec2d..2f1bf3531 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -223,9 +223,6 @@ class CI_Session_cookie extends CI_Session_driver { show_error('In order to use the Cookie Session driver you are required to set an encryption key in your config file.'); } - // Load the string helper so we can use the strip_slashes() function - $this->CI->load->helper('string'); - // Do we need encryption? If so, load the encryption class if ($this->sess_encrypt_cookie === TRUE) { @@ -755,7 +752,7 @@ class CI_Session_cookie extends CI_Session_driver { */ protected function _unserialize($data) { - $data = @unserialize(strip_slashes(trim($data))); + $data = @unserialize(trim($data)); if (is_array($data)) { -- cgit v1.2.3-24-g4f1b From 2b5b92e6535fb328bf4fbe75396c80e352b7c3a2 Mon Sep 17 00:00:00 2001 From: vkeranov Date: Sat, 27 Oct 2012 18:01:47 +0300 Subject: Remove extra space... --- system/libraries/Session/drivers/Session_native.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index da744f39b..a837b89f6 100755 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -1,4 +1,4 @@ - Date: Sat, 27 Oct 2012 18:47:26 +0300 Subject: Remove extra spaces... --- system/libraries/Session/Session.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 978506062..fec9b5b31 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -1,4 +1,4 @@ -valid_drivers = array( 'Session_native', - 'Session_cookie' + 'Session_cookie' ); $key = 'sess_valid_drivers'; $drivers = isset($params[$key]) ? $params[$key] : $CI->config->item($key); @@ -243,7 +243,7 @@ class CI_Session extends CI_Driver_Library { /** * Fetch all flashdata * - * @return array Flash data array + * @return array Flash data array */ public function all_flashdata() { -- cgit v1.2.3-24-g4f1b From e2afc886d5e7fe1d55a467c9bc46fe40c1a2bbf6 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 1 Nov 2012 01:35:34 +0200 Subject: Session cookie driver changes - Changed docs CREATE TABLE ci_sessions example to have the PRIMARY KEY of session_id, ip_address and user_agent combined. - Changed DB updates to add WHERE clauses for the ip_address and/or user_agent strings if sess_match_ip and/or sess_match_useragent are set to TRUE. --- .../libraries/Session/drivers/Session_cookie.php | 36 +++++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 2f1bf3531..8f527ace7 100755 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -540,11 +540,25 @@ class CI_Session_cookie extends CI_Session_driver { // Check for database if ($this->sess_use_database === TRUE) { + $this->CI->db->where('session_id', $old_sessid); + + if ($this->sess_match_ip === TRUE) + { + $this->CI->db->where('ip_address', $this->CI->input->ip_address()); + } + + if ($this->sess_match_useragent === TRUE) + { + $this->CI->db->where('user_agent', trim(substr($this->CI->input->user_agent(), 0, 120))); + } + // Update the session ID and last_activity field in the DB - $this->CI->db->update($this->sess_table_name, array( - 'last_activity' => $this->now, - 'session_id' => $this->userdata['session_id'] - ), array('session_id' => $old_sessid)); + $this->CI->db->update($this->sess_table_name, + array( + 'last_activity' => $this->now, + 'session_id' => $this->userdata['session_id'] + ) + ); } // Write the cookie @@ -590,7 +604,19 @@ class CI_Session_cookie extends CI_Session_driver { // Run the update query // Any time we change the session id, it gets updated immediately, // so our where clause below is always safe - $this->CI->db->update($this->sess_table_name, $set, array('session_id' => $this->userdata['session_id'])); + $this->CI->db->where('session_id', $this->userdata['session_id']); + + if ($this->sess_match_ip === TRUE) + { + $this->CI->db->where('ip_address', $this->CI->input->ip_address()); + } + + if ($this->sess_match_useragent === TRUE) + { + $this->CI->db->where('user_agent', trim(substr($this->CI->input->user_agent(), 0, 120))); + } + + $this->CI->db->update($this->sess_table_name, $set); // Clear dirty flag to prevent double updates $this->data_dirty = FALSE; -- cgit v1.2.3-24-g4f1b From c5536aac5752054f7f76e448d58b86407d8f574e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 1 Nov 2012 17:33:58 +0200 Subject: Manually apply PR #1594 (fixing phpdoc page-level generation/warnings) Also partially fixes issue #1295, fixes inconsistencies in some page-level docblocks and adds include checks in language files. --- system/libraries/Session/Session.php | 5 +++-- system/libraries/Session/drivers/Session_cookie.php | 5 +++-- system/libraries/Session/drivers/Session_native.php | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index fec9b5b31..fb5b9fdd3 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -1,4 +1,4 @@ - Date: Thu, 1 Nov 2012 23:33:14 +0200 Subject: [ci skip] DocBlocks for Pagination, Session, Trackback, Jquery libraries Partially fixes issue #1295 --- system/libraries/Session/Session.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index fb5b9fdd3..bb13c3376 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -52,10 +52,29 @@ defined('BASEPATH') OR exit('No direct script access allowed'); */ class CI_Session extends CI_Driver_Library { + /** + * Initialization parameters + * + * @var array + */ public $params = array(); + + /** + * Current driver in use + * + * @var string + */ protected $current = NULL; + + /** + * User data + * + * @var array + */ protected $userdata = array(); + // ------------------------------------------------------------------------ + const FLASHDATA_KEY = 'flash'; const FLASHDATA_NEW = ':new:'; const FLASHDATA_OLD = ':old:'; @@ -63,6 +82,8 @@ class CI_Session extends CI_Driver_Library { const EXPIRATION_KEY = '__expirations'; const TEMP_EXP_DEF = 300; + // ------------------------------------------------------------------------ + /** * CI_Session constructor * @@ -596,8 +617,16 @@ class CI_Session extends CI_Driver_Library { */ abstract class CI_Session_driver extends CI_Driver { + /** + * CI Singleton + * + * @see get_instance() + * @var object + */ protected $CI; + // ------------------------------------------------------------------------ + /** * Constructor * -- cgit v1.2.3-24-g4f1b From e24eed7e4e410fabf7479a67d3a27e2596444505 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 2 Nov 2012 23:33:45 +0200 Subject: Some micro-optimizations --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index bb13c3376..96e65f154 100755 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -528,7 +528,7 @@ class CI_Session extends CI_Driver_Library { foreach ($this->all_userdata() as $name => $value) { $parts = explode(self::FLASHDATA_NEW, $name); - if (is_array($parts) && count($parts) === 2) + if (count($parts) === 2) { $new_name = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1]; $this->set_userdata($new_name, $value); -- cgit v1.2.3-24-g4f1b From 2eaeee5aa3971932e58ffac48554e554d799249f Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 21 Nov 2012 14:31:26 +0200 Subject: Change fs permissions and add some missing index.html files (#2017) --- system/libraries/Session/Session.php | 0 system/libraries/Session/drivers/Session_cookie.php | 0 system/libraries/Session/drivers/Session_native.php | 0 system/libraries/Session/drivers/index.html | 10 ++++++++++ system/libraries/Session/index.html | 10 ++++++++++ 5 files changed, 20 insertions(+) mode change 100755 => 100644 system/libraries/Session/Session.php mode change 100755 => 100644 system/libraries/Session/drivers/Session_cookie.php mode change 100755 => 100644 system/libraries/Session/drivers/Session_native.php create mode 100644 system/libraries/Session/drivers/index.html create mode 100644 system/libraries/Session/index.html (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php old mode 100755 new mode 100644 diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php old mode 100755 new mode 100644 diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php old mode 100755 new mode 100644 diff --git a/system/libraries/Session/drivers/index.html b/system/libraries/Session/drivers/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/system/libraries/Session/drivers/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + \ No newline at end of file diff --git a/system/libraries/Session/index.html b/system/libraries/Session/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/system/libraries/Session/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 4beca5c9b64ba7bd1622e5c01666491f02cfa6db Mon Sep 17 00:00:00 2001 From: Johnathan Croom Date: Fri, 23 Nov 2012 18:32:46 -0700 Subject: keep_flashdata accepts array --- system/libraries/Session/Session.php | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 96e65f154..81d63c304 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -389,18 +389,28 @@ class CI_Session extends CI_Driver_Library { /** * Keeps existing flashdata available to next request. * - * @param string Item key + * @param mixed Item key * @return void */ - public function keep_flashdata($key) + public function keep_flashdata($data) { - // 'old' flashdata gets removed. Here we mark all flashdata as 'new' to preserve it from _flashdata_sweep() - // Note the function will return NULL if the $key provided cannot be found - $old_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; - $value = $this->userdata($old_flashdata_key); + // Wrap item as array if singular + if (is_string($data)) + { + $data = array($data); + } + + foreach($data as $key) + { + // 'old' flashdata gets removed. Here we mark all flashdata as 'new' to preserve it from _flashdata_sweep() + // Note the function will return NULL if the $key provided cannot be found + $old_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; + $value = $this->userdata($old_flashdata_key); + + $new_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key; + $this->set_userdata($new_flashdata_key, $value); + } - $new_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key; - $this->set_userdata($new_flashdata_key, $value); } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 9d9849b2c459cb09ccebcdf89b2b3a15bc4fd722 Mon Sep 17 00:00:00 2001 From: Johnathan Croom Date: Sat, 24 Nov 2012 13:03:13 -0700 Subject: Requested changed to keep_flashdata --- system/libraries/Session/Session.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 81d63c304..910b99936 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -389,18 +389,18 @@ class CI_Session extends CI_Driver_Library { /** * Keeps existing flashdata available to next request. * - * @param mixed Item key + * @param mixed Item key(s) * @return void */ public function keep_flashdata($data) { // Wrap item as array if singular - if (is_string($data)) + if (!is_array($data)) { $data = array($data); } - foreach($data as $key) + foreach ($data as $key) { // 'old' flashdata gets removed. Here we mark all flashdata as 'new' to preserve it from _flashdata_sweep() // Note the function will return NULL if the $key provided cannot be found @@ -410,7 +410,6 @@ class CI_Session extends CI_Driver_Library { $new_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key; $this->set_userdata($new_flashdata_key, $value); } - } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 6262d053db57957c4445ef7fce76070854c3e30d Mon Sep 17 00:00:00 2001 From: dchill42 Date: Sat, 24 Nov 2012 18:41:13 -0500 Subject: Added support for extending individual driver classes and driver unit tests Signed-off-by: dchill42 --- system/libraries/Session/Session.php | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 96e65f154..b6c862dae 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -107,17 +107,15 @@ class CI_Session extends CI_Driver_Library { // Get valid drivers list $this->valid_drivers = array( - 'Session_native', - 'Session_cookie' + 'native', + 'cookie' ); $key = 'sess_valid_drivers'; $drivers = isset($params[$key]) ? $params[$key] : $CI->config->item($key); if ($drivers) { - is_array($drivers) OR $drivers = array($drivers); - // Add driver names to valid list - foreach ($drivers as $driver) + foreach ((array) $drivers as $driver) { if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers))) { @@ -134,9 +132,9 @@ class CI_Session extends CI_Driver_Library { $driver = 'cookie'; } - if ( ! in_array('session_'.strtolower($driver), array_map('strtolower', $this->valid_drivers))) + if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers))) { - $this->valid_drivers[] = 'Session_'.$driver; + $this->valid_drivers[] = $driver; } // Save a copy of parameters in case drivers need access @@ -178,17 +176,17 @@ class CI_Session extends CI_Driver_Library { /** * Select default session storage driver * - * @param string Driver classname + * @param string Driver name * @return void */ public function select_driver($driver) { // Validate driver name - $lowername = strtolower(str_replace('CI_', '', $driver)); - if (in_array($lowername, array_map('strtolower', $this->valid_drivers))) + $prefix = (string) get_instance()->config->item('subclass_prefix'); + $child = strtolower(str_replace(array('CI_', $prefix, $this->lib_name.'_'), '', $driver)); + if (in_array($child, array_map('strtolower', $this->valid_drivers))) { // See if driver is loaded - $child = str_replace($this->lib_name.'_', '', $driver); if (isset($this->$child)) { // See if driver is already current -- cgit v1.2.3-24-g4f1b From 8d8543da992985ae61a6903a138d949f189721e9 Mon Sep 17 00:00:00 2001 From: Johnathan Croom Date: Sun, 25 Nov 2012 10:36:57 -0700 Subject: Improved array keey_flashdata + Changelog --- system/libraries/Session/Session.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 910b99936..9b011dea3 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -392,24 +392,26 @@ class CI_Session extends CI_Driver_Library { * @param mixed Item key(s) * @return void */ - public function keep_flashdata($data) + public function keep_flashdata($key) { - // Wrap item as array if singular - if (!is_array($data)) - { - $data = array($data); - } - foreach ($data as $key) + if (is_array($key)) { - // 'old' flashdata gets removed. Here we mark all flashdata as 'new' to preserve it from _flashdata_sweep() - // Note the function will return NULL if the $key provided cannot be found - $old_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; - $value = $this->userdata($old_flashdata_key); + foreach ($key as $k) + { + $this->keep_flashdata($k); + } - $new_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key; - $this->set_userdata($new_flashdata_key, $value); + return; } + + // 'old' flashdata gets removed. Here we mark all flashdata as 'new' to preserve it from _flashdata_sweep() + // Note the function will return NULL if the $key provided cannot be found + $old_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; + $value = $this->userdata($old_flashdata_key); + + $new_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key; + $this->set_userdata($new_flashdata_key, $value); } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 4abd0945f1204e40f7ae356e99592655a430ed11 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 26 Nov 2012 12:13:59 +0200 Subject: Manually implement PR #2033 Check for an empty encryption_key shouldn't use strict comparison. --- system/libraries/Session/drivers/Session_cookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 3c4848265..6d926ae3d 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -219,7 +219,7 @@ class CI_Session_cookie extends CI_Session_driver { : $this->CI->config->item($key); } - if ($this->encryption_key === '') + if (empty($this->encryption_key)) { show_error('In order to use the Cookie Session driver you are required to set an encryption key in your config file.'); } -- cgit v1.2.3-24-g4f1b From a8e34acb42552b4668b327cc6fcefab5c6d3442b Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 17 Dec 2012 10:39:32 +0200 Subject: Fix #2074 --- system/libraries/Session/drivers/Session_cookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 6d926ae3d..9392a4dbe 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -457,7 +457,7 @@ class CI_Session_cookie extends CI_Session_driver { } // No result? Kill it! - if ($query->num_rows() === 0) + if (empty($query) OR $query->num_rows() === 0) { $this->sess_destroy(); return FALSE; -- cgit v1.2.3-24-g4f1b From 80500afbd188600212ca913a7bac073009feac73 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 1 Jan 2013 08:16:53 +0200 Subject: [ci skip] Happy new year --- system/libraries/Session/Session.php | 2 +- system/libraries/Session/drivers/Session_cookie.php | 2 +- system/libraries/Session/drivers/Session_native.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 85a483592..c7f6f828c 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2013, 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 2.0 diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 9392a4dbe..474641642 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2013, 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 diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 3e700ad5d..fb5ce1906 100644 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2013, 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 -- cgit v1.2.3-24-g4f1b From cc221dc434e0d31138e81a940d38b81e994d48fe Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 8 Feb 2013 21:57:42 +0200 Subject: [ci skip] Add a missing space --- system/libraries/Session/drivers/Session_cookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 474641642..11bb32fe0 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -805,7 +805,7 @@ class CI_Session_cookie extends CI_Session_driver { { if (is_string($val)) { - $val= str_replace('{{slash}}', '\\', $val); + $val = str_replace('{{slash}}', '\\', $val); } } -- cgit v1.2.3-24-g4f1b From f8e2d0ed10018f81db5814d421dbafbe6d0834e4 Mon Sep 17 00:00:00 2001 From: Dionysis Arvanitis Date: Tue, 19 Feb 2013 23:27:16 +0200 Subject: Issue #2086 Session_cookie's _update_db not guaranteed to update --- system/libraries/Session/drivers/Session_cookie.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 11bb32fe0..057e5a1d1 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -602,6 +602,9 @@ class CI_Session_cookie extends CI_Session_driver { $set['user_data'] = $this->_serialize($userdata); } + // Reset query builder values. + $this->CI->db->reset_query(); + // Run the update query // Any time we change the session id, it gets updated immediately, // so our where clause below is always safe -- cgit v1.2.3-24-g4f1b From 930d8ef0f04688e63cfcdaa6f0f7b073e7b644ff Mon Sep 17 00:00:00 2001 From: Daniel Robbins Date: Fri, 1 Mar 2013 21:36:48 -0500 Subject: Fix Session cookie driver storing untrimmed user agent string in the database causing set_userdata() calls to fail when $config['sess_match_useragent'] = TRUE Signed-off-by: Daniel Robbins --- system/libraries/Session/drivers/Session_cookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 057e5a1d1..0e8644102 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -494,7 +494,7 @@ class CI_Session_cookie extends CI_Session_driver { $this->userdata = array( 'session_id' => $this->_make_sess_id(), 'ip_address' => $this->CI->input->ip_address(), - 'user_agent' => substr($this->CI->input->user_agent(), 0, 120), + 'user_agent' => trim(substr($this->CI->input->user_agent(), 0, 120)), 'last_activity' => $this->now, ); -- cgit v1.2.3-24-g4f1b From 0612756dd37a3472259a19814e1a9bb403ab6e11 Mon Sep 17 00:00:00 2001 From: vlakoff Date: Sat, 30 Mar 2013 00:06:39 +0100 Subject: Some cleanup related to mt_rand() - min and max values are 0 and mt_getrandmax() by default - remove useless mt_srand() seed calls --- system/libraries/Session/drivers/Session_cookie.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 0e8644102..7174d63c8 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -641,7 +641,7 @@ class CI_Session_cookie extends CI_Session_driver { $new_sessid = ''; do { - $new_sessid .= mt_rand(0, mt_getrandmax()); + $new_sessid .= mt_rand(); } while (strlen($new_sessid) < 32); @@ -832,7 +832,6 @@ class CI_Session_cookie extends CI_Session_driver { $probability = ini_get('session.gc_probability'); $divisor = ini_get('session.gc_divisor'); - srand(time()); if ((mt_rand(0, $divisor) / $divisor) < $probability) { $expire = $this->now - $this->sess_expiration; -- cgit v1.2.3-24-g4f1b From e18de50dc1a4369aef18df9b368f8bfb0f9177d9 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 17 Jul 2013 19:59:20 +0300 Subject: Cherry-picking some changes from PR #2425: - Session events logging (debug) - Bug fix for OCI8 method stored_procedure() --- system/libraries/Session/drivers/Session_cookie.php | 9 +++++++++ system/libraries/Session/drivers/Session_native.php | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 7174d63c8..d3d22d03a 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -402,6 +402,7 @@ class CI_Session_cookie extends CI_Session_driver { // Is the session data we unserialized an array with the correct format? if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity'])) { + log_message('debug', 'Session: Wrong cookie data format'); $this->sess_destroy(); return FALSE; } @@ -409,6 +410,7 @@ class CI_Session_cookie extends CI_Session_driver { // Is the session current? if (($session['last_activity'] + $this->sess_expiration) < $this->now OR $session['last_activity'] > $this->now) { + log_message('debug', 'Session: Expired'); $this->sess_destroy(); return FALSE; } @@ -416,6 +418,7 @@ class CI_Session_cookie extends CI_Session_driver { // Does the IP match? if ($this->sess_match_ip === TRUE && $session['ip_address'] !== $this->CI->input->ip_address()) { + log_message('debug', 'Session: IP address mismatch'); $this->sess_destroy(); return FALSE; } @@ -424,6 +427,7 @@ class CI_Session_cookie extends CI_Session_driver { if ($this->sess_match_useragent === TRUE && trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120))) { + log_message('debug', 'Session: User Agent string mismatch'); $this->sess_destroy(); return FALSE; } @@ -459,6 +463,7 @@ class CI_Session_cookie extends CI_Session_driver { // No result? Kill it! if (empty($query) OR $query->num_rows() === 0) { + log_message('debug', 'Session: No match found in our database'); $this->sess_destroy(); return FALSE; } @@ -498,6 +503,8 @@ class CI_Session_cookie extends CI_Session_driver { 'last_activity' => $this->now, ); + log_message('debug', 'Session: Creating new session ('.$this->userdata['session_id'].')'); + // Check for database if ($this->sess_use_database === TRUE) { @@ -536,6 +543,8 @@ class CI_Session_cookie extends CI_Session_driver { { // Get new id $this->userdata['session_id'] = $this->_make_sess_id(); + + log_message('debug', 'Session: Regenerate ID'); } // Check for database diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index fb5ce1906..c237ad059 100644 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -117,18 +117,21 @@ class CI_Session_native extends CI_Session_driver { if (isset($_SESSION['last_activity']) && (($_SESSION['last_activity'] + $expire) < $now OR $_SESSION['last_activity'] > $now)) { // Expired - destroy + log_message('debug', 'Session: Expired'); $destroy = TRUE; } elseif ($config['sess_match_ip'] === TRUE && isset($_SESSION['ip_address']) && $_SESSION['ip_address'] !== $this->CI->input->ip_address()) { // IP doesn't match - destroy + log_message('debug', 'Session: IP address mismatch'); $destroy = TRUE; } elseif ($config['sess_match_useragent'] === TRUE && isset($_SESSION['user_agent']) && $_SESSION['user_agent'] !== trim(substr($this->CI->input->user_agent(), 0, 50))) { // Agent doesn't match - destroy + log_message('debug', 'Session: User Agent string mismatch'); $destroy = TRUE; } @@ -145,9 +148,10 @@ class CI_Session_native extends CI_Session_driver { && ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now) { // Changing the session ID amidst a series of AJAX calls causes problems - if( ! $this->CI->input->is_ajax_request()) + if ( ! $this->CI->input->is_ajax_request()) { // Regenerate ID, but don't destroy session + log_message('debug', 'Session: Regenerate ID'); $this->sess_regenerate(FALSE); } } -- cgit v1.2.3-24-g4f1b From c958eebea2525133bcef9fe47a5dfab9e23128dd Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Jul 2013 14:28:50 +0300 Subject: Optimize CI_Session::__construct() routines and make driver validity check stricter --- system/libraries/Session/Session.php | 39 +++++++++++++++++------------------- 1 file changed, 18 insertions(+), 21 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index c7f6f828c..659a0269e 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -59,12 +59,19 @@ class CI_Session extends CI_Driver_Library { */ public $params = array(); + /** + * Valid drivers list + * + * @var array + */ + public $valid_drivers = array('native', 'cookie'); + /** * Current driver in use * * @var string */ - protected $current = NULL; + public $current = NULL; /** * User data @@ -105,36 +112,26 @@ class CI_Session extends CI_Driver_Library { log_message('debug', 'CI_Session Class Initialized'); - // Get valid drivers list - $this->valid_drivers = array( - 'native', - 'cookie' - ); - $key = 'sess_valid_drivers'; - $drivers = isset($params[$key]) ? $params[$key] : $CI->config->item($key); - if ($drivers) + // Add possible extra entries to our valid drivers list + $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $CI->config->item('sess_valid_drivers'); + if ( ! empty($drivers)) { - // Add driver names to valid list - foreach ((array) $drivers as $driver) - { - if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers))) - { - $this->valid_drivers[] = $driver; - } - } + $drivers = array_map('strtolower', (array) $drivers); + $this->valid_drivers = array_merge($this->valid_drivers, array_diff($drivers, $this->valid_drivers)); } // Get driver to load - $key = 'sess_driver'; - $driver = isset($params[$key]) ? $params[$key] : $CI->config->item($key); + $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $CI->config->item('sess_driver'); if ( ! $driver) { + log_message('debug', "Session: No driver name is configured, defaulting to 'cookie'."); $driver = 'cookie'; } - if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers))) + if ( ! in_array($driver, $this->valid_drivers)) { - $this->valid_drivers[] = $driver; + log_message('error', 'Session: Configured driver name is not valid, aborting.'); + return; } // Save a copy of parameters in case drivers need access -- cgit v1.2.3-24-g4f1b From f964b16f3db95d655420dfae2012ee9fbb98a1a8 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 12 Nov 2013 17:04:55 +0200 Subject: Deprecate CI_Input::is_cli_request() and add common function is_cli() to replace it Calls to this function are often needed before the Input library is available --- system/libraries/Session/Session.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 659a0269e..19de97994 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -102,10 +102,10 @@ class CI_Session extends CI_Driver_Library { */ public function __construct(array $params = array()) { - $CI =& get_instance(); + $_config =& get_instance()->config; // No sessions under CLI - if ($CI->input->is_cli_request()) + if (is_cli()) { return; } @@ -113,7 +113,7 @@ class CI_Session extends CI_Driver_Library { log_message('debug', 'CI_Session Class Initialized'); // Add possible extra entries to our valid drivers list - $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $CI->config->item('sess_valid_drivers'); + $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $_config->item('sess_valid_drivers'); if ( ! empty($drivers)) { $drivers = array_map('strtolower', (array) $drivers); @@ -121,7 +121,7 @@ class CI_Session extends CI_Driver_Library { } // Get driver to load - $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $CI->config->item('sess_driver'); + $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $_config->item('sess_driver'); if ( ! $driver) { log_message('debug', "Session: No driver name is configured, defaulting to 'cookie'."); -- cgit v1.2.3-24-g4f1b From 74c5f2668d31f7384ea5f014014356144059cbf3 Mon Sep 17 00:00:00 2001 From: Tyler Brownell Date: Fri, 13 Dec 2013 00:23:12 -0500 Subject: Issue #2763 - Fixes Session GC Probability Calculation This should resolve issue #2763 where the cookie session garbage collection was running every request. --- system/libraries/Session/drivers/Session_cookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index d3d22d03a..cd8074474 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -841,7 +841,7 @@ class CI_Session_cookie extends CI_Session_driver { $probability = ini_get('session.gc_probability'); $divisor = ini_get('session.gc_divisor'); - if ((mt_rand(0, $divisor) / $divisor) < $probability) + if (mt_rand(1, $divisor) <= $probability) { $expire = $this->now - $this->sess_expiration; $this->CI->db->delete($this->sess_table_name, 'last_activity < '.$expire); -- cgit v1.2.3-24-g4f1b From 5d6b9c597a9870f55a65bcfcb301d19d83447078 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sat, 21 Dec 2013 13:56:41 -0800 Subject: Remove unneeded manual escaping of session data --- .../libraries/Session/drivers/Session_cookie.php | 63 ++-------------------- 1 file changed, 3 insertions(+), 60 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index cd8074474..124e0098e 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -739,86 +739,29 @@ class CI_Session_cookie extends CI_Session_driver { /** * Serialize an array * - * This function first converts any slashes found in the array to a temporary - * marker, so when it gets unserialized the slashes will be preserved + * This function serializes an array * * @param mixed Data to serialize * @return string Serialized data */ protected function _serialize($data) { - if (is_array($data)) - { - array_walk_recursive($data, array(&$this, '_escape_slashes')); - } - elseif (is_string($data)) - { - $data = str_replace('\\', '{{slash}}', $data); - } - return serialize($data); } // ------------------------------------------------------------------------ - /** - * Escape slashes - * - * This function converts any slashes found into a temporary marker - * - * @param string Value - * @param string Key - * @return void - */ - protected function _escape_slashes(&$val, $key) - { - if (is_string($val)) - { - $val = str_replace('\\', '{{slash}}', $val); - } - } - - // ------------------------------------------------------------------------ - /** * Unserialize * - * This function unserializes a data string, then converts any - * temporary slash markers back to actual slashes + * This function unserializes a data string * * @param mixed Data to unserialize * @return mixed Unserialized data */ protected function _unserialize($data) { - $data = @unserialize(trim($data)); - - if (is_array($data)) - { - array_walk_recursive($data, array(&$this, '_unescape_slashes')); - return $data; - } - - return is_string($data) ? str_replace('{{slash}}', '\\', $data) : $data; - } - - // ------------------------------------------------------------------------ - - /** - * Unescape slashes - * - * This function converts any slash markers back into actual slashes - * - * @param string Value - * @param string Key - * @return void - */ - protected function _unescape_slashes(&$val, $key) - { - if (is_string($val)) - { - $val = str_replace('{{slash}}', '\\', $val); - } + return @unserialize(trim($data)); } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 5306cad2e40596a3a6fcac787e54689a7095e769 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Mon, 23 Dec 2013 11:10:51 -0800 Subject: Remove _serialize() and _unserialize() methods Since removing the unneeded manual escaping code, there is no-longer any reason to have the serialization functions abstracted. This also allows us to only suppress errors when unserializing cookie data, and only trim when we are unserializing database data (see commit 6b8312). --- .../libraries/Session/drivers/Session_cookie.php | 38 +++------------------- 1 file changed, 4 insertions(+), 34 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 124e0098e..dc75d8e8e 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -397,7 +397,7 @@ class CI_Session_cookie extends CI_Session_driver { } // Unserialize the session array - $session = $this->_unserialize($session); + $session = @unserialize($session); // Is the session data we unserialized an array with the correct format? if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity'])) @@ -472,7 +472,7 @@ class CI_Session_cookie extends CI_Session_driver { $row = $query->row(); if ( ! empty($row->user_data)) { - $custom_data = $this->_unserialize($row->user_data); + $custom_data = unserialize(trim($row->user_data)); if (is_array($custom_data)) { @@ -608,7 +608,7 @@ class CI_Session_cookie extends CI_Session_driver { if ( ! empty($userdata)) { // Serialize the custom data array so we can store it - $set['user_data'] = $this->_serialize($userdata); + $set['user_data'] = serialize($userdata); } // Reset query builder values. @@ -696,7 +696,7 @@ class CI_Session_cookie extends CI_Session_driver { : $this->userdata; // Serialize the userdata for the cookie - $cookie_data = $this->_serialize($cookie_data); + $cookie_data = serialize($cookie_data); if ($this->sess_encrypt_cookie === TRUE) { @@ -736,36 +736,6 @@ class CI_Session_cookie extends CI_Session_driver { // ------------------------------------------------------------------------ - /** - * Serialize an array - * - * This function serializes an array - * - * @param mixed Data to serialize - * @return string Serialized data - */ - protected function _serialize($data) - { - return serialize($data); - } - - // ------------------------------------------------------------------------ - - /** - * Unserialize - * - * This function unserializes a data string - * - * @param mixed Data to unserialize - * @return mixed Unserialized data - */ - protected function _unserialize($data) - { - return @unserialize(trim($data)); - } - - // ------------------------------------------------------------------------ - /** * Garbage collection * -- cgit v1.2.3-24-g4f1b From e6376aa4a95b7641a5d0cc5101118b9307be75bc Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 6 Jan 2014 13:11:30 +0200 Subject: Make CI_Session's set_userdata(), set_flashdata(), set_tempdata(), unset_userdata() and unset_flashdata()'s first parameter mandatory --- system/libraries/Session/Session.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 19de97994..ac97b944c 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -288,7 +288,7 @@ class CI_Session extends CI_Driver_Library { * @param string Item value or empty string * @return void */ - public function set_userdata($newdata = array(), $newval = '') + public function set_userdata($newdata, $newval = '') { // Wrap params as array if singular if (is_string($newdata)) @@ -317,7 +317,7 @@ class CI_Session extends CI_Driver_Library { * @param mixed Item name or array of item names * @return void */ - public function unset_userdata($newdata = array()) + public function unset_userdata($newdata) { // Wrap single name as array if (is_string($newdata)) @@ -360,7 +360,7 @@ class CI_Session extends CI_Driver_Library { * @param string Item value or empty string * @return void */ - public function set_flashdata($newdata = array(), $newval = '') + public function set_flashdata($newdata, $newval = '') { // Wrap item as array if singular if (is_string($newdata)) @@ -434,7 +434,7 @@ class CI_Session extends CI_Driver_Library { * @param int Item lifetime in seconds or 0 for default * @return void */ - public function set_tempdata($newdata = array(), $newval = '', $expire = 0) + public function set_tempdata($newdata, $newval = '', $expire = 0) { // Set expiration time $expire = time() + ($expire ? $expire : self::TEMP_EXP_DEF); @@ -475,7 +475,7 @@ class CI_Session extends CI_Driver_Library { * @param mixed Item name or array of item names * @return void */ - public function unset_tempdata($newdata = array()) + public function unset_tempdata($newdata) { // Get expirations list $expirations = $this->userdata(self::EXPIRATION_KEY); -- cgit v1.2.3-24-g4f1b From bfb635b276d880336db795f1a603de66ccfc80f6 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 8 Jan 2014 18:32:05 +0200 Subject: Make newline standardization configurable Added ['standardize_newlines'] Also altered the Session cookie driver, which experienced issues with this feature due to it's HMAC verification failing after the Input class alters newlines in non-encrypted session cookies. Supersedes PR #2470 --- .../libraries/Session/drivers/Session_cookie.php | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index dc75d8e8e..65debcb44 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -165,6 +165,8 @@ class CI_Session_cookie extends CI_Session_driver { */ public $now; + // ------------------------------------------------------------------------ + /** * Default userdata keys * @@ -184,6 +186,15 @@ class CI_Session_cookie extends CI_Session_driver { */ protected $data_dirty = FALSE; + /** + * Standardize newlines flag + * + * @var bool + */ + protected $_standardize_newlines; + + // ------------------------------------------------------------------------ + /** * Initialize session driver object * @@ -209,9 +220,11 @@ class CI_Session_cookie extends CI_Session_driver { 'sess_time_to_update', 'time_reference', 'cookie_prefix', - 'encryption_key' + 'encryption_key', ); + $this->_standardize_newlines = (bool) $config['standardize_newlines']; + foreach ($prefs as $key) { $this->$key = isset($this->_parent->params[$key]) @@ -695,6 +708,16 @@ class CI_Session_cookie extends CI_Session_driver { ? array_intersect_key($this->userdata, $this->defaults) : $this->userdata; + // The Input class will do this and since we use HMAC verification, + // unless we standardize here as well, the hash won't match. + if ($this->_standardize_newlines) + { + foreach (array_keys($this->userdata) as $key) + { + $this->userdata[$key] = preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $this->userdata[$key]); + } + } + // Serialize the userdata for the cookie $cookie_data = serialize($cookie_data); -- cgit v1.2.3-24-g4f1b From 4ea76cc2216b19bfae38dbbfe7104c21ee278d81 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 8 Jan 2014 21:49:23 +0200 Subject: Fix 2 errors caused by recent commits --- system/libraries/Session/drivers/Session_cookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 65debcb44..971dfeabe 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -223,7 +223,7 @@ class CI_Session_cookie extends CI_Session_driver { 'encryption_key', ); - $this->_standardize_newlines = (bool) $config['standardize_newlines']; + $this->_standardize_newlines = (bool) config_item('standardize_newlines'); foreach ($prefs as $key) { -- cgit v1.2.3-24-g4f1b From ecc260e0be0cdb55c4e4802b78ddd78b0d8b0ebc Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 24 Jan 2014 14:20:13 +0200 Subject: Righting a wrong in the Session library - Change userdata(), flashdata(), tempdata() to return all the respective data when no parameter is passed. - Revert the addition of all_flashdata(). - Deprecate all_userdata(). - Fix related changelog entries that were all inconsistent. --- system/libraries/Session/Session.php | 89 ++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 40 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index ac97b944c..d9f2f506f 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -238,9 +238,14 @@ class CI_Session extends CI_Driver_Library { * @param string Item key * @return string Item value or NULL if not found */ - public function userdata($item) + public function userdata($item = NULL) { - return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL; + if (isset($item)) + { + return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL; + } + + return isset($this->userdata) ? $this->userdata : array(); } // ------------------------------------------------------------------------ @@ -248,35 +253,12 @@ class CI_Session extends CI_Driver_Library { /** * Fetch all session data * + * @deprecated 3.0.0 Use userdata() with no parameters instead * @return array User data array */ public function all_userdata() { - return isset($this->userdata) ? $this->userdata : NULL; - } - - // ------------------------------------------------------------------------ - - /** - * Fetch all flashdata - * - * @return array Flash data array - */ - public function all_flashdata() - { - $out = array(); - - // loop through all userdata - foreach ($this->all_userdata() as $key => $val) - { - // if it contains flashdata, add it - if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE) - { - $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key); - $out[$key] = $val; - } - } - return $out; + return isset($this->userdata) ? $this->userdata : array(); } // ------------------------------------------------------------------------ @@ -417,11 +399,25 @@ class CI_Session extends CI_Driver_Library { * @param string Item key * @return string */ - public function flashdata($key) + public function flashdata($key = NULL) { - // Prepend key and retrieve value - $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; - return $this->userdata($flashdata_key); + if (isset($key)) + { + return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key); + } + + // Get our flashdata items from userdata + $out = array(); + foreach ($this->userdata() as $key => $val) + { + if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE) + { + $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key); + $out[$key] = $val; + } + } + + return $out; } // ------------------------------------------------------------------------ @@ -514,11 +510,25 @@ class CI_Session extends CI_Driver_Library { * @param string Item key * @return string */ - public function tempdata($key) + public function tempdata($key = NULL) { - // Prepend key and return value - $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key; - return $this->userdata($tempdata_key); + if (isset($key)) + { + return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key); + } + + // Get our tempdata items from userdata + $out = array(); + foreach ($this->userdata() as $key => $val) + { + if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_EXP) !== FALSE) + { + $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_EXP, '', $key); + $out[$key] = $val; + } + } + + return $out; } // ------------------------------------------------------------------------ @@ -531,13 +541,12 @@ class CI_Session extends CI_Driver_Library { */ protected function _flashdata_mark() { - foreach ($this->all_userdata() as $name => $value) + foreach ($this->userdata() as $name => $value) { $parts = explode(self::FLASHDATA_NEW, $name); if (count($parts) === 2) { - $new_name = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1]; - $this->set_userdata($new_name, $value); + $this->set_userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1], $value); $this->unset_userdata($name); } } @@ -552,7 +561,7 @@ class CI_Session extends CI_Driver_Library { */ protected function _flashdata_sweep() { - $userdata = $this->all_userdata(); + $userdata = $this->userdata(); foreach (array_keys($userdata) as $key) { if (strpos($key, self::FLASHDATA_OLD)) @@ -581,7 +590,7 @@ class CI_Session extends CI_Driver_Library { // Unset expired elements $now = time(); - $userdata = $this->all_userdata(); + $userdata = $this->userdata(); foreach (array_keys($userdata) as $key) { if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now) -- cgit v1.2.3-24-g4f1b From 4a2918a33c756ac7cc9defc2e6acd371e4412af6 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 5 Feb 2014 01:03:46 +0200 Subject: Integrate CI_Encryption into the framework TODO: Add documentation in user_guide_src/source/libraries/encryption.rst --- .../libraries/Session/drivers/Session_cookie.php | 55 ++++++++++++---------- 1 file changed, 30 insertions(+), 25 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 971dfeabe..5d338fc04 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -240,7 +240,7 @@ class CI_Session_cookie extends CI_Session_driver { // Do we need encryption? If so, load the encryption class if ($this->sess_encrypt_cookie === TRUE) { - $this->CI->load->library('encrypt'); + $this->CI->load->library('encryption'); } // Check for database @@ -383,30 +383,33 @@ class CI_Session_cookie extends CI_Session_driver { return FALSE; } - $len = strlen($session) - 40; - - if ($len < 0) + if ($this->sess_encrypt_cookie === TRUE) { - log_message('debug', 'The session cookie was not signed.'); - return FALSE; + $session = $this->CI->encryption->decrypt($session); + if ($session === FALSE) + { + log_message('error', 'Session: Unable to decrypt the session cookie, possibly due to a HMAC mismatch.'); + return FALSE; + } } - - // Check cookie authentication - $hmac = substr($session, $len); - $session = substr($session, 0, $len); - - if ($hmac !== hash_hmac('sha1', $session, $this->encryption_key)) + else { - log_message('error', 'The session cookie data did not match what was expected.'); - $this->sess_destroy(); - return FALSE; - } + if (($len = strlen($session) - 40) <= 0) + { + log_message('error', 'Session: The session cookie was not signed.'); + return FALSE; + } - // Check for encryption - if ($this->sess_encrypt_cookie === TRUE) - { - // Decrypt the cookie data - $session = $this->CI->encrypt->decode($session); + // Check cookie authentication + $hmac = substr($session, $len); + $session = substr($session, 0, $len); + + if ($hmac !== hash_hmac('sha1', $session, $this->encryption_key)) + { + log_message('error', 'Session: HMAC mismatch. The session cookie data did not match what was expected.'); + $this->sess_destroy(); + return FALSE; + } } // Unserialize the session array @@ -723,11 +726,13 @@ class CI_Session_cookie extends CI_Session_driver { if ($this->sess_encrypt_cookie === TRUE) { - $cookie_data = $this->CI->encrypt->encode($cookie_data); + $cookie_data = $this->CI->encryption->encrypt($cookie_data); + } + else + { + // Require message authentication + $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key); } - - // Require message authentication - $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key); $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time(); -- cgit v1.2.3-24-g4f1b From 3aa781a65267d72000009df0fa2feee5cb3bdd8d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 6 Feb 2014 05:34:19 +0200 Subject: Make CI_Session's HMAC comparison time-attack-safe --- system/libraries/Session/drivers/Session_cookie.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 971dfeabe..c8dfad6c9 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -395,7 +395,15 @@ class CI_Session_cookie extends CI_Session_driver { $hmac = substr($session, $len); $session = substr($session, 0, $len); - if ($hmac !== hash_hmac('sha1', $session, $this->encryption_key)) + // Time-attack-safe comparison + $hmac_check = hash_hmac('sha1', $session, $this->encryption_key); + $diff = 0; + for ($i = 0; $i < 40; $i++) + { + $diff |= ord($hmac[$i]) ^ ord($hmac_check[$i]); + } + + if ($diff !== 0) { log_message('error', 'The session cookie data did not match what was expected.'); $this->sess_destroy(); -- cgit v1.2.3-24-g4f1b From 871754af60251993d640981e107d2def5f2db396 Mon Sep 17 00:00:00 2001 From: darwinel Date: Tue, 11 Feb 2014 17:34:57 +0100 Subject: 2013 > 2014 Update copyright notices from 2013 to 2014. And update one calendar example in user_guide from year 2013/2014 to 2014/2015. --- system/libraries/Session/Session.php | 2 +- system/libraries/Session/drivers/Session_cookie.php | 2 +- system/libraries/Session/drivers/Session_native.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index d9f2f506f..905352bb3 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 2.0 diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 79712ad94..566c40bd8 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index c237ad059..4104652b8 100644 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -18,7 +18,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, 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 -- cgit v1.2.3-24-g4f1b From 47a47fb9fafdb26206d01d846d8013f6e883eb37 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 31 May 2014 16:08:30 +0300 Subject: Initial version of new Session library --- system/libraries/Session/Session.php | 846 ++++++++++----------- .../libraries/Session/SessionHandlerInterface.php | 51 ++ system/libraries/Session/Session_driver.php | 202 +++++ .../libraries/Session/drivers/Session_cookie.php | 805 -------------------- .../Session/drivers/Session_database_driver.php | 317 ++++++++ .../Session/drivers/Session_files_driver.php | 276 +++++++ .../libraries/Session/drivers/Session_native.php | 246 ------ 7 files changed, 1255 insertions(+), 1488 deletions(-) create mode 100644 system/libraries/Session/SessionHandlerInterface.php create mode 100644 system/libraries/Session/Session_driver.php delete mode 100644 system/libraries/Session/drivers/Session_cookie.php create mode 100644 system/libraries/Session/drivers/Session_database_driver.php create mode 100644 system/libraries/Session/drivers/Session_files_driver.php delete mode 100644 system/libraries/Session/drivers/Session_native.php (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 905352bb3..0d444e8ca 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -29,729 +29,701 @@ defined('BASEPATH') OR exit('No direct script access allowed'); /** * CodeIgniter Session Class * - * The user interface defined by EllisLabs, now with puggable drivers to manage different storage mechanisms. - * By default, the cookie session driver will load, but the 'sess_driver' config/param item (see above) can be - * used to specify the 'native' driver, or any other you might create. - * Once loaded, this driver setup is a drop-in replacement for the former CI_Session library, taking its place as the - * 'session' member of the global controller framework (e.g.: $CI->session or $this->session). - * In keeping with the CI_Driver methodology, multiple drivers may be loaded, although this might be a bit confusing. - * The CI_Session library class keeps track of the most recently loaded driver as "current" to call for driver methods. - * Ideally, one driver is loaded and all calls go directly through the main library interface. However, any methods - * called through the specific driver will switch the "current" driver to itself before invoking the library method - * (which will then call back into the driver for low-level operations). So, alternation between two drivers can be - * achieved by specifying which driver to use for each call (e.g.: $this->session->native->set_userdata('foo', 'bar'); - * $this->session->cookie->userdata('foo'); $this->session->native->unset_userdata('foo');). Notice in the previous - * example that the _native_ userdata value 'foo' would be set to 'bar', which would NOT be returned by the call for - * the _cookie_ userdata 'foo', nor would the _cookie_ value be unset by the call to unset the _native_ 'foo' value. - * * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author EllisLab Dev Team + * @author Andrey Andreev * @link http://codeigniter.com/user_guide/libraries/sessions.html */ -class CI_Session extends CI_Driver_Library { - - /** - * Initialization parameters - * - * @var array - */ - public $params = array(); - - /** - * Valid drivers list - * - * @var array - */ - public $valid_drivers = array('native', 'cookie'); +class CI_Session { - /** - * Current driver in use - * - * @var string - */ - public $current = NULL; - - /** - * User data - * - * @var array - */ - protected $userdata = array(); - - // ------------------------------------------------------------------------ - - const FLASHDATA_KEY = 'flash'; - const FLASHDATA_NEW = ':new:'; - const FLASHDATA_OLD = ':old:'; - const FLASHDATA_EXP = ':exp:'; - const EXPIRATION_KEY = '__expirations'; - const TEMP_EXP_DEF = 300; + protected $_driver = 'files'; // ------------------------------------------------------------------------ /** - * CI_Session constructor - * - * The constructor loads the configured driver ('sess_driver' in config.php or as a parameter), running - * routines in its constructor, and manages flashdata aging. + * Class constructor * - * @param array Configuration parameters + * @param array $params Configuration parameters * @return void */ public function __construct(array $params = array()) { - $_config =& get_instance()->config; // No sessions under CLI if (is_cli()) { + log_message('debug', 'Session: Initialization under CLI aborted.'); return; } - - log_message('debug', 'CI_Session Class Initialized'); - - // Add possible extra entries to our valid drivers list - $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $_config->item('sess_valid_drivers'); - if ( ! empty($drivers)) + elseif ((bool) ini_get('session.auto_start')) { - $drivers = array_map('strtolower', (array) $drivers); - $this->valid_drivers = array_merge($this->valid_drivers, array_diff($drivers, $this->valid_drivers)); + log_message('error', 'Session: session.auto_start is enabled in php.ini. Aborting.'); + return; + } + elseif ( ! empty($params['driver'])) + { + $this->_driver = $params['driver']; + unset($params['driver']); } - // Get driver to load - $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $_config->item('sess_driver'); - if ( ! $driver) + if (($class = $this->_ci_load_classes($this->_driver)) === FALSE) { - log_message('debug', "Session: No driver name is configured, defaulting to 'cookie'."); - $driver = 'cookie'; + return; } - if ( ! in_array($driver, $this->valid_drivers)) + $class = new $class($params); + if ($class instanceof SessionHandlerInterface) { - log_message('error', 'Session: Configured driver name is not valid, aborting.'); + if (is_php('5.4')) + { + session_set_save_handler($class, TRUE); + } + else + { + session_set_save_handler( + array($class, 'open'), + array($class, 'close'), + array($class, 'read'), + array($class, 'write'), + array($class, 'destroy'), + array($class, 'gc') + ); + + register_shutdown_function('session_write_close'); + } + } + else + { + log_message('error', "Session: Driver '".$this->_driver."' doesn't implement SessionHandlerInterface. Aborting."); return; } - // Save a copy of parameters in case drivers need access - $this->params = $params; + session_start(); + $this->_ci_init_vars(); - // Load driver and get array reference - $this->load_driver($driver); + log_message('debug', "Session: Class initialized using '".$this->_driver."' driver."); + } - // Delete 'old' flashdata (from last request) - $this->_flashdata_sweep(); + // ------------------------------------------------------------------------ - // Mark all new flashdata as old (data will be deleted before next request) - $this->_flashdata_mark(); + protected function _ci_load_classes($driver) + { + // PHP 5.4 compatibility + interface_exists('SessionHandlerInterface', FALSE) OR require_once(BASEPATH.'libraries/Session/SessionHandlerInterface.php'); - // Delete expired tempdata - $this->_tempdata_sweep(); + $prefix = config_item('subclass_prefix'); - log_message('debug', 'CI_Session routines successfully run'); - } + if ( ! class_exists('CI_Session_driver', FALSE)) + { + if (file_exists($file_path = APPPATH.'libraries/Session/Session_driver.php') OR file_exists($file_path = BASEPATH.'libraries/Session/Session_driver.php')) + { + require_once($file_path); + } - // ------------------------------------------------------------------------ + if (file_exists($file_path = APPPATH.'libraries/Session/'.$prefix.'Session_driver.php')) + { + require_once($file_path); + } + } - /** - * Loads session storage driver - * - * @param string Driver classname - * @return object Loaded driver object - */ - public function load_driver($driver) - { - // Save reference to most recently loaded driver as library default and sync userdata - $this->current = parent::load_driver($driver); - $this->userdata =& $this->current->get_userdata(); - return $this->current; - } + $class = 'Session_'.$driver.'_driver'; - // ------------------------------------------------------------------------ + if ( ! class_exists('CI_'.$class, FALSE)) + { + if (file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$class.'.php') OR file_exists($file_path = BASEPATH.'libraries/Session/drivers/'.$class.'.php')) + { + require_once($file_path); + } - /** - * Select default session storage driver - * - * @param string Driver name - * @return void - */ - public function select_driver($driver) - { - // Validate driver name - $prefix = (string) get_instance()->config->item('subclass_prefix'); - $child = strtolower(str_replace(array('CI_', $prefix, $this->lib_name.'_'), '', $driver)); - if (in_array($child, array_map('strtolower', $this->valid_drivers))) + if ( ! class_exists('CI_'.$class, FALSE)) + { + log_message('error', "Session: Configured driver '".$driver."' was not found. Aborting."); + return FALSE; + } + } + + if ( ! class_exists($prefix.$class) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$prefix.$class.'.php')) { - // See if driver is loaded - if (isset($this->$child)) + require_once($file_path); + if (class_exists($prefix.$class, FALSE)) { - // See if driver is already current - if ($this->$child !== $this->current) - { - // Make driver current and sync userdata - $this->current = $this->$child; - $this->userdata =& $this->current->get_userdata(); - } + return $prefix.$class; } else { - // Load new driver - $this->load_driver($child); + log_message('debug', 'Session: '.$prefix.$class.".php found but it doesn't declare class ".$prefix.$class.'.'); } } + + return 'CI_'.$class; } // ------------------------------------------------------------------------ /** - * Destroy the current session + * Handle temporary variables + * + * Clears old "flash" data, marks the new one for deletion and handles + * "temp" data deletion. * * @return void */ - public function sess_destroy() + protected function _ci_init_vars() { - // Just call destroy on driver - $this->current->sess_destroy(); - } + if ( ! empty($_SESSION['__ci_vars'])) + { + $current_time = time(); - // ------------------------------------------------------------------------ + foreach ($_SESSION['__ci_vars'] as $key => &$value) + { + if ($value === 'new') + { + $_SESSION['__ci_vars'][$key] = 'old'; + } + // Hacky, but 'old' will (implicitly) always be less than time() ;) + // DO NOT move this above the 'new' check! + elseif ($value < $current_time) + { + unset($_SESSION[$key], $_SESSION['__ci_vars'][$key]); + } + } - /** - * Regenerate the current session - * - * @param bool Destroy session data flag (default: false) - * @return void - */ - public function sess_regenerate($destroy = FALSE) - { - // Call regenerate on driver and resync userdata - $this->current->sess_regenerate($destroy); - $this->userdata =& $this->current->get_userdata(); + if (empty($_SESSION['__ci_vars'])) + { + unset($_SESSION['__ci_vars']); + } + } } // ------------------------------------------------------------------------ /** - * Fetch a specific item from the session array + * Mark as flash * - * @param string Item key - * @return string Item value or NULL if not found + * @param mixed $key Session data key(s) + * @return bool */ - public function userdata($item = NULL) + public function mark_as_flash($key) { - if (isset($item)) + if (is_array($key)) { - return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL; - } + for ($i = 0, $c = count($key); $i < $c; $i++) + { + if ( ! isset($_SESSION[$key[$i]])) + { + return FALSE; + } + } - return isset($this->userdata) ? $this->userdata : array(); - } + $new = array_fill_keys($key, 'new'); - // ------------------------------------------------------------------------ + $_SESSION['__ci_vars'] = isset($_SESSION['__ci_vars']) + ? array_merge($_SESSION['__ci_vars'], $new) + : $new; - /** - * Fetch all session data - * - * @deprecated 3.0.0 Use userdata() with no parameters instead - * @return array User data array - */ - public function all_userdata() - { - return isset($this->userdata) ? $this->userdata : array(); + return TRUE; + } + + if ( ! isset($_SESSION[$key])) + { + return FALSE; + } + + $_SESSION['__ci_vars'][$key] = 'new'; + return TRUE; } // ------------------------------------------------------------------------ /** - * Add or change data in the "userdata" array + * Get flash keys * - * @param mixed Item name or array of items - * @param string Item value or empty string - * @return void + * @return array */ - public function set_userdata($newdata, $newval = '') + public function get_flash_keys() { - // Wrap params as array if singular - if (is_string($newdata)) + if ( ! isset($_SESSION['__ci_vars'])) { - $newdata = array($newdata => $newval); + return array(); } - // Set each name/value pair - if (count($newdata) > 0) + $keys = array(); + foreach (array_keys($_SESSION['__ci_vars']) as $key) { - foreach ($newdata as $key => $val) - { - $this->userdata[$key] = $val; - } + is_int($_SESSION['__ci_vars'][$key]) OR $keys[] = $key; } - // Tell driver data changed - $this->current->sess_save(); + return $keys; } // ------------------------------------------------------------------------ /** - * Delete a session variable from the "userdata" array + * Unmark flash * - * @param mixed Item name or array of item names + * @param mixed $key Session data key(s) * @return void */ - public function unset_userdata($newdata) + public function unmark_flash($key) { - // Wrap single name as array - if (is_string($newdata)) + if (empty($_SESSION['__ci_vars'])) { - $newdata = array($newdata => ''); + return; } - // Unset each item name - if (count($newdata) > 0) + is_array($key) OR $key = array($key); + + foreach ($key as $k) { - foreach (array_keys($newdata) as $key) + if (isset($_SESSION['__ci_vars'][$k]) && ! is_int($_SESSION['__ci_vars'][$k])) { - unset($this->userdata[$key]); + unset($_SESSION['__ci_vars'][$k]); } } - // Tell driver data changed - $this->current->sess_save(); + if (empty($_SESSION['__ci_vars'])) + { + unset($_SESSION['__ci_vars']); + } } // ------------------------------------------------------------------------ /** - * Determine if an item exists + * Mark as temp * - * @param string Item name + * @param mixed $key Session data key(s) + * @param int $ttl Time-to-live in seconds * @return bool */ - public function has_userdata($item) + public function mark_as_temp($key, $ttl = 300) { - return isset($this->userdata[$item]); + $ttl += time(); + + if (is_array($key)) + { + $temp = array(); + + foreach ($key as $k => $v) + { + // Do we have a key => ttl pair, or just a key? + if (is_int($k)) + { + $k = $v; + $v = $ttl; + } + else + { + $v += time(); + } + + if ( ! isset($_SESSION[$k])) + { + return FALSE; + } + + $temp[$k] = $ts; + } + + $_SESSION['__ci_vars'] = isset($_SESSION['__ci_vars']) + ? array_merge($_SESSION['__ci_vars'], $temp) + : $temp; + + return TRUE; + } + + if ( ! isset($_SESSION[$key])) + { + return FALSE; + } + + $_SESSION['__ci_vars'][$key] = $ttl; + return TRUE; } // ------------------------------------------------------------------------ /** - * Add or change flashdata, only available until the next request + * Get temp keys * - * @param mixed Item name or array of items - * @param string Item value or empty string - * @return void + * @return array */ - public function set_flashdata($newdata, $newval = '') + public function get_temp_keys() { - // Wrap item as array if singular - if (is_string($newdata)) + if ( ! isset($_SESSION['__ci_vars'])) { - $newdata = array($newdata => $newval); + return array(); } - // Prepend each key name and set value - if (count($newdata) > 0) + $keys = array(); + foreach (array_keys($_SESSION['__ci_vars']) as $key) { - foreach ($newdata as $key => $val) - { - $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key; - $this->set_userdata($flashdata_key, $val); - } + is_int($_SESSION['__ci_vars'][$key]) && $keys[] = $key; } + + return $keys; } // ------------------------------------------------------------------------ /** - * Keeps existing flashdata available to next request. + * Unmark flash * - * @param mixed Item key(s) + * @param mixed $key Session data key(s) * @return void */ - public function keep_flashdata($key) + public function unmark_temp($key) { + if (empty($_SESSION['__ci_vars'])) + { + return; + } - if (is_array($key)) + is_array($key) OR $key = array($key); + + foreach ($key as $k) { - foreach ($key as $k) + if (isset($_SESSION['__ci_vars'][$k]) && is_int($_SESSION['__ci_vars'][$k])) { - $this->keep_flashdata($k); + unset($_SESSION['__ci_vars'][$k]); } - - return; } - // 'old' flashdata gets removed. Here we mark all flashdata as 'new' to preserve it from _flashdata_sweep() - // Note the function will return NULL if the $key provided cannot be found - $old_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key; - $value = $this->userdata($old_flashdata_key); - - $new_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key; - $this->set_userdata($new_flashdata_key, $value); + if (empty($_SESSION['__ci_vars'])) + { + unset($_SESSION['__ci_vars']); + } } // ------------------------------------------------------------------------ /** - * Fetch a specific flashdata item from the session array + * __get() * - * @param string Item key - * @return string + * @param string $key 'session_id' or a session data key + * @return mixed */ - public function flashdata($key = NULL) + public function __get($key) { - if (isset($key)) + // Note: Keep this order the same, just in case somebody wants to + // use 'session_id' as a session data key, for whatever reason + if (isset($_SESSION[$key])) { - return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key); + return $_SESSION[$key]; } - - // Get our flashdata items from userdata - $out = array(); - foreach ($this->userdata() as $key => $val) + elseif ($key === 'session_id') { - if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE) - { - $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key); - $out[$key] = $val; - } + return session_id(); } - return $out; + return NULL; } // ------------------------------------------------------------------------ /** - * Add or change tempdata, only available until expiration + * __set() * - * @param mixed Item name or array of items - * @param string Item value or empty string - * @param int Item lifetime in seconds or 0 for default + * @param string $key Session data key + * @param mixed $value Session data value * @return void */ - public function set_tempdata($newdata, $newval = '', $expire = 0) + public function __set($key, $value) { - // Set expiration time - $expire = time() + ($expire ? $expire : self::TEMP_EXP_DEF); - - // Wrap item as array if singular - if (is_string($newdata)) - { - $newdata = array($newdata => $newval); - } - - // Get or create expiration list - $expirations = $this->userdata(self::EXPIRATION_KEY); - if ( ! $expirations) - { - $expirations = array(); - } + $_SESSION[$key] = $value; + } - // Prepend each key name and set value - if (count($newdata) > 0) - { - foreach ($newdata as $key => $val) - { - $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key; - $expirations[$tempdata_key] = $expire; - $this->set_userdata($tempdata_key, $val); - } - } + // ------------------------------------------------------------------------ - // Update expiration list - $this->set_userdata(self::EXPIRATION_KEY, $expirations); + /** + * Session destroy + * + * Legacy CI_Session compatibility method + * + * @return void + */ + public function sess_destroy() + { + session_destroy(); } // ------------------------------------------------------------------------ /** - * Delete a temporary session variable from the "userdata" array + * Session regenerate + * + * Legacy CI_Session compatibility method * - * @param mixed Item name or array of item names + * @param bool $destroy Destroy old session data flag * @return void */ - public function unset_tempdata($newdata) + public function sess_regenerate($destroy = FALSE) { - // Get expirations list - $expirations = $this->userdata(self::EXPIRATION_KEY); - if (empty($expirations)) - { - // Nothing to do - return; - } - - // Wrap single name as array - if (is_string($newdata)) - { - $newdata = array($newdata => ''); - } + session_regenerate_id($destroy); + } - // Prepend each item name and unset - if (count($newdata) > 0) - { - foreach (array_keys($newdata) as $key) - { - $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key; - unset($expirations[$tempdata_key]); - $this->unset_userdata($tempdata_key); - } - } + // ------------------------------------------------------------------------ - // Update expiration list - $this->set_userdata(self::EXPIRATION_KEY, $expirations); + /** + * Get userdata reference + * + * Legacy CI_Session compatibility method + * + * @returns array + */ + public function &get_userdata() + { + return $_SESSION; } // ------------------------------------------------------------------------ /** - * Fetch a specific tempdata item from the session array + * Userdata (fetch) * - * @param string Item key - * @return string + * Legacy CI_Session compatibility method + * + * @param string $key Session data key + * @return mixed Session data value or NULL if not found */ - public function tempdata($key = NULL) + public function userdata($key = NULL) { if (isset($key)) { - return $this->userdata(self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key); + return isset($_SESSION[$key]) ? $_SESSION[$key] : NULL; } - - // Get our tempdata items from userdata - $out = array(); - foreach ($this->userdata() as $key => $val) + elseif (empty($_SESSION)) { - if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_EXP) !== FALSE) - { - $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_EXP, '', $key); - $out[$key] = $val; - } + return array(); } - return $out; - } + $userdata = array(); + $_exclude = array_merge( + array('__ci_f', '__ci_t'), + $this->get_flash_keys(), + $this->get_temp_keys() + ); - // ------------------------------------------------------------------------ - - /** - * Identifies flashdata as 'old' for removal - * when _flashdata_sweep() runs. - * - * @return void - */ - protected function _flashdata_mark() - { - foreach ($this->userdata() as $name => $value) + foreach (array_keys($_SESSION) as $key) { - $parts = explode(self::FLASHDATA_NEW, $name); - if (count($parts) === 2) + if ( ! in_array($key, $_exclude, TRUE)) { - $this->set_userdata(self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1], $value); - $this->unset_userdata($name); + $userdata[$key] = $_SESSION[$key]; } } + + return $userdata; } // ------------------------------------------------------------------------ /** - * Removes all flashdata marked as 'old' + * Set userdata * + * Legacy CI_Session compatibility method + * + * @param mixed $data Session data key or an associative array + * @param mixed $value Value to store * @return void */ - protected function _flashdata_sweep() + public function set_userdata($data, $value = NULL) { - $userdata = $this->userdata(); - foreach (array_keys($userdata) as $key) + if (is_array($data)) { - if (strpos($key, self::FLASHDATA_OLD)) + foreach ($data as $key => &$value) { - $this->unset_userdata($key); + $_SESSION[$key] = $value; } + + return; } + + $_SESSION[$data] = $value; } // ------------------------------------------------------------------------ /** - * Removes all expired tempdata + * Unset userdata + * + * Legacy CI_Session compatibility method * + * @param mixed $data Session data key(s) * @return void */ - protected function _tempdata_sweep() + public function unset_userdata($key) { - // Get expirations list - $expirations = $this->userdata(self::EXPIRATION_KEY); - if (empty($expirations)) - { - // Nothing to do - return; - } - - // Unset expired elements - $now = time(); - $userdata = $this->userdata(); - foreach (array_keys($userdata) as $key) + if (is_array($key)) { - if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now) + foreach ($key as $k) { - unset($expirations[$key]); - $this->unset_userdata($key); + unset($_SESSION[$key]); } + + return; } - // Update expiration list - $this->set_userdata(self::EXPIRATION_KEY, $expirations); + unset($_SESSION[$key]); } -} - -// ------------------------------------------------------------------------ - -/** - * CI_Session_driver Class - * - * Extend this class to make a new CI_Session driver. - * A CI_Session driver basically manages an array of name/value pairs with some sort of storage mechanism. - * To make a new driver, derive from (extend) CI_Session_driver. Overload the initialize method and read or create - * session data. Then implement a save handler to write changed data to storage (sess_save), a destroy handler - * to remove deleted data (sess_destroy), and an access handler to expose the data (get_userdata). - * Put your driver in the libraries/Session/drivers folder anywhere in the loader paths. This includes the - * application directory, the system directory, or any path you add with $CI->load->add_package_path(). - * Your driver must be named CI_Session_, and your filename must be Session_.php, - * preferably also capitalized. (e.g.: CI_Session_foo in libraries/Session/drivers/Session_foo.php) - * Then specify the driver by setting 'sess_driver' in your config file or as a parameter when loading the CI_Session - * object. (e.g.: $config['sess_driver'] = 'foo'; OR $CI->load->driver('session', array('sess_driver' => 'foo')); ) - * Already provided are the Native driver, which manages the native PHP $_SESSION array, and - * the Cookie driver, which manages the data in a browser cookie, with optional extra storage in a database table. - * - * @package CodeIgniter - * @subpackage Libraries - * @category Sessions - * @author EllisLab Dev Team - */ -abstract class CI_Session_driver extends CI_Driver { - - /** - * CI Singleton - * - * @see get_instance() - * @var object - */ - protected $CI; - // ------------------------------------------------------------------------ /** - * Constructor + * All userdata (fetch) * - * Gets the CI singleton, so that individual drivers - * don't have to do it separately. + * Legacy CI_Session compatibility method * - * @return void + * @return array $_SESSION, excluding flash data items */ - public function __construct() + public function all_userdata() { - $this->CI =& get_instance(); + return $this->userdata(); } // ------------------------------------------------------------------------ /** - * Decorate + * Has userdata * - * Decorates the child with the parent driver lib's methods and properties + * Legacy CI_Session compatibility method * - * @param object Parent library object - * @return void + * @param string $key Session data key + * @return bool */ - public function decorate($parent) + public function has_userdata($key) { - // Call base class decorate first - parent::decorate($parent); - - // Call initialize method now that driver has access to $this->_parent - $this->initialize(); + return isset($_SESSION[$key]); } // ------------------------------------------------------------------------ /** - * __call magic method + * Flashdata (fetch) * - * Handles access to the parent driver library's methods + * Legacy CI_Session compatibility method * - * @param string Library method name - * @param array Method arguments (default: none) - * @return mixed + * @param string $key Session data key + * @return mixed Session data value or NULL if not found */ - public function __call($method, $args = array()) + public function flashdata($key = NULL) { - // Make sure the parent library uses this driver - $this->_parent->select_driver(get_class($this)); - return parent::__call($method, $args); + if (isset($key)) + { + return isset($_SESSION['__ci_f'], $_SESSION['__ci_f'][$key], $_SESSION[$key]) + ? $_SESSION[$key] + : NULL; + } + + $flashdata = array(); + + if ( ! empty($_SESSION['__ci_f'])) + { + foreach (array_keys($_SESSION['__ci_f']) as $key) + { + $flashdata[$key] = $_SESSION[$key]; + } + } + + return $flashdata; } // ------------------------------------------------------------------------ /** - * Initialize driver + * Set flashdata * + * Legacy CI_Session compatibiliy method + * + * @param mixed $data Session data key or an associative array + * @param mixed $value Value to store * @return void */ - protected function initialize() + public function set_flashdata($data, $value = NULL) { - // Overload this method to implement initialization + $this->set_userdata($data, $value); + $this->mark_as_flash($data); } // ------------------------------------------------------------------------ /** - * Save the session data + * Keep flashdata * - * Data in the array has changed - perform any storage synchronization - * necessary. The child class MUST implement this abstract method! + * Legacy CI_Session compatibility method * + * @param mixed $key Session data key(s) * @return void */ - abstract public function sess_save(); + public function keep_flashdata($key) + { + $this->mark_as_flash($key); + } // ------------------------------------------------------------------------ /** - * Destroy the current session + * Temp data (fetch) * - * Clean up storage for this session - it has been terminated. - * The child class MUST implement this abstract method! + * Legacy CI_Session compatibility method * - * @return void + * @param string $key Session data key + * @return mixed Session data value or NULL if not found */ - abstract public function sess_destroy(); + public function tempdata($key = NULL) + { + if (isset($key)) + { + return isset($_SESSION['__ci_t'], $_SESSION['__ci_t'][$key], $_SESSION[$key]) + ? $_SESSION[$key] + : NULL; + } + + $tempdata = array(); + + if ( ! empty($_SESSION['__ci_t'])) + { + foreach (array_keys($_SESSION['__ci_t']) as $key) + { + $tempdata[$key] = $_SESSION[$key]; + } + } + + return $tempdata; + } // ------------------------------------------------------------------------ /** - * Regenerate the current session + * Set tempdata * - * Regenerate the session ID. - * The child class MUST implement this abstract method! + * Legacy CI_Session compatibility method * - * @param bool Destroy session data flag (default: false) + * @param mixed $data Session data key or an associative array of items + * @param mixed $value Value to store + * @param int $ttl Time-to-live in seconds * @return void */ - abstract public function sess_regenerate($destroy = FALSE); + public function set_tempdata($data, $value = NULL, $ttl = 300) + { + $this->set_userdata($data, $value); + $this->mark_as_temp($data, $ttl); + } // ------------------------------------------------------------------------ /** - * Get a reference to user data array + * Unset tempdata * - * Give array access to the main CI_Session object. - * The child class MUST implement this abstract method! + * Legacy CI_Session compatibility method * - * @return array Reference to userdata + * @param mixed $data Session data key(s) + * @return void */ - abstract public function &get_userdata(); + public function unset_tempdata($key) + { + $this->unmark_temp($key); + } } diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php new file mode 100644 index 000000000..7473ff8ec --- /dev/null +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -0,0 +1,51 @@ + &$value) + { + $key = (strncmp($key, 'sess_', 5) === 0) + ? substr($key, 4) + : '_'.$key; + + property_exists($this, $key) && $this->$key = $value; + } + + isset($this->_expiration) OR $this->_expiration = (int) config_item('sess_expiration'); + isset($this->_cookie_name) OR $this->_cookie_name = config_item('sess_cookie_name'); + isset($this->_cookie_domain) OR $this->_cookie_domain = config_item('cookie_domain'); + isset($this->_cookie_path) OR $this->_cookie_path = config_item('cookie_path'); + isset($this->_cookie_secure) OR $this->_cookie_secure = config_item('cookie_secure'); + isset($this->_cookie_httponly) OR $this->_cookie_httponly = config_item('cookie_httponly'); + isset($this->_match_ip) OR $this->_match_ip = config_item('sess_match_ip'); + + // Pass our configuration to php.ini, when appropriate + ini_set('session.name', $this->_cookie_name); + isset($this->_cookie_domain) && ini_set('session.cookie_domain', $this->_cookie_domain); + isset($this->_cookie_path) && ini_set('session.cookie_path', $this->_cookie_path); + isset($this->_cookie_secure) && ini_set('session.cookie_secure', $this->_cookie_secure); + isset($this->_cookie_httponly) && ini_set('session.cookie_httponly', $this->_cookie_httponly); + + if ($this->_expiration) + { + ini_set('session.gc_maxlifetime', $this->_expiration); + } + + // Security is king + ini_set('session.use_trans_id', 0); + ini_set('session.use_strict_mode', 1); + ini_set('session.use_cookies', 1); + ini_set('session.use_only_cookies', 1); + ini_set('session.hash_function', 1); + ini_set('session.hash_bits_per_character', 4); + + // Work-around for PHP bug #66827 (https://bugs.php.net/bug.php?id=66827) + // + // The session ID sanitizer doesn't check for the value type and blindly does + // an implicit cast to string, which triggers an 'Array to string' E_NOTICE. + if (isset($_COOKIE[$this->_cookie_name]) && ! is_string($_COOKIE[$this->_cookie_name])) + { + unset($_COOKIE[$this->_cookie_name]); + } + +/* + Need to test if this is necessary for a custom driver or if it's only + relevant to PHP's own files handler. + + https://bugs.php.net/bug.php?id=65475 + do this after session is started: + if (is_php('5.5.2') && ! is_php('5.5.4')) + { + $session_id = session_id(); + if ($_COOKIE[$this->_cookie_name] !== $session_id && file_exists(teh file)) + { + unlink(); + } + + setcookie( + $this->_cookie_name, + $session_id, + $this->_expiration + ? time() + $this->_expiration + : 0, + $this->_cookie_path, + $this->_cookie_domain, + $this->_cookie_secure, + $this->_cookie_httponly + ); + } +*/ + } + + // ------------------------------------------------------------------------ + + protected function _cookie_destroy() + { + return setcookie( + $this->_cookie_name, + NULL, + 1, + $this->_cookie_path, + $this->_cookie_domain, + $this->_cookie_secure, + $this->_cookie_httponly + ); + } + +} + +/* End of file Session_driver.php */ +/* Location: ./system/libraries/Session/Session_driver.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php deleted file mode 100644 index 566c40bd8..000000000 --- a/system/libraries/Session/drivers/Session_cookie.php +++ /dev/null @@ -1,805 +0,0 @@ - NULL, - 'ip_address' => NULL, - 'user_agent' => NULL, - 'last_activity' => NULL - ); - - /** - * Data needs DB update flag - * - * @var bool - */ - protected $data_dirty = FALSE; - - /** - * Standardize newlines flag - * - * @var bool - */ - protected $_standardize_newlines; - - // ------------------------------------------------------------------------ - - /** - * Initialize session driver object - * - * @return void - */ - protected function initialize() - { - // Set all the session preferences, which can either be set - // manually via the $params array or via the config file - $prefs = array( - 'sess_encrypt_cookie', - 'sess_use_database', - 'sess_table_name', - 'sess_expiration', - 'sess_expire_on_close', - 'sess_match_ip', - 'sess_match_useragent', - 'sess_cookie_name', - 'cookie_path', - 'cookie_domain', - 'cookie_secure', - 'cookie_httponly', - 'sess_time_to_update', - 'time_reference', - 'cookie_prefix', - 'encryption_key', - ); - - $this->_standardize_newlines = (bool) config_item('standardize_newlines'); - - foreach ($prefs as $key) - { - $this->$key = isset($this->_parent->params[$key]) - ? $this->_parent->params[$key] - : $this->CI->config->item($key); - } - - if (empty($this->encryption_key)) - { - show_error('In order to use the Cookie Session driver you are required to set an encryption key in your config file.'); - } - - // Do we need encryption? If so, load the encryption class - if ($this->sess_encrypt_cookie === TRUE) - { - $this->CI->load->library('encryption'); - } - - // Check for database - if ($this->sess_use_database === TRUE && $this->sess_table_name !== '') - { - // Load database driver - $this->CI->load->database(); - - // Register shutdown function - register_shutdown_function(array($this, '_update_db')); - } - - // 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 - // set to zero we'll set the expiration two years from now. - if ($this->sess_expiration === 0) - { - $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. - if ( ! $this->_sess_read()) - { - $this->_sess_create(); - } - else - { - $this->_sess_update(); - } - - // Delete expired sessions if necessary - $this->_sess_gc(); - } - - // ------------------------------------------------------------------------ - - /** - * Write the session data - * - * @return void - */ - public function sess_save() - { - // Check for database - if ($this->sess_use_database === TRUE) - { - // Mark custom data as dirty so we know to update the DB - $this->data_dirty = TRUE; - } - - // Write the cookie - $this->_set_cookie(); - } - - // ------------------------------------------------------------------------ - - /** - * Destroy the current session - * - * @return void - */ - public function sess_destroy() - { - // Kill the session DB row - if ($this->sess_use_database === TRUE && isset($this->userdata['session_id'])) - { - $this->CI->db->delete($this->sess_table_name, array('session_id' => $this->userdata['session_id'])); - $this->data_dirty = FALSE; - } - - // Kill the cookie - $this->_setcookie($this->sess_cookie_name, '', ($this->now - 31500000), - $this->cookie_path, $this->cookie_domain, 0); - - // Kill session data - $this->userdata = array(); - } - - // ------------------------------------------------------------------------ - - /** - * Regenerate the current session - * - * Regenerate the session id - * - * @param bool Destroy session data flag (default: false) - * @return void - */ - public function sess_regenerate($destroy = FALSE) - { - // Check destroy flag - if ($destroy) - { - // Destroy old session and create new one - $this->sess_destroy(); - $this->_sess_create(); - } - else - { - // Just force an update to recreate the id - $this->_sess_update(TRUE); - } - } - - // ------------------------------------------------------------------------ - - /** - * Get a reference to user data array - * - * @return array Reference to userdata - */ - public function &get_userdata() - { - return $this->userdata; - } - - // ------------------------------------------------------------------------ - - /** - * Fetch the current session data if it exists - * - * @return bool - */ - protected function _sess_read() - { - // Fetch the cookie - $session = $this->CI->input->cookie($this->sess_cookie_name); - - // No cookie? Goodbye cruel world!... - if ($session === NULL) - { - log_message('debug', 'A session cookie was not found.'); - return FALSE; - } - - if ($this->sess_encrypt_cookie === TRUE) - { - $session = $this->CI->encryption->decrypt($session); - if ($session === FALSE) - { - log_message('error', 'Session: Unable to decrypt the session cookie, possibly due to a HMAC mismatch.'); - return FALSE; - } - } - else - { - if (($len = strlen($session) - 40) <= 0) - { - log_message('error', 'Session: The session cookie was not signed.'); - return FALSE; - } - - // Check cookie authentication - $hmac = substr($session, $len); - $session = substr($session, 0, $len); - - // Time-attack-safe comparison - $hmac_check = hash_hmac('sha1', $session, $this->encryption_key); - $diff = 0; - for ($i = 0; $i < 40; $i++) - { - $diff |= ord($hmac[$i]) ^ ord($hmac_check[$i]); - } - - if ($diff !== 0) - { - log_message('error', 'Session: HMAC mismatch. The session cookie data did not match what was expected.'); - $this->sess_destroy(); - return FALSE; - } - } - - // Unserialize the session array - $session = @unserialize($session); - - // Is the session data we unserialized an array with the correct format? - if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity'])) - { - log_message('debug', 'Session: Wrong cookie data format'); - $this->sess_destroy(); - return FALSE; - } - - // Is the session current? - if (($session['last_activity'] + $this->sess_expiration) < $this->now OR $session['last_activity'] > $this->now) - { - log_message('debug', 'Session: Expired'); - $this->sess_destroy(); - return FALSE; - } - - // Does the IP match? - if ($this->sess_match_ip === TRUE && $session['ip_address'] !== $this->CI->input->ip_address()) - { - log_message('debug', 'Session: IP address mismatch'); - $this->sess_destroy(); - return FALSE; - } - - // Does the User Agent Match? - if ($this->sess_match_useragent === TRUE && - trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120))) - { - log_message('debug', 'Session: User Agent string mismatch'); - $this->sess_destroy(); - return FALSE; - } - - // Is there a corresponding session in the DB? - if ($this->sess_use_database === TRUE) - { - $this->CI->db->where('session_id', $session['session_id']); - - if ($this->sess_match_ip === TRUE) - { - $this->CI->db->where('ip_address', $session['ip_address']); - } - - if ($this->sess_match_useragent === TRUE) - { - $this->CI->db->where('user_agent', $session['user_agent']); - } - - // Is caching in effect? Turn it off - $db_cache = $this->CI->db->cache_on; - $this->CI->db->cache_off(); - - $query = $this->CI->db->limit(1)->get($this->sess_table_name); - - // Was caching in effect? - if ($db_cache) - { - // Turn it back on - $this->CI->db->cache_on(); - } - - // No result? Kill it! - if (empty($query) OR $query->num_rows() === 0) - { - log_message('debug', 'Session: No match found in our database'); - $this->sess_destroy(); - return FALSE; - } - - // Is there custom data? If so, add it to the main session array - $row = $query->row(); - if ( ! empty($row->user_data)) - { - $custom_data = unserialize(trim($row->user_data)); - - if (is_array($custom_data)) - { - $session = $session + $custom_data; - } - } - } - - // Session is valid! - $this->userdata = $session; - return TRUE; - } - - // ------------------------------------------------------------------------ - - /** - * Create a new session - * - * @return void - */ - protected function _sess_create() - { - // Initialize userdata - $this->userdata = array( - 'session_id' => $this->_make_sess_id(), - 'ip_address' => $this->CI->input->ip_address(), - 'user_agent' => trim(substr($this->CI->input->user_agent(), 0, 120)), - 'last_activity' => $this->now, - ); - - log_message('debug', 'Session: Creating new session ('.$this->userdata['session_id'].')'); - - // Check for database - if ($this->sess_use_database === TRUE) - { - // Add empty user_data field and save the data to the DB - $this->CI->db->set('user_data', '')->insert($this->sess_table_name, $this->userdata); - } - - // Write the cookie - $this->_set_cookie(); - } - - // ------------------------------------------------------------------------ - - /** - * Update an existing session - * - * @param bool Force update flag (default: false) - * @return void - */ - protected function _sess_update($force = FALSE) - { - // We only update the session every five minutes by default (unless forced) - if ( ! $force && ($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now) - { - return; - } - - // Update last activity to now - $this->userdata['last_activity'] = $this->now; - - // Save the old session id so we know which DB record to update - $old_sessid = $this->userdata['session_id']; - - // Changing the session ID during an AJAX call causes problems - if ( ! $this->CI->input->is_ajax_request()) - { - // Get new id - $this->userdata['session_id'] = $this->_make_sess_id(); - - log_message('debug', 'Session: Regenerate ID'); - } - - // Check for database - if ($this->sess_use_database === TRUE) - { - $this->CI->db->where('session_id', $old_sessid); - - if ($this->sess_match_ip === TRUE) - { - $this->CI->db->where('ip_address', $this->CI->input->ip_address()); - } - - if ($this->sess_match_useragent === TRUE) - { - $this->CI->db->where('user_agent', trim(substr($this->CI->input->user_agent(), 0, 120))); - } - - // Update the session ID and last_activity field in the DB - $this->CI->db->update($this->sess_table_name, - array( - 'last_activity' => $this->now, - 'session_id' => $this->userdata['session_id'] - ) - ); - } - - // Write the cookie - $this->_set_cookie(); - } - - // ------------------------------------------------------------------------ - - /** - * Update database with current data - * - * This gets called from the shutdown function and also - * registered with PHP to run at the end of the request - * so it's guaranteed to update even when a fatal error - * occurs. The first call makes the update and clears the - * dirty flag so it won't happen twice. - * - * @return void - */ - public function _update_db() - { - // Check for database and dirty flag and unsaved - if ($this->sess_use_database === TRUE && $this->data_dirty === TRUE) - { - // Set up activity and data fields to be set - // If we don't find custom data, user_data will remain an empty string - $set = array( - 'last_activity' => $this->userdata['last_activity'], - 'user_data' => '' - ); - - // Get the custom userdata, leaving out the defaults - // (which get stored in the cookie) - $userdata = array_diff_key($this->userdata, $this->defaults); - - // Did we find any custom data? - if ( ! empty($userdata)) - { - // Serialize the custom data array so we can store it - $set['user_data'] = serialize($userdata); - } - - // Reset query builder values. - $this->CI->db->reset_query(); - - // Run the update query - // Any time we change the session id, it gets updated immediately, - // so our where clause below is always safe - $this->CI->db->where('session_id', $this->userdata['session_id']); - - if ($this->sess_match_ip === TRUE) - { - $this->CI->db->where('ip_address', $this->CI->input->ip_address()); - } - - if ($this->sess_match_useragent === TRUE) - { - $this->CI->db->where('user_agent', trim(substr($this->CI->input->user_agent(), 0, 120))); - } - - $this->CI->db->update($this->sess_table_name, $set); - - // Clear dirty flag to prevent double updates - $this->data_dirty = FALSE; - - log_message('debug', 'CI_Session Data Saved To DB'); - } - } - - // ------------------------------------------------------------------------ - - /** - * Generate a new session id - * - * @return string Hashed session id - */ - protected function _make_sess_id() - { - $new_sessid = ''; - do - { - $new_sessid .= mt_rand(); - } - 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 and return - return md5(uniqid($new_sessid, TRUE)); - } - - // ------------------------------------------------------------------------ - - /** - * Get the "now" time - * - * @return int Time - */ - protected function _get_time() - { - if ($this->time_reference === 'local' OR $this->time_reference === date_default_timezone_get()) - { - return time(); - } - - $datetime = new DateTime('now', new DateTimeZone($this->time_reference)); - sscanf($datetime->format('j-n-Y G:i:s'), '%d-%d-%d %d:%d:%d', $day, $month, $year, $hour, $minute, $second); - - return mktime($hour, $minute, $second, $month, $day, $year); - } - - // ------------------------------------------------------------------------ - - /** - * Write the session cookie - * - * @return void - */ - protected function _set_cookie() - { - // Get userdata (only defaults if database) - $cookie_data = ($this->sess_use_database === TRUE) - ? array_intersect_key($this->userdata, $this->defaults) - : $this->userdata; - - // The Input class will do this and since we use HMAC verification, - // unless we standardize here as well, the hash won't match. - if ($this->_standardize_newlines) - { - foreach (array_keys($this->userdata) as $key) - { - $this->userdata[$key] = preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $this->userdata[$key]); - } - } - - // Serialize the userdata for the cookie - $cookie_data = serialize($cookie_data); - - if ($this->sess_encrypt_cookie === TRUE) - { - $cookie_data = $this->CI->encryption->encrypt($cookie_data); - } - else - { - // Require message authentication - $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key); - } - - $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time(); - - // Set the cookie - $this->_setcookie($this->sess_cookie_name, $cookie_data, $expire, $this->cookie_path, $this->cookie_domain, - $this->cookie_secure, $this->cookie_httponly); - } - - // ------------------------------------------------------------------------ - - /** - * Set a cookie with the system - * - * This abstraction of the setcookie call allows overriding for unit testing - * - * @param string Cookie name - * @param string Cookie value - * @param int Expiration time - * @param string Cookie path - * @param string Cookie domain - * @param bool Secure connection flag - * @param bool HTTP protocol only flag - * @return void - */ - protected function _setcookie($name, $value = '', $expire = 0, $path = '', $domain = '', $secure = FALSE, $httponly = FALSE) - { - setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); - } - - // ------------------------------------------------------------------------ - - /** - * Garbage collection - * - * This deletes expired session rows from database - * if the probability percentage is met - * - * @return void - */ - protected function _sess_gc() - { - if ($this->sess_use_database !== TRUE) - { - return; - } - - $probability = ini_get('session.gc_probability'); - $divisor = ini_get('session.gc_divisor'); - - if (mt_rand(1, $divisor) <= $probability) - { - $expire = $this->now - $this->sess_expiration; - $this->CI->db->delete($this->sess_table_name, 'last_activity < '.$expire); - - log_message('debug', 'Session garbage collection performed.'); - } - } - -} - -/* End of file Session_cookie.php */ -/* Location: ./system/libraries/Session/drivers/Session_cookie.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php new file mode 100644 index 000000000..24847456c --- /dev/null +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -0,0 +1,317 @@ +db) OR $CI->load->database(); + $this->_db =& $CI->db; + + if ( ! $this->_db instanceof CI_DB_query_builder) + { + throw new Exception('Query Builder not enabled for the configured database. Aborting.'); + } + elseif ($this->_db->pconnect) + { + throw new Exception('Configured database connection is persistent. Aborting.'); + } + + $db_driver = $this->_db->dbdriver.(empty($this->_db->subdriver) ? '' : '_'.$this->_db->subdriver); + if (strpos($db_driver, 'mysql') !== FALSE) + { + $this->_lock_type = 'mysql'; + } + elseif (in_array($db_driver, array('postgre', 'pdo_pgsql'), TRUE)) + { + $this->_lock_type = 'postgre'; + } + elseif (extension_loaded('sysvsem')) + { + $this->_lock_type = 'semaphore'; + } + + isset($this->_table) OR $this->_table = config_item('sess_table_name'); + } + + // ------------------------------------------------------------------------ + + public function open($save_path, $name) + { + return empty($this->_db->conn_id) + ? ( ! $this->_db->autoinit && $this->_db->db_connect()) + : TRUE; + } + + // ------------------------------------------------------------------------ + + public function read($session_id) + { + $this->_session_id = $session_id; + if (($this->_lock = $this->_get_lock()) !== FALSE) + { + $this->_db + ->select('data') + ->from($this->_table) + ->where('id', $session_id); + + if ($this->_match_ip) + { + $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); + } + + if (($result = $this->_db->get()->row()) === NULL) + { + $this->_fingerprint = md5(''); + return ''; + } + + $this->_fingerprint = md5(rtrim($result->data)); + $this->_row_exists = TRUE; + return $result->data; + } + + $this->_fingerprint = md5(''); + return ''; + } + + public function write($session_id, $session_data) + { + if ($this->_lock === FALSE) + { + return FALSE; + } + + if ($this->_row_exists === FALSE) + { + if ($this->_db->insert($this->_table, array('id' => $session_id, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'timestamp' => time(), 'data' => $session_data))) + { + $this->_fingerprint = md5($session_data); + return $this->_row_exists = TRUE; + } + + return FALSE; + } + + $this->_db->where('id', $session_id); + if ($this->_match_ip) + { + $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); + } + + $update_data = ($this->_fingerprint === md5($session_data)) + ? array('timestamp' => time()) + : array('timestamp' => time(), 'data' => $session_data); + + if ($this->_db->update($this->_table, $update_data)) + { + $this->_fingerprint = md5($session_data); + return TRUE; + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + public function close() + { + return ($this->_lock) + ? $this->_release_lock() + : TRUE; + } + + // ------------------------------------------------------------------------ + + public function destroy($session_id) + { + if ($this->_lock) + { + $this->_db->where('id', $session_id); + if ($this->_match_ip) + { + $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); + } + + return $this->_db->delete($this->_table) + ? ($this->close() && $this->_cookie_destroy()) + : FALSE; + } + + return ($this->close() && $this->_cookie_destroy()); + } + + // ------------------------------------------------------------------------ + + public function gc($maxlifetime) + { + return $this->_db->delete($this->_table, 'timestamp < '.(time() - $maxlifetime)); + } + + // ------------------------------------------------------------------------ + + protected function _get_lock() + { + $arg = $this->_session_id + .($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''); + + if ($this->_lock_driver === 'mysql') + { + return (bool) $this->_db + ->query("SELECT GET_LOCK('".$session_id."', 10) AS ci_session_lock") + ->row() + ->ci_session_lock; + } + elseif ($this->_lock_driver === 'postgre') + { + return (bool) $this->_db->simple_query('SELECT pg_advisory_lock('.$arg.')'); + } + elseif ($this->_lock_driver === 'semaphore') + { + if (($this->_sem = sem_get($arg, 1, 0644)) === FALSE) + { + return FALSE; + } + + if ( ! sem_acquire($this->_sem)) + { + sem_remove($this->_sem); + return FALSE; + } + + return TRUE; + } + + return TRUE; + } + + // ------------------------------------------------------------------------ + + protected function _release_lock() + { + if ($this->_lock_driver === 'mysql') + { + $arg = $this->_session_id + .($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''); + + return (bool) $this->_db + ->query("SELECT RELEASE_LOCK('".$arg."') AS ci_session_lock") + ->row() + ->ci_session_lock; + } + elseif ($this->_lock_driver === 'postgre') + { + $arg = "hashtext('".$this->_session_id."')" + .($this->_match_ip ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : ''); + + return (bool) $this->_db->simple_query('SELECT pg_advisory_unlock('.$arg.')'); + } + elseif ($this->_lock_driver === 'semaphore') + { + sem_release($this->_sem); + sem_remove($this->_sem); + } + + return TRUE; + } + +} + +/* End of file Session_database_driver.php */ +/* Location: ./system/libraries/Session/drivers/Session_database_driver.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php new file mode 100644 index 000000000..4acbcf6c5 --- /dev/null +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -0,0 +1,276 @@ +_save_path)) + { + $this->_save_path = rtrim($this->_save_path, '/\\'); + ini_set('session.save_path', $this->_save_path); + } + else + { + $this->_save_path = rtrim(ini_get('session.save_path'), '/\\'); + } + } + + // ------------------------------------------------------------------------ + + public function open($save_path, $name) + { + if ( ! is_dir($save_path) && ! mkdir($save_path, 0700, TRUE)) + { + log_message('error', "Session: Configured save path '".$this->_save_path."' is not a directory, doesn't exist or cannot be created."); + return FALSE; + } + + $this->_save_path = $save_path; + $this->_file_path = $this->_save_path.DIRECTORY_SEPARATOR + .$name // we'll use the session cookie name as a prefix to avoid collisions + .($this->_match_ip ? md5($_SERVER['REMOTE_ADDR']) : ''); + + return TRUE; + } + + // ------------------------------------------------------------------------ + + public function read($session_id) + { + // This might seem weird, but PHP 5.6 introduces session_reset(), + // which re-reads session data + if ($this->_file_handle === NULL) + { + $this->_file_path .= $session_id; + + // Just using fopen() with 'c+b' mode would be perfect, but it is only + // available since PHP 5.2.6 and we have to set permissions for new files, + // so we'd have to hack around this ... + if (($this->_file_new = ! file_exists($this->_file_path)) === TRUE) + { + if (($this->_file_handle = fopen($this->_file_path, 'w+b')) === FALSE) + { + log_message('error', "Session: File '".$this->_file_path."' doesn't exist and cannot be created."); + return FALSE; + } + } + elseif (($this->_file_handle = fopen($this->_file_path, 'r+b')) === FALSE) + { + log_message('error', "Session: Unable to open file '".$this->_file_path."'."); + return FALSE; + } + + if (flock($this->_file_handle, LOCK_EX) === FALSE) + { + log_message('error', "Session: Unable to obtain lock for file '".$this->_file_path."'."); + fclose($this->_file_handle); + $this->_file_handle = NULL; + return FALSE; + } + + if ($this->_file_new) + { + chmod($this->_file_path, 0600); + $this->_fingerprint = md5(''); + return ''; + } + } + else + { + rewind($this->_file_handle); + } + + $session_data = ''; + for ($read = 0, $length = filesize($this->_file_path); $read < $length; $read += strlen($buffer)) + { + if (($buffer = fread($this->_file_handle, $length - $read)) === FALSE) + { + break; + } + + $session_data .= $buffer; + } + + $this->_fingerprint = md5($session_data); + return $session_data; + } + + public function write($session_id, $session_data) + { + if ( ! is_resource($this->_file_handle)) + { + return FALSE; + } + elseif ($this->_fingerprint === md5($session_data)) + { + return ($this->_file_new) + ? TRUE + : touch($this->_file_path); + } + + if ( ! $this->_file_new) + { + ftruncate($this->_file_handle, 0); + rewind($this->_file_handle); + } + + for ($written = 0, $length = strlen($session_data); $written < $length; $written += $result) + { + if (($result = fwrite($this->_file_handle, substr($session_data, $written))) === FALSE) + { + break; + } + } + + if ( ! is_int($result)) + { + $this->_fingerprint = md5(substr($session_data, 0, $written)); + log_message('error', 'Session: Unable to write data.'); + return FALSE; + } + + $this->_fingerprint = md5($session_data); + return TRUE; + } + + // ------------------------------------------------------------------------ + + public function close() + { + if (is_resource($this->_file_handle)) + { + flock($this->_file_handle, LOCK_UN); + fclose($this->_file_handle); + + $this->_file_handle = $this->_file_new = NULL; + return TRUE; + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + public function destroy($session_id) + { + if ($this->close()) + { + return unlink($this->_file_path) && $this->_cookie_destroy(); + } + elseif ($this->_file_path !== NULL) + { + clearstatcache(); + return file_exists($this->_file_path) + ? (unlink($this->_file_path) && $this->_cookie_destroy()) + : TRUE; + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + public function gc($maxlifetime) + { + if ( ! is_dir($this->_save_path) OR ($files = scandir($this->_save_path)) === FALSE) + { + log_message('debug', "Session: Garbage collector couldn't list files under directory '".$this->_save_path."'."); + return FALSE; + } + + $ts = time() - $maxlifetime; + + foreach ($files as $file) + { + // If the filename doesn't match this pattern, it's either not a session file or is not ours + if ( ! preg_match('/(?:[0-9a-f]{32})?[0-9a-f]{40}$/i', $file) + OR ! is_file($this->_save_path.DIRECTORY_SEPARATOR.$file) + OR ($mtime = filemtime($file)) === FALSE + OR $mtime > $ts) + { + continue; + } + + unlink($this->_save_path.DIRECTORY_SEPARATOR.$file); + } + + return TRUE; + } + +} + +/* End of file Session_files_driver.php */ +/* Location: ./system/libraries/Session/drivers/Session_files_driver.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php deleted file mode 100644 index 4104652b8..000000000 --- a/system/libraries/Session/drivers/Session_native.php +++ /dev/null @@ -1,246 +0,0 @@ -_parent->params[$key]) - ? $this->_parent->params[$key] - : $this->CI->config->item($key); - } - - // Set session name, if specified - if ($config['sess_cookie_name']) - { - // Differentiate name from cookie driver with '_id' suffix - $name = $config['sess_cookie_name'].'_id'; - if ($config['cookie_prefix']) - { - // Prepend cookie prefix - $name = $config['cookie_prefix'].$name; - } - session_name($name); - } - - // Set expiration, path, and domain - $expire = 7200; - $path = '/'; - $domain = ''; - $secure = (bool) $config['cookie_secure']; - $http_only = (bool) $config['cookie_httponly']; - - if ($config['sess_expiration'] !== FALSE) - { - // Default to 2 years if expiration is "0" - $expire = ($config['sess_expiration'] == 0) ? (60*60*24*365*2) : $config['sess_expiration']; - } - - if ($config['cookie_path']) - { - // Use specified path - $path = $config['cookie_path']; - } - - if ($config['cookie_domain']) - { - // Use specified domain - $domain = $config['cookie_domain']; - } - - session_set_cookie_params($config['sess_expire_on_close'] ? 0 : $expire, $path, $domain, $secure, $http_only); - - // Start session - session_start(); - - // Check session expiration, ip, and agent - $now = time(); - $destroy = FALSE; - if (isset($_SESSION['last_activity']) && (($_SESSION['last_activity'] + $expire) < $now OR $_SESSION['last_activity'] > $now)) - { - // Expired - destroy - log_message('debug', 'Session: Expired'); - $destroy = TRUE; - } - elseif ($config['sess_match_ip'] === TRUE && isset($_SESSION['ip_address']) - && $_SESSION['ip_address'] !== $this->CI->input->ip_address()) - { - // IP doesn't match - destroy - log_message('debug', 'Session: IP address mismatch'); - $destroy = TRUE; - } - elseif ($config['sess_match_useragent'] === TRUE && isset($_SESSION['user_agent']) - && $_SESSION['user_agent'] !== trim(substr($this->CI->input->user_agent(), 0, 50))) - { - // Agent doesn't match - destroy - log_message('debug', 'Session: User Agent string mismatch'); - $destroy = TRUE; - } - - // Destroy expired or invalid session - if ($destroy) - { - // Clear old session and start new - $this->sess_destroy(); - session_start(); - } - - // Check for update time - if ($config['sess_time_to_update'] && isset($_SESSION['last_activity']) - && ($_SESSION['last_activity'] + $config['sess_time_to_update']) < $now) - { - // Changing the session ID amidst a series of AJAX calls causes problems - if ( ! $this->CI->input->is_ajax_request()) - { - // Regenerate ID, but don't destroy session - log_message('debug', 'Session: Regenerate ID'); - $this->sess_regenerate(FALSE); - } - } - - // Set activity time - $_SESSION['last_activity'] = $now; - - // Set matching values as required - if ($config['sess_match_ip'] === TRUE && ! isset($_SESSION['ip_address'])) - { - // Store user IP address - $_SESSION['ip_address'] = $this->CI->input->ip_address(); - } - - if ($config['sess_match_useragent'] === TRUE && ! isset($_SESSION['user_agent'])) - { - // Store user agent string - $_SESSION['user_agent'] = trim(substr($this->CI->input->user_agent(), 0, 50)); - } - - // Make session ID available - $_SESSION['session_id'] = session_id(); - } - - // ------------------------------------------------------------------------ - - /** - * Save the session data - * - * @return void - */ - public function sess_save() - { - // Nothing to do - changes to $_SESSION are automatically saved - } - - // ------------------------------------------------------------------------ - - /** - * Destroy the current session - * - * @return void - */ - public function sess_destroy() - { - // Cleanup session - $_SESSION = array(); - $name = session_name(); - if (isset($_COOKIE[$name])) - { - // Clear session cookie - $params = session_get_cookie_params(); - setcookie($name, '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']); - unset($_COOKIE[$name]); - } - session_destroy(); - } - - // ------------------------------------------------------------------------ - - /** - * Regenerate the current session - * - * Regenerate the session id - * - * @param bool Destroy session data flag (default: FALSE) - * @return void - */ - public function sess_regenerate($destroy = FALSE) - { - // Just regenerate id, passing destroy flag - session_regenerate_id($destroy); - $_SESSION['session_id'] = session_id(); - } - - // ------------------------------------------------------------------------ - - /** - * Get a reference to user data array - * - * @return array Reference to userdata - */ - public function &get_userdata() - { - // Just return reference to $_SESSION - return $_SESSION; - } - -} - -/* End of file Session_native.php */ -/* Location: ./system/libraries/Session/drivers/Session_native.php */ \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 34b1ef5c13882c4a7827be71e82503ee47d4c271 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 31 May 2014 21:23:41 +0300 Subject: [ci skip] A quick and dirty fix for allowing 'sess_driver' configuration --- system/libraries/Session/Session.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 0d444e8ca..518dc28b0 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -49,7 +49,6 @@ class CI_Session { */ public function __construct(array $params = array()) { - // No sessions under CLI if (is_cli()) { @@ -66,6 +65,11 @@ class CI_Session { $this->_driver = $params['driver']; unset($params['driver']); } + // Note: Make the autoloader pass sess_* params to this constructor + elseif (empty($params) && $driver = config_item('sess_driver')) + { + $this->_driver = $driver; + } if (($class = $this->_ci_load_classes($this->_driver)) === FALSE) { -- cgit v1.2.3-24-g4f1b From e1b9665567bbfc28bb13e5e41093901a8da99a0d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 2 Jun 2014 10:09:56 +0300 Subject: Fix Session_database_driver locking Ref: #3073 --- .../Session/drivers/Session_database_driver.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 24847456c..2bdc4d0d5 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -116,15 +116,15 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $db_driver = $this->_db->dbdriver.(empty($this->_db->subdriver) ? '' : '_'.$this->_db->subdriver); if (strpos($db_driver, 'mysql') !== FALSE) { - $this->_lock_type = 'mysql'; + $this->_lock_driver = 'mysql'; } elseif (in_array($db_driver, array('postgre', 'pdo_pgsql'), TRUE)) { - $this->_lock_type = 'postgre'; + $this->_lock_driver = 'postgre'; } elseif (extension_loaded('sysvsem')) { - $this->_lock_type = 'semaphore'; + $this->_lock_driver = 'semaphore'; } isset($this->_table) OR $this->_table = config_item('sess_table_name'); @@ -248,18 +248,20 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan protected function _get_lock() { - $arg = $this->_session_id - .($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''); - if ($this->_lock_driver === 'mysql') { + $arg = $this->_session_id + .($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''); return (bool) $this->_db - ->query("SELECT GET_LOCK('".$session_id."', 10) AS ci_session_lock") + ->query("SELECT GET_LOCK('".$arg."', 10) AS ci_session_lock") ->row() ->ci_session_lock; } elseif ($this->_lock_driver === 'postgre') { + $arg = "hashtext('".$this->_session_id."')" + .($this->_match_ip ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : ''); + return (bool) $this->_db->simple_query('SELECT pg_advisory_lock('.$arg.')'); } elseif ($this->_lock_driver === 'semaphore') -- cgit v1.2.3-24-g4f1b From ac4f47283a6a8ce575f59c15c1a08ad3bc2efdd9 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 2 Jun 2014 11:16:32 +0300 Subject: #3073: BC workarounds for sess_use_database, sess_expire_on_close --- system/libraries/Session/Session.php | 5 +++++ system/libraries/Session/Session_driver.php | 6 ++++++ 2 files changed, 11 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 518dc28b0..bdcde1e76 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -70,6 +70,11 @@ class CI_Session { { $this->_driver = $driver; } + // Note: BC workaround + elseif (config_item('sess_use_database')) + { + $this->_driver = 'database'; + } if (($class = $this->_ci_load_classes($this->_driver)) === FALSE) { diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index c46ca3a34..cc35b66d1 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -133,6 +133,12 @@ abstract class CI_Session_driver implements SessionHandlerInterface { if ($this->_expiration) { ini_set('session.gc_maxlifetime', $this->_expiration); + ini_set('session.cookie_lifetime', $this->_expiration); + } + // BC workaround for setting cookie lifetime + elseif (config_item('sess_expire_on_close')) + { + ini_set('session.cookie_lifetime', 0); } // Security is king -- cgit v1.2.3-24-g4f1b From 5995e08ed0d5cf89747911443be06a26e410154f Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 3 Jun 2014 15:33:51 +0300 Subject: #3073: Fix an undefined variable error --- .../Session/drivers/Session_files_driver.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 4acbcf6c5..f95edcf2c 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -187,19 +187,22 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle rewind($this->_file_handle); } - for ($written = 0, $length = strlen($session_data); $written < $length; $written += $result) + if (($length = strlen($session_data)) > 0) { - if (($result = fwrite($this->_file_handle, substr($session_data, $written))) === FALSE) + for ($written = 0; $written < $length; $written += $result) { - break; + if (($result = fwrite($this->_file_handle, substr($session_data, $written))) === FALSE) + { + break; + } } - } - if ( ! is_int($result)) - { - $this->_fingerprint = md5(substr($session_data, 0, $written)); - log_message('error', 'Session: Unable to write data.'); - return FALSE; + if ( ! is_int($result)) + { + $this->_fingerprint = md5(substr($session_data, 0, $written)); + log_message('error', 'Session: Unable to write data.'); + return FALSE; + } } $this->_fingerprint = md5($session_data); -- cgit v1.2.3-24-g4f1b From ef41786a8a3e04d30fef757acd83c5ab888df88e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 4 Jun 2014 21:28:13 +0300 Subject: #3073: Fix temp/flash data getters --- system/libraries/Session/Session.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index bdcde1e76..df6225e68 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -509,7 +509,7 @@ class CI_Session { $userdata = array(); $_exclude = array_merge( - array('__ci_f', '__ci_t'), + array('__ci_vars'), $this->get_flash_keys(), $this->get_temp_keys() ); @@ -619,18 +619,18 @@ class CI_Session { { if (isset($key)) { - return isset($_SESSION['__ci_f'], $_SESSION['__ci_f'][$key], $_SESSION[$key]) + return (isset($_SESSION['__ci_vars'], $_SESSION['__ci_vars'][$key], $_SESSION[$key]) && ! is_int($_SESSION['__ci_vars'][$key])) ? $_SESSION[$key] : NULL; } $flashdata = array(); - if ( ! empty($_SESSION['__ci_f'])) + if ( ! empty($_SESSION['__ci_vars'])) { - foreach (array_keys($_SESSION['__ci_f']) as $key) + foreach ($_SESSION['__ci_vars'] as $key => &$value) { - $flashdata[$key] = $_SESSION[$key]; + is_int($value) OR $flashdata[$key] = $_SESSION[$key]; } } @@ -683,18 +683,18 @@ class CI_Session { { if (isset($key)) { - return isset($_SESSION['__ci_t'], $_SESSION['__ci_t'][$key], $_SESSION[$key]) + return (isset($_SESSION['__ci_vars'], $_SESSION['__ci_vars'][$key], $_SESSION[$key]) && is_int($_SESSION['__ci_vars'][$key])) ? $_SESSION[$key] : NULL; } $tempdata = array(); - if ( ! empty($_SESSION['__ci_t'])) + if ( ! empty($_SESSION['__ci_vars'])) { - foreach (array_keys($_SESSION['__ci_t']) as $key) + foreach ($_SESSION['__ci_vars'] as $key => &$value) { - $tempdata[$key] = $_SESSION[$key]; + is_int($value) && $tempdata[$key] = $_SESSION[$key]; } } -- cgit v1.2.3-24-g4f1b From e86603fb4eb218077e255d76a638a3e545e2fd0c Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 11 Jun 2014 14:03:36 +0300 Subject: [ci skip] A tiny optimization --- system/libraries/Session/Session.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index df6225e68..a5c9737f7 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -125,10 +125,11 @@ class CI_Session { if ( ! class_exists('CI_Session_driver', FALSE)) { - if (file_exists($file_path = APPPATH.'libraries/Session/Session_driver.php') OR file_exists($file_path = BASEPATH.'libraries/Session/Session_driver.php')) - { - require_once($file_path); - } + require_once( + file_exists(APPPATH.'libraries/Session/Session_driver.php') + ? APPPATH.'libraries/Session/Session_driver.php' + : BASEPATH.'libraries/Session/Session_driver.php' + ); if (file_exists($file_path = APPPATH.'libraries/Session/'.$prefix.'Session_driver.php')) { @@ -137,7 +138,6 @@ class CI_Session { } $class = 'Session_'.$driver.'_driver'; - if ( ! class_exists('CI_'.$class, FALSE)) { if (file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$class.'.php') OR file_exists($file_path = BASEPATH.'libraries/Session/drivers/'.$class.'.php')) -- cgit v1.2.3-24-g4f1b From 85f0c558ca2f47453ce7e8ae767451f5c0045479 Mon Sep 17 00:00:00 2001 From: Marcos SF Filho Date: Mon, 11 Aug 2014 10:11:57 -0300 Subject: Added file path for file GC --- system/libraries/Session/drivers/Session_files_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index f95edcf2c..7779e9beb 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -261,7 +261,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // If the filename doesn't match this pattern, it's either not a session file or is not ours if ( ! preg_match('/(?:[0-9a-f]{32})?[0-9a-f]{40}$/i', $file) OR ! is_file($this->_save_path.DIRECTORY_SEPARATOR.$file) - OR ($mtime = filemtime($file)) === FALSE + OR ($mtime = filemtime($this->_save_path.DIRECTORY_SEPARATOR.$file)) === FALSE OR $mtime > $ts) { continue; -- cgit v1.2.3-24-g4f1b From 93d9fa77732b2538417b934a9c23293ee465a23d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 27 Aug 2014 22:14:36 +0300 Subject: feature/session (#3073): Rework locking mechanism & add Redis driver --- system/libraries/Session/Session_driver.php | 64 ++++++++++++- .../Session/drivers/Session_database_driver.php | 104 +++++++-------------- 2 files changed, 98 insertions(+), 70 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index cc35b66d1..a3bc392ad 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -90,12 +90,19 @@ abstract class CI_Session_driver implements SessionHandlerInterface { protected $_match_ip; /** - * Data dash + * Data fingerprint * * @var bool */ protected $_fingerprint; + /** + * Lock placeholder + * + * @var mixed + */ + protected $_lock = FALSE; + // ------------------------------------------------------------------------ /** @@ -202,6 +209,61 @@ abstract class CI_Session_driver implements SessionHandlerInterface { ); } + // ------------------------------------------------------------------------ + + /** + * Get lock + * + * A default locking mechanism via semaphores, if ext/sysvsem is available. + * + * Drivers will usually override this and only fallback to it if no other + * locking mechanism is available. + * + * @param string $session_id + * @return bool + */ + protected function _get_lock($session_id) + { + if ( ! extension_loaded('sysvsem')) + { + $this->_lock = TRUE; + return TRUE; + } + + if (($this->_lock = sem_get($session_id.($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''), 1, 0644)) === FALSE) + { + return FALSE; + } + + if ( ! sem_acquire($this->_lock)) + { + sem_remove($this->_lock); + $this->_lock = FALSE; + return FALSE; + } + + return TRUE; + } + + // ------------------------------------------------------------------------ + + /** + * Release lock + * + * @return bool + */ + protected function _release_lock() + { + if (extension_loaded('sysvsem') && $this->_lock) + { + sem_release($this->_lock); + sem_remove($this->_lock); + $this->_lock = FALSE; + } + + return TRUE; + } + } /* End of file Session_driver.php */ diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 2bdc4d0d5..032199fc1 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -51,13 +51,6 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan */ protected $_table; - /** - * Session ID - * - * @var string - */ - protected $_session_id; - /** * Row exists flag * @@ -70,23 +63,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan * * @var string */ - protected $_lock_driver; - - /** - * Lock status flag - * - * @var bool - */ - protected $_lock = FALSE; - - /** - * Semaphore ID - * - * Used for locking if the database doesn't support advisory locks - * - * @var resource - */ - protected $_sem; + protected $_lock_driver = 'semaphore'; // ------------------------------------------------------------------------ @@ -122,10 +99,6 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { $this->_lock_driver = 'postgre'; } - elseif (extension_loaded('sysvsem')) - { - $this->_lock_driver = 'semaphore'; - } isset($this->_table) OR $this->_table = config_item('sess_table_name'); } @@ -143,8 +116,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan public function read($session_id) { - $this->_session_id = $session_id; - if (($this->_lock = $this->_get_lock()) !== FALSE) + if ($this->_get_lock() !== FALSE) { $this->_db ->select('data') @@ -246,71 +218,65 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // ------------------------------------------------------------------------ - protected function _get_lock() + protected function _get_lock($session_id) { if ($this->_lock_driver === 'mysql') { - $arg = $this->_session_id - .($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''); - return (bool) $this->_db - ->query("SELECT GET_LOCK('".$arg."', 10) AS ci_session_lock") - ->row() - ->ci_session_lock; - } - elseif ($this->_lock_driver === 'postgre') - { - $arg = "hashtext('".$this->_session_id."')" - .($this->_match_ip ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : ''); - - return (bool) $this->_db->simple_query('SELECT pg_advisory_lock('.$arg.')'); - } - elseif ($this->_lock_driver === 'semaphore') - { - if (($this->_sem = sem_get($arg, 1, 0644)) === FALSE) + $arg = $session_id.($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''); + if ($this->_db->query("SELECT GET_LOCK('".$arg."', 10) AS ci_session_lock")->row()->ci_session_lock) { - return FALSE; + $this->_lock = $arg; + return TRUE; } - if ( ! sem_acquire($this->_sem)) + return FALSE; + } + elseif ($this->_lock_driver === 'postgre') + { + $arg = "hashtext('".$session_id."')".($this->_match_ip ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : ''); + if ($this->_db->simple_query('SELECT pg_advisory_lock('.$arg.')')) { - sem_remove($this->_sem); - return FALSE; + $this->_lock = $arg; + return TRUE; } - return TRUE; + return FALSE; } - return TRUE; + return parent::_get_lock($session_id); } // ------------------------------------------------------------------------ protected function _release_lock() { + if ( ! $this->_lock) + { + return TRUE; + } + if ($this->_lock_driver === 'mysql') { - $arg = $this->_session_id - .($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''); + if ($this->_db->query("SELECT RELEASE_LOCK('".$this->_lock."') AS ci_session_lock")->row()->ci_session_lock) + { + $this->_lock = FALSE; + return TRUE; + } - return (bool) $this->_db - ->query("SELECT RELEASE_LOCK('".$arg."') AS ci_session_lock") - ->row() - ->ci_session_lock; + return FALSE; } elseif ($this->_lock_driver === 'postgre') { - $arg = "hashtext('".$this->_session_id."')" - .($this->_match_ip ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : ''); + if ($this->_db->simple_query('SELECT pg_advisory_unlock('.$this->_lock.')')) + { + $this->_lock = FALSE; + return TRUE; + } - return (bool) $this->_db->simple_query('SELECT pg_advisory_unlock('.$arg.')'); - } - elseif ($this->_lock_driver === 'semaphore') - { - sem_release($this->_sem); - sem_remove($this->_sem); + return FALSE; } - return TRUE; + return parent::_release_lock(); } } -- cgit v1.2.3-24-g4f1b From 43f6cdba6c22290c69e795168e326fe1aa8743f6 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 27 Aug 2014 22:26:40 +0300 Subject: feature/session (#3073): Add Redis session driver Seems like I forgot to 'git add' it in previous commit. --- .../Session/drivers/Session_redis_driver.php | 311 +++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 system/libraries/Session/drivers/Session_redis_driver.php (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php new file mode 100644 index 000000000..6c013a657 --- /dev/null +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -0,0 +1,311 @@ +_save_path)) + { + log_message('error', 'Session: No Redis save path configured.'); + } + elseif (preg_match('#(?:tcp://)?([^:]+)(?:\:(\d+))?(\?.+)?#', $this->_save_path, $matches)) + { + $this->_save_path = array( + 'host' => $matches[1], + 'port' => empty($matches[2]) ? NULL : $matches[2], + 'password' => preg_match('#auth=([^\s&]+)#', $matches[3], $match) ? $match[1] : NULL, + 'database' => preg_match('#database=(\d+)#', $matches[3], $match) ? (int) $match[1] : NULL, + 'timeout' => preg_match('#timeout=(\d+\.\d+)#', $matches[3], $match) ? (float) $match[1] : NULL + ); + + preg_match('#prefix=([^\s&]+)#', $matches[3], $match) && $this->_key_prefix = $match[1]; + } + else + { + log_message('error', 'Session: Invalid Redis save path format: '.$this->_save_path); + } + + if ($this->_match_ip === TRUE) + { + $this->_key_prefix .= $_SERVER['REMOTE_ADDR'].':'; + } + } + + // ------------------------------------------------------------------------ + + public function open($save_path, $name) + { + if (empty($this->_save_path)) + { + return FALSE; + } + + $redis = new Redis(); + if ( ! $redis->connect($this->_save_path['host'], $this->_save_path['port'], $this->_save_path['timeout'])) + { + log_message('error', 'Session: Unable to connect to Redis with the configured settings.'); + } + elseif (isset($this->_save_path['password']) && ! $redis->auth($this->_save_path['password'])) + { + log_message('error', 'Session: Unable to authenticate to Redis instance.'); + } + elseif (isset($this->_save_path['database']) && ! $redis->select($this->_save_path['database'])) + { + log_message('error', 'Session: Unable to select Redis database with index '.$this->_save_path['database']); + } + else + { + $this->_redis = $redis; + return TRUE; + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + public function read($session_id) + { + if (isset($this->_redis) && $this->_get_lock($session_id)) + { + $session_data = (string) $this->_redis->get($this->_key_prefix.$session_id); + $this->_fingerprint = md5($session_data); + return $session_data; + } + + return FALSE; + } + + public function write($session_id, $session_data) + { + if (isset($this->_redis, $this->_lock_key)) + { + $this->_redis->setTimeout($this->_lock_key, 10, time()); + if ($this->_fingerprint !== ($fingerprint = md5($session_data))) + { + if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_expiration)) + { + $this->_fingerprint = $fingerprint; + return TRUE; + } + + return FALSE; + } + + return $this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_expiration); + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + public function close() + { + if (isset($this->_redis)) + { + try { + if ($this->_redis->ping() === '+PONG') + { + isset($this->_lock_key) && $this->_redis->delete($this->_lock_key); + if ( ! $this->_redis->close()) + { + return FALSE; + } + } + } + catch (RedisException $e) + { + log_message('error', 'Session: Got RedisException on close(): '.$e->getMessage()); + } + + $this->_redis = NULL; + return TRUE; + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + public function destroy($session_id) + { + if (isset($this->_redis, $this->_lock_key)) + { + if ($this->_redis->delete($this->_key_prefix.$session_id) !== 1) + { + log_message('debug', 'Session: Redis::delete() expected to return 1, got '.var_export($result, TRUE).' instead.'); + } + + return ($this->_cookie_destroy() && $this->close()); + } + + return $this->close(); + } + + // ------------------------------------------------------------------------ + + public function gc($maxlifetime) + { + // TODO: keys()/getKeys() is said to be performance-intensive, + // although it supports patterns (*, [charlist] at the very least). + // scan() seems to be recommended, but requires redis 2.8 + // Not sure if we need any of these though, as we set keys with expire times + return TRUE; + } + + // ------------------------------------------------------------------------ + + protected function _get_lock($session_id) + { + if (isset($this->_lock_key)) + { + return $this->_redis->setTimeout($this->_lock_key, 5); + } + + $lock_key = $this->_key_prefix.$session_id.':lock'; + if (($ttl = $this->_redis->ttl($lock_key)) < 1) + { + if ( ! $this->_redis->setex($lock_key, 5, time())) + { + log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); + return FALSE; + } + + $this->_lock_key = $lock_key; + + if ($ttl === -1) + { + log_message('debug', 'Session: Lock for '.$this->_key_prefix.$session_id.' had no TTL, overriding.'); + } + + $this->_lock = TRUE; + return TRUE; + } + + // Another process has the lock, we'll try to wait for it to free itself ... + $attempt = 0; + while ($attempt++ < 5) + { + usleep(($ttl * 1000000) - 20000); + if (($ttl = $this->_redis->ttl($lock_key)) > 0) + { + continue; + } + + if ( ! $this->_redis->setex($lock_key, 5, time())) + { + log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); + return FALSE; + } + + $this->_lock_key = $lock_key; + break; + } + + if ($attempt === 5) + { + log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 5 attempts, aborting.'); + return FALSE; + } + + $this->_lock = TRUE; + return TRUE; + } + + // ------------------------------------------------------------------------ + + protected function _release_lock() + { + if (isset($this->_redis, $this->_lock_key) && $this->_lock) + { + if ( ! $this->_redis->delete($this->_lock_key)) + { + log_message('error', 'Session: Error while trying to free lock for '.$this->_key_prefix.$session_id); + return FALSE; + } + + $this->_lock_key = NULL; + $this->_lock = FALSE; + } + + return TRUE; + } + +} + +/* End of file Session_redis_driver.php */ +/* Location: ./system/libraries/Session/drivers/Session_redis_driver.php */ \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 2a1f940884f50c8157594cdec66af65fa3874b39 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 27 Aug 2014 23:52:55 +0300 Subject: feature/session (#3073): Fix an E_WARNING in CI_Session_redis_driver --- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 6c013a657..d4ce5b274 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -153,7 +153,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if (isset($this->_redis, $this->_lock_key)) { - $this->_redis->setTimeout($this->_lock_key, 10, time()); + $this->_redis->setTimeout($this->_lock_key, 5); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_expiration)) -- cgit v1.2.3-24-g4f1b From c9efaced2fd453bf4c2fcefd31ee1a9afdf8ff16 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 2 Sep 2014 15:19:01 +0300 Subject: feature/session (#3073): Add Memcached session driver --- .../Session/drivers/Session_memcached_driver.php | 287 +++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 system/libraries/Session/drivers/Session_memcached_driver.php (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php new file mode 100644 index 000000000..c6ad56511 --- /dev/null +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -0,0 +1,287 @@ +_save_path)) + { + log_message('error', 'Session: No Memcached save path configured.'); + } + + if ($this->_match_ip === TRUE) + { + $this->_key_prefix .= $_SERVER['REMOTE_ADDR'].':'; + } + } + + // ------------------------------------------------------------------------ + + public function open($save_path, $name) + { + $this->_memcached = new Memcached(); + $server_list = array(); + foreach ($this->_memcached->getServerList() as $server) + { + $server_list[] = $server['host'].':'.$server['port']; + } + + if ( ! preg_match_all('#,?([^,:]+)\:(\d{1,5})(?:\:(\d+))?#', $this->_save_path, $matches, PREG_SET_ORDER)) + { + $this->_memcached = NULL; + log_message('error', 'Session: Invalid Memcached save path format: '.$this->_save_path); + return FALSE; + } + + foreach ($matches as $match) + { + // If Memcached already has this server (or if the port is invalid), skip it + if (in_array($match[1].':'.$match[2], $server_list, TRUE)) + { + log_message('debug', 'Session: Memcached server pool already has '.$match[1].':'.$match[2]); + continue; + } + + if ( ! $this->_memcached->addServer($match[1], $match[2], isset($match[3]) ? $match[3] : 0)) + { + log_message('error', 'Could not add '.$match[1].':'.$match[2].' to Memcached server pool.'); + } + else + { + $server_list[] = $server['host'].':'.$server['port']; + } + } + + if (empty($server_list)) + { + log_message('error', 'Session: Memcached server pool is empty.'); + return FALSE; + } + + return TRUE; + } + + // ------------------------------------------------------------------------ + + public function read($session_id) + { + if (isset($this->_memcached) && $this->_get_lock($session_id)) + { + $session_data = (string) $this->_memcached->get($this->_key_prefix.$session_id); + $this->_fingerprint = md5($session_data); + return $session_data; + } + + return FALSE; + } + + public function write($session_id, $session_data) + { + if (isset($this->_memcached, $this->_lock_key)) + { + $this->_memcached->replace($this->_lock_key, time(), 5); + if ($this->_fingerprint !== ($fingerprint = md5($session_data))) + { + if ($this->_memcached->set($this->_key_prefix.$session_id, $session_data, $this->_expiration)) + { + $this->_fingerprint = $fingerprint; + return TRUE; + } + + return FALSE; + } + + return $this->_memcached->touch($this->_key_prefix.$session_id, $this->_expiration); + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + public function close() + { + if (isset($this->_memcached)) + { + isset($this->_lock_key) && $this->_memcached->delete($this->_lock_key); + if ( ! $this->_memcached->quit()) + { + return FALSE; + } + + $this->_memcached = NULL; + return TRUE; + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + public function destroy($session_id) + { + if (isset($this->_memcached, $this->_lock_key)) + { + $this->_memcached->delete($this->_key_prefix.$session_id); + return ($this->_cookie_destroy() && $this->close()); + } + + return $this->close(); + } + + // ------------------------------------------------------------------------ + + public function gc($maxlifetime) + { + return TRUE; + } + + // ------------------------------------------------------------------------ + + protected function _get_lock($session_id) + { + if (isset($this->_lock_key)) + { + return $this->_memcached->replace($this->_lock_key, time(), 5); + } + + $lock_key = $this->_key_prefix.$session_id.':lock'; + if ( ! ($ts = $this->_memcached->get($lock_key))) + { + if ( ! $this->_memcached->set($lock_key, TRUE, 5)) + { + log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); + return FALSE; + } + + $this->_lock_key = $lock_key; + $this->_lock = TRUE; + return TRUE; + } + + // Another process has the lock, we'll try to wait for it to free itself ... + $attempt = 0; + while ($attempt++ < 5) + { + usleep(((time() - $ts) * 1000000) - 20000); + if (($ts = $this->_memcached->get($lock_key)) < time()) + { + continue; + } + + if ( ! $this->_memcached->set($lock_key, time(), 5)) + { + log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); + return FALSE; + } + + $this->_lock_key = $lock_key; + break; + } + + if ($attempt === 5) + { + log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 5 attempts, aborting.'); + return FALSE; + } + + $this->_lock = TRUE; + return TRUE; + } + + // ------------------------------------------------------------------------ + + protected function _release_lock() + { + if (isset($this->_memcached, $this->_lock_key) && $this->_lock) + { + if ( ! $this->_memcached->delete($this->_lock_key) && $this->_memcached->getResultCode() !== Memcached::RES_NOTFOUND) + { + log_message('error', 'Session: Error while trying to free lock for '.$this->_key_prefix.$session_id); + return FALSE; + } + + $this->_lock_key = NULL; + $this->_lock = FALSE; + } + + return TRUE; + } + +} + +/* End of file Session_memcached_driver.php */ +/* Location: ./system/libraries/Session/drivers/Session_memcached_driver.php */ \ No newline at end of file -- cgit v1.2.3-24-g4f1b From d069b9bc148f739733a5aa0a737e51e57c10b3ad Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 16 Sep 2014 10:18:16 +0300 Subject: feature/session (#3073): Bug fixes - CI_Session_database_driver::read() didn't pass the session ID to _get_lock() - CI_Session::unset_userdata() used a wrong key for unsetting when an array is passed to it --- system/libraries/Session/Session.php | 2 +- system/libraries/Session/drivers/Session_database_driver.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index a5c9737f7..be9f5e3c7 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -567,7 +567,7 @@ class CI_Session { { foreach ($key as $k) { - unset($_SESSION[$key]); + unset($_SESSION[$k]); } return; diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 032199fc1..563d1fd6a 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -116,7 +116,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan public function read($session_id) { - if ($this->_get_lock() !== FALSE) + if ($this->_get_lock($session_id) !== FALSE) { $this->_db ->select('data') -- cgit v1.2.3-24-g4f1b From 39ec29585b7cdca7edc1a0757c913a13a2ee4f85 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 17 Sep 2014 14:16:05 +0300 Subject: feature/session (#3073): Redis driver save_path param parsing fixes Close #3240 --- system/libraries/Session/drivers/Session_redis_driver.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index d4ce5b274..6d8044da1 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -81,8 +81,9 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { log_message('error', 'Session: No Redis save path configured.'); } - elseif (preg_match('#(?:tcp://)?([^:]+)(?:\:(\d+))?(\?.+)?#', $this->_save_path, $matches)) + elseif (preg_match('#(?:tcp://)?([^:?]+)(?:\:(\d+))?(\?.+)?#', $this->_save_path, $matches)) { + isset($matches[3]) OR $matches[3] = ''; // Just to avoid undefined index notices below $this->_save_path = array( 'host' => $matches[1], 'port' => empty($matches[2]) ? NULL : $matches[2], -- cgit v1.2.3-24-g4f1b From dfb39bec5faf77e806e55f3ee9d2138e57d55010 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 6 Oct 2014 01:50:14 +0300 Subject: feature/session (#3073): Refactor configuration & fix cookie expiry times --- system/libraries/Session/Session.php | 121 ++++++++++++++++- system/libraries/Session/Session_driver.php | 146 ++------------------- .../Session/drivers/Session_database_driver.php | 29 ++-- .../Session/drivers/Session_files_driver.php | 26 ++-- .../Session/drivers/Session_memcached_driver.php | 19 +-- .../Session/drivers/Session_redis_driver.php | 31 ++--- 6 files changed, 169 insertions(+), 203 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index be9f5e3c7..47c43074e 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -38,6 +38,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); class CI_Session { protected $_driver = 'files'; + protected $_config; // ------------------------------------------------------------------------ @@ -65,8 +66,7 @@ class CI_Session { $this->_driver = $params['driver']; unset($params['driver']); } - // Note: Make the autoloader pass sess_* params to this constructor - elseif (empty($params) && $driver = config_item('sess_driver')) + elseif ($driver = config_item('sess_driver')) { $this->_driver = $driver; } @@ -81,7 +81,10 @@ class CI_Session { return; } - $class = new $class($params); + // Configuration ... + $this->_configure($params); + + $class = new $class($this->_config); if ($class instanceof SessionHandlerInterface) { if (is_php('5.4')) @@ -108,9 +111,50 @@ class CI_Session { return; } + // Work-around for PHP bug #66827 (https://bugs.php.net/bug.php?id=66827) + // + // The session ID sanitizer doesn't check for the value type and blindly does + // an implicit cast to string, which triggers an 'Array to string' E_NOTICE. + if (isset($_COOKIE[$this->_cookie_name]) && ! is_string($_COOKIE[$this->_cookie_name])) + { + unset($_COOKIE[$this->_cookie_name]); + } + session_start(); + + // Another work-around ... PHP doesn't seem to send the session cookie + // unless it is being currently created or regenerated + if (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id()) + { + setcookie( + $this->_config['cookie_name'], + session_id(), + (empty($this->_config['cookie_lifetime']) ? 0 : time() + $this->_config['cookie_lifetime']), + $this->_config['cookie_path'], + $this->_config['cookie_domain'], + $this->_config['cookie_secure'], + TRUE + ); + } + $this->_ci_init_vars(); +/* + Need to test if this is necessary for a custom driver or if it's only + relevant to PHP's own files handler. + + https://bugs.php.net/bug.php?id=65475 + do this after session is started: + if (is_php('5.5.2') && ! is_php('5.5.4')) + { + $session_id = session_id(); + if ($_COOKIE[$this->_cookie_name] !== $session_id && file_exists(teh file)) + { + unlink(); + } + } +*/ + log_message('debug', "Session: Class initialized using '".$this->_driver."' driver."); } @@ -170,6 +214,77 @@ class CI_Session { // ------------------------------------------------------------------------ + /** + * Configuration + * + * Handle input parameters and configuration defaults + * + * @param array &$params Input parameters + * @return void + */ + protected function _configure(&$params) + { + $expiration = config_item('sess_expiration'); + + if (isset($params['cookie_lifetime'])) + { + $params['cookie_lifetime'] = (int) $params['cookie_lifetime']; + } + else + { + $params['cookie_lifetime'] = ( ! isset($expiration) && config_item('sess_expire_on_close')) + ? 0 : (int) $expiration; + } + + isset($params['cookie_name']) OR $params['cookie_name'] = config_item('sess_cookie_name'); + if (empty($params['cookie_name'])) + { + $params['cookie_name'] = ini_get('session.name'); + } + else + { + ini_set('session.name', $params['cookie_name']); + } + + isset($params['cookie_path']) OR $params['cookie_path'] = config_item('cookie_path'); + isset($params['cookie_domain']) OR $parrams['cookie_domain'] = config_item('cookie_domain'); + isset($params['cookie_secure']) OR $params['cookie_secure'] = (bool) config_item('cookie_secure'); + + session_set_cookie_params( + $params['cookie_lifetime'], + $params['cookie_path'], + $params['cookie_domain'], + $params['cookie_secure'], + TRUE // HttpOnly; Yes, this is intentional and not configurable for security reasons + ); + + if (empty($expiration)) + { + $params['expiration'] = (int) ini_get('session.gc_maxlifetime'); + } + else + { + $params['expiration'] = (int) $expiration; + ini_set('session.gc_maxlifetime', $expiration); + } + + $params['match_ip'] = (bool) (isset($params['match_ip']) ? $params['match_ip'] : config_item('sess_match_ip')); + + isset($params['save_path']) OR $params['save_path'] = config_item('sess_save_path'); + + $this->_config = $params; + + // Security is king + ini_set('session.use_trans_id', 0); + ini_set('session.use_strict_mode', 1); + ini_set('session.use_cookies', 1); + ini_set('session.use_only_cookies', 1); + ini_set('session.hash_function', 1); + ini_set('session.hash_bits_per_character', 4); + } + + // ------------------------------------------------------------------------ + /** * Handle temporary variables * diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index a3bc392ad..fb695dade 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -37,57 +37,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); */ abstract class CI_Session_driver implements SessionHandlerInterface { - // WARNING! Setting default values to properties will - // prevent using the configuration file values. - - /** - * Expiration time - * - * @var int - */ - protected $_expiration; - - /** - * Cookie name - * - * @var string - */ - protected $_cookie_name; - - /** - * Cookie domain - * - * @var string - */ - protected $_cookie_domain; - - /** - * Cookie path - * - * @var string - */ - protected $_cookie_path; - - /** - * Cookie secure flag - * - * @var bool - */ - protected $_cookie_secure; - - /** - * Cookie HTTP-only flag - * - * @var bool - */ - protected $_cookie_httponly; - - /** - * Match IP addresses flag - * - * @var bool - */ - protected $_match_ip; + protected $_config; /** * Data fingerprint @@ -111,87 +61,9 @@ abstract class CI_Session_driver implements SessionHandlerInterface { * @param array $params Configuration parameters * @return void */ - public function __construct($params) + public function __construct(&$params) { - foreach ($params as $key => &$value) - { - $key = (strncmp($key, 'sess_', 5) === 0) - ? substr($key, 4) - : '_'.$key; - - property_exists($this, $key) && $this->$key = $value; - } - - isset($this->_expiration) OR $this->_expiration = (int) config_item('sess_expiration'); - isset($this->_cookie_name) OR $this->_cookie_name = config_item('sess_cookie_name'); - isset($this->_cookie_domain) OR $this->_cookie_domain = config_item('cookie_domain'); - isset($this->_cookie_path) OR $this->_cookie_path = config_item('cookie_path'); - isset($this->_cookie_secure) OR $this->_cookie_secure = config_item('cookie_secure'); - isset($this->_cookie_httponly) OR $this->_cookie_httponly = config_item('cookie_httponly'); - isset($this->_match_ip) OR $this->_match_ip = config_item('sess_match_ip'); - - // Pass our configuration to php.ini, when appropriate - ini_set('session.name', $this->_cookie_name); - isset($this->_cookie_domain) && ini_set('session.cookie_domain', $this->_cookie_domain); - isset($this->_cookie_path) && ini_set('session.cookie_path', $this->_cookie_path); - isset($this->_cookie_secure) && ini_set('session.cookie_secure', $this->_cookie_secure); - isset($this->_cookie_httponly) && ini_set('session.cookie_httponly', $this->_cookie_httponly); - - if ($this->_expiration) - { - ini_set('session.gc_maxlifetime', $this->_expiration); - ini_set('session.cookie_lifetime', $this->_expiration); - } - // BC workaround for setting cookie lifetime - elseif (config_item('sess_expire_on_close')) - { - ini_set('session.cookie_lifetime', 0); - } - - // Security is king - ini_set('session.use_trans_id', 0); - ini_set('session.use_strict_mode', 1); - ini_set('session.use_cookies', 1); - ini_set('session.use_only_cookies', 1); - ini_set('session.hash_function', 1); - ini_set('session.hash_bits_per_character', 4); - - // Work-around for PHP bug #66827 (https://bugs.php.net/bug.php?id=66827) - // - // The session ID sanitizer doesn't check for the value type and blindly does - // an implicit cast to string, which triggers an 'Array to string' E_NOTICE. - if (isset($_COOKIE[$this->_cookie_name]) && ! is_string($_COOKIE[$this->_cookie_name])) - { - unset($_COOKIE[$this->_cookie_name]); - } - -/* - Need to test if this is necessary for a custom driver or if it's only - relevant to PHP's own files handler. - - https://bugs.php.net/bug.php?id=65475 - do this after session is started: - if (is_php('5.5.2') && ! is_php('5.5.4')) - { - $session_id = session_id(); - if ($_COOKIE[$this->_cookie_name] !== $session_id && file_exists(teh file)) - { - unlink(); - } - - setcookie( - $this->_cookie_name, - $session_id, - $this->_expiration - ? time() + $this->_expiration - : 0, - $this->_cookie_path, - $this->_cookie_domain, - $this->_cookie_secure, - $this->_cookie_httponly - ); - } -*/ + $this->_config =& $params; } // ------------------------------------------------------------------------ @@ -199,13 +71,13 @@ abstract class CI_Session_driver implements SessionHandlerInterface { protected function _cookie_destroy() { return setcookie( - $this->_cookie_name, + $this->_config['cookie_name'], NULL, 1, - $this->_cookie_path, - $this->_cookie_domain, - $this->_cookie_secure, - $this->_cookie_httponly + $this->_config['cookie_path'], + $this->_config['cookie_domain'], + $this->_config['cookie_secure'], + TRUE ); } @@ -230,7 +102,7 @@ abstract class CI_Session_driver implements SessionHandlerInterface { return TRUE; } - if (($this->_lock = sem_get($session_id.($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''), 1, 0644)) === FALSE) + if (($this->_lock = sem_get($session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : ''), 1, 0644)) === FALSE) { return FALSE; } diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 563d1fd6a..e3a3c505e 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -44,13 +44,6 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan */ protected $_db; - /** - * DB table - * - * @var string - */ - protected $_table; - /** * Row exists flag * @@ -100,7 +93,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_lock_driver = 'postgre'; } - isset($this->_table) OR $this->_table = config_item('sess_table_name'); + isset($this->_config['save_path']) OR $this->_config['save_path'] = config_item('sess_table_name'); } // ------------------------------------------------------------------------ @@ -120,10 +113,10 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { $this->_db ->select('data') - ->from($this->_table) + ->from($this->_config['save_path']) ->where('id', $session_id); - if ($this->_match_ip) + if ($this->_config['match_ip']) { $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } @@ -152,7 +145,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if ($this->_row_exists === FALSE) { - if ($this->_db->insert($this->_table, array('id' => $session_id, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'timestamp' => time(), 'data' => $session_data))) + if ($this->_db->insert($this->_config['save_path'], array('id' => $session_id, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'timestamp' => time(), 'data' => $session_data))) { $this->_fingerprint = md5($session_data); return $this->_row_exists = TRUE; @@ -162,7 +155,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan } $this->_db->where('id', $session_id); - if ($this->_match_ip) + if ($this->_config['match_ip']) { $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } @@ -171,7 +164,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan ? array('timestamp' => time()) : array('timestamp' => time(), 'data' => $session_data); - if ($this->_db->update($this->_table, $update_data)) + if ($this->_db->update($this->_config['save_path'], $update_data)) { $this->_fingerprint = md5($session_data); return TRUE; @@ -196,12 +189,12 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if ($this->_lock) { $this->_db->where('id', $session_id); - if ($this->_match_ip) + if ($this->_config['match_ip']) { $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } - return $this->_db->delete($this->_table) + return $this->_db->delete($this->_config['save_path']) ? ($this->close() && $this->_cookie_destroy()) : FALSE; } @@ -213,7 +206,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan public function gc($maxlifetime) { - return $this->_db->delete($this->_table, 'timestamp < '.(time() - $maxlifetime)); + return $this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime)); } // ------------------------------------------------------------------------ @@ -222,7 +215,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if ($this->_lock_driver === 'mysql') { - $arg = $session_id.($this->_match_ip ? '_'.$_SERVER['REMOTE_ADDR'] : ''); + $arg = $session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : ''); if ($this->_db->query("SELECT GET_LOCK('".$arg."', 10) AS ci_session_lock")->row()->ci_session_lock) { $this->_lock = $arg; @@ -233,7 +226,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan } elseif ($this->_lock_driver === 'postgre') { - $arg = "hashtext('".$session_id."')".($this->_match_ip ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : ''); + $arg = "hashtext('".$session_id."')".($this->_config['match_ip'] ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : ''); if ($this->_db->simple_query('SELECT pg_advisory_lock('.$arg.')')) { $this->_lock = $arg; diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 7779e9beb..a4f1b9f2f 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -77,14 +77,14 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { parent::__construct($params); - if (isset($this->_save_path)) + if (isset($this->_config['save_path'])) { - $this->_save_path = rtrim($this->_save_path, '/\\'); - ini_set('session.save_path', $this->_save_path); + $this->_config['save_path'] = rtrim($this->_config['save_path'], '/\\'); + ini_set('session.save_path', $this->_config['save_path']); } else { - $this->_save_path = rtrim(ini_get('session.save_path'), '/\\'); + $this->_config['save_path'] = rtrim(ini_get('session.save_path'), '/\\'); } } @@ -94,14 +94,14 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { if ( ! is_dir($save_path) && ! mkdir($save_path, 0700, TRUE)) { - log_message('error', "Session: Configured save path '".$this->_save_path."' is not a directory, doesn't exist or cannot be created."); + log_message('error', "Session: Configured save path '".$this->_config['save_path']."' is not a directory, doesn't exist or cannot be created."); return FALSE; } - $this->_save_path = $save_path; - $this->_file_path = $this->_save_path.DIRECTORY_SEPARATOR + $this->_config['save_path'] = $save_path; + $this->_file_path = $this->_config['save_path'].DIRECTORY_SEPARATOR .$name // we'll use the session cookie name as a prefix to avoid collisions - .($this->_match_ip ? md5($_SERVER['REMOTE_ADDR']) : ''); + .($this->_config['match_ip'] ? md5($_SERVER['REMOTE_ADDR']) : ''); return TRUE; } @@ -248,9 +248,9 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle public function gc($maxlifetime) { - if ( ! is_dir($this->_save_path) OR ($files = scandir($this->_save_path)) === FALSE) + if ( ! is_dir($this->_config['save_path']) OR ($files = scandir($this->_config['save_path'])) === FALSE) { - log_message('debug', "Session: Garbage collector couldn't list files under directory '".$this->_save_path."'."); + log_message('debug', "Session: Garbage collector couldn't list files under directory '".$this->_config['save_path']."'."); return FALSE; } @@ -260,14 +260,14 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { // If the filename doesn't match this pattern, it's either not a session file or is not ours if ( ! preg_match('/(?:[0-9a-f]{32})?[0-9a-f]{40}$/i', $file) - OR ! is_file($this->_save_path.DIRECTORY_SEPARATOR.$file) - OR ($mtime = filemtime($this->_save_path.DIRECTORY_SEPARATOR.$file)) === FALSE + OR ! is_file($this->_config['save_path'].DIRECTORY_SEPARATOR.$file) + OR ($mtime = filemtime($this->_config['save_path'].DIRECTORY_SEPARATOR.$file)) === FALSE OR $mtime > $ts) { continue; } - unlink($this->_save_path.DIRECTORY_SEPARATOR.$file); + unlink($this->_config['save_path'].DIRECTORY_SEPARATOR.$file); } return TRUE; diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index c6ad56511..318c11afa 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -37,13 +37,6 @@ defined('BASEPATH') OR exit('No direct script access allowed'); */ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHandlerInterface { - /** - * Save path - * - * @var string - */ - protected $_save_path; - /** * Memcached instance * @@ -77,12 +70,12 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { parent::__construct($params); - if (empty($this->_save_path)) + if (empty($this->_config['save_path'])) { log_message('error', 'Session: No Memcached save path configured.'); } - if ($this->_match_ip === TRUE) + if ($this->_config['match_ip'] === TRUE) { $this->_key_prefix .= $_SERVER['REMOTE_ADDR'].':'; } @@ -99,10 +92,10 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $server_list[] = $server['host'].':'.$server['port']; } - if ( ! preg_match_all('#,?([^,:]+)\:(\d{1,5})(?:\:(\d+))?#', $this->_save_path, $matches, PREG_SET_ORDER)) + if ( ! preg_match_all('#,?([^,:]+)\:(\d{1,5})(?:\:(\d+))?#', $this->_config['save_path'], $matches, PREG_SET_ORDER)) { $this->_memcached = NULL; - log_message('error', 'Session: Invalid Memcached save path format: '.$this->_save_path); + log_message('error', 'Session: Invalid Memcached save path format: '.$this->_config['save_path']); return FALSE; } @@ -155,7 +148,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $this->_memcached->replace($this->_lock_key, time(), 5); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { - if ($this->_memcached->set($this->_key_prefix.$session_id, $session_data, $this->_expiration)) + if ($this->_memcached->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; return TRUE; @@ -164,7 +157,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return FALSE; } - return $this->_memcached->touch($this->_key_prefix.$session_id, $this->_expiration); + return $this->_memcached->touch($this->_key_prefix.$session_id, $this->_config['expiration']); } return FALSE; diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 6d8044da1..ef18defe2 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -37,13 +37,6 @@ defined('BASEPATH') OR exit('No direct script access allowed'); */ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandlerInterface { - /** - * Save path - * - * @var string - */ - protected $_save_path; - /** * phpRedis instance * @@ -77,14 +70,14 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { parent::__construct($params); - if (empty($this->_save_path)) + if (empty($this->_config['save_path'])) { log_message('error', 'Session: No Redis save path configured.'); } - elseif (preg_match('#(?:tcp://)?([^:?]+)(?:\:(\d+))?(\?.+)?#', $this->_save_path, $matches)) + elseif (preg_match('#(?:tcp://)?([^:?]+)(?:\:(\d+))?(\?.+)?#', $this->_config['save_path'], $matches)) { isset($matches[3]) OR $matches[3] = ''; // Just to avoid undefined index notices below - $this->_save_path = array( + $this->_config['save_path'] = array( 'host' => $matches[1], 'port' => empty($matches[2]) ? NULL : $matches[2], 'password' => preg_match('#auth=([^\s&]+)#', $matches[3], $match) ? $match[1] : NULL, @@ -96,10 +89,10 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle } else { - log_message('error', 'Session: Invalid Redis save path format: '.$this->_save_path); + log_message('error', 'Session: Invalid Redis save path format: '.$this->_config['save_path']); } - if ($this->_match_ip === TRUE) + if ($this->_config['match_ip'] === TRUE) { $this->_key_prefix .= $_SERVER['REMOTE_ADDR'].':'; } @@ -109,23 +102,23 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle public function open($save_path, $name) { - if (empty($this->_save_path)) + if (empty($this->_config['save_path'])) { return FALSE; } $redis = new Redis(); - if ( ! $redis->connect($this->_save_path['host'], $this->_save_path['port'], $this->_save_path['timeout'])) + if ( ! $redis->connect($this->_config['save_path']['host'], $this->_config['save_path']['port'], $this->_config['save_path']['timeout'])) { log_message('error', 'Session: Unable to connect to Redis with the configured settings.'); } - elseif (isset($this->_save_path['password']) && ! $redis->auth($this->_save_path['password'])) + elseif (isset($this->_config['save_path']['password']) && ! $redis->auth($this->_config['save_path']['password'])) { log_message('error', 'Session: Unable to authenticate to Redis instance.'); } - elseif (isset($this->_save_path['database']) && ! $redis->select($this->_save_path['database'])) + elseif (isset($this->_config['save_path']['database']) && ! $redis->select($this->_config['save_path']['database'])) { - log_message('error', 'Session: Unable to select Redis database with index '.$this->_save_path['database']); + log_message('error', 'Session: Unable to select Redis database with index '.$this->_config['save_path']['database']); } else { @@ -157,7 +150,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle $this->_redis->setTimeout($this->_lock_key, 5); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { - if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_expiration)) + if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; return TRUE; @@ -166,7 +159,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return FALSE; } - return $this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_expiration); + return $this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration']); } return FALSE; -- cgit v1.2.3-24-g4f1b From 41b546deee9f1ed99f3820de5a2014b2d74a0c94 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 6 Oct 2014 03:01:22 +0300 Subject: feature/session (#3073): Fix a variable name --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 47c43074e..c00262cc2 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -247,7 +247,7 @@ class CI_Session { } isset($params['cookie_path']) OR $params['cookie_path'] = config_item('cookie_path'); - isset($params['cookie_domain']) OR $parrams['cookie_domain'] = config_item('cookie_domain'); + isset($params['cookie_domain']) OR $params['cookie_domain'] = config_item('cookie_domain'); isset($params['cookie_secure']) OR $params['cookie_secure'] = (bool) config_item('cookie_secure'); session_set_cookie_params( -- cgit v1.2.3-24-g4f1b From c5519ce166943b744bbea75a87831132aced4247 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sun, 26 Oct 2014 11:57:20 +0200 Subject: #3073 (feature/session): Fix a GC issue with the files driver --- system/libraries/Session/drivers/Session_files_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index a4f1b9f2f..ff1553f84 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -261,7 +261,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // If the filename doesn't match this pattern, it's either not a session file or is not ours if ( ! preg_match('/(?:[0-9a-f]{32})?[0-9a-f]{40}$/i', $file) OR ! is_file($this->_config['save_path'].DIRECTORY_SEPARATOR.$file) - OR ($mtime = filemtime($this->_config['save_path'].DIRECTORY_SEPARATOR.$file)) === FALSE + OR ($mtime = fileatime($this->_config['save_path'].DIRECTORY_SEPARATOR.$file)) === FALSE OR $mtime > $ts) { continue; -- cgit v1.2.3-24-g4f1b From c6e50989480d5e9a9847177b8dc7cefa6559329a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sun, 26 Oct 2014 21:27:28 +0200 Subject: #3073 (feature/session): set_flashdata() crap --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index c00262cc2..7908badf8 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -766,7 +766,7 @@ class CI_Session { public function set_flashdata($data, $value = NULL) { $this->set_userdata($data, $value); - $this->mark_as_flash($data); + $this->mark_as_flash(is_array($data) ? array_keys($data) : $data); } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From cd489611cf2d4e7ba7f5afb370a4b8a01f71c5bc Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 27 Oct 2014 16:09:01 +0200 Subject: Revert "#3073 (feature/session): Fix a GC issue with the files driver" This reverts commit c5519ce166943b744bbea75a87831132aced4247. --- system/libraries/Session/drivers/Session_files_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index ff1553f84..a4f1b9f2f 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -261,7 +261,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // If the filename doesn't match this pattern, it's either not a session file or is not ours if ( ! preg_match('/(?:[0-9a-f]{32})?[0-9a-f]{40}$/i', $file) OR ! is_file($this->_config['save_path'].DIRECTORY_SEPARATOR.$file) - OR ($mtime = fileatime($this->_config['save_path'].DIRECTORY_SEPARATOR.$file)) === FALSE + OR ($mtime = filemtime($this->_config['save_path'].DIRECTORY_SEPARATOR.$file)) === FALSE OR $mtime > $ts) { continue; -- cgit v1.2.3-24-g4f1b From bdb96ca1b1dbfc1791172fd169d7751cbc4d7d55 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 28 Oct 2014 00:13:31 +0200 Subject: [ci skip] Switch to MIT license; close #3293 --- system/libraries/Session/Session.php | 39 ++++++++++++++-------- .../libraries/Session/drivers/Session_cookie.php | 39 ++++++++++++++-------- .../libraries/Session/drivers/Session_native.php | 39 ++++++++++++++-------- 3 files changed, 75 insertions(+), 42 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 905352bb3..3b26a2f17 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -4,24 +4,35 @@ * * An open source application development framework for PHP 5.2.4 or newer * - * NOTICE OF LICENSE + * This content is released under the MIT License (MIT) * - * Licensed under the Open Software License version 3.0 + * Copyright (c) 2014, British Columbia Institute of Technology * - * 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: - * http://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to obtain it - * through the world wide web, please send an email to - * licensing@ellislab.com so we can send you a copy immediately. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * @package CodeIgniter - * @author EllisLab Dev Team + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, 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 2.0 + * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link http://codeigniter.com + * @since Version 2.0.0 * @filesource */ defined('BASEPATH') OR exit('No direct script access allowed'); diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 566c40bd8..0001dc2d8 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -4,24 +4,35 @@ * * An open source application development framework for PHP 5.2.4 or newer * - * NOTICE OF LICENSE + * This content is released under the MIT License (MIT) * - * Licensed under the Open Software License version 3.0 + * Copyright (c) 2014, British Columbia Institute of Technology * - * 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: - * http://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to obtain it - * through the world wide web, please send an email to - * licensing@ellislab.com so we can send you a copy immediately. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * @package CodeIgniter - * @author EllisLab Dev Team + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, 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 + * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link http://codeigniter.com + * @since Version 1.0.0 * @filesource */ defined('BASEPATH') OR exit('No direct script access allowed'); diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 4104652b8..995f5a768 100644 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -4,24 +4,35 @@ * * An open source application development framework for PHP 5.2.4 or newer * - * NOTICE OF LICENSE + * This content is released under the MIT License (MIT) * - * Licensed under the Open Software License version 3.0 + * Copyright (c) 2014, British Columbia Institute of Technology * - * 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: - * http://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to obtain it - * through the world wide web, please send an email to - * licensing@ellislab.com so we can send you a copy immediately. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * @package CodeIgniter - * @author EllisLab Dev Team + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, 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 + * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link http://codeigniter.com + * @since Version 1.0.0 * @filesource */ defined('BASEPATH') OR exit('No direct script access allowed'); -- cgit v1.2.3-24-g4f1b From 7474a6799b44e4988b6a7a4adcc2901ec0b993b4 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 31 Oct 2014 23:35:32 +0200 Subject: #3073 (feature/session): Fix session_regenerate_id() issues --- system/libraries/Session/Session_driver.php | 10 ++++++ .../Session/drivers/Session_database_driver.php | 14 ++++++++ .../Session/drivers/Session_files_driver.php | 40 +++++++++++++--------- .../Session/drivers/Session_memcached_driver.php | 26 ++++++++++++-- .../Session/drivers/Session_redis_driver.php | 32 ++++++++++++----- 5 files changed, 95 insertions(+), 27 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index fb695dade..ad64e238a 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -53,6 +53,16 @@ abstract class CI_Session_driver implements SessionHandlerInterface { */ protected $_lock = FALSE; + /** + * Read session ID + * + * Used to detect session_regenerate_id() calls because PHP only calls + * write() after regenerating the ID. + * + * @var string + */ + protected $_session_id; + // ------------------------------------------------------------------------ /** diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index e3a3c505e..9e74605bc 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -111,6 +111,9 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if ($this->_get_lock($session_id) !== FALSE) { + // Needed by write() to detect session_regenerate_id() calls + $this->_session_id = $session_id; + $this->_db ->select('data') ->from($this->_config['save_path']) @@ -142,6 +145,17 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { return FALSE; } + // Was the ID regenerated? + elseif ($session_id !== $this->_session_id) + { + if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) + { + return FALSE; + } + + $this->_row_exists = FALSE; + $this->_session_id = $session_id; + } if ($this->_row_exists === FALSE) { diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index ff1553f84..3d6fa6322 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -114,36 +114,37 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // which re-reads session data if ($this->_file_handle === NULL) { - $this->_file_path .= $session_id; - // Just using fopen() with 'c+b' mode would be perfect, but it is only // available since PHP 5.2.6 and we have to set permissions for new files, // so we'd have to hack around this ... - if (($this->_file_new = ! file_exists($this->_file_path)) === TRUE) + if (($this->_file_new = ! file_exists($this->_file_path.$session_id)) === TRUE) { - if (($this->_file_handle = fopen($this->_file_path, 'w+b')) === FALSE) + if (($this->_file_handle = fopen($this->_file_path.$session_id, 'w+b')) === FALSE) { - log_message('error', "Session: File '".$this->_file_path."' doesn't exist and cannot be created."); + log_message('error', "Session: File '".$this->_file_path.$session_id."' doesn't exist and cannot be created."); return FALSE; } } - elseif (($this->_file_handle = fopen($this->_file_path, 'r+b')) === FALSE) + elseif (($this->_file_handle = fopen($this->_file_path.$session_id, 'r+b')) === FALSE) { - log_message('error', "Session: Unable to open file '".$this->_file_path."'."); + log_message('error', "Session: Unable to open file '".$this->_file_path.$session_id."'."); return FALSE; } if (flock($this->_file_handle, LOCK_EX) === FALSE) { - log_message('error', "Session: Unable to obtain lock for file '".$this->_file_path."'."); + log_message('error', "Session: Unable to obtain lock for file '".$this->_file_path.$session_id."'."); fclose($this->_file_handle); $this->_file_handle = NULL; return FALSE; } + // Needed by write() to detect session_regenerate_id() calls + $this->_session_id = $session_id; + if ($this->_file_new) { - chmod($this->_file_path, 0600); + chmod($this->_file_path.$session_id, 0600); $this->_fingerprint = md5(''); return ''; } @@ -154,7 +155,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle } $session_data = ''; - for ($read = 0, $length = filesize($this->_file_path); $read < $length; $read += strlen($buffer)) + for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += strlen($buffer)) { if (($buffer = fread($this->_file_handle, $length - $read)) === FALSE) { @@ -170,6 +171,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle public function write($session_id, $session_data) { + // If the two IDs don't match, we have a session_regenerate_id() call + // and we need to close the old handle and open a new one + if ($session_id !== $this->_session_id && ( ! $this->close() OR $this->read($session_id) === FALSE)) + { + return FALSE; + } + if ( ! is_resource($this->_file_handle)) { return FALSE; @@ -178,7 +186,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { return ($this->_file_new) ? TRUE - : touch($this->_file_path); + : touch($this->_file_path.$session_id); } if ( ! $this->_file_new) @@ -218,11 +226,11 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle flock($this->_file_handle, LOCK_UN); fclose($this->_file_handle); - $this->_file_handle = $this->_file_new = NULL; + $this->_file_handle = $this->_file_new = $this->_session_id = NULL; return TRUE; } - return FALSE; + return TRUE; } // ------------------------------------------------------------------------ @@ -231,13 +239,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { if ($this->close()) { - return unlink($this->_file_path) && $this->_cookie_destroy(); + return unlink($this->_file_path.$session_id) && $this->_cookie_destroy(); } elseif ($this->_file_path !== NULL) { clearstatcache(); - return file_exists($this->_file_path) - ? (unlink($this->_file_path) && $this->_cookie_destroy()) + return file_exists($this->_file_path.$session_id) + ? (unlink($this->_file_path.$session_id) && $this->_cookie_destroy()) : TRUE; } diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 318c11afa..8905e8d6f 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -133,6 +133,9 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if (isset($this->_memcached) && $this->_get_lock($session_id)) { + // Needed by write() to detect session_regenerate_id() calls + $this->_session_id = $session_id; + $session_data = (string) $this->_memcached->get($this->_key_prefix.$session_id); $this->_fingerprint = md5($session_data); return $session_data; @@ -143,7 +146,23 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa public function write($session_id, $session_data) { - if (isset($this->_memcached, $this->_lock_key)) + if ( ! isset($this->_memcached)) + { + return FALSE; + } + // Was the ID regenerated? + elseif ($session_id !== $this->_session_id) + { + if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) + { + return FALSE; + } + + $this->_fingerprint = md5(''); + $this->_session_id = $session_id; + } + + if (isset($this->_lock_key)) { $this->_memcached->replace($this->_lock_key, time(), 5); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) @@ -189,16 +208,17 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if (isset($this->_memcached, $this->_lock_key)) { $this->_memcached->delete($this->_key_prefix.$session_id); - return ($this->_cookie_destroy() && $this->close()); + return $this->_cookie_destroy(); } - return $this->close(); + return FALSE; } // ------------------------------------------------------------------------ public function gc($maxlifetime) { + // Not necessary, Memcached takes care of that. return TRUE; } diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index ef18defe2..bc6150d2d 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -135,6 +135,9 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if (isset($this->_redis) && $this->_get_lock($session_id)) { + // Needed by write() to detect session_regenerate_id() calls + $this->_session_id = $session_id; + $session_data = (string) $this->_redis->get($this->_key_prefix.$session_id); $this->_fingerprint = md5($session_data); return $session_data; @@ -145,7 +148,23 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle public function write($session_id, $session_data) { - if (isset($this->_redis, $this->_lock_key)) + if ( ! isset($this->_redis)) + { + return FALSE; + } + // Was the ID regenerated? + elseif ($session_id !== $this->_session_id) + { + if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) + { + return FALSE; + } + + $this->_fingerprint = md5(''); + $this->_session_id = $session_id; + } + + if (isset($this->_lock_key)) { $this->_redis->setTimeout($this->_lock_key, 5); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) @@ -190,7 +209,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return TRUE; } - return FALSE; + return TRUE; } // ------------------------------------------------------------------------ @@ -204,20 +223,17 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle log_message('debug', 'Session: Redis::delete() expected to return 1, got '.var_export($result, TRUE).' instead.'); } - return ($this->_cookie_destroy() && $this->close()); + return $this->_cookie_destroy(); } - return $this->close(); + return FALSE; } // ------------------------------------------------------------------------ public function gc($maxlifetime) { - // TODO: keys()/getKeys() is said to be performance-intensive, - // although it supports patterns (*, [charlist] at the very least). - // scan() seems to be recommended, but requires redis 2.8 - // Not sure if we need any of these though, as we set keys with expire times + // Not necessary, Redis takes care of that. return TRUE; } -- cgit v1.2.3-24-g4f1b From 305186d50e80d643645dd171abc4790fd4b57b61 Mon Sep 17 00:00:00 2001 From: Shakespeare2000 Date: Sun, 2 Nov 2014 11:28:47 +0100 Subject: Fix write() for session_regenerate_id(TRUE) Switching the if statements, because destroy() already removed the lock. --- system/libraries/Session/drivers/Session_database_driver.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 9e74605bc..efdec40e5 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -141,12 +141,8 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan public function write($session_id, $session_data) { - if ($this->_lock === FALSE) - { - return FALSE; - } // Was the ID regenerated? - elseif ($session_id !== $this->_session_id) + if ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { @@ -156,6 +152,10 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_row_exists = FALSE; $this->_session_id = $session_id; } + elseif ($this->_lock === FALSE) + { + return FALSE; + } if ($this->_row_exists === FALSE) { -- cgit v1.2.3-24-g4f1b From 8e60b9a40a01a021e865b24e7d709e9e6ede0beb Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 4 Nov 2014 11:08:06 +0200 Subject: #3073 (feature/session): Implement automatic ID regeneration --- system/libraries/Session/Session.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 7908badf8..f250c3d64 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -122,9 +122,20 @@ class CI_Session { session_start(); + if (($regenerate_time = config_item('sess_time_to_update')) > 0) + { + if ( ! isset($_SESSION['__ci_last_regenerate'])) + { + $_SESSION['__ci_last_regenerate'] = time(); + } + elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time)) + { + $this->sess_regenerate(FALSE); + } + } // Another work-around ... PHP doesn't seem to send the session cookie // unless it is being currently created or regenerated - if (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id()) + elseif (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id()) { setcookie( $this->_config['cookie_name'], @@ -138,7 +149,6 @@ class CI_Session { } $this->_ci_init_vars(); - /* Need to test if this is necessary for a custom driver or if it's only relevant to PHP's own files handler. @@ -584,6 +594,7 @@ class CI_Session { */ public function sess_regenerate($destroy = FALSE) { + $_SESSION['__ci_last_regenerate'] = time(); session_regenerate_id($destroy); } -- cgit v1.2.3-24-g4f1b From ff37ffe164443e53b24d529f967a1bdf065bff3a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 4 Nov 2014 12:28:57 +0200 Subject: #3073 (feature/session): Don't regenerate IDs on AJAX requests --- system/libraries/Session/Session.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index f250c3d64..bf11cd181 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -122,7 +122,11 @@ class CI_Session { session_start(); - if (($regenerate_time = config_item('sess_time_to_update')) > 0) + // Is session ID auto-regeneration configured? (ignoring ajax requests) + if ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) + && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest' + && $regenerate_time = config_item('sess_time_to_update')) > 0 + ) { if ( ! isset($_SESSION['__ci_last_regenerate'])) { -- cgit v1.2.3-24-g4f1b From de5c246dfcaf1c92e8b77830249df44b3cca2e8c Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 4 Nov 2014 12:31:03 +0200 Subject: #3073 (feature/session): Fix a typo from ff37ffe164443e53b24d529f967a1bdf065bff3a --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index bf11cd181..e6ba341dd 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -125,7 +125,7 @@ class CI_Session { // Is session ID auto-regeneration configured? (ignoring ajax requests) if ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest' - && $regenerate_time = config_item('sess_time_to_update')) > 0 + && ($regenerate_time = config_item('sess_time_to_update')) > 0 ) { if ( ! isset($_SESSION['__ci_last_regenerate'])) -- cgit v1.2.3-24-g4f1b From a8f29f9ddaeac5cee582a51ce7f255459e1ca711 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 10 Nov 2014 18:55:55 +0200 Subject: #3073 (feature/session): (Try to) fix memcached driver --- system/libraries/Session/drivers/Session_memcached_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 8905e8d6f..2ee922f94 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -114,7 +114,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa } else { - $server_list[] = $server['host'].':'.$server['port']; + $server_list[] = $match[1].':'.$match[2]; } } -- cgit v1.2.3-24-g4f1b From 4f50256a84e8052fc3356683f28286d36f8a322c Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 10 Nov 2014 19:18:33 +0200 Subject: #3073 (feature/session): Enable Memcached::OPT_BINARY_PROTOCOL Otherwise Memcached::touch() doesn't work. --- system/libraries/Session/drivers/Session_memcached_driver.php | 1 + 1 file changed, 1 insertion(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 2ee922f94..6652addee 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -86,6 +86,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa public function open($save_path, $name) { $this->_memcached = new Memcached(); + $this->_memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, TRUE); // required for touch() usage $server_list = array(); foreach ($this->_memcached->getServerList() as $server) { -- cgit v1.2.3-24-g4f1b From 46f2f26d7cc43c548ea3f2978f532754b3476d5f Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 11 Nov 2014 14:37:51 +0200 Subject: [ci skip] Update system/libraries/Session/ with the MIT license notice --- .../libraries/Session/SessionHandlerInterface.php | 45 +++++++++++++-------- system/libraries/Session/Session_driver.php | 45 +++++++++++++-------- .../Session/drivers/Session_database_driver.php | 45 +++++++++++++-------- .../Session/drivers/Session_files_driver.php | 47 +++++++++++++--------- .../Session/drivers/Session_memcached_driver.php | 45 +++++++++++++-------- .../Session/drivers/Session_redis_driver.php | 45 +++++++++++++-------- 6 files changed, 169 insertions(+), 103 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php index 7473ff8ec..06f252d7e 100644 --- a/system/libraries/Session/SessionHandlerInterface.php +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -4,24 +4,35 @@ * * An open source application development framework for PHP 5.2.4 or newer * - * NOTICE OF LICENSE + * This content is released under the MIT License (MIT) * - * Licensed under the Open Software License version 3.0 + * Copyright (c) 2014, British Columbia Institute of Technology * - * 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: - * http://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to obtain it - * through the world wide web, please send an email to - * licensing@ellislab.com so we can send you a copy immediately. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * @package CodeIgniter - * @author EllisLab Dev Team + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, 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 3.0 + * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link http://codeigniter.com + * @since Version 3.0.0 * @filesource */ defined('BASEPATH') OR exit('No direct script access allowed'); @@ -31,11 +42,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * * PHP 5.4 compatibility interface * - * @package CodeIgniter + * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @author Andrey Andreev + * @link http://codeigniter.com/user_guide/libraries/sessions.html */ interface SessionHandlerInterface { diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index ad64e238a..0eca83905 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -4,24 +4,35 @@ * * An open source application development framework for PHP 5.2.4 or newer * - * NOTICE OF LICENSE + * This content is released under the MIT License (MIT) * - * Licensed under the Open Software License version 3.0 + * Copyright (c) 2014, British Columbia Institute of Technology * - * 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: - * http://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to obtain it - * through the world wide web, please send an email to - * licensing@ellislab.com so we can send you a copy immediately. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * @package CodeIgniter - * @author EllisLab Dev Team + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, 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 3.0 + * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link http://codeigniter.com + * @since Version 3.0.0 * @filesource */ defined('BASEPATH') OR exit('No direct script access allowed'); @@ -29,11 +40,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); /** * CodeIgniter Session Driver Class * - * @package CodeIgniter + * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @author Andrey Andreev + * @link http://codeigniter.com/user_guide/libraries/sessions.html */ abstract class CI_Session_driver implements SessionHandlerInterface { diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index efdec40e5..a6c411b34 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -4,24 +4,35 @@ * * An open source application development framework for PHP 5.2.4 or newer * - * NOTICE OF LICENSE + * This content is released under the MIT License (MIT) * - * Licensed under the Open Software License version 3.0 + * Copyright (c) 2014, British Columbia Institute of Technology * - * 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: - * http://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to obtain it - * through the world wide web, please send an email to - * licensing@ellislab.com so we can send you a copy immediately. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * @package CodeIgniter - * @author Andrey Andreev + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, 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 3.0 + * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link http://codeigniter.com + * @since Version 3.0.0 * @filesource */ defined('BASEPATH') OR exit('No direct script access allowed'); @@ -29,11 +40,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); /** * CodeIgniter Session Database Driver * - * @package CodeIgniter + * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @author Andrey Andreev + * @link http://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_database_driver extends CI_Session_driver implements SessionHandlerInterface { diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 973337753..b82d9f55d 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -4,36 +4,47 @@ * * An open source application development framework for PHP 5.2.4 or newer * - * NOTICE OF LICENSE + * This content is released under the MIT License (MIT) * - * Licensed under the Open Software License version 3.0 + * Copyright (c) 2014, British Columbia Institute of Technology * - * 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: - * http://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to obtain it - * through the world wide web, please send an email to - * licensing@ellislab.com so we can send you a copy immediately. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * @package CodeIgniter - * @author Andrey Andreev + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, 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 3.0 + * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link http://codeigniter.com + * @since Version 3.0.0 * @filesource - */ +*/ defined('BASEPATH') OR exit('No direct script access allowed'); /** * CodeIgniter Session Files Driver * - * @package CodeIgniter + * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @author Andrey Andreev + * @link http://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_files_driver extends CI_Session_driver implements SessionHandlerInterface { diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 6652addee..3da7ddd6d 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -4,24 +4,35 @@ * * An open source application development framework for PHP 5.2.4 or newer * - * NOTICE OF LICENSE + * This content is released under the MIT License (MIT) * - * Licensed under the Open Software License version 3.0 + * Copyright (c) 2014, British Columbia Institute of Technology * - * 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: - * http://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to obtain it - * through the world wide web, please send an email to - * licensing@ellislab.com so we can send you a copy immediately. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * @package CodeIgniter - * @author Andrey Andreev + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, 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 3.0 + * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link http://codeigniter.com + * @since Version 3.0.0 * @filesource */ defined('BASEPATH') OR exit('No direct script access allowed'); @@ -29,11 +40,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); /** * CodeIgniter Session Memcached Driver * - * @package CodeIgniter + * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @author Andrey Andreev + * @link http://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHandlerInterface { diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index bc6150d2d..e8eac9857 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -4,24 +4,35 @@ * * An open source application development framework for PHP 5.2.4 or newer * - * NOTICE OF LICENSE + * This content is released under the MIT License (MIT) * - * Licensed under the Open Software License version 3.0 + * Copyright (c) 2014, British Columbia Institute of Technology * - * 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: - * http://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to obtain it - * through the world wide web, please send an email to - * licensing@ellislab.com so we can send you a copy immediately. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * @package CodeIgniter - * @author Andrey Andreev + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @package CodeIgniter + * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, 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 3.0 + * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @license http://opensource.org/licenses/MIT MIT License + * @link http://codeigniter.com + * @since Version 3.0.0 * @filesource */ defined('BASEPATH') OR exit('No direct script access allowed'); @@ -29,11 +40,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); /** * CodeIgniter Session Redis Driver * - * @package CodeIgniter + * @package CodeIgniter * @subpackage Libraries * @category Sessions - * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @author Andrey Andreev + * @link http://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandlerInterface { -- cgit v1.2.3-24-g4f1b From 562e39bab43181fb709aeaf4dee14bf481a2cc6a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 12 Nov 2014 15:38:58 +0200 Subject: #3073 (feature/session): Validate incoming session IDs --- system/libraries/Session/Session.php | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 293811ec8..1d93cb1c8 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -122,13 +122,15 @@ class CI_Session { return; } - // Work-around for PHP bug #66827 (https://bugs.php.net/bug.php?id=66827) - // - // The session ID sanitizer doesn't check for the value type and blindly does - // an implicit cast to string, which triggers an 'Array to string' E_NOTICE. - if (isset($_COOKIE[$this->_cookie_name]) && ! is_string($_COOKIE[$this->_cookie_name])) + // Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers + if (isset($_COOKIE[$this->_config['cookie_name']]) + && ( + ! is_string($_COOKIE[$this->_config['cookie_name']]) + OR ! preg_match('/^[0-9a-f]{40}$/', $_COOKIE[$this->_config['cookie_name']]) + ) + ) { - unset($_COOKIE[$this->_cookie_name]); + unset($_COOKIE[$this->_config['cookie_name']]); } session_start(); @@ -164,21 +166,6 @@ class CI_Session { } $this->_ci_init_vars(); -/* - Need to test if this is necessary for a custom driver or if it's only - relevant to PHP's own files handler. - - https://bugs.php.net/bug.php?id=65475 - do this after session is started: - if (is_php('5.5.2') && ! is_php('5.5.4')) - { - $session_id = session_id(); - if ($_COOKIE[$this->_cookie_name] !== $session_id && file_exists(teh file)) - { - unlink(); - } - } -*/ log_message('debug', "Session: Class initialized using '".$this->_driver."' driver."); } -- cgit v1.2.3-24-g4f1b From ed3fc511e4e5aa7b171fd806e73401ace2497b32 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 18 Nov 2014 11:12:35 +0200 Subject: Force ORDER BY usage with OFFSET-FETCH on SQL Server Close #3128 Close #3332 Close #3334 Close #3335 --- system/libraries/Session/drivers/Session_cookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 0001dc2d8..21ded899a 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -486,7 +486,7 @@ class CI_Session_cookie extends CI_Session_driver { $db_cache = $this->CI->db->cache_on; $this->CI->db->cache_off(); - $query = $this->CI->db->limit(1)->get($this->sess_table_name); + $query = $this->CI->db->get($this->sess_table_name); // Was caching in effect? if ($db_cache) -- cgit v1.2.3-24-g4f1b From cd94dd7e1d8969658810ccc4158a75d2936d0a44 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 9 Dec 2014 17:38:56 +0200 Subject: #3073 (feature/session): Allow custom drivers without the CI_ or MY_ prefix --- system/libraries/Session/Session.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 1d93cb1c8..4fa9fd248 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -194,6 +194,17 @@ class CI_Session { } $class = 'Session_'.$driver.'_driver'; + + // Allow custom drivers without the CI_ or MY_ prefix + if ( ! class_exists($class, FALSE) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$class.'.php')) + { + require_once($file_path); + if (class_exists($class, FALSE)) + { + return $class; + } + } + if ( ! class_exists('CI_'.$class, FALSE)) { if (file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$class.'.php') OR file_exists($file_path = BASEPATH.'libraries/Session/drivers/'.$class.'.php')) @@ -201,7 +212,7 @@ class CI_Session { require_once($file_path); } - if ( ! class_exists('CI_'.$class, FALSE)) + if ( ! class_exists('CI_'.$class, FALSE) && ! class_exists($class, FALSE)) { log_message('error', "Session: Configured driver '".$driver."' was not found. Aborting."); return FALSE; -- cgit v1.2.3-24-g4f1b From fe9309d22c1b088f5363954d6dac013c8c955894 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 9 Jan 2015 17:48:58 +0200 Subject: Bulk (mostly documentation) update - Remove PHP version from license notices - Bump year number in copyright notices - Recommend PHP 5.4 or newer to be used - Tell Travis-CI to test on PHP 5.3.0 instead of the latest 5.3 version Related: #3450 --- system/libraries/Session/Session.php | 8 ++++---- system/libraries/Session/drivers/Session_cookie.php | 6 +++--- system/libraries/Session/drivers/Session_native.php | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 3b26a2f17..452afd5e5 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 or newer + * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014, British Columbia Institute of Technology + * Copyright (c) 2014 - 2015, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 2.0.0 @@ -40,7 +40,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); /** * CodeIgniter Session Class * - * The user interface defined by EllisLabs, now with puggable drivers to manage different storage mechanisms. + * The user interface defined by EllisLab, now with puggable drivers to manage different storage mechanisms. * By default, the cookie session driver will load, but the 'sess_driver' config/param item (see above) can be * used to specify the 'native' driver, or any other you might create. * Once loaded, this driver setup is a drop-in replacement for the former CI_Session library, taking its place as the diff --git a/system/libraries/Session/drivers/Session_cookie.php b/system/libraries/Session/drivers/Session_cookie.php index 21ded899a..c0e62affa 100644 --- a/system/libraries/Session/drivers/Session_cookie.php +++ b/system/libraries/Session/drivers/Session_cookie.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 or newer + * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014, British Columbia Institute of Technology + * Copyright (c) 2014 - 2015, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 1.0.0 diff --git a/system/libraries/Session/drivers/Session_native.php b/system/libraries/Session/drivers/Session_native.php index 995f5a768..c95e7f23f 100644 --- a/system/libraries/Session/drivers/Session_native.php +++ b/system/libraries/Session/drivers/Session_native.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 or newer + * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014, British Columbia Institute of Technology + * Copyright (c) 2014 - 2015, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 1.0.0 -- cgit v1.2.3-24-g4f1b From bf6b11d7d9732dbc46ca0ea897cfd4023fff7844 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 12 Jan 2015 17:27:12 +0200 Subject: [ci skip] Remove PHP version from license notices and bump year --- system/libraries/Session/SessionHandlerInterface.php | 6 +++--- system/libraries/Session/Session_driver.php | 6 +++--- system/libraries/Session/drivers/Session_database_driver.php | 6 +++--- system/libraries/Session/drivers/Session_files_driver.php | 6 +++--- system/libraries/Session/drivers/Session_memcached_driver.php | 6 +++--- system/libraries/Session/drivers/Session_redis_driver.php | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php index 06f252d7e..2050e1e4d 100644 --- a/system/libraries/Session/SessionHandlerInterface.php +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 or newer + * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014, British Columbia Institute of Technology + * Copyright (c) 2014 - 2015, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 0eca83905..944659c4c 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 or newer + * An open source application development framework for PHP 5.2.4 * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014, British Columbia Institute of Technology + * Copyright (c) 2014 - 2015, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index a6c411b34..ec988912f 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 or newer + * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014, British Columbia Institute of Technology + * Copyright (c) 2014 - 2015, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index b82d9f55d..761eed46f 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 or newer + * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014, British Columbia Institute of Technology + * Copyright (c) 2014 - 2015, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 3da7ddd6d..e2b568f52 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 or newer + * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014, British Columbia Institute of Technology + * Copyright (c) 2014 - 2015, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index e8eac9857..cde587b97 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 or newer + * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014, British Columbia Institute of Technology + * Copyright (c) 2014 - 2015, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 -- cgit v1.2.3-24-g4f1b From 19c25249a9d4f379773d9def3390c2e44dde0a22 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 14 Jan 2015 22:13:36 +0200 Subject: Fix #3473 I don't know why I thought of semaphores in the first place ... --- system/libraries/Session/Session_driver.php | 30 +++++------------------------ 1 file changed, 5 insertions(+), 25 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 944659c4c..de1908ac6 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -107,34 +107,16 @@ abstract class CI_Session_driver implements SessionHandlerInterface { /** * Get lock * - * A default locking mechanism via semaphores, if ext/sysvsem is available. - * - * Drivers will usually override this and only fallback to it if no other - * locking mechanism is available. + * A dummy method allowing drivers with no locking functionality + * (databases other than PostgreSQL and MySQL) to act as if they + * do acquire a lock. * * @param string $session_id * @return bool */ protected function _get_lock($session_id) { - if ( ! extension_loaded('sysvsem')) - { - $this->_lock = TRUE; - return TRUE; - } - - if (($this->_lock = sem_get($session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : ''), 1, 0644)) === FALSE) - { - return FALSE; - } - - if ( ! sem_acquire($this->_lock)) - { - sem_remove($this->_lock); - $this->_lock = FALSE; - return FALSE; - } - + $this->_lock = TRUE; return TRUE; } @@ -147,10 +129,8 @@ abstract class CI_Session_driver implements SessionHandlerInterface { */ protected function _release_lock() { - if (extension_loaded('sysvsem') && $this->_lock) + if ($this->_lock) { - sem_release($this->_lock); - sem_remove($this->_lock); $this->_lock = FALSE; } -- cgit v1.2.3-24-g4f1b From e9ca012ca64e6a589de1425052d4c733404291d0 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 15 Jan 2015 17:42:17 +0200 Subject: feature/session (#3073): Improve PostgreSQL storage Use a TEXT field with Base64-encoded data under PostgreSQL. Also, renamed a variable. --- .../Session/drivers/Session_database_driver.php | 28 ++++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index ec988912f..d378d537f 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -67,7 +67,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan * * @var string */ - protected $_lock_driver = 'semaphore'; + protected $_platform; // ------------------------------------------------------------------------ @@ -97,11 +97,11 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $db_driver = $this->_db->dbdriver.(empty($this->_db->subdriver) ? '' : '_'.$this->_db->subdriver); if (strpos($db_driver, 'mysql') !== FALSE) { - $this->_lock_driver = 'mysql'; + $this->_platform = 'mysql'; } elseif (in_array($db_driver, array('postgre', 'pdo_pgsql'), TRUE)) { - $this->_lock_driver = 'postgre'; + $this->_platform = 'postgre'; } isset($this->_config['save_path']) OR $this->_config['save_path'] = config_item('sess_table_name'); @@ -141,7 +141,15 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return ''; } - $this->_fingerprint = md5(rtrim($result->data)); + // PostgreSQL's variant of a BLOB datatype is Bytea, which is a + // PITA to work with, so we use base64-encoded data in a TEXT + // field instead. + if ($this->_platform === 'postgre') + { + $result = base64_decode(rtrim($result->data)); + } + + $this->_fingerprint = md5(rtrim($result)); $this->_row_exists = TRUE; return $result->data; } @@ -170,7 +178,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if ($this->_row_exists === FALSE) { - if ($this->_db->insert($this->_config['save_path'], array('id' => $session_id, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'timestamp' => time(), 'data' => $session_data))) + if ($this->_db->insert($this->_config['save_path'], array('id' => $session_id, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'timestamp' => time(), 'data' => base64_encode($session_data)))) { $this->_fingerprint = md5($session_data); return $this->_row_exists = TRUE; @@ -187,7 +195,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $update_data = ($this->_fingerprint === md5($session_data)) ? array('timestamp' => time()) - : array('timestamp' => time(), 'data' => $session_data); + : array('timestamp' => time(), 'data' => base64_encode($session_data)); if ($this->_db->update($this->_config['save_path'], $update_data)) { @@ -238,7 +246,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan protected function _get_lock($session_id) { - if ($this->_lock_driver === 'mysql') + if ($this->_platform === 'mysql') { $arg = $session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : ''); if ($this->_db->query("SELECT GET_LOCK('".$arg."', 10) AS ci_session_lock")->row()->ci_session_lock) @@ -249,7 +257,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return FALSE; } - elseif ($this->_lock_driver === 'postgre') + elseif ($this->_platform === 'postgre') { $arg = "hashtext('".$session_id."')".($this->_config['match_ip'] ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : ''); if ($this->_db->simple_query('SELECT pg_advisory_lock('.$arg.')')) @@ -273,7 +281,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return TRUE; } - if ($this->_lock_driver === 'mysql') + if ($this->_platform === 'mysql') { if ($this->_db->query("SELECT RELEASE_LOCK('".$this->_lock."') AS ci_session_lock")->row()->ci_session_lock) { @@ -283,7 +291,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return FALSE; } - elseif ($this->_lock_driver === 'postgre') + elseif ($this->_platform === 'postgre') { if ($this->_db->simple_query('SELECT pg_advisory_unlock('.$this->_lock.')')) { -- cgit v1.2.3-24-g4f1b From 7f8eb360e80449c81be425f06cef60666e32fe21 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 15 Jan 2015 18:01:41 +0200 Subject: [ci skip] Add a note about sess_table_name --- system/libraries/Session/drivers/Session_database_driver.php | 1 + 1 file changed, 1 insertion(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index d378d537f..42ff96b7c 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -104,6 +104,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_platform = 'postgre'; } + // Note: BC work-around for the old 'sess_table_name' setting, should be removed in the future. isset($this->_config['save_path']) OR $this->_config['save_path'] = config_item('sess_table_name'); } -- cgit v1.2.3-24-g4f1b From d0122559db3ca45523c7344c223bb28848fd3514 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 15 Jan 2015 21:25:58 +0200 Subject: feature/session (#3073): Fix an error from previous patch --- system/libraries/Session/drivers/Session_database_driver.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 42ff96b7c..6c667b01f 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -145,12 +145,11 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // PostgreSQL's variant of a BLOB datatype is Bytea, which is a // PITA to work with, so we use base64-encoded data in a TEXT // field instead. - if ($this->_platform === 'postgre') - { - $result = base64_decode(rtrim($result->data)); - } + $result = ($this->_platform === 'postgre') + ? base64_decode(rtrim($result->data)) + : $result->data; - $this->_fingerprint = md5(rtrim($result)); + $this->_fingerprint = md5($result); $this->_row_exists = TRUE; return $result->data; } -- cgit v1.2.3-24-g4f1b From 74009756ea938c2bde8147cb757d9a4835b78e6d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 15 Jan 2015 21:36:25 +0200 Subject: feature/session (#3073): Third time is the charm --- system/libraries/Session/drivers/Session_database_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 6c667b01f..46780b0db 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -151,7 +151,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_fingerprint = md5($result); $this->_row_exists = TRUE; - return $result->data; + return $result; } $this->_fingerprint = md5(''); -- cgit v1.2.3-24-g4f1b From 5231d3267269d7fd8e84b1faf637cef3ba2f1dec Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 19 Jan 2015 02:29:49 +0200 Subject: feature/session (#3073): Only PostgreSQL data should be base64-encoded --- .../Session/drivers/Session_database_driver.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 46780b0db..e27c96595 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -178,7 +178,14 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if ($this->_row_exists === FALSE) { - if ($this->_db->insert($this->_config['save_path'], array('id' => $session_id, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'timestamp' => time(), 'data' => base64_encode($session_data)))) + $insert_data = array( + 'id' => $session_id, + 'ip_address' => $_SERVER['REMOTE_ADDR'], + 'timestamp' => time(), + 'data' => ($this->_platform === 'postgre' ? base64_encode($session_data) : $session_data) + ); + + if ($this->_db->insert($this->_config['save_path'], $insert_data)) { $this->_fingerprint = md5($session_data); return $this->_row_exists = TRUE; @@ -193,9 +200,13 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } - $update_data = ($this->_fingerprint === md5($session_data)) - ? array('timestamp' => time()) - : array('timestamp' => time(), 'data' => base64_encode($session_data)); + $update_data = array('timestamp' => $time); + if ($this->_fingerprint !== md5($session_data)) + { + $update_data['data'] = ($this->_platform === 'postgre') + ? base64_encode($session_data) + : $session_data; + } if ($this->_db->update($this->_config['save_path'], $update_data)) { -- cgit v1.2.3-24-g4f1b From c33c3adff7d0c36208fa9c3a1dc364fa7f23f07d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 19 Jan 2015 10:54:21 +0200 Subject: feature/session (#3073): Fix non-existing variable error --- system/libraries/Session/drivers/Session_database_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index e27c96595..055a1a613 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -200,7 +200,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } - $update_data = array('timestamp' => $time); + $update_data = array('timestamp' => time()); if ($this->_fingerprint !== md5($session_data)) { $update_data['data'] = ($this->_platform === 'postgre') -- cgit v1.2.3-24-g4f1b From b4b215e6baed4e61a7e1143e2ff22713846b0667 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 19 Jan 2015 11:59:11 +0200 Subject: feature/session (#3073): Add CI_Session:: as reference to For backwards compatibility purposes. --- system/libraries/Session/Session.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 9c3b2b06c..4a96aa6b1 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -48,6 +48,13 @@ defined('BASEPATH') OR exit('No direct script access allowed'); */ class CI_Session { + /** + * Userdata array + * + * Just a reference to $_SESSION, for BC purposes. + */ + public $userdata; + protected $_driver = 'files'; protected $_config; @@ -341,6 +348,8 @@ class CI_Session { unset($_SESSION['__ci_vars']); } } + + $this->userdata =& $_SESSION; } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 10411fc94395bdf217e8bbae61e0af3a73d37325 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 19 Jan 2015 13:54:53 +0200 Subject: [ci skip] feature/session (#3073): Add missing method docblocks --- system/libraries/Session/Session.php | 10 ++++ system/libraries/Session/Session_driver.php | 8 +++ .../Session/drivers/Session_database_driver.php | 66 ++++++++++++++++++++++ .../Session/drivers/Session_files_driver.php | 51 +++++++++++++++++ .../Session/drivers/Session_memcached_driver.php | 66 ++++++++++++++++++++++ .../Session/drivers/Session_redis_driver.php | 66 ++++++++++++++++++++++ 6 files changed, 267 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 4a96aa6b1..5c61002a6 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -179,6 +179,16 @@ class CI_Session { // ------------------------------------------------------------------------ + /** + * CI Load Classes + * + * An internal method to load all possible dependency and extension + * classes. It kind of emulates the CI_Driver library, but is + * self-sufficient. + * + * @param string $driver Driver name + * @return string Driver class name + */ protected function _ci_load_classes($driver) { // PHP 5.4 compatibility diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index de1908ac6..c4fbde4f8 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -89,6 +89,14 @@ abstract class CI_Session_driver implements SessionHandlerInterface { // ------------------------------------------------------------------------ + /** + * Cookie destroy + * + * Internal method to force removal of a cookie by the client + * when session_destroy() is called. + * + * @return bool + */ protected function _cookie_destroy() { return setcookie( diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 055a1a613..87d80a2b0 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -110,6 +110,15 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // ------------------------------------------------------------------------ + /** + * Open + * + * Initializes the database connection + * + * @param string $save_path Table name + * @param string $name Session cookie name, unused + * @return bool + */ public function open($save_path, $name) { return empty($this->_db->conn_id) @@ -119,6 +128,14 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // ------------------------------------------------------------------------ + /** + * Read + * + * Reads session data and acquires a lock + * + * @param string $session_id Session ID + * @return string Serialized session data + */ public function read($session_id) { if ($this->_get_lock($session_id) !== FALSE) @@ -158,6 +175,17 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return ''; } + // ------------------------------------------------------------------------ + + /** + * Write + * + * Writes (create / update) session data + * + * @param string $session_id Session ID + * @param string $session_data Serialized session data + * @return bool + */ public function write($session_id, $session_data) { // Was the ID regenerated? @@ -219,6 +247,13 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // ------------------------------------------------------------------------ + /** + * Close + * + * Releases locks + * + * @return void + */ public function close() { return ($this->_lock) @@ -228,6 +263,14 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // ------------------------------------------------------------------------ + /** + * Destroy + * + * Destroys the current session. + * + * @param string $session_id Session ID + * @return bool + */ public function destroy($session_id) { if ($this->_lock) @@ -248,6 +291,14 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // ------------------------------------------------------------------------ + /** + * Garbage Collector + * + * Deletes expired sessions + * + * @param int $maxlifetime Maximum lifetime of sessions + * @return bool + */ public function gc($maxlifetime) { return $this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime)); @@ -255,6 +306,14 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // ------------------------------------------------------------------------ + /** + * Get lock + * + * Acquires a lock, depending on the underlying platform. + * + * @param string $session_id Session ID + * @return bool + */ protected function _get_lock($session_id) { if ($this->_platform === 'mysql') @@ -285,6 +344,13 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // ------------------------------------------------------------------------ + /** + * Release lock + * + * Releases a previously acquired lock + * + * @return bool + */ protected function _release_lock() { if ( ! $this->_lock) diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 761eed46f..95ab7f14c 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -101,6 +101,15 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Open + * + * Sanitizes the save_path directory. + * + * @param string $save_path Path to session files' directory + * @param string $name Session cookie name, unused + * @return bool + */ public function open($save_path, $name) { if ( ! is_dir($save_path) && ! mkdir($save_path, 0700, TRUE)) @@ -119,6 +128,14 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Read + * + * Reads session data and acquires a lock + * + * @param string $session_id Session ID + * @return string Serialized session data + */ public function read($session_id) { // This might seem weird, but PHP 5.6 introduces session_reset(), @@ -180,6 +197,17 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle return $session_data; } + // ------------------------------------------------------------------------ + + /** + * Write + * + * Writes (create / update) session data + * + * @param string $session_id Session ID + * @param string $session_data Serialized session data + * @return bool + */ public function write($session_id, $session_data) { // If the two IDs don't match, we have a session_regenerate_id() call @@ -230,6 +258,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Close + * + * Releases locks and closes file descriptor. + * + * @return void + */ public function close() { if (is_resource($this->_file_handle)) @@ -246,6 +281,14 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Destroy + * + * Destroys the current session. + * + * @param string $session_id Session ID + * @return bool + */ public function destroy($session_id) { if ($this->close()) @@ -265,6 +308,14 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Garbage Collector + * + * Deletes expired sessions + * + * @param int $maxlifetime Maximum lifetime of sessions + * @return bool + */ public function gc($maxlifetime) { if ( ! is_dir($this->_config['save_path']) OR ($files = scandir($this->_config['save_path'])) === FALSE) diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index e2b568f52..683bb5c69 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -94,6 +94,15 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa // ------------------------------------------------------------------------ + /** + * Open + * + * Sanitizes save_path and initializes connections. + * + * @param string $save_path Server path(s) + * @param string $name Session cookie name, unused + * @return bool + */ public function open($save_path, $name) { $this->_memcached = new Memcached(); @@ -141,6 +150,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa // ------------------------------------------------------------------------ + /** + * Read + * + * Reads session data and acquires a lock + * + * @param string $session_id Session ID + * @return string Serialized session data + */ public function read($session_id) { if (isset($this->_memcached) && $this->_get_lock($session_id)) @@ -156,6 +173,17 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return FALSE; } + // ------------------------------------------------------------------------ + + /** + * Write + * + * Writes (create / update) session data + * + * @param string $session_id Session ID + * @param string $session_data Serialized session data + * @return bool + */ public function write($session_id, $session_data) { if ( ! isset($this->_memcached)) @@ -196,6 +224,13 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa // ------------------------------------------------------------------------ + /** + * Close + * + * Releases locks and closes connection. + * + * @return void + */ public function close() { if (isset($this->_memcached)) @@ -215,6 +250,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa // ------------------------------------------------------------------------ + /** + * Destroy + * + * Destroys the current session. + * + * @param string $session_id Session ID + * @return bool + */ public function destroy($session_id) { if (isset($this->_memcached, $this->_lock_key)) @@ -228,6 +271,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa // ------------------------------------------------------------------------ + /** + * Garbage Collector + * + * Deletes expired sessions + * + * @param int $maxlifetime Maximum lifetime of sessions + * @return bool + */ public function gc($maxlifetime) { // Not necessary, Memcached takes care of that. @@ -236,6 +287,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa // ------------------------------------------------------------------------ + /** + * Get lock + * + * Acquires an (emulated) lock. + * + * @param string $session_id Session ID + * @return bool + */ protected function _get_lock($session_id) { if (isset($this->_lock_key)) @@ -289,6 +348,13 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa // ------------------------------------------------------------------------ + /** + * Release lock + * + * Releases a previously acquired lock + * + * @return bool + */ protected function _release_lock() { if (isset($this->_memcached, $this->_lock_key) && $this->_lock) diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index cde587b97..a0ec40907 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -111,6 +111,15 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Open + * + * Sanitizes save_path and initializes connection. + * + * @param string $save_path Server path + * @param string $name Session cookie name, unused + * @return bool + */ public function open($save_path, $name) { if (empty($this->_config['save_path'])) @@ -142,6 +151,14 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Read + * + * Reads session data and acquires a lock + * + * @param string $session_id Session ID + * @return string Serialized session data + */ public function read($session_id) { if (isset($this->_redis) && $this->_get_lock($session_id)) @@ -157,6 +174,17 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return FALSE; } + // ------------------------------------------------------------------------ + + /** + * Write + * + * Writes (create / update) session data + * + * @param string $session_id Session ID + * @param string $session_data Serialized session data + * @return bool + */ public function write($session_id, $session_data) { if ( ! isset($this->_redis)) @@ -197,6 +225,13 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Close + * + * Releases locks and closes connection. + * + * @return void + */ public function close() { if (isset($this->_redis)) @@ -225,6 +260,14 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Destroy + * + * Destroys the current session. + * + * @param string $session_id Session ID + * @return bool + */ public function destroy($session_id) { if (isset($this->_redis, $this->_lock_key)) @@ -242,6 +285,14 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Garbage Collector + * + * Deletes expired sessions + * + * @param int $maxlifetime Maximum lifetime of sessions + * @return bool + */ public function gc($maxlifetime) { // Not necessary, Redis takes care of that. @@ -250,6 +301,14 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Get lock + * + * Acquires an (emulated) lock. + * + * @param string $session_id Session ID + * @return bool + */ protected function _get_lock($session_id) { if (isset($this->_lock_key)) @@ -309,6 +368,13 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle // ------------------------------------------------------------------------ + /** + * Release lock + * + * Releases a previously acquired lock + * + * @return bool + */ protected function _release_lock() { if (isset($this->_redis, $this->_lock_key) && $this->_lock) -- cgit v1.2.3-24-g4f1b From 90da83c91c3359e656dec99b5be4f1779608f3b1 Mon Sep 17 00:00:00 2001 From: Ivan Tcholakov Date: Mon, 19 Jan 2015 17:23:08 +0200 Subject: A minor header update, CI_Session_driver. --- system/libraries/Session/Session_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index c4fbde4f8..8edd31999 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -2,7 +2,7 @@ /** * CodeIgniter * - * An open source application development framework for PHP 5.2.4 + * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * -- cgit v1.2.3-24-g4f1b From 90726b8c769ea75aec34814ddfa91655d488e6c3 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 20 Jan 2015 12:39:22 +0200 Subject: [ci skip] Change some log messages' level 'Class Loaded' type of messages flood log files when log_threshold is set to 2 (debug). They're now logged as 'info' level. This is manually applying PR #1528, which was created to do the same thing, but became outdated. --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 5c61002a6..bc4a5ca1c 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -174,7 +174,7 @@ class CI_Session { $this->_ci_init_vars(); - log_message('debug', "Session: Class initialized using '".$this->_driver."' driver."); + log_message('info', "Session: Class initialized using '".$this->_driver."' driver."); } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 4cbe463b4c442e0e2dae2f43565e77f7ac5ecb86 Mon Sep 17 00:00:00 2001 From: vlakoff Date: Wed, 21 Jan 2015 22:56:22 +0100 Subject: Remove closing blocks at end of PHP files --- system/libraries/Session/Session.php | 3 --- system/libraries/Session/SessionHandlerInterface.php | 3 --- system/libraries/Session/Session_driver.php | 3 --- system/libraries/Session/drivers/Session_database_driver.php | 3 --- system/libraries/Session/drivers/Session_files_driver.php | 3 --- system/libraries/Session/drivers/Session_memcached_driver.php | 3 --- system/libraries/Session/drivers/Session_redis_driver.php | 3 --- 7 files changed, 21 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index bc4a5ca1c..5f7791dee 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -893,6 +893,3 @@ class CI_Session { } } - -/* End of file Session.php */ -/* Location: ./system/libraries/Session/Session.php */ \ No newline at end of file diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php index 2050e1e4d..9dab5ac07 100644 --- a/system/libraries/Session/SessionHandlerInterface.php +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -57,6 +57,3 @@ interface SessionHandlerInterface { public function destroy($session_id); public function gc($maxlifetime); } - -/* End of file SessionHandlerInterface.php */ -/* Location: ./system/libraries/Session/SessionHandlerInterface.php */ \ No newline at end of file diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 8edd31999..47376da5b 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -146,6 +146,3 @@ abstract class CI_Session_driver implements SessionHandlerInterface { } } - -/* End of file Session_driver.php */ -/* Location: ./system/libraries/Session/Session_driver.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 87d80a2b0..76596f041 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -383,6 +383,3 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan } } - -/* End of file Session_database_driver.php */ -/* Location: ./system/libraries/Session/drivers/Session_database_driver.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 95ab7f14c..04562b282 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -344,6 +344,3 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle } } - -/* End of file Session_files_driver.php */ -/* Location: ./system/libraries/Session/drivers/Session_files_driver.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 683bb5c69..00112c88c 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -373,6 +373,3 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa } } - -/* End of file Session_memcached_driver.php */ -/* Location: ./system/libraries/Session/drivers/Session_memcached_driver.php */ \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index a0ec40907..c53975ae4 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -393,6 +393,3 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle } } - -/* End of file Session_redis_driver.php */ -/* Location: ./system/libraries/Session/drivers/Session_redis_driver.php */ \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 00c222db1e23ecc3692a5ca5664d8fc25f1789fc Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 29 Jan 2015 18:14:31 +0200 Subject: Fix #3529 Seems to be some really obscure PHP bug ... --- system/libraries/Session/drivers/Session_database_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 76596f041..0ec6e34f0 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -83,7 +83,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $CI =& get_instance(); isset($CI->db) OR $CI->load->database(); - $this->_db =& $CI->db; + $this->_db = $CI->db; if ( ! $this->_db instanceof CI_DB_query_builder) { -- cgit v1.2.3-24-g4f1b From 5f4d01a97d9979f25ace6a7bce4dea23f630524e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 2 Feb 2015 18:38:00 +0200 Subject: Throw exception if 'files' session path is invalid --- system/libraries/Session/drivers/Session_files_driver.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 04562b282..32aeab614 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -1,4 +1,4 @@ -_config['save_path']."' is not a directory, doesn't exist or cannot be created."); - return FALSE; + if ( ! mkdir($save_path, 0700, TRUE)) + { + throw new Exception("Session: Configured save path '".$this->_config['save_path']."' is not a directory, doesn't exist or cannot be created."); + } + } + elseif ( ! is_writable($save_path)) + { + throw new Exception("Session: Configured save path '".$this->_config['save_path']."' is not writable by the PHP process."); } $this->_config['save_path'] = $save_path; -- cgit v1.2.3-24-g4f1b From 05afe3eac1ff69aabdb34b795004acb8a386d20d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 2 Feb 2015 19:04:37 +0200 Subject: Err ... r --- system/libraries/Session/drivers/Session_files_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 32aeab614..ad8315d52 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -1,4 +1,4 @@ -r Date: Mon, 2 Feb 2015 23:22:29 +0200 Subject: Fix a wrong var name in CI_Session::mark_as_temp() --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 5f7791dee..2551e54e9 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -489,7 +489,7 @@ class CI_Session { return FALSE; } - $temp[$k] = $ts; + $temp[$k] = $v; } $_SESSION['__ci_vars'] = isset($_SESSION['__ci_vars']) -- cgit v1.2.3-24-g4f1b From 1fb500077784638399be79b32fe354aec257413c Mon Sep 17 00:00:00 2001 From: Gabriel Potkány Date: Wed, 4 Feb 2015 01:45:59 +0100 Subject: Fixed inconsistent return types --- system/libraries/Session/drivers/Session_database_driver.php | 2 +- system/libraries/Session/drivers/Session_files_driver.php | 2 +- system/libraries/Session/drivers/Session_memcached_driver.php | 2 +- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 0ec6e34f0..20cec00fd 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -252,7 +252,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan * * Releases locks * - * @return void + * @return bool */ public function close() { diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index ad8315d52..d3ef34acd 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -269,7 +269,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle * * Releases locks and closes file descriptor. * - * @return void + * @return bool */ public function close() { diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 00112c88c..600b8ca66 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -229,7 +229,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa * * Releases locks and closes connection. * - * @return void + * @return bool */ public function close() { diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index c53975ae4..c3c75b3b6 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -230,7 +230,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle * * Releases locks and closes connection. * - * @return void + * @return bool */ public function close() { -- cgit v1.2.3-24-g4f1b From 5fa4b7266d7c61dc2482e529bd6afb9a67edadb7 Mon Sep 17 00:00:00 2001 From: Gabriel Potkány Date: Wed, 4 Feb 2015 10:46:24 +0100 Subject: Fixed return values types in session drivers --- system/libraries/Session/drivers/Session_files_driver.php | 6 +++--- system/libraries/Session/drivers/Session_memcached_driver.php | 2 +- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index d3ef34acd..217d3f9db 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -156,13 +156,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle if (($this->_file_handle = fopen($this->_file_path.$session_id, 'w+b')) === FALSE) { log_message('error', "Session: File '".$this->_file_path.$session_id."' doesn't exist and cannot be created."); - return FALSE; + return ''; } } elseif (($this->_file_handle = fopen($this->_file_path.$session_id, 'r+b')) === FALSE) { log_message('error', "Session: Unable to open file '".$this->_file_path.$session_id."'."); - return FALSE; + return ''; } if (flock($this->_file_handle, LOCK_EX) === FALSE) @@ -170,7 +170,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle log_message('error', "Session: Unable to obtain lock for file '".$this->_file_path.$session_id."'."); fclose($this->_file_handle); $this->_file_handle = NULL; - return FALSE; + return ''; } // Needed by write() to detect session_regenerate_id() calls diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 600b8ca66..80d8b3df6 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -170,7 +170,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $session_data; } - return FALSE; + return '';; } // ------------------------------------------------------------------------ diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index c3c75b3b6..af427d273 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -171,7 +171,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $session_data; } - return FALSE; + return ''; } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 0dd2538900bcbf5ab34798c9fb56632fefbfdad0 Mon Sep 17 00:00:00 2001 From: Gabriel Potkány Date: Wed, 4 Feb 2015 12:15:06 +0100 Subject: Revert "Fixed return values types in session drivers" This reverts commit 5fa4b7266d7c61dc2482e529bd6afb9a67edadb7. --- system/libraries/Session/drivers/Session_files_driver.php | 6 +++--- system/libraries/Session/drivers/Session_memcached_driver.php | 2 +- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 217d3f9db..d3ef34acd 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -156,13 +156,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle if (($this->_file_handle = fopen($this->_file_path.$session_id, 'w+b')) === FALSE) { log_message('error', "Session: File '".$this->_file_path.$session_id."' doesn't exist and cannot be created."); - return ''; + return FALSE; } } elseif (($this->_file_handle = fopen($this->_file_path.$session_id, 'r+b')) === FALSE) { log_message('error', "Session: Unable to open file '".$this->_file_path.$session_id."'."); - return ''; + return FALSE; } if (flock($this->_file_handle, LOCK_EX) === FALSE) @@ -170,7 +170,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle log_message('error', "Session: Unable to obtain lock for file '".$this->_file_path.$session_id."'."); fclose($this->_file_handle); $this->_file_handle = NULL; - return ''; + return FALSE; } // Needed by write() to detect session_regenerate_id() calls diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 80d8b3df6..600b8ca66 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -170,7 +170,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $session_data; } - return '';; + return FALSE; } // ------------------------------------------------------------------------ diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index af427d273..c3c75b3b6 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -171,7 +171,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $session_data; } - return ''; + return FALSE; } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 395f92882afada9701ab2384772ce331ae9b3f9d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 5 Feb 2015 13:29:56 +0200 Subject: [ci skip] Fix a bug where session IDs are not regenerated Reported via the forums: http://forum.codeigniter.com/thread-996.html --- system/libraries/Session/Session.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 2551e54e9..ba1919b44 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -143,8 +143,7 @@ class CI_Session { session_start(); // Is session ID auto-regeneration configured? (ignoring ajax requests) - if ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) - && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest' + if ((empty($_SERVER['HTTP_X_REQUESTED_WITH']) OR strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') && ($regenerate_time = config_item('sess_time_to_update')) > 0 ) { -- cgit v1.2.3-24-g4f1b From 388ce59de69cc524e6869994c4d18294c089477f Mon Sep 17 00:00:00 2001 From: Tom Atkinson Date: Wed, 4 Feb 2015 17:54:52 +0100 Subject: Use session cookie name in gc check --- system/libraries/Session/drivers/Session_files_driver.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index d3ef34acd..5852277e8 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -107,7 +107,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle * Sanitizes the save_path directory. * * @param string $save_path Path to session files' directory - * @param string $name Session cookie name, unused + * @param string $name Session cookie name * @return bool */ public function open($save_path, $name) @@ -332,10 +332,16 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle $ts = time() - $maxlifetime; + $pattern = sprintf( + '/^%s[0-9a-f]{%d}$/', + preg_quote($this->_config['cookie_name'], '/'), + ($this->_config['match_ip'] === TRUE ? 72 : 40) + ); + foreach ($files as $file) { // If the filename doesn't match this pattern, it's either not a session file or is not ours - if ( ! preg_match('/(?:[0-9a-f]{32})?[0-9a-f]{40}$/i', $file) + if ( ! preg_match($pattern, $file) OR ! is_file($this->_config['save_path'].DIRECTORY_SEPARATOR.$file) OR ($mtime = filemtime($this->_config['save_path'].DIRECTORY_SEPARATOR.$file)) === FALSE OR $mtime > $ts) -- cgit v1.2.3-24-g4f1b From 789b1fe3e78f59cdb35ac5e6cf7166f6b97436c7 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 7 Feb 2015 19:30:30 +0200 Subject: Add 'sess_regenerate_destroy' setting --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index ba1919b44..de9b1e829 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -153,7 +153,7 @@ class CI_Session { } elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time)) { - $this->sess_regenerate(FALSE); + $this->sess_regenerate((bool) config_item('sess_regenerate_destroy')); } } // Another work-around ... PHP doesn't seem to send the session cookie -- cgit v1.2.3-24-g4f1b From 00025885b8042114c3b1859855656a94316b4e57 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 11 Feb 2015 16:23:46 +0200 Subject: Fix undefined variable notice in Session redis, memcached drivers --- system/libraries/Session/drivers/Session_memcached_driver.php | 2 +- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 600b8ca66..f1a6e2400 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -361,7 +361,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if ( ! $this->_memcached->delete($this->_lock_key) && $this->_memcached->getResultCode() !== Memcached::RES_NOTFOUND) { - log_message('error', 'Session: Error while trying to free lock for '.$this->_key_prefix.$session_id); + log_message('error', 'Session: Error while trying to free lock for '.$this->_lock_key); return FALSE; } diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index c3c75b3b6..1cc4d75d7 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -381,7 +381,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if ( ! $this->_redis->delete($this->_lock_key)) { - log_message('error', 'Session: Error while trying to free lock for '.$this->_key_prefix.$session_id); + log_message('error', 'Session: Error while trying to free lock for '.$this->_lock_key); return FALSE; } -- cgit v1.2.3-24-g4f1b From c02952d2e6ccf0ee227836683d33239c8ef4e2df Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 13 Feb 2015 13:04:38 +0200 Subject: Fix a typo in CI_Session --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index de9b1e829..f3b819af9 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -314,7 +314,7 @@ class CI_Session { $this->_config = $params; // Security is king - ini_set('session.use_trans_id', 0); + ini_set('session.use_trans_sid', 0); ini_set('session.use_strict_mode', 1); ini_set('session.use_cookies', 1); ini_set('session.use_only_cookies', 1); -- cgit v1.2.3-24-g4f1b From b68a811f1a09b8d6012b6782b36a988daf68a82e Mon Sep 17 00:00:00 2001 From: Tjoosten Date: Sun, 15 Feb 2015 22:44:24 +0100 Subject: add --- system/libraries/Session/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/index.html b/system/libraries/Session/index.html index c942a79ce..b702fbc39 100644 --- a/system/libraries/Session/index.html +++ b/system/libraries/Session/index.html @@ -1,3 +1,4 @@ + 403 Forbidden @@ -7,4 +8,4 @@

Directory access is forbidden.

- \ No newline at end of file + -- cgit v1.2.3-24-g4f1b From 3cf58eaf15abaa1b5ab3e9ff671f174c9455b28f Mon Sep 17 00:00:00 2001 From: Ivan Tcholakov Date: Tue, 17 Feb 2015 20:03:09 +0200 Subject: Finishing PR #3596 --- system/libraries/Session/drivers/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/index.html b/system/libraries/Session/drivers/index.html index c942a79ce..b702fbc39 100644 --- a/system/libraries/Session/drivers/index.html +++ b/system/libraries/Session/drivers/index.html @@ -1,3 +1,4 @@ + 403 Forbidden @@ -7,4 +8,4 @@

Directory access is forbidden.

- \ No newline at end of file + -- cgit v1.2.3-24-g4f1b From 6c7c8917d853bcd4acdce930b9afa537b2fb8b95 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 19 Feb 2015 14:44:18 +0200 Subject: Remove 'autoinit' DB setting It doesn't make sense to do a load->database() call but not connect to the database. IIRC there was more stuff in CI_DB_driver::initialize() at some point, so that was probably the reason why the setting existed in the first place. However, now it only results in users making invalid bug reports because they don't understand the feature ... Examples during just the past 2 weeks: #3571 #3601 #3607 --- system/libraries/Session/drivers/Session_database_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 20cec00fd..f496b4fe0 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -122,7 +122,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan public function open($save_path, $name) { return empty($this->_db->conn_id) - ? ( ! $this->_db->autoinit && $this->_db->db_connect()) + ? (bool) $this->_db->db_connect() : TRUE; } -- cgit v1.2.3-24-g4f1b From c519b26d78edb21fd189e73f0feb12690aa34f2d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 21 Feb 2015 19:20:03 +0200 Subject: Fix #3610 --- system/libraries/Session/drivers/Session_files_driver.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 5852277e8..74528e9d2 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -299,7 +299,9 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { if ($this->close()) { - return unlink($this->_file_path.$session_id) && $this->_cookie_destroy(); + return file_exists($this->_file_path.$session_id) + ? (unlink($this->_file_path.$session_id) && $this->_cookie_destroy()) + : TRUE; } elseif ($this->_file_path !== NULL) { -- cgit v1.2.3-24-g4f1b From abc8f00465beb4cb99cc533ab2dbf3cb4191cbbe Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 23 Feb 2015 08:38:06 +0200 Subject: [ci skip] Fix #3618 --- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 1cc4d75d7..5fbb5222c 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -272,7 +272,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if (isset($this->_redis, $this->_lock_key)) { - if ($this->_redis->delete($this->_key_prefix.$session_id) !== 1) + if (($result = $this->_redis->delete($this->_key_prefix.$session_id)) !== 1) { log_message('debug', 'Session: Redis::delete() expected to return 1, got '.var_export($result, TRUE).' instead.'); } -- cgit v1.2.3-24-g4f1b From e1a5bb345b1b30ea777348efa9cade21c1f2e2fb Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 4 Mar 2015 13:33:39 +0200 Subject: Fix #3627: Keep timed locks for more than 5 seconds Emulated locks for Redis and Memcached now have a TTL of 300 seconds (the default HTTP request timeout value on many environments) and 30 attemps, each separated by sleep(1), are made by the blocked request to try and obtain a lock if it has been freed. Additionaly, the blocking time for MySQL's locks, which are also timed, is also set to 300 seconds. --- .../Session/drivers/Session_database_driver.php | 2 +- .../Session/drivers/Session_memcached_driver.php | 30 +++++----------- .../Session/drivers/Session_redis_driver.php | 40 +++++++--------------- 3 files changed, 23 insertions(+), 49 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index f496b4fe0..76c1cf34e 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -319,7 +319,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if ($this->_platform === 'mysql') { $arg = $session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : ''); - if ($this->_db->query("SELECT GET_LOCK('".$arg."', 10) AS ci_session_lock")->row()->ci_session_lock) + if ($this->_db->query("SELECT GET_LOCK('".$arg."', 300) AS ci_session_lock")->row()->ci_session_lock) { $this->_lock = $arg; return TRUE; diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index f1a6e2400..938a612d9 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -204,7 +204,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if (isset($this->_lock_key)) { - $this->_memcached->replace($this->_lock_key, time(), 5); + $this->_memcached->replace($this->_lock_key, time(), 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { if ($this->_memcached->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) @@ -299,34 +299,21 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if (isset($this->_lock_key)) { - return $this->_memcached->replace($this->_lock_key, time(), 5); + return $this->_memcached->replace($this->_lock_key, time(), 300); } + // 30 attempts to obtain a lock, in case another request already has it $lock_key = $this->_key_prefix.$session_id.':lock'; - if ( ! ($ts = $this->_memcached->get($lock_key))) - { - if ( ! $this->_memcached->set($lock_key, TRUE, 5)) - { - log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); - return FALSE; - } - - $this->_lock_key = $lock_key; - $this->_lock = TRUE; - return TRUE; - } - - // Another process has the lock, we'll try to wait for it to free itself ... $attempt = 0; - while ($attempt++ < 5) + do { - usleep(((time() - $ts) * 1000000) - 20000); - if (($ts = $this->_memcached->get($lock_key)) < time()) + if ($this->_memcached->get($lock_key)) { + sleep(1); continue; } - if ( ! $this->_memcached->set($lock_key, time(), 5)) + if ( ! $this->_memcached->set($lock_key, time(), 300)) { log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); return FALSE; @@ -335,8 +322,9 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $this->_lock_key = $lock_key; break; } + while ($attempt++ < 30); - if ($attempt === 5) + if ($attempt === 30) { log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 5 attempts, aborting.'); return FALSE; diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 5fbb5222c..1ce101daf 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -205,7 +205,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle if (isset($this->_lock_key)) { - $this->_redis->setTimeout($this->_lock_key, 5); + $this->_redis->setTimeout($this->_lock_key, 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) @@ -313,40 +313,21 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if (isset($this->_lock_key)) { - return $this->_redis->setTimeout($this->_lock_key, 5); + return $this->_redis->setTimeout($this->_lock_key, 300); } + // 30 attempts to obtain a lock, in case another request already has it $lock_key = $this->_key_prefix.$session_id.':lock'; - if (($ttl = $this->_redis->ttl($lock_key)) < 1) - { - if ( ! $this->_redis->setex($lock_key, 5, time())) - { - log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); - return FALSE; - } - - $this->_lock_key = $lock_key; - - if ($ttl === -1) - { - log_message('debug', 'Session: Lock for '.$this->_key_prefix.$session_id.' had no TTL, overriding.'); - } - - $this->_lock = TRUE; - return TRUE; - } - - // Another process has the lock, we'll try to wait for it to free itself ... $attempt = 0; - while ($attempt++ < 5) + do { - usleep(($ttl * 1000000) - 20000); if (($ttl = $this->_redis->ttl($lock_key)) > 0) { + sleep(1); continue; } - if ( ! $this->_redis->setex($lock_key, 5, time())) + if ( ! $this->_redis->setex($lock_key, 300, time())) { log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); return FALSE; @@ -355,12 +336,17 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle $this->_lock_key = $lock_key; break; } + while ($attempt++ < 30); - if ($attempt === 5) + if ($attempt === 30) { - log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 5 attempts, aborting.'); + log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 30 attempts, aborting.'); return FALSE; } + elseif ($ttl === -1) + { + log_message('debug', 'Session: Lock for '.$this->_key_prefix.$session_id.' had no TTL, overriding.'); + } $this->_lock = TRUE; return TRUE; -- cgit v1.2.3-24-g4f1b From c1dc446cc60f449eb4fa35bb2bbe8e95d3edc9f8 Mon Sep 17 00:00:00 2001 From: Master Yoda Date: Fri, 6 Mar 2015 22:22:24 -0800 Subject: Housekeeping. Corrected typo in user guide for sessions, corrected misepelled key in calendar language file, added two links & updated wording on the repo readme. Signed-off-by:Master Yoda --- system/libraries/Session/drivers/Session_memcached_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 938a612d9..c7185ee44 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -326,7 +326,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if ($attempt === 30) { - log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 5 attempts, aborting.'); + log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 30 attempts, aborting.'); return FALSE; } -- cgit v1.2.3-24-g4f1b From 34b92c6c058a27fda4572f16af41340e0b46f4df Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 12 Mar 2015 12:42:00 +0200 Subject: Throw an exception on invalid session driver config --- system/libraries/Session/Session.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index f3b819af9..54d31ee1a 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -94,10 +94,7 @@ class CI_Session { $this->_driver = 'database'; } - if (($class = $this->_ci_load_classes($this->_driver)) === FALSE) - { - return; - } + $class = $this->_ci_load_classes($this->_driver); // Configuration ... $this->_configure($params); @@ -230,8 +227,7 @@ class CI_Session { if ( ! class_exists('CI_'.$class, FALSE) && ! class_exists($class, FALSE)) { - log_message('error', "Session: Configured driver '".$driver."' was not found. Aborting."); - return FALSE; + throw new \UnexpectedValueException("Session: Configured driver '".$driver."' was not found. Aborting."); } } -- cgit v1.2.3-24-g4f1b From 1d19520c7bc40280050b59e05a212ecedd9edd53 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 13 Mar 2015 11:25:29 +0200 Subject: [ci skip] Remove NS usage in CI_Session It was accidental --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 54d31ee1a..bb457c659 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -227,7 +227,7 @@ class CI_Session { if ( ! class_exists('CI_'.$class, FALSE) && ! class_exists($class, FALSE)) { - throw new \UnexpectedValueException("Session: Configured driver '".$driver."' was not found. Aborting."); + throw new UnexpectedValueException("Session: Configured driver '".$driver."' was not found. Aborting."); } } -- cgit v1.2.3-24-g4f1b From 737a5660c09e844d44969d1b7e8165b5f0296e37 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 21 Mar 2015 12:41:38 +0200 Subject: [ci skip] Forbid DB session usage with cache_on enabled --- system/libraries/Session/drivers/Session_database_driver.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 76c1cf34e..1d01c2923 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -93,6 +93,10 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { throw new Exception('Configured database connection is persistent. Aborting.'); } + elseif ($this->_db->cache_on) + { + throw new Exception('Configured database connection has cache enabled. Aborting.'); + } $db_driver = $this->_db->dbdriver.(empty($this->_db->subdriver) ? '' : '_'.$this->_db->subdriver); if (strpos($db_driver, 'mysql') !== FALSE) -- cgit v1.2.3-24-g4f1b From 2f79f9a9e8a5b167ce899609a2058c4d2f480aa8 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 26 Mar 2015 12:52:05 +0200 Subject: Improve Session GC for files driver Close #3701 --- system/libraries/Session/drivers/Session_files_driver.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 74528e9d2..45da91c46 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -326,7 +326,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle */ public function gc($maxlifetime) { - if ( ! is_dir($this->_config['save_path']) OR ($files = scandir($this->_config['save_path'])) === FALSE) + if ( ! is_dir($this->_config['save_path']) OR ($directory = opendir($this->_config['save_path'])) === FALSE) { log_message('debug', "Session: Garbage collector couldn't list files under directory '".$this->_config['save_path']."'."); return FALSE; @@ -340,7 +340,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle ($this->_config['match_ip'] === TRUE ? 72 : 40) ); - foreach ($files as $file) + while (($file = readdir($directory)) !== FALSE) { // If the filename doesn't match this pattern, it's either not a session file or is not ours if ( ! preg_match($pattern, $file) @@ -354,6 +354,8 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle unlink($this->_config['save_path'].DIRECTORY_SEPARATOR.$file); } + closedir($directory); + return TRUE; } -- cgit v1.2.3-24-g4f1b From fd3105716f5cdede79b9b471561413c161db250c Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 30 Mar 2015 17:19:26 +0300 Subject: Fix #3717 --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index bb457c659..0549fef66 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -869,7 +869,7 @@ class CI_Session { public function set_tempdata($data, $value = NULL, $ttl = 300) { $this->set_userdata($data, $value); - $this->mark_as_temp($data, $ttl); + $this->mark_as_temp(is_array($data) ? array_keys($data) : $data, $ttl); } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 73b9e851a96dcafc0c07a0d0480853e31ba48e59 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 30 Apr 2015 13:06:40 +0300 Subject: Fix #3823 --- system/libraries/Session/drivers/Session_memcached_driver.php | 2 +- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index c7185ee44..97b860588 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -322,7 +322,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $this->_lock_key = $lock_key; break; } - while ($attempt++ < 30); + while (++$attempt < 30); if ($attempt === 30) { diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 1ce101daf..b098cc441 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -336,7 +336,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle $this->_lock_key = $lock_key; break; } - while ($attempt++ < 30); + while (++$attempt < 30); if ($attempt === 30) { -- cgit v1.2.3-24-g4f1b From 55bc50578b9f1aa3fd71cb427848b21748655690 Mon Sep 17 00:00:00 2001 From: Calvin Tam Date: Fri, 24 Jul 2015 02:27:24 -0700 Subject: Fixed typos --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 0549fef66..05a470d86 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -795,7 +795,7 @@ class CI_Session { /** * Set flashdata * - * Legacy CI_Session compatibiliy method + * Legacy CI_Session compatibility method * * @param mixed $data Session data key or an associative array * @param mixed $value Value to store -- cgit v1.2.3-24-g4f1b From de8b82ca8c4e201ad21c07ca962f5480493143eb Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sun, 18 Oct 2015 20:58:38 +0300 Subject: Fix #4179 --- system/libraries/Session/drivers/Session_database_driver.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 1d01c2923..72b39d12d 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -159,6 +159,10 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if (($result = $this->_db->get()->row()) === NULL) { + // PHP7 will reuse the same SessionHandler object after + // ID regeneration, so we need to explicitly set this to + // FALSE instead of relying on the default ... + $this->_row_exists = FALSE; $this->_fingerprint = md5(''); return ''; } -- cgit v1.2.3-24-g4f1b From 8df6efd402180a6361b4dd619f5535d6c2bed334 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 11 Dec 2015 17:55:55 +0200 Subject: Fix #4039 --- system/libraries/Session/drivers/Session_files_driver.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 45da91c46..173b43710 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -183,6 +183,12 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle return ''; } } + // We shouldn't need this, but apparently we do ... + // See https://github.com/bcit-ci/CodeIgniter/issues/4039 + elseif ($this->_file_handler === FALSE) + { + return FALSE; + } else { rewind($this->_file_handle); -- cgit v1.2.3-24-g4f1b From af849696d43f5c3b68962af1ae5096151a6d9f1a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 12 Dec 2015 14:07:39 +0200 Subject: [ci skip] Proper error handling for Sessions on PHP 5 This was actually a PHP bug, see https://wiki.php.net/rfc/session.user.return-value Also related: #4039 --- system/libraries/Session/Session_driver.php | 23 +++++++++ .../Session/drivers/Session_database_driver.php | 49 +++++++++++------- .../Session/drivers/Session_files_driver.php | 59 +++++++++++++--------- .../Session/drivers/Session_memcached_driver.php | 45 +++++++++-------- .../Session/drivers/Session_redis_driver.php | 35 +++++++------ 5 files changed, 133 insertions(+), 78 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 47376da5b..64b4bb511 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -74,6 +74,18 @@ abstract class CI_Session_driver implements SessionHandlerInterface { */ protected $_session_id; + /** + * Success and failure return values + * + * Necessary due to a bug in all PHP 5 versions where return values + * from userspace handlers are not handled properly. PHP 7 fixes the + * bug, so we need to return different values depending on the version. + * + * @see https://wiki.php.net/rfc/session.user.return-value + * @var mixed + */ + protected $_success, $_failure; + // ------------------------------------------------------------------------ /** @@ -85,6 +97,17 @@ abstract class CI_Session_driver implements SessionHandlerInterface { public function __construct(&$params) { $this->_config =& $params; + + if (is_php('7')) + { + $this->_success = TRUE; + $this->_failure = FALSE; + } + else + { + $this->_success = 0; + $this->_failure = -1; + } } // ------------------------------------------------------------------------ diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 72b39d12d..40a358fb8 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -125,9 +125,12 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan */ public function open($save_path, $name) { - return empty($this->_db->conn_id) - ? (bool) $this->_db->db_connect() - : TRUE; + if (empty($this->_db->conn_id) && ! $this->_db->db_connect()) + { + return $this->_failure; + } + + return $this->_success; } // ------------------------------------------------------------------------ @@ -201,7 +204,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return FALSE; + return $this->_failure; } $this->_row_exists = FALSE; @@ -209,7 +212,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan } elseif ($this->_lock === FALSE) { - return FALSE; + return $this->_failure; } if ($this->_row_exists === FALSE) @@ -224,10 +227,11 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if ($this->_db->insert($this->_config['save_path'], $insert_data)) { $this->_fingerprint = md5($session_data); - return $this->_row_exists = TRUE; + $this->_row_exists = TRUE; + return $this->_success; } - return FALSE; + return $this->_failure; } $this->_db->where('id', $session_id); @@ -247,10 +251,10 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if ($this->_db->update($this->_config['save_path'], $update_data)) { $this->_fingerprint = md5($session_data); - return TRUE; + return $this->_success; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -264,9 +268,9 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan */ public function close() { - return ($this->_lock) - ? $this->_release_lock() - : TRUE; + return ($this->_lock && ! $this->_release_lock()) + ? $this->_failure + : $this->_success; } // ------------------------------------------------------------------------ @@ -289,12 +293,19 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } - return $this->_db->delete($this->_config['save_path']) - ? ($this->close() && $this->_cookie_destroy()) - : FALSE; + if ( ! $this->_db->delete($this->_config['save_path'])) + { + return $this->_failure; + } + } + + if ($this->close()) + { + $this->_cookie_destroy(); + return $this->_success; } - return ($this->close() && $this->_cookie_destroy()); + return $this->_failure; } // ------------------------------------------------------------------------ @@ -309,7 +320,9 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan */ public function gc($maxlifetime) { - return $this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime)); + return ($this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime))) + ? $this->_success + : $this->_failure; } // ------------------------------------------------------------------------ @@ -390,4 +403,4 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return parent::_release_lock(); } -} +} \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 173b43710..f0f055f87 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -129,7 +129,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle .$name // we'll use the session cookie name as a prefix to avoid collisions .($this->_config['match_ip'] ? md5($_SERVER['REMOTE_ADDR']) : ''); - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -156,13 +156,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle if (($this->_file_handle = fopen($this->_file_path.$session_id, 'w+b')) === FALSE) { log_message('error', "Session: File '".$this->_file_path.$session_id."' doesn't exist and cannot be created."); - return FALSE; + return $this->_failure; } } elseif (($this->_file_handle = fopen($this->_file_path.$session_id, 'r+b')) === FALSE) { log_message('error', "Session: Unable to open file '".$this->_file_path.$session_id."'."); - return FALSE; + return $this->_failure; } if (flock($this->_file_handle, LOCK_EX) === FALSE) @@ -170,7 +170,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle log_message('error', "Session: Unable to obtain lock for file '".$this->_file_path.$session_id."'."); fclose($this->_file_handle); $this->_file_handle = NULL; - return FALSE; + return $this->_failure; } // Needed by write() to detect session_regenerate_id() calls @@ -187,7 +187,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // See https://github.com/bcit-ci/CodeIgniter/issues/4039 elseif ($this->_file_handler === FALSE) { - return FALSE; + return $this->_failure; } else { @@ -226,18 +226,18 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // and we need to close the old handle and open a new one if ($session_id !== $this->_session_id && ( ! $this->close() OR $this->read($session_id) === FALSE)) { - return FALSE; + return $this->_failure; } if ( ! is_resource($this->_file_handle)) { - return FALSE; + return $this->_failure; } elseif ($this->_fingerprint === md5($session_data)) { - return ($this->_file_new) - ? TRUE - : touch($this->_file_path.$session_id); + return ( ! $this->_file_new && ! touch($this->_file_path.$session_id)) + ? $this->_failure + : $this->_success; } if ( ! $this->_file_new) @@ -260,12 +260,12 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { $this->_fingerprint = md5(substr($session_data, 0, $written)); log_message('error', 'Session: Unable to write data.'); - return FALSE; + return $this->_failure; } } $this->_fingerprint = md5($session_data); - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -285,10 +285,9 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle fclose($this->_file_handle); $this->_file_handle = $this->_file_new = $this->_session_id = NULL; - return TRUE; } - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -305,19 +304,31 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { if ($this->close()) { - return file_exists($this->_file_path.$session_id) - ? (unlink($this->_file_path.$session_id) && $this->_cookie_destroy()) - : TRUE; + if (file_exists($this->_file_path.$session_id)) + { + $this->_cookie_destroy(); + return unlink($this->_file_path.$session_id) + ? $this->_success + : $this->_failure; + } + + return $this->_success; } elseif ($this->_file_path !== NULL) { clearstatcache(); - return file_exists($this->_file_path.$session_id) - ? (unlink($this->_file_path.$session_id) && $this->_cookie_destroy()) - : TRUE; + if (file_exists($this->_file_path.$session_id)) + { + $this->_cookie_destroy(); + return unlink($this->_file_path.$session_id) + ? $this->_success + : $this->_failure; + } + + return $this->_success; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -335,7 +346,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle if ( ! is_dir($this->_config['save_path']) OR ($directory = opendir($this->_config['save_path'])) === FALSE) { log_message('debug', "Session: Garbage collector couldn't list files under directory '".$this->_config['save_path']."'."); - return FALSE; + return $this->_failure; } $ts = time() - $maxlifetime; @@ -362,7 +373,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle closedir($directory); - return TRUE; + return $this->_success; } -} +} \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 97b860588..760239dfb 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -117,7 +117,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { $this->_memcached = NULL; log_message('error', 'Session: Invalid Memcached save path format: '.$this->_config['save_path']); - return FALSE; + return $this->_failure; } foreach ($matches as $match) @@ -142,10 +142,10 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if (empty($server_list)) { log_message('error', 'Session: Memcached server pool is empty.'); - return FALSE; + return $this->_failure; } - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -170,7 +170,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $session_data; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -188,14 +188,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if ( ! isset($this->_memcached)) { - return FALSE; + return $this->_failure; } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return FALSE; + return $this->_failure; } $this->_fingerprint = md5(''); @@ -210,16 +210,18 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if ($this->_memcached->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; - return TRUE; + return $this->_success; } - return FALSE; + return $this->_failure; } - return $this->_memcached->touch($this->_key_prefix.$session_id, $this->_config['expiration']); + return $this->_memcached->touch($this->_key_prefix.$session_id, $this->_config['expiration']) + ? $this->_success + : $this->_failure; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -238,14 +240,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa isset($this->_lock_key) && $this->_memcached->delete($this->_lock_key); if ( ! $this->_memcached->quit()) { - return FALSE; + return $this->_failure; } $this->_memcached = NULL; - return TRUE; + return $this->_success; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -263,10 +265,11 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if (isset($this->_memcached, $this->_lock_key)) { $this->_memcached->delete($this->_key_prefix.$session_id); - return $this->_cookie_destroy(); + $this->_cookie_destroy(); + return $this->_success; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -282,7 +285,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa public function gc($maxlifetime) { // Not necessary, Memcached takes care of that. - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -299,7 +302,9 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if (isset($this->_lock_key)) { - return $this->_memcached->replace($this->_lock_key, time(), 300); + return ($this->_memcached->replace($this->_lock_key, time(), 300)) + ? $this->_success + : $this->_failure; } // 30 attempts to obtain a lock, in case another request already has it @@ -316,7 +321,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if ( ! $this->_memcached->set($lock_key, time(), 300)) { log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); - return FALSE; + return $this->_failure; } $this->_lock_key = $lock_key; @@ -327,11 +332,11 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if ($attempt === 30) { log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 30 attempts, aborting.'); - return FALSE; + return $this->_failure; } $this->_lock = TRUE; - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index b098cc441..e8915306f 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -124,7 +124,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if (empty($this->_config['save_path'])) { - return FALSE; + return $this->_failure; } $redis = new Redis(); @@ -143,10 +143,10 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle else { $this->_redis = $redis; - return TRUE; + return $this->_success; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -171,7 +171,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $session_data; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -189,14 +189,14 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if ( ! isset($this->_redis)) { - return FALSE; + return $this->_failure; } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return FALSE; + return $this->_failure; } $this->_fingerprint = md5(''); @@ -211,16 +211,18 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; - return TRUE; + return $this->_success; } - return FALSE; + return $this->_failure; } - return $this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration']); + return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) + ? $this->_success + : $this->_failure; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -242,7 +244,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle isset($this->_lock_key) && $this->_redis->delete($this->_lock_key); if ( ! $this->_redis->close()) { - return FALSE; + return $this->_failure; } } } @@ -252,10 +254,10 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle } $this->_redis = NULL; - return TRUE; + return $this->_success; } - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ @@ -277,10 +279,11 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle log_message('debug', 'Session: Redis::delete() expected to return 1, got '.var_export($result, TRUE).' instead.'); } - return $this->_cookie_destroy(); + $this->_cookie_destroy(); + return $this->_success; } - return FALSE; + return $this->_failure; } // ------------------------------------------------------------------------ @@ -296,7 +299,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle public function gc($maxlifetime) { // Not necessary, Redis takes care of that. - return TRUE; + return $this->_success; } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 2d6d9ab0bfeb546d8c9d7924af7ccc095f798e41 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 15 Dec 2015 12:32:50 +0200 Subject: Really fix #4039 A typo from 8df6efd402180a6361b4dd619f5535d6c2bed334 --- system/libraries/Session/drivers/Session_files_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index f0f055f87..1a943d5c9 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -185,7 +185,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle } // We shouldn't need this, but apparently we do ... // See https://github.com/bcit-ci/CodeIgniter/issues/4039 - elseif ($this->_file_handler === FALSE) + elseif ($this->_file_handle === FALSE) { return $this->_failure; } -- cgit v1.2.3-24-g4f1b From bb71dbadb7441a97a09e1e6d90fbddc884af67d1 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 15 Dec 2015 13:00:52 +0200 Subject: Fix logical errors from af849696d43f5c3b68962af1ae5096151a6d9f1a --- system/libraries/Session/drivers/Session_database_driver.php | 2 +- system/libraries/Session/drivers/Session_files_driver.php | 4 ++-- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 40a358fb8..f2adacb6b 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -299,7 +299,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan } } - if ($this->close()) + if ($this->close() === $this->_success) { $this->_cookie_destroy(); return $this->_success; diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 1a943d5c9..c540996a7 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -224,7 +224,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle { // If the two IDs don't match, we have a session_regenerate_id() call // and we need to close the old handle and open a new one - if ($session_id !== $this->_session_id && ( ! $this->close() OR $this->read($session_id) === FALSE)) + if ($session_id !== $this->_session_id && ($this->close() === $this->_failure OR $this->read($session_id) === $this->_failure)) { return $this->_failure; } @@ -302,7 +302,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle */ public function destroy($session_id) { - if ($this->close()) + if ($this->close() === $this->_success) { if (file_exists($this->_file_path.$session_id)) { diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index e8915306f..b60ef6b34 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -242,7 +242,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle if ($this->_redis->ping() === '+PONG') { isset($this->_lock_key) && $this->_redis->delete($this->_lock_key); - if ( ! $this->_redis->close()) + if ($this->_redis->close() === $this->_failure) { return $this->_failure; } -- cgit v1.2.3-24-g4f1b From 79b8a086187f199bb708bd56477850fbf1dd9e91 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 7 Jan 2016 13:55:21 +0200 Subject: Fix #4362 --- system/libraries/Session/drivers/Session_memcached_driver.php | 5 ++++- system/libraries/Session/drivers/Session_redis_driver.php | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 760239dfb..9d7ab1172 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -300,7 +300,10 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa */ protected function _get_lock($session_id) { - if (isset($this->_lock_key)) + // PHP 7 reuses the SessionHandler object on regeneration, + // so we need to check here if the lock key is for the + // correct session ID. + if ($this->_lock_key === $this->_key_prefix.$session_id.':lock') { return ($this->_memcached->replace($this->_lock_key, time(), 300)) ? $this->_success diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index b60ef6b34..a31c45372 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -314,7 +314,10 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle */ protected function _get_lock($session_id) { - if (isset($this->_lock_key)) + // PHP 7 reuses the SessionHandler object on regeneration, + // so we need to check here if the lock key is for the + // correct session ID. + if ($this->_lock_key === $this->_key_prefix.$session_id.':lock') { return $this->_redis->setTimeout($this->_lock_key, 300); } -- cgit v1.2.3-24-g4f1b From fd5fe1a64c03ae7204a7e72d936215f7a61d8c30 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 11 Jan 2016 11:58:40 +0200 Subject: Fix #4374 --- system/libraries/Session/drivers/Session_database_driver.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index f2adacb6b..8c4555481 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -147,6 +147,9 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if ($this->_get_lock($session_id) !== FALSE) { + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); + // Needed by write() to detect session_regenerate_id() calls $this->_session_id = $session_id; @@ -199,6 +202,9 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan */ public function write($session_id, $session_data) { + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); + // Was the ID regenerated? if ($session_id !== $this->_session_id) { @@ -287,6 +293,9 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if ($this->_lock) { + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); + $this->_db->where('id', $session_id); if ($this->_config['match_ip']) { @@ -320,6 +329,9 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan */ public function gc($maxlifetime) { + // Prevent previous QB calls from messing with our queries + $this->_db->reset_query(); + return ($this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime))) ? $this->_success : $this->_failure; -- cgit v1.2.3-24-g4f1b From 125ef4751080a2118cb203357d77687699e3eb25 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 11 Jan 2016 12:33:00 +0200 Subject: [ci skip] Bump year to 2016 --- system/libraries/Session/Session.php | 4 ++-- system/libraries/Session/SessionHandlerInterface.php | 4 ++-- system/libraries/Session/Session_driver.php | 4 ++-- system/libraries/Session/drivers/Session_database_driver.php | 4 ++-- system/libraries/Session/drivers/Session_files_driver.php | 4 ++-- system/libraries/Session/drivers/Session_memcached_driver.php | 4 ++-- system/libraries/Session/drivers/Session_redis_driver.php | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 05a470d86..28c93434d 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 2.0.0 diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php index 9dab5ac07..90bae937a 100644 --- a/system/libraries/Session/SessionHandlerInterface.php +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 64b4bb511..6d66e274b 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 8c4555481..5523655d2 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index c540996a7..f9dc426aa 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 9d7ab1172..cf52caac4 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index a31c45372..6a90a7405 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2015, British Columbia Institute of Technology + * Copyright (c) 2014 - 2016, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) - * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link http://codeigniter.com * @since Version 3.0.0 -- cgit v1.2.3-24-g4f1b From bd202c91b0e9cf0a8c93bcaa71df9574f5909346 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 11 Jan 2016 12:50:18 +0200 Subject: [ci skip] Update codeigniter.com links to https --- system/libraries/Session/Session.php | 4 ++-- system/libraries/Session/SessionHandlerInterface.php | 4 ++-- system/libraries/Session/Session_driver.php | 4 ++-- system/libraries/Session/drivers/Session_database_driver.php | 4 ++-- system/libraries/Session/drivers/Session_files_driver.php | 4 ++-- system/libraries/Session/drivers/Session_memcached_driver.php | 4 ++-- system/libraries/Session/drivers/Session_redis_driver.php | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 28c93434d..1e81ec53f 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -31,7 +31,7 @@ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 2.0.0 * @filesource */ @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session { diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php index 90bae937a..ea825a066 100644 --- a/system/libraries/Session/SessionHandlerInterface.php +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -31,7 +31,7 @@ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -46,7 +46,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ interface SessionHandlerInterface { diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 6d66e274b..02d984cdf 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -31,7 +31,7 @@ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ abstract class CI_Session_driver implements SessionHandlerInterface { diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 5523655d2..b3191e060 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -31,7 +31,7 @@ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_database_driver extends CI_Session_driver implements SessionHandlerInterface { diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index f9dc426aa..5ac1dcd36 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -31,7 +31,7 @@ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_files_driver extends CI_Session_driver implements SessionHandlerInterface { diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index cf52caac4..b2feb56f1 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -31,7 +31,7 @@ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHandlerInterface { diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 6a90a7405..047760554 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -31,7 +31,7 @@ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License - * @link http://codeigniter.com + * @link https://codeigniter.com * @since Version 3.0.0 * @filesource */ @@ -44,7 +44,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * @subpackage Libraries * @category Sessions * @author Andrey Andreev - * @link http://codeigniter.com/user_guide/libraries/sessions.html + * @link https://codeigniter.com/user_guide/libraries/sessions.html */ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandlerInterface { -- cgit v1.2.3-24-g4f1b From 1924e879b165fb119847a49a7a5eab2f28295fa2 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 11 Jan 2016 12:55:34 +0200 Subject: [ci skip] Update ellislab.com links to https too --- system/libraries/Session/Session.php | 2 +- system/libraries/Session/SessionHandlerInterface.php | 2 +- system/libraries/Session/Session_driver.php | 2 +- system/libraries/Session/drivers/Session_database_driver.php | 2 +- system/libraries/Session/drivers/Session_files_driver.php | 2 +- system/libraries/Session/drivers/Session_memcached_driver.php | 2 +- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 1e81ec53f..b93c00c15 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -28,7 +28,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php index ea825a066..b3533dd1e 100644 --- a/system/libraries/Session/SessionHandlerInterface.php +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -28,7 +28,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 02d984cdf..98fc897e3 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -28,7 +28,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index b3191e060..3ba9d3d36 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -28,7 +28,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 5ac1dcd36..119bf6572 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -28,7 +28,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index b2feb56f1..d017dfb2f 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -28,7 +28,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 047760554..46b8fa1c2 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -28,7 +28,7 @@ * * @package CodeIgniter * @author EllisLab Dev Team - * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/) + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com -- cgit v1.2.3-24-g4f1b From 173cf413d38be042b40c2e519041ecaafb6a0919 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 5 Feb 2016 14:36:50 +0200 Subject: Merge pull request #4424 from jonty-comp/develop [ci skip] Fix PHP session_write_close() warning when writing a new session to Redis --- .../Session/drivers/Session_redis_driver.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 46b8fa1c2..ad95309da 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -69,6 +69,13 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle */ protected $_lock_key; + /** + * Key exists flag + * + * @var bool + */ + protected $_key_exists = FALSE; + // ------------------------------------------------------------------------ /** @@ -166,7 +173,12 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle // Needed by write() to detect session_regenerate_id() calls $this->_session_id = $session_id; - $session_data = (string) $this->_redis->get($this->_key_prefix.$session_id); + $session_data = $this->_redis->get($this->_key_prefix.$session_id); + + is_string($session_data) + ? $this->_key_exists = TRUE + : $session_data = ''; + $this->_fingerprint = md5($session_data); return $session_data; } @@ -199,18 +211,19 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $this->_failure; } - $this->_fingerprint = md5(''); + $this->_key_exists = FALSE; $this->_session_id = $session_id; } if (isset($this->_lock_key)) { $this->_redis->setTimeout($this->_lock_key, 300); - if ($this->_fingerprint !== ($fingerprint = md5($session_data))) + if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE) { if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; + $this->_key_exists = TRUE; return $this->_success; } -- cgit v1.2.3-24-g4f1b From c4de3c2f93cb6d2af65b325ae2812fccad7e98b8 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 10 Feb 2016 07:41:43 +0200 Subject: [ci skip] Fix Memcached session lock handling and error checking around replace() usage --- .../Session/drivers/Session_memcached_driver.php | 26 ++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index d017dfb2f..e9246443c 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -204,10 +204,16 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if (isset($this->_lock_key)) { + $key = $this->_key_prefix.$session_id; + $this->_memcached->replace($this->_lock_key, time(), 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { - if ($this->_memcached->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) + + if ( + $this->_memcached->replace($key, $session_data, $this->_config['expiration']) + OR ($this->_memcached->getResultCode() === Memcached::RES_NOTSTORED && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) + ) { $this->_fingerprint = $fingerprint; return $this->_success; @@ -305,9 +311,12 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa // correct session ID. if ($this->_lock_key === $this->_key_prefix.$session_id.':lock') { - return ($this->_memcached->replace($this->_lock_key, time(), 300)) - ? $this->_success - : $this->_failure; + if ( ! $this->_memcached->replace($this->_lock_key, time(), 300)) + { + return ($this->_memcached->getResultCode() === Memcached::RES_NOTSTORED) + ? $this->_memcached->set($this->_lock_key, time(), 300) + : FALSE; + } } // 30 attempts to obtain a lock, in case another request already has it @@ -324,7 +333,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if ( ! $this->_memcached->set($lock_key, time(), 300)) { log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); - return $this->_failure; + return FALSE; } $this->_lock_key = $lock_key; @@ -335,11 +344,11 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if ($attempt === 30) { log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 30 attempts, aborting.'); - return $this->_failure; + return FALSE; } $this->_lock = TRUE; - return $this->_success; + return TRUE; } // ------------------------------------------------------------------------ @@ -367,5 +376,4 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return TRUE; } - -} +} \ No newline at end of file -- cgit v1.2.3-24-g4f1b From a54a2b90bf057d7883ea7506d78a1073478ea4cf Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 10 Feb 2016 19:55:39 +0200 Subject: Fix a bug where CI_Session_memcached_driver doesn't write empty sessions Related: #3919 --- system/libraries/Session/drivers/Session_memcached_driver.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index e9246443c..ab3b1d97c 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -209,7 +209,6 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $this->_memcached->replace($this->_lock_key, time(), 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { - if ( $this->_memcached->replace($key, $session_data, $this->_config['expiration']) OR ($this->_memcached->getResultCode() === Memcached::RES_NOTSTORED && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) @@ -222,9 +221,13 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $this->_failure; } - return $this->_memcached->touch($this->_key_prefix.$session_id, $this->_config['expiration']) - ? $this->_success - : $this->_failure; + if ( + $this->_memcached->touch($key, $this->_config['expiration']) + OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) + ) + { + return $this->_success; + } } return $this->_failure; -- cgit v1.2.3-24-g4f1b From 8215e2fcf828964b232e9f48befac4f08fa11187 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 11 Feb 2016 20:30:43 +0200 Subject: [ci skip] Fix Memcached replace() result code checks in CI_Session Related #3919 --- system/libraries/Session/drivers/Session_memcached_driver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index ab3b1d97c..875e72255 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -211,7 +211,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if ( $this->_memcached->replace($key, $session_data, $this->_config['expiration']) - OR ($this->_memcached->getResultCode() === Memcached::RES_NOTSTORED && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) + OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) ) { $this->_fingerprint = $fingerprint; @@ -316,7 +316,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if ( ! $this->_memcached->replace($this->_lock_key, time(), 300)) { - return ($this->_memcached->getResultCode() === Memcached::RES_NOTSTORED) + return ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND) ? $this->_memcached->set($this->_lock_key, time(), 300) : FALSE; } -- cgit v1.2.3-24-g4f1b From 738b9e30404a56a8e2e8053f024550232b72ea09 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 24 Feb 2016 12:14:10 +0200 Subject: Merge pull request #4480 from versalle88/develop Changed class_exists() calls to ignore __autoload() --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index b93c00c15..77c56ae70 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -231,7 +231,7 @@ class CI_Session { } } - if ( ! class_exists($prefix.$class) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$prefix.$class.'.php')) + if ( ! class_exists($prefix.$class, FALSE) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$prefix.$class.'.php')) { require_once($file_path); if (class_exists($prefix.$class, FALSE)) -- cgit v1.2.3-24-g4f1b From f06858c3df09fd33c80f9fc415b6c63b3430869c Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 29 Feb 2016 17:35:12 +0200 Subject: Merge pull request #4491 from roastduck/develop [ci skip] Clean current lock key on close() in redis session driver --- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index ad95309da..7b7951f5d 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -254,7 +254,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle try { if ($this->_redis->ping() === '+PONG') { - isset($this->_lock_key) && $this->_redis->delete($this->_lock_key); + $this->_release_lock(); if ($this->_redis->close() === $this->_failure) { return $this->_failure; -- cgit v1.2.3-24-g4f1b From 215922144082eb4b613e2418ba552776d23ea1db Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 29 Feb 2016 17:38:51 +0200 Subject: [ci skip] Apply #4491 to Memcached driver --- system/libraries/Session/drivers/Session_memcached_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 875e72255..4bd63991f 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -246,7 +246,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if (isset($this->_memcached)) { - isset($this->_lock_key) && $this->_memcached->delete($this->_lock_key); + $this->_release_lock(); if ( ! $this->_memcached->quit()) { return $this->_failure; -- cgit v1.2.3-24-g4f1b From a027a7fd0d770cec0d71e888d8b6f4aa1568ce9f Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 10 Mar 2016 13:59:20 +0200 Subject: Improve ext/session error messages --- system/libraries/Session/Session_driver.php | 20 ++++++++++++++++++++ .../Session/drivers/Session_database_driver.php | 21 ++++++++++----------- .../Session/drivers/Session_memcached_driver.php | 20 ++++++++++---------- .../Session/drivers/Session_redis_driver.php | 22 +++++++++++----------- 4 files changed, 51 insertions(+), 32 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 98fc897e3..55ddb25e0 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -168,4 +168,24 @@ abstract class CI_Session_driver implements SessionHandlerInterface { return TRUE; } + // ------------------------------------------------------------------------ + + /** + * Fail + * + * Drivers other than the 'files' one don't (need to) use the + * session.save_path INI setting, but that leads to confusing + * error messages emitted by PHP when open() or write() fail, + * as the message contains session.save_path ... + * To work around the problem, the drivers will call this method + * so that the INI is set just in time for the error message to + * be properly generated. + * + * @return mixed + */ + protected function _fail() + { + ini_set('session.save_path', config_item('sess_save_path')); + return $this->_failure; + } } diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 3ba9d3d36..da0331220 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -127,7 +127,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if (empty($this->_db->conn_id) && ! $this->_db->db_connect()) { - return $this->_failure; + return $this->_fail(); } return $this->_success; @@ -163,7 +163,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } - if (($result = $this->_db->get()->row()) === NULL) + if ( ! ($result = $this->_db->get()) OR $result->row() === NULL) { // PHP7 will reuse the same SessionHandler object after // ID regeneration, so we need to explicitly set this to @@ -210,7 +210,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return $this->_failure; + return $this->_fail(); } $this->_row_exists = FALSE; @@ -218,7 +218,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan } elseif ($this->_lock === FALSE) { - return $this->_failure; + return $this->_fail(); } if ($this->_row_exists === FALSE) @@ -237,7 +237,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return $this->_success; } - return $this->_failure; + return $this->_fail(); } $this->_db->where('id', $session_id); @@ -260,7 +260,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return $this->_success; } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -275,7 +275,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan public function close() { return ($this->_lock && ! $this->_release_lock()) - ? $this->_failure + ? $this->_fail() : $this->_success; } @@ -304,7 +304,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan if ( ! $this->_db->delete($this->_config['save_path'])) { - return $this->_failure; + return $this->_fail(); } } @@ -314,7 +314,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return $this->_success; } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -334,7 +334,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return ($this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime))) ? $this->_success - : $this->_failure; + : $this->_fail(); } // ------------------------------------------------------------------------ @@ -414,5 +414,4 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return parent::_release_lock(); } - } \ No newline at end of file diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 4bd63991f..88eb4b3a6 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -117,7 +117,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { $this->_memcached = NULL; log_message('error', 'Session: Invalid Memcached save path format: '.$this->_config['save_path']); - return $this->_failure; + return $this->_fail(); } foreach ($matches as $match) @@ -142,7 +142,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa if (empty($server_list)) { log_message('error', 'Session: Memcached server pool is empty.'); - return $this->_failure; + return $this->_fail(); } return $this->_success; @@ -170,7 +170,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $session_data; } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -188,14 +188,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa { if ( ! isset($this->_memcached)) { - return $this->_failure; + return $this->_fail(); } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return $this->_failure; + return $this->_fail(); } $this->_fingerprint = md5(''); @@ -218,7 +218,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $this->_success; } - return $this->_failure; + return $this->_fail(); } if ( @@ -230,7 +230,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa } } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -249,14 +249,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $this->_release_lock(); if ( ! $this->_memcached->quit()) { - return $this->_failure; + return $this->_fail(); } $this->_memcached = NULL; return $this->_success; } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -278,7 +278,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $this->_success; } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 7b7951f5d..cc242dd3d 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -131,7 +131,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if (empty($this->_config['save_path'])) { - return $this->_failure; + return $this->_fail(); } $redis = new Redis(); @@ -153,7 +153,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $this->_success; } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -183,7 +183,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $session_data; } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -201,14 +201,14 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle { if ( ! isset($this->_redis)) { - return $this->_failure; + return $this->_fail(); } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { - return $this->_failure; + return $this->_fail(); } $this->_key_exists = FALSE; @@ -227,15 +227,15 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $this->_success; } - return $this->_failure; + return $this->_fail(); } return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) ? $this->_success - : $this->_failure; + : $this->_fail(); } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ @@ -255,9 +255,9 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle if ($this->_redis->ping() === '+PONG') { $this->_release_lock(); - if ($this->_redis->close() === $this->_failure) + if ($this->_redis->close() === $this->_fail()) { - return $this->_failure; + return $this->_fail(); } } } @@ -296,7 +296,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle return $this->_success; } - return $this->_failure; + return $this->_fail(); } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 7bdd4950da2226859b00042ce9e8b2b9797129a7 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 10 Mar 2016 14:01:09 +0200 Subject: Fix a logical error from last commit --- system/libraries/Session/drivers/Session_database_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index da0331220..317bd7d4d 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -163,7 +163,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } - if ( ! ($result = $this->_db->get()) OR $result->row() === NULL) + if ( ! ($result = $this->_db->get()) OR ($result = $result->row()) === NULL) { // PHP7 will reuse the same SessionHandler object after // ID regeneration, so we need to explicitly set this to -- cgit v1.2.3-24-g4f1b From f56068bfd34e3ebc1325b049bf33901d855c7321 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 11 Mar 2016 11:11:53 +0200 Subject: Revert an unintended change from a027a7fd0d770cec0d71e888d8b6f4aa1568ce9f --- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index cc242dd3d..e4e09fe0d 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -255,7 +255,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle if ($this->_redis->ping() === '+PONG') { $this->_release_lock(); - if ($this->_redis->close() === $this->_fail()) + if ($this->_redis->close() === $this->_failure) { return $this->_fail(); } -- cgit v1.2.3-24-g4f1b From 2c10f60586faf59b9380608c5a9bf01ff2522483 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 15 Mar 2016 14:39:02 +0200 Subject: Add __isset() to CI_Session --- system/libraries/Session/Session.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 77c56ae70..c9d2e8adc 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -583,6 +583,24 @@ class CI_Session { // ------------------------------------------------------------------------ + /** + * __isset() + * + * @param string $key 'session_id' or a session data key + * @return bool + */ + public function __isset($key) + { + if ($key === 'session_id') + { + return (session_status() === PHP_SESSION_ACTIVE); + } + + return isset($_SESSION[$key]); + } + + // ------------------------------------------------------------------------ + /** * __set() * -- cgit v1.2.3-24-g4f1b From 85dfc2a6f76ca95e803535c25877e2aa1c05c38b Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 1 Apr 2016 22:54:15 +0300 Subject: [ci skip] Add some 'debug' log messages to CI_Session --- system/libraries/Session/Session.php | 1 + system/libraries/Session/drivers/Session_database_driver.php | 5 ++++- system/libraries/Session/drivers/Session_files_driver.php | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index c9d2e8adc..1bdc6e5cc 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -91,6 +91,7 @@ class CI_Session { // Note: BC workaround elseif (config_item('sess_use_database')) { + log_message('debug', 'Session: "sess_driver" is empty; using BC fallback to "sess_use_database".'); $this->_driver = 'database'; } diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 317bd7d4d..cb152f91f 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -109,7 +109,10 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan } // Note: BC work-around for the old 'sess_table_name' setting, should be removed in the future. - isset($this->_config['save_path']) OR $this->_config['save_path'] = config_item('sess_table_name'); + if ( ! isset($this->_config['save_path']) && ($this->_config['save_path'] = config_item('sess_table_name'))) + { + log_message('debug', 'Session: "sess_save_path" is empty; using BC fallback to "sess_table_name".'); + } } // ------------------------------------------------------------------------ diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 119bf6572..57c3777a2 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -95,6 +95,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle } else { + log_message('debug', 'Session: "sess_save_path" is empty; using "session.save_path" value from php.ini.'); $this->_config['save_path'] = rtrim(ini_get('session.save_path'), '/\\'); } } -- cgit v1.2.3-24-g4f1b From e13fa9fdb3f2e311bd7331e49b26889f24bc81cb Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 20 May 2016 17:30:07 +0300 Subject: Merge pull request #4638 from kasimtan/phpdoc_fixes [ci skip] Fixed PHPDoc parameter name and type discrepancies --- system/libraries/Session/Session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 1bdc6e5cc..3b391a8ef 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -730,7 +730,7 @@ class CI_Session { * * Legacy CI_Session compatibility method * - * @param mixed $data Session data key(s) + * @param mixed $key Session data key(s) * @return void */ public function unset_userdata($key) -- cgit v1.2.3-24-g4f1b From d680779debb08d1e50fb234ceb63a75b1a2710ed Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 26 May 2016 10:28:04 +0300 Subject: [ci skip] Fix a minor Redis Session bug --- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index e4e09fe0d..8db74c0ca 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -255,7 +255,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle if ($this->_redis->ping() === '+PONG') { $this->_release_lock(); - if ($this->_redis->close() === $this->_failure) + if ($this->_redis->close() === FALSE) { return $this->_fail(); } -- cgit v1.2.3-24-g4f1b From 1748567f5442409d6a8c1e795f56599caff8296e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 28 Jul 2016 15:16:38 +0300 Subject: [ci skip] Fix #3919, #4732 --- system/libraries/Session/drivers/Session_memcached_driver.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 88eb4b3a6..99b4d1baa 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -209,10 +209,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $this->_memcached->replace($this->_lock_key, time(), 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { - if ( - $this->_memcached->replace($key, $session_data, $this->_config['expiration']) - OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) - ) + if ($this->_memcached->set($key, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; return $this->_success; @@ -220,8 +217,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return $this->_fail(); } - - if ( + elseif ( $this->_memcached->touch($key, $this->_config['expiration']) OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) ) -- cgit v1.2.3-24-g4f1b From a838279625becfba98ccb7635d35c67297129c42 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 28 Jul 2016 16:40:12 +0300 Subject: Remove dead code written for PHP 5.2 --- system/libraries/Session/drivers/Session_files_driver.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 57c3777a2..bf4df8b20 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -149,18 +149,9 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle // which re-reads session data if ($this->_file_handle === NULL) { - // Just using fopen() with 'c+b' mode would be perfect, but it is only - // available since PHP 5.2.6 and we have to set permissions for new files, - // so we'd have to hack around this ... - if (($this->_file_new = ! file_exists($this->_file_path.$session_id)) === TRUE) - { - if (($this->_file_handle = fopen($this->_file_path.$session_id, 'w+b')) === FALSE) - { - log_message('error', "Session: File '".$this->_file_path.$session_id."' doesn't exist and cannot be created."); - return $this->_failure; - } - } - elseif (($this->_file_handle = fopen($this->_file_path.$session_id, 'r+b')) === FALSE) + $this->_file_new = ! file_exists($this->_file_path.$session_id); + + if (($this->_file_handle = fopen($this->_file_path.$session_id, 'c+b')) === FALSE) { log_message('error', "Session: Unable to open file '".$this->_file_path.$session_id."'."); return $this->_failure; -- cgit v1.2.3-24-g4f1b From 103a4263fe8c2715f622355ee7d76114d015f242 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 3 Oct 2016 11:19:11 +0300 Subject: Fix #4823 --- .../Session/drivers/Session_files_driver.php | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index bf4df8b20..5f05396c0 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -76,6 +76,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle */ protected $_file_new; + /** + * mbstring.func_override flag + * + * @var bool + */ + protected static $func_override; + // ------------------------------------------------------------------------ /** @@ -98,6 +105,8 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle log_message('debug', 'Session: "sess_save_path" is empty; using "session.save_path" value from php.ini.'); $this->_config['save_path'] = rtrim(ini_get('session.save_path'), '/\\'); } + + isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); } // ------------------------------------------------------------------------ @@ -187,7 +196,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle } $session_data = ''; - for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += strlen($buffer)) + for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += self::strlen($buffer)) { if (($buffer = fread($this->_file_handle, $length - $read)) === FALSE) { @@ -368,4 +377,18 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle return $this->_success; } -} \ No newline at end of file + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_override) + ? mb_strlen($str, '8bit') + : strlen($str); + } +} -- cgit v1.2.3-24-g4f1b From 6c6ee1a1e73b3f8a93ca031107bec35e56272a0a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 22 Oct 2016 16:33:06 +0300 Subject: Close #4830, #3649 --- system/libraries/Session/Session.php | 36 ++++++++++++++++++++-- .../Session/drivers/Session_files_driver.php | 18 +++++++++-- 2 files changed, 48 insertions(+), 6 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 3b391a8ef..5aac12f36 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -57,6 +57,7 @@ class CI_Session { protected $_driver = 'files'; protected $_config; + protected $_sid_regexp; // ------------------------------------------------------------------------ @@ -99,6 +100,7 @@ class CI_Session { // Configuration ... $this->_configure($params); + $this->_config['_sid_regexp'] = $this->_sid_regexp; $class = new $class($this->_config); if ($class instanceof SessionHandlerInterface) @@ -131,7 +133,7 @@ class CI_Session { if (isset($_COOKIE[$this->_config['cookie_name']]) && ( ! is_string($_COOKIE[$this->_config['cookie_name']]) - OR ! preg_match('/^[0-9a-f]{40}$/', $_COOKIE[$this->_config['cookie_name']]) + OR ! preg_match('#\A'.$this->_sid_regexp.'\z#', $_COOKIE[$this->_config['cookie_name']]) ) ) { @@ -315,8 +317,36 @@ class CI_Session { ini_set('session.use_strict_mode', 1); ini_set('session.use_cookies', 1); ini_set('session.use_only_cookies', 1); - ini_set('session.hash_function', 1); - ini_set('session.hash_bits_per_character', 4); + + if (PHP_VERSION_ID < 70100) + { + if ((int) ini_get('session.hash_function') === 0) + { + ini_set('session.hash_function', 1); + ini_set('session.hash_bits_per_character', $bits_per_character = 4); + } + else + { + $bits_per_character = (int) ini_get('session.hash_bits_per_character'); + } + } + elseif ((int) ini_get('session.sid_length') < 40 && ($bits_per_character = (int) ini_get('session.sid_bits_per_character')) === 4) + { + ini_set('session.sid_length', 40); + } + + switch ($bits_per_character) + { + case 4: + $this->_sid_regexp = '[0-9a-f]{40,}'; + break; + case 5: + $this->_sid_regexp = '[0-9a-v]{40,}'; + break; + case 6: + $this->_sid_regexp = '[0-9a-zA-Z,-]{40,}'; + break; + } } // ------------------------------------------------------------------------ diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 5f05396c0..37315d3cd 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -76,6 +76,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle */ protected $_file_new; + /** + * Validate SID regular expression + * + * @var string + */ + protected $_sid_regexp; + /** * mbstring.func_override flag * @@ -106,6 +113,8 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle $this->_config['save_path'] = rtrim(ini_get('session.save_path'), '/\\'); } + $this->_sid_regexp = $this->_config['_sid_regexp']; + isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); } @@ -352,10 +361,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle $ts = time() - $maxlifetime; + $pattern = ($this->_config['match_ip'] === TRUE) + ? '[0-9a-f]{32}' + : ''; + $pattern = sprintf( - '/^%s[0-9a-f]{%d}$/', - preg_quote($this->_config['cookie_name'], '/'), - ($this->_config['match_ip'] === TRUE ? 72 : 40) + '#\A%s'.$pattern.$this->_sid_regexp.'\z#', + preg_quote($this->_config['cookie_name']) ); while (($file = readdir($directory)) !== FALSE) -- cgit v1.2.3-24-g4f1b From 2f760877c313871e5066b93b0b1aa76428c09fb6 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 27 Oct 2016 16:39:12 +0300 Subject: Fix #4874 --- system/libraries/Session/Session.php | 63 ++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 9 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 5aac12f36..ea7853108 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -318,35 +318,80 @@ class CI_Session { ini_set('session.use_cookies', 1); ini_set('session.use_only_cookies', 1); + $this->_configure_sid_length(); + } + + // ------------------------------------------------------------------------ + + /** + * Configure session ID length + * + * To make life easier, we used to force SHA-1 and 4 bits per + * character on everyone. And of course, someone was unhappy. + * + * Then PHP 7.1 broke backwards-compatibility because ext/session + * is such a mess that nobody wants to touch it with a pole stick, + * and the one guy who does, nobody has the energy to argue with. + * + * So we were forced to make changes, and OF COURSE something was + * going to break and now we have this pile of shit. -- Narf + * + * @return void + */ + protected function _configure_sid_length() + { if (PHP_VERSION_ID < 70100) { - if ((int) ini_get('session.hash_function') === 0) + $hash_function = ini_get('session.hash_function'); + if (ctype_digit($hash_function)) + { + if ($hash_function !== '1') + { + ini_set('session.hash_function', 1); + $bits = 160; + } + } + elseif ( ! in_array($hash_function, hash_algos(), TRUE)) { ini_set('session.hash_function', 1); - ini_set('session.hash_bits_per_character', $bits_per_character = 4); + $bits = 160; } - else + elseif (($bits = strlen(hash($hash_function, 'dummy', false)) * 4) < 160) { - $bits_per_character = (int) ini_get('session.hash_bits_per_character'); + ini_set('session.hash_function', 1); + $bits = 160; } + + $bits_per_character = (int) ini_get('session.hash_bits_per_character'); + $sid_length = $bits * $bits_per_character; } - elseif ((int) ini_get('session.sid_length') < 40 && ($bits_per_character = (int) ini_get('session.sid_bits_per_character')) === 4) + else { - ini_set('session.sid_length', 40); + $bits_per_character = (int) ini_get('session.sid_bits_per_character'); + $sid_length = (int) ini_get('session.sid_length'); + if (($bits = $sid_length * $bits_per_character) < 160) + { + // Add as many more characters as necessary to reach at least 160 bits + $sid_length += (int) ceil((160 % $bits) / $bits_per_character); + ini_set('session.sid_length', $sid_length); + } } + // Yes, 4,5,6 are the only known possible values as of 2016-10-27 switch ($bits_per_character) { case 4: - $this->_sid_regexp = '[0-9a-f]{40,}'; + $this->_sid_regexp = '[0-9a-f]'; break; case 5: - $this->_sid_regexp = '[0-9a-v]{40,}'; + $this->_sid_regexp = '[0-9a-v]'; break; case 6: - $this->_sid_regexp = '[0-9a-zA-Z,-]{40,}'; + $this->_sid_regexp = '[0-9a-zA-Z,-]'; break; } + + $this->_sid_regexp .= '{'.$sid_length.'}'; } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From dbc025b6c2c9b0b085bb79dc126bc58fb2a8c2a8 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 27 Oct 2016 17:37:25 +0300 Subject: [ci skip] Another attempt at #4874 --- system/libraries/Session/Session.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index ea7853108..01989d2d7 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -348,8 +348,9 @@ class CI_Session { if ($hash_function !== '1') { ini_set('session.hash_function', 1); - $bits = 160; } + + $bits = 160; } elseif ( ! in_array($hash_function, hash_algos(), TRUE)) { @@ -363,7 +364,7 @@ class CI_Session { } $bits_per_character = (int) ini_get('session.hash_bits_per_character'); - $sid_length = $bits * $bits_per_character; + $sid_length = (int) ceil($bits / $bits_per_character); } else { -- cgit v1.2.3-24-g4f1b From e49aa1f1cb63ad90d6c2d204439f538dcc282243 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 22 Nov 2016 12:02:55 +0200 Subject: Fix #4916 --- system/libraries/Session/drivers/Session_database_driver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index cb152f91f..6a7282b23 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -354,7 +354,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan { if ($this->_platform === 'mysql') { - $arg = $session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : ''); + $arg = md5($session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : '')); if ($this->_db->query("SELECT GET_LOCK('".$arg."', 300) AS ci_session_lock")->row()->ci_session_lock) { $this->_lock = $arg; @@ -417,4 +417,4 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan return parent::_release_lock(); } -} \ No newline at end of file +} -- cgit v1.2.3-24-g4f1b From 6276926c6dcdf976a5f4de34d62f501852e2f84b Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 29 Nov 2016 15:30:30 +0200 Subject: Fix #4923 --- .../Session/drivers/Session_database_driver.php | 10 +++--- .../Session/drivers/Session_memcached_driver.php | 37 ++++++++++------------ .../Session/drivers/Session_redis_driver.php | 27 +++++++--------- 3 files changed, 33 insertions(+), 41 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 6a7282b23..2f5241256 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -208,8 +208,12 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // Prevent previous QB calls from messing with our queries $this->_db->reset_query(); + if ($this->_lock === FALSE) + { + return $this->_fail(); + } // Was the ID regenerated? - if ($session_id !== $this->_session_id) + elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { @@ -219,10 +223,6 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_row_exists = FALSE; $this->_session_id = $session_id; } - elseif ($this->_lock === FALSE) - { - return $this->_fail(); - } if ($this->_row_exists === FALSE) { diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index 99b4d1baa..eb1dcd3d8 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -186,7 +186,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa */ public function write($session_id, $session_data) { - if ( ! isset($this->_memcached)) + if ( ! isset($this->_memcached, $this->_lock_key)) { return $this->_fail(); } @@ -202,28 +202,25 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa $this->_session_id = $session_id; } - if (isset($this->_lock_key)) - { - $key = $this->_key_prefix.$session_id; - - $this->_memcached->replace($this->_lock_key, time(), 300); - if ($this->_fingerprint !== ($fingerprint = md5($session_data))) - { - if ($this->_memcached->set($key, $session_data, $this->_config['expiration'])) - { - $this->_fingerprint = $fingerprint; - return $this->_success; - } + $key = $this->_key_prefix.$session_id; - return $this->_fail(); - } - elseif ( - $this->_memcached->touch($key, $this->_config['expiration']) - OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) - ) + $this->_memcached->replace($this->_lock_key, time(), 300); + if ($this->_fingerprint !== ($fingerprint = md5($session_data))) + { + if ($this->_memcached->set($key, $session_data, $this->_config['expiration'])) { + $this->_fingerprint = $fingerprint; return $this->_success; } + + return $this->_fail(); + } + elseif ( + $this->_memcached->touch($key, $this->_config['expiration']) + OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) + ) + { + return $this->_success; } return $this->_fail(); @@ -375,4 +372,4 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa return TRUE; } -} \ No newline at end of file +} diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index 8db74c0ca..a780100b1 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -199,7 +199,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle */ public function write($session_id, $session_data) { - if ( ! isset($this->_redis)) + if ( ! isset($this->_redis, $this->_lock_key)) { return $this->_fail(); } @@ -215,27 +215,22 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle $this->_session_id = $session_id; } - if (isset($this->_lock_key)) + $this->_redis->setTimeout($this->_lock_key, 300); + if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE) { - $this->_redis->setTimeout($this->_lock_key, 300); - if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE) + if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) { - if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) - { - $this->_fingerprint = $fingerprint; - $this->_key_exists = TRUE; - return $this->_success; - } - - return $this->_fail(); + $this->_fingerprint = $fingerprint; + $this->_key_exists = TRUE; + return $this->_success; } - return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) - ? $this->_success - : $this->_fail(); + return $this->_fail(); } - return $this->_fail(); + return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration'])) + ? $this->_success + : $this->_fail(); } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From da60e9bc66ec90970fbd2dfd08b0a6e66b9f5f5f Mon Sep 17 00:00:00 2001 From: Master Yoda Date: Sat, 31 Dec 2016 08:46:18 -0800 Subject: Update copyright data to 2017 --- system/libraries/Session/Session.php | 4 ++-- system/libraries/Session/Session_driver.php | 4 ++-- system/libraries/Session/drivers/Session_database_driver.php | 4 ++-- system/libraries/Session/drivers/Session_files_driver.php | 4 ++-- system/libraries/Session/drivers/Session_memcached_driver.php | 4 ++-- system/libraries/Session/drivers/Session_redis_driver.php | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 01989d2d7..eb433de64 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 2.0.0 diff --git a/system/libraries/Session/Session_driver.php b/system/libraries/Session/Session_driver.php index 55ddb25e0..f32f14ae0 100644 --- a/system/libraries/Session/Session_driver.php +++ b/system/libraries/Session/Session_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 2f5241256..31f5a4663 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 37315d3cd..6016e094e 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_memcached_driver.php b/system/libraries/Session/drivers/Session_memcached_driver.php index eb1dcd3d8..2556bf0f7 100644 --- a/system/libraries/Session/drivers/Session_memcached_driver.php +++ b/system/libraries/Session/drivers/Session_memcached_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index a780100b1..d260f7b82 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 -- cgit v1.2.3-24-g4f1b From 0642faa79669826603502239b8fc092d0f1a437a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 3 Jan 2017 12:31:41 +0200 Subject: [ci skip] Update year number in remaining files that were recently deleted from develop --- system/libraries/Session/SessionHandlerInterface.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/SessionHandlerInterface.php b/system/libraries/Session/SessionHandlerInterface.php index b3533dd1e..2eef61db8 100644 --- a/system/libraries/Session/SessionHandlerInterface.php +++ b/system/libraries/Session/SessionHandlerInterface.php @@ -6,7 +6,7 @@ * * This content is released under the MIT License (MIT) * - * Copyright (c) 2014 - 2016, British Columbia Institute of Technology + * Copyright (c) 2014 - 2017, British Columbia Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) - * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @copyright Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/) * @license http://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 3.0.0 -- cgit v1.2.3-24-g4f1b From 37226c036a52ae857b13109774b1cdfc4b1d4db9 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 11 Jan 2017 12:05:32 +0200 Subject: [ci skip] Fix an error with DB sessions triggered with regenerate + destroy --- system/libraries/Session/drivers/Session_database_driver.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_database_driver.php b/system/libraries/Session/drivers/Session_database_driver.php index 31f5a4663..b519b782f 100644 --- a/system/libraries/Session/drivers/Session_database_driver.php +++ b/system/libraries/Session/drivers/Session_database_driver.php @@ -208,12 +208,8 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan // Prevent previous QB calls from messing with our queries $this->_db->reset_query(); - if ($this->_lock === FALSE) - { - return $this->_fail(); - } // Was the ID regenerated? - elseif ($session_id !== $this->_session_id) + if (isset($this->_session_id) && $session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { @@ -223,6 +219,10 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan $this->_row_exists = FALSE; $this->_session_id = $session_id; } + elseif ($this->_lock === FALSE) + { + return $this->_fail(); + } if ($this->_row_exists === FALSE) { -- cgit v1.2.3-24-g4f1b From c0c74d5201c171cd6d0cdc2133e63077ebe1a407 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 19 Jan 2017 15:26:35 +0200 Subject: More byte-safety --- system/libraries/Session/drivers/Session_files_driver.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 6016e094e..8860ef667 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -84,11 +84,11 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle protected $_sid_regexp; /** - * mbstring.func_override flag + * mbstring.func_overload flag * * @var bool */ - protected static $func_override; + protected static $func_overload; // ------------------------------------------------------------------------ @@ -115,7 +115,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle $this->_sid_regexp = $this->_config['_sid_regexp']; - isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); + isset(self::$func_overload) OR self::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); } // ------------------------------------------------------------------------ @@ -399,7 +399,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle */ protected static function strlen($str) { - return (self::$func_override) + return (self::$func_overload) ? mb_strlen($str, '8bit') : strlen($str); } -- cgit v1.2.3-24-g4f1b From ee9d428171dc201f51eaffdb62616312915681ff Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 5 Jun 2017 10:44:37 +0300 Subject: [ci skip] Merge pull request #5143 from TysonAndre/misc-phpdoc-nits Fix misc inconsistencies between code and doc comments --- system/libraries/Session/drivers/Session_redis_driver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_redis_driver.php b/system/libraries/Session/drivers/Session_redis_driver.php index d260f7b82..e220a2951 100644 --- a/system/libraries/Session/drivers/Session_redis_driver.php +++ b/system/libraries/Session/drivers/Session_redis_driver.php @@ -51,7 +51,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle /** * phpRedis instance * - * @var resource + * @var Redis */ protected $_redis; -- cgit v1.2.3-24-g4f1b