Source for file session.php

Documentation is available at session.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Platform
  4.  * @subpackage  Session
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. /**
  13.  * Class for managing HTTP sessions
  14.  *
  15.  * Provides access to session-state values as well as session-level
  16.  * settings and lifetime management methods.
  17.  * Based on the standard PHP session handling mechanism it provides
  18.  * more advanced features such as expire timeouts.
  19.  *
  20.  * @package     Joomla.Platform
  21.  * @subpackage  Session
  22.  * @since       11.1
  23.  */
  24. class JSession implements IteratorAggregate
  25. {
  26.     /**
  27.      * Internal state.
  28.      * One of 'inactive'|'active'|'expired'|'destroyed'|'error'
  29.      *
  30.      * @var    string 
  31.      * @see    JSession::getState()
  32.      * @since  11.1
  33.      */
  34.     protected $_state = 'inactive';
  35.  
  36.     /**
  37.      * Maximum age of unused session in minutes
  38.      *
  39.      * @var    string 
  40.      * @since  11.1
  41.      */
  42.     protected $_expire = 15;
  43.  
  44.     /**
  45.      * The session store object.
  46.      *
  47.      * @var    JSessionStorage 
  48.      * @since  11.1
  49.      */
  50.     protected $_store = null;
  51.  
  52.     /**
  53.      * Security policy.
  54.      * List of checks that will be done.
  55.      *
  56.      * Default values:
  57.      * - fix_browser
  58.      * - fix_adress
  59.      *
  60.      * @var    array 
  61.      * @since  11.1
  62.      */
  63.     protected $_security = array('fix_browser');
  64.  
  65.     /**
  66.      * Force cookies to be SSL only
  67.      * Default  false
  68.      *
  69.      * @var    boolean 
  70.      * @since  11.1
  71.      */
  72.     protected $_force_ssl = false;
  73.  
  74.     /**
  75.      * JSession instances container.
  76.      *
  77.      * @var    JSession 
  78.      * @since  11.3
  79.      */
  80.     protected static $instance;
  81.  
  82.     /**
  83.      * The type of storage for the session.
  84.      *
  85.      * @var    string 
  86.      * @since  12.2
  87.      */
  88.     protected $storeName;
  89.  
  90.     /**
  91.      * Holds the JInput object
  92.      *
  93.      * @var    JInput 
  94.      * @since  12.2
  95.      */
  96.     private $_input null;
  97.  
  98.     /**
  99.      * Holds the event dispatcher object
  100.      *
  101.      * @var    JEventDispatcher 
  102.      * @since  12.2
  103.      */
  104.     private $_dispatcher null;
  105.  
  106.     /**
  107.      * Constructor
  108.      *
  109.      * @param   string  $store    The type of storage for the session.
  110.      * @param   array   $options  Optional parameters
  111.      *
  112.      * @since   11.1
  113.      */
  114.     public function __construct($store 'none'array $options array())
  115.     {
  116.         // Need to destroy any existing sessions started with session.auto_start
  117.         if (session_id())
  118.         {
  119.             session_unset();
  120.             session_destroy();
  121.         }
  122.  
  123.         // Disable transparent sid support
  124.         ini_set('session.use_trans_sid''0');
  125.  
  126.         // Only allow the session ID to come from cookies and nothing else.
  127.         ini_set('session.use_only_cookies''1');
  128.  
  129.         // Create handler
  130.         $this->_store = JSessionStorage::getInstance($store$options);
  131.  
  132.         $this->storeName = $store;
  133.  
  134.         // Set options
  135.         $this->_setOptions($options);
  136.  
  137.         $this->_setCookieParams();
  138.  
  139.         $this->_state = 'inactive';
  140.     }
  141.  
  142.     /**
  143.      * Magic method to get read-only access to properties.
  144.      *
  145.      * @param   string  $name  Name of property to retrieve
  146.      *
  147.      * @return  mixed   The value of the property
  148.      *
  149.      * @since   12.2
  150.      */
  151.     public function __get($name)
  152.     {
  153.         if ($name === 'storeName')
  154.         {
  155.             return $this->$name;
  156.         }
  157.  
  158.         if ($name === 'state' || $name === 'expire')
  159.         {
  160.             $property '_' $name;
  161.             return $this->$property;
  162.         }
  163.     }
  164.  
  165.     /**
  166.      * Returns the global Session object, only creating it
  167.      * if it doesn't already exist.
  168.      *
  169.      * @param   string  $handler  The type of session handler.
  170.      * @param   array   $options  An array of configuration options.
  171.      *
  172.      * @return  JSession  The Session object.
  173.      *
  174.      * @since   11.1
  175.      */
  176.     public static function getInstance($handler$options)
  177.     {
  178.         if (!is_object(self::$instance))
  179.         {
  180.             self::$instance new JSession($handler$options);
  181.         }
  182.  
  183.         return self::$instance;
  184.     }
  185.  
  186.     /**
  187.      * Get current state of session
  188.      *
  189.      * @return  string  The session state
  190.      *
  191.      * @since   11.1
  192.      */
  193.     public function getState()
  194.     {
  195.         return $this->_state;
  196.     }
  197.  
  198.     /**
  199.      * Get expiration time in minutes
  200.      *
  201.      * @return  integer  The session expiration time in minutes
  202.      *
  203.      * @since   11.1
  204.      */
  205.     public function getExpire()
  206.     {
  207.         return $this->_expire;
  208.     }
  209.  
  210.     /**
  211.      * Get a session token, if a token isn't set yet one will be generated.
  212.      *
  213.      * Tokens are used to secure forms from spamming attacks. Once a token
  214.      * has been generated the system will check the post request to see if
  215.      * it is present, if not it will invalidate the session.
  216.      *
  217.      * @param   boolean  $forceNew  If true, force a new token to be created
  218.      *
  219.      * @return  string  The session token
  220.      *
  221.      * @since   11.1
  222.      */
  223.     public function getToken($forceNew false)
  224.     {
  225.         $token $this->get('session.token');
  226.  
  227.         // Create a token
  228.         if ($token === null || $forceNew)
  229.         {
  230.             $token $this->_createToken(12);
  231.             $this->set('session.token'$token);
  232.         }
  233.  
  234.         return $token;
  235.     }
  236.  
  237.     /**
  238.      * Method to determine if a token exists in the session. If not the
  239.      * session will be set to expired
  240.      *
  241.      * @param   string   $tCheck       Hashed token to be verified
  242.      * @param   boolean  $forceExpire  If true, expires the session
  243.      *
  244.      * @return  boolean 
  245.      *
  246.      * @since   11.1
  247.      */
  248.     public function hasToken($tCheck$forceExpire true)
  249.     {
  250.         // Check if a token exists in the session
  251.         $tStored $this->get('session.token');
  252.  
  253.         // Check token
  254.         if (($tStored !== $tCheck))
  255.         {
  256.             if ($forceExpire)
  257.             {
  258.                 $this->_state = 'expired';
  259.             }
  260.             return false;
  261.         }
  262.  
  263.         return true;
  264.     }
  265.  
  266.     /**
  267.      * Method to determine a hash for anti-spoofing variable names
  268.      *
  269.      * @param   boolean  $forceNew  If true, force a new token to be created
  270.      *
  271.      * @return  string  Hashed var name
  272.      *
  273.      * @since   11.1
  274.      */
  275.     public static function getFormToken($forceNew false)
  276.     {
  277.         $user    JFactory::getUser();
  278.         $session JFactory::getSession();
  279.  
  280.         // TODO: Decouple from legacy JApplication class.
  281.         if (is_callable(array('JApplication''getHash')))
  282.         {
  283.             $hash JApplication::getHash($user->get('id'0$session->getToken($forceNew));
  284.         }
  285.         else
  286.         {
  287.             $hash md5(JFactory::getApplication()->get('secret'$user->get('id'0$session->getToken($forceNew));
  288.         }
  289.  
  290.         return $hash;
  291.     }
  292.  
  293.     /**
  294.      * Retrieve an external iterator.
  295.      *
  296.      * @return  ArrayIterator  Return an ArrayIterator of $_SESSION.
  297.      *
  298.      * @since   12.2
  299.      */
  300.     public function getIterator()
  301.     {
  302.         return new ArrayIterator($_SESSION);
  303.     }
  304.  
  305.     /**
  306.      * Checks for a form token in the request.
  307.      *
  308.      * Use in conjunction with JHtml::_('form.token') or JSession::getFormToken.
  309.      *
  310.      * @param   string  $method  The request method in which to look for the token key.
  311.      *
  312.      * @return  boolean  True if found and valid, false otherwise.
  313.      *
  314.      * @since   12.1
  315.      */
  316.     public static function checkToken($method 'post')
  317.     {
  318.         $token self::getFormToken();
  319.         $app JFactory::getApplication();
  320.  
  321.         if (!$app->input->$method->get($token'''alnum'))
  322.         {
  323.             $session JFactory::getSession();
  324.             if ($session->isNew())
  325.             {
  326.                 // Redirect to login screen.
  327.                 $app->enqueueMessage(JText::_('JLIB_ENVIRONMENT_SESSION_EXPIRED')'warning');
  328.                 $app->redirect(JRoute::_('index.php'));
  329.             }
  330.             else
  331.             {
  332.                 return false;
  333.             }
  334.         }
  335.         else
  336.         {
  337.             return true;
  338.         }
  339.     }
  340.  
  341.     /**
  342.      * Get session name
  343.      *
  344.      * @return  string  The session name
  345.      *
  346.      * @since   11.1
  347.      */
  348.     public function getName()
  349.     {
  350.         if ($this->_state === 'destroyed')
  351.         {
  352.             // @TODO : raise error
  353.             return null;
  354.         }
  355.         return session_name();
  356.     }
  357.  
  358.     /**
  359.      * Get session id
  360.      *
  361.      * @return  string  The session name
  362.      *
  363.      * @since   11.1
  364.      */
  365.     public function getId()
  366.     {
  367.         if ($this->_state === 'destroyed')
  368.         {
  369.             // @TODO : raise error
  370.             return null;
  371.         }
  372.         return session_id();
  373.     }
  374.  
  375.     /**
  376.      * Get the session handlers
  377.      *
  378.      * @return  array  An array of available session handlers
  379.      *
  380.      * @since   11.1
  381.      */
  382.     public static function getStores()
  383.     {
  384.         $connectors array();
  385.  
  386.         // Get an iterator and loop trough the driver classes.
  387.         $iterator new DirectoryIterator(__DIR__ . '/storage');
  388.  
  389.         foreach ($iterator as $file)
  390.         {
  391.             $fileName $file->getFilename();
  392.  
  393.             // Only load for php files.
  394.             // Note: DirectoryIterator::getExtension only available PHP >= 5.3.6
  395.             if (!$file->isFile(|| substr($fileNamestrrpos($fileName'.'1!= 'php')
  396.             {
  397.                 continue;
  398.             }
  399.  
  400.             // Derive the class name from the type.
  401.             $class str_ireplace('.php''''JSessionStorage' ucfirst(trim($fileName)));
  402.  
  403.             // If the class doesn't exist we have nothing left to do but look at the next type. We did our best.
  404.             if (!class_exists($class))
  405.             {
  406.                 continue;
  407.             }
  408.  
  409.             // Sweet!  Our class exists, so now we just need to know if it passes its test method.
  410.             if ($class::isSupported())
  411.             {
  412.                 // Connector names should not have file extensions.
  413.                 $connectors[str_ireplace('.php'''$fileName);
  414.             }
  415.         }
  416.  
  417.         return $connectors;
  418.     }
  419.  
  420.     /**
  421.      * Shorthand to check if the session is active
  422.      *
  423.      * @return  boolean 
  424.      *
  425.      * @since   12.2
  426.      */
  427.     public function isActive()
  428.     {
  429.         return (bool) ($this->_state == 'active');
  430.     }
  431.  
  432.     /**
  433.      * Check whether this session is currently created
  434.      *
  435.      * @return  boolean  True on success.
  436.      *
  437.      * @since   11.1
  438.      */
  439.     public function isNew()
  440.     {
  441.         $counter $this->get('session.counter');
  442.         return (bool) ($counter === 1);
  443.     }
  444.  
  445.     /**
  446.      * Check whether this session is currently created
  447.      *
  448.      * @param   JInput            $input       JInput object for the session to use.
  449.      * @param   JEventDispatcher  $dispatcher  Dispatcher object for the session to use.
  450.      *
  451.      * @return  void. 
  452.      *
  453.      * @since   12.2
  454.      */
  455.     public function initialise(JInput $inputJEventDispatcher $dispatcher null)
  456.     {
  457.         $this->_input      $input;
  458.         $this->_dispatcher $dispatcher;
  459.     }
  460.  
  461.     /**
  462.      * Get data from the session store
  463.      *
  464.      * @param   string  $name       Name of a variable
  465.      * @param   mixed   $default    Default value of a variable if not set
  466.      * @param   string  $namespace  Namespace to use, default to 'default'
  467.      *
  468.      * @return  mixed  Value of a variable
  469.      *
  470.      * @since   11.1
  471.      */
  472.     public function get($name$default null$namespace 'default')
  473.     {
  474.         // Add prefix to namespace to avoid collisions
  475.         $namespace '__' $namespace;
  476.  
  477.         if ($this->_state !== 'active' && $this->_state !== 'expired')
  478.         {
  479.             // @TODO :: generated error here
  480.             $error null;
  481.             return $error;
  482.         }
  483.  
  484.         if (isset($_SESSION[$namespace][$name]))
  485.         {
  486.             return $_SESSION[$namespace][$name];
  487.         }
  488.         return $default;
  489.     }
  490.  
  491.     /**
  492.      * Set data into the session store.
  493.      *
  494.      * @param   string  $name       Name of a variable.
  495.      * @param   mixed   $value      Value of a variable.
  496.      * @param   string  $namespace  Namespace to use, default to 'default'.
  497.      *
  498.      * @return  mixed  Old value of a variable.
  499.      *
  500.      * @since   11.1
  501.      */
  502.     public function set($name$value null$namespace 'default')
  503.     {
  504.         // Add prefix to namespace to avoid collisions
  505.         $namespace '__' $namespace;
  506.  
  507.         if ($this->_state !== 'active')
  508.         {
  509.             // @TODO :: generated error here
  510.             return null;
  511.         }
  512.  
  513.         $old = isset($_SESSION[$namespace][$name]$_SESSION[$namespace][$namenull;
  514.  
  515.         if (null === $value)
  516.         {
  517.             unset($_SESSION[$namespace][$name]);
  518.         }
  519.         else
  520.         {
  521.             $_SESSION[$namespace][$name$value;
  522.         }
  523.  
  524.         return $old;
  525.     }
  526.  
  527.     /**
  528.      * Check whether data exists in the session store
  529.      *
  530.      * @param   string  $name       Name of variable
  531.      * @param   string  $namespace  Namespace to use, default to 'default'
  532.      *
  533.      * @return  boolean  True if the variable exists
  534.      *
  535.      * @since   11.1
  536.      */
  537.     public function has($name$namespace 'default')
  538.     {
  539.         // Add prefix to namespace to avoid collisions.
  540.         $namespace '__' $namespace;
  541.  
  542.         if ($this->_state !== 'active')
  543.         {
  544.             // @TODO :: generated error here
  545.             return null;
  546.         }
  547.  
  548.         return isset($_SESSION[$namespace][$name]);
  549.     }
  550.  
  551.     /**
  552.      * Unset data from the session store
  553.      *
  554.      * @param   string  $name       Name of variable
  555.      * @param   string  $namespace  Namespace to use, default to 'default'
  556.      *
  557.      * @return  mixed   The value from session or NULL if not set
  558.      *
  559.      * @since   11.1
  560.      */
  561.     public function clear($name$namespace 'default')
  562.     {
  563.         // Add prefix to namespace to avoid collisions
  564.         $namespace '__' $namespace;
  565.  
  566.         if ($this->_state !== 'active')
  567.         {
  568.             // @TODO :: generated error here
  569.             return null;
  570.         }
  571.  
  572.         $value null;
  573.         if (isset($_SESSION[$namespace][$name]))
  574.         {
  575.             $value $_SESSION[$namespace][$name];
  576.             unset($_SESSION[$namespace][$name]);
  577.         }
  578.  
  579.         return $value;
  580.     }
  581.  
  582.     /**
  583.      * Start a session.
  584.      *
  585.      * @return  void 
  586.      *
  587.      * @since   12.2
  588.      */
  589.     public function start()
  590.     {
  591.         if ($this->_state === 'active')
  592.         {
  593.             return;
  594.         }
  595.  
  596.         $this->_start();
  597.  
  598.         $this->_state = 'active';
  599.  
  600.         // Initialise the session
  601.         $this->_setCounter();
  602.         $this->_setTimers();
  603.  
  604.         // Perform security checks
  605.         $this->_validate();
  606.  
  607.         if ($this->_dispatcher instanceof JEventDispatcher)
  608.         {
  609.             $this->_dispatcher->trigger('onAfterSessionStart');
  610.         }
  611.     }
  612.  
  613.     /**
  614.      * Start a session.
  615.      *
  616.      * Creates a session (or resumes the current one based on the state of the session)
  617.      *
  618.      * @return  boolean  true on success
  619.      *
  620.      * @since   11.1
  621.      */
  622.     protected function _start()
  623.     {
  624.         // Start session if not started
  625.         if ($this->_state === 'restart')
  626.         {
  627.             session_regenerate_id(true);
  628.         }
  629.         else
  630.         {
  631.             $session_name session_name();
  632.  
  633.             // Get the JInputCookie object
  634.             $cookie $this->_input->cookie;
  635.  
  636.             if (is_null($cookie->get($session_name)))
  637.             {
  638.                 $session_clean $this->_input->get($session_namefalse'string');
  639.  
  640.                 if ($session_clean)
  641.                 {
  642.                     session_id($session_clean);
  643.                     $cookie->set($session_name''time(3600);
  644.                 }
  645.             }
  646.         }
  647.  
  648.         /**
  649.          * Write and Close handlers are called after destructing objects since PHP 5.0.5.
  650.          * Thus destructors can use sessions but session handler can't use objects.
  651.          * So we are moving session closure before destructing objects.
  652.          *
  653.          * Replace with session_register_shutdown() when dropping compatibility with PHP 5.3
  654.          */
  655.         register_shutdown_function('session_write_close');
  656.  
  657.         session_cache_limiter('none');
  658.         session_start();
  659.  
  660.         return true;
  661.     }
  662.  
  663.     /**
  664.      * Frees all session variables and destroys all data registered to a session
  665.      *
  666.      * This method resets the $_SESSION variable and destroys all of the data associated
  667.      * with the current session in its storage (file or DB). It forces new session to be
  668.      * started after this method is called. It does not unset the session cookie.
  669.      *
  670.      * @return  boolean  True on success
  671.      *
  672.      * @see     session_destroy()
  673.      * @see     session_unset()
  674.      * @since   11.1
  675.      */
  676.     public function destroy()
  677.     {
  678.         // Session was already destroyed
  679.         if ($this->_state === 'destroyed')
  680.         {
  681.             return true;
  682.         }
  683.  
  684.         /*
  685.          * In order to kill the session altogether, such as to log the user out, the session id
  686.          * must also be unset. If a cookie is used to propagate the session id (default behavior),
  687.          * then the session cookie must be deleted.
  688.          */
  689.         if (isset($_COOKIE[session_name()]))
  690.         {
  691.             $config JFactory::getConfig();
  692.             $cookie_domain $config->get('cookie_domain''');
  693.             $cookie_path $config->get('cookie_path''/');
  694.             setcookie(session_name()''time(42000$cookie_path$cookie_domain);
  695.         }
  696.  
  697.         session_unset();
  698.         session_destroy();
  699.  
  700.         $this->_state = 'destroyed';
  701.         return true;
  702.     }
  703.  
  704.     /**
  705.      * Restart an expired or locked session.
  706.      *
  707.      * @return  boolean  True on success
  708.      *
  709.      * @see     JSession::destroy()
  710.      * @since   11.1
  711.      */
  712.     public function restart()
  713.     {
  714.         $this->destroy();
  715.         if ($this->_state !== 'destroyed')
  716.         {
  717.             // @TODO :: generated error here
  718.             return false;
  719.         }
  720.  
  721.         // Re-register the session handler after a session has been destroyed, to avoid PHP bug
  722.         $this->_store->register();
  723.  
  724.         $this->_state = 'restart';
  725.  
  726.         // Regenerate session id
  727.         session_regenerate_id(true);
  728.         $this->_start();
  729.         $this->_state = 'active';
  730.  
  731.         $this->_validate();
  732.         $this->_setCounter();
  733.  
  734.         return true;
  735.     }
  736.  
  737.     /**
  738.      * Create a new session and copy variables from the old one
  739.      *
  740.      * @return  boolean $result true on success
  741.      *
  742.      * @since   11.1
  743.      */
  744.     public function fork()
  745.     {
  746.         if ($this->_state !== 'active')
  747.         {
  748.             // @TODO :: generated error here
  749.             return false;
  750.         }
  751.  
  752.         // Keep session config
  753.         $cookie session_get_cookie_params();
  754.  
  755.         // Kill session
  756.         session_destroy();
  757.  
  758.         // Re-register the session store after a session has been destroyed, to avoid PHP bug
  759.         $this->_store->register();
  760.  
  761.         // Restore config
  762.         session_set_cookie_params($cookie['lifetime']$cookie['path']$cookie['domain']$cookie['secure']true);
  763.  
  764.         // Restart session with new id
  765.         session_regenerate_id(true);
  766.         session_start();
  767.  
  768.         return true;
  769.     }
  770.  
  771.     /**
  772.      * Writes session data and ends session
  773.      *
  774.      * Session data is usually stored after your script terminated without the need
  775.      * to call JSession::close(), but as session data is locked to prevent concurrent
  776.      * writes only one script may operate on a session at any time. When using
  777.      * framesets together with sessions you will experience the frames loading one
  778.      * by one due to this locking. You can reduce the time needed to load all the
  779.      * frames by ending the session as soon as all changes to session variables are
  780.      * done.
  781.      *
  782.      * @return  void 
  783.      *
  784.      * @see     session_write_close()
  785.      * @since   11.1
  786.      */
  787.     public function close()
  788.     {
  789.         session_write_close();
  790.     }
  791.  
  792.     /**
  793.      * Set session cookie parameters
  794.      *
  795.      * @return  void 
  796.      *
  797.      * @since   11.1
  798.      */
  799.     protected function _setCookieParams()
  800.     {
  801.         $cookie session_get_cookie_params();
  802.         if ($this->_force_ssl)
  803.         {
  804.             $cookie['secure'true;
  805.         }
  806.  
  807.         $config JFactory::getConfig();
  808.  
  809.         if ($config->get('cookie_domain'''!= '')
  810.         {
  811.             $cookie['domain'$config->get('cookie_domain');
  812.         }
  813.  
  814.         if ($config->get('cookie_path'''!= '')
  815.         {
  816.             $cookie['path'$config->get('cookie_path');
  817.         }
  818.         session_set_cookie_params($cookie['lifetime']$cookie['path']$cookie['domain']$cookie['secure']true);
  819.     }
  820.  
  821.     /**
  822.      * Create a token-string
  823.      *
  824.      * @param   integer  $length  Length of string
  825.      *
  826.      * @return  string  Generated token
  827.      *
  828.      * @since   11.1
  829.      */
  830.     protected function _createToken($length 32)
  831.     {
  832.         static $chars '0123456789abcdef';
  833.         $max strlen($chars1;
  834.         $token '';
  835.         $name session_name();
  836.         for ($i 0$i $length++$i)
  837.         {
  838.             $token .= $chars[(rand(0$max))];
  839.         }
  840.  
  841.         return md5($token $name);
  842.     }
  843.  
  844.     /**
  845.      * Set counter of session usage
  846.      *
  847.      * @return  boolean  True on success
  848.      *
  849.      * @since   11.1
  850.      */
  851.     protected function _setCounter()
  852.     {
  853.         $counter $this->get('session.counter'0);
  854.         ++$counter;
  855.  
  856.         $this->set('session.counter'$counter);
  857.         return true;
  858.     }
  859.  
  860.     /**
  861.      * Set the session timers
  862.      *
  863.      * @return  boolean  True on success
  864.      *
  865.      * @since   11.1
  866.      */
  867.     protected function _setTimers()
  868.     {
  869.         if (!$this->has('session.timer.start'))
  870.         {
  871.             $start time();
  872.  
  873.             $this->set('session.timer.start'$start);
  874.             $this->set('session.timer.last'$start);
  875.             $this->set('session.timer.now'$start);
  876.         }
  877.  
  878.         $this->set('session.timer.last'$this->get('session.timer.now'));
  879.         $this->set('session.timer.now'time());
  880.  
  881.         return true;
  882.     }
  883.  
  884.     /**
  885.      * Set additional session options
  886.      *
  887.      * @param   array  $options  List of parameter
  888.      *
  889.      * @return  boolean  True on success
  890.      *
  891.      * @since   11.1
  892.      */
  893.     protected function _setOptions(array $options)
  894.     {
  895.         // Set name
  896.         if (isset($options['name']))
  897.         {
  898.             session_name(md5($options['name']));
  899.         }
  900.  
  901.         // Set id
  902.         if (isset($options['id']))
  903.         {
  904.             session_id($options['id']);
  905.         }
  906.  
  907.         // Set expire time
  908.         if (isset($options['expire']))
  909.         {
  910.             $this->_expire $options['expire'];
  911.         }
  912.  
  913.         // Get security options
  914.         if (isset($options['security']))
  915.         {
  916.             $this->_security explode(','$options['security']);
  917.         }
  918.  
  919.         if (isset($options['force_ssl']))
  920.         {
  921.             $this->_force_ssl = (bool) $options['force_ssl'];
  922.         }
  923.  
  924.         // Sync the session maxlifetime
  925.         ini_set('session.gc_maxlifetime'$this->_expire);
  926.  
  927.         return true;
  928.     }
  929.  
  930.     /**
  931.      * Do some checks for security reason
  932.      *
  933.      * - timeout check (expire)
  934.      * - ip-fixiation
  935.      * - browser-fixiation
  936.      *
  937.      * If one check failed, session data has to be cleaned.
  938.      *
  939.      * @param   boolean  $restart  Reactivate session
  940.      *
  941.      * @return  boolean  True on success
  942.      *
  943.      * @see     http://shiflett.org/articles/the-truth-about-sessions
  944.      * @since   11.1
  945.      */
  946.     protected function _validate($restart false)
  947.     {
  948.         // Allow to restart a session
  949.         if ($restart)
  950.         {
  951.             $this->_state 'active';
  952.  
  953.             $this->set('session.client.address'null);
  954.             $this->set('session.client.forwarded'null);
  955.             $this->set('session.client.browser'null);
  956.             $this->set('session.token'null);
  957.         }
  958.  
  959.         // Check if session has expired
  960.         if ($this->_expire)
  961.         {
  962.             $curTime $this->get('session.timer.now'0);
  963.             $maxTime $this->get('session.timer.last'0$this->_expire;
  964.  
  965.             // Empty session variables
  966.             if ($maxTime $curTime)
  967.             {
  968.                 $this->_state 'expired';
  969.                 return false;
  970.             }
  971.         }
  972.  
  973.         // Record proxy forwarded for in the session in case we need it later
  974.         if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
  975.         {
  976.             $this->set('session.client.forwarded'$_SERVER['HTTP_X_FORWARDED_FOR']);
  977.         }
  978.  
  979.         // Check for client address
  980.         if (in_array('fix_adress'$this->_security&& isset($_SERVER['REMOTE_ADDR']))
  981.         {
  982.             $ip $this->get('session.client.address');
  983.  
  984.             if ($ip === null)
  985.             {
  986.                 $this->set('session.client.address'$_SERVER['REMOTE_ADDR']);
  987.             }
  988.             elseif ($_SERVER['REMOTE_ADDR'!== $ip)
  989.             {
  990.                 $this->_state 'error';
  991.                 return false;
  992.             }
  993.         }
  994.  
  995.         // Check for clients browser
  996.         if (in_array('fix_browser'$this->_security&& isset($_SERVER['HTTP_USER_AGENT']))
  997.         {
  998.             $browser $this->get('session.client.browser');
  999.  
  1000.             if ($browser === null)
  1001.             {
  1002.                 $this->set('session.client.browser'$_SERVER['HTTP_USER_AGENT']);
  1003.             }
  1004.             elseif ($_SERVER['HTTP_USER_AGENT'!== $browser)
  1005.             {
  1006.                 // @todo remove code:                 $this->_state    =    'error';
  1007.                 // @todo remove code:                 return false;
  1008.             }
  1009.         }
  1010.  
  1011.         return true;
  1012.     }
  1013. }

Documentation generated on Tue, 19 Nov 2013 15:12:52 +0100 by phpDocumentor 1.4.3