ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 (session_status() === PHP_SESSION_ACTIVE) {
53  if (session_name() === $this->cookie_name || $this->cookie_name === null) {
54  Logger::warning(
55  'There is already a PHP session with the same name as SimpleSAMLphp\'s session, or the '.
56  "'session.phpsession.cookiename' configuration option is not set. Make sure to set ".
57  "SimpleSAMLphp's cookie name with a value not used by any other applications."
58  );
59  }
60 
61  /*
62  * We shouldn't have a session at this point, so it might be an application session. Save the details to
63  * retrieve it later and commit.
64  */
65  $this->previous_session['cookie_params'] = session_get_cookie_params();
66  $this->previous_session['id'] = session_id();
67  $this->previous_session['name'] = session_name();
68  session_write_close();
69  }
70 
71  if (!empty($this->cookie_name)) {
72  session_name($this->cookie_name);
73  } else {
74  $this->cookie_name = session_name();
75  }
76 
77  $params = $this->getCookieParams();
78 
79  if (!headers_sent()) {
80  session_set_cookie_params(
81  $params['lifetime'],
82  $params['path'],
83  $params['domain'],
84  $params['secure'],
85  $params['httponly']
86  );
87  }
88 
89  $savepath = $config->getString('session.phpsession.savepath', null);
90  if (!empty($savepath)) {
91  session_save_path($savepath);
92  }
93  }
94 
95 
99  private function sessionStart()
100  {
101  $cacheLimiter = session_cache_limiter();
102  if (headers_sent()) {
103  /*
104  * session_start() tries to send HTTP headers depending on the configuration, according to the
105  * documentation:
106  *
107  * http://php.net/manual/en/function.session-start.php
108  *
109  * If headers have been already sent, it will then trigger an error since no more headers can be sent.
110  * Being unable to send headers does not mean we cannot recover the session by calling session_start(),
111  * so we still want to call it. In this case, though, we want to avoid session_start() to send any
112  * headers at all so that no error is generated, so we clear the cache limiter temporarily (no headers
113  * sent then) and restore it after successfully starting the session.
114  */
115  session_cache_limiter('');
116  }
117  session_cache_limiter($cacheLimiter);
118  @session_start();
119  }
120 
121 
132  public function restorePrevious()
133  {
134  if (empty($this->previous_session)) {
135  return; // nothing to do here
136  }
137 
138  // close our own session
139  session_write_close();
140 
141  session_name($this->previous_session['name']);
142  session_set_cookie_params(
143  $this->previous_session['cookie_params']['lifetime'],
144  $this->previous_session['cookie_params']['path'],
145  $this->previous_session['cookie_params']['domain'],
146  $this->previous_session['cookie_params']['secure'],
147  $this->previous_session['cookie_params']['httponly']
148  );
149  session_id($this->previous_session['id']);
150  $this->previous_session = array();
151  $this->sessionStart();
152 
153  /*
154  * At this point, we have restored a previously-existing session, so we can't continue to use our session here.
155  * Therefore, we need to load our session again in case we need it. We remove this handler from the parent
156  * class so that the handler is initialized again if we ever need to do something with the session.
157  */
158  parent::$sessionHandler = null;
159  }
160 
161 
167  public function newSessionId()
168  {
169  // generate new (secure) session id
170  $sessionId = bin2hex(openssl_random_pseudo_bytes(16));
172 
173  return $sessionId;
174  }
175 
176 
184  public function getCookieSessionId()
185  {
186  if (!self::hasSessionCookie()) {
187  return null; // there's no session cookie, can't return ID
188  }
189 
190  // do not rely on session_id() as it can return the ID of a previous session. Get it from the cookie instead.
191  session_id($_COOKIE[$this->cookie_name]);
192 
193  $session_cookie_params = session_get_cookie_params();
194 
195  if ($session_cookie_params['secure'] && !HTTP::isHTTPS()) {
196  throw new \SimpleSAML_Error_Exception('Session start with secure cookie not allowed on http.');
197  }
198 
199  $this->sessionStart();
200  return session_id();
201  }
202 
203 
209  public function getSessionCookieName()
210  {
211  return $this->cookie_name;
212  }
213 
214 
221  {
222  $_SESSION['SimpleSAMLphp_SESSION'] = serialize($session);
223  }
224 
225 
236  public function loadSession($sessionId = null)
237  {
238  assert(is_string($sessionId) || $sessionId === null);
239 
240  if ($sessionId !== null) {
241  if (session_id() === '') {
242  // session not initiated with getCookieSessionId(), start session without setting cookie
243  $ret = ini_set('session.use_cookies', '0');
244  if ($ret === false) {
245  throw new \SimpleSAML_Error_Exception('Disabling PHP option session.use_cookies failed.');
246  }
247 
248  session_id($sessionId);
249  $this->sessionStart();
250  } elseif ($sessionId !== session_id()) {
251  throw new \SimpleSAML_Error_Exception('Cannot load PHP session with a specific ID.');
252  }
253  } elseif (session_id() === '') {
254  self::getCookieSessionId();
255  }
256 
257  if (!isset($_SESSION['SimpleSAMLphp_SESSION'])) {
258  return null;
259  }
260 
261  $session = $_SESSION['SimpleSAMLphp_SESSION'];
262  assert(is_string($session));
263 
264  $session = unserialize($session);
265 
266  return ($session !== false) ? $session : null;
267  }
268 
269 
277  public function hasSessionCookie()
278  {
279  return array_key_exists($this->cookie_name, $_COOKIE);
280  }
281 
282 
294  public function getCookieParams()
295  {
297 
298  $ret = parent::getCookieParams();
299 
300  if ($config->hasValue('session.phpsession.limitedpath') && $config->hasValue('session.cookie.path')) {
301  throw new \SimpleSAML_Error_Exception(
302  'You cannot set both the session.phpsession.limitedpath and session.cookie.path options.'
303  );
304  } elseif ($config->hasValue('session.phpsession.limitedpath')) {
305  $ret['path'] = $config->getBoolean(
306  'session.phpsession.limitedpath',
307  false
308  ) ? $config->getBasePath() : '/';
309  }
310 
311  $ret['httponly'] = $config->getBoolean('session.phpsession.httponly', true);
312 
313  return $ret;
314  }
315 
316 
326  public function setCookie($sessionName, $sessionID, array $cookieParams = null)
327  {
328  if ($cookieParams === null) {
329  $cookieParams = session_get_cookie_params();
330  }
331 
332  if ($cookieParams['secure'] && !HTTP::isHTTPS()) {
333  throw new CannotSetCookie(
334  'Setting secure cookie on plain HTTP is not allowed.',
335  CannotSetCookie::SECURE_COOKIE
336  );
337  }
338 
339  if (headers_sent()) {
340  throw new CannotSetCookie(
341  'Headers already sent.',
342  CannotSetCookie::HEADERS_SENT
343  );
344  }
345 
346  if (session_id() !== '') {
347  // session already started, close it
348  session_write_close();
349  }
350 
351  session_set_cookie_params(
352  $cookieParams['lifetime'],
353  $cookieParams['path'],
354  $cookieParams['domain'],
355  $cookieParams['secure'],
356  $cookieParams['httponly']
357  );
358 
359  session_id($sessionID);
360  $this->sessionStart();
361  }
362 }
$_COOKIE['client_id']
Definition: server.php:9
$_SESSION["AccountId"]
$config
Definition: bootstrap.php:15
setCookie($sessionName, $sessionID, array $cookieParams=null)
Set a session cookie.
static createSession($sessionId)
Create a new session and cache it.
Definition: Session.php:416
$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.
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.
static getInstance($instancename='simplesaml')
Get a configuration file by its instance name.
__construct()
Initialize the PHP session handling.
getSessionCookieName()
Retrieve the session cookie name.