I've faced this problem maybe a week ago and still unable to figure out what is wrong.
I have 2 machines, one is running Windows, the other is running Debian 8.
So the thing is:
On Windows code executes as it should
On Linux it is a total mess
The problem is with sessions, i'm unable to make them work on Linux.
How they work:
Client Access Website --> PHP Creates Session --> Write to DB (ID, Key, Data) --> Get DB Session --> Check if it correct --> Update Data --> User leaves/log out --> Delete session
What i have:
On Windows it works exactly as i described above
On Linux script keep adding values to DB (ID and KEY are identical) and not deleting them after logout
From here i cant use authorization on Linux, but it works perfectly on Windows.
Here is a Sessions Class:
<?php
Class Session
{
public static $DBConnection;
private static $SessionCreated = false;
private static $Salt;
public function __construct($Database)
{
session_set_save_handler(array($this, 'Open'), array($this, 'Close'), array($this, 'Read'), array($this, 'Write'), array($this, 'Destroy'), array($this, 'GarbageCollector'));
register_shutdown_function('session_write_close');
Session::$DBConnection = $Database::$Connection;
$FileLocation = getcwd().DS.'Core'.DS.'Libraries'.DS.'FreedomCore';
$Files = scandir($FileLocation);
for($i = 0; $i < 4; $i++)
unset($Files[$i]);
if(!empty($Files))
{
Session::$Salt = file_get_contents($FileLocation.DS.$Files[4]);
}
else
{
$RandomFileName = substr( "abcdefghijklmnopqrstuvwxyz" ,mt_rand( 0 ,25 ) ,1 ) .substr( md5( time( ) ) ,1 );
$RandomSalt = Session::GenerateRandomSalt();
file_put_contents($FileLocation.DS.$RandomFileName, $RandomSalt);
Session::$Salt = $RandomSalt;
}
}
public static function UpdateSession($Data)
{
if (session_status() != PHP_SESSION_NONE)
foreach($Data as $key=>$value)
$_SESSION[$key] = $value;
}
public static function SessionStatus()
{
if(session_status() == PHP_SESSION_NONE)
return false;
else
return true;
}
private static function GenerateRandomSalt()
{
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789*+|/-';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $charactersLength; $i++)
$randomString .= $characters[rand(0, $charactersLength - 1)];
return $randomString;
}
public static function GenerateCSRFToken()
{
$InitialString = "abcdefghijklmnopqrstuvwxyz1234567890";
$PartOne = substr(str_shuffle($InitialString),0,8);
$PartTwo = substr(str_shuffle($InitialString),0,4);
$PartThree = substr(str_shuffle($InitialString),0,4);
$PartFour = substr(str_shuffle($InitialString),0,4);
$PartFive = substr(str_shuffle($InitialString),0,12);
$FinalCode = $PartOne.'-'.$PartTwo.'-'.$PartThree.'-'.$PartFour.'-'.$PartFive;
$_SESSION['generated_csrf'] = $FinalCode;
return $FinalCode;
}
public static function ValidateCSRFToken($Token)
{
if(isset($Token) && $Token == $_SESSION['generated_csrf'])
{
unset($_SESSION['generated_csrf']);
return true;
}
else
return false;
}
public static function UnsetKeys($Keys)
{
foreach($Keys as $Key)
unset($_SESSION[$Key]);
}
public static function Start($SessionName, $Secure)
{
$HTTPOnly = true;
$Session_Hash = 'sha512';
if(in_array($Session_Hash, hash_algos()))
ini_set('session.hash_function', $Session_Hash);
ini_set('session.hash_bits_per_character', 6);
ini_set('session.use_only_cookies', 1);
$CookieParameters = session_get_cookie_params();
session_set_cookie_params($CookieParameters["lifetime"], $CookieParameters["path"], $CookieParameters["domain"], $Secure, $HTTPOnly);
session_name($SessionName);
session_start();
//session_regenerate_id(true);
Session::$SessionCreated = true;
}
static function Open()
{
if(is_null(Session::$DBConnection))
{
die("Unable to establish connection with database for Secure Session!");
return false;
}
else
return true;
}
static function Close()
{
Session::$DBConnection = null;
return true;
}
static function Read($SessionID)
{
$Statement = Session::$DBConnection->prepare("SELECT data FROM sessions WHERE id = :sessionid LIMIT 1");
$Statement->bindParam(':sessionid', $SessionID);
$Statement->execute();
$Result = $Statement->fetch(PDO::FETCH_ASSOC);
$Key = Session::GetKey($SessionID);
$Data = Session::Decrypt($Result['data'], $Key);
return $Data;
}
static function Write($SessionID, $SessionData)
{
$Key = Session::GetKey($SessionID);
$Data = Session::Encrypt($SessionData, $Key);
$TimeNow = time();
$Statement = Session::$DBConnection->prepare('REPLACE INTO sessions (id, set_time, data, session_key) VALUES (:sessionid, :creation_time, :session_data, :session_key)');
$Statement->bindParam(':sessionid', $SessionID);
$Statement->bindParam(':creation_time', $TimeNow);
$Statement->bindParam(':session_data', $Data);
$Statement->bindParam(':session_key', $Key);
$Statement->execute();
return true;
}
static function Destroy($SessionID)
{
$Statement = Session::$DBConnection->prepare('DELETE FROM sessions WHERE id = :sessionid');
$Statement->bindParam(':sessionid', $SessionID);
$Statement->execute();
Session::$SessionCreated = false;
setcookie("FreedomCoreLanguage", null, time()-3600);
setcookie("FreedomCore", null, time()-3600);
return true;
}
private static function GarbageCollector($Max)
{
$Statement = Session::$DBConnection->prepare('DELETE FROM sessions WHERE set_time < :maxtime');
$OldSessions = time()-$Max;
$Statement->bindParam(':maxtime', $OldSessions);
$Statement->execute();
return true;
}
private static function GetKey($SessionID)
{
$Statement = Session::$DBConnection->prepare('SELECT session_key FROM sessions WHERE id = :sessionid LIMIT 1');
$Statement->bindParam(':sessionid', $SessionID);
$Statement->execute();
$Result = $Statement->fetch(PDO::FETCH_ASSOC);
if($Result['session_key'] != '')
return $Result['session_key'];
else
return hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
}
private static function Encrypt($SessionData, $SessionKey)
{
$Salt = Session::$Salt;
$SessionKey = substr(hash('sha256', $Salt.$SessionKey.$Salt), 0, 32);
$Get_IV_Size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$IV = mcrypt_create_iv($Get_IV_Size, MCRYPT_RAND);
$Encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $SessionKey, $SessionData, MCRYPT_MODE_ECB, $IV));
return $Encrypted;
}
private static function Decrypt($SessionData, $SessionKey)
{
$Salt = Session::$Salt;
$SessionKey = substr(hash('sha256', $Salt.$SessionKey.$Salt), 0, 32);
$Get_IV_Size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$IV = mcrypt_create_iv($Get_IV_Size, MCRYPT_RAND);
$Decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $SessionKey, base64_decode($SessionData), MCRYPT_MODE_ECB, $IV);
return $Decrypted;
}
}
?>
Here is how session initialized:
if(session_status() == PHP_SESSION_NONE)
{
$Session = new Session($Database);
$InstallationIsInProgress = false;
if(isset($_COOKIE['FreedomCore']))
Session::Start('FreedomCore', false);
}
Folder with scripts on github
Important files are Database.FreedomCore.php and Sessions.FreedomCore.php
The main question is:
Why exactly the same code works perfectly on Windows, and cant to work at all on Linux?
P.S. Servers running exactly the same versions of Apache and PHP
Thanks for any help!
Related
I have the following class that I am trying to use to encrypt and decrypt my cookies. I need to store user id in cookies for the Keep Me Logged In feature so that the user stays logged in even if he closes the browser and returns later. The following function that I am using is working fine for the encryption. However, it's not working for decryption. I got this class from this question.
$key = 'alabooencryptionkey';
$iv = AES256Encryption::generateIv();
class AES256Encryption {
public const BLOCK_SIZE = 8;
public const IV_LENGTH = 16;
public const CIPHER = 'AES256';
public static function generateIv(bool $allowLessSecure = false): string {
$success = false;
$random = openssl_random_pseudo_bytes(openssl_cipher_iv_length(static::CIPHER));
if(!$success) {
if (function_exists('sodium_randombytes_random16')) {
$random = sodium_randombytes_random16();
}else{
try {
$random = random_bytes(static::IV_LENGTH);
}catch (Exception $e) {
if($allowLessSecure) {
$permitted_chars = implode('',
array_merge(
range('A', 'z'),
range(0, 9),
str_split('~!##$%&*()-=+{};:"<>,.?/\'')
)
);
$random = '';
for($i = 0; $i < static::IV_LENGTH; $i++) {
$random .= $permitted_chars[mt_rand(0, (static::IV_LENGTH) - 1)];
}
}else{
throw new RuntimeException('Unable to generate initialization vector (IV)');
}
}
}
}
return $random;
}
protected static function getPaddedText(string $plainText): string {
$stringLength = strlen($plainText);
if($stringLength % static::BLOCK_SIZE) {
$plainText = str_pad($plainText, $stringLength + static::BLOCK_SIZE - $stringLength % static::BLOCK_SIZE, "\0");
}
return $plainText;
}
public static function encrypt(string $plainText, string $key, string $iv): string {
$plainText = static::getPaddedText($plainText);
return base64_encode(openssl_encrypt($plainText, static::CIPHER, $key, OPENSSL_RAW_DATA, $iv));
}
public static function decrypt(string $encryptedText, string $key, string $iv): string {
return openssl_decrypt(base64_decode($encryptedText), static::CIPHER, $key, OPENSSL_RAW_DATA, $iv);
}
}
I am using it here for encrypting my cookie which works fine.
function setLoginCookieSession($user){
global $key, $iv;
$_SESSION['newchatapp'] = $user;
setcookie("newchatapp", AES256Encryption::encrypt($user, $key, $iv), time()+3600*24*365*10, '/');
}
And here for decrypting which is not working. It returns nothing.
function sessionUser(){
global $key, $iv;
// return (isset($_SESSION['newchatapp']))?$_SESSION['newchatapp']:AES256Encryption::decrypt($_COOKIE['newchatapp'], $key, $iv);
return AES256Encryption::decrypt($_COOKIE['newchatapp'], $key, $iv);
}
Even if I manually input try to decode the encrypted string it still returns nothing.
echo AES256Encryption::decrypt('ianXhsXhh6MWAHliZoshEA%3D%3D', $key, $iv);
This means that the decryption is not working at all. What can I do to make it work?
I need help with the setting up payTM plugin in opencart v3.0.3.2, I'm getting following error when I click on extension setting:
Parse error: syntax error, unexpected '.', expecting ',' or ';' in
/home2/infipick/public_html/shop/system/library/paytm/PaytmConstants.php on line 14
I'm using php 7.3 on apache server which is hosted online and I used a theme called nutripe by thementic. I fllow all the needed step and getting following issue only on payment plugin.
Here are the files that I'm using of payTM plugin:
PaytmConstants.php
<?php
class PaytmConstants{
CONST TRANSACTION_URL_PRODUCTION = "https://securegw.paytm.in/order/process";
CONST TRANSACTION_STATUS_URL_PRODUCTION = "https://securegw.paytm.in/order/status";
CONST TRANSACTION_URL_STAGING = "https://securegw-stage.paytm.in/order/process";
CONST TRANSACTION_STATUS_URL_STAGING = "https://securegw-stage.paytm.in/order/status";
CONST SAVE_PAYTM_RESPONSE = true;
CONST CHANNEL_ID = "WEB";
CONST APPEND_TIMESTAMP = false;
CONST ONLY_SUPPORTED_INR = true;
CONST X_REQUEST_ID = "PLUGIN_OPENCART_" . VERSION;
CONST MAX_RETRY_COUNT = 3;
CONST CONNECT_TIMEOUT = 10;
CONST TIMEOUT = 10;
CONST LAST_UPDATED = "20200120";
CONST PLUGIN_VERSION = "2.0";
CONST CUSTOM_CALLBACK_URL = "";
}
?>
PaytmHelper.php
<?php
require_once(DIR_SYSTEM . 'library/paytm/PaytmConstants.php');
class PaytmHelper{
/**
* include timestap with order id
*/
public static function getPaytmOrderId($order_id){
if($order_id && PaytmConstants::APPEND_TIMESTAMP){
return $order_id . '_' . date("YmdHis");
}else{
return $order_id;
}
}
/**
* exclude timestap with order id
*/
public static function getOrderId($order_id){
if(($pos = strrpos($order_id, '_')) !== false && PaytmConstants::APPEND_TIMESTAMP) {
$order_id = substr($order_id, 0, $pos);
}
return $order_id;
}
/**
* exclude timestap with order id
*/
public static function getTransactionURL($isProduction = 0){
if($isProduction == 1){
return PaytmConstants::TRANSACTION_URL_PRODUCTION;
}else{
return PaytmConstants::TRANSACTION_URL_STAGING;
}
}
/**
* exclude timestap with order id
*/
public static function getTransactionStatusURL($isProduction = 0){
if($isProduction == 1){
return PaytmConstants::TRANSACTION_STATUS_URL_PRODUCTION;
}else{
return PaytmConstants::TRANSACTION_STATUS_URL_STAGING;
}
}
/**
* check and test cURL is working or able to communicate properly with paytm
*/
public static function validateCurl($transaction_status_url = ''){
if(!empty($transaction_status_url) && function_exists("curl_init")){
$ch = curl_init(trim($transaction_status_url));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
curl_close($ch);
return $res !== false;
}
return false;
}
public static function getcURLversion(){
if(function_exists('curl_version')){
$curl_version = curl_version();
if(!empty($curl_version['version'])){
return $curl_version['version'];
}
}
return false;
}
public static function executecUrl($apiURL, $requestParamList) {
$responseParamList = array();
$JsonData = json_encode($requestParamList);
$postData = 'JsonData='.urlencode($JsonData);
$ch = curl_init($apiURL);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, PaytmConstants::CONNECT_TIMEOUT);
curl_setopt($ch, CURLOPT_TIMEOUT, PaytmConstants::TIMEOUT);
/*
** default value is 2 and we also want to use 2
** so no need to specify since older PHP version might not support 2 as valid value
** see https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html
*/
// curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 2);
// TLS 1.2 or above required
// curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($postData))
);
$jsonResponse = curl_exec($ch);
if (!curl_errno($ch)) {
return json_decode($jsonResponse, true);
} else {
return false;
}
}
}
?>
PaytmChecksum.php
<?php
class PaytmChecksum{
private static $iv = "XXXXXXXXXXXX";
static public function encrypt($input, $key) {
$key = html_entity_decode($key);
if(function_exists('openssl_encrypt')){
$data = openssl_encrypt ( $input , "AES-128-CBC" , $key, 0, self::$iv );
} else {
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, 'cbc');
$input = self::pkcs5Pad($input, $size);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
mcrypt_generic_init($td, $key, self::$iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = base64_encode($data);
}
return $data;
}
static public function decrypt($encrypted, $key) {
$key = html_entity_decode($key);
if(function_exists('openssl_decrypt')){
$data = openssl_decrypt ( $encrypted , "AES-128-CBC" , $key, 0, self::$iv );
} else {
$encrypted = base64_decode($encrypted);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
mcrypt_generic_init($td, $key, self::$iv);
$data = mdecrypt_generic($td, $encrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = self::pkcs5Unpad($data);
$data = rtrim($data);
}
return $data;
}
static public function generateSignature($params, $key) {
if(!is_array($params) && !is_string($params)){
throw new Exception("string or array expected, ".gettype($params)." given");
}
if(is_array($params)){
$params = self::getStringByParams($params);
}
return self::generateSignatureByString($params, $key);
}
static public function verifySignature($params, $key, $checksum){
if(!is_array($params) && !is_string($params)){
throw new Exception("string or array expected, ".gettype($params)." given");
}
if(is_array($params)){
$params = self::getStringByParams($params);
}
return self::verifySignatureByString($params, $key, $checksum);
}
static private function generateSignatureByString($params, $key){
$salt = self::generateRandomString(4);
return self::calculateChecksum($params, $key, $salt);
}
static private function verifySignatureByString($params, $key, $checksum){
$paytm_hash = self::decrypt($checksum, $key);
$salt = substr($paytm_hash, -4);
return $paytm_hash == self::calculateHash($params, $salt) ? true : false;
}
static private function generateRandomString($length) {
$random = "";
srand((double) microtime() * 1000000);
$data = "9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAabcdefghijklmnopqrstuvwxyz!##$&_";
for ($i = 0; $i < $length; $i++) {
$random .= substr($data, (rand() % (strlen($data))), 1);
}
return $random;
}
static private function getStringByParams($params) {
ksort($params);
$params = array_map(function ($value){
return ($value == null) ? "" : $value;
}, $params);
return implode("|", $params);
}
static private function calculateHash($params, $salt){
$finalString = $params . "|" . $salt;
$hash = hash("sha256", $finalString);
return $hash . $salt;
}
static private function calculateChecksum($params, $key, $salt){
$hashString = self::calculateHash($params, $salt);
return self::encrypt($hashString, $key);
}
static private function pkcs5Pad($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
static private function pkcs5Unpad($text) {
$pad = ord($text{strlen($text) - 1});
if ($pad > strlen($text))
return false;
return substr($text, 0, -1 * $pad);
}
}
my script has a problem and gives me this warning:
Warning: session_start(): Failed to read session data: user (path:
/Users/soroush/Documents/www/new/tmp/session) in
/Users/soroush/Documents/www/new/include/class.session.php on line 35
this is my class:
class SecureSessionHandler extends SessionHandler {
protected $key, $name, $cookie;
public function __construct($name = 'MY_SESSION', $cookie = [])
{
$this->key = SESSION_KEY;
$this->name = $name;
$this->cookie = $cookie;
$this->cookie += [
'lifetime' => 0,
'path' => ini_get('session.cookie_path'),
'domain' => ini_get('session.cookie_domain'),
'secure' => isset($_SERVER['HTTPS']),
'httponly' => true
];
$this->setup();
}
private function setup()
{
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
session_name($this->name);
session_set_cookie_params(
$this->cookie['lifetime'],
$this->cookie['path'],
$this->cookie['domain'],
$this->cookie['secure'],
$this->cookie['httponly']
);
}
public function start()
{
if (session_id() === '') {
if (session_start()) {
return mt_rand(0, 4) === 0 ? $this->refresh() : true; // 1/5
}
}
return false;
}
public function forget()
{
if (session_id() === '') {
return false;
}
$_SESSION = [];
setcookie(
$this->name,
'',
time() - 42000,
$this->cookie['path'],
$this->cookie['domain'],
$this->cookie['secure'],
$this->cookie['httponly']
);
return session_destroy();
}
public function refresh()
{
return session_regenerate_id(true);
}
public function read($id)
{
$data = openssl_decrypt(parent::read($id),'AES256',$this->key);
return $data;
}
public function write($id, $data)
{
return parent::write($id, openssl_encrypt(parent::read($id),'AES256',$this->key));
}
public function isExpired($ttl = 30)
{
$last = isset($_SESSION['_last_activity'])
? $_SESSION['_last_activity']
: false;
if ($last !== false && time() - $last > $ttl * 60) {
return true;
}
$_SESSION['_last_activity'] = time();
return false;
}
public function isFingerprint()
{
$hash = md5(
$_SERVER['HTTP_USER_AGENT'] .
(ip2long($_SERVER['REMOTE_ADDR']) & ip2long('255.255.0.0'))
);
if (isset($_SESSION['_fingerprint'])) {
return $_SESSION['_fingerprint'] === $hash;
}
$_SESSION['_fingerprint'] = $hash;
return true;
}
public function isValid()
{
return ! $this->isExpired() && $this->isFingerprint();
}
public function get($name)
{
$parsed = explode('.', $name);
$result = $_SESSION;
while ($parsed) {
$next = array_shift($parsed);
if (isset($result[$next])) {
$result = $result[$next];
} else {
return null;
}
}
return $result;
}
public function put($name, $value)
{
$parsed = explode('.', $name);
$session =& $_SESSION;
while (count($parsed) > 1) {
$next = array_shift($parsed);
if ( ! isset($session[$next]) || ! is_array($session[$next])) {
$session[$next] = [];
}
$session =& $session[$next];
}
$session[array_shift($parsed)] = $value;
}
}
and i use this class like this:
$session = new SecureSessionHandler();
ini_set('session.save_handler', 'files');
session_set_save_handler($session, true);
session_save_path(SITE_PATH.'tmp/session');
$session->start();
if ( ! $session->isValid(5)) {
$session->destroy();
die();
}
$session->put('site.langu', $lang->lang);
but it give me a warning in php 7.1
i use a mac os system and do this works
give 0777 permission to session folder
change chown with php running group and user
what should I do to fix this warning?
i solved this problem with this change:
public function read($id)
{
return (string)openssl_decrypt (parent::read($id) , "aes-256-cbc", $this->key);
}
public function write($id, $data)
{
return parent::write($id, openssl_encrypt($data, "aes-256-cbc", $this->key));
}
viva google :))
After updating to PHP7 I have some problems with my applications sessionhandling.
It doesn't seem to be a big problem but PHP throws this error everytime:
[18-Jun-2016 20:49:10 UTC] PHP Warning: session_decode(): Session is not active. You cannot decode session data in /var/www/app/phpsessionredis.php on line 90
The session_handler is nothing special. It stores JSONified sessiondata to redis etc.
class phpsessionredis implements \SessionHandlerInterface {
public function __construct( &$redis ) {
$this->__rc = $redis;
}
public function open($savePath, $sessionName) {
return true;
}
public function destroy($id) {
try { $this->__rc->del($id); }
catch (\RedisException $e) { return false; }
}
public function close() {
return true;
}
public function write($id, $data) {
session_decode($data); // throws an error
try{
$this->__rc->setex( $id, 3600, json_encode($_SESSION) );
} catch (\RedisException $e) { return false; }
return true;
}
public function read($id) {
try {
$r = $this->__rc
->multi()
->get($id)
->expire($id, 3600)
->exec();
} catch (\RedisException $e) { return false; }
$_SESSION = json_decode( $r[0], true );
if( isset( $_SESSION ) && ! empty( $_SESSION ) && $_SESSION != null ){
return session_encode();
}
return '';
}
public function gc($maxLifetime) {
return true;
}
}
$sessionhandler = new phpsessionredis( $redis );
session_set_save_handler($sessionhandler);
ob_start();
session_start();
Any help is welcome.
I've got the same issue when updating to PHP7.
You get that warning because session_decode() needs an active session, it will populate $_SESSION.
That's not needed, you only want to unserialize the data to be stored into Redis.
This is the best solution i've found.
You can use this class to unserialize the session.
<?php
class Session {
public static function unserialize($session_data) {
$method = ini_get("session.serialize_handler");
switch ($method) {
case "php":
return self::unserialize_php($session_data);
break;
case "php_binary":
return self::unserialize_phpbinary($session_data);
break;
default:
throw new Exception("Unsupported session.serialize_handler: " . $method . ". Supported: php, php_binary");
}
}
private static function unserialize_php($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
if (!strstr(substr($session_data, $offset), "|")) {
throw new Exception("invalid data, remaining: " . substr($session_data, $offset));
}
$pos = strpos($session_data, "|", $offset);
$num = $pos - $offset;
$varname = substr($session_data, $offset, $num);
$offset += $num + 1;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
private static function unserialize_phpbinary($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
$num = ord($session_data[$offset]);
$offset += 1;
$varname = substr($session_data, $offset, $num);
$offset += $num;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
}
?>
Your write() will be:
public function write($id, $data) {
$session_data = Session::unserialize($data);
try{
$this->__rc->setex( $id, 3600, json_encode($session_data) );
} catch (\RedisException $e) { return false; }
return true;
}
I don't know if this should be handled as a correct answer but it is a solution that seems to work.
ini_set('session.serialize_handler', 'php_serialize');
With this option we don't need session_decode and can replace it with unserialze() within the write method.
public function write($id, $data) {
$data = unserialize($data);
/** do something **/
}
For me this looks like a workaround.
Getting php fatal error
PHP Fatal error: Cannot redeclare page_protect() (previously declared
on line 48) on line 103
my code looks like that. What's wrong? Please search for "line 48" and "line 103" in the code
<?php
/*db connection*/
$db=...;
/*ip detection*/
$url="http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
//shared client check
if (!empty($_SERVER['HTTP_CLIENT_IP'])){
$ip=$_SERVER['HTTP_CLIENT_IP'];
//proxy check
}elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip=$_SERVER['REMOTE_ADDR'];
}
$ip = sprintf('%u', ip2long($ip));
/* Registration Type (Automatic or Manual)
1 -> Automatic Registration (Users will receive activation code and they will be automatically approved after clicking activation link)
0 -> Manual Approval (Users will not receive activation code and you will need to approve every user manually)
*/
$user_registration = 1; // set 0 or 1
define("COOKIE_TIME_OUT", 10); //specify cookie timeout in days (default is 10 days)
define('SALT_LENGTH', 9); // salt for password
//define ("ADMIN_NAME", "admin"); // sp
/* Specify user levels */
define ("ADMIN_LEVEL", 5);
define ("USER_LEVEL", 1);
define ("GUEST_LEVEL", 0);
function page_protect() {
/*line 48*/session_start();
global $db;
/* Secure against Session Hijacking by checking user agent */
if (isset($_SESSION['HTTP_USER_AGENT']))
{
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
{
logout();
exit;
}
}
// before we allow sessions, we need to check authentication key - ckey and ctime stored in database
/* If session not set, check for cookies set by Remember me */
if (!isset($_SESSION['id']) && !isset($_SESSION['login']) )
{
if(isset($_COOKIE['id']) && isset($_COOKIE['key'])){
/* we double check cookie expiry time against stored in database */
$cookie_user_id = filter($_COOKIE['id']);
$rs_ctime = $db -> query("select `ckey`,`ctime` from `users` where `id` ='$cookie_user_id'") or die($db->error);
list($ckey,$ctime) = $rs_ctime->fetch_row();
// coookie expiry
if( (time() - $ctime) > 60*60*24*COOKIE_TIME_OUT) {
logout();
}
/* Security check with untrusted cookies - dont trust value stored in cookie.
/* We also do authentication check of the `ckey` stored in cookie matches that stored in database during login*/
if( !empty($ckey) && is_numeric($_COOKIE['id']) && isUserID($_COOKIE['login']) && $_COOKIE['key'] == sha1($ckey) ) {
session_regenerate_id(); //against session fixation attacks.
$_SESSION['id'] = $_COOKIE['id'];
$_SESSION['login'] = $_COOKIE['login'];
/* query user level from database instead of storing in cookies */
$level=$db->query("select user_level from users where id='$_SESSION[id]'");
$_SESSION['level'] = $level->fetch_row();
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
} else {
logout();
}
} else {
if($page!='main'){
header("Location: login.php");
exit();
}
}
}
/*line 103*/ }
function filter($data) {
$data = trim(htmlentities(strip_tags($data)));
global $db;
if (get_magic_quotes_gpc())
$data = stripslashes($data);
$data = $db->real_escape_string($data);
return $data;
}
function EncodeURL($url)
{
$new = strtolower(ereg_replace(' ','_',$url));
return($new);
}
function DecodeURL($url)
{
$new = ucwords(ereg_replace('_',' ',$url));
return($new);
}
function ChopStr($str, $len)
{
if (strlen($str) < $len)
return $str;
$str = substr($str,0,$len);
if ($spc_pos = strrpos($str," "))
$str = substr($str,0,$spc_pos);
return $str . "...";
}
function isEmail($email){
return preg_match('/^\S+#[\w\d.-]{2,}\.[\w]{2,6}$/iU', $email) ? TRUE : FALSE;
}
function isUserID($login)
{
if (preg_match('/^[a-z\d_]{5,20}$/i', $login)) {
return true;
} else {
return false;
}
}
function isURL($url)
{
if (preg_match('/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i', $url)) {
return true;
} else {
return false;
}
}
function checkPwd($x,$y)
{
if(empty($x) || empty($y) ) { return false; }
if (strlen($x) < 4 || strlen($y) < 4) { return false; }
if (strcmp($x,$y) != 0) {
return false;
}
return true;
}
function GenPwd($length = 7)
{
$password = "";
$possible = "0123456789bcdfghjkmnpqrstvwxyz"; //no vowels
$i = 0;
while ($i < $length) {
$char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
if (!strstr($password, $char)) {
$password .= $char;
$i++;
}
}
return $password;
}
function GenKey($length = 7)
{
$password = "";
$possible = "0123456789abcdefghijkmnopqrstuvwxyz";
$i = 0;
while ($i < $length) {
$char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
if (!strstr($password, $char)) {
$password .= $char;
$i++;
}
}
return $password;
}
function logout()
{
global $db;
session_start();
if(isset($_SESSION['id']) || isset($_COOKIE['id'])) {
$db->query("update `users`
set `ckey`= '', `ctime`= ''
where `id`='$_SESSION[id]' OR `id` = '$_COOKIE[id]'") or die($db->error);
}
/************ Delete the sessions****************/
unset($_SESSION['id']);
unset($_SESSION['login']);
unset($_SESSION['level']);
unset($_SESSION['HTTP_USER_AGENT']);
session_unset();
session_destroy();
/* Delete the cookies*******************/
setcookie("id", '', time()-60*60*24*COOKIE_TIME_OUT, "/");
setcookie("login", '', time()-60*60*24*COOKIE_TIME_OUT, "/");
setcookie("key", '', time()-60*60*24*COOKIE_TIME_OUT, "/");
$link = $_SERVER["PHP_SELF"];
header("Location: http://localhost/");
}
// Password and salt generation
function PwdHash($pwd, $salt = null)
{
if ($salt === null) {
$salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
}
else {
$salt = substr($salt, 0, SALT_LENGTH);
}
return $salt . sha1($pwd . $salt);
}
function checkAdmin() {
if($_SESSION['level'] == ADMIN_LEVEL) {
return 1;
} else { return 0 ;
}
}
?>
The function page_protect() is declared twice. Either this function name is already in use in another file in your application, or your includeing this file twice.
It means there is already a function page_protect when you try to define that function. That is, you have two functions page_protect, which is an error. May you are including this file twice.