|
// | At web: http://www.code.dearneighbor.com |
// | |
// | Silas Palmer from Australia, wrote the code in sessEncode and |
// | sessDecode member functions. Code used with permission and under GNU |
// | GPL too. Web address: http://www.silaspalmer.com |
// | |
// +----------------------------------------------------------------------+
// | |
// | C H A N G E L O G |
// | ------------------- |
// | |
// | DATE VERSION DESCRIPTION |
// | ---------- ------- ----------------------------------------------- |
// | 05/05/2004 1.0.0 Initial code distribution to the general public |
// | 06/03/2004 1.0.1 sessDecode: removed substr() and added trim(). |
// | 08/08/2004 1.0.2 sessDecode: Initialized $_decoded variable. |
// | _getSecID: Commented out HTTP_ACCEPT_ENCODING. |
// +----------------------------------------------------------------------+
/**
* DB_ESESSION_LOADED - For checking whether the class has been defined. You can
* use DB_ESESSION_LOADED or class_exists().
*
* @access public
* @global bool To indicate this class has been loaded (with an include or require)
*/
define('DB_ESESSION_LOADED', TRUE);
/**
* @package DB_eSession
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @author Lawrence Osiris
* @link http://www.code.dearneighbor.com
* @copyright Copyright © 2004, Lawrence Osiris
* @version $Version: 1.0.0$
* @access public
*/
class DB_eSession
{
/**
* @var string $_ver This scripts version number
* @access private
*/
var $_ver = '1.0.0';
/**
* @var string $_REQ_VER The minimum PHP version number this script
* requires in order to execute successfully.
* @access private
*/
var $_REQ_VER = '4.2.0';
/**
* @var string $_mysql_ver The current MySQL version number
* @access private
*/
var $_mysql_ver = NULL;
/**
* @var int $_dbh The resource link to the session database
* @access private
*/
var $_dbh;
/**
* @var array $_db Holds session database access and table info.
* @access private
*/
var $_db = array();
/**
* @var array $_sess_opt Holds the session configuration option values
* @access private
*/
var $_sess_opt = array();
/**
* @var string $_sess_name Holds the current session name.
* @access private
*/
var $_sess_name = NULL;
/**
* @var int $_sess_ID_len Holds the character length of session ID.
* @access private
*/
var $_sess_ID_len;
/**
* @var string $_DEFAULT_LANG What the default language code is
* @access private
*/
var $_DEFAULT_LANG;
/**
* @var string $_CURRENT_LANG What the current language code in use is
* @access private
*/
var $_CURRENT_LANG;
/**
* @var bool $_stop_on_warn Whether to stop script on encountering a
* warning message. Set $_param['stop_on_warn'].
* @access private
*/
var $_stop_on_warn;
/**
* @var string $_WRN_COLOR Contains font color for warning messages.
* @access private
*/
var $_WRN_COLOR;
/**
* @var string $_WRN_SIZE Contains font size for warning messages.
* @access private
*/
var $_WRN_SIZE;
/**
* @var array $_WRN_MSGS Contains warning message constants for ea. lang.
* @access private
*/
var $_WRN_MSGS;
/**
* @var string $_warnings Contains any non-fatal warning messages
* @access private
*/
var $_warnings = NULL;
/**
* @var bool $_stop_on_error Whether to stop script on encountering an
* error message or not. Set $_param['stop_on_error'].
* @access private
*/
var $_stop_on_error;
/**
* @var string $_ERR_COLOR Contains font color for error messages.
* @access private
*/
var $_ERR_COLOR;
/**
* @var string $_ERR_SIZE Contains font size for error messages.
* @access private
*/
var $_ERR_SIZE;
/**
* @var array $_ERR_MSGS Contains error message constants for ea. lang.
* @access private
*/
var $_ERR_MSGS;
/**
* @var string $_errors Contains error messages encountered
* @access private
*/
var $_errors = NULL;
/**
* @var bool $_DETAIL_ERR_MSGS Display detail errors/warnings or not.
* @access private
*/
var $_DETAIL_ERR_MSGS;
/**
* @var int $_MIN_SESS_ID_LEN Holds the minimum session ID length (12)
* @access private
*/
var $_MIN_SESS_ID_LEN = 12;
/**
* @var int $_MAX_SESS_ID_LEN Holds the maximum session ID length of 32
* @access private
*/
var $_MAX_SESS_ID_LEN = 32;
/**
* @var int $_SESS_LIFE Holds the session life duration in seconds
* @access private
*/
var $_SESS_LIFE;
/**
* @var int $_SESS_TIMEOUT Holds the absolute session life in seconds
* @access private
*/
var $_SESS_TIMEOUT;
/**
* @var int $_SEC_LEVEL Holds a number designating session security level
* @access private
*/
var $_SEC_LEVEL;
/**
* @var bool $_ENCRYPT A flag to turn on session encryption TRUE/FALSE
* @access private
*/
var $_ENCRYPT;
/**
* @var bool $_ENCRYPT_KEY A value used in session encryption/decryption
* @access private
*/
var $_ENCRYPT_KEY;
/**
* @var bool $_ENC_KEY_HASHED An md5 value of $_ENCRYPT_KEY for security.
* @access private
*/
var $_ENC_KEY_HASHED;
/**
* @var bool $_MCRYPT A flag to indicate if mcrypt library installed
* @access private
*/
var $_MCRYPT;
/**
* @var bool $_MCRYPT_LATEST A flag to indicate if it's a newer library
* @access private
*/
var $_MCRYPT_LATEST;
/**
* @var string $_KEY_PREFIX A secret key used in prefixing MD5 hashes
* @access private
*/
var $_KEY_PREFIX;
/**
* @var string $_KEY_SUFFIX A secret key used in suffixing MD5 hashes
* @access private
*/
var $_KEY_SUFFIX;
/**
* @var string $_CONF_PSWD A confirmation password for delete and lock
* @access private
*/
var $_CONF_PSWD;
/**
* @var bool $_MAGIC_QUOTES_GPC Determines if GET/POST/COOKIE data are
* slashed
* @access private
*/
var $_MAGIC_QUOTES_GPC;
/**
* @var bool $_MAGIC_QUOTES_RUNTIME Determines if external source data is
* slashed after reads (like from a DB)
* @access private
*/
var $_MAGIC_QUOTES_RUNTIME;
/**
* @var bool $_ARG_SEP Output argument separator. Usually '&'.
* @access private
*/
var $_ARG_SEP;
/**
* @var bool $_SLASH_ANYWAY Forces addslashes to occur to session data
* @access private
*/
var $_SLASH_ANYWAY;
/**
* @var bool $_STRIP_ANYWAY Forces stripslashes to occur to session data
* @access private
*/
var $_STRIP_ANYWAY;
/**
* @var bool $_GC_DEL_LOCKED Garbage Collection delete locked session T/F
* @access private
*/
var $_GC_DEL_LOCKED;
/**
* DB_eSession - Constructor
* You could change to always pass by reference like this: (&$_param)
* Or you could leave as is, and pass by reference to save on memory, like
* this: $sess = new DB_eSession(&$sess_param);
*
* @param array $_param Various database and session setting options
* @return obj New instance of DB_eSession class
* @access private
*/
function DB_eSession($_param = array())
{
define('STOP', TRUE);
/**
* Check minimum PHP version number for script to work, and
* produce error if it doesn't meet that requirement.
* version_compare() requires PHP v4.1.0 to work but shouldn't
* use here because current PHP might be less than that.
*/
if (strcmp($this->_REQ_VER, PHP_VERSION) > 0) {
$this->_errors = PHP_VERSION . ' < ' . $this->_REQ_VER . "\n";
/**
* Display error and stop execution regardless of _stop_on_error
* setting.
*/
$this->_handleErrors(STOP); // Severe error - exit script
}
if (is_array($_param)) {
$_not_array = NULL;
} else {
$_not_array = 'NOT_ARRAY'; // For producing a warning
$_param = array();
}
/**
* Set the default and current language codes for displaying error and
* warning messages. Default is 'en' for English.
*/
$this->_DEFAULT_LANG = isSet($_param['default_lang']) ?
$_param['default_lang'] : 'en';
$this->_CURRENT_LANG = isSet($_param['current_lang']) ?
$_param['current_lang'] :
isSet($_SERVER['HTTP_ACCEPT_LANGUAGE']) ?
substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) : 'en';
/**
* Set $_param['stop_on_error'] => FALSE to not have this class
* stop execution upon an error. This means you will handle the
* error checking and displays in your script. Default is to stop
* (TRUE). This is used as the initial setting. This can be turned
* on and off at any time by using stopOnErrors() or endStopOnErrors().
*/
$this->_stop_on_error = (bool) isSet($_param['stop_on_error']) ?
$_param['stop_on_error'] : TRUE;
/**
* Set the font color for error messages (any valid HTML syntax)
*/
$this->_ERR_COLOR = isSet($_param['error_color']) ?
$_param['error_color'] : 'RED';
/**
* Set the font size for error messages (any valid HTML syntax)
*/
$this->_ERR_SIZE = isSet($_param['error_size']) ?
$_param['error_size'] : '+0';
/**
* Set $_param['stop_on_warn'] => TRUE to have this class
* stop execution upon a warning. Default is not to stop (FALSE). This
* is used as the initial setting. This can be turned on and off at any
* time by using stopOnWarnings() or endStopOnWarnings().
*/
$this->_stop_on_warn = (bool) isSet($_param['stop_on_warn']) ?
$_param['stop_on_warn'] : FALSE;
/**
* Set the font color for warning messages (any valid HTML syntax)
*/
$this->_WRN_COLOR = isSet($_param['warn_color']) ?
$_param['warn_color'] : 'BLUE';
/**
* Set the font size for warning messages (any valid HTML syntax)
*/
$this->_WRN_SIZE = isSet($_param['warn_size']) ?
$_param['warn_size'] : '+0';
/**
* Set to TRUE to display SQL syntax and other values when displaying
* errors or warning messages encountered. Default is FALSE for security
* purposes. Turn on mostly when in development or testing your site,
* but remember to turn it off for a production ready site.
*/
$this->_DETAIL_ERR_MSGS = (bool) isSet($_param['detail_err_msgs']) ?
$_param['detail_err_msgs'] :
FALSE;
/**
* Set $_param['buffer'] => TRUE to have this class
* execute the ob_start() command to start buffering the output.
* You may want to use if you can't resolve the 'headers already sent'
* warning message generated by PHP/this script. The ob_end_flush()
* is called implicitly at the end of your script. It flushes out the
* contents of the buffer to the browser, and destroys the current
* output buffer.
*/
$_buffer = (bool) isSet($_param['buffer']) ? $_param['buffer'] : FALSE;
if ($_buffer)
ob_start();
/**
* Set the path and filename of the file containing the errors array
* constants. You can use relative (recommended) or absolute file paths.
* For security, specify a filename without the '.php' because the
* class will automatically add '.php' to the end. i.e. If you specify
* 'errors.php' this class will try to locate a file called
* 'errors.php.php'. So, just specify 'errors'. The default path is
* the current directory (where your script is running from), but
* but recommend to put the errors file off the web directory along
* with this class.DB_eSession.php file.
*/
$_errors_path = isSet($_param['errors_path']) ?
$_param['errors_path'] : './';
$_errors_file = isSet($_param['errors_file']) ?
$_param['errors_file'] : 'errors.DB_eSession';
$_filename = $_errors_path . $_errors_file . '.php';
if (($this->pregMatches('/^[a-z0-9_.]+$/i', $_errors_file)) &&
(file_exists($_filename))) {
$_loaded = require_once($_filename);
} else {
$this->_errors = "xxxx --> " . $_filename . " <-- xxxx\n";
$this->_handleErrors(STOP); // Severe error - exit script
}
if ((0 === strcmp($_loaded, 'LOAD_OK')) &&
(isSet($_ERR)) &&
(isSet($_WRN))) {
$this->_ERR_MSGS = $_ERR;
$this->_WRN_MSGS = $_WRN;
unset($_ERR, $_WRN);
} else {
$this->_errors = '$_ERR $_WRN xxxx --> ' . $_filename .
" <-- xxxx\n";
$this->_handleErrors(STOP); // Severe error - exit script
}
if (!empty($_not_array))
// Warning: parameter passed to class is not an array
$this->_setWrnMsg($_not_array);
/**
* Whether or not to encrypt/decrypt the WHOLE session data. This will
* trigger the use of the mcrypt library or sessEncode/sessDecode.
* This can be set on or off on the fly and it will work accordingly.
* The default is off since encryption takes extra resources/time.
*/
$this->_ENCRYPT = (bool) isSet($_param['encrypt']) ?
$_param['encrypt'] : FALSE;
/**
* The key used to encrypt/decrypt individual field data or the whole
* session data. Keep this key a secret (keep off the web directory).
* Use readable characters and make at least 62 UNIQUE characters long.
*/
$this->_ENCRYPT_KEY = isSet($_param['encrypt_key']) ?
$_param['encrypt_key'] :
"z1Mc6KRxAfNwZ0dGjY5qBXhtrPgJO7eCaUmHvQT3yW8nDsI2VkEpiS4blFoLu9";
/**
* Determine if libmcrypt is installed and if it's one of the
* latest versions.
*/
$this->_MCRYPT = extension_loaded('mcrypt');
$this->_MCRYPT_LATEST = FALSE;
if ($this->_MCRYPT) {
if (defined('MCRYPT_TRIPLEDES')) // Only defined in >= 2.4.x
$this->_MCRYPT_LATEST = TRUE;
/**
* The key field used to encrypt/decrypt using the mcrypt library.
*/
$this->_ENC_KEY_HASHED = md5($this->_ENCRYPT_KEY);
$this->_ENC_ALGO = isSet($_param['encrypt_cipher']) ?
$_param['encrypt_cipher'] : MCRYPT_GOST;
$_algo = mcrypt_list_algorithms();
if (!in_array($this->_ENC_ALGO, $_algo)) {
// Could not assign the encryption algorithm...
$this->_setErrMsg('BAD_ALGO', NULL, $this->_ENC_ALGO);
$this->_handleErrors();
$this->_ENC_ALGO = NULL;
}
$this->_ENC_MODE = isSet($_param['encrypt_mode']) ?
$_param['encrypt_mode'] : MCRYPT_MODE_CFB;
$_modes = mcrypt_list_modes();
if (!in_array($this->_ENC_MODE, $_modes)) {
// Could not assign the encryption mode...
$this->_setErrMsg('BAD_ENC_MODE', NULL, $this->_ENC_MODE);
$this->_handleErrors();
$this->_ENC_MODE = NULL;
} else
if (($this->_ENC_MODE != MCRYPT_MODE_ECB) &&
($this->_ENC_MODE != MCRYPT_MODE_CBC) &&
($this->_ENC_MODE != MCRYPT_MODE_CFB) &&
($this->_ENC_MODE != MCRYPT_MODE_OFB)) {
// Could not assign the encryption mode...Use class supported
$this->_setErrMsg('BAD_MODE_SUPP', NULL, $this->_ENC_MODE,
'ECB, CBC, CFB, OFB.');
$this->_handleErrors();
$this->_ENC_MODE = NULL;
}
} else {
$this->_ENC_KEY_HASHED = NULL;
$this->_ENC_ALGO = NULL;
$this->_ENC_MODE = NULL;
}
/**
* As of PHP 4.2.0, there is no need to seed the random number
* generator, however, we'll do it here for portability. This will be
* needed for use with the encryption/decryption mcrypt routines and
* generating of a new session ID.
*/
mt_srand((double)microtime()*1000000);
srand((double)microtime()*1000000);
/**
* See if MD5 hashing keys have been passed, otherwise set defaults.
*/
$this->_KEY_PREFIX = isSet($_param['key_prefix']) ?
$_param['key_prefix'] : 'O9R^3mp#i|34';
$this->_KEY_SUFFIX = isSet($_param['key_suffix']) ?
$_param['key_suffix'] : '+t97!u0K-2L5';
/**
* A password used to pass to the delete all session/lock functions as a
* way to confirm the intent of modifying all rows in the sessions
* table.
*/
$this->_CONF_PSWD = isSet($_param['confirm_pswd']) ?
$_param['confirm_pswd'] : '!*CONFIRMED*!';
/**
* Database related variables with assigned default values when not set.
* Assign these necessary fields to allow connection to the database.
* Remember to give 'sess_user' access privileges to 'db_esessions'.
* Make sure the password is correct (sess1234 is the default).
*/
$this->_db['db_host'] =
isSet($_param['db_host']) ? $_param['db_host'] : 'localhost';
$this->_db['db_user'] =
isSet($_param['db_user']) ? $_param['db_user'] : 'sess_user';
$this->_db['db_pswd'] =
isSet($_param['db_pswd']) ? $_param['db_pswd'] : 'sess1234';
$this->_db['db_name'] =
isSet($_param['db_name']) ? $_param['db_name'] : 'db_esessions';
$this->_db['db_persistent'] =
isSet($_param['db_persistent']) ?
(bool) $_param['db_persistent'] : FALSE;
$this->_db['db_resource'] =
isSet($_param['db_resource']) ? $_param['db_resource'] : NULL;
/**
* Optionally supply a database resource link. This class will NOT
* attempt to connect to MySQL and use the link instead.
*/
if (is_resource($this->_db['db_resource']))
$this->_dbh = $this->_db['db_resource'];
else
$this->_dbh = NULL;
/**
* Table related variables with assigned default values when not set.
* Assign these necessary fields to allow connection to the 'sessions'
* table. Specify what each column name is defined as in the table.
*/
$this->_db['tb_name'] =
isSet($_param['tb_name']) ? $_param['tb_name'] : 'eSessions';
$this->_db['tb_id_col'] =
isSet($_param['tb_id_col']) ? $_param['tb_id_col'] : 'sess_id';
$this->_db['tb_sl_col'] =
isSet($_param['tb_sl_col']) ? $_param['tb_sl_col'] :
'sess_sec_level';
$this->_db['tb_cr_col'] =
isSet($_param['tb_cr_col']) ? $_param['tb_cr_col'] :
'sess_created';
$this->_db['tb_ex_col'] =
isSet($_param['tb_ex_col']) ? $_param['tb_ex_col'] : 'sess_expiry';
$this->_db['tb_to_col'] =
isSet($_param['tb_to_col']) ? $_param['tb_to_col'] :
'sess_timeout';
$this->_db['tb_lk_col'] =
isSet($_param['tb_lk_col']) ? $_param['tb_lk_col'] : 'sess_locked';
$this->_db['tb_vl_col'] =
isSet($_param['tb_vl_col']) ? $_param['tb_vl_col'] : 'sess_value';
$this->_db['tb_iv_col'] =
isSet($_param['tb_iv_col']) ? $_param['tb_iv_col'] : 'sess_enc_iv';
$this->_db['tb_si_col'] =
isSet($_param['tb_si_col']) ? $_param['tb_si_col'] : 'sess_sec_id';
$this->_db['tb_tr_col'] =
isSet($_param['tb_tr_col']) ? $_param['tb_tr_col'] : 'sess_trace';
/**
* Set $_param['sess_id_len'] to be the length of the session ID.
* Default of $this->_MAX_SESS_ID_LEN will be used.
*/
$this->_sess_ID_len = (int)
isSet($_param['sess_id_len']) ? intval($_param['sess_id_len']) :
$this->_MAX_SESS_ID_LEN;
if ($this->_sess_ID_len < $this->_MIN_SESS_ID_LEN)
$this->_sess_ID_len = $this->_MIN_SESS_ID_LEN;
else
if ($this->_sess_ID_len > $this->_MAX_SESS_ID_LEN)
$this->_sess_ID_len = $this->_MAX_SESS_ID_LEN;
/**
* Set $_param['new_sid'] => TRUE to create a new session ID.
* Default is FALSE. Takes effect before a session_start().
* This can be set TRUE without setting $_param['sess_id'], in
* which case, a session ID will be automatically generated.
*/
$_new_sess_ID = (bool)
isSet($_param['new_sid']) ? $_param['new_sid'] : FALSE;
/**
* If desired, set $_param['sess_id'] to a valid custom session ID.
* Works in conjunction with $_param['new_sid'] (must be set to TRUE).
*/
$_sess_ID =
isSet($_param['sess_id']) ? $_param['sess_id'] : NULL;
if (!empty($_sess_ID)) {
if (strlen($_sess_ID) != $this->_sess_ID_len) {
// Warning: Custom session ID passed is not the right length
$this->_setWrnMsg('SESS_LENGTH', NULL, $this->_sess_ID_len,
$_param['sess_id']);
$_sess_ID = NULL;
} else
if (!$this->pregMatches('/^[a-zA-Z0-9]+/', $_sess_ID)) {
// Warning: Custom session ID passed is invalid.
$this->_setWrnMsg('SESS_INVALID', NULL, $_param['sess_id']);
$_sess_ID = NULL;
}
}
/**
* Set $_param['ie_fix'] => TRUE (default) to send a header output to
* fix the IE bug. See further comments below.
*/
$_IE_fix = (bool)
isSet($_param['ie_fix']) ? $_param['ie_fix'] : TRUE;
/**
* When set to TRUE, locked session rows will be deleted right
* away, regardless of their current expiry or timeout settings when
* the Garbage Collection cleanup/delete function is invoked.
*/
$this->_GC_DEL_LOCKED = (bool)
isSet($_param['gc_del_locked']) ? $_param['gc_del_locked'] : FALSE;
/**
* Session Runtime Configurations. See:
* http://us2.php.net/manual/en/ref.session.php
*
* Not all can be set or take effect outside of the php.ini
* configuration file. Some options can be set at runtime without
* an error produced, but have no effect. i.e. session.auto_start
*
* All session options are used here in case there is future support
* to make option take effect at runtime. i.e. session.use_trans_sid
*
* When $_param['stop_on_warn'] is FALSE, check for warning messages
* using warningsExist().
*/
$this->_sess_opt['save_path'] =
isSet($_param['save_path']) ? $_param['save_path'] : 'db_esessions';
if (isSet($_param['name'])) {
// Check to make sure name is only alphanumeric
if (!$this->pregMatches('/^[a-zA-Z0-9]+/', $_param['name'])) {
// Warning: Session configuration option session.name alpha
$this->_setWrnMsg('NAME_INVALID', NULL, $_param['name']);
$this->_sess_opt['name'] = 'eSESSION';
} else {
$this->_sess_opt['name'] = $_param['name'];
}
} else {
$this->_sess_opt['name'] = 'eSESSION';
}
$this->_sess_opt['save_handler'] =
isSet($_param['save_handler']) ? $_param['save_handler'] : 'user';
if (isSet($_param['auto_start']))
$this->_sess_opt['auto_start'] = (bool) $_param['auto_start'];
if (isSet($_param['gc_probability']))
$this->_sess_opt['gc_probability'] = (int)
(0 == intval($_param['gc_probability'])) ?
10 : intval($_param['gc_probability']);
if (isSet($_param['gc_divisor']))
$this->_sess_opt['gc_divisor'] = (int)
(0 == intval($_param['gc_divisor'])) ?
100 : intval($_param['gc_divisor']);
/**
* There maybe a bug with sessions lifetime under Windows and FAT32 in
* PHP version 4.1.0/1/2. See: http://bugs.php.net/bug.php?id=14798
*/
if (isSet($_param['gc_maxlifetime']))
$this->_sess_opt['gc_maxlifetime'] =
intval($_param['gc_maxlifetime']);
if (isSet($_param['serialize_handler']))
$this->_sess_opt['serialize_handler'] =
$_param['serialize_handler'];
if (isSet($_param['cookie_lifetime']))
$this->_sess_opt['cookie_lifetime'] =
intval($_param['cookie_lifetime']);
if (isSet($_param['cookie_path']))
$this->_sess_opt['cookie_path'] = $_param['cookie_path'];
if (isSet($_param['cookie_domain']))
$this->_sess_opt['cookie_domain'] = $_param['cookie_domain'];
if (isSet($_param['cookie_secure'])) {
$this->_sess_opt['cookie_secure'] = $_param['cookie_secure'];
if ((0 === strcmp($this->_sess_opt['cookie_secure'], '1')) &&
(!$this->secureConnection())) {
// Warning: You are setting session.cookie_secure - not secure
$this->_setWrnMsg('NOT_SECURE');
}
}
if (isSet($_param['use_cookies']))
$this->_sess_opt['use_cookies'] = (bool) $_param['use_cookies'];
if ((isSet($_param['use_only_cookies'])) &&
(version_compare(PHP_VERSION, '4.3.0', '>=')))
$this->_sess_opt['use_only_cookies'] =
(bool) $_param['use_only_cookies'];
if (isSet($_param['referer_check']))
$this->_sess_opt['referer_check'] = $_param['referer_check'];
if (isSet($_param['entropy_file']))
$this->_sess_opt['entropy_file'] = $_param['entropy_file'];
if (isSet($_param['entropy_length']))
$this->_sess_opt['entropy_length'] =
intval($_param['entropy_length']);
if (isSet($_param['cache_limiter']))
$this->_sess_opt['cache_limiter'] = $_param['cache_limiter'];
if (isSet($_param['cache_expire'])) // For PHP version >= 4.2.0
$this->_sess_opt['cache_expire'] = intval($_param['cache_expire']);
if (isSet($_param['bug_compat_42']))
$this->_sess_opt['bug_compat_42'] = (bool) $_param['bug_compat_42'];
if (isSet($_param['bug_compat_warn']))
$this->_sess_opt['bug_compat_warn'] = (bool)
$_param['bug_compat_warn'];
if (version_compare(PHP_VERSION, '5.0.0', '>=')) {
// session.use_trans_sid can be changed in a script from v5.0.0 on
if (isSet($_param['use_trans_sid']))
$this->_sess_opt['use_trans_sid'] = $_param['use_trans_sid'];
if (isSet($_param['hash_function']))
$this->_sess_opt['hash_function'] = $_param['hash_function'];
if (isSet($_param['hash_bits_per_character']))
$this->_sess_opt['hash_bits_per_character'] =
$_param['hash_bits_per_character'];
}
/**
* Set session configuration options. Values will remain during the
* script's execution, and will be restored at the script's ending.
*/
foreach ($this->_sess_opt as $_key => $_value) {
if (FALSE === $this->_setSessOption($_key, $_value))
// Warning: Session configuration option ... not assigned
$this->_setWrnMsg('SESS_OPTION', NULL, $_key, $_value);
}
/**
* Support for url_rewriter.tags option since it relates to sessions.
* Example: Like you might want to add the iframe=src to it, as in:
* a=href,area=href,frame=src,iframe=src,form=,fieldset=,input=src
*/
if (isSet($_param['tags'])) {
if (FALSE === $this->_setSessOption('url_rewriter.tags',
$_param['tags'],
FALSE))
// Warning: Configuration option [url_rewriter.tags] not assign
$this->_setWrnMsg('URL_TAGS', NULL, $_param['tags']);
}
/**
* Security Level: A numerical method to represent access authority for
* current session/web page. The lower the number means the higher the
* security clearance. In other words, security level 5 can only access
* all level 5 or higher session/web pages, and nothing lower than 5.
* Range 0-255. The default is 128. For administration or sensitive pages
* use 0 (zero) or 1 (one) as a value. A security level can't be changed
* after a session has been created. So, the first time the session
* is created with a set security level, it dictates the access
* authority for the rest of that active session.
*/
$this->_SEC_LEVEL = isSet($_param['security_level']) ?
intval($_param['security_level']) : 128;
/**
* Get current setting of sessions life duration in seconds.
* This is the number of seconds that is allowed to pass since
* the last time the session data was accessed.
* Otherwise, default it to 1440 seconds (24 minutes).
*/
$this->_SESS_LIFE = intval(ini_get('session.gc_maxlifetime'));
$this->_SESS_LIFE = (int) ($this->_SESS_LIFE < 1) ?
1440 : $this->_SESS_LIFE;
/**
* Calculates maximum life of session in seconds. It's three times
* the length of gc_maxlifetime (for the default). For example: if
* gc_maxlifetime is 1440 seconds (24 minutes), then session
* timeout maximum is set to 4320 seconds (72 minutes). The timeout
* value can't be less than the gc_maxlifetime value.
*/
if (isSet($_param['timeout'])) {
$this->_SESS_TIMEOUT = (int)
(intval($_param['timeout']) < $this->_SESS_LIFE) ?
$this->_SESS_LIFE * 3 : intval($_param['timeout']);
} else {
$this->_SESS_TIMEOUT = (int) $this->_SESS_LIFE * 3;
}
/**
* Must not send any HTML output before session_start() is invoked.
* Set a warning message if HTML headers have been sent to the browser.
* Exception: ob_start() for buffering.
*/
if (!$_buffer) {
if (version_compare(PHP_VERSION, '4.3.0', '>=')) {
$_filename = '';
$_linenbr = (int) 0;
if (headers_sent($_filename, $_linenbr)) {
// Warning: HTTP headers already sent - with detail
$this->_setWrnMsg('HEADER_SENT_1', NULL, $_filename,
$_linenbr);
}
} else
if (headers_sent()) {
// Warning: HTTP headers have already been sent - no detail
$this->_setWrnMsg('HEADER_SENT_2');
}
}
/**
* Assign session storage tasks to methods in this class.
*/
if (!session_set_save_handler(array(&$this, '_sessDBOpen'),
array(&$this, '_sessDBClose'),
array(&$this, '_sessDBRead'),
array(&$this, '_sessDBWrite'),
array(&$this, '_sessDBDestroy'),
array(&$this, '_sessDBGC')
)) {
// execution of session_set_save_handler() failed
$this->_setErrMsg('HANDLER_FAIL');
$this->_handleErrors(STOP); // Severe error - exit script
}
$this->_sess_name = session_name();
/**
* Set whether the magic quotes GPC that effects slashing quotes of
* GET/POST/COOKIE data is set.
*/
$this->_MAGIC_QUOTES_GPC = (bool) get_magic_quotes_gpc();
/**
* Set whether the magic quotes runtime that effects slashing quotes of
* external data sources is set.
*/
$this->_MAGIC_QUOTES_RUNTIME = (bool) get_magic_quotes_runtime();
$this->_ARG_SEP = ('' == ini_get('arg_separator.output')) ? '&' :
ini_get('arg_separator.output');
/**
* Set TRUE to force addslashes() to occur on session data regardless
* of the magic quotes runtime option setting. Default is on (TRUE).
* If you find that data has slashes incorrectly, then turn this off.
*/
$this->_SLASH_ANYWAY = (bool) isSet($_param['slash_anyway']) ?
$_param['slash_anyway'] : TRUE;
/**
* Set TRUE to force stripslashes() to occur on encrypted session data
* regardless of the magic quotes runtime option setting. The default
* is on (TRUE). If you find that data is saved incorrectly, then
* turn this off.
*/
$this->_STRIP_ANYWAY = (bool) isSet($_param['strip_anyway']) ?
$_param['strip_anyway'] : TRUE;
/**
* Try and save the current session ID if one is defined already.
*/
if (isSet($_COOKIE[$this->_sess_name]))
$_sess_id_set = $_COOKIE[$this->_sess_name];
else
if (isSet($GLOBALS[$this->_sess_name]))
$_sess_id_set = $GLOBALS[$this->_sess_name];
else
$_sess_id_set = NULL;
/**
* Create a new session ID when requested, or when the session ID length
* is less than the standard maximum if a session hasn't been started
* or created already ($_COOKIE or $GLOBALS[$this->_sess_name]).
*/
if (($_new_sess_ID) ||
(($this->_sess_ID_len < $this->_MAX_SESS_ID_LEN) &&
(!isSet($_COOKIE[$this->_sess_name])) &&
(!isSet($GLOBALS[$this->_sess_name])))) {
$this->_setNewSessID($_sess_ID);
}
/**
* When warning flag is set and there's warning messages, stop
* execution here. No point in proceeding.
*/
$this->_handleErrors();
/**
* By default this class will do a session_start(), however, you may
* want to turn it off when using the maintenance type of functions.
*/
$_do_sess_start = (bool) isSet($_param['session_start']) ?
$_param['session_start'] : TRUE;
/**
* When session start is requested and $_SESSION doesn't exist, it
* means that the auto start option is not on, and no session_start()
* has been invoked yet. So, start a session. This is safer than
* checking the 'session.auto_start' configuration setting with
* ini_get(). Otherwise, just make a manual connection to the DB for
* now (to make the maintenance type of member functions available for
* use). You would then have to invoke the session_start() from within
* your script (if desired). If the session is started in your script,
* then another call to _sessDBOpen will be invoked but it will be
* handled alright.
*/
if (($_do_sess_start) &&
(!isSet($_SESSION)))
session_start();
else
if (!$_do_sess_start)
$this->_sessDBOpen($this->_sess_opt['save_path'], $this->_sess_name);
/**
* If there was a previous session ID set and we now have a new one,
* then delete the old session row right away without waiting for it to
* expire first (for security reasons).
*/
if (($_do_sess_start) &&
(!empty($_sess_id_set))) {
if (0 !== strcmp($_sess_id_set, session_id()))
$this->deleteSession($_sess_id_set);
}
/**
* There is a form bug in IE v6 while using PHP sessions which causes
* the loss of filled-in information when returning to the form, after
* already leaving the form page (by any means). A work around is to use
* the HTTP 1.1 header "Cache-Control: private"
*/
if ($_IE_fix)
$this->sendCacheHeader('private');
} // End of DB_eSession Constructor
/**
* _formatFont - Formats the HTML font color and size attributes to the
* text that's passed to it.
*
* @param string $_text Text or the data to be enclosed in the font attr.
* @param string $_color The font color to use (any valid HTML syntax).
* @param string $_size The font size to use (any valid HTML syntax).
* @return string Returns the text with the font and size attributes added.
* @access private
*/
function _formatFont($_text, $_color = 'BLACK', $_size = '+0')
{
if (empty($_color))
$_color = 'BLACK';
if (empty($_size))
$_size = '+0';
return '' .
$_text . '';
}
/**
* _setErrMsg - Sets an error message. Fills-in any passed values in order
* to produce a formatted error message.
*
* @param string $_errMsgKey Name of key to match against array of errors.
* @param string $_SQL The value of the last executed SQL command (if any).
* @param mixed Pass one to many arguments to use as fill-in values for
* the error messages.
* @return bool Returns TRUE when error message set, or FALSE on failure.
* @access private
*/
function _setErrMsg ($_errMsgKey = '', $_SQL = NULL)
{
$_lang = $this->_CURRENT_LANG;
if (!isSet($this->_ERR_MSGS[$_errMsgKey][$_lang])) {
if (isSet($this->_ERR_MSGS[$_errMsgKey][$this->_DEFAULT_LANG])) {
// Error message not found in current lang; switching to def.
$_lang = $this->_DEFAULT_LANG;
} else {
// Could not find the supplied key of error message
$this->_errors .= '$_ERR[\'' . $_errMsgKey . "']\n";
return FALSE;
}
}
if (@func_num_args() > 2) { // Do we have extra argument values?
$_arg = @func_get_args();
array_shift($_arg); // Remove $_errMsgKey value passed
array_shift($_arg); // Remove $_SQL value passed
$_cnt = count($_arg);
/**
* Create a pattern for the number of arguments passed
*/
$_patterns = str_repeat('/%s/i,', $_cnt);
$_patterns = explode(',', $_patterns);
array_pop($_patterns); // Remove extra entry created by explode
/**
* When no detail requested, replace argument values with [xxx]
*/
for ($i = 0; $i < $_cnt; $i++) {
if ($this->_DETAIL_ERR_MSGS)
// Slash $ signs that's in the data for displaying correctly
$_arg[$i] = str_replace('$', '\$', $_arg[$i]);
else
$_arg[$i] = '[xxx]';
}
/**
* Replace the '%s' place holder with argument values passed
* sprintf() doesn't allow array arguments.
*/
$_err = @preg_replace($_patterns,
$_arg,
$this->_ERR_MSGS[$_errMsgKey][$_lang],
1
);
} else { // No extra arguments were passed
$_err = $this->_ERR_MSGS[$_errMsgKey][$_lang];
}
if (!empty($_SQL)) {
switch ($this->_DETAIL_ERR_MSGS) {
case TRUE:
$_err .= "SQL: $_SQL\nErr # " .
@mysql_errno($this->_dbh) . ': ' .
@mysql_error($this->_dbh) . "\n";
break;
default:
$_err .= "SQL Err # " .
@mysql_errno($this->_dbh) . ': ' .
@mysql_error($this->_dbh) . "\n";
}
}
$this->_errors .= $_err;
return TRUE;
}
/**
* _setWrnMsg - Sets a warning message. Fills-in any passed values in order
* to produce a formatted warning message.
*
* @param string $_wrnMsgKey Name of key to match against array of warnings
* @param string $_SQL The value of the last executed SQL command (if any).
* @param mixed Pass one to many arguments to use as fill-in values for
* the warning messages.
* @return bool Returns TRUE when warning message set, or FALSE on failure
* @access private
*/
function _setWrnMsg ($_wrnMsgKey = '', $_SQL = NULL)
{
$_lang = $this->_CURRENT_LANG;
if (!isSet($this->_WRN_MSGS[$_wrnMsgKey][$_lang])) {
if (isSet($this->_WRN_MSGS[$_wrnMsgKey][$this->_DEFAULT_LANG])) {
// Warning message not found in current lang; switching to def.
$_lang = $this->_DEFAULT_LANG;
} else {
// Could not find the supplied key of warning message
$this->_warnings .= '$_WRN[\'' . $_wrnMsgKey . "']\n";
return FALSE;
}
}
if (@func_num_args() > 2) { // Do we have extra argument values?
$_arg = @func_get_args();
array_shift($_arg); // Remove $_wrnMsgKey value passed
array_shift($_arg); // Remove $_SQL value passed
$_cnt = count($_arg);
/**
* Create a pattern for the number of arguments passed
*/
$_patterns = str_repeat('/%s/i,', $_cnt);
$_patterns = explode(',', $_patterns);
array_pop($_patterns); // Remove extra entry created by explode
/**
* When no detail requested, replace argument values with [xxx]
*/
for ($i = 0; $i < $_cnt; $i++) {
if ($this->_DETAIL_ERR_MSGS)
// Slash $ signs that's in the data for displaying correctly
$_arg[$i] = str_replace('$', '\$', $_arg[$i]);
else
$_arg[$i] = '[xxx]';
}
/**
* Replace the '%s' place holder with argument values passed
* sprintf() doesn't allow array arguments.
*/
$_wrn = @preg_replace($_patterns,
$_arg,
$this->_WRN_MSGS[$_wrnMsgKey][$_lang],
1
);
} else { // No extra arguments were passed
$_wrn = $this->_WRN_MSGS[$_wrnMsgKey][$_lang];
}
if (!empty($_SQL)) {
switch ($this->_DETAIL_ERR_MSGS) {
case TRUE:
$_wrn .= "SQL: $_SQL\nErr # " .
@mysql_errno($this->_dbh) . ': ' .
@mysql_error($this->_dbh) . "\n";
break;
default:
$_wrn .= "SQL Err # " .
@mysql_errno($this->_dbh) . ': ' .
@mysql_error($this->_dbh) . "\n";
}
}
$this->_warnings .= $_wrn;
return TRUE;
}
/**
* _handleErrors - Detects if errors have occurred and ends the script when
* the flag is set to stop. Errors are always displayed before warnings.
*
* @param bool $_stop Flags whether to stop script anyway (on severe
* errors.
* @return bool Always returns TRUE.
* @access private
*/
function _handleErrors($_stop = FALSE)
{
if (($this->warningsExist()) &&
($this->_stop_on_warn)) {
if ($this->errorsExist())
echo $this->getErrors($this->_ERR_COLOR, $this->_ERR_SIZE);
echo $this->getWarnings($this->_WRN_COLOR, $this->_WRN_SIZE);
exit;
}
if (($this->errorsExist()) &&
($this->_stop_on_error)) {
echo $this->getErrors($this->_ERR_COLOR, $this->_ERR_SIZE);
if ($this->warningsExist())
echo $this->getWarnings($this->_WRN_COLOR, $this->_WRN_SIZE);
exit;
}
if (!is_bool($_stop))
$_stop = FALSE;
if ($_stop) {
if ($this->errorsExist())
echo $this->getErrors($this->_ERR_COLOR, $this->_ERR_SIZE);
if ($this->warningsExist())
echo $this->getWarnings($this->_WRN_COLOR, $this->_WRN_SIZE);
exit;
}
return TRUE;
}
/**
* _setSessOption - Sets the value of the given session configuration option
*
* @param string $_config_option Session related configuration option
* @param mixed $_value The value to assign the configuration option
* @param bool $_check_sess Flags whether to verify 'session.' exists
* @return mixed Returns the old value on success, FALSE on failure.
* @access private
*/
function _setSessOption($_config_option, $_value, $_check_sess = TRUE)
{
$_config_option = trim($_config_option);
if (empty($_config_option)) {
return FALSE;
} else {
// When TRUE, check to see if 'session.' is included
if ($_check_sess) {
// Add 'session.' if not included in $_config_option
if (0 !== strpos(strtolower($_config_option), 'session.'))
$_config_option = 'session.' . $_config_option;
}
return ini_set($_config_option, $_value);
}
}
/**
* _genString - Generates random characters from 1 to 32 in length.
* 32 characters is the default when length not specified.
*
* @param int $_length The number of characters to generate.
* @return string Returns a string of the requested number of characters.
* @access private
*/
function _genString($_length = 0)
{
$_length = intval($_length);
if (($_length < 1) ||
($_length > $this->_MAX_SESS_ID_LEN))
$_length = $this->_MAX_SESS_ID_LEN;
/**
* Random number seeding already performed in constructor.
*/
$_string = md5(uniqid(mt_rand(), TRUE));
return substr($_string, 0, $_length);
}
/**
* _setNewSessID - Creates and sets a new session ID.
* This is called before session_start() and before any output to the
* browser.
*
* Note: It's possible if you have PHP version 4.3.2 or higher and are
* using the default maximum session length (32), to call
* this member function, without an argument, & no output sent
* to the browser, after a session_start() has been executed.
* That will invoke session_regenerate_id(), which seems to work
* correctly (member could have been made public for that reason).
* If session_start() has been executed already, then doing
* session_id('somevalue') will NOT change the session ID properly.
* It's less problematic to keep as a private method (and call
* before a session_start()).
*
* @param string $_sess_id An optional session ID to use (of _sess_ID_len)
* @return string Returns the new session ID.
* @access private
*/
function _setNewSessID($_sess_id = NULL)
{
global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS;
$_continue = TRUE;
/**
* If supplied with a session ID, validate it and use it when it's good.
*/
if (strlen($_sess_id) == $this->_sess_ID_len) {
if (!$this->pregMatches('/^[a-zA-Z0-9]+/', $_sess_id)) {
// Warning: Custom session ID passed is invalid.
$this->_setWrnMsg('SESS_INVALID', NULL, $_sess_id);
$this->_handleErrors();
// Ignoring value and assigning a new session ID.
$this->_setWrnMsg('NEW_SESS_ID');
} else {
session_id($_sess_id);
$_continue = FALSE;
}
}
/**
* Use session_regenerate_id() when the session ID length desired is the
* same as the maximum allowed, because it generates the maximum length.
* It is only available in PHP version 4.3.2 or higher. As of PHP 4.3.3,
* if session cookies are enabled, use of session_regenerate_id() is
* supposed to submit a new session cookie with the new session id.
*/
if (($_continue) &&
($this->_sess_ID_len == $this->_MAX_SESS_ID_LEN) &&
(version_compare(PHP_VERSION, '4.3.2', '>='))) {
if (session_regenerate_id()) {
$_sess_id = session_id();
$_continue = FALSE;
}
}
if ($_continue) {
$_sess_id = $this->_genString($this->_sess_ID_len);
session_id($_sess_id);
}
// To be safe set...
if (isSet($_REQUEST[$this->_sess_name]))
$_REQUEST[$this->_sess_name] = $_sess_id;
if (isSet($_GET[$this->_sess_name]))
$_GET[$this->_sess_name] = $_sess_id;
if (isSet($HTTP_GET_VARS[$this->_sess_name]))
$HTTP_GET_VARS[$this->_sess_name] = $_sess_id;
if (isSet($_POST[$this->_sess_name]))
$_POST[$this->_sess_name] = $_sess_id;
if (isSet($HTTP_POST_VARS[$this->_sess_name]))
$HTTP_POST_VARS[$this->_sess_name] = $_sess_id;
if (isSet($_COOKIE[$this->_sess_name]))
$_COOKIE[$this->_sess_name] = $_sess_id;
// May not actually change until next refresh
if (isSet($HTTP_COOKIE_VARS[$this->_sess_name]))
$HTTP_COOKIE_VARS[$this->_sess_name] = $_sess_id;
if (isSet($GLOBALS[$this->_sess_name]))
$GLOBALS[$this->_sess_name] = $_sess_id;
return $_sess_id;
}
/**
* _getSecID - Creates an MD5 of a users trace information. Used to verify
* session belongs to same user. Not full-proof but adequate.
* Note: Not using HTTP_ACCEPT since results are inconsistent in IE6.
*
* @return string An MD5 hash of secret keys plus server collected data.
* @access private
*/
function _getSecID()
{
$_type_used = NULL;
$_IP = $this->getIPAddr($_type_used);
$_agent = isSet($_SERVER['HTTP_USER_AGENT']) ?
$_SERVER['HTTP_USER_AGENT'] : 'NO USER AGENT';
/* Rev 1.0.2: Found IE 6 to not return consistent results (under HTTPS)
$_encoding = isSet($_SERVER['HTTP_ACCEPT_ENCODING']) ?
$_SERVER['HTTP_ACCEPT_ENCODING'] : 'NO ENCODING';
*/
return md5($this->_KEY_PREFIX .
$_IP .
$_type_used .
$_agent .
//*** $_encoding . Rev 1.0.2: Found as unreliable
$this->_KEY_SUFFIX
);
}
/**
* _getSessTrace - Creates a concatenated string of users trace information.
* Used for tracing IP in case of unauthorized intruder. Not using secret
* key here, or in the same order as session security ID. MySQL will
* truncate at INSERT if character length is longer than column limit.
* The '~' is used as a delimiter.
*
* @return string A non-hash of server collected data used for tracing.
* @access private
*/
function _getSessTrace()
{
$_type_used = NULL;
$_IP = $this->getIPAddr($_type_used);
$_agent = isSet($_SERVER['HTTP_USER_AGENT']) ?
$_SERVER['HTTP_USER_AGENT'] : 'NO USER AGENT';
$_accept = isSet($_SERVER['HTTP_ACCEPT']) ?
$_SERVER['HTTP_ACCEPT'] : 'NO ACCEPT';
$_encoding = isSet($_SERVER['HTTP_ACCEPT_ENCODING']) ?
$_SERVER['HTTP_ACCEPT_ENCODING'] : 'NO ENCODING';
return ($_type_used . '~' .
$_IP . '~' .
$_agent . '~' .
$_accept . '~' .
$_encoding
);
}
/**
* _sessDBOpen - Connects and selects the database.
*
* @param string $_save_path Session save location path.
* @param string $_session_name Alphanumeric session name (used in URL's).
* @return bool TRUE on good connection and select of DB, FALSE on errors.
* @access private
*/
function _sessDBOpen($_save_path, $_session_name)
{
// Override _sess_name with what PHP thinks is the session name.
$this->_sess_name = $_session_name;
/**
* When no resource link initially supplied, connect to database.
*/
if (!is_resource($this->_dbh)) {
if ($this->_db['db_persistent']) {
$this->_dbh = @mysql_pconnect($this->_db['db_host'],
$this->_db['db_user'],
$this->_db['db_pswd']
);
} else {
$this->_dbh = @mysql_connect ($this->_db['db_host'],
$this->_db['db_user'],
$this->_db['db_pswd']
);
}
}
if (!$this->_dbh)
// Connection to MySQL server failed
$this->_setErrMsg('CONNECT_FAIL'); // No error code available
else {
$_db_select = @mysql_select_db($this->_db['db_name'], $this->_dbh);
if (!$_db_select)
// Could not select MySQL database
$this->_setErrMsg('SELECTDB_FAIL', 'mysql_select_db',
$this->_db['db_name']);
}
$this->_handleErrors();
if ((!$this->_dbh) ||
(!$_db_select)) {
return (bool) FALSE;
} else {
$this->_mysql_ver = @mysql_get_server_info($this->_dbh);
return (bool) TRUE;
}
}
/**
* _sessDBClose - Closes the connection to the database for non-persistent
* connections.
*
* @return bool Always returns TRUE.
* @access private
*/
function _sessDBClose()
{
if ((!$this->_db['db_persistent']) &&
(is_resource($this->_dbh)))
if (!@mysql_close($this->_dbh))
// Warning: Could not close MySQL database
$this->_setWrnMsg('CLOSEDB_FAIL', 'mysql_close',
$this->_db['db_name']);
$this->_handleErrors();
return (bool) TRUE;
}
/**
* _sessDBRead - Retrieves session data from the table. If encrypted, the
* data will automatically be decrypted before returning the value back.
*
* @param string $_sess_id Session ID of the row to retrieve.
* @return string The session data is returned or an empty string on error.
* @access private
*/
function _sessDBRead($_sess_id)
{
$_time = time();
$_sec_level = $this->_SEC_LEVEL;
$_sec_ID = $this->_getSecID();
$_sql = 'SELECT ' . $this->_db['tb_vl_col'] .
', ' . $this->_db['tb_iv_col'] .
' FROM ' . $this->_db['tb_name'] .
' WHERE (' . $this->_db['tb_id_col'] . " = '$_sess_id')" .
' AND (' . $this->_db['tb_sl_col'] . " <= '$_sec_level')" .
' AND (' . $this->_db['tb_ex_col'] . " > '$_time')" .
' AND (' . $this->_db['tb_to_col'] . " > '$_time')" .
' AND (' . $this->_db['tb_lk_col'] . " = '0')" .
' AND (' . $this->_db['tb_si_col'] . " = '$_sec_ID')";
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Main select/read query failed. Could not read session data
$this->_setErrMsg('READ_FAILED', $_sql, $_sess_id);
$this->_handleErrors();
return (string) ''; // Return empty string on error
} else {
$_row = @mysql_fetch_assoc($_result);
if (!$_row) {
return (string) ''; // No data found, return an empty string
} else {
$_row[$this->_db['tb_vl_col']] =
isSet($_row[$this->_db['tb_vl_col']]) ?
$_row[$this->_db['tb_vl_col']] : '';
$_row[$this->_db['tb_iv_col']] =
isSet($_row[$this->_db['tb_iv_col']]) ?
$_row[$this->_db['tb_iv_col']] : '';
if ($this->_MAGIC_QUOTES_RUNTIME) {
$_row[$this->_db['tb_vl_col']] =
stripslashes($_row[$this->_db['tb_vl_col']]);
$_row[$this->_db['tb_iv_col']] =
stripslashes($_row[$this->_db['tb_iv_col']]);
}
/**
* Decrypt the data if it was encrypted
*/
if ((!empty($_row[$this->_db['tb_iv_col']])) &&
(!empty($_row[$this->_db['tb_vl_col']]))) {
$_row[$this->_db['tb_vl_col']] =
$this->sessDecrypt($_row[$this->_db['tb_vl_col']],
$_row[$this->_db['tb_iv_col']],
TRUE);
}
// When invoked, did decrypt fail?
return (string) (FALSE === $_row[$this->_db['tb_vl_col']]) ?
'' : $_row[$this->_db['tb_vl_col']];
}
}
}
/**
* _sessDBWrite - Inserts or updates session data to the table.
*
* @param string $_sess_id Session ID which is used as the primary key.
* @param string $_sess_data Session data to save in the database.
* @return bool TRUE on a successful Insert/Update, and FALSE on error.
* @access private
*/
function _sessDBWrite($_sess_id, $_sess_data)
{
$_time = time();
$_expiry = $_time + $this->_SESS_LIFE;
$_timeout = $_time + $this->_SESS_TIMEOUT;
$_sec_level = $this->_SEC_LEVEL;
$_sec_ID = $this->_getSecID();
$_trace = addslashes($this->_getSessTrace());
$_enc_iv = '';
/**
* Encrypt the whole session data when flag is set to TRUE.
*/
if ($this->_ENCRYPT) {
/**
* When magic quotes GPC option is on or strip anyway option
* is on, strip session data before encrypting. We don't need
* the slashes when encrypting because the data value will change.
*/
if (($this->_MAGIC_QUOTES_GPC) ||
($this->_STRIP_ANYWAY))
$_sess_data = stripslashes($_sess_data);
$_sess_data = $this->sessEncrypt($_sess_data, $_enc_iv, TRUE);
}
/**
* When magic quotes GPC option is off or slash anyway option
* is on, slash quotes in session data and encryption IV.
*/
if ((!$this->_MAGIC_QUOTES_GPC) ||
($this->_SLASH_ANYWAY)) {
$_sess_data = addslashes($_sess_data);
$_enc_iv = addslashes($_enc_iv);
}
$_sql = 'INSERT INTO ' . $this->_db['tb_name'] .
' (' . $this->_db['tb_id_col'] .
', ' . $this->_db['tb_sl_col'] .
', ' . $this->_db['tb_cr_col'] .
', ' . $this->_db['tb_ex_col'] .
', ' . $this->_db['tb_to_col'] .
', ' . $this->_db['tb_lk_col'] .
', ' . $this->_db['tb_vl_col'] .
', ' . $this->_db['tb_iv_col'] .
', ' . $this->_db['tb_si_col'] .
', ' . $this->_db['tb_tr_col'] .
') VALUES (' .
"'$_sess_id'" .
", '$_sec_level'" .
", '$_time'" .
", '$_expiry'" .
", '$_timeout'" .
", '0'" .
", '$_sess_data'" .
", '$_enc_iv'" .
", '$_sec_ID'" .
", '$_trace'" .
')';
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
$_errno = @mysql_errno($this->_dbh);
if ((1062 == $_errno) || // ER_DUP_ENTRY
(1022 == $_errno)) { // ER_DUP_KEY
$_sql = 'UPDATE ' . $this->_db['tb_name'] .
' SET ' .
$this->_db['tb_ex_col'] .
"='$_expiry'" .
', ' . $this->_db['tb_vl_col'] .
"='$_sess_data'" .
', ' . $this->_db['tb_iv_col'] .
"='$_enc_iv'" .
' WHERE ('. $this->_db['tb_id_col'] .
" = '$_sess_id')" .
' AND ('. $this->_db['tb_cr_col'] .
" < '$_time')" .
' AND ('. $this->_db['tb_sl_col'] .
" <= '$_sec_level')" .
' AND ('. $this->_db['tb_ex_col'] .
" > '$_time')" .
' AND ('. $this->_db['tb_to_col'] .
" > '$_time')" .
' AND ('. $this->_db['tb_lk_col'] .
" = '0')" .
' AND ('. $this->_db['tb_si_col'] .
" = '$_sec_ID')";
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Update failed. Could not update session data
$this->_setErrMsg('UPDATE_FAILED', $_sql, $_sess_id);
}
} else {
// Insert failed. Could not insert session data
$this->_setErrMsg('INSERT_FAILED', $_sql, $_sess_id);
if (1064 == $_errno) { // ER_PARSE_ERROR
// Data may contain single quotes without backslashes
$this->_setErrMsg('PARSE_ERROR', $_sql);
if (($this->_MAGIC_QUOTES_GPC) &&
(!$this->_SLASH_ANYWAY)) {
// Recommend to turn on param['slash_anyway'] to TRUE
$this->_setErrMsg('RECOMD_SLASH');
}
}
}
}
$this->_handleErrors();
return (bool) $_result;
}
/**
* _sessDBDestroy - Deletes session data from the table. Automatically
* executed when session_destroy() is executed.
*
* @param string $_sess_id Session ID of the row to delete.
* @return bool TRUE on a successful delete, and FALSE on error.
* @access private
*/
function _sessDBDestroy($_sess_id)
{
global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS;
$_sql = 'DELETE FROM ' . $this->_db['tb_name'] .
' WHERE ' . $this->_db['tb_id_col'] .
" = '$_sess_id'";
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Destroy failed. Could not delete session data
$this->_setErrMsg('DESTROY_FAIL', $_sql, $_sess_id);
$this->_handleErrors();
}
session_unset();
// To be safe remove...
if (isSet($_REQUEST[$this->_sess_name]))
unset($_REQUEST[$this->_sess_name]);
if (isSet($_GET[$this->_sess_name]))
unset($_GET[$this->_sess_name]);
if (isSet($HTTP_GET_VARS[$this->_sess_name]))
unset($HTTP_GET_VARS[$this->_sess_name]);
if (isSet($_POST[$this->_sess_name]))
unset($_POST[$this->_sess_name]);
if (isSet($HTTP_POST_VARS[$this->_sess_name]))
unset($HTTP_POST_VARS[$this->_sess_name]);
if (isSet($_COOKIE[$this->_sess_name]))
unset($_COOKIE[$this->_sess_name]);
if (isSet($HTTP_COOKIE_VARS[$this->_sess_name]))
unset($HTTP_COOKIE_VARS[$this->_sess_name]);
if (isSet($GLOBALS[$this->_sess_name]))
unset($GLOBALS[$this->_sess_name]);
return (bool) $_result;
}
/**
* _sessDBGC - Deletes expired session data from the table. It deletes
* sessions that expire by inactivity timeout, absolute
* timeout, or that are flagged as locked.
*
* @param int $_maxlifetime Session's life setting in seconds.
* @return bool TRUE on successful deletes, and FALSE on error.
* @access private
*/
function _sessDBGC($_maxlifetime)
{
$_time = time();
$_sql = 'DELETE FROM ' . $this->_db['tb_name'] .
' WHERE ' .
'(' . $this->_db['tb_ex_col'] .
" < '" . ($_time - $_maxlifetime) . "')" .
' OR ' .
'(' . $this->_db['tb_to_col'] . " < '$_time')";
if ($this->_GC_DEL_LOCKED) {
$_sql .= ' OR ' .
'(' . $this->_db['tb_lk_col'] . " = '1')";
}
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Delete failed during garbage collection/cleanup
$this->_setErrMsg('GARBAGE_FAIL', $_sql);
$this->_handleErrors();
}
return (bool) $_result;
}
/***************************************************************************
*
* Start of Public Member Functions
*
***************************************************************************/
/**
* getDBResource - Returns the current established MySQL resource link.
* It can be used in your script to access other tables/databases.
*
* @return resource Returns a MySQL resource link identifier.
* @access public
*/
function getDBResource()
{
return $this->_dbh;
}
/**
* getSessInfo - This will return column information for the session ID
* passed. The current session ID is used when no session ID is passed.
* It returns an associative array with the table column names as the key.
* The session data value, and encryption IV column values are returned
* only when a confirm password is passed. If the session value is
* encrypted, it will automatically be decrypted, however the session
* value data will be raw (in serialized format).
* The other columns retrieved are useful for determining when a session
* was created/started and when it will expire.
* If $_full_exp is FALSE, only the session ID is used to retrieve the row.
*
* The trace column can be split into individual values. For example:
* $fields = $sess->getSessInfo();
* $arr = explode('~', $fields['sess_trace']); // $arr[1] is IP Address
*
* You can use PHP's getdate() function to convert the columns that contain
* epoch values (such as session created, expiry, and timeout).
* @link http://us4.php.net/manual/en/function.getdate.php
*
* @param string $_sess_id The session ID to look for (default is current)
* @param bool $_full_exp Use the full expression in the WHERE clause.
* Only used when the session ID is the active one (TRUE def)
* @param string $_confirmation_pswd Pass to retrieve raw session value.
* @return mixed Returns an assoc. array of data or FALSE on error/no data.
* @access public
*/
function getSessInfo($_sess_id = NULL,
$_full_exp = TRUE,
$_confirmation_pswd = NULL)
{
$_sess_id = empty($_sess_id) ? session_id() : $_sess_id;
/**
* Verify that raw session value is requested to be retrieved as well
* by checking the passed password against the confirm password
* defined in _param['confirm_pswd']
*/
$_pswd_valid = (0 === strcmp($_confirmation_pswd, $this->_CONF_PSWD)) ?
TRUE : FALSE;
$_sql = 'SELECT ' . $this->_db['tb_id_col'] .
', ' . $this->_db['tb_sl_col'] .
', ' . $this->_db['tb_cr_col'] .
', ' . $this->_db['tb_ex_col'] .
', ' . $this->_db['tb_to_col'] .
', ' . $this->_db['tb_lk_col'] .
', ' . $this->_db['tb_si_col'] .
', ' . $this->_db['tb_tr_col'];
if ($_pswd_valid)
$_sql .= ', ' . $this->_db['tb_vl_col'] .
', ' . $this->_db['tb_iv_col'];
$_sql .= ' FROM ' . $this->_db['tb_name'] .
' WHERE (' . $this->_db['tb_id_col'] . " = '$_sess_id')";
/**
* When requested to use full search expressions and the session ID is
* the same as the current active session ID, use all the rest of the
* search criteria/fields.
*/
if (($_full_exp) &&
(0 === strcmp($_sess_id, session_id()))) {
$_time = time();
$_sec_level = $this->_SEC_LEVEL;
$_sec_ID = $this->_getSecID();
$_sql .=
' AND (' . $this->_db['tb_sl_col'] . " <= '$_sec_level')" .
' AND (' . $this->_db['tb_ex_col'] . " > '$_time')" .
' AND (' . $this->_db['tb_to_col'] . " > '$_time')" .
' AND (' . $this->_db['tb_lk_col'] . " = '0')" .
' AND (' . $this->_db['tb_si_col'] . " = '$_sec_ID')";
}
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Session info. query failed. Could not read session data
$this->_setErrMsg('INFO_FAIL', $_sql, $_sess_id);
$this->_handleErrors();
return FALSE;
} else {
$_row = @mysql_fetch_assoc($_result);
if (!$_row) {
// Warning: No session data found while doing session info query
$this->_setWrnMsg('NO_SESS_INFO', $_sql, $_sess_id);
$this->_handleErrors();
} else
if ($_pswd_valid) {
$_row[$this->_db['tb_vl_col']] =
isSet($_row[$this->_db['tb_vl_col']]) ?
$_row[$this->_db['tb_vl_col']] : '';
$_row[$this->_db['tb_iv_col']] =
isSet($_row[$this->_db['tb_iv_col']]) ?
$_row[$this->_db['tb_iv_col']] : '';
if ($this->_MAGIC_QUOTES_RUNTIME) {
$_row[$this->_db['tb_vl_col']] =
stripslashes($_row[$this->_db['tb_vl_col']]);
$_row[$this->_db['tb_iv_col']] =
stripslashes($_row[$this->_db['tb_iv_col']]);
}
/**
* Decrypt the data if it was encrypted
*/
if ((!empty($_row[$this->_db['tb_iv_col']])) &&
(!empty($_row[$this->_db['tb_vl_col']]))) {
$_row[$this->_db['tb_vl_col']] =
$this->sessDecrypt($_row[$this->_db['tb_vl_col']],
$_row[$this->_db['tb_iv_col']],
TRUE);
}
}
if (is_array($_row)) {
if ($this->_MAGIC_QUOTES_RUNTIME) {
$_row[$this->_db['tb_si_col']] =
stripslashes($_row[$this->_db['tb_si_col']]);
$_row[$this->_db['tb_tr_col']] =
stripslashes($_row[$this->_db['tb_tr_col']]);
}
return $_row;
} else {
return FALSE;
}
}
}
/**
* getAllSessInfo - This will return column information for the number of
* rows indicated (default is to return all rows). You can select the
* column to sort by (expiry is the default) and whether to sort by
* ascending or descending (default) sort order. It returns a two
* dimensional associative array. The first array index is the row number,
* and the second array index is the table column names.
* The session data value, and encryption IV column values are returned
* only when a confirm password is passed. If the session value is
* encrypted, it will automatically be decrypted, however the session
* value data will be raw (in serialized format).
* The other columns retrieved are useful for determining when a session
* was created/started and when it will expire.
*
* The trace column can be split into individual values. For example:
* $data = $sess->getAllSessInfo();
* $arr = explode('~', $data[0]['sess_trace']); // $arr[1] is IP Address
*
* You can use PHP's getdate() function to convert the columns that contain
* epoch values (such as session created, expiry, and timeout).
* @link http://us4.php.net/manual/en/function.getdate.php
*
* @param int $_offset The row number to start returning data from
* @param int $_row_count The number of rows to return (-1 = all rows).
* @param string $_order_by The column name to sort rows by (def=expiry).
* @param bool $_ascending Ascending or descending sort order (def=desc)
* @param string $_confirmation_pswd Pass to retrieve raw session value.
* @return mixed Returns a 2D array of data or FALSE on error/no data.
* @access public
*/
function getAllSessInfo($_offset = 0,
$_row_count = -1,
$_order_by = NULL,
$_ascending = FALSE,
$_confirmation_pswd = NULL)
{
if (!is_int($_offset))
$_offset = (int) 0;
if ($_offset < 0)
$_offset = (int) 0;
if (!is_int($_row_count))
$_row_count = (int) -1;
if (0 == $_row_count)
$_row_count = (int) -1;
if (empty($_order_by))
$_order_by = $this->_db['tb_ex_col'];
else
if (($_order_by != $this->_db['tb_id_col']) &&
($_order_by != $this->_db['tb_sl_col']) &&
($_order_by != $this->_db['tb_cr_col']) &&
($_order_by != $this->_db['tb_ex_col']) &&
($_order_by != $this->_db['tb_to_col']) &&
($_order_by != $this->_db['tb_lk_col']) &&
($_order_by != $this->_db['tb_vl_col']) &&
($_order_by != $this->_db['tb_iv_col']) &&
($_order_by != $this->_db['tb_si_col']) &&
($_order_by != $this->_db['tb_tr_col']))
$_order_by = $this->_db['tb_ex_col'];
if (!is_bool($_ascending))
$_ascending = FALSE;
$_asc_desc = (TRUE === $_ascending) ? 'ASC' : 'DESC';
/**
* Verify that raw session value is requested to be retrieved as well
* by checking the passed password against the confirm password
* defined in _param['confirm_pswd']
*/
$_pswd_valid = (0 === strcmp($_confirmation_pswd, $this->_CONF_PSWD)) ?
TRUE : FALSE;
$_sql = 'SELECT ' . $this->_db['tb_id_col'] .
', ' . $this->_db['tb_sl_col'] .
', ' . $this->_db['tb_cr_col'] .
', ' . $this->_db['tb_ex_col'] .
', ' . $this->_db['tb_to_col'] .
', ' . $this->_db['tb_lk_col'] .
', ' . $this->_db['tb_si_col'] .
', ' . $this->_db['tb_tr_col'];
if ($_pswd_valid)
$_sql .= ', ' . $this->_db['tb_vl_col'] .
', ' . $this->_db['tb_iv_col'];
$_sql .= ' FROM ' . $this->_db['tb_name'] .
" ORDER BY $_order_by $_asc_desc LIMIT $_offset,$_row_count";
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// All session information query failed.
$this->_setErrMsg('ALL_INFO_FAIL', $_sql);
$this->_handleErrors();
return FALSE;
} else {
$_rows = array();
while ($_row = @mysql_fetch_assoc($_result)) {
if ($_pswd_valid) {
$_row[$this->_db['tb_vl_col']] =
isSet($_row[$this->_db['tb_vl_col']]) ?
$_row[$this->_db['tb_vl_col']] : '';
$_row[$this->_db['tb_iv_col']] =
isSet($_row[$this->_db['tb_iv_col']]) ?
$_row[$this->_db['tb_iv_col']] : '';
if ($this->_MAGIC_QUOTES_RUNTIME) {
$_row[$this->_db['tb_vl_col']] =
stripslashes($_row[$this->_db['tb_vl_col']]);
$_row[$this->_db['tb_iv_col']] =
stripslashes($_row[$this->_db['tb_iv_col']]);
}
/**
* Decrypt the data if it was encrypted
*/
if ((!empty($_row[$this->_db['tb_iv_col']])) &&
(!empty($_row[$this->_db['tb_vl_col']]))) {
$_row[$this->_db['tb_vl_col']] =
$this->sessDecrypt($_row[$this->_db['tb_vl_col']],
$_row[$this->_db['tb_iv_col']],
TRUE);
}
}
if ($this->_MAGIC_QUOTES_RUNTIME) {
$_row[$this->_db['tb_si_col']] =
stripslashes($_row[$this->_db['tb_si_col']]);
$_row[$this->_db['tb_tr_col']] =
stripslashes($_row[$this->_db['tb_tr_col']]);
}
$_rows[] = $_row;
}
if (count($_rows) > 0) {
@mysql_free_result($_result);
return $_rows;
} else {
// Warning: No session data found while doing all session query
$this->_setWrnMsg('NO_SESS_INFO2', $_sql);
$this->_handleErrors();
return FALSE;
}
}
}
/**
* getTableName - Returns the name of the session table.
*
* @return string Returns the MySQL table name
* @access public
*/
function getTableName()
{
return $this->_db['tb_name'];
}
/**
* getSessIDName - Returns the name of the session ID (key) column.
*
* @return string Returns the MySQL table column name for session ID
* @access public
*/
function getSessIDName()
{
return $this->_db['tb_id_col'];
}
/**
* getSecLevelName - Returns the name of the security level column.
*
* @return string Returns the MySQL table column name for security level
* @access public
*/
function getSecLevelName()
{
return $this->_db['tb_sl_col'];
}
/**
* getCreateName - Returns the name of the session created column.
*
* @return string Returns the MySQL table column name for created epoch.
* @access public
*/
function getCreateName()
{
return $this->_db['tb_cr_col'];
}
/**
* getExpiryName - Returns the name of the session expiry column.
*
* @return string Returns the MySQL table column name for expiry epoch.
* @access public
*/
function getExpiryName()
{
return $this->_db['tb_ex_col'];
}
/**
* getTimeoutName - Returns the name of the session timeout column.
*
* @return string Returns the MySQL table column name for timeout epoch.
* @access public
*/
function getTimeoutName()
{
return $this->_db['tb_to_col'];
}
/**
* getLockName - Returns the name of the session locked column.
*
* @return string Returns the MySQL table column name for locked boolean.
* @access public
*/
function getLockName()
{
return $this->_db['tb_lk_col'];
}
/**
* getSessValueName - Returns the name of the session value column.
*
* @return string Returns the MySQL table column name for session value.
* @access public
*/
function getSessValueName()
{
return $this->_db['tb_vl_col'];
}
/**
* getEncIVName - Returns the name of the encryption IV column.
*
* @return string Returns the MySQL table column name for encryption IV.
* @access public
*/
function getEncIVName()
{
return $this->_db['tb_iv_col'];
}
/**
* getSecIDName - Returns the name of the security ID column.
*
* @return string Returns the MySQL table column name for security ID.
* @access public
*/
function getSecIDName()
{
return $this->_db['tb_si_col'];
}
/**
* getTraceName - Returns the name of the session trace column.
*
* @return string Returns the MySQL table column name for session trace.
* @access public
*/
function getTraceName()
{
return $this->_db['tb_tr_col'];
}
/**
* nbrActiveSess - Retrieves the number of active sessions currently in the
* table.
*
* @return int The number of session rows that are considered active.
* @access public
*/
function nbrActiveSess()
{
$_time = time();
$_sql = 'SELECT ' . $this->_db['tb_lk_col'] .
' FROM ' . $this->_db['tb_name'] .
' WHERE (' . $this->_db['tb_ex_col'] . " > '$_time')" .
' AND (' . $this->_db['tb_to_col'] . " > '$_time')" .
' AND (' . $this->_db['tb_lk_col'] . " = '0')";
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Active sessions query failed. Could not read session data
$this->_setErrMsg('ACTIVE_FAIL', $_sql);
$this->_handleErrors();
return (bool) FALSE; // Return an error
} else {
return @mysql_num_rows($_result);
}
}
/**
* nbrInactiveSess - Retrieves the number of inactive sessions currently in
* the table.
*
* @return int The number of session rows that are considered inactive.
* @access public
*/
function nbrInactiveSess()
{
$_time = time();
$_sql = 'SELECT ' . $this->_db['tb_lk_col'] .
' FROM ' . $this->_db['tb_name'] .
' WHERE (' . $this->_db['tb_ex_col'] . " < '$_time')" .
' OR (' . $this->_db['tb_to_col'] . " < '$_time')" .
' OR (' . $this->_db['tb_lk_col'] . " = '1')";
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Inactive sessions query failed. Could not read session data
$this->_setErrMsg('INACTIVE_FAIL', $_sql);
$this->_handleErrors();
return (bool) FALSE; // Return an error
} else {
return @mysql_num_rows($_result);
}
}
/**
* changeSessLock - To lock or unlock a session row in the table.
* When a session is locked, it will not be further read and is considered
* temporarily or permanently suspended.
* Must pass a valid session ID; no default assigned.
* Note: MySQL will not update columns where the new value is the same as
* the old value.
*
* @param string $_sess_id Session ID of the row to change the lock on.
* @param bool $_lock_mode Set to TRUE for lock and FALSE for unlock.
* @return bool TRUE on a successful lock/unlock, and FALSE on error or
* empty session string.
* @access public
*/
function changeSessLock($_sess_id, $_lock_mode = FALSE)
{
if (empty($_sess_id))
return FALSE;
if (!is_bool($_lock_mode))
$_lock_mode = FALSE;
if (TRUE === $_lock_mode)
$_lock_mode = 1;
else
$_lock_mode = 0;
$_sql = 'UPDATE ' . $this->_db['tb_name'] .
' SET ' .
$this->_db['tb_lk_col'] .
"='$_lock_mode'" .
' WHERE ' . $this->_db['tb_id_col'] .
" = '$_sess_id'";
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Lock/unlock failed. Could not change session data
$this->_setErrMsg('A_LOCK_FAIL', $_sql, $_sess_id);
$this->_handleErrors();
}
return (bool) $_result;
}
/**
* changeAllSessLocks - To lock or unlock all session rows in the table.
* When a session is locked, it will not be further read and is considered
* temporarily or permanently suspended. Pass the _param['confirm_pswd']
* to this member function as a way of making sure that it is the intention
* to lock/unlock all rows in the session table.
* Note: MySQL will not update columns where the new value is the same as
* the old value.
*
* @param string $_confirmation_pswd Password required to change all rows.
* @param bool $_lock_mode Set to TRUE for lock and FALSE for unlock.
* @return bool TRUE when rows are successfully locked/unlocked, or FALSE
* on error or invalid password supplied.
* @access public
*/
function changeAllSessLocks($_confirmation_pswd = NULL, $_lock_mode = FALSE)
{
/**
* Verify lock/unlock request by checking the passed password against
* the confirm password defined in _param['confirm_pswd']
*/
if (0 !== strcmp($_confirmation_pswd, $this->_CONF_PSWD))
return FALSE;
if (!is_bool($_lock_mode))
$_lock_mode = FALSE;
if (TRUE === $_lock_mode)
$_lock_mode = 1;
else
$_lock_mode = 0;
$_sql = 'UPDATE ' . $this->_db['tb_name'] .
' SET ' . $this->_db['tb_lk_col'] .
"='$_lock_mode'";
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Lock/unlock failed. Could not change all the session data
$this->_setErrMsg('ALL_LOCK_FAIL', $_sql);
$this->_handleErrors();
}
return (bool) $_result;
}
/**
* deleteSession - To manually delete an old/expired session row from the
* table. Must pass a valid session ID; no default assigned.
*
* @param string $_sess_id Session ID of the row to delete.
* @return bool TRUE on a successful delete, and FALSE on error or empty
* session string.
* @access public
*/
function deleteSession($_sess_id)
{
if (empty($_sess_id))
return FALSE;
/**
* When session ID is the same as the current one, then use
* session_destroy() to delete a current active session
* instead of this method.
*/
if (0 === strcmp($_sess_id, session_id()))
return session_destroy();
$_sql = 'DELETE FROM ' . $this->_db['tb_name'] .
' WHERE ' . $this->_db['tb_id_col'] .
" = '$_sess_id'";
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Delete request failed. Could not delete session data
$this->_setErrMsg('A_DEL_FAIL', $_sql, $_sess_id);
$this->_handleErrors();
}
return (bool) $_result;
}
/**
* deleteAllSessions - To delete all session rows from table. It's faster
* to drop and create the table again, however, the current database user
* should not have such security privileges. Pass the _param['confirm_pswd']
* to this member function as a way of making sure that it is the intention
* to delete all rows from the session table.
*
* @param string $_confirmation_pswd Password required to delete all rows.
* @return bool TRUE when rows are successfully deleted, and FALSE on
* error or invalid password supplied.
* @access public
*/
function deleteAllSessions($_confirmation_pswd = NULL)
{
/**
* Verify delete request by checking the passed password against
* the confirm password defined in _param['confirm_pswd']
*/
if (0 !== strcmp($_confirmation_pswd, $this->_CONF_PSWD))
return FALSE;
$_sql = 'DELETE FROM ' . $this->_db['tb_name'];
$_result = @mysql_query($_sql, $this->_dbh);
if (!$_result) {
// Delete all request failed. Could not delete all session data
$this->_setErrMsg('ALL_DEL_FAIL', $_sql);
$this->_handleErrors();
}
return (bool) $_result;
}
/**
* pregMatches - Returns a boolean of a whole word preg_match result. It
* checks $_pattern against $_value and returns a boolean result. The
* preg_match result must match $_value for it to return a TRUE result.
* It uses a default pattern of '/[a-zA-Z0-9]+/' when no pattern is
* specified.
*
* @param string $_pattern Set to a valid regular expression pattern.
* @param string $_value Set to a value to have the $_pattern check against
* @return bool Returns TRUE when $_pattern is found in $_value.
* @access public
*/
function pregMatches($_pattern, $_value)
{
if (empty($_pattern))
$_pattern = '/[a-zA-Z0-9]+/'; // Match this pattern 1 or more times
$_matches = array();
if (preg_match($_pattern, $_value, $_matches) > 0)
if (0 === @strcmp($_value, $_matches[0]))
return TRUE;
return FALSE;
}
/**
* stringSplit - Parses out a string into x number of byte chunk characters.
* Example: $arr = stringSplit('Hi', 1);
*
* $arr then contains: $arr[0] = 'H' and $arr[1] = 'i'
*
* @param string $_text Pass a text string you would like to parse out.
* @param int $_chunksize The number of characters to split by.
* @return array Returns an array with each index containing x characters.
* @access public
*/
function stringSplit($_text, $_chunksize = 1)
{
preg_match_all('/(' . str_repeat('.', $_chunksize) . ')/Uims',
$_text,
$_matches);
return $_matches[1];
}
/**
* sessEncode - Encrypts plain text. It uses an Initialization Vector (IV)
* integer in the range of 1-500 in order to produce more varied results.
* You must use the same IV number when calling the sessDecode member.
* The encrypted text may be longer than original plain text.
* This function requires PHP ver >= 4.2.0 because of str_rot13 function.
*
*
* @param string $_text Pass the plain text you would like to encrypt.
* @param int $_IV Pass a random number between 1 and 500.
* @return string Returns the plain text passed in encrypted format.
* @access public
*/
function sessEncode($_text, $_IV = 3)
{
if (is_numeric($_IV)) {
$_IV = intval($_IV);
if ($_IV < 1)
$_IV = 1;
else
if ($_IV > 500)
$_IV = 42;
} else {
$_IV = 3;
}
$_text .= ' ';
$_arr1 = $this->stringSplit($this->_ENCRYPT_KEY);
$_arr2 = $_arr1;
foreach ($_arr1 as $_i1 => $_v1) {
foreach ($_arr2 as $_i2 => $_v2) {
$_counter = ($_i2 + 1) + ($_i1 * strlen($this->_ENCRYPT_KEY));
$_array[$_counter] = $_v1 . $_v2;
if ($_v1 == $_v2)
$_array[$_counter] = $_v1 . '_';
}
}
$_encoded = '';
$_count = 0;
$_msgarr = $this->stringSplit($_text);
foreach ($_msgarr as $_mindex => $_mvalue) {
If ($_mindex / 2 <> ceil ($_mindex / 2)) {
$_masc = ord($_mvalue) - 31;
$_masc = $_masc + (ceil($_count * $_IV / 3) + $_IV);
$_count++;
if ($_count > 12)
$_count = 0;
$_encoded .= $_array[$_masc];
} else {
// No need to get around str_rot13 bug here since $_mvalue is
// not being referenced after this point & will get overriden.
$_encoded .= str_rot13($_mvalue);
}
}
return $_encoded;
}
/**
* sessDecode - Decodes text that was previously encrypted with sessEncode.
* This function requires PHP ver >= 4.2.0 because of str_rot13 function.
*
* @param string $_text Pass the encrypted text created by sessEncode.
* @param int $_IV Pass the same IV number as used in sessEncode.
* @return string Returns the unencrypted plain text.
* @access public
*/
function sessDecode($_text, $_IV = 3)
{
$_count = 0;
if (is_numeric($_IV)) {
$_IV = intval($_IV);
if ($_IV < 1)
$_IV = 1;
else
if ($_IV > 500)
$_IV = 42;
} else {
$_IV = 3;
}
$_arr1 = $this->stringSplit($this->_ENCRYPT_KEY);
$_arr2 = $_arr1;
foreach ($_arr1 as $_i1 => $_v1) {
foreach ($_arr2 as $_i2 => $_v2) {
$_counter = ($_i2 + 1) + ($_i1 * strlen($this->_ENCRYPT_KEY));
$_array[$_counter] = $_v1 . $_v2;
if ($_v1 == $_v2)
$_array[$_counter] = $_v1 . '_';
}
}
$_array = array_flip($_array);
$_msgarr = $this->stringSplit($_text, 3);
$_decoded = ''; // Rev 1.0.2: Added this initialization line
foreach ($_msgarr as $_mvalue) {
// $_tmp_hold used to get around a possible PHP bug in versions
// earlier than 4.3.0. The variable passed in function might change.
$_tmp_hold = $_mvalue;
$_decoded .= str_rot13($_tmp_hold{0});
$_ivalue = $_array[substr($_mvalue, 1, 2)];
$_ivalue = $_ivalue - (ceil($_count * $_IV / 3) + $_IV);
$_count++;
if ($_count > 12)
$_count = 0;
$_masc = chr($_ivalue + 31);
$_decoded .= $_masc;
}
return trim($_decoded); // Rev 1.0.1: Added trim(). Removed substr().
}
/**
* sessEncrypt - Encrypts plain text. It uses an Initialization Vector (IV).
* The same IV is needed for the decryption phase. Must save IV for
* later decryption. This routine will attempt to use the mcrypt
* algorithms if installed first, otherwise the sessEncode member is used.
* The encrypted text may be longer than original plain text. When you have
* a few/many fields to encrypt in one script cycle, choose to keep the
* mcrypt module open to speed up encryption (only for libmcrypt >= 2.4.x).
*
* @link http://mcrypt.hellug.gr
* @param string $_text Pass the plain text you would like to encrypt.
* @param string $IV Pass by reference var. This will get assigned the IV.
* @param bool $_keep_open TRUE to keep mcrypt module open, FALSE close.
* @return mixed Returns an encrypted value representing the original
* text, or FALSE on error.
* @access public
*/
function sessEncrypt($_text, &$IV, $_keep_open = FALSE)
{
static $_open_already = FALSE; // Open encrypt flag For ver >= 2.4.x
static $_module = NULL;
if (!is_bool($_keep_open))
$_keep_open = FALSE;
if (($this->_MCRYPT) &&
(!empty($this->_ENC_ALGO)) &&
(!empty($this->_ENC_MODE))) {
if ($this->_MCRYPT_LATEST) { // For >= 2.4.x
if (!$_open_already) {
$_module = @mcrypt_module_open($this->_ENC_ALGO, '',
$this->_ENC_MODE, '');
if (FALSE === $_module) {
// Could not open encryption module for encrypting
$this->_setErrMsg('ENC_OPEN_FAIL', NULL,
$this->_ENC_ALGO, $this->_ENC_MODE);
$this->_handleErrors();
return FALSE;
}
$_open_already = TRUE;
}
$IV = @mcrypt_create_iv (@mcrypt_enc_get_iv_size($_module),
MCRYPT_RAND); // For Windows support
$_key = substr($this->_ENC_KEY_HASHED, 0,
@mcrypt_enc_get_key_size($_module));
$_result = mcrypt_generic_init($_module, $_key, $IV);
if ($_result < 0) {
switch ($_result) {
case -3:
// Key length for encryption is incorrect
$this->_setErrMsg('ENC_KEY_LEN', NULL,
$this->_ENC_ALGO,
$this->_ENC_MODE,
strlen($_key));
case -4:
// There were memory allocation problems - encrypt
$this->_setErrMsg('ENC_MEMORY', NULL,
$this->_ENC_ALGO,
$this->_ENC_MODE);
default:
// There were unknown errors while trying to encrypt
$this->_setErrMsg('ENC_UNKNOWN', NULL,
$this->_ENC_ALGO,
$this->_ENC_MODE);
}
$this->_handleErrors();
return FALSE;
}
$_enc = @mcrypt_generic($_module, $_text);
if (!$_keep_open) {
@mcrypt_generic_deinit($_module);
@mcrypt_module_close($_module);
$_open_already = FALSE;
$_module = NULL;
}
} else { // For 2.2.x
$IV = @mcrypt_create_iv(
@mcrypt_get_block_size(
$this->_ENC_ALGO
// FYI: Would be needed to run in > 2.2.x , $this->_ENC_MODE
),
MCRYPT_RAND
); // MCRYPT_RAND for Windows support
$_key = substr($this->_ENC_KEY_HASHED, 0,
@mcrypt_get_key_size($this->_ENC_ALGO
// FYI: Would be needed to run in > 2.2.x , $this->_ENC_MODE
)
);
switch ($this->_ENC_MODE) {
case MCRYPT_MODE_ECB:
$_enc = @mcrypt_ecb(
$this->_ENC_ALGO,
$_key,
$_text,
MCRYPT_ENCRYPT
// FYI: Would be needed to run in > 2.2.x , $IV
);
$IV = ''; // FYI: Would comment to run in > 2.2.x
break;
case MCRYPT_MODE_CFB:
$_enc = @mcrypt_cfb(
$this->_ENC_ALGO,
$_key,
$_text,
MCRYPT_ENCRYPT,
$IV
);
break;
case MCRYPT_MODE_OFB:
$_enc = @mcrypt_ofb(
$this->_ENC_ALGO,
$_key,
$_text,
MCRYPT_ENCRYPT,
$IV
);
break;
default:
$_enc = @mcrypt_cbc(
$this->_ENC_ALGO,
$_key,
$_text,
MCRYPT_ENCRYPT,
$IV
);
}
}
$_enc = trim(@base64_encode($_enc));
$IV = trim(@base64_encode($IV));
} else {
$IV = (int) mt_rand(1, 500);
$_enc = $this->sessEncode($_text, $IV);
}
return $_enc;
}
/**
* sessDecrypt - Decrypts encrypted text created by the sessEncrypt member.
* It needs to be passed the same Initialization Vector (IV) used in the
* encryption process. When you have a few/many fields to decrypt in one
* script cycle, choose to keep the mcrypt module open to speed up
* decryption (only for libmcrypt >= 2.4.x). A correctly decrypted field
* will be returned as a string, so if you're expecting/wanting an integer
* then you have to type cast or use intval() function.
*
* @param string $_enc Pass the encrypted text you would like to decrypt.
* @param string $_IV Pass the same IV used in the encryption phase.
* @param bool $_keep_open TRUE to keep mcrypt module open, FALSE close.
* @return mixed Returns the original plain text or FALSE on error.
* @access public
*/
function sessDecrypt($_enc, $_IV, $_keep_open = FALSE)
{
static $_open_already = FALSE; // Open encrypt flag For ver >= 2.4.x
static $_module = NULL;
if (!is_bool($_keep_open))
$_keep_open = FALSE;
if ((is_numeric($_IV)) &&
(strlen($_IV) > 0) &&
(strlen($_IV) < 4) &&
(intval($_IV) > 0) &&
(intval($_IV) < 501)) {
$_text = $this->sessDecode($_enc, intval($_IV));
} else
if (($this->_MCRYPT) &&
(!empty($this->_ENC_ALGO)) &&
(!empty($this->_ENC_MODE))) {
$_IV = @base64_decode($_IV);
$_enc = @base64_decode($_enc);
if ($this->_MCRYPT_LATEST) { // For >= 2.4.x
if (!$_open_already) {
$_module = @mcrypt_module_open($this->_ENC_ALGO, '',
$this->_ENC_MODE, '');
if (FALSE === $_module) {
// Could not open encryption module for decryption
$this->_setErrMsg('DEC_OPEN_FAIL', NULL,
$this->_ENC_ALGO, $this->_ENC_MODE);
$this->_handleErrors();
return FALSE;
}
$_open_already = TRUE;
}
$_key = substr($this->_ENC_KEY_HASHED, 0,
@mcrypt_enc_get_key_size($_module));
$_result = @mcrypt_generic_init($_module, $_key, $_IV);
if ($_result < 0) {
switch ($_result) {
case -3:
// Key length for decryption is incorrect
$this->_setErrMsg('DEC_KEY_LEN', NULL,
$this->_ENC_ALGO,
$this->_ENC_MODE,
strlen($_key));
case -4:
// There were memory allocation problems - decrypt
$this->_setErrMsg('DEC_MEMORY', NULL,
$this->_ENC_ALGO,
$this->_ENC_MODE);
default:
// There were unknown errors while trying to decrypt
$this->_setErrMsg('DEC_UNKNOWN', NULL,
$this->_ENC_ALGO,
$this->_ENC_MODE);
}
$this->_handleErrors();
return FALSE;
}
// trim is especially needed in Cipher Block Chaining (CBC) mode
$_text = trim(@mdecrypt_generic($_module, $_enc));
if (!$_keep_open) {
@mcrypt_generic_deinit($_module);
@mcrypt_module_close($_module);
$_open_already = FALSE;
$_module = NULL;
}
} else { // For 2.2.x
$_key = substr($this->_ENC_KEY_HASHED, 0,
@mcrypt_get_key_size($this->_ENC_ALGO
// FYI: Would be needed to run in > 2.2.x ,$this->_ENC_MODE
)
);
switch ($this->_ENC_MODE) {
case MCRYPT_MODE_ECB:
$_text = @mcrypt_ecb(
$this->_ENC_ALGO,
$_key,
$_enc,
MCRYPT_DECRYPT
// FYI: Would be needed to run in > 2.2.x ,$_IV
);
break;
case MCRYPT_MODE_CFB:
$_text = @mcrypt_cfb(
$this->_ENC_ALGO,
$_key,
$_enc,
MCRYPT_DECRYPT,
$_IV
);
break;
case MCRYPT_MODE_OFB:
$_text = @mcrypt_ofb(
$this->_ENC_ALGO,
$_key,
$_enc,
MCRYPT_DECRYPT,
$_IV
);
break;
default:
$_text = @mcrypt_cbc(
$this->_ENC_ALGO,
$_key,
$_enc,
MCRYPT_DECRYPT,
$_IV
);
}
$_text = trim($_text); // Especially needed for CBC mode
}
} else {
$_text = FALSE;
}
return $_text;
}
/**
* sendCacheHeader - Transmits the value for the Cache-Control header
* option(s).
*
* @uses Example to stop caching: 'no-store, no-cache, must-revalidate,
* post-check=0, pre-check=0'
*
* @param string $_options Cache-Control header option(s)
* @return bool Always returns TRUE.
* @access public
*/
function sendCacheHeader($_options = 'private')
{
header("Cache-Control: $_options");
return TRUE;
}
/**
* getMySQLVer - Call to obtain the version number of the MySQL server.
*
* @return string Returns the current MySQL server version number.
* @access public
*/
function getMySQLVer()
{
return $this->_mysql_ver;
}
/**
* getSessName - Call to obtain the current PHP Session name (used in URL's)
*
* @return string Returns the current PHP Session name.
* @access public
*/
function getSessName()
{
return $this->_sess_name;
}
/**
* getSessLife - Retrieves the current PHP Session life duration. Set
* $_in_minutes to TRUE to return a value in minutes (rounded up to
* the next whole minute).
*
* @param bool $_in_minutes A switch to signify that the return value
* should be in minutes instead of seconds (the default).
* @return int Returns the number of seconds or minutes of session life.
* @access public
*/
function getSessLife($_in_minutes = FALSE)
{
if ($_in_minutes)
return intval(ceil($this->_SESS_LIFE / 60));
else
return (int) $this->_SESS_LIFE;
}
/**
* getSessTimeout - Returns what the session timeout duration is set to. Set
* $_in_minutes to TRUE to return a value in minutes (rounded up to
* the next whole minute).
*
* @param bool $_in_minutes A switch to signify that the return value
* should be in minutes instead of seconds (the default).
* @return int Returns the number of seconds/minutes of session timeout.
* @access public
*/
function getSessTimeout($_in_minutes = FALSE)
{
if ($_in_minutes)
return intval(ceil($this->_SESS_TIMEOUT / 60));
else
return (int) $this->_SESS_TIMEOUT;
}
/**
* setSessVar - Creates or updates a session variable's value. You can
* select to have the session variables contents be encrypted. For extra
* security, you can select for an extra/duplicate field to be created which
* will contain the encrypted value (while leaving the non-encrypted value
* in the session field specified untouched). By using this option,
* getSessVar() will automatically make a comparison of the two values for
* extra validity. For the encryption option, the value can't be an array,
* a boolean, a resource, or an object.
*
* @param string $_field Name to assign as key index in $_SESSION array.
* @param mixed $_value to assign the field name/key in $_SESSION array.
* @param bool $_encrypt_value Set TRUE to have encryption performed.
* @param bool $_extra_field Set TRUE to create a new encrypted field.
* @param string $_ENC_SFX Encrypted field suffix value added to create
* the new encrypted field.
* @param string $_ENC_IV_SFX The IV field suffix value added to create
* the IV field. Always created with encryption option.
* @param bool $_ERROR Set to what value should be returned upon error.
* @return bool Returns TRUE when field value is set, FALSE on NULL/error.
* @access public
*/
function setSessVar($_field,
$_value = NULL,
$_encrypt_value = FALSE,
$_extra_field = FALSE,
$_ENC_SFX = '_enc',
$_ENC_IV_SFX = '_enc_iv',
$_ERROR = FALSE
)
{
if (empty($_field))
return $_ERROR;
if (!is_bool($_encrypt_value))
$_encrypt_value = FALSE;
/**
* When encryption requested, see if we can encrypt this type of value.
*/
if (($_encrypt_value) &&
(!is_array($_value)) &&
(!is_bool($_value)) &&
(!is_resource($_value)) &&
(!is_object($_value))) {
$_enc_iv = 0;
$_enc = $this->sessEncrypt($_value, $_enc_iv, TRUE);
if (FALSE === $_enc)
return $_ERROR; // Encryption didn't work
if (!$this->pregMatches('/[a-zA-Z0-9_]+/', $_ENC_IV_SFX))
$_ENC_IV_SFX = '_enc_iv';
/**
* Save encrypted info.
*/
$_SESSION[$_field . $_ENC_IV_SFX] = $_enc_iv;
if (!is_bool($_extra_field))
$_extra_field = FALSE;
if ($_extra_field) {
if (!$this->pregMatches('/[a-zA-Z0-9_]+/', $_ENC_SFX))
$_ENC_SFX = '_enc';
/**
* Place encrypted value in a new field, and leave non-encrypted
* value in selected/same field.
*/
$_SESSION[$_field . $_ENC_SFX] = $_enc;
$_SESSION[$_field] = $_value;
} else {
/**
* No extra field wanted, so place encrypted value in
* selected/same field.
*/
$_SESSION[$_field] = $_enc;
}
} else { // Encryption not requested or not right type
$_SESSION[$_field] = $_value;
}
return isSet($_SESSION[$_field]);
}
/**
* getSessVar - Returns a session variables value if assigned (and not NULL)
* or the default value supplied, or NULL when no default supplied. Also,
* this will detect if a value had been encrypted and will automatically
* return the decrypted value. When the extra field option is used in
* setSessVar(), then a comparison of original and extra field values are
* automatically performed to make sure that the original fields value has
* not been modified by an outside source (hacker).
* FYI: The $_SESSION array is only made available after a session_start().
*
* @param string $_field Key name to look for in $_SESSION superglobal
* array.
* @param mixed $_default A value to return when var is not set/NULL.
* @param string $_ENC_SFX Encrypted field suffix value used when
* encryption field was created (in setSessVar).
* @param string $_ENC_IV_SFX The IV field suffix value used when the IV
* field was created (in setSessVar).
* @param bool $_ERROR Set to what value should be returned upon error.
* @return mixed Returns session variable value, assigned default, or
* FALSE on error.
* @access public
*/
function getSessVar($_field,
$_default = NULL,
$_ENC_SFX = '_enc',
$_ENC_IV_SFX = '_enc_iv',
$_ERROR = FALSE
)
{
if (empty($_field))
return $_ERROR;
/**
* Determine if field has already been defined
*/
if (isSet($_SESSION[$_field])) {
if (!$this->pregMatches('/[a-zA-Z0-9_]+/', $_ENC_IV_SFX))
$_ENC_IV_SFX = '_enc_iv';
/**
* When this field is defined we have an encrypted value
*/
$_enc_iv = (isSet($_SESSION[$_field . $_ENC_IV_SFX])) ?
$_SESSION[$_field . $_ENC_IV_SFX] : NULL;
/**
* It's not encrypted when there's no IV value defined
*/
if (is_null($_enc_iv)) {
return $_SESSION[$_field]; // Return non-encrypted value
}
if (!$this->pregMatches('/[a-zA-Z0-9_]+/', $_ENC_SFX))
$_ENC_SFX = '_enc';
/**
* We now know that we have an encrypted value. Find out if the
* original or the extra field contains the encrypted value.
*/
$_enc = (isSet($_SESSION[$_field . $_ENC_SFX])) ?
$_SESSION[$_field . $_ENC_SFX] :
$_SESSION[$_field];
$_text = $this->sessDecrypt($_enc, $_enc_iv, TRUE);
if (FALSE === $_text)
return $_ERROR; // Error with decryption
/**
* If the extra field contained the encrypted value, then compare
* the original fields value with the decrypted value. They should
* both match if security hasn't been compromised.
*/
if (isSet($_SESSION[$_field . $_ENC_SFX])) {
if ($_SESSION[$_field] != $_text)
return $_ERROR; // Field integrity compromised
}
return $_text; // Return decrypted value
} else {
return $_default; // Field not defined, so return the default
}
}
/**
* stopOnWarnings - Set to stop script when warning messages are generated.
*
* @return bool Returns TRUE meaning any warnings will stop the script.
* @access public
*/
function stopOnWarnings()
{
return $this->_stop_on_warn = TRUE;
}
/**
* endStopOnWarnings - Set to keep script running when warning messages are
* generated.
*
* @return bool Returns FALSE meaning script will not stop on warnings.
* @access public
*/
function endStopOnWarnings()
{
return $this->_stop_on_warn = FALSE;
}
/**
* warningsExist - A check to see if warning messages have been generated.
*
* @return bool Returns TRUE if there are warning messages, otherwise FALSE
* @access public
*/
function warningsExist()
{
return (empty($this->_warnings)) ? FALSE : TRUE;
}
/**
* flushWarnings - Clears all warning messages that may have been generated.
*
* @return string Always returns NULL.
* @access public
*/
function flushWarnings()
{
return $this->_warnings = NULL;
}
/**
* getWarnings - Retrieves and formats all warning messages for displaying.
* Clears the warnings once called.
*
* @param string $_color Font color to return warning in (HTML syntax).
* @param string $_size Font size to return warning in (HTML syntax).
* @return string Warning messages with HTML breaks/entities added.
* @access public
*/
function getWarnings($_color = 'BLUE', $_size = '+0')
{
if (empty($_color))
$_color = 'BLUE';
if (empty($_size))
$_size = '+0';
$_warnMsgs = nl2br(htmlentities($this->_warnings, ENT_QUOTES));
$_warnMsgs = $this->_formatFont($_warnMsgs, $_color, $_size);
$this->flushWarnings();
return $_warnMsgs;
}
/**
* stopOnErrors - Set to stop script when error messages are generated.
*
* @return bool Returns TRUE meaning any errors will stop the script.
* @access public
*/
function stopOnErrors()
{
return $this->_stop_on_error = TRUE;
}
/**
* endStopOnErrors - Set to keep script running when error messages are
* generated.
*
* @return bool Returns FALSE meaning script will not stop on errors.
* @access public
*/
function endStopOnErrors()
{
return $this->_stop_on_error = FALSE;
}
/**
* errorsExist - A check to see if error messages have been generated.
*
* @return bool Returns TRUE if there are error messages, otherwise FALSE.
* @access public
*/
function errorsExist()
{
return (empty($this->_errors)) ? FALSE : TRUE;
}
/**
* flushErrors - Clears all error messages that may have been generated.
*
* @return string Always returns NULL.
* @access public
*/
function flushErrors()
{
return $this->_errors = NULL;
}
/**
* getErrors - Retrieves and formats all error messages for displaying.
* Clears the errors once called.
*
* @param string $_color Font color to return error in (HTML syntax).
* @param string $_size Font size to return error in (HTML syntax).
* @return string Severe error messages with HTML breaks/entities added.
* @access public
*/
function getErrors($_color = 'RED', $_size = '+0')
{
if (empty($_color))
$_color = 'RED';
if (empty($_size))
$_size = '+0';
$_errMsgs = nl2br(htmlentities($this->_errors, ENT_QUOTES));
$_errMsgs = $this->_formatFont($_errMsgs, $_color, $_size);
$this->flushErrors();
return $_errMsgs;
}
/**
* setSessURI - Appends the PHP session name and ID to the end of a URI.
* It checks whether a question mark already is in the URI.
* Useful for creating a URI to be used in a redirect (but less secure).
*
* @param string $_uri A URI i.e. http://www.example.com/index.php
* @return string The URI only, or URI with the session name and ID appended
* @access public
*/
function setSessURI($_uri)
{
if (!empty($_uri)) {
$_sess_id = session_id();
if (!empty($_sess_id)) { // instead of using SID
if (FALSE === strstr($_uri, '?'))
$_uri .= '?' . $this->_sess_name . '=' . $_sess_id;
else
$_uri .= $this->_ARG_SEP . $this->_sess_name . '=' .
$_sess_id;
}
}
return $_uri;
}
/**
* createLink - Creates a link and appends the PHP session name and ID when
* requested by setting $_add_sess to TRUE, which is the default.
*
* @param string $_uri The URI for the link. i.e. http://www.example.com
* @param string $_desc The text description for the link. URI used if none
* @param string $_target Where to display upon click. i.e. _blank
* @param bool $_add_sess When TRUE it adds session name and ID to link.
* @return string HTML link or empty string.
* @access public
*/
function createLink($_uri,
$_desc = NULL,
$_target = NULL,
$_add_sess = TRUE
)
{
if (empty($_uri))
return '';
if (!is_bool($_add_sess))
$_add_sess = TRUE;
$_desc = empty($_desc) ? $_uri : $_desc;
if ($_add_sess)
$_uri = $this->setSessURI($_uri);
if (empty($_target))
return sprintf("%s", $_uri, $_desc);
else
return sprintf("%s",
$_uri,
$_target,
$_desc);
}
/**
* getIPAddr - Detects and retrieves the IP address. If the value is
* obtained from HTTP_X_FORWARDED_FOR, it could have multiple IP addresses.
*
* @param string $type_used Passed by reference; used to return back a code
* @return string Returns the IP address.
* @return string Returns by reference a code used to signify the field type
* used to determine IP. Either: C, F, R, or U
* @access public
*/
function getIPAddr(&$type_used)
{
if (isSet($_SERVER['HTTP_CLIENT_IP'])) {
$_ip = $_SERVER['HTTP_CLIENT_IP'];
$type_used = 'C';
} else
if (isSet($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$type_used = 'F';
} else
if (isSet($_SERVER['REMOTE_ADDR'])) {
$_ip = $_SERVER['REMOTE_ADDR'];
$type_used = 'R';
} else {
$_ip = 'UNKNOWN';
$type_used = 'U';
}
return $_ip;
}
/**
* secureConnection - Determines whether current connection is secure (SSL).
*
* @return bool Returns TRUE when this web connection is using SSL (HTTPS).
* @access public
*/
function secureConnection()
{
if (isSet($_SERVER['HTTPS']))
return (0 === strcmp($_SERVER['HTTPS'], 'on')) ? TRUE : FALSE;
else
return FALSE;
}
/**
* getVersion - Indicates the version number of this DB_eSession class.
*
* @return string Returns the current version number of this script.
* @access public
*/
function getVersion()
{
return $this->_ver;
}
/**
* getSiteWarn - Formats a site warning message for displaying on your site.
* When $_add_link is TRUE and warning message contains 'DB_eSession', it
* will convert that text to a link to the author's web site.
*
* @param string $_color Font color to return message in (HTML syntax).
* @param string $_size Font size to return message in (HTML syntax).
* @param bool $_center TRUE-centers message (adds ).
* @param bool $_add_link When TRUE it creates a link to authors site.
* @return string Returns the site warning message.
* @access public
*/
function getSiteWarn($_color = "NAVY", $_size = '-2', $_center = FALSE,
$_add_link = TRUE)
{
$_tmp_hold = $this->_warnings;
$this->flushWarnings();
$this->_setWrnMsg('SITE_WARN');
$_msg = $this->_warnings;
$this->_warnings = $_tmp_hold;
$_msg = nl2br(htmlentities($_msg, ENT_QUOTES));
if (empty($_color))
$_color = 'NAVY';
if (empty($_size))
$_size = '-2';
if (!is_bool($_center))
$_center = FALSE;
if (!is_bool($_add_link))
$_add_link = TRUE;
if ($_add_link) {
$_msg = str_replace('DB_eSession',
$this->createLink('http://www.code.dearneighbor.com',
'DB_eSession', '_blank', FALSE),
$_msg);
}
$_msg = $this->_formatFont($_msg, $_color, $_size);
if ($_center)
$_msg = "{$_msg}";
return $_msg;
}
} // End of DB_eSession class
// Make sure there are no whitespaces after the '>' character on the last line.
?>