ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
SessionHandlerPHP.php
Go to the documentation of this file.
1 <?php
2 
12 namespace SimpleSAML;
13 
16 
18 {
19 
25  protected $cookie_name;
26 
37  private $previous_session = array();
38 
39 
44  protected function __construct()
45  {
46  // call the parent constructor in case it should become necessary in the future
47  parent::__construct();
48 
50  $this->cookie_name = $config->getString('session.phpsession.cookiename', null);
51 
52  if (function_exists('session_status') && defined('PHP_SESSION_ACTIVE')) { // PHP >= 5.4
53  $previous_session = session_status() === PHP_SESSION_ACTIVE;
54  } else {
55  $previous_session = (session_id() !== '') && (session_name() !== $this->cookie_name);
56  }
57 
58  if ($previous_session) {
59  if (session_name() === $this->cookie_name || $this->cookie_name === null) {
60  Logger::warning(
61  'There is already a PHP session with the same name as SimpleSAMLphp\'s session, or the '.
62  "'session.phpsession.cookiename' configuration option is not set. Make sure to set ".
63  "SimpleSAMLphp's cookie name with a value not used by any other applications."
64  );
65  }
66 
67  /*
68  * We shouldn't have a session at this point, so it might be an application session. Save the details to
69  * retrieve it later and commit.
70  */
71  $this->previous_session['cookie_params'] = session_get_cookie_params();
72  $this->previous_session['id'] = session_id();
73  $this->previous_session['name'] = session_name();
74  session_write_close();
75  }
76 
77  if (!empty($this->cookie_name)) {
78  session_name($this->cookie_name);
79  } else {
80  $this->cookie_name = session_name();
81  }
82 
83  $params = $this->getCookieParams();
84 
85  session_set_cookie_params(
86  $params['lifetime'],
87  $params['path'],
88  $params['domain'],
89  $params['secure'],
90  $params['httponly']
91  );
92 
93  $savepath = $config->getString('session.phpsession.savepath', null);
94  if (!empty($savepath)) {
95  session_save_path($savepath);
96  }
97  }
98 
99 
103  private function sessionStart()
104  {
105  $cacheLimiter = session_cache_limiter();
106  if (headers_sent()) {
107  /*
108  * session_start() tries to send HTTP headers depending on the configuration, according to the
109  * documentation:
110  *
111  * http://php.net/manual/en/function.session-start.php
112  *
113  * If headers have been already sent, it will then trigger an error since no more headers can be sent.
114  * Being unable to send headers does not mean we cannot recover the session by calling session_start(),
115  * so we still want to call it. In this case, though, we want to avoid session_start() to send any
116  * headers at all so that no error is generated, so we clear the cache limiter temporarily (no headers
117  * sent then) and restore it after successfully starting the session.
118  */
119  session_cache_limiter('');
120  }
121  session_cache_limiter($cacheLimiter);
122  @session_start();
123  }
124 
125 
136  public function restorePrevious()
137  {
138  if (empty($this->previous_session)) {
139  return; // nothing to do here
140  }
141 
142  // close our own session
143  session_write_close();
144 
145  session_name($this->previous_session['name']);
146  session_set_cookie_params(
147  $this->previous_session['cookie_params']['lifetime'],
148  $this->previous_session['cookie_params']['path'],
149  $this->previous_session['cookie_params']['domain'],
150  $this->previous_session['cookie_params']['secure'],
151  $this->previous_session['cookie_params']['httponly']
152  );
153  session_id($this->previous_session['id']);
154  $this->previous_session = array();
155  $this->sessionStart();
156 
157  /*
158  * At this point, we have restored a previously-existing session, so we can't continue to use our session here.
159  * Therefore, we need to load our session again in case we need it. We remove this handler from the parent
160  * class so that the handler is initialized again if we ever need to do something with the session.
161  */
162  parent::$sessionHandler = null;
163  }
164 
165 
171  public function newSessionId()
172  {
173  // generate new (secure) session id
174  $sessionId = bin2hex(openssl_random_pseudo_bytes(16));
176 
177  return $sessionId;
178  }
179 
180 
188  public function getCookieSessionId()
189  {
190  if (!self::hasSessionCookie()) {
191  return null; // there's no session cookie, can't return ID
192  }
193 
194  // do not rely on session_id() as it can return the ID of a previous session. Get it from the cookie instead.
195  session_id($_COOKIE[$this->cookie_name]);
196 
197  $session_cookie_params = session_get_cookie_params();
198 
199  if ($session_cookie_params['secure'] && !HTTP::isHTTPS()) {
200  throw new \SimpleSAML_Error_Exception('Session start with secure cookie not allowed on http.');
201  }
202 
203  $this->sessionStart();
204  return session_id();
205  }
206 
207 
213  public function getSessionCookieName()
214  {
215  return $this->cookie_name;
216  }
217 
218 
225  {
226  $_SESSION['SimpleSAMLphp_SESSION'] = serialize($session);
227  }
228 
229 
240  public function loadSession($sessionId = null)
241  {
242  assert('is_string($sessionId) || is_null($sessionId)');
243 
244  if ($sessionId !== null) {
245  if (session_id() === '') {
246  // session not initiated with getCookieSessionId(), start session without setting cookie
247  $ret = ini_set('session.use_cookies', '0');
248  if ($ret === false) {
249  throw new \SimpleSAML_Error_Exception('Disabling PHP option session.use_cookies failed.');
250  }
251 
252  session_id($sessionId);
253  $this->sessionStart();
254  } elseif ($sessionId !== session_id()) {
255  throw new \SimpleSAML_Error_Exception('Cannot load PHP session with a specific ID.');
256  }
257  } elseif (session_id() === '') {
258  self::getCookieSessionId();
259  }
260 
261  if (!isset($_SESSION['SimpleSAMLphp_SESSION'])) {
262  return null;
263  }
264 
265  $session = $_SESSION['SimpleSAMLphp_SESSION'];
266  assert('is_string($session)');
267 
268  $session = unserialize($session);
269 
270  return ($session !== false) ? $session : null;
271  }
272 
273 
281  public function hasSessionCookie()
282  {
283  return array_key_exists($this->cookie_name, $_COOKIE);
284  }
285 
286 
298  public function getCookieParams()
299  {
301 
302  $ret = parent::getCookieParams();
303 
304  if ($config->hasValue('session.phpsession.limitedpath') && $config->hasValue('session.cookie.path')) {
305  throw new \SimpleSAML_Error_Exception(
306  'You cannot set both the session.phpsession.limitedpath and session.cookie.path options.'
307  );
308  } elseif ($config->hasValue('session.phpsession.limitedpath')) {
309  $ret['path'] = $config->getBoolean(
310  'session.phpsession.limitedpath',
311  false
312  ) ? $config->getBasePath() : '/';
313  }
314 
315  $ret['httponly'] = $config->getBoolean('session.phpsession.httponly', true);
316 
317  return $ret;
318  }
319 
320 
330  public function setCookie($sessionName, $sessionID, array $cookieParams = null)
331  {
332  if ($cookieParams === null) {
333  $cookieParams = session_get_cookie_params();
334  }
335 
336  if ($cookieParams['secure'] && !HTTP::isHTTPS()) {
337  throw new CannotSetCookie(
338  'Setting secure cookie on plain HTTP is not allowed.',
339  CannotSetCookie::SECURE_COOKIE
340  );
341  }
342 
343  if (headers_sent()) {
344  throw new CannotSetCookie(
345  'Headers already sent.',
346  CannotSetCookie::HEADERS_SENT
347  );
348  }
349 
350  session_set_cookie_params(
351  $cookieParams['lifetime'],
352  $cookieParams['path'],
353  $cookieParams['domain'],
354  $cookieParams['secure'],
355  $cookieParams['httponly']
356  );
357 
358  if (session_id() !== '') {
359  // session already started, close it
360  session_write_close();
361  }
362 
363  session_id($sessionID);
364  $this->sessionStart();
365  }
366 }
$params
Definition: disable.php:11
$_COOKIE['client_id']
Definition: server.php:9
$_SESSION["AccountId"]
setCookie($sessionName, $sessionID, array $cookieParams=null)
Set a session cookie.
static createSession($sessionId)
Create a new session and cache it.
Definition: Session.php:418
$sessionID
$session
hasSessionCookie()
Check whether the session cookie is set.
getCookieSessionId()
Retrieve the session ID saved in the session cookie, if there&#39;s one.
saveSession(\SimpleSAML_Session $session)
Save the current session to the PHP session array.
Attribute-related utility methods.
sessionStart()
This method starts a session, making sure no warnings are generated due to headers being already sent...
restorePrevious()
Restore a previously-existing session.
Create styles array
The data for the language used.
newSessionId()
Create a new session id.
getCookieParams()
Get the cookie parameters that should be used for session cookies.
$ret
Definition: parser.php:6
loadSession($sessionId=null)
Load the session from the PHP session array.
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'
Definition: bootstrap.php:27
static getInstance($instancename='simplesaml')
Get a configuration file by its instance name.
__construct()
Initialize the PHP session handling.
getSessionCookieName()
Retrieve the session cookie name.