Location: PHPKode > scripts > Data Transmission Shield > data-transmission-shield/class.shield.php
<?php

	/**
	* Data Shield Class
	*
	* Data Shield for protecting and validating data when transmitting
	* between pages and forms.
	*
	* Copyright (C) 2005 Oliver Lillie
	* 
	* This library is free software; you can redistribute it and/or
	* modify it under the terms of the GNU Lesser General Public
	* License as published by the Free Software Foundation; either
	* version 2.1 of the License, or (at your option) any later version.
	*
	* This library is distributed in the hope that it will be useful,
	* but WITHOUT ANY WARRANTY; without even the implied warranty of
	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	* Lesser General Public License for more details.
	*
	* You should have received a copy of the GNU Lesser General Public
	* License along with this library; if not, write to the Free Software
	* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
	*
	* @link http://www.buggedcom.co.uk/
	* @author Oliver Lillie, buggedcom <publicmail at buggedcom dot co dot uk>
	* @history -----------------------------------------------------------------
	* 0.71 30/09/2005 - Added option to add slashes to form strings
	* 0.7 30/09/2005  - Added javascript > php encrypt and decryption protocols for
	*					protecting data sent via none https forms (compatabile with the 
	*					des module only)
	*				  - Added various new methods for detecting if data is transmitted
	*				  - Added mcrypt debug table
	* 0.64 26/09/2005 - Renamed encrypted vars for slightly shorter encrypted strings
	* 0.63 25/09/2005 - Added fatal error triggers to validation and excecution methods
	*				  - Added defined vars for the error type
	* 0.62 15/09/2005 - Fixed improper reference to _stripslashes_r
	* 0.61 11/09/2005 - Fixed intermitent bug with encoding and decoding
	* 0.6 07/07/2005  - Added timeout param so link is only valid for a certain
	*					amount of time after which it fails.
	*				  - Added zlib checking so not used if not available
	* 0.5 04/07/2005  - Added private function for removing globals and magic
	*					quotes. set in the constructor
	* 0.4 01/07/2005  - Added expunge and make_secure functions
	* 0.3 29/06/2005  - Marc Wöhlken has made suggestions and improved some stuff
	*				  - Added new shield type - PURE_GET
	*				  - removed random seeding
	*				  - added filename safe rfc3548 encoding and decoding
	*				  - changed default algorithm to twofish, apparently it is 30% 
	*					faster
	* 0.2 28/06/2005  - Typos corrected thanks to Greg Winterstein
	* 0.1 26/06/2005  - Created
	*/

	/**
	* Defined variables for on error handling
	* @access public 
	*/
	define('SHIELD_VERBOSE', 'SHIELD_VERBOSE');
	define('SHIELD_QUIET', 'SHIELD_QUIET');
	define('SHIELD_FATAL', 'SHIELD_FATAL');

	/**
	* Defined variables for error returning (SHIELD_QUIET)
	* @access public 
	*/
	define('SHIELD_OK', 'SHIELD_OK');
	define('SHIELD_EMPTY', 'SHIELD_EMPTY');
	define('SHIELD_SIG404', 'SHIELD_SIG404');
	define('SHIELD_TIMEOUT', 'SHIELD_TIMEOUT');
	define('SHIELD_DATA_FAULT', 'SHIELD_DATA_FAULT');
	define('SHIELD_POST_ENCRYPT_ALGORITHM_ERROR', 'SHIELD_POST_ENCRYPT_ALGORITHM_ERROR');
	define('SHIELD_POST_INVALID_CAPTCHA', 'SHIELD_POST_INVALID_CAPTCHA');

	/**
	* Defined params for different return types used in shield::protect()
	* @access public 
	*/
	define('SHIELD_PURE_GET', 'SHIELD_PURE_GET');
	define('SHIELD_PURE_GET_MULTI', 'SHIELD_PURE_GET_MULTI');
	define('SHIELD_PURE_GET_MULTI_RANDOM', 'SHIELD_PURE_GET_MULTI_RANDOM');
	define('SHIELD_GET', 'SHIELD_GET');
	define('SHIELD_GET_MULTI', 'SHIELD_GET_MULTI');
	define('SHIELD_GET_MULTI_RANDOM', 'SHIELD_GET_MULTI_RANDOM');
	define('SHIELD_PLAIN', 'SHIELD_PLAIN');
	define('SHIELD_INPUT', 'SHIELD_INPUT');
	define('SHIELD_INPUT_MULTI', 'SHIELD_INPUT_MULTI');
	define('SHIELD_INPUT_MULTI_RANDOM', 'SHIELD_INPUT_MULTI_RANDOM');

	class shield {
	
		/**
		* PUBLIC VARS
		**/

		/**
		* hash key used to encrypt the url data.
		* @access public 
		* @var string
		*/
		 var $HASH_KEY 		= 'vr1Akqw28HIpqwTlm1o4AqQe6roAf85vnDwcc9vYSmx2cDmo6wrb8gSpDwa60VwsU86YNiur3DgnBiw4ec1d';
		 
		/**
		* Digital signature md5'd into the var for validation
		* @access public 
		* @var string
		*/
		 var $DIGITAL_SIG 	= 'h0PsC0Tch';
		 		 
		/**
		* The algorithm to be used by mcrypt. Marc Wöhlken believes that twofish
		* is a faster and lighter algorithm.
		* @access public 
		* @var string
		*/
		var $ALGORITHM		= 'twofish';

		/**
		* The mode to be used by mcrypt. default = 'ecb'
		* @access public 
		* @var string
		*/
		var $MODE			= 'ecb';
		
		/**
		* The name of the var that the encoded data will take, default = '@c'
		* @access public 
		* @var string
		*/
		var $VAR_NAME		= '@c';
		
		/**
		* The algorithm to be used by javascript and mcrypt to enable POST data encryption, currently only supports one encryption module, des (default)
		* @access public 
		* @var string
		*/
		var $POST_ALGORITHM	= 'des';
		
		/**
		* The mode to be used by javascript and mcrypt to enable POST data encryption, currently only supports one encryption mode, default = 'ecb'
		* @access public 
		* @var string
		*/
		var $POST_MODE		= 'ecb';
		
		/**
		* The name of the var that the encoded data will take, default = '@c'
		* @access public 
		* @var string
		*/
		var $POST_VAR_NAME	= 'SHIELD';

		/**
		* Determines if errors are returned or false values, SHIELD_VERBOSE (default), SHIELD_QUIET, SHIELD_FATAL
		* @access public 
		* @var defined var
		*/
		var $ON_ERROR		= SHIELD_FATAL;
		
		/**
		* PRIVATE VARS
		**/

		/**
		* Init the var used to store the directory of the script
		* @access private 
		*/
		var $_DIR;

		/**
		* Init the var used to store if the server is zlib compatible
		* @access private 
		*/
		var $_ZLIB;

		/**
		* Init the expunge data array, used to collect merge var names
		* @access private 
		*/
		var $_VAR_NAMES;

		/**
		* Determines if the mycrypt module has been opened and inited
		* @access private 
		*/
		var $_OPEN 			= false;
		
		/**
		* Stores a reference to the open mcrypt module
		* @access private 
		*/
		var $_MODULE_REF;
				
		/**
		* PUBLIC FUNCTIONS
		**/
		
		/**
		* Constructor
		*
		* @access public
		* @param $remove_register_globals bool Removes defined globals if register_globals is active
		* @param $remove_magic_quotes bool Removes magic quotes if magic quotes are active
		* @return void
		**/
		function shield($remove_register_globals=true, $remove_magic_quotes=false)
		{
			# start the session
			session_start();
			# check to see if class is secure
			$this->_check_secure();
			# check for valid mycrypt stuff
			$this->_validate_algorithm();
			# create the _DIR value
			$this->_DIR = dirname(__FILE__);
			# check for zip compat
			$this->_ZLIB = function_exists('gzdeflate');
			# run the clean up funcs if required
			if($remove_register_globals) $this->_remove_globals();
			if($remove_magic_quotes) $this->_remove_magic_quotes();
			# open the shield
			$this->_open_shield();
		}
		
		/**
		* protect
		*
		* Protects data by converting the data into a string that contains the encrypted information.
		* The returned value can take several formats depending on what is required by the script.
		*
		* @access public 
		* @param mixed $data Variables you want to encrypt for transfering to another page
		* @param string $shield_type The type of return string
  		*		 SHIELD_PLAIN		- returns a plain string for input into a form value for submission
  		*				  	  		  ie vreinvg3rihviv234rv23vjmosvfe
  		*				  	  		  => <input type="hidden" name="shield" value="vreinvg3rihviv234rv23vjmosvfe" />
		*		 SHIELD_GET 		- returns a string for an url sending data
		*				   	 		   ie ?shield=vreinvg3rihviv234rv23vjmosvfe
		*				  	  		  => http://www.myhost.com/submit.php?shield=vreinvg3rihviv234rv23vjmosvfe
		*		 SHIELD_PURE_GET 	- returns a string for in the form var_name=encrypted_value
		*				   	  		  ie shield=vreinvg3rihviv234rv23vjmosvfe
		*					  		  Added by Marc Wöhlken
  		*		 SHIELD_INPUT		- returns a ready made form input string
  		*				  	  		  ie <input type="hidden" name="shield" value="vreinvg3rihviv234rv23vjmosvfe" />
		* @param string $var_name The name of the value of the return string
		* @param string|boolean $digital_sig If you want to use a different digital signature 
		*		 other than the default class one, make this the sig string, otherwise
		*		 if false the default signature is used.
		* @param integer $time If you wish to create a timeout period for this var then set this to
		* 		 the number of milliseconds you want the var to be valid for. If left at '0' then
		*		 no timeout setting will be used.
  		* @return string
		**/
		function protect($data, $shield_type=SHIELD_PLAIN, $time=0, $var_name=false, $digital_sig=false)
		{
			# check to see if class is secure
			$this->_check_secure();
								
			# process the data and return
			$_d = $this->_process_data($data, $digital_sig, $time, $var_name);
					
			# switch through the shield types
			switch($shield_type)
			{
				# Marc Wöhlken - Added PURE_GET to make it more easy to submit 
				# encoded and not encoded simultaneously
				case SHIELD_PURE_GET : 
					return $_d['var_name'] . '=' . $_d['data'];
				case SHIELD_GET : 
					# process the data and return
					return '?' . $_d['var_name'] . '=' . $_d['data'];
				case SHIELD_INPUT :
					return '<input type="hidden" name="' . $_d['var_name'] . '" value="' . $_d['data'] . '" />';
				case SHIELD_PLAIN :
					return $_d['data'];
			}
		}
		
		/**
		* expose
		*
		* This exposes the data that has been encrypted by the shield class. If required
		* it modifies the super global arrays, ie $_GET, $_POST & $_REQUEST. If the data
		* is contains the appropriate signature or if a valid time period has been set
		* the data is also returned as and array. If the data does not contain a valid
		* signature returns SIG_404. If the data contains a validity period and the value
		* is being accessed past that period then it returns TIMEOUT
		*
		* @access public 
		* @param string|boolean $str The encrypted string to decrypt and validate, or false 
		*		 to get it from the $_REQUEST global array.
		* @param string $var_name The name of the value of the return string
		* @param string $digital_sig If you want to use a different digital signature 
		*		 other than the default class one, make this the sig string, otherwise
		*		 if false the default signature is used.
		* @param boolean $modify If true, modifies the Super Global Arrays so you can reference
		*		 any data how you would of in the first place, ie $_GET['nextpage'];
		* @return array|string
		*/
		function expose($str=false, $var_name=false, $digital_sig=false, $modify=true)
		{
			# check to see if class is secure
			$this->_check_secure();

			# get the var name
			$var_name = !$var_name ? $this->VAR_NAME : $var_name;

			# check to see if the var exists
			if($str === false && !isset($_REQUEST[$var_name])) return $this->ON_ERROR == SHIELD_VERBOSE ? SHIELD_EMPTY : ($this->ON_ERROR == SHIELD_QUIET ? false : $this->_trigger_error('The string to be exposed by the Data Transmission Class contains no data.', true));
			
			# get the data
			if($str === false) $_s = $_REQUEST[$var_name];
			else $_s = $str;

			# run the decryption 
			$data = $this->_decrypt($_s);

			# check for valid digital signature
			if($data['_ds'] != (!$digital_sig ? md5($this->_DIR).md5($this->DIGITAL_SIG) : md5($digital_sig)))
			{
				if($str !== false)
				{
					unset($_REQUEST[$var_name]);
					unset($_POST[$var_name]);
					unset($_GET[$var_name]);
				}
				return $this->ON_ERROR == SHIELD_VERBOSE ? SHIELD_SIG404 : ($this->ON_ERROR == SHIELD_QUIET ? false : $this->_trigger_error('The Data Transmission Shield has not detected a correct digital signature.', true));
			}

			# check for timeout
			if($data['_to'] != -1 && isset($data['_to']) && $data['_to'] < time()) 
			{
				if($str !== false)
				{
					unset($_REQUEST[$var_name]);
					unset($_POST[$var_name]);
					unset($_GET[$var_name]);
				}
				return $this->ON_ERROR == SHIELD_VERBOSE ? SHIELD_TIMEOUT : ($this->ON_ERROR == SHIELD_QUIET ? false : $this->_trigger_error('The string protected by the Data Transmission Shield has timed out.', true));
			}
			
			# delete the validation data
			unset($data['_ds']);
			unset($data['_to']);
			
			# check for none array flag
			if(isset($data['_f'])) 
			{	
				# note if data has been flagged then that means the data encrypted was not an array
				# thus the data is not returned to the _GET of _POST array but just returned as the value
				$data = $data['_d'];
			}
			else
			{
				# if the modify is true then it will modify the GET or POST
				# super globals
				if($modify && $str === false)
				{
					# modify the global properties
					if(isset($_GET[$var_name])) 
					{
						unset($_GET[$var_name]);
						$_GET = array_merge($_GET, $data);
					}
					if(isset($_POST[$var_name])) 
					{
						unset($_POST[$var_name]);
						$_POST = array_merge($_POST, $data);
					}
					# modify the request data
					unset($_REQUEST[$var_name]);
					$_REQUEST = array_merge($_REQUEST, $data);
					# loop through the names for the expunge data
					foreach($data as $key=>$value)
					{
						$this->_VAR_NAMES[] = $key;
					}
				}
			}
						
			# return the data
			return $str !== false ? $data : ($this->ON_ERROR == SHIELD_VERBOSE ? SHIELD_OK : true);
		}
		
		/**
		* expunge
		*
		* removes the data from the super global arrays
		*
		* @access public 
  		* @return void
		**/
		function expunge($make_secure=false)
		{
			# check there are vars names to delete so no errors are thrown
			if(count($this->_VAR_NAMES) > 0)
			{
				# loop through the properties and remove from global arrays
				foreach($this->_VAR_NAMES as $key=>$var_name)
				{
					if(isset($_GET[$var_name])) unset($_GET[$var_name]);
					if(isset($_POST[$var_name])) unset($_POST[$var_name]);
					if(isset($_REQUEST[$var_name])) unset($_REQUEST[$var_name]);
				}
			}
			# remove the varnames
			unset($this->_VAR_NAMES);
			# make the class secure
			if($make_secure) $this->make_secure();
		}
		
		/**
		 * create_key_image
		 * 
		 * Creates the image used by the javascript to enter the correct key for encryption.
		 * It should be used in a seperate file from the main class as it outputs a png file.
		 * 
		 * @param integer $character_num The number of charactes the key should have
		 * @param string $font The path to the font used by the CAPTCHA
		 * @param integer $fontsize The size of the font used
		 * @param array $font_rgb The color of the font in the format array('r'=>255,'g'=>0,'b'=>0)
		 * @param integer $padding The padding between the edge of the image and the text
		 * @param array $back_rgb The color of the background in the format array('r'=>255,'g'=>0,'b'=>0)
		 * @param boolean $transparent If the background is transparent or not
		 */
		function create_key_image($character_num, $font, $fontsize=30, $font_rgb=array('r'=>255,'g'=>0,'b'=>0), $padding=10, $back_rgb=array('r'=>255,'g'=>255,'b'=>255), $transparent=false) 
		{
			# init the vars
			$width 		= 0;
			$height 	= 0;
			$offset_x 	= 0;
			$offset_y 	= 0;
			$bounds 	= array();
			$image 		= "";
			# missing 0 and O because they are inditinguishable in some fonts
			$str 		= $this->_generate_random_string($character_num, 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789123456789');
			
			# determine font height.
			$bounds 	= ImageTTFBBox($fontsize, 0, $font, "W");
			$font_height= abs($bounds[7]-$bounds[1]);
		
			# determine bounding box.
			$bounds 	= ImageTTFBBox($fontsize, 0, $font, $str);
			$width 		= abs($bounds[4]-$bounds[6]);
			$height 	= abs($bounds[7]-$bounds[1]);
			$offset_y 	= $font_height;
			$offset_x 	= 0;
			
			# create the image base
			$image 		= imagecreate($width+($padding*2)+1,$height+($padding*2)+1);
			
			# create the back and fore grounds
			$background = ImageColorAllocate($image, $back_rgb['r'], $back_rgb['g'], $back_rgb['b']);
			$foreground = ImageColorAllocate($image, $font_rgb['r'], $font_rgb['g'], $font_rgb['b']);
			
			# make transparent if required
			if ($transparent) ImageColorTransparent($image, $background);
			
			# compile image
			ImageInterlace($image, false);
			ImageTTFText($image, $fontsize, 0, $padding, $padding+$font_height, $foreground, $font, $str);
			
			# output key 
			header('Content-type: image/png');
			imagePNG($image);
			
			# init the session vars
			$_SESSION['SHIELD_CAPTCHA_KEY'] = $str;
			$_SESSION['SHIELD_CAPTCHA_KEY_LENGTH'] = $character_num;
			
			# exit the building
			exit;
		}
		
		/**
		 * create_html_elements
		 *
		 * Creates html form elements and the includes the nessecary javascript files
		 *
		 * @access public
		 * @param string $form_name The name of the form the elements are residing in
		 * @param array $form_elements_to_protect An array of element names that require protection
		 * @param string $form_onsubmit_callback The name of the function to callback on submit if the form
		 * @return void
		 */
		function create_html_elements($form_name, $form_elements_to_protect, $form_onsubmit_callback=false)
		{
			# check for correct algorithm
			if($this->POST_ALGORITHM != 'des') $this->ON_ERROR == SHIELD_VERBOSE ? SHIELD_POST_ENCRYPT_ALGORITHM_ERROR : ($this->ON_ERROR == SHIELD_QUIET ? false : $this->_trigger_error('The algorithm used by the Data Transmition Shields Post Encrypt methods must be either set to \'des\'.', true));
			
			# write out the include
			echo '<script type="text/javascript" src="shield_js/'.$this->POST_ALGORITHM.'.js"></script>'."\r\n";			
			echo '<script type="text/javascript" src="shield_js/base64.js"></script>'."\r\n";			
			
			# write out the html elements
			echo '<input type="text" id="SHIELD_CAPTCHA_KEY" name="SHIELD_CAPTCHA_KEY" value="" maxchars="'.$_SESSION['SHIELD_CAPTCHA_LENGTH'].'" />'."\r\n";
			
			# loop through the elements you want to encrypt
			# and add hidden elements
			foreach ($form_elements_to_protect as $key=>$name) 
			{
				echo '<input type="hidden" id="'.$this->POST_VAR_NAME.'['.$name.']" name="'.$this->POST_VAR_NAME.'['.$name.']" value="" />'."\r\n";
			}
			
			# write out the processing javascript functions
			echo '<script type="text/javascript">'."\r\n";
			echo '	function hide_from_prying_eyes()'."\r\n";
			echo '	{'."\r\n";
			
			# check for a callback and handle appropriatley
			if($form_onsubmit_callback == false) echo '		var callback_result = true'."\r\n";
			else echo '		var callback_result = '.$form_onsubmit_callback.'()'."\r\n";
			
			# if js callback went ok do the encryption
			echo '		if(callback_result)'."\r\n";
			echo '		{'."\r\n";
			
			# loop through the elements you want to encrypt
			foreach ($form_elements_to_protect as $key=>$name) 
			{
				echo '			// ------------------------'."\r\n";
				echo '			var key 		= document.forms.'.$form_name.'.SHIELD_CAPTCHA_KEY.value;'."\r\n";
				echo '			var val 		= document.forms.'.$form_name.'.'.$name.'.value;'."\r\n";
				if($this->POST_ALGORITHM == 'des')
				echo '			var enc_val	= rfc3548_encode(des (key, serialize({value:val}), 1, 0));'."\r\n";
				echo '			document.forms.'.$form_name.'["'.$this->POST_VAR_NAME.'['.$name.']"].value = enc_val;'."\r\n";
				echo '			document.forms.'.$form_name.'.'.$name.'.disabled = true;'."\r\n";
			}
			echo '			document.forms.'.$form_name.'.SHIELD_CAPTCHA_KEY.disabled = true;'."\r\n";
			echo '		}'."\r\n";
			echo '		else return false;'."\r\n";
			echo '		return callback_result && result;'."\r\n";
			echo '	}'."\r\n";
			echo '	document.forms.'.$form_name.'.onsubmit = hide_from_prying_eyes;';
			echo '</script>'."\r\n";
			
		}
		
		/**
		 * is_form_shielded
		 *
		 * Returns true if the $_REQUEST data has data that has been shielded from a form
		 *
		 * @return boolean
		 */
		function is_form_shielded()
		{
			return isset($_REQUEST[$this->POST_VAR_NAME]);
		}
		
		/**
		 * is_data_shielded
		 *
		 * Returns true if the $_REQUEST data has data that has been shielded in the SHIELD_GET format
		 *
		 * @return boolean
		 */
		function is_data_shielded()
		{
			return isset($_REQUEST[$this->VAR_NAME]);
		}
		
		/**
		 * expose_form
		 * 
		 * Acts similar to the normal expose function except it exposes data that has been encrypted by javascript
		 * from inside a form
		 * 
		 * @param boolean $modify If you wish the GLOBALS to be modified for easy use then true it is.
		 * @return mixed returns array on success or boolean or defined var on fault
		 */
		function expose_form($escape=false, $modify=true)
		{
			
			# check to see if class is secure
			$this->_check_secure();

			# check to see if the var exists
			if(!isset($_REQUEST[$this->POST_VAR_NAME])) return $this->ON_ERROR == SHIELD_VERBOSE ? SHIELD_EMPTY : ($this->ON_ERROR == SHIELD_QUIET ? false : $this->_trigger_error('The form protected by the Data Transmission Shield sent no data.', true));
			
			# get the data
			$_s = $_REQUEST[$this->POST_VAR_NAME];
			
			# close the current mcrypt as it is likely to be the main method of encryption
			# don't need to open it up as one will open up when used
			$this->_close_shield();
			
			$_data = array();
			foreach ($_s as $name=>$value)
			{
				$data = $this->_decrypt($value, $_SESSION['SHIELD_CAPTCHA_KEY']);
				$data[$name] = empty($data) ? SHIELD_POST_INVALID_CAPTCHA : ($escape ? addslashes($data['value']) : $data['value']);
				unset($data['value']);
				
				# if the modify is true then it will modify the GET or POST
				# super globals
				if($modify)
				{
					# modify the global properties
					if(isset($_GET[$name])) 
					{
						unset($_GET[$name]);
						$_GET = array_merge($_GET, $data);
					}
					if(isset($_POST[$name])) 
					{
						unset($_POST[$name]);
						$_POST = array_merge($_POST, $data);
					}
					# modify the request data
					unset($_REQUEST[$name]);
					$_REQUEST = array_merge($_REQUEST, $data);
					# loop through the names for the expunge data
					foreach($data as $key=>$value)
					{
						$this->_VAR_NAMES[] = $key;
					}
				}
				
			}
			
			# unset session data
			unset($_SESSION['SHIELD_CAPTCHA_KEY']);
			unset($_SESSION['SHIELD_CAPTCHA_KEY_LENGTH']);
			
			# unset the shield var
			unset($_GET[$this->POST_VAR_NAME]);
			unset($_POST[$this->POST_VAR_NAME]);
			unset($_REQUEST[$this->POST_VAR_NAME]);

			# close the post vars
			$this->_close_shield();
						
			# return the data
			return $str !== false ? $_data : ($this->ON_ERROR == SHIELD_VERBOSE ? SHIELD_OK : true);
		}

		/**
		* make_secure
		*
		* deletes all class values and makes class void to prevent re-writing of
		* a key;
		*
		* @access public 
		* @return void
		**/
		function make_secure()
		{
			# walkthrough and delete the class vars
			foreach(array_keys(get_object_vars($this)) as $value)
			{
				unset($this->$value);
			}
			# define that class is secure
			define('_SECURE_', 1);
		}
		
		/**
		* close
		*
		* public shortcut for closing the mcrypt module
		*
		* @access public 
		* @return void
		**/
		function close()
		{
			$this->_close_shield();	
		}
		
		/**
		* debug_mcrypt
		*
		* Displays a table of mycrypt compatability. lifted from  http://www.php.net/mcrypt
		*
		* @access public 
		* @return void
		**/
		function debug_mcrypt() 
		{ 
			$modes 		= mcrypt_list_modes(); 
			$algorithms = mcrypt_list_algorithms(); 
			echo "<table border=1>"; 
			echo "<tr><td align=center><strong>Algorithm</strong></td align=center><td><strong>Status</strong></td>"; 
			foreach ($modes as $mode) echo "<td align=center><strong>".strtoupper($mode)."</strong></td>"; 
			echo "</tr>"; 
			foreach ($algorithms as $cipher) 
			{ 
				echo "<tr><td bgcolor=f0f0ff align=left>".strtoupper($cipher)."</td>"; 
				if(mcrypt_module_self_test($cipher)) print "<td bgcolor=green align=center>OK</td>"; 
				else print "<td bgcolor=red align=center>NOT OK</td>"; 
				foreach ($modes as $mode)
				{
					if($mode == 'stream') $result = "<td bgcolor=gray align=center>NOT TESTED</td>"; 
					else if($this->_mcrypt_test_module_mode($cipher, $mode)) $result = "<td bgcolor=green align=center><strong>OK</strong></td>"; 
					else $result = "<td bgcolor=red align=center>NOT OK</td>"; 
					print $result; 
				}
				echo "</tr>"; 
			}
			echo "</table>"; 
		}  

		/**
		* PRIVATE FUNCTIONS
		**/

		/**
		* _mcrypt_test_module_mode
		*
		* a variant on the example posted in mdecrypt_generic 
		*
		* @access private
		* @return void
		**/
		function _mcrypt_test_module_mode($module, $mode)
		{
			/* Data */ 
			$plain_text = 'Hello World, Nice Day Today Isn\'t It. '.date('d/M/Y'); 
			
			/* Open module, and create IV */ 
			$td 	 = @mcrypt_module_open($module, '', $mode, ''); 
			if($td)
			{
				$key 	 = substr($this->HASH_KEY, 0, mcrypt_enc_get_key_size($td)); 
				$iv_size = @mcrypt_enc_get_iv_size($td); 
				$iv 	 = @mcrypt_create_iv($iv_size, MCRYPT_RAND); 
		
				/* Initialize encryption handle */ 
				if (mcrypt_generic_init($td, $key, $iv) != -1)
				{
		
					/* Encrypt data */ 
					$c_t = mcrypt_generic($td, $plain_text); 
					mcrypt_generic_deinit($td); 
					
					// close the module 
					mcrypt_module_close($td); 
					
					/* Reinitialize buffers for decryption */ 
					/* Open module */ 
					$td = mcrypt_module_open($module, '', $mode, ''); 
					$key = substr($key, 0, mcrypt_enc_get_key_size($td)); 
					
					mcrypt_generic_init($td, $key, $iv); 
					$p_t = trim(mdecrypt_generic($td, $c_t)); //trim to remove padding 
					
					/* Clean up */ 
					mcrypt_generic_end($td); 
					mcrypt_module_close($td); 
				} 
			}
			else return false;
			return (strncmp($p_t, $plain_text, strlen($plain_text)) == 0);
		}

		/**
		* _open_shield
		*
		* Opens the Mycrypt module for use and registers a shutdown function to autoclose the module
		*
		* @access private
		* @return void
		**/
		function _open_shield($form_key=false)
		{
			if(!$this->_OPEN)
			{
				$algorithm 	= $form_key !== false ? $this->POST_ALGORITHM : $this->ALGORITHM; 
				$mode 		= $form_key !== false ? $this->POST_MODE : $this->MODE; 
				$key		= $form_key !== false ? $form_key : $this->HASH_KEY; 
				# typo corrected < thanks to Greg Winterstein
				# openup mcrypt
				$this->_MODULE_REF 	= @mcrypt_module_open($algorithm, '', $mode, '');
				$iv 				= @mcrypt_create_iv (@mcrypt_enc_get_iv_size($this->_MODULE_REF), MCRYPT_RAND);
				# process the key
				$key 	= substr($key, 0, @mcrypt_enc_get_key_size($this->_MODULE_REF));
				# init mcrypt
				@mcrypt_generic_init($this->_MODULE_REF, $key, $iv);
				# mark as open
				$this->_OPEN = true;
			}
		}

		/**
		* _close_shield
		*
		* Closes the Mycrypt open module
		*
		* @access private
		* @return void
		**/
		function _close_shield()
		{
			if($this->_OPEN)
			{
				# mark as closed
				$this->_OPEN = false;

				# shutdown mcrypt
				@mcrypt_generic_deinit($this->_MODULE_REF);
				@mcrypt_module_close($this->_MODULE_REF);
							
			}

		}

		/**
		* _process_data
	 	*
		* Process the raw data and returns the appropriate var name and encrypted data
		* 
		* @param mixed $data
		* @param string $digital_sig
		* @param integer $time
		* @param mixed $var_name
		* @return array
		*/
		function _process_data($data, $digital_sig, $time, $var_name=false)
		{
			# process the varname
			$_vn  = $var_name === false ? $this->VAR_NAME : $var_name;
			# do the data retrieval
			$data = is_array($data) ? $data : array('_d'=>$data, '_f'=>1);
			# add the digital sig
			$data['_ds'] = !$digital_sig ? md5($this->_DIR).md5($this->DIGITAL_SIG) : md5($digital_sig);
			# add the timeout
			$data['_to'] = $time > 0 ? time()+$time : -1;
			# return the data
			return array('data'=>$this->_encrypt($data), 'var_name'=>$_vn);
		}
		
		/**
		* _encrypt
		*
		* encrypts the key
		*
		* @access private 
		* @param $src_array array The data array that contains the key data
  		* @return string Returns the encrypted string
		**/
		function _encrypt($src_array, $form_key=false)
		{			
			# check to see if class is secure
			$this->_check_secure();
			
			# make sure that mcrypt is open
			$this->_open_shield($form_key);

			# encrypt data
			# Use gzip to reduce URL size introduced by Marc Wöhlken
			# lib checking added later
			$data 	= $this->_ZLIB && $form_key===false ? gzdeflate(serialize($src_array), 9) : serialize($src_array);
			$crypt 	= @mcrypt_generic($this->_MODULE_REF, $data);
		
			# return the key
			# MW. Use RFC 3548 "Base 64 Encoding with URL and Filename 
			# Safe Alphabet"introduced by Marc Wöhlken
			return $this->_rfc3548_encode($crypt);
		}
		
		/**
		* _decrypt
		*
		* decrypts the key
		*
		* @access private 
		* @param $enc_string string The key string that contains the data
  		* @return array Returns decrypted array
		**/
		function _decrypt($enc_string, $form_key=false)
		{
			# check to see if class is secure
			$this->_check_secure();
			
			# make sure that mcrypt is open
			$this->_open_shield($form_key);

			# Use RFC 3548 "Base 64 Encoding with URL and Filename 
			# Safe Alphabet" introduced by Marc Wöhlken
			$enc_string = $this->_rfc3548_decode($enc_string);

			# decrypt the data and return
			$decrypt = @mdecrypt_generic($this->_MODULE_REF, $enc_string);

			# return the key
			# gzip compression added by Marc Wöhlken
			# lib checking added later
			$decrypt = $this->_ZLIB && $form_key===false ? gzinflate($decrypt) : $decrypt;
			return unserialize($decrypt);
		}
		
		/**
		* _generate_random_string
		*
		* creates a random string
		*
		* @access private 
		* @param integer 
		* @param string 
		* @return string
		**/
		function _generate_random_string($length=10, $seeds=false)
		{
			$str = '';
			$seeds = $seeds == false ? 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789' : $seeds;
			$seeds_count = strlen($seeds);
		
			list($usec, $sec) = explode(' ', microtime());
			$seed = (float) $sec + ((float) $usec * 100000);
			mt_srand($seed);
		
			for ($i = 0; $length > $i; $i++) {
				$str .= $seeds{mt_rand(0, $seeds_count - 1)};
			}
			return $str;
		}
		
		/**
		* _remove_globals
		*
		* remove globals if register_globals is on
		* borrowed from http://www.phpguru.org/#58
		*
		* @access private 
		* @return void
		**/
		function _remove_globals()
		{
			if (ini_get('register_globals'))
			{ 
				foreach ($_REQUEST as $k => $v)
				{ 
					unset($GLOBALS[$k]); 
				} 
			} 
		}

		/**
		* _remove_magic_quotes
		*
		* remove magic quotes if magic_quotes_gpc is on
		* borrowed from http://www.phpguru.org/#58
		*
		* @access private 
		* @return void
		**/
		function _remove_magic_quotes()
		{
			if (ini_get('magic_quotes_gpc')) 
			{ 
				foreach (array('_GET', '_POST', '_COOKIE') as $super) 
				{ 
					foreach ($GLOBALS[$super] as $k => $v) 
					{ 
						$GLOBALS[$super][$k] = $this->_stripslashes_r($v); 
					} 
				} 
			} 
		}

		/**
		* _stripslashes_r
		*
		* Recursive stripslashes. array_walk_recursive seems to have great 
		* trouble with stripslashes().
		* borrowed from http://www.phpguru.org/#58
		*
		* @access private 
		* @param  mixed $str String or array 
		* @return mixed      String or array with slashes removed 
		**/
		function _stripslashes_r($str) 
		{ 
			if (is_array($str))
			{ 
				foreach ($str as $k => $v)
				{ 
					$str[$k] = $this->_stripslashes_r($v); 
				} 
				return $str; 
			} 
			else 
			{ 
				return stripslashes($str); 
			} 
		} 
		
		/**
		* _trigger_error
		*
		* triggers an error
		*
		* @access private 
		* @param $message string The string to read in the error.
		* @param $fatal boolean If true script termination occurs.
		* @return void
		**/
		function _trigger_error($message, $fatal=true)
		{
				trigger_error("<br /><br /><span style='color: #F00;font-weight: bold;'>".$message."<br /><br /></span>", E_USER_ERROR);
				if($fatal) exit;
		}
		
		/**
		* _validate_algorithm
		*
		* validates the mcrypt settings
		*
		* @access private 
		* @return void
		**/
		function _validate_algorithm()
		{
			if(!function_exists('mcrypt_module_open')) $this->_trigger_error("In order to function this script needs to use the PHP Library '<a href='http://www.php.net/mcrypt' target='_blank'>Mcrypt<a/>'. Unfortunately Mcrypt is not present on your PHP installation. Please contact your server administrator for further advice.", true);
			if(!in_array($this->ALGORITHM, mcrypt_list_algorithms())) $this->_trigger_error("In order to function this script uses the PHP Library '<a href='http://www.php.net/mcrypt' target='_blank'>Mcrypt<a/>'. Unfortunately Mcrypt whilst present on your PHP installation does not have access to the '".$this->ALGORITHM."' algorithm. Please contact your server administrator for further advice.", true);
			if(!in_array($this->MODE, mcrypt_list_modes())) $this->_trigger_error("In order to function this script uses the PHP Library '<a href='http://www.php.net/mcrypt' target='_blank'>Mcrypt<a/>'. Unfortunately Mcrypt whilst present on your PHP installation does not have access to the '".$this->MODE."' mode. Please contact your server administrator for further advice.", true);
		}
		
		
		/**
		* _rfc3548_encode
		*
		* replaces double base64_encoding
		* credits to Marc Wöhlken
		*
		* @access private 
		* @return void
		**/
		function _rfc3548_encode($str)
		{
			return str_replace(array('/', '+'), array('_', '-'), base64_encode($str));
		}
		
		/**
		* _rfc3548_decode
		*
		* replaces double base64_decoding
		* credits to Marc Wöhlken
		*
		* @access private 
		* @return void
		**/
		function _rfc3548_decode($str)
		{
			return base64_decode(str_replace(array('_', '-'), array('/', '+'), $str));
		}
		
		/**
		* _check_secure
		*
		* checks to see if the class has been made secure
		*
		* @access private 
		**/
		function _check_secure()
		{
			if(defined('_SECURE_')) $this->_trigger_error('The Data Transmission Shield has been made secure. This script has been terminated.', true);
		}
	}



?>
Return current item: Data Transmission Shield