-
Tim van Dijen authored601185f8
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
<?php
/**
* This file is part of SimpleSAMLphp. See the file COPYING in the root of the distribution for licence information.
*
* This file defines a base class for session handlers that need to store the session id in a cookie. It takes care of
* storing and retrieving the session id.
*
* @package SimpleSAMLphp
* @abstract
*/
declare(strict_types=1);
namespace SimpleSAML;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Utils;
abstract class SessionHandlerCookie extends SessionHandler
{
/**
* This variable contains the current session id.
*
* @var string|null
*/
private ?string $session_id = null;
/**
* This variable contains the session cookie name.
*
* @var string
*/
protected string $cookie_name;
/**
* This constructor initializes the session id based on what we receive in a cookie. We create a new session id and
* set a cookie with this id if we don't have a session id.
*/
protected function __construct()
{
// call the constructor in the base class in case it should become necessary in the future
parent::__construct();
$config = Configuration::getInstance();
$this->cookie_name = $config->getOptionalString('session.cookie.name', 'SimpleSAMLSessionID');
}
/**
* Create a new session id.
*
* @return string The new session id.
*/
public function newSessionId(): string
{
$this->session_id = self::createSessionID();
Session::createSession($this->session_id);
return $this->session_id;
}
/**
* Retrieve the session ID saved in the session cookie, if there's one.
*
* @return string|null The session id saved in the cookie or null if no session cookie was set.
*/
public function getCookieSessionId(): ?string
{
if ($this->session_id === null) {
if ($this->hasSessionCookie()) {
// attempt to retrieve the session id from the cookie
$this->session_id = $_COOKIE[$this->cookie_name];
}
// check if we have a valid session id
if (!is_null($this->session_id) && !self::isValidSessionID($this->session_id)) {
// invalid, disregard this session
return null;
}
}
return $this->session_id;
}
/**
* Retrieve the session cookie name.
*
* @return string The session cookie name.
*/
public function getSessionCookieName(): string
{
return $this->cookie_name;
}
/**
* This static function creates a session id. A session id consists of 32 random hexadecimal characters.
*
* @return string A random session id.
*/
private static function createSessionID(): string
{
return bin2hex(openssl_random_pseudo_bytes(16));
}
/**
* This static function validates a session id. A session id is valid if it only consists of characters which are
* allowed in a session id and it is the correct length.
*
* @param string $session_id The session ID we should validate.
*
* @return boolean True if this session ID is valid, false otherwise.
*/
private static function isValidSessionID(string $session_id): bool
{
if (strlen($session_id) != 32) {
return false;
}
if (preg_match('/[^0-9a-f]/', $session_id)) {
return false;
}
return true;
}
/**
* Check whether the session cookie is set.
*
* This function will only return false if is is certain that the cookie isn't set.
*
* @return boolean True if it was set, false otherwise.
*/
public function hasSessionCookie(): bool
{
return array_key_exists($this->cookie_name, $_COOKIE);
}
/**
* Set a session cookie.
*
* @param string $sessionName The name of the session.
* @param string|null $sessionID The session ID to use. Set to null to delete the cookie.
* @param array|null $cookieParams Additional parameters to use for the session cookie.
*
* @throws \SimpleSAML\Error\CannotSetCookie If we can't set the cookie.
*/
public function setCookie(string $sessionName, ?string $sessionID, array $cookieParams = null): void
{
if ($cookieParams !== null) {
$params = array_merge($this->getCookieParams(), $cookieParams);
} else {
$params = $this->getCookieParams();
}
$httpUtils = new Utils\HTTP();
$httpUtils->setCookie($sessionName, $sessionID, $params, true);
}
}