Page MenuHomeIn-Portal Phabricator

cookie_manager.php
No OneTemporary

File Metadata

Created
Tue, Sep 30, 12:48 AM

cookie_manager.php

<?php
/**
* @version $Id: cookie_manager.php 16731 2022-09-13 13:08:44Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2022 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
final class CookieManager extends kBase
{
/**
* Filters cookies.
*
* @param array $cookies Cookies.
*
* @return array
*/
public function filterAllowed(array $cookies)
{
$ret = array();
$all_cookie_names = array_keys($cookies);
$plain_text_cookies = $this->Application->ConfigValue('PlainTextCookies');
if ( $plain_text_cookies ) {
$plain_text_cookies = array_intersect(explode(',', $plain_text_cookies), $all_cookie_names);
foreach ( $plain_text_cookies as $cookie_name ) {
$ret[$cookie_name] = $cookies[$cookie_name];
}
}
$encrypted_cookies = $this->Application->ConfigValue('EncryptedCookies');
if ( $encrypted_cookies ) {
$encrypted_cookies = explode(',', $encrypted_cookies);
}
else {
// Happens during an upgrade, when "EncryptedCookies" system setting is missing.
$encrypted_cookies = $this->getRequiredEncryptedCookies();
}
$encrypted_cookies = array_intersect($encrypted_cookies, $all_cookie_names);
/** @var SecurityEncrypter $encrypter */
$encrypter = $this->Application->recallObject('SecurityEncrypter');
foreach ( $encrypted_cookies as $cookie_name ) {
try {
$ret[$cookie_name] = $encrypter->decrypt($cookies[$cookie_name]);
}
catch ( LogicException $e ) {
// Can't delete malformed cookie here, because session isn't initialized yet.
trigger_error(
'Error decrypting cookie "' . $cookie_name . '": ' . $e->getMessage(),
E_USER_NOTICE
);
}
}
return $ret;
}
/**
* Returns required encrypted cookies.
*
* @return array
*/
public function getRequiredEncryptedCookies()
{
$session_cookie_name = $this->Application->ConfigValue('SessionCookieName');
return array(
'adm_' . $session_cookie_name,
'adm_' . $session_cookie_name . '_live',
$session_cookie_name,
$session_cookie_name . '_live',
);
}
/**
* Encrypts and tracks a cookie.
*
* @param string $cookie_name Cookie name.
* @param string $cookie_value Cookie value.
*
* @return string
*/
public function encryptAndTrack($cookie_name, $cookie_value)
{
$encrypted_cookies = $this->Application->ConfigValue('EncryptedCookies');
$encrypted_cookies = $encrypted_cookies ? explode(',', $encrypted_cookies) : array();
// Has no effect during an upgrade, because "EncryptedCookies" system setting is absent.
if ( !in_array($cookie_name, $encrypted_cookies) ) {
$encrypted_cookies[] = $cookie_name;
$this->Application->SetConfigValue('EncryptedCookies', implode(',', $encrypted_cookies));
}
/** @var SecurityEncrypter $encrypter */
$encrypter = $this->Application->recallObject('SecurityEncrypter');
// Don't change encrypted cookie value, when it's decrypted value hasn't changed.
if ( array_key_exists($cookie_name, $_COOKIE) ) {
$old_encrypted_value = $_COOKIE[$cookie_name];
$decrypted_cookies = $this->filterAllowed(array(
$cookie_name => $old_encrypted_value,
));
// Decryption was successful and value hasn't changed.
if ( array_key_exists($cookie_name, $decrypted_cookies)
&& $decrypted_cookies[$cookie_name] === $cookie_value
) {
return $old_encrypted_value;
}
}
// Would return different encrypted string for same plain-text string on each call !!!
return $encrypter->encrypt($cookie_value);
}
}

Event Timeline