<?php
/**
*
* @author Benjamin Gillissen <hide@address.com>
*
* **************************************************************
Copyright (C) 2009 Benjamin Gillissen
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details at:
http://www.gnu.org/copyleft/gpl.html
* **************************************************************
*/
class cooky {
private $ref, $exp, $dir;
private $crypt; //Ref to crypt object
public function __construct($ref, $exp, $cipher=FALSE, $mode='ECB', $key=NULL){
if ( headers_sent($file, $line) ){
errors::raise('No Cookies operation possible, Output started at : '.$file.':'.$line, CORE_LOG_ERR, 'COOK');
return;
}
$this->ref = $ref;
$this->exp = time()+$exp;
$this->dir = browsing::basedir();
if ( empty($this->dir) ){ $this->dir = '/'; }
if ( FALSE !== $cipher ){ $this->crypt_update($key, $cipher, $mode); } //do we crypt our cookies ?
}
private function crypt_update($key, $cipher, $mode){
$this->crypt = new crypt($cipher, $mode);
$key = CORE::hash($key, 24); //site key.
$lokey = CORE::hash(NULL, 24); //a random key
$enkey = CORE::hash($key.$lokey, 24); //new encryption key, sitekey + randomkey (clientkey)
if ( isset($_COOKIE[$this->ref."_key"]) ){
$this->crypt->setkey($key); //clientkey is crypted using the site key
$ckey = $this->crypt->decrypt($_COOKIE[$this->ref."_key"]); //we got the clear clientkey
$dekey = CORE::hash($key.$ckey, 24); //now we got the cooky decrypt key (site key + client key)
if ( isset($_COOKIE[$this->ref]) ){
$this->crypt->setkey($dekey); //we use computed key to decrypt cookies
$buf = $this->crypt->decrypt($_COOKIE[$this->ref]); //we decrypt
$this->crypt->setkey($enkey); //we use encrypt key to set cookies
$buf = $this->crypt->encrypt($buf); //we reencrypt.
setcookie($this->ref, $buf, $this->exp, $this->dir); //we update client cooky eh,
$_COOKIE[$this->ref] = $buf;
}
}
$this->crypt->setkey($key); //we use the site key to crypt the remote key
$buf = $this->crypt->encrypt($lokey); //we encrypt client key using site key
setcookie($this->ref.'_key', $buf, $this->exp, $this->dir); //we update client key
$this->crypt->setkey($enkey); //we use encrypt key to crypt cookies
}
public function read($var){
if ( !isset($_COOKIE[$this->ref]) ){ return FALSE; }
$buf = urldecode($_COOKIE[$this->ref]);
if ( isset($this->crypt) ){ $buf = $this->crypt->decrypt($buf); }
$buf = unserialize($buf);
if ( ! isset($buf[$var]) ){ return FALSE; }
return ($buf[$var]);
return FALSE;
}
public function isdefined($var){
if ( !isset($_COOKIE[$this->ref]) ){ return FALSE; }
$buf = urldecode($_COOKIE[$this->ref]);
if ( isset($this->crypt) ){ $buf = $this->crypt->decrypt($buf); }
$buf = unserialize($buf);
return isset($buf[$var]);
}
public function set($var, $val){
if ( headers_sent($file, $line) ){
errors::raise('Cookies could not be defined : Output started at : '.$file.':'.$line, CORE_LOG_ERR, 'COOK');
return FALSE;
}
if ( isset($_COOKIE[$this->ref]) ){
$buf = urldecode($_COOKIE[$this->ref]);
if ( isset($this->crypt) ){ $buf = $this->crypt->decrypt($buf); }
$buf = @unserialize($buf);
//errors::raise("Adding Cooky '$var' in channel $this->ref, to already set : ".print_r($buf, TRUE), CORE_LOG_DEBUG, 'COOK');
} else {
//errors::raise("Creating Cooky '$var' in channel $this->ref", CORE_LOG_DEBUG, 'COOK');
$buf = Array();
}
$buf[$var] = $val;
$buf = serialize($buf);
if ( isset($this->crypt) ){ $buf = $this->crypt->encrypt($buf); }
$buf = urlencode($buf);
$r = setcookie($this->ref, $buf, $this->exp, $this->dir);
if ( FALSE === $r ){ return FALSE; }
errors::raise("Cooky '$var' in channel $this->ref, has been defined", CORE_LOG_DEBUG, 'COOK');
$_COOKIE[$this->ref] = $buf;
return TRUE;
}
public function del($var){
if ( headers_sent($file, $line) ){
errors::raise('Cookies could not be unset : Output started at : '.$file.':'.$line, CORE_LOG_ERR, 'COOK');
return FALSE;
}
if ( !isset($_COOKIE[$this->ref]) ){ return TRUE; }
$buf = urldecode($_COOKIE[$this->ref]);
if ( isset($this->crypt) ){ $buf = $this->crypt->decrypt($buf); }
$buf = unserialize($buf);
if ( isset($buf[$var]) ){ unset($buf[$var]); }
$buf = serialize($buf);
if ( isset($this->crypt) ){ $buf = $this->crypt->encrypt($buf); }
$buf = urlencode($buf);
$r = setcookie($this->ref, $buf, $this->exp, $this->dir);
if ( FALSE === $r ){ return FALSE; }
$_COOKIE[$this->ref] = $buf;
}
public function clear(){
if ( headers_sent($file, $line) ){
errors::raise('Cookies channel could not be cleared : Output started at : '.$file.':'.$line, CORE_LOG_ERR, 'COOK');
return FALSE;
}
if ( !isset($_COOKIE[$this->ref]) ){ return TRUE; }
$r = setcookie($this->ref, '', 0, $this->dir);
if ( FALSE === $r ){ return FALSE; }
unset($_COOKIE[$this->ref]);
return TRUE;
}
}