Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 156 lines (154 sloc) 6.39 KB
<?php
/**
* Cryptomaniac
* Send "encrypted" files over HTTP and decrypt them.
*
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @license http://www.gnu.org/licenses/gpl-2.0.html GPL v2 License
*
* @author Ben Kulbertis <ben@kulbertis.org>
*
* @since Oct 31, 2010
*/
class Cryptomaniac {
/**
* Send an "encrypted" file over HTTP with a POST request
*
* @param string $requested_file Path to the file to be transferred.
* @param string $target URL to file that is set to recieve the file.
* @param int $pass_length The length of the substring to be inserted into the data-string (for more obfuscation).
* @param int $pass_location Where the substring to be inserted into the data-string should be placed (for more obfuscation).
*
* @return boolean True on Success False on Failure
*/
public static function send_file($requested_file, $target, $pass_length = 32, $pass_location = 1) {
if(!self::_check_file($requested_file))
return false;
$requested_file = file_get_contents($requested_file);
$password = self::_get_pass($pass_length);
$encrypted_file = self::_encrypt($requested_file, $password, $pass_location);
$data = http_build_query(array(
'enc_file' => $encrypted_file
));
$length = strlen($data);
if(!self::_post_request($data, $target, $length))
return false;
else
return true;
}
/**
* Recieve a file sent using send_file(), decrypt and optionally write to a new file.
*
* @param mixed $write_to_file If not set or set as false the function will return the decrypted file-data as a string. If set as a string, it will write the data to a file using the name of the string.
* @param int $pass_length The length of the substring that was defined in the `send_file` function corresponding to this `recieve_file`. Must be the same or the decoded data will be malformed.
* @param int $pass_location Where the substring was inserted into the data-string as defined in the `send_file` function corresponding to this `recieve_file`. Must be the same or the decoded data will be malformed.
*
* @return mixed If writing to a file it will return true on success and false on failure, if not writing to a file it will return the file-data as a string.
*/
public static function recieve_file($write_to_file = false, $pass_length = 32, $pass_location = 1) {
$encrypted_file = $_POST['enc_file'];
if($encrypted_file !== null){
$decrypted_file = self::_decrypt($encrypted_file, $pass_location, $pass_length);
if($write_to_file !== false){
file_put_contents($write_to_file, $decrypted_file);
return true;
} else
return $decrypted_file;
}
else
return false;
}
/**
* Check if the requested file exists.
*
* @param string $requested_file Path to file to be transferred by send_file()
*
* @return boolean True on Success False on Failure
*/
private static function _check_file($requested_file) {
if(!file_exists($requested_file))
return false; // 404
else
return true;
}
/**
* Generate a "password" used to "encrypt" the data
*
* @param int $length The length of the generated string
*
* @return string The generated string
*/
private static function _get_pass($length) {
if($length > 32) throw new Exception('Password length can not be greater than 32. Please choose a smaller number.');
$code = md5(uniqid(rand(), true));
return substr($code, 0, $length);
}
/**
* "Encrypt" the data by inserting the
*
* @param string $requested_file The file-data string
* @param string $password The randomly generated string used to obfuscate the code
* @param int $pass_location The location where $password will be inserted
*
* @return mixed False on error, returns encrypted file-data string on success
*/
private static function _encrypt($requested_file, $password, $pass_location) {
$encrypted_file = base64_encode($requested_file);
if(strlen($encrypted_file) < $pass_location){
throw new Exception('The location you selected for the password is too great for the filesize. Please choose a lower number. Consult the readme for more information.');
return false;
}
$password = strtoupper($password);
$encrypted_file = substr_replace($encrypted_file, $password, $pass_location, 0);
$encrypted_file = base64_encode($encrypted_file);
return $encrypted_file;
}
/**
* Decrypt a file "encrypted" by _encrypt() by reversing the "encryption" process.
*
* @param string $encrypted_file The "encrypted" file-data string
* @param int $pass_location Where the inserted "password" is located
* @param int $pass_length The length of the "password"
*
* @return string The decrypted file string.
*/
private static function _decrypt($encrypted_file, $pass_location, $pass_length) {
$encrypted_file = base64_decode($encrypted_file);
$encrypted_file = substr_replace($encrypted_file, '', $pass_location, $pass_length);
$decrypted_file = base64_decode($encrypted_file);
return $decrypted_file;
}
/**
* Send an HTTP post request
*
* @param string $data The data to be sent via post.
* @param string $optional_headers Optional headers to be sent with the post request.
*
* @return The response from the server where the post data was being sent.
*
* @author Wez Furlong - http://wezfurlong.org/blog/2006/nov/http-post-from-php-without-curl
*/
private static function _post_request($data, $target, $length, $optional_headers = null){
$params = array('http' => array(
'method' => 'POST',
'content' => $data,
'length' => $length
));
if ($optional_headers !== null) {
$params['http']['header'] = $optional_headers;
}
$ctx = stream_context_create($params);
$fp = @fopen($target, 'rb', false, $ctx);
if (!$fp) {
throw new Exception("Problem with $target, $php_errormsg");
return false;
}
$response = @stream_get_contents($fp);
if ($response === false) {
throw new Exception("Problem reading data from $target, $php_errormsg");
return false;
}
return true;
}
}
?>