Сборка REDL: панель на PHP 8, капча-тумблер, закрытые уязвимости, установщики в один клик

- панель работает на PHP 8.4 (оригинал под PHP 7.0): elFinder utf8_encode, apache_get_modules, warnings
- капча выключена и управляется из админки (флаг captcha_enable + блок настроек)
- закрыты две SQL-инъекции без авторизации (createAuthLog: пароль из POST и CF-Connecting-IP)
- убрано хранение паролей в открытом виде в authlog, XSS в поле ref
- установщики install-panel.sh и install-node.sh (оригинальный затирал sources.list репозиториями Debian 9)
- современный Dockerfile (оригинальный на debian:stretch больше не собирается)
- планировщик и автозапуск работают без systemd
- брендинг REDL.IO, год 2026, ссылки на redl.io
- документация на русском: ИЗМЕНЕНИЯ, БЕЗОПАСНОСТЬ, ИНСТРУКЦИЯ
This commit is contained in:
2026-07-30 02:00:01 +00:00
commit 6ee2744e3a
492 changed files with 354172 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
deny from all
+78
View File
@@ -0,0 +1,78 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
final class mysqlDriver {
private $link;
private $count = 0;
public function __construct($hostname, $username, $password, $database) {
if (!$this->link = @mysqli_connect($hostname, $username, $password)) {
exit('Ошибка: Не удалось соединиться с сервером базы данных!');
}
if (!mysqli_select_db($this->link, $database)) {
exit('Ошибка: Не удалось соединиться с базой ' . $database);
}
mysqli_query($this->link, "SET NAMES 'utf8'");
mysqli_query($this->link, "SET CHARACTER SET utf8");
mysqli_query($this->link, "SET CHARACTER_SET_CONNECTION=utf8");
mysqli_query($this->link, "SET SQL_MODE = ''");
}
public function query($sql) {
$resource = mysqli_query($this->link, $sql);
$this->count++;
if($resource) {
if($resource instanceof mysqli_result) {
$i = 0;
$data = array();
while($result = mysqli_fetch_assoc($resource)) {
$data[$i] = $result;
$i++;
}
mysqli_free_result($resource);
$query = new stdClass();
$query->row = isset($data[0]) ? $data[0] : array();
$query->rows = $data;
$query->num_rows = $i;
unset($data);
return $query;
} else {
return true;
}
} else {
exit('Ошибка: ' . mysqli_error($this->link) . '<br>Номер ошибки: ' . mysqli_errno($this->link) . '<br>' . $sql);
}
}
public function escape($value) {
$value = str_replace(array("'", "\"", "%", "`", "", "\xbf\x27"), "", $value);
return mysqli_real_escape_string($this->link, $value);
}
public function countAffected() {
return mysqli_affected_rows($this->link);
}
public function getLastId() {
return mysqli_insert_id($this->link);
}
public function getCount() {
return $this->count;
}
public function __destruct() {
mysqli_close($this->link);
}
}
?>
+2
View File
@@ -0,0 +1,2 @@
order deny,allow
deny from all
+55
View File
@@ -0,0 +1,55 @@
<?php
define('ELFINDER_PHP_ROOT_PATH', dirname(__FILE__));
function elFinderAutoloader($name)
{
$map = array(
'elFinder' => 'elFinder.class.php',
'elFinderConnector' => 'elFinderConnector.class.php',
'elFinderEditor' => 'editors/editor.php',
'elFinderLibGdBmp' => 'libs/GdBmp.php',
'elFinderPlugin' => 'elFinderPlugin.php',
'elFinderPluginAutoResize' => 'plugins/AutoResize/plugin.php',
'elFinderPluginAutoRotate' => 'plugins/AutoRotate/plugin.php',
'elFinderPluginNormalizer' => 'plugins/Normalizer/plugin.php',
'elFinderPluginSanitizer' => 'plugins/Sanitizer/plugin.php',
'elFinderPluginWatermark' => 'plugins/Watermark/plugin.php',
'elFinderSession' => 'elFinderSession.php',
'elFinderSessionInterface' => 'elFinderSessionInterface.php',
'elFinderVolumeDriver' => 'elFinderVolumeDriver.class.php',
'elFinderVolumeDropbox2' => 'elFinderVolumeDropbox2.class.php',
'elFinderVolumeFTP' => 'elFinderVolumeFTP.class.php',
'elFinderVolumeFlysystemGoogleDriveCache' => 'elFinderFlysystemGoogleDriveNetmount.php',
'elFinderVolumeFlysystemGoogleDriveNetmount' => 'elFinderFlysystemGoogleDriveNetmount.php',
'elFinderVolumeGoogleDrive' => 'elFinderVolumeGoogleDrive.class.php',
'elFinderVolumeGroup' => 'elFinderVolumeGroup.class.php',
'elFinderVolumeLocalFileSystem' => 'elFinderVolumeLocalFileSystem.class.php',
'elFinderVolumeMySQL' => 'elFinderVolumeMySQL.class.php',
'elFinderVolumeTrash' => 'elFinderVolumeTrash.class.php',
);
if (isset($map[$name])) {
return include_once(ELFINDER_PHP_ROOT_PATH . '/' . $map[$name]);
}
$prefix = substr($name, 0, 14);
if (substr($prefix, 0, 8) === 'elFinder') {
if ($prefix === 'elFinderVolume') {
$file = ELFINDER_PHP_ROOT_PATH . '/' . $name . '.class.php';
return (is_file($file) && include_once($file));
} else if ($prefix === 'elFinderPlugin') {
$file = ELFINDER_PHP_ROOT_PATH . '/plugins/' . substr($name, 14) . '/plugin.php';
return (is_file($file) && include_once($file));
} else if ($prefix === 'elFinderEditor') {
$file = ELFINDER_PHP_ROOT_PATH . '/editors/' . substr($name, 14) . '/editor.php';
return (is_file($file) && include_once($file));
}
}
return false;
}
if (version_compare(PHP_VERSION, '5.3', '<')) {
spl_autoload_register('elFinderAutoloader');
} else {
spl_autoload_register('elFinderAutoloader', true, true);
}
@@ -0,0 +1,113 @@
<?php
class elFinderEditorOnlineConvert extends elFinderEditor
{
protected $allowed = array('init', 'api');
public function enabled()
{
return defined('ELFINDER_ONLINE_CONVERT_APIKEY') && ELFINDER_ONLINE_CONVERT_APIKEY && (!defined('ELFINDER_DISABLE_ONLINE_CONVERT') || !ELFINDER_DISABLE_ONLINE_CONVERT);
}
public function init()
{
return array('api' => defined('ELFINDER_ONLINE_CONVERT_APIKEY') && ELFINDER_ONLINE_CONVERT_APIKEY && function_exists('curl_init'));
}
public function api()
{
// return array('apires' => array('message' => 'Currently disabled for developping...'));
$endpoint = 'https://api2.online-convert.com/jobs';
$category = $this->argValue('category');
$convert = $this->argValue('convert');
$options = $this->argValue('options');
$source = $this->argValue('source');
$filename = $this->argValue('filename');
$mime = $this->argValue('mime');
$jobid = $this->argValue('jobid');
$string_method = '';
$options = array();
// Currently these converts are make error with API call. I don't know why.
$nonApi = array('android', 'blackberry', 'dpg', 'ipad', 'iphone', 'ipod', 'nintendo-3ds', 'nintendo-ds', 'ps3', 'psp', 'wii', 'xbox');
if (in_array($convert, $nonApi)) {
return array('apires' => array());
}
$ch = null;
if ($convert && $source) {
$request = array(
'input' => array(array(
'type' => 'remote',
'source' => $source
)),
'conversion' => array(array(
'target' => $convert
))
);
if ($filename !== '') {
$request['input'][0]['filename'] = $filename;
}
if ($mime !== '') {
$request['input'][0]['content_type'] = $mime;
}
if ($category) {
$request['conversion'][0]['category'] = $category;
}
if ($options && $options !== 'null') {
$options = json_decode($options, true);
}
if (!is_array($options)) {
$options = array();
}
if ($options) {
$request['conversion'][0]['options'] = $options;
}
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-Oc-Api-Key: ' . ELFINDER_ONLINE_CONVERT_APIKEY,
'Content-Type: application/json',
'cache-control: no-cache'
));
} else if ($jobid) {
$ch = curl_init($endpoint . '/' . $jobid);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X-Oc-Api-Key: ' . ELFINDER_ONLINE_CONVERT_APIKEY,
'cache-control: no-cache'
));
}
if ($ch) {
$response = curl_exec($ch);
$info = curl_getinfo($ch);
$error = curl_error($ch);
curl_close($ch);
if (!empty($error)) {
$res = array('error' => $error);
} else {
$data = json_decode($response, true);
if (isset($data['status']) && isset($data['status']['code']) && $data['status']['code'] === 'completed') {
/** @var elFinderSession $session */
$session = $this->elfinder->getSession();
$urlContentSaveIds = $session->get('urlContentSaveIds', array());
$urlContentSaveIds['OnlineConvert-' . $data['id']] = true;
$session->set('urlContentSaveIds', $urlContentSaveIds);
}
$res = array('apires' => $data);
}
return $res;
} else {
return array('error' => array('errCmdParams', 'editor.OnlineConvert.api'));
}
}
}
@@ -0,0 +1,12 @@
<?php
class elFinderEditorZipArchive extends elFinderEditor
{
public function enabled()
{
return (!defined('ELFINDER_DISABLE_ZIPEDITOR') || !ELFINDER_DISABLE_ZIPEDITOR) &&
class_exists('Barryvdh\elFinderFlysystemDriver\Driver') &&
class_exists('League\Flysystem\Filesystem') &&
class_exists('League\Flysystem\ZipArchive\ZipArchiveAdapter');
}
}
@@ -0,0 +1,206 @@
<?php
class elFinderEditorZohoOffice extends elFinderEditor
{
private static $curlTimeout = 20;
protected $allowed = array('init', 'save', 'chk');
protected $editor_settings = array(
'writer' => array(
'unit' => 'mm',
'view' => 'pageview'
),
'sheet' => array(
'country' => 'US'
),
'show' => array()
);
private $urls = array(
'writer' => 'https://writer.zoho.com/writer/officeapi/v1/document',
'sheet' => 'https://sheet.zoho.com/sheet/officeapi/v1/spreadsheet',
'show' => 'https://show.zoho.com/show/officeapi/v1/presentation',
);
private $srvs = array(
'application/msword' => 'writer',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'writer',
'application/pdf' => 'writer',
'application/vnd.oasis.opendocument.text' => 'writer',
'application/rtf' => 'writer',
'text/html' => 'writer',
'application/vnd.ms-excel' => 'sheet',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'sheet',
'application/vnd.oasis.opendocument.spreadsheet' => 'sheet',
'application/vnd.sun.xml.calc' => 'sheet',
'text/csv' => 'sheet',
'text/tab-separated-values' => 'sheet',
'application/vnd.ms-powerpoint' => 'show',
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'show',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'show',
'application/vnd.oasis.opendocument.presentation' => 'show',
'application/vnd.sun.xml.impress' => 'show',
);
private $myName = '';
public function __construct($elfinder, $args)
{
parent::__construct($elfinder, $args);
$this->myName = preg_replace('/^elFinderEditor/i', '', get_class($this));
}
public function enabled()
{
return defined('ELFINDER_ZOHO_OFFICE_APIKEY') && ELFINDER_ZOHO_OFFICE_APIKEY && function_exists('curl_init');
}
public function init()
{
if (!defined('ELFINDER_ZOHO_OFFICE_APIKEY') || !function_exists('curl_init')) {
return array('error', array(elFinder::ERROR_CONF, '`ELFINDER_ZOHO_OFFICE_APIKEY` or curl extension'));
}
if (!empty($this->args['target'])) {
$fp = $cfile = null;
$hash = $this->args['target'];
/** @var elFinderVolumeDriver $srcVol */
if (($srcVol = $this->elfinder->getVolume($hash)) && ($file = $srcVol->file($hash))) {
$cdata = empty($this->args['cdata']) ? '' : $this->args['cdata'];
$cookie = $this->elfinder->getFetchCookieFile();
$save = false;
$ch = curl_init();
$conUrl = elFinder::getConnectorUrl();
curl_setopt($ch, CURLOPT_URL, $conUrl . (strpos($conUrl, '?') !== false? '&' : '?') . 'cmd=editor&name=' . $this->myName . '&method=chk&args[target]=' . rawurlencode($hash) . $cdata);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if ($cookie) {
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
}
$res = curl_exec($ch);
curl_close($ch);
if ($res) {
if ($data = json_decode($res, true)) {
$save = !empty($data['cansave']);
}
}
if ($size = $file['size']) {
$src = $srcVol->open($hash);
$fp = tmpfile();
stream_copy_to_stream($src, $fp);
$srcVol->close($src, $hash);
$info = stream_get_meta_data($fp);
if ($info && !empty($info['uri'])) {
$srcFile = $info['uri'];
if (class_exists('CURLFile')) {
$cfile = new CURLFile($srcFile);
$cfile->setPostFilename($file['name']);
$cfile->setMimeType($file['mime']);
} else {
$cfile = '@' . $srcFile;
}
}
}
//$srv = $this->args['service'];
$format = $srcVol->getExtentionByMime($file['mime']);
if (!$format) {
$format = substr($file['name'], strrpos($file['name'], '.') * -1);
}
$lang = $this->args['lang'];
if ($lang === 'jp') {
$lang = 'ja';
}
$srvsName = $this->srvs[$file['mime']];
$data = array(
'apikey' => ELFINDER_ZOHO_OFFICE_APIKEY,
'callback_settings' => array(
'save_format' => $format,
'context_info' => array(
'hash' => $hash
)
),
'editor_settings' => $this->editor_settings[$srvsName],
'document_info' => array(
'document_name' => substr($file['name'], 0, strlen($file['name']) - strlen($format)- 1)
)
);
$data['editor_settings']['language'] = $lang;
if ($save) {
$conUrl = elFinder::getConnectorUrl();
$data['callback_settings']['save_url'] = $conUrl . (strpos($conUrl, '?') !== false? '&' : '?') . 'cmd=editor&name=' . $this->myName . '&method=save' . $cdata;
}
foreach($data as $_k => $_v) {
if (is_array($_v)){
$data[$_k] = json_encode($_v);
}
}
if ($cfile) {
$data['document'] = $cfile;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->urls[$srvsName]);
curl_setopt($ch, CURLOPT_TIMEOUT, self::$curlTimeout);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$res = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
$fp && fclose($fp);
if ($res && $res = @json_decode($res, true)) {
if (!empty($res['document_url'])) {
$ret = array('zohourl' => $res['document_url']);
if (!$save) {
$ret['warning'] = 'exportToSave';
}
return $ret;
} else {
$error = $res;
}
}
if ($error) {
return array('error' => is_string($error)? preg_split('/[\r\n]+/', $error) : 'Error code: ' . $error);
}
}
}
return array('error' => array('errCmdParams', 'editor.' . $this->myName . '.init'));
}
public function save()
{
if (!empty($_POST) && !empty($_POST['id']) && !empty($_FILES) && !empty($_FILES['content'])) {
$data = @json_decode(str_replace('&quot;', '"', $_POST['id']), true);
if (!empty($data['hash'])) {
$hash = $data['hash'];
/** @var elFinderVolumeDriver $volume */
if ($volume = $this->elfinder->getVolume($hash)) {
if ($content = file_get_contents($_FILES['content']['tmp_name'])) {
if ($volume->putContents($hash, $content)) {
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 200 OK');
}
}
}
}
}
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 500 Internal Server Error');
}
public function chk()
{
$hash = $this->args['target'];
$res = false;
/** @var elFinderVolumeDriver $volume */
if ($volume = $this->elfinder->getVolume($hash)) {
if ($file = $volume->file($hash)) {
$res = (bool)$file['write'];
}
}
return array('cansave' => $res);
}
}
@@ -0,0 +1,79 @@
<?php
/**
* Abstract class of editor plugins.
*
* @author Naoki Sawada
*/
class elFinderEditor
{
/**
* Array of allowed method by request from client side.
*
* @var array
*/
protected $allowed = array();
/**
* elFinder instance
*
* @var object elFinder instance
*/
protected $elfinder;
/**
* Arguments
*
* @var array argValues
*/
protected $args;
/**
* Constructor.
*
* @param object $elfinder
* @param array $args
*/
public function __construct($elfinder, $args)
{
$this->elfinder = $elfinder;
$this->args = $args;
}
/**
* Return boolean that this plugin is enabled.
*
* @return bool
*/
public function enabled()
{
return true;
}
/**
* Return boolean that $name method is allowed.
*
* @param string $name
*
* @return bool
*/
public function isAllowedMethod($name)
{
$checker = array_flip($this->allowed);
return isset($checker[$name]);
}
/**
* Return $this->args value of the key
*
* @param string $key target key
* @param string $empty empty value
*
* @return mixed
*/
public function argValue($key, $empty = '')
{
return isset($this->args[$key]) ? $this->args[$key] : $empty;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,380 @@
<?php
/**
* Default elFinder connector
*
* @author Dmitry (dio) Levashov
**/
class elFinderConnector
{
/**
* elFinder instance
*
* @var elFinder
**/
protected $elFinder;
/**
* Options
*
* @var array
**/
protected $options = array();
/**
* Must be use output($data) $data['header']
*
* @var string
* @deprecated
**/
protected $header = '';
/**
* HTTP request method
*
* @var string
*/
protected $reqMethod = '';
/**
* Content type of output JSON
*
* @var string
*/
protected static $contentType = 'Content-Type: application/json; charset=utf-8';
/**
* Constructor
*
* @param $elFinder
* @param bool $debug
*
* @author Dmitry (dio) Levashov
*/
public function __construct($elFinder, $debug = false)
{
$this->elFinder = $elFinder;
$this->reqMethod = strtoupper($_SERVER["REQUEST_METHOD"]);
if ($debug) {
self::$contentType = 'Content-Type: text/plain; charset=utf-8';
}
}
/**
* Execute elFinder command and output result
*
* @return void
* @throws Exception
* @author Dmitry (dio) Levashov
*/
public function run()
{
$isPost = $this->reqMethod === 'POST';
$src = $isPost ? array_merge($_GET, $_POST) : $_GET;
$maxInputVars = (!$src || isset($src['targets'])) ? ini_get('max_input_vars') : null;
if ((!$src || $maxInputVars) && $rawPostData = file_get_contents('php://input')) {
// for max_input_vars and supports IE XDomainRequest()
$parts = explode('&', $rawPostData);
if (!$src || $maxInputVars < count($parts)) {
$src = array();
foreach ($parts as $part) {
list($key, $value) = array_pad(explode('=', $part), 2, '');
$key = rawurldecode($key);
if (preg_match('/^(.+?)\[([^\[\]]*)\]$/', $key, $m)) {
$key = $m[1];
$idx = $m[2];
if (!isset($src[$key])) {
$src[$key] = array();
}
if ($idx) {
$src[$key][$idx] = rawurldecode($value);
} else {
$src[$key][] = rawurldecode($value);
}
} else {
$src[$key] = rawurldecode($value);
}
}
$_POST = $this->input_filter($src);
$_REQUEST = $this->input_filter(array_merge_recursive($src, $_REQUEST));
}
}
if (isset($src['targets']) && $this->elFinder->maxTargets && count($src['targets']) > $this->elFinder->maxTargets) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_MAX_TARGTES)));
}
$cmd = isset($src['cmd']) ? $src['cmd'] : '';
$args = array();
if (!function_exists('json_encode')) {
$error = $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_JSON);
$this->output(array('error' => '{"error":["' . implode('","', $error) . '"]}', 'raw' => true));
}
if (!$this->elFinder->loaded()) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_VOL), 'debug' => $this->elFinder->mountErrors));
}
// telepat_mode: on
if (!$cmd && $isPost) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UPLOAD, elFinder::ERROR_UPLOAD_TOTAL_SIZE), 'header' => 'Content-Type: text/html'));
}
// telepat_mode: off
if (!$this->elFinder->commandExists($cmd)) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UNKNOWN_CMD)));
}
// collect required arguments to exec command
$hasFiles = false;
foreach ($this->elFinder->commandArgsList($cmd) as $name => $req) {
if ($name === 'FILES') {
if (isset($_FILES)) {
$hasFiles = true;
} elseif ($req) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
}
} else {
$arg = isset($src[$name]) ? $src[$name] : '';
if (!is_array($arg) && $req !== '') {
$arg = trim($arg);
}
if ($req && $arg === '') {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
}
$args[$name] = $arg;
}
}
$args['debug'] = isset($src['debug']) ? !!$src['debug'] : false;
$args = $this->input_filter($args);
if ($hasFiles) {
$args['FILES'] = $_FILES;
}
try {
$this->output($this->elFinder->exec($cmd, $args));
} catch (elFinderAbortException $e) {
// connection aborted
// unlock session data for multiple access
$this->elFinder->getSession()->close();
// HTTP response code
header('HTTP/1.0 204 No Content');
// clear output buffer
while (ob_get_level() && ob_end_clean()) {
}
exit();
}
}
/**
* Sets the header.
*
* @param array|string $value HTTP header(s)
*/
public function setHeader($value)
{
$this->header = $value;
}
/**
* Output json
*
* @param array data to output
*
* @return void
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
*/
protected function output(array $data)
{
// unlock session data for multiple access
$this->elFinder->getSession()->close();
// client disconnect should abort
ignore_user_abort(false);
if ($this->header) {
self::sendHeader($this->header);
}
if (isset($data['pointer'])) {
// set time limit to 0
elFinder::extendTimeLimit(0);
// send optional header
if (!empty($data['header'])) {
self::sendHeader($data['header']);
}
// clear output buffer
while (ob_get_level() && ob_end_clean()) {
}
$toEnd = true;
$fp = $data['pointer'];
$sendData = !($this->reqMethod === 'HEAD' || !empty($data['info']['xsendfile']));
$psize = null;
if (($this->reqMethod === 'GET' || !$sendData)
&& (elFinder::isSeekableStream($fp) || elFinder::isSeekableUrl($fp))
&& (array_search('Accept-Ranges: none', headers_list()) === false)) {
header('Accept-Ranges: bytes');
if (!empty($_SERVER['HTTP_RANGE'])) {
$size = $data['info']['size'];
$end = $size - 1;
if (preg_match('/bytes=(\d*)-(\d*)(,?)/i', $_SERVER['HTTP_RANGE'], $matches)) {
if (empty($matches[3])) {
if (empty($matches[1]) && $matches[1] !== '0') {
$start = $size - $matches[2];
} else {
$start = intval($matches[1]);
if (!empty($matches[2])) {
$end = intval($matches[2]);
if ($end >= $size) {
$end = $size - 1;
}
$toEnd = ($end == ($size - 1));
}
}
$psize = $end - $start + 1;
header('HTTP/1.1 206 Partial Content');
header('Content-Length: ' . $psize);
header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size);
// Apache mod_xsendfile dose not support range request
if (isset($data['info']['xsendfile']) && strtolower($data['info']['xsendfile']) === 'x-sendfile') {
if (function_exists('header_remove')) {
header_remove($data['info']['xsendfile']);
} else {
header($data['info']['xsendfile'] . ':');
}
unset($data['info']['xsendfile']);
if ($this->reqMethod !== 'HEAD') {
$sendData = true;
}
}
$sendData && !elFinder::isSeekableUrl($fp) && fseek($fp, $start);
}
}
}
if ($sendData && is_null($psize)) {
elFinder::rewind($fp);
}
} else {
header('Accept-Ranges: none');
if (isset($data['info']) && !$data['info']['size']) {
if (function_exists('header_remove')) {
header_remove('Content-Length');
} else {
header('Content-Length:');
}
}
}
if ($sendData) {
if ($toEnd || elFinder::isSeekableUrl($fp)) {
// PHP < 5.6 has a bug of fpassthru
// see https://bugs.php.net/bug.php?id=66736
if (version_compare(PHP_VERSION, '5.6', '<')) {
file_put_contents('php://output', $fp);
} else {
fpassthru($fp);
}
} else {
$out = fopen('php://output', 'wb');
stream_copy_to_stream($fp, $out, $psize);
fclose($out);
}
}
if (!empty($data['volume'])) {
$data['volume']->close($fp, $data['info']['hash']);
} else {
fclose($fp);
}
exit();
} else {
self::outputJson($data);
exit(0);
}
}
/**
* Remove null & stripslashes applies on "magic_quotes_gpc"
*
* @param mixed $args
*
* @return mixed
* @author Naoki Sawada
*/
protected function input_filter($args)
{
static $magic_quotes_gpc = NULL;
if ($magic_quotes_gpc === NULL)
$magic_quotes_gpc = (version_compare(PHP_VERSION, '5.4', '<') && get_magic_quotes_gpc());
if (is_array($args)) {
return array_map(array(& $this, 'input_filter'), $args);
}
$res = str_replace("\0", '', $args);
$magic_quotes_gpc && ($res = stripslashes($res));
return $res;
}
/**
* Send HTTP header
*
* @param string|array $header optional header
*/
protected static function sendHeader($header = null)
{
if ($header) {
if (is_array($header)) {
foreach ($header as $h) {
header($h);
}
} else {
header($header);
}
}
}
/**
* Output JSON
*
* @param array $data
*/
public static function outputJson($data)
{
// send header
$header = isset($data['header']) ? $data['header'] : self::$contentType;
self::sendHeader($header);
unset($data['header']);
if (!empty($data['raw']) && isset($data['error'])) {
$out = $data['error'];
} else {
if (isset($data['debug']) && isset($data['debug']['backendErrors'])) {
$data['debug']['backendErrors'] = array_merge($data['debug']['backendErrors'], elFinder::$phpErrors);
}
$out = json_encode($data);
}
// clear output buffer
while (ob_get_level() && ob_end_clean()) {
}
header('Content-Length: ' . strlen($out));
echo $out;
flush();
}
}// END class
+113
View File
@@ -0,0 +1,113 @@
<?php
/**
* elFinder Plugin Abstract
*
* @package elfinder
* @author Naoki Sawada
* @license New BSD
*/
class elFinderPlugin
{
/**
* This plugin's options
*
* @var array
*/
protected $opts = array();
/**
* Get current volume's options
*
* @param object $volume
*
* @return array options
*/
protected function getCurrentOpts($volume)
{
$name = substr(get_class($this), 14); // remove "elFinderPlugin"
$opts = $this->opts;
if (is_object($volume)) {
$volOpts = $volume->getOptionsPlugin($name);
if (is_array($volOpts)) {
$opts = array_merge($opts, $volOpts);
}
}
return $opts;
}
/**
* Is enabled with options
*
* @param array $opts
* @param elFinder $elfinder
*
* @return boolean
*/
protected function iaEnabled($opts, $elfinder = null)
{
if (!$opts['enable']) {
return false;
}
// check post var 'contentSaveId' to disable this plugin
if ($elfinder && !empty($opts['disableWithContentSaveId'])) {
$session = $elfinder->getSession();
$urlContentSaveIds = $session->get('urlContentSaveIds', array());
if (!empty(elFinder::$currentArgs['contentSaveId']) && ($contentSaveId = elFinder::$currentArgs['contentSaveId'])) {
if (!empty($urlContentSaveIds[$contentSaveId])) {
$elfinder->removeUrlContentSaveId($contentSaveId);
return false;
}
}
}
if (isset($opts['onDropWith']) && !is_null($opts['onDropWith'])) {
// plugin disabled by default, enabled only if given key is pressed
if (isset($_REQUEST['dropWith']) && $_REQUEST['dropWith']) {
$onDropWith = $opts['onDropWith'];
$action = (int)$_REQUEST['dropWith'];
if (!is_array($onDropWith)) {
$onDropWith = array($onDropWith);
}
foreach ($onDropWith as $key) {
$key = (int)$key;
if (($action & $key) === $key) {
return true;
}
}
}
return false;
}
if (isset($opts['offDropWith']) && !is_null($opts['offDropWith']) && isset($_REQUEST['dropWith'])) {
// plugin enabled by default, disabled only if given key is pressed
$offDropWith = $opts['offDropWith'];
$action = (int)$_REQUEST['dropWith'];
if (!is_array($offDropWith)) {
$offDropWith = array($offDropWith);
}
$res = true;
foreach ($offDropWith as $key) {
$key = (int)$key;
if ($key === 0) {
if ($action === 0) {
$res = false;
break;
}
} else {
if (($action & $key) === $key) {
$res = false;
break;
}
}
}
if (!$res) {
return false;
}
}
return true;
}
}
+337
View File
@@ -0,0 +1,337 @@
<?php
/**
* elFinder - file manager for web.
* Session Wrapper Class.
*
* @package elfinder
* @author Naoki Sawada
**/
class elFinderSession implements elFinderSessionInterface
{
/**
* A flag of session started
*
* @var boolean
*/
protected $started = false;
/**
* To fix PHP bug that duplicate Set-Cookie header to be sent
*
* @var boolean
* @see https://bugs.php.net/bug.php?id=75554
*/
protected $fixCookieRegist = false;
/**
* Array of session keys of this instance
*
* @var array
*/
protected $keys = array();
/**
* Is enabled base64encode
*
* @var boolean
*/
protected $base64encode = false;
/**
* Default options array
*
* @var array
*/
protected $opts = array(
'base64encode' => false,
'keys' => array(
'default' => 'elFinderCaches',
'netvolume' => 'elFinderNetVolumes'
),
'cookieParams' => array()
);
/**
* Constractor
*
* @param array $opts The options
*
* @return self Instanse of this class
*/
public function __construct($opts)
{
$this->opts = array_merge($this->opts, $opts);
$this->base64encode = !empty($this->opts['base64encode']);
$this->keys = $this->opts['keys'];
if (function_exists('apache_get_version') || $this->opts['cookieParams']) {
$this->fixCookieRegist = true;
}
return $this;
}
/**
* {@inheritdoc}
*/
public function get($key, $empty = null)
{
$closed = false;
if (!$this->started) {
$closed = true;
$this->start();
}
$data = null;
if ($this->started) {
$session =& $this->getSessionRef($key);
$data = $session;
if ($data && $this->base64encode) {
$data = $this->decodeData($data);
}
}
$checkFn = null;
if (!is_null($empty)) {
if (is_string($empty)) {
$checkFn = 'is_string';
} elseif (is_array($empty)) {
$checkFn = 'is_array';
} elseif (is_object($empty)) {
$checkFn = 'is_object';
} elseif (is_float($empty)) {
$checkFn = 'is_float';
} elseif (is_int($empty)) {
$checkFn = 'is_int';
}
}
if (is_null($data) || ($checkFn && !$checkFn($data))) {
$session = $data = $empty;
}
if ($closed) {
$this->close();
}
return $data;
}
/**
* {@inheritdoc}
*/
public function start()
{
set_error_handler(array($this, 'session_start_error'), E_NOTICE | E_WARNING);
// apache2 SAPI has a bug of session cookie register
// see https://bugs.php.net/bug.php?id=75554
// see https://github.com/php/php-src/pull/3231
if ($this->fixCookieRegist === true) {
if ((int)ini_get('session.use_cookies') === 1) {
if (ini_set('session.use_cookies', 0) === false) {
$this->fixCookieRegist === false;
}
}
}
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
if (session_status() !== PHP_SESSION_ACTIVE) {
session_start();
}
} else {
session_start();
}
$this->started = session_id() ? true : false;
restore_error_handler();
return $this;
}
/**
* Get variable reference of $_SESSION
*
* @param string $key key of $_SESSION array
*
* @return mixed|null
*/
protected function & getSessionRef($key)
{
$session = null;
if ($this->started) {
list($cat, $name) = array_pad(explode('.', $key, 2), 2, null);
if (is_null($name)) {
if (!isset($this->keys[$cat])) {
$name = $cat;
$cat = 'default';
}
}
if (isset($this->keys[$cat])) {
$cat = $this->keys[$cat];
} else {
$name = $cat . '.' . $name;
$cat = $this->keys['default'];
}
if (is_null($name)) {
if (!isset($_SESSION[$cat])) {
$_SESSION[$cat] = null;
}
$session =& $_SESSION[$cat];
} else {
if (!isset($_SESSION[$cat]) || !is_array($_SESSION[$cat])) {
$_SESSION[$cat] = array();
}
if (!isset($_SESSION[$cat][$name])) {
$_SESSION[$cat][$name] = null;
}
$session =& $_SESSION[$cat][$name];
}
}
return $session;
}
/**
* base64 decode of session val
*
* @param $data
*
* @return bool|mixed|string|null
*/
protected function decodeData($data)
{
if ($this->base64encode) {
if (is_string($data)) {
if (($data = base64_decode($data)) !== false) {
$data = unserialize($data);
} else {
$data = null;
}
} else {
$data = null;
}
}
return $data;
}
/**
* {@inheritdoc}
*/
public function close()
{
if ($this->started) {
if ($this->fixCookieRegist === true) {
// regist cookie only once for apache2 SAPI
$cParm = session_get_cookie_params();
if ($this->opts['cookieParams'] && is_array($this->opts['cookieParams'])) {
$cParm = array_merge($cParm, $this->opts['cookieParams']);
}
if (version_compare(PHP_VERSION, '7.3', '<')) {
setcookie(session_name(), session_id(), 0, $cParm['path'] . (!empty($cParm['SameSite'])? '; SameSite=' . $cParm['SameSite'] : ''), $cParm['domain'], $cParm['secure'], $cParm['httponly']);
} else {
$allows = array('expires' => true, 'path' => true, 'domain' => true, 'secure' => true, 'httponly' => true, 'samesite' => true);
foreach(array_keys($cParm) as $_k) {
if (!isset($allows[$_k])) {
unset($cParm[$_k]);
}
}
setcookie(session_name(), session_id(), $cParm);
}
$this->fixCookieRegist = false;
}
session_write_close();
}
$this->started = false;
return $this;
}
/**
* {@inheritdoc}
*/
public function set($key, $data)
{
$closed = false;
if (!$this->started) {
$closed = true;
$this->start();
}
$session =& $this->getSessionRef($key);
if ($this->base64encode) {
$data = $this->encodeData($data);
}
$session = $data;
if ($closed) {
$this->close();
}
return $this;
}
/**
* base64 encode for session val
*
* @param $data
*
* @return string
*/
protected function encodeData($data)
{
if ($this->base64encode) {
$data = base64_encode(serialize($data));
}
return $data;
}
/**
* {@inheritdoc}
*/
public function remove($key)
{
$closed = false;
if (!$this->started) {
$closed = true;
$this->start();
}
list($cat, $name) = array_pad(explode('.', $key, 2), 2, null);
if (is_null($name)) {
if (!isset($this->keys[$cat])) {
$name = $cat;
$cat = 'default';
}
}
if (isset($this->keys[$cat])) {
$cat = $this->keys[$cat];
} else {
$name = $cat . '.' . $name;
$cat = $this->keys['default'];
}
if (is_null($name)) {
unset($_SESSION[$cat]);
} else {
if (isset($_SESSION[$cat]) && is_array($_SESSION[$cat])) {
unset($_SESSION[$cat][$name]);
}
}
if ($closed) {
$this->close();
}
return $this;
}
/**
* sessioin error handler (Only for suppression of error at session start)
*
* @param $errno
* @param $errstr
*/
protected function session_start_error($errno, $errstr)
{
}
}
@@ -0,0 +1,57 @@
<?php
/**
* elFinder - file manager for web.
* Session Wrapper Interface.
*
* @package elfinder
* @author Naoki Sawada
**/
interface elFinderSessionInterface
{
/**
* Session start
*
* @return self
**/
public function start();
/**
* Session write & close
*
* @return self
**/
public function close();
/**
* Get session data
* This method must be equipped with an automatic start / close.
*
* @param string $key Target key
* @param mixed $empty Return value of if session target key does not exist
*
* @return mixed
**/
public function get($key, $empty = '');
/**
* Set session data
* This method must be equipped with an automatic start / close.
*
* @param string $key Target key
* @param mixed $data Value
*
* @return self
**/
public function set($key, $data);
/**
* Get session data
*
* @param string $key Target key
*
* @return self
**/
public function remove($key);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,315 @@
<?php
/**
* elFinder driver for Volume Group.
*
* @author Naoki Sawada
**/
class elFinderVolumeGroup extends elFinderVolumeDriver
{
/**
* Driver id
* Must be started from letter and contains [a-z0-9]
* Used as part of volume id
*
* @var string
**/
protected $driverId = 'g';
/**
* Constructor
* Extend options with required fields
*/
public function __construct()
{
$this->options['type'] = 'group';
$this->options['path'] = '/';
$this->options['dirUrlOwn'] = true;
$this->options['syncMinMs'] = 0;
$this->options['tmbPath'] = '';
$this->options['disabled'] = array(
'archive',
'copy',
'cut',
'duplicate',
'edit',
'empty',
'extract',
'getfile',
'mkdir',
'mkfile',
'paste',
'resize',
'rm',
'upload'
);
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/*********************** paths/urls *************************/
/**
* @inheritdoc
**/
protected function _dirname($path)
{
return '/';
}
/**
* {@inheritDoc}
**/
protected function _basename($path)
{
return '';
}
/**
* {@inheritDoc}
**/
protected function _joinPath($dir, $name)
{
return '/' . $name;
}
/**
* {@inheritDoc}
**/
protected function _normpath($path)
{
return '/';
}
/**
* {@inheritDoc}
**/
protected function _relpath($path)
{
return '/';
}
/**
* {@inheritDoc}
**/
protected function _abspath($path)
{
return '/';
}
/**
* {@inheritDoc}
**/
protected function _path($path)
{
return '/';
}
/**
* {@inheritDoc}
**/
protected function _inpath($path, $parent)
{
return false;
}
/***************** file stat ********************/
/**
* {@inheritDoc}
**/
protected function _stat($path)
{
if ($path === '/') {
return array(
'size' => 0,
'ts' => 0,
'mime' => 'directory',
'read' => true,
'write' => false,
'locked' => true,
'hidden' => false,
'dirs' => 0
);
}
return false;
}
/**
* {@inheritDoc}
**/
protected function _subdirs($path)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _dimensions($path, $mime)
{
return false;
}
/******************** file/dir content *********************/
/**
* {@inheritDoc}
**/
protected function readlink($path)
{
return null;
}
/**
* {@inheritDoc}
**/
protected function _scandir($path)
{
return array();
}
/**
* {@inheritDoc}
**/
protected function _fopen($path, $mode = 'rb')
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _fclose($fp, $path = '')
{
return true;
}
/******************** file/dir manipulations *************************/
/**
* {@inheritDoc}
**/
protected function _mkdir($path, $name)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _mkfile($path, $name)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _symlink($source, $targetDir, $name)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _copy($source, $targetDir, $name)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _move($source, $targetDir, $name)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _unlink($path)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _rmdir($path)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _save($fp, $dir, $name, $stat)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _getContents($path)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _filePutContents($path, $content)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _checkArchivers()
{
return;
}
/**
* {@inheritDoc}
**/
protected function _chmod($path, $mode)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _findSymlinks($path)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _extract($path, $arc)
{
return false;
}
/**
* {@inheritDoc}
**/
protected function _archive($dir, $files, $name, $arc)
{
return false;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,51 @@
<?php
/**
* elFinder driver for trash bin at local filesystem.
*
* @author NaokiSawada
**/
class elFinderVolumeTrash extends elFinderVolumeLocalFileSystem
{
/**
* Driver id
* Must be started from letter and contains [a-z0-9]
* Used as part of volume id.
*
* @var string
**/
protected $driverId = 't';
public function __construct()
{
parent::__construct();
// original option of the Trash
$this->options['lockEverything'] = false; // Lock all items in the trash to disable delete, move, rename.
// common options as the volume driver
$this->options['alias'] = 'Trash';
$this->options['quarantine'] = '';
$this->options['rootCssClass'] = 'elfinder-navbar-root-trash';
$this->options['copyOverwrite'] = false;
$this->options['uiCmdMap'] = array('paste' => 'hidden', 'mkdir' => 'hidden', 'copy' => 'restore');
$this->options['disabled'] = array('archive', 'duplicate', 'edit', 'extract', 'mkfile', 'places', 'put', 'rename', 'resize', 'upload');
}
public function mount(array $opts)
{
if ($this->options['lockEverything']) {
if (!is_array($opts['attributes'])) {
$opts['attributes'] = array();
}
$attr = array(
'pattern' => '/./',
'locked' => true,
);
array_unshift($opts['attributes'], $attr);
}
// force set `copyJoin` to true
$opts['copyJoin'] = true;
return parent::mount($opts);
}
}
+473
View File
@@ -0,0 +1,473 @@
<?php
/**
* Copyright (c) 2011, oov. All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the oov nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* bmp ファイルを GD で使えるように
* 使用例:
* //ファイルから読み込む場合はGDでPNGなどを読み込むのと同じような方法で可
* $image = imagecreatefrombmp("test.bmp");
* imagedestroy($image);
* //文字列から読み込む場合は以下の方法で可
* $image = GdBmp::loadFromString(file_get_contents("test.bmp"));
* //自動判定されるので破損ファイルでなければこれでも上手くいく
* //$image = imagecreatefrombmp(file_get_contents("test.bmp"));
* imagedestroy($image);
* //その他任意のストリームからの読み込みも可能
* $stream = fopen("http://127.0.0.1/test.bmp");
* $image = GdBmp::loadFromStream($stream);
* //自動判定されるのでこれでもいい
* //$image = imagecreatefrombmp($stream);
* fclose($stream);
* imagedestroy($image);
* 対応フォーマット
* 1bit
* 4bit
* 4bitRLE
* 8bit
* 8bitRLE
* 16bit(任意のビットフィールド)
* 24bit
* 32bit(任意のビットフィールド)
* BITMAPINFOHEADER の biCompression が BI_PNG / BI_JPEG の画像
* すべての形式でトップダウン/ボトムアップの両方をサポート
* 特殊なビットフィールドでもビットフィールドデータが正常なら読み込み可能
* 以下のものは非対応
* BITMAPV4HEADER と BITMAPV5HEADER に含まれる色空間に関する様々な機能
*
* @param $filename_or_stream_or_binary
*
* @return bool|resource
*/
if (!function_exists('imagecreatefrombmp')) {
function imagecreatefrombmp($filename_or_stream_or_binary)
{
return elFinderLibGdBmp::load($filename_or_stream_or_binary);
}
}
class elFinderLibGdBmp
{
public static function load($filename_or_stream_or_binary)
{
if (is_resource($filename_or_stream_or_binary)) {
return self::loadFromStream($filename_or_stream_or_binary);
} else if (is_string($filename_or_stream_or_binary) && strlen($filename_or_stream_or_binary) >= 26) {
$bfh = unpack("vtype/Vsize", $filename_or_stream_or_binary);
if ($bfh["type"] == 0x4d42 && ($bfh["size"] == 0 || $bfh["size"] == strlen($filename_or_stream_or_binary))) {
return self::loadFromString($filename_or_stream_or_binary);
}
}
return self::loadFromFile($filename_or_stream_or_binary);
}
public static function loadFromFile($filename)
{
$fp = fopen($filename, "rb");
if ($fp === false) {
return false;
}
$bmp = self::loadFromStream($fp);
fclose($fp);
return $bmp;
}
public static function loadFromString($str)
{
//data scheme より古いバージョンから対応しているようなので php://memory を使う
$fp = fopen("php://memory", "r+b");
if ($fp === false) {
return false;
}
if (fwrite($fp, $str) != strlen($str)) {
fclose($fp);
return false;
}
if (fseek($fp, 0) === -1) {
fclose($fp);
return false;
}
$bmp = self::loadFromStream($fp);
fclose($fp);
return $bmp;
}
public static function loadFromStream($stream)
{
$buf = fread($stream, 14); //2+4+2+2+4
if ($buf === false) {
return false;
}
//シグネチャチェック
if ($buf[0] != 'B' || $buf[1] != 'M') {
return false;
}
$bitmap_file_header = unpack(
//BITMAPFILEHEADER構造体
"vtype/" .
"Vsize/" .
"vreserved1/" .
"vreserved2/" .
"Voffbits", $buf
);
return self::loadFromStreamAndFileHeader($stream, $bitmap_file_header);
}
public static function loadFromStreamAndFileHeader($stream, array $bitmap_file_header)
{
if ($bitmap_file_header["type"] != 0x4d42) {
return false;
}
//情報ヘッダサイズを元に形式を区別して読み込み
$buf = fread($stream, 4);
if ($buf === false) {
return false;
}
list(, $header_size) = unpack("V", $buf);
if ($header_size == 12) {
$buf = fread($stream, $header_size - 4);
if ($buf === false) {
return false;
}
extract(unpack(
//BITMAPCOREHEADER構造体 - OS/2 Bitmap
"vwidth/" .
"vheight/" .
"vplanes/" .
"vbit_count", $buf
));
//飛んでこない分は 0 で初期化しておく
$clr_used = $clr_important = $alpha_mask = $compression = 0;
//マスク類は初期化されないのでここで割り当てておく
$red_mask = 0x00ff0000;
$green_mask = 0x0000ff00;
$blue_mask = 0x000000ff;
} else if (124 < $header_size || $header_size < 40) {
//未知の形式
return false;
} else {
//この時点で36バイト読めることまではわかっている
$buf = fread($stream, 36); //既に読んだ部分は除外しつつBITMAPINFOHEADERのサイズだけ読む
if ($buf === false) {
return false;
}
//BITMAPINFOHEADER構造体 - Windows Bitmap
extract(unpack(
"Vwidth/" .
"Vheight/" .
"vplanes/" .
"vbit_count/" .
"Vcompression/" .
"Vsize_image/" .
"Vx_pels_per_meter/" .
"Vy_pels_per_meter/" .
"Vclr_used/" .
"Vclr_important", $buf
));
/**
* @var integer $width
* @var integer $height
* @var integer $planes
* @var integer $bit_count
* @var integer $compression
* @var integer $size_image
* @var integer $x_pels_per_meter
* @var integer $y_pels_per_meter
* @var integer $clr_used
* @var integer $clr_important
*/
//負の整数を受け取る可能性があるものは自前で変換する
if ($width & 0x80000000) {
$width = -(~$width & 0xffffffff) - 1;
}
if ($height & 0x80000000) {
$height = -(~$height & 0xffffffff) - 1;
}
if ($x_pels_per_meter & 0x80000000) {
$x_pels_per_meter = -(~$x_pels_per_meter & 0xffffffff) - 1;
}
if ($y_pels_per_meter & 0x80000000) {
$y_pels_per_meter = -(~$y_pels_per_meter & 0xffffffff) - 1;
}
//ファイルによっては BITMAPINFOHEADER のサイズがおかしい(書き込み間違い?)ケースがある
//自分でファイルサイズを元に逆算することで回避できることもあるので再計算できそうなら正当性を調べる
//シークできないストリームの場合全体のファイルサイズは取得できないので、$bitmap_file_headerにサイズ申告がなければやらない
if ($bitmap_file_header["size"] != 0) {
$colorsize = $bit_count == 1 || $bit_count == 4 || $bit_count == 8 ? ($clr_used ? $clr_used : pow(2, $bit_count)) << 2 : 0;
$bodysize = $size_image ? $size_image : ((($width * $bit_count + 31) >> 3) & ~3) * abs($height);
$calcsize = $bitmap_file_header["size"] - $bodysize - $colorsize - 14;
//本来であれば一致するはずなのに合わない時は、値がおかしくなさそうなら(BITMAPV5HEADERの範囲内なら)計算して求めた値を採用する
if ($header_size < $calcsize && 40 <= $header_size && $header_size <= 124) {
$header_size = $calcsize;
}
}
//BITMAPV4HEADER や BITMAPV5HEADER の場合まだ読むべきデータが残っている可能性がある
if ($header_size - 40 > 0) {
$buf = fread($stream, $header_size - 40);
if ($buf === false) {
return false;
}
extract(unpack(
//BITMAPV4HEADER構造体(Windows95以降)
//BITMAPV5HEADER構造体(Windows98/2000以降)
"Vred_mask/" .
"Vgreen_mask/" .
"Vblue_mask/" .
"Valpha_mask", $buf . str_repeat("\x00", 120)
));
} else {
$alpha_mask = $red_mask = $green_mask = $blue_mask = 0;
}
//パレットがないがカラーマスクもない時
if (
($bit_count == 16 || $bit_count == 24 || $bit_count == 32) &&
$compression == 0 &&
$red_mask == 0 && $green_mask == 0 && $blue_mask == 0
) {
//もしカラーマスクを所持していない場合は
//規定のカラーマスクを適用する
switch ($bit_count) {
case 16:
$red_mask = 0x7c00;
$green_mask = 0x03e0;
$blue_mask = 0x001f;
break;
case 24:
case 32:
$red_mask = 0x00ff0000;
$green_mask = 0x0000ff00;
$blue_mask = 0x000000ff;
break;
}
}
}
if (
($width == 0) ||
($height == 0) ||
($planes != 1) ||
(($alpha_mask & $red_mask) != 0) ||
(($alpha_mask & $green_mask) != 0) ||
(($alpha_mask & $blue_mask) != 0) ||
(($red_mask & $green_mask) != 0) ||
(($red_mask & $blue_mask) != 0) ||
(($green_mask & $blue_mask) != 0)
) {
//不正な画像
return false;
}
//BI_JPEG と BI_PNG の場合は jpeg/png がそのまま入ってるだけなのでそのまま取り出してデコードする
if ($compression == 4 || $compression == 5) {
$buf = stream_get_contents($stream, $size_image);
if ($buf === false) {
return false;
}
return imagecreatefromstring($buf);
}
//画像本体の読み出し
//1行のバイト数
$line_bytes = (($width * $bit_count + 31) >> 3) & ~3;
//全体の行数
$lines = abs($height);
//y軸進行量(ボトムアップかトップダウンか)
$y = $height > 0 ? $lines - 1 : 0;
$line_step = $height > 0 ? -1 : 1;
//256色以下の画像か?
if ($bit_count == 1 || $bit_count == 4 || $bit_count == 8) {
$img = imagecreate($width, $lines);
//画像データの前にパレットデータがあるのでパレットを作成する
$palette_size = $header_size == 12 ? 3 : 4; //OS/2形式の場合は x に相当する箇所のデータは最初から確保されていない
$colors = $clr_used ? $clr_used : pow(2, $bit_count); //色数
$palette = array();
for ($i = 0; $i < $colors; ++$i) {
$buf = fread($stream, $palette_size);
if ($buf === false) {
imagedestroy($img);
return false;
}
extract(unpack("Cb/Cg/Cr/Cx", $buf . "\x00"));
/**
* @var integer $b
* @var integer $g
* @var integer $r
* @var integer $x
*/
$palette[] = imagecolorallocate($img, $r, $g, $b);
}
$shift_base = 8 - $bit_count;
$mask = ((1 << $bit_count) - 1) << $shift_base;
//圧縮されている場合とされていない場合でデコード処理が大きく変わる
if ($compression == 1 || $compression == 2) {
$x = 0;
$qrt_mod2 = $bit_count >> 2 & 1;
for (; ;) {
//もし描写先が範囲外になっている場合デコード処理がおかしくなっているので抜ける
//変なデータが渡されたとしても最悪なケースで255回程度の無駄なので目を瞑る
if ($x < -1 || $x > $width || $y < -1 || $y > $height) {
imagedestroy($img);
return false;
}
$buf = fread($stream, 1);
if ($buf === false) {
imagedestroy($img);
return false;
}
switch ($buf) {
case "\x00":
$buf = fread($stream, 1);
if ($buf === false) {
imagedestroy($img);
return false;
}
switch ($buf) {
case "\x00": //EOL
$y += $line_step;
$x = 0;
break;
case "\x01": //EOB
$y = 0;
$x = 0;
break 3;
case "\x02": //MOV
$buf = fread($stream, 2);
if ($buf === false) {
imagedestroy($img);
return false;
}
list(, $xx, $yy) = unpack("C2", $buf);
$x += $xx;
$y += $yy * $line_step;
break;
default: //ABS
list(, $pixels) = unpack("C", $buf);
$bytes = ($pixels >> $qrt_mod2) + ($pixels & $qrt_mod2);
$buf = fread($stream, ($bytes + 1) & ~1);
if ($buf === false) {
imagedestroy($img);
return false;
}
for ($i = 0, $pos = 0; $i < $pixels; ++$i, ++$x, $pos += $bit_count) {
list(, $c) = unpack("C", $buf[$pos >> 3]);
$b = $pos & 0x07;
imagesetpixel($img, $x, $y, $palette[($c & ($mask >> $b)) >> ($shift_base - $b)]);
}
break;
}
break;
default:
$buf2 = fread($stream, 1);
if ($buf2 === false) {
imagedestroy($img);
return false;
}
list(, $size, $c) = unpack("C2", $buf . $buf2);
for ($i = 0, $pos = 0; $i < $size; ++$i, ++$x, $pos += $bit_count) {
$b = $pos & 0x07;
imagesetpixel($img, $x, $y, $palette[($c & ($mask >> $b)) >> ($shift_base - $b)]);
}
break;
}
}
} else {
for ($line = 0; $line < $lines; ++$line, $y += $line_step) {
$buf = fread($stream, $line_bytes);
if ($buf === false) {
imagedestroy($img);
return false;
}
$pos = 0;
for ($x = 0; $x < $width; ++$x, $pos += $bit_count) {
list(, $c) = unpack("C", $buf[$pos >> 3]);
$b = $pos & 0x7;
imagesetpixel($img, $x, $y, $palette[($c & ($mask >> $b)) >> ($shift_base - $b)]);
}
}
}
} else {
$img = imagecreatetruecolor($width, $lines);
imagealphablending($img, false);
if ($alpha_mask) {
//αデータがあるので透過情報も保存できるように
imagesavealpha($img, true);
}
//x軸進行量
$pixel_step = $bit_count >> 3;
$alpha_max = $alpha_mask ? 0x7f : 0x00;
$alpha_mask_r = $alpha_mask ? 1 / $alpha_mask : 1;
$red_mask_r = $red_mask ? 1 / $red_mask : 1;
$green_mask_r = $green_mask ? 1 / $green_mask : 1;
$blue_mask_r = $blue_mask ? 1 / $blue_mask : 1;
for ($line = 0; $line < $lines; ++$line, $y += $line_step) {
$buf = fread($stream, $line_bytes);
if ($buf === false) {
imagedestroy($img);
return false;
}
$pos = 0;
for ($x = 0; $x < $width; ++$x, $pos += $pixel_step) {
list(, $c) = unpack("V", substr($buf, $pos, $pixel_step) . "\x00\x00");
$a_masked = $c & $alpha_mask;
$r_masked = $c & $red_mask;
$g_masked = $c & $green_mask;
$b_masked = $c & $blue_mask;
$a = $alpha_max - ((($a_masked << 7) - $a_masked) * $alpha_mask_r);
$r = (($r_masked << 8) - $r_masked) * $red_mask_r;
$g = (($g_masked << 8) - $g_masked) * $green_mask_r;
$b = (($b_masked << 8) - $b_masked) * $blue_mask_r;
imagesetpixel($img, $x, $y, ($a << 24) | ($r << 16) | ($g << 8) | $b);
}
}
imagealphablending($img, true); //デフォルト値に戻しておく
}
return $img;
}
}
+781
View File
@@ -0,0 +1,781 @@
# This file maps Internet media types to unique file extension(s).
# Although created for httpd, this file is used by many software systems
# and has been placed in the public domain for unlimited redisribution.
#
# The table below contains both registered and (common) unregistered types.
# A type that has no unique extension can be ignored -- they are listed
# here to guide configurations toward known types and to make it easier to
# identify "new" types. File extensions are also commonly used to indicate
# content languages and encodings, so choose them carefully.
#
# Internet media types should be registered as described in RFC 4288.
# The registry is at <http://www.iana.org/assignments/media-types/>.
#
# MIME type (lowercased) Extensions
application/andrew-inset ez
application/applixware aw
application/atom+xml atom
application/atomcat+xml atomcat
application/atomsvc+xml atomsvc
application/ccxml+xml ccxml
application/cdmi-capability cdmia
application/cdmi-container cdmic
application/cdmi-domain cdmid
application/cdmi-object cdmio
application/cdmi-queue cdmiq
application/cu-seeme cu
application/davmount+xml davmount
application/docbook+xml dbk
application/dssc+der dssc
application/dssc+xml xdssc
application/ecmascript ecma
application/emma+xml emma
application/epub+zip epub
application/exi exi
application/font-tdpfr pfr
application/gml+xml gml
application/gpx+xml gpx
application/gxf gxf
application/hyperstudio stk
application/inkml+xml ink inkml
application/ipfix ipfix
application/java-archive jar
application/java-serialized-object ser
application/java-vm class
application/javascript js
application/json json
application/jsonml+json jsonml
application/lost+xml lostxml
application/mac-binhex40 hqx
application/mac-compactpro cpt
application/mads+xml mads
application/marc mrc
application/marcxml+xml mrcx
application/mathematica ma nb mb
application/mathml+xml mathml
application/mbox mbox
application/mediaservercontrol+xml mscml
application/metalink+xml metalink
application/metalink4+xml meta4
application/mets+xml mets
application/mods+xml mods
application/mp21 m21 mp21
application/mp4 mp4s
application/msword doc dot
application/mxf mxf
application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy
application/oda oda
application/oebps-package+xml opf
application/ogg ogx
application/omdoc+xml omdoc
application/onenote onetoc onetoc2 onetmp onepkg
application/oxps oxps
application/patch-ops-error+xml xer
application/pdf pdf
application/pgp-encrypted pgp
application/pgp-signature asc sig
application/pics-rules prf
application/pkcs10 p10
application/pkcs7-mime p7m p7c
application/pkcs7-signature p7s
application/pkcs8 p8
application/pkix-attr-cert ac
application/pkix-cert cer
application/pkix-crl crl
application/pkix-pkipath pkipath
application/pkixcmp pki
application/pls+xml pls
application/postscript ai eps ps
application/prs.cww cww
application/pskc+xml pskcxml
application/rdf+xml rdf
application/reginfo+xml rif
application/relax-ng-compact-syntax rnc
application/resource-lists+xml rl
application/resource-lists-diff+xml rld
application/rls-services+xml rs
application/rpki-ghostbusters gbr
application/rpki-manifest mft
application/rpki-roa roa
application/rsd+xml rsd
application/rss+xml rss
application/rtf rtf
application/sbml+xml sbml
application/scvp-cv-request scq
application/scvp-cv-response scs
application/scvp-vp-request spq
application/scvp-vp-response spp
application/sdp sdp
application/set-payment-initiation setpay
application/set-registration-initiation setreg
application/shf+xml shf
application/smil+xml smi smil
application/sparql-query rq
application/sparql-results+xml srx
application/srgs gram
application/srgs+xml grxml
application/sru+xml sru
application/ssdl+xml ssdl
application/ssml+xml ssml
application/tei+xml tei teicorpus
application/thraud+xml tfi
application/timestamped-data tsd
application/vnd.3gpp.pic-bw-large plb
application/vnd.3gpp.pic-bw-small psb
application/vnd.3gpp.pic-bw-var pvb
application/vnd.3gpp2.tcap tcap
application/vnd.3m.post-it-notes pwn
application/vnd.accpac.simply.aso aso
application/vnd.accpac.simply.imp imp
application/vnd.acucobol acu
application/vnd.acucorp atc acutc
application/vnd.adobe.air-application-installer-package+zip air
application/vnd.adobe.formscentral.fcdt fcdt
application/vnd.adobe.fxp fxp fxpl
application/vnd.adobe.xdp+xml xdp
application/vnd.adobe.xfdf xfdf
application/vnd.ahead.space ahead
application/vnd.airzip.filesecure.azf azf
application/vnd.airzip.filesecure.azs azs
application/vnd.amazon.ebook azw
application/vnd.americandynamics.acc acc
application/vnd.amiga.ami ami
application/vnd.android.package-archive apk
application/vnd.anser-web-certificate-issue-initiation cii
application/vnd.anser-web-funds-transfer-initiation fti
application/vnd.antix.game-component atx
application/vnd.apple.installer+xml mpkg
application/vnd.apple.mpegurl m3u8
application/vnd.aristanetworks.swi swi
application/vnd.astraea-software.iota iota
application/vnd.audiograph aep
application/vnd.blueice.multipass mpm
application/vnd.bmi bmi
application/vnd.businessobjects rep
application/vnd.chemdraw+xml cdxml
application/vnd.chipnuts.karaoke-mmd mmd
application/vnd.cinderella cdy
application/vnd.claymore cla
application/vnd.cloanto.rp9 rp9
application/vnd.clonk.c4group c4g c4d c4f c4p c4u
application/vnd.cluetrust.cartomobile-config c11amc
application/vnd.cluetrust.cartomobile-config-pkg c11amz
application/vnd.commonspace csp
application/vnd.contact.cmsg cdbcmsg
application/vnd.cosmocaller cmc
application/vnd.crick.clicker clkx
application/vnd.crick.clicker.keyboard clkk
application/vnd.crick.clicker.palette clkp
application/vnd.crick.clicker.template clkt
application/vnd.crick.clicker.wordbank clkw
application/vnd.criticaltools.wbs+xml wbs
application/vnd.ctc-posml pml
application/vnd.cups-ppd ppd
application/vnd.curl.car car
application/vnd.curl.pcurl pcurl
application/vnd.dart dart
application/vnd.data-vision.rdz rdz
application/vnd.dece.data uvf uvvf uvd uvvd
application/vnd.dece.ttml+xml uvt uvvt
application/vnd.dece.unspecified uvx uvvx
application/vnd.dece.zip uvz uvvz
application/vnd.denovo.fcselayout-link fe_launch
application/vnd.dna dna
application/vnd.dolby.mlp mlp
application/vnd.dpgraph dpg
application/vnd.dreamfactory dfac
application/vnd.ds-keypoint kpxx
application/vnd.dvb.ait ait
application/vnd.dvb.service svc
application/vnd.dynageo geo
application/vnd.ecowin.chart mag
application/vnd.enliven nml
application/vnd.epson.esf esf
application/vnd.epson.msf msf
application/vnd.epson.quickanime qam
application/vnd.epson.salt slt
application/vnd.epson.ssf ssf
application/vnd.eszigno3+xml es3 et3
application/vnd.ezpix-album ez2
application/vnd.ezpix-package ez3
application/vnd.fdf fdf
application/vnd.fdsn.mseed mseed
application/vnd.fdsn.seed seed dataless
application/vnd.flographit gph
application/vnd.fluxtime.clip ftc
application/vnd.framemaker fm frame maker book
application/vnd.frogans.fnc fnc
application/vnd.frogans.ltf ltf
application/vnd.fsc.weblaunch fsc
application/vnd.fujitsu.oasys oas
application/vnd.fujitsu.oasys2 oa2
application/vnd.fujitsu.oasys3 oa3
application/vnd.fujitsu.oasysgp fg5
application/vnd.fujitsu.oasysprs bh2
application/vnd.fujixerox.ddd ddd
application/vnd.fujixerox.docuworks xdw
application/vnd.fujixerox.docuworks.binder xbd
application/vnd.fuzzysheet fzs
application/vnd.genomatix.tuxedo txd
application/vnd.geogebra.file ggb
application/vnd.geogebra.tool ggt
application/vnd.geometry-explorer gex gre
application/vnd.geonext gxt
application/vnd.geoplan g2w
application/vnd.geospace g3w
application/vnd.gmx gmx
application/vnd.google-earth.kml+xml kml
application/vnd.google-earth.kmz kmz
application/vnd.grafeq gqf gqs
application/vnd.groove-account gac
application/vnd.groove-help ghf
application/vnd.groove-identity-message gim
application/vnd.groove-injector grv
application/vnd.groove-tool-message gtm
application/vnd.groove-tool-template tpl
application/vnd.groove-vcard vcg
application/vnd.hal+xml hal
application/vnd.handheld-entertainment+xml zmm
application/vnd.hbci hbci
application/vnd.hhe.lesson-player les
application/vnd.hp-hpgl hpgl
application/vnd.hp-hpid hpid
application/vnd.hp-hps hps
application/vnd.hp-jlyt jlt
application/vnd.hp-pcl pcl
application/vnd.hp-pclxl pclxl
application/vnd.hydrostatix.sof-data sfd-hdstx
application/vnd.ibm.minipay mpy
application/vnd.ibm.modcap afp listafp list3820
application/vnd.ibm.rights-management irm
application/vnd.ibm.secure-container sc
application/vnd.iccprofile icc icm
application/vnd.igloader igl
application/vnd.immervision-ivp ivp
application/vnd.immervision-ivu ivu
application/vnd.insors.igm igm
application/vnd.intercon.formnet xpw xpx
application/vnd.intergeo i2g
application/vnd.intu.qbo qbo
application/vnd.intu.qfx qfx
application/vnd.ipunplugged.rcprofile rcprofile
application/vnd.irepository.package+xml irp
application/vnd.is-xpr xpr
application/vnd.isac.fcs fcs
application/vnd.jam jam
application/vnd.jcp.javame.midlet-rms rms
application/vnd.jisp jisp
application/vnd.joost.joda-archive joda
application/vnd.kahootz ktz ktr
application/vnd.kde.karbon karbon
application/vnd.kde.kchart chrt
application/vnd.kde.kformula kfo
application/vnd.kde.kivio flw
application/vnd.kde.kontour kon
application/vnd.kde.kpresenter kpr kpt
application/vnd.kde.kspread ksp
application/vnd.kde.kword kwd kwt
application/vnd.kenameaapp htke
application/vnd.kidspiration kia
application/vnd.kinar kne knp
application/vnd.koan skp skd skt skm
application/vnd.kodak-descriptor sse
application/vnd.las.las+xml lasxml
application/vnd.llamagraphics.life-balance.desktop lbd
application/vnd.llamagraphics.life-balance.exchange+xml lbe
application/vnd.lotus-1-2-3 123
application/vnd.lotus-approach apr
application/vnd.lotus-freelance pre
application/vnd.lotus-notes nsf
application/vnd.lotus-organizer org
application/vnd.lotus-screencam scm
application/vnd.lotus-wordpro lwp
application/vnd.macports.portpkg portpkg
application/vnd.mcd mcd
application/vnd.medcalcdata mc1
application/vnd.mediastation.cdkey cdkey
application/vnd.mfer mwf
application/vnd.mfmp mfm
application/vnd.micrografx.flo flo
application/vnd.micrografx.igx igx
application/vnd.mif mif
application/vnd.mobius.daf daf
application/vnd.mobius.dis dis
application/vnd.mobius.mbk mbk
application/vnd.mobius.mqy mqy
application/vnd.mobius.msl msl
application/vnd.mobius.plc plc
application/vnd.mobius.txf txf
application/vnd.mophun.application mpn
application/vnd.mophun.certificate mpc
application/vnd.mozilla.xul+xml xul
application/vnd.ms-artgalry cil
application/vnd.ms-cab-compressed cab
application/vnd.ms-excel xls xlm xla xlc xlt xlw
application/vnd.ms-excel.addin.macroenabled.12 xlam
application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb
application/vnd.ms-excel.sheet.macroenabled.12 xlsm
application/vnd.ms-excel.template.macroenabled.12 xltm
application/vnd.ms-fontobject eot
application/vnd.ms-htmlhelp chm
application/vnd.ms-ims ims
application/vnd.ms-lrm lrm
application/vnd.ms-officetheme thmx
application/vnd.ms-pki.seccat cat
application/vnd.ms-pki.stl stl
application/vnd.ms-powerpoint ppt pps pot
application/vnd.ms-powerpoint.addin.macroenabled.12 ppam
application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm
application/vnd.ms-powerpoint.slide.macroenabled.12 sldm
application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm
application/vnd.ms-powerpoint.template.macroenabled.12 potm
application/vnd.ms-project mpp mpt
application/vnd.ms-word.document.macroenabled.12 docm
application/vnd.ms-word.template.macroenabled.12 dotm
application/vnd.ms-works wps wks wcm wdb
application/vnd.ms-wpl wpl
application/vnd.ms-xpsdocument xps
application/vnd.mseq mseq
application/vnd.musician mus
application/vnd.muvee.style msty
application/vnd.mynfc taglet
application/vnd.neurolanguage.nlu nlu
application/vnd.nitf ntf nitf
application/vnd.noblenet-directory nnd
application/vnd.noblenet-sealer nns
application/vnd.noblenet-web nnw
application/vnd.nokia.n-gage.data ngdat
application/vnd.nokia.n-gage.symbian.install n-gage
application/vnd.nokia.radio-preset rpst
application/vnd.nokia.radio-presets rpss
application/vnd.novadigm.edm edm
application/vnd.novadigm.edx edx
application/vnd.novadigm.ext ext
application/vnd.oasis.opendocument.chart odc
application/vnd.oasis.opendocument.chart-template otc
application/vnd.oasis.opendocument.database odb
application/vnd.oasis.opendocument.formula odf
application/vnd.oasis.opendocument.formula-template odft
application/vnd.oasis.opendocument.graphics odg
application/vnd.oasis.opendocument.graphics-template otg
application/vnd.oasis.opendocument.image odi
application/vnd.oasis.opendocument.image-template oti
application/vnd.oasis.opendocument.presentation odp
application/vnd.oasis.opendocument.presentation-template otp
application/vnd.oasis.opendocument.spreadsheet ods
application/vnd.oasis.opendocument.spreadsheet-template ots
application/vnd.oasis.opendocument.text odt
application/vnd.oasis.opendocument.text-master odm
application/vnd.oasis.opendocument.text-template ott
application/vnd.oasis.opendocument.text-web oth
application/vnd.olpc-sugar xo
application/vnd.oma.dd2+xml dd2
application/vnd.openofficeorg.extension oxt
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
application/vnd.openxmlformats-officedocument.presentationml.slide sldx
application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
application/vnd.openxmlformats-officedocument.presentationml.template potx
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
application/vnd.osgeo.mapguide.package mgp
application/vnd.osgi.dp dp
application/vnd.osgi.subsystem esa
application/vnd.palm pdb pqa oprc
application/vnd.pawaafile paw
application/vnd.pg.format str
application/vnd.pg.osasli ei6
application/vnd.picsel efif
application/vnd.pmi.widget wg
application/vnd.pocketlearn plf
application/vnd.powerbuilder6 pbd
application/vnd.previewsystems.box box
application/vnd.proteus.magazine mgz
application/vnd.publishare-delta-tree qps
application/vnd.pvi.ptid1 ptid
application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
application/vnd.realvnc.bed bed
application/vnd.recordare.musicxml mxl
application/vnd.recordare.musicxml+xml musicxml
application/vnd.rig.cryptonote cryptonote
application/vnd.rim.cod cod
application/vnd.rn-realmedia rm
application/vnd.rn-realmedia-vbr rmvb
application/vnd.route66.link66+xml link66
application/vnd.sailingtracker.track st
application/vnd.seemail see
application/vnd.sema sema
application/vnd.semd semd
application/vnd.semf semf
application/vnd.shana.informed.formdata ifm
application/vnd.shana.informed.formtemplate itp
application/vnd.shana.informed.interchange iif
application/vnd.shana.informed.package ipk
application/vnd.simtech-mindmapper twd twds
application/vnd.smaf mmf
application/vnd.smart.teacher teacher
application/vnd.solent.sdkm+xml sdkm sdkd
application/vnd.spotfire.dxp dxp
application/vnd.spotfire.sfs sfs
application/vnd.stardivision.calc sdc
application/vnd.stardivision.draw sda
application/vnd.stardivision.impress sdd
application/vnd.stardivision.math smf
application/vnd.stardivision.writer sdw vor
application/vnd.stardivision.writer-global sgl
application/vnd.stepmania.package smzip
application/vnd.stepmania.stepchart sm
application/vnd.sun.xml.calc sxc
application/vnd.sun.xml.calc.template stc
application/vnd.sun.xml.draw sxd
application/vnd.sun.xml.draw.template std
application/vnd.sun.xml.impress sxi
application/vnd.sun.xml.impress.template sti
application/vnd.sun.xml.math sxm
application/vnd.sun.xml.writer sxw
application/vnd.sun.xml.writer.global sxg
application/vnd.sun.xml.writer.template stw
application/vnd.sus-calendar sus susp
application/vnd.svd svd
application/vnd.symbian.install sis sisx
application/vnd.syncml+xml xsm
application/vnd.syncml.dm+wbxml bdm
application/vnd.syncml.dm+xml xdm
application/vnd.tao.intent-module-archive tao
application/vnd.tcpdump.pcap pcap cap dmp
application/vnd.tmobile-livetv tmo
application/vnd.trid.tpt tpt
application/vnd.triscape.mxs mxs
application/vnd.trueapp tra
application/vnd.ufdl ufd ufdl
application/vnd.uiq.theme utz
application/vnd.umajin umj
application/vnd.unity unityweb
application/vnd.uoml+xml uoml
application/vnd.vcx vcx
application/vnd.visio vsd vst vss vsw
application/vnd.visionary vis
application/vnd.vsf vsf
application/vnd.wap.wbxml wbxml
application/vnd.wap.wmlc wmlc
application/vnd.wap.wmlscriptc wmlsc
application/vnd.webturbo wtb
application/vnd.wolfram.player nbp
application/vnd.wordperfect wpd
application/vnd.wqd wqd
application/vnd.wt.stf stf
application/vnd.xara xar
application/vnd.xfdl xfdl
application/vnd.yamaha.hv-dic hvd
application/vnd.yamaha.hv-script hvs
application/vnd.yamaha.hv-voice hvp
application/vnd.yamaha.openscoreformat osf
application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg
application/vnd.yamaha.smaf-audio saf
application/vnd.yamaha.smaf-phrase spf
application/vnd.yellowriver-custom-menu cmp
application/vnd.zul zir zirz
application/vnd.zzazz.deck+xml zaz
application/voicexml+xml vxml
application/widget wgt
application/winhlp hlp
application/wsdl+xml wsdl
application/wspolicy+xml wspolicy
application/x-7z-compressed 7z
application/x-abiword abw
application/x-ace-compressed ace
application/x-apple-diskimage dmg
application/x-authorware-bin aab x32 u32 vox
application/x-authorware-map aam
application/x-authorware-seg aas
application/x-bcpio bcpio
application/x-bittorrent torrent
application/x-blorb blb blorb
application/x-bzip bz
application/x-bzip2 bz2 boz
application/x-cbr cbr cba cbt cbz cb7
application/x-cdlink vcd
application/x-cfs-compressed cfs
application/x-chat chat
application/x-chess-pgn pgn
application/x-conference nsc
application/x-cpio cpio
application/x-csh csh
application/x-debian-package deb udeb
application/x-dgc-compressed dgc
application/x-director dir dcr dxr cst cct cxt w3d fgd swa
application/x-doom wad
application/x-dtbncx+xml ncx
application/x-dtbook+xml dtb
application/x-dtbresource+xml res
application/x-dvi dvi
application/x-envoy evy
application/x-eva eva
application/x-font-bdf bdf
application/x-font-ghostscript gsf
application/x-font-linux-psf psf
application/x-font-pcf pcf
application/x-font-snf snf
application/x-font-type1 pfa pfb pfm afm
application/x-freearc arc
application/x-futuresplash spl
application/x-gca-compressed gca
application/x-glulx ulx
application/x-gnumeric gnumeric
application/x-gramps-xml gramps
application/x-gtar gtar
application/x-hdf hdf
application/x-install-instructions install
application/x-iso9660-image iso
application/x-java-jnlp-file jnlp
application/x-latex latex
application/x-lzh-compressed lzh lha
application/x-mie mie
application/x-mobipocket-ebook prc mobi
application/x-ms-application application
application/x-ms-shortcut lnk
application/x-ms-wmd wmd
application/x-ms-wmz wmz
application/x-ms-xbap xbap
application/x-msaccess mdb
application/x-msbinder obd
application/x-mscardfile crd
application/x-msclip clp
application/x-msdownload exe dll com bat msi
application/x-msmediaview mvb m13 m14
application/x-msmetafile wmf wmz emf emz
application/x-msmoney mny
application/x-mspublisher pub
application/x-msschedule scd
application/x-msterminal trm
application/x-mswrite wri
application/x-netcdf nc cdf
application/x-nzb nzb
application/x-pkcs12 p12 pfx
application/x-pkcs7-certificates p7b spc
application/x-pkcs7-certreqresp p7r
application/x-rar-compressed rar
application/x-research-info-systems ris
application/x-sh sh
application/x-shar shar
application/x-shockwave-flash swf
application/x-silverlight-app xap
application/x-sql sql
application/x-stuffit sit
application/x-stuffitx sitx
application/x-subrip srt
application/x-sv4cpio sv4cpio
application/x-sv4crc sv4crc
application/x-t3vm-image t3
application/x-tads gam
application/x-tar tar
application/x-tcl tcl
application/x-tex tex
application/x-tex-tfm tfm
application/x-texinfo texinfo texi
application/x-tgif obj
application/x-ustar ustar
application/x-wais-source src
application/x-x509-ca-cert der crt
application/x-xfig fig
application/x-xliff+xml xlf
application/x-xpinstall xpi
application/x-xz xz
application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8
application/xaml+xml xaml
application/xcap-diff+xml xdf
application/xenc+xml xenc
application/xhtml+xml xhtml xht
application/xml xml xsl
application/xml-dtd dtd
application/xop+xml xop
application/xproc+xml xpl
application/xslt+xml xslt
application/xspf+xml xspf
application/xv+xml mxml xhvml xvml xvm
application/yang yang
application/yin+xml yin
application/zip zip
audio/adpcm adp
audio/basic au snd
audio/midi mid midi kar rmi
audio/mp4 m4a mp4a
audio/mpeg mpga mp2 mp2a mp3 m2a m3a
audio/ogg oga ogg spx
audio/s3m s3m
audio/silk sil
audio/vnd.dece.audio uva uvva
audio/vnd.digital-winds eol
audio/vnd.dra dra
audio/vnd.dts dts
audio/vnd.dts.hd dtshd
audio/vnd.lucent.voice lvp
audio/vnd.ms-playready.media.pya pya
audio/vnd.nuera.ecelp4800 ecelp4800
audio/vnd.nuera.ecelp7470 ecelp7470
audio/vnd.nuera.ecelp9600 ecelp9600
audio/vnd.rip rip
audio/webm weba
audio/x-aac aac
audio/x-aiff aif aiff aifc
audio/x-caf caf
audio/x-flac flac
audio/x-matroska mka
audio/x-mpegurl m3u
audio/x-ms-wax wax
audio/x-ms-wma wma
audio/x-pn-realaudio ram ra
audio/x-pn-realaudio-plugin rmp
audio/x-wav wav
audio/xm xm
chemical/x-cdx cdx
chemical/x-cif cif
chemical/x-cmdf cmdf
chemical/x-cml cml
chemical/x-csml csml
chemical/x-xyz xyz
font/collection ttc
font/otf otf
font/ttf ttf
font/woff woff
font/woff2 woff2
image/bmp bmp
image/cgm cgm
image/g3fax g3
image/gif gif
image/ief ief
image/jpeg jpeg jpg jpe
image/ktx ktx
image/png png
image/prs.btif btif
image/sgi sgi
image/svg+xml svg svgz
image/tiff tiff tif
image/vnd.adobe.photoshop psd
image/vnd.dece.graphic uvi uvvi uvg uvvg
image/vnd.djvu djvu djv
image/vnd.dvb.subtitle sub
image/vnd.dwg dwg
image/vnd.dxf dxf
image/vnd.fastbidsheet fbs
image/vnd.fpx fpx
image/vnd.fst fst
image/vnd.fujixerox.edmics-mmr mmr
image/vnd.fujixerox.edmics-rlc rlc
image/vnd.ms-modi mdi
image/vnd.ms-photo wdp
image/vnd.net-fpx npx
image/vnd.wap.wbmp wbmp
image/vnd.xiff xif
image/webp webp
image/x-3ds 3ds
image/x-cmu-raster ras
image/x-cmx cmx
image/x-freehand fh fhc fh4 fh5 fh7
image/x-icon ico
image/x-mrsid-image sid
image/x-pcx pcx
image/x-pict pic pct
image/x-portable-anymap pnm
image/x-portable-bitmap pbm
image/x-portable-graymap pgm
image/x-portable-pixmap ppm
image/x-rgb rgb
image/x-tga tga
image/x-xbitmap xbm
image/x-xpixmap xpm
image/x-xwindowdump xwd
message/rfc822 eml mime
model/iges igs iges
model/mesh msh mesh silo
model/vnd.collada+xml dae
model/vnd.dwf dwf
model/vnd.gdl gdl
model/vnd.gtw gtw
model/vnd.mts mts
model/vnd.vtu vtu
model/vrml wrl vrml
model/x3d+binary x3db x3dbz
model/x3d+vrml x3dv x3dvz
model/x3d+xml x3d x3dz
text/cache-manifest appcache
text/calendar ics ifb
text/css css
text/csv csv
text/html html htm
text/n3 n3
text/plain txt text conf def list log in
text/prs.lines.tag dsc
text/richtext rtx
text/sgml sgml sgm
text/tab-separated-values tsv
text/troff t tr roff man me ms
text/turtle ttl
text/uri-list uri uris urls
text/vcard vcard
text/vnd.curl curl
text/vnd.curl.dcurl dcurl
text/vnd.curl.mcurl mcurl
text/vnd.curl.scurl scurl
text/vnd.dvb.subtitle sub
text/vnd.fly fly
text/vnd.fmi.flexstor flx
text/vnd.graphviz gv
text/vnd.in3d.3dml 3dml
text/vnd.in3d.spot spot
text/vnd.sun.j2me.app-descriptor jad
text/vnd.wap.wml wml
text/vnd.wap.wmlscript wmls
text/x-asm s asm
text/x-c c cc cxx cpp h hh dic
text/x-fortran f for f77 f90
text/x-java-source java
text/x-nfo nfo
text/x-opml opml
text/x-pascal p pas
text/x-setext etx
text/x-sfv sfv
text/x-uuencode uu
text/x-vcalendar vcs
text/x-vcard vcf
video/3gpp 3gp
video/3gpp2 3g2
video/h261 h261
video/h263 h263
video/h264 h264
video/jpeg jpgv
video/jpm jpm jpgm
video/mj2 mj2 mjp2
video/mp4 mp4 mp4v mpg4
video/mpeg mpeg mpg mpe m1v m2v
video/ogg ogv
video/quicktime qt mov
video/vnd.dece.hd uvh uvvh
video/vnd.dece.mobile uvm uvvm
video/vnd.dece.pd uvp uvvp
video/vnd.dece.sd uvs uvvs
video/vnd.dece.video uvv uvvv
video/vnd.dvb.file dvb
video/vnd.fvt fvt
video/vnd.mpegurl mxu m4u
video/vnd.ms-playready.media.pyv pyv
video/vnd.uvvu.mp4 uvu uvvu
video/vnd.vivo viv
video/webm webm
video/x-f4v f4v
video/x-fli fli
video/x-flv flv
video/x-m4v m4v
video/x-matroska mkv mk3d mks
video/x-mng mng
video/x-ms-asf asf asx
video/x-ms-vob vob
video/x-ms-wm wm
video/x-ms-wmv wmv
video/x-ms-wmx wmx
video/x-ms-wvx wvx
video/x-msvideo avi
video/x-sgi-movie movie
video/x-smv smv
x-conference/x-cooltalk ice
@@ -0,0 +1,151 @@
<?php
/**
* elFinder Plugin AutoResize
* Auto resize on file upload.
* ex. binding, configure on connector options
* $opts = array(
* 'bind' => array(
* 'upload.presave' => array(
* 'Plugin.AutoResize.onUpLoadPreSave'
* )
* ),
* // global configure (optional)
* 'plugin' => array(
* 'AutoResize' => array(
* 'enable' => true, // For control by volume driver
* 'maxWidth' => 1024, // Path to Water mark image
* 'maxHeight' => 1024, // Margin right pixel
* 'quality' => 95, // JPEG image save quality
* 'preserveExif' => false, // Preserve EXIF data (Imagick only)
* 'forceEffect' => false, // For change quality or make progressive JPEG of small images
* 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* )
* ),
* // each volume configure (optional)
* 'roots' => array(
* array(
* 'driver' => 'LocalFileSystem',
* 'path' => '/path/to/files/',
* 'URL' => 'http://localhost/to/files/'
* 'plugin' => array(
* 'AutoResize' => array(
* 'enable' => true, // For control by volume driver
* 'maxWidth' => 1024, // Path to Water mark image
* 'maxHeight' => 1024, // Margin right pixel
* 'quality' => 95, // JPEG image save quality
* 'preserveExif' => false, // Preserve EXIF data (Imagick only)
* 'forceEffect' => false, // For change quality or make progressive JPEG of small images
* 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* )
* )
* )
* )
* );
*
* @package elfinder
* @author Naoki Sawada
* @license New BSD
*/
class elFinderPluginAutoResize extends elFinderPlugin
{
public function __construct($opts)
{
$defaults = array(
'enable' => true, // For control by volume driver
'maxWidth' => 1024, // Path to Water mark image
'maxHeight' => 1024, // Margin right pixel
'quality' => 95, // JPEG image save quality
'preserveExif' => false, // Preserve EXIF data (Imagick only)
'forceEffect' => false, // For change quality or make progressive JPEG of small images
'targetType' => IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP, // Target image formats ( bit-field )
'offDropWith' => null, // To disable it if it is dropped with pressing the meta key
// Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
// In case of using any key, specify it as an array
'disableWithContentSaveId' => true // Disable on URL upload with post data "contentSaveId"
);
$this->opts = array_merge($defaults, $opts);
}
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
{
if (!$src) {
return false;
}
$opts = $this->getCurrentOpts($volume);
if (!$this->iaEnabled($opts, $elfinder)) {
return false;
}
$imageType = null;
$srcImgInfo = null;
if (extension_loaded('fileinfo') && function_exists('mime_content_type')) {
$mime = mime_content_type($src);
if (substr($mime, 0, 5) !== 'image') {
return false;
}
}
if (extension_loaded('exif') && function_exists('exif_imagetype')) {
$imageType = exif_imagetype($src);
if ($imageType === false) {
return false;
}
} else {
$srcImgInfo = getimagesize($src);
if ($srcImgInfo === false) {
return false;
}
$imageType = $srcImgInfo[2];
}
// check target image type
$imgTypes = array(
IMAGETYPE_GIF => IMG_GIF,
IMAGETYPE_JPEG => IMG_JPEG,
IMAGETYPE_PNG => IMG_PNG,
IMAGETYPE_BMP => IMG_WBMP,
IMAGETYPE_WBMP => IMG_WBMP
);
if (!isset($imgTypes[$imageType]) || !($opts['targetType'] & $imgTypes[$imageType])) {
return false;
}
if (!$srcImgInfo) {
$srcImgInfo = getimagesize($src);
}
if ($opts['forceEffect'] || $srcImgInfo[0] > $opts['maxWidth'] || $srcImgInfo[1] > $opts['maxHeight']) {
return $this->resize($volume, $src, $srcImgInfo, $opts['maxWidth'], $opts['maxHeight'], $opts['quality'], $opts['preserveExif']);
}
return false;
}
private function resize($volume, $src, $srcImgInfo, $maxWidth, $maxHeight, $jpgQuality, $preserveExif)
{
$zoom = min(($maxWidth / $srcImgInfo[0]), ($maxHeight / $srcImgInfo[1]));
$width = round($srcImgInfo[0] * $zoom);
$height = round($srcImgInfo[1] * $zoom);
$unenlarge = true;
$checkAnimated = true;
return $volume->imageUtil('resize', $src, compact('width', 'height', 'jpgQuality', 'preserveExif', 'unenlarge', 'checkAnimated'));
}
}
@@ -0,0 +1,148 @@
<?php
/**
* elFinder Plugin AutoRotate
* Auto rotation on file upload of JPEG file by EXIF Orientation.
* ex. binding, configure on connector options
* $opts = array(
* 'bind' => array(
* 'upload.presave' => array(
* 'Plugin.AutoRotate.onUpLoadPreSave'
* )
* ),
* // global configure (optional)
* 'plugin' => array(
* 'AutoRotate' => array(
* 'enable' => true, // For control by volume driver
* 'quality' => 95, // JPEG image save quality
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* )
* ),
* // each volume configure (optional)
* 'roots' => array(
* array(
* 'driver' => 'LocalFileSystem',
* 'path' => '/path/to/files/',
* 'URL' => 'http://localhost/to/files/'
* 'plugin' => array(
* 'AutoRotate' => array(
* 'enable' => true, // For control by volume driver
* 'quality' => 95, // JPEG image save quality
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* )
* )
* )
* )
* );
*
* @package elfinder
* @author Naoki Sawada
* @license New BSD
*/
class elFinderPluginAutoRotate extends elFinderPlugin
{
public function __construct($opts)
{
$defaults = array(
'enable' => true, // For control by volume driver
'quality' => 95, // JPEG image save quality
'offDropWith' => null, // To disable it if it is dropped with pressing the meta key
// Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
// In case of using any key, specify it as an array
'disableWithContentSaveId' => true // Disable on URL upload with post data "contentSaveId"
);
$this->opts = array_merge($defaults, $opts);
}
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
{
if (!$src) {
return false;
}
$opts = $this->getCurrentOpts($volume);
if (!$this->iaEnabled($opts, $elfinder)) {
return false;
}
$imageType = null;
$srcImgInfo = null;
if (extension_loaded('fileinfo') && function_exists('mime_content_type')) {
$mime = mime_content_type($src);
if (substr($mime, 0, 5) !== 'image') {
return false;
}
}
if (extension_loaded('exif') && function_exists('exif_imagetype')) {
$imageType = exif_imagetype($src);
if ($imageType === false) {
return false;
}
} else {
$srcImgInfo = getimagesize($src);
if ($srcImgInfo === false) {
return false;
}
$imageType = $srcImgInfo[2];
}
// check target image type
if ($imageType !== IMAGETYPE_JPEG) {
return false;
}
if (!$srcImgInfo) {
$srcImgInfo = getimagesize($src);
}
return $this->rotate($volume, $src, $srcImgInfo, $opts['quality']);
}
private function rotate($volume, $src, $srcImgInfo, $quality)
{
if (!function_exists('exif_read_data')) {
return false;
}
$degree = 0;
$errlev =error_reporting();
error_reporting($errlev ^ E_WARNING);
$exif = exif_read_data($src);
error_reporting($errlev);
if ($exif && !empty($exif['Orientation'])) {
switch ($exif['Orientation']) {
case 8:
$degree = 270;
break;
case 3:
$degree = 180;
break;
case 6:
$degree = 90;
break;
}
}
if (!$degree) {
return false;
}
$opts = array(
'degree' => $degree,
'jpgQuality' => $quality,
'checkAnimated' => true
);
return $volume->imageUtil('rotate', $src, $opts);
}
}
@@ -0,0 +1,204 @@
<?php
/**
* elFinder Plugin Normalizer
* UTF-8 Normalizer of file-name and file-path etc.
* nfc(NFC): Canonical Decomposition followed by Canonical Composition
* nfkc(NFKC): Compatibility Decomposition followed by Canonical
* This plugin require Class "Normalizer" (PHP 5 >= 5.3.0, PECL intl >= 1.0.0)
* or PEAR package "I18N_UnicodeNormalizer"
* ex. binding, configure on connector options
* $opts = array(
* 'bind' => array(
* 'upload.pre mkdir.pre mkfile.pre rename.pre archive.pre ls.pre' => array(
* 'Plugin.Normalizer.cmdPreprocess'
* ),
* 'upload.presave paste.copyfrom' => array(
* 'Plugin.Normalizer.onUpLoadPreSave'
* )
* ),
* // global configure (optional)
* 'plugin' => array(
* 'Normalizer' => array(
* 'enable' => true,
* 'nfc' => true,
* 'nfkc' => true,
* 'umlauts' => false,
* 'lowercase' => false,
* 'convmap' => array()
* )
* ),
* // each volume configure (optional)
* 'roots' => array(
* array(
* 'driver' => 'LocalFileSystem',
* 'path' => '/path/to/files/',
* 'URL' => 'http://localhost/to/files/'
* 'plugin' => array(
* 'Normalizer' => array(
* 'enable' => true,
* 'nfc' => true,
* 'nfkc' => true,
* 'umlauts' => false,
* 'lowercase' => false,
* 'convmap' => array()
* )
* )
* )
* )
* );
*
* @package elfinder
* @author Naoki Sawada
* @license New BSD
*/
class elFinderPluginNormalizer extends elFinderPlugin
{
private $replaced = array();
private $keyMap = array(
'ls' => 'intersect',
'upload' => 'renames',
'mkdir' => array('name', 'dirs')
);
public function __construct($opts)
{
$defaults = array(
'enable' => true, // For control by volume driver
'nfc' => true, // Canonical Decomposition followed by Canonical Composition
'nfkc' => true, // Compatibility Decomposition followed by Canonical
'umlauts' => false, // Convert umlauts with their closest 7 bit ascii equivalent
'lowercase' => false, // Make chars lowercase
'convmap' => array()// Convert map ('FROM' => 'TO') array
);
$this->opts = array_merge($defaults, $opts);
}
public function cmdPreprocess($cmd, &$args, $elfinder, $volume)
{
$opts = $this->getCurrentOpts($volume);
if (!$opts['enable']) {
return false;
}
$this->replaced[$cmd] = array();
$key = (isset($this->keyMap[$cmd])) ? $this->keyMap[$cmd] : 'name';
if (is_array($key)) {
$keys = $key;
} else {
$keys = array($key);
}
foreach ($keys as $key) {
if (isset($args[$key])) {
if (is_array($args[$key])) {
foreach ($args[$key] as $i => $name) {
if ($cmd === 'mkdir' && $key === 'dirs') {
// $name need '/' as prefix see #2607
$name = '/' . ltrim($name, '/');
$_names = explode('/', $name);
$_res = array();
foreach ($_names as $_name) {
$_res[] = $this->normalize($_name, $opts);
}
$this->replaced[$cmd][$name] = $args[$key][$i] = join('/', $_res);
} else {
$this->replaced[$cmd][$name] = $args[$key][$i] = $this->normalize($name, $opts);
}
}
} else if ($args[$key] !== '') {
$name = $args[$key];
$this->replaced[$cmd][$name] = $args[$key] = $this->normalize($name, $opts);
}
}
}
if ($cmd === 'ls' || $cmd === 'mkdir') {
if (!empty($this->replaced[$cmd])) {
// un-regist for legacy settings
$elfinder->unbind($cmd, array($this, 'cmdPostprocess'));
$elfinder->bind($cmd, array($this, 'cmdPostprocess'));
}
}
return true;
}
public function cmdPostprocess($cmd, &$result, $args, $elfinder, $volume)
{
if ($cmd === 'ls') {
if (!empty($result['list']) && !empty($this->replaced['ls'])) {
foreach ($result['list'] as $hash => $name) {
if ($keys = array_keys($this->replaced['ls'], $name)) {
if (count($keys) === 1) {
$result['list'][$hash] = $keys[0];
} else {
$result['list'][$hash] = $keys;
}
}
}
}
} else if ($cmd === 'mkdir') {
if (!empty($result['hashes']) && !empty($this->replaced['mkdir'])) {
foreach ($result['hashes'] as $name => $hash) {
if ($keys = array_keys($this->replaced['mkdir'], $name)) {
$result['hashes'][$keys[0]] = $hash;
}
}
}
}
}
// NOTE: $thash is directory hash so it unneed to process at here
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
{
$opts = $this->getCurrentOpts($volume);
if (!$opts['enable']) {
return false;
}
$name = $this->normalize($name, $opts);
return true;
}
protected function normalize($str, $opts)
{
if ($opts['nfc'] || $opts['nfkc']) {
if (class_exists('Normalizer', false)) {
if ($opts['nfc'] && !Normalizer::isNormalized($str, Normalizer::FORM_C))
$str = Normalizer::normalize($str, Normalizer::FORM_C);
if ($opts['nfkc'] && !Normalizer::isNormalized($str, Normalizer::FORM_KC))
$str = Normalizer::normalize($str, Normalizer::FORM_KC);
} else {
if (!class_exists('I18N_UnicodeNormalizer', false)) {
if (is_readable('I18N/UnicodeNormalizer.php')) {
include_once 'I18N/UnicodeNormalizer.php';
} else {
trigger_error('Plugin Normalizer\'s options "nfc" or "nfkc" require PHP class "Normalizer" or PEAR package "I18N_UnicodeNormalizer"', E_USER_WARNING);
}
}
if (class_exists('I18N_UnicodeNormalizer', false)) {
$normalizer = new I18N_UnicodeNormalizer();
if ($opts['nfc'])
$str = $normalizer->normalize($str, 'NFC');
if ($opts['nfkc'])
$str = $normalizer->normalize($str, 'NFKC');
}
}
}
if ($opts['umlauts']) {
if (strpos($str = htmlentities($str, ENT_QUOTES, 'UTF-8'), '&') !== false) {
$str = html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|caron|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1', $str), ENT_QUOTES, 'utf-8');
}
}
if ($opts['convmap'] && is_array($opts['convmap'])) {
$str = strtr($str, $opts['convmap']);
}
if ($opts['lowercase']) {
if (function_exists('mb_strtolower')) {
$str = mb_strtolower($str, 'UTF-8');
} else {
$str = strtolower($str);
}
}
return $str;
}
}
@@ -0,0 +1,157 @@
<?php
/**
* elFinder Plugin Sanitizer
* Sanitizer of file-name and file-path etc.
* ex. binding, configure on connector options
* $opts = array(
* 'bind' => array(
* 'upload.pre mkdir.pre mkfile.pre rename.pre archive.pre ls.pre' => array(
* 'Plugin.Sanitizer.cmdPreprocess'
* ),
* 'upload.presave paste.copyfrom' => array(
* 'Plugin.Sanitizer.onUpLoadPreSave'
* )
* ),
* // global configure (optional)
* 'plugin' => array(
* 'Sanitizer' => array(
* 'enable' => true,
* 'targets' => array('\\','/',':','*','?','"','<','>','|'), // target chars
* 'replace' => '_', // replace to this
* 'callBack' => null // Or @callable sanitize function
* )
* ),
* // each volume configure (optional)
* 'roots' => array(
* array(
* 'driver' => 'LocalFileSystem',
* 'path' => '/path/to/files/',
* 'URL' => 'http://localhost/to/files/'
* 'plugin' => array(
* 'Sanitizer' => array(
* 'enable' => true,
* 'targets' => array('\\','/',':','*','?','"','<','>','|'), // target chars
* 'replace' => '_', // replace to this
* 'callBack' => null // Or @callable sanitize function
* )
* )
* )
* )
* );
*
* @package elfinder
* @author Naoki Sawada
* @license New BSD
*/
class elFinderPluginSanitizer extends elFinderPlugin
{
private $replaced = array();
private $keyMap = array(
'ls' => 'intersect',
'upload' => 'renames',
'mkdir' => array('name', 'dirs')
);
public function __construct($opts)
{
$defaults = array(
'enable' => true, // For control by volume driver
'targets' => array('\\', '/', ':', '*', '?', '"', '<', '>', '|'), // target chars
'replace' => '_', // replace to this
'callBack' => null // Or callable sanitize function
);
$this->opts = array_merge($defaults, $opts);
}
public function cmdPreprocess($cmd, &$args, $elfinder, $volume)
{
$opts = $this->getCurrentOpts($volume);
if (!$opts['enable']) {
return false;
}
$this->replaced[$cmd] = array();
$key = (isset($this->keyMap[$cmd])) ? $this->keyMap[$cmd] : 'name';
if (is_array($key)) {
$keys = $key;
} else {
$keys = array($key);
}
foreach ($keys as $key) {
if (isset($args[$key])) {
if (is_array($args[$key])) {
foreach ($args[$key] as $i => $name) {
if ($cmd === 'mkdir' && $key === 'dirs') {
// $name need '/' as prefix see #2607
$name = '/' . ltrim($name, '/');
$_names = explode('/', $name);
$_res = array();
foreach ($_names as $_name) {
$_res[] = $this->sanitizeFileName($_name, $opts);
}
$this->replaced[$cmd][$name] = $args[$key][$i] = join('/', $_res);
} else {
$this->replaced[$cmd][$name] = $args[$key][$i] = $this->sanitizeFileName($name, $opts);
}
}
} else if ($args[$key] !== '') {
$name = $args[$key];
$this->replaced[$cmd][$name] = $args[$key] = $this->sanitizeFileName($name, $opts);
}
}
}
if ($cmd === 'ls' || $cmd === 'mkdir') {
if (!empty($this->replaced[$cmd])) {
// un-regist for legacy settings
$elfinder->unbind($cmd, array($this, 'cmdPostprocess'));
$elfinder->bind($cmd, array($this, 'cmdPostprocess'));
}
}
return true;
}
public function cmdPostprocess($cmd, &$result, $args, $elfinder, $volume)
{
if ($cmd === 'ls') {
if (!empty($result['list']) && !empty($this->replaced['ls'])) {
foreach ($result['list'] as $hash => $name) {
if ($keys = array_keys($this->replaced['ls'], $name)) {
if (count($keys) === 1) {
$result['list'][$hash] = $keys[0];
} else {
$result['list'][$hash] = $keys;
}
}
}
}
} else if ($cmd === 'mkdir') {
if (!empty($result['hashes']) && !empty($this->replaced['mkdir'])) {
foreach ($result['hashes'] as $name => $hash) {
if ($keys = array_keys($this->replaced['mkdir'], $name)) {
$result['hashes'][$keys[0]] = $hash;
}
}
}
}
}
// NOTE: $thash is directory hash so it unneed to process at here
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
{
$opts = $this->getCurrentOpts($volume);
if (!$opts['enable']) {
return false;
}
$name = $this->sanitizeFileName($name, $opts);
return true;
}
protected function sanitizeFileName($filename, $opts)
{
if (!empty($opts['callBack']) && is_callable($opts['callBack'])) {
return call_user_func_array($opts['callBack'], array($filename, $opts));
}
return str_replace($opts['targets'], $opts['replace'], $filename);
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

@@ -0,0 +1,432 @@
<?php
/**
* elFinder Plugin Watermark
* Print watermark on file upload.
* ex. binding, configure on connector options
* $opts = array(
* 'bind' => array(
* 'upload.presave' => array(
* 'Plugin.Watermark.onUpLoadPreSave'
* )
* ),
* // global configure (optional)
* 'plugin' => array(
* 'Watermark' => array(
* 'enable' => true, // For control by volume driver
* 'source' => 'logo.png', // Path to Water mark image
* 'ratio' => 0.2, // Ratio to original image (ratio > 0 and ratio <= 1)
* 'position' => 'RB', // Position L(eft)/C(enter)/R(ight) and T(op)/M(edium)/B(ottom)
* 'marginX' => 5, // Margin horizontal pixel
* 'marginY' => 5, // Margin vertical pixel
* 'quality' => 95, // JPEG image save quality
* 'transparency' => 70, // Water mark image transparency ( other than PNG )
* 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
* 'targetMinPixel' => 200, // Target image minimum pixel size
* 'interlace' => IMG_GIF|IMG_JPG, // Set interlacebit image formats ( bit-field )
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* )
* ),
* // each volume configure (optional)
* 'roots' => array(
* array(
* 'driver' => 'LocalFileSystem',
* 'path' => '/path/to/files/',
* 'URL' => 'http://localhost/to/files/'
* 'plugin' => array(
* 'Watermark' => array(
* 'enable' => true, // For control by volume driver
* 'source' => 'logo.png', // Path to Water mark image
* 'ratio' => 0.2, // Ratio to original image (ratio > 0 and ratio <= 1)
* 'position' => 'RB', // Position L(eft)/C(enter)/R(ight) and T(op)/M(edium)/B(ottom)
* 'marginX' => 5, // Margin horizontal pixel
* 'marginY' => 5, // Margin vertical pixel
* 'quality' => 95, // JPEG image save quality
* 'transparency' => 70, // Water mark image transparency ( other than PNG )
* 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
* 'targetMinPixel' => 200, // Target image minimum pixel size
* 'interlace' => IMG_GIF|IMG_JPG, // Set interlacebit image formats ( bit-field )
* 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
* // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
* // In case of using any key, specify it as an array
* )
* )
* )
* )
* );
*
* @package elfinder
* @author Naoki Sawada
* @license New BSD
*/
class elFinderPluginWatermark extends elFinderPlugin
{
private $watermarkImgInfo = null;
public function __construct($opts)
{
$defaults = array(
'enable' => true, // For control by volume driver
'source' => 'logo.png', // Path to Water mark image
'ratio' => 0.2, // Ratio to original image (ratio > 0 and ratio <= 1)
'position' => 'RB', // Position L(eft)/C(enter)/R(ight) and T(op)/M(edium)/B(ottom)
'marginX' => 5, // Margin horizontal pixel
'marginY' => 5, // Margin vertical pixel
'quality' => 95, // JPEG image save quality
'transparency' => 70, // Water mark image transparency ( other than PNG )
'targetType' => IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP, // Target image formats ( bit-field )
'targetMinPixel' => 200, // Target image minimum pixel size
'interlace' => IMG_GIF | IMG_JPG, // Set interlacebit image formats ( bit-field )
'offDropWith' => null, // To disable it if it is dropped with pressing the meta key
// Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
// In case of using any key, specify it as an array
'marginRight' => 0, // Deprecated - marginX should be used
'marginBottom' => 0, // Deprecated - marginY should be used
'disableWithContentSaveId' => true // Disable on URL upload with post data "contentSaveId"
);
$this->opts = array_merge($defaults, $opts);
}
public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
{
if (!$src) {
return false;
}
$opts = $this->getCurrentOpts($volume);
if (!$this->iaEnabled($opts, $elfinder)) {
return false;
}
$imageType = null;
$srcImgInfo = null;
if (extension_loaded('fileinfo') && function_exists('mime_content_type')) {
$mime = mime_content_type($src);
if (substr($mime, 0, 5) !== 'image') {
return false;
}
}
if (extension_loaded('exif') && function_exists('exif_imagetype')) {
$imageType = exif_imagetype($src);
if ($imageType === false) {
return false;
}
} else {
$srcImgInfo = getimagesize($src);
if ($srcImgInfo === false) {
return false;
}
$imageType = $srcImgInfo[2];
}
// check target image type
$imgTypes = array(
IMAGETYPE_GIF => IMG_GIF,
IMAGETYPE_JPEG => IMG_JPEG,
IMAGETYPE_PNG => IMG_PNG,
IMAGETYPE_BMP => IMG_WBMP,
IMAGETYPE_WBMP => IMG_WBMP
);
if (!isset($imgTypes[$imageType]) || !($opts['targetType'] & $imgTypes[$imageType])) {
return false;
}
// check Animation Gif
if ($imageType === IMAGETYPE_GIF && elFinder::isAnimationGif($src)) {
return false;
}
// check Animation Png
if ($imageType === IMAGETYPE_PNG && elFinder::isAnimationPng($src)) {
return false;
}
// check water mark image
if (!file_exists($opts['source'])) {
$opts['source'] = dirname(__FILE__) . "/" . $opts['source'];
}
if (is_readable($opts['source'])) {
$watermarkImgInfo = getimagesize($opts['source']);
if (!$watermarkImgInfo) {
return false;
}
} else {
return false;
}
if (!$srcImgInfo) {
$srcImgInfo = getimagesize($src);
}
$watermark = $opts['source'];
$quality = $opts['quality'];
$transparency = $opts['transparency'];
// check target image size
if ($opts['targetMinPixel'] > 0 && $opts['targetMinPixel'] > min($srcImgInfo[0], $srcImgInfo[1])) {
return false;
}
$watermark_width = $watermarkImgInfo[0];
$watermark_height = $watermarkImgInfo[1];
// Specified as a ratio to the image size
if ($opts['ratio'] && $opts['ratio'] > 0 && $opts['ratio'] <= 1) {
$maxW = $srcImgInfo[0] * $opts['ratio'] - ($opts['marginX'] * 2);
$maxH = $srcImgInfo[1] * $opts['ratio'] - ($opts['marginY'] * 2);
$dx = $dy = 0;
if (($maxW >= $watermarkImgInfo[0] && $maxH >= $watermarkImgInfo[0]) || ($maxW <= $watermarkImgInfo[0] && $maxH <= $watermarkImgInfo[0])) {
$dx = abs($srcImgInfo[0] - $watermarkImgInfo[0]);
$dy = abs($srcImgInfo[1] - $watermarkImgInfo[1]);
} else if ($maxW < $watermarkImgInfo[0]) {
$dx = -1;
} else {
$dy = -1;
}
if ($dx < $dy) {
$ww = $maxW;
$wh = $watermarkImgInfo[1] * ($ww / $watermarkImgInfo[0]);
} else {
$wh = $maxH;
$ww = $watermarkImgInfo[0] * ($wh / $watermarkImgInfo[1]);
}
$watermarkImgInfo[0] = $ww;
$watermarkImgInfo[1] = $wh;
} else {
$opts['ratio'] = null;
}
$opts['position'] = strtoupper($opts['position']);
// Set vertical position
if (strpos($opts['position'], 'T') !== false) {
// Top
$dest_x = $opts['marginX'];
} else if (strpos($opts['position'], 'M') !== false) {
// Middle
$dest_x = ($srcImgInfo[0] - $watermarkImgInfo[0]) / 2;
} else {
// Bottom
$dest_x = $srcImgInfo[0] - $watermarkImgInfo[0] - max($opts['marginBottom'], $opts['marginX']);
}
// Set horizontal position
if (strpos($opts['position'], 'L') !== false) {
// Left
$dest_y = $opts['marginY'];
} else if (strpos($opts['position'], 'C') !== false) {
// Middle
$dest_y = ($srcImgInfo[1] - $watermarkImgInfo[1]) / 2;
} else {
// Right
$dest_y = $srcImgInfo[1] - $watermarkImgInfo[1] - max($opts['marginRight'], $opts['marginY']);
}
// check interlace
$opts['interlace'] = ($opts['interlace'] & $imgTypes[$imageType]);
// Repeated use of Imagick::compositeImage() may cause PHP to hang, so disable it
//if (class_exists('Imagick', false)) {
// return $this->watermarkPrint_imagick($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $opts);
//} else {
elFinder::expandMemoryForGD(array($watermarkImgInfo, $srcImgInfo));
return $this->watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo, $opts);
//}
}
private function watermarkPrint_imagick($src, $watermarkSrc, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $opts)
{
try {
// Open the original image
$img = new Imagick($src);
// Open the watermark
$watermark = new Imagick($watermarkSrc);
// zoom
if ($opts['ratio']) {
$watermark->scaleImage($watermarkImgInfo[0], $watermarkImgInfo[1]);
}
// Set transparency
if (strtoupper($watermark->getImageFormat()) !== 'PNG') {
$watermark->setImageOpacity($transparency / 100);
}
// Overlay the watermark on the original image
$img->compositeImage($watermark, imagick::COMPOSITE_OVER, $dest_x, $dest_y);
// Set quality
if (strtoupper($img->getImageFormat()) === 'JPEG') {
$img->setImageCompression(imagick::COMPRESSION_JPEG);
$img->setCompressionQuality($quality);
}
// set interlace
$opts['interlace'] && $img->setInterlaceScheme(Imagick::INTERLACE_PLANE);
$result = $img->writeImage($src);
$img->clear();
$img->destroy();
$watermark->clear();
$watermark->destroy();
return $result ? true : false;
} catch (Exception $e) {
$ermsg = $e->getMessage();
$ermsg && trigger_error($ermsg);
return false;
}
}
private function watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo, $opts)
{
$watermark_width = $watermarkImgInfo[0];
$watermark_height = $watermarkImgInfo[1];
$ermsg = '';
switch ($watermarkImgInfo['mime']) {
case 'image/gif':
if (imagetypes() & IMG_GIF) {
$oWatermarkImg = imagecreatefromgif($watermark);
} else {
$ermsg = 'GIF images are not supported as watermark image';
}
break;
case 'image/jpeg':
if (imagetypes() & IMG_JPG) {
$oWatermarkImg = imagecreatefromjpeg($watermark);
} else {
$ermsg = 'JPEG images are not supported as watermark image';
}
break;
case 'image/png':
if (imagetypes() & IMG_PNG) {
$oWatermarkImg = imagecreatefrompng($watermark);
} else {
$ermsg = 'PNG images are not supported as watermark image';
}
break;
case 'image/wbmp':
if (imagetypes() & IMG_WBMP) {
$oWatermarkImg = imagecreatefromwbmp($watermark);
} else {
$ermsg = 'WBMP images are not supported as watermark image';
}
break;
default:
$oWatermarkImg = false;
$ermsg = $watermarkImgInfo['mime'] . ' images are not supported as watermark image';
break;
}
if (!$ermsg) {
// zoom
if ($opts['ratio']) {
$tmpImg = imagecreatetruecolor($watermarkImgInfo[0], $watermarkImgInfo[1]);
imagealphablending($tmpImg, false);
imagesavealpha($tmpImg, true);
imagecopyresampled($tmpImg, $oWatermarkImg, 0, 0, 0, 0, $watermarkImgInfo[0], $watermarkImgInfo[1], imagesx($oWatermarkImg), imagesy($oWatermarkImg));
imageDestroy($oWatermarkImg);
$oWatermarkImg = $tmpImg;
$tmpImg = null;
}
switch ($srcImgInfo['mime']) {
case 'image/gif':
if (imagetypes() & IMG_GIF) {
$oSrcImg = imagecreatefromgif($src);
} else {
$ermsg = 'GIF images are not supported as source image';
}
break;
case 'image/jpeg':
if (imagetypes() & IMG_JPG) {
$oSrcImg = imagecreatefromjpeg($src);
} else {
$ermsg = 'JPEG images are not supported as source image';
}
break;
case 'image/png':
if (imagetypes() & IMG_PNG) {
$oSrcImg = imagecreatefrompng($src);
} else {
$ermsg = 'PNG images are not supported as source image';
}
break;
case 'image/wbmp':
if (imagetypes() & IMG_WBMP) {
$oSrcImg = imagecreatefromwbmp($src);
} else {
$ermsg = 'WBMP images are not supported as source image';
}
break;
default:
$oSrcImg = false;
$ermsg = $srcImgInfo['mime'] . ' images are not supported as source image';
break;
}
}
if ($ermsg || false === $oSrcImg || false === $oWatermarkImg) {
$ermsg && trigger_error($ermsg);
return false;
}
if ($srcImgInfo['mime'] === 'image/png') {
if (function_exists('imagecolorallocatealpha')) {
$bg = imagecolorallocatealpha($oSrcImg, 255, 255, 255, 127);
imagefill($oSrcImg, 0, 0, $bg);
}
}
if ($watermarkImgInfo['mime'] === 'image/png') {
imagecopy($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);
} else {
imagecopymerge($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, $transparency);
}
// set interlace
$opts['interlace'] && imageinterlace($oSrcImg, true);
switch ($srcImgInfo['mime']) {
case 'image/gif':
imagegif($oSrcImg, $src);
break;
case 'image/jpeg':
imagejpeg($oSrcImg, $src, $quality);
break;
case 'image/png':
if (function_exists('imagesavealpha') && function_exists('imagealphablending')) {
imagealphablending($oSrcImg, false);
imagesavealpha($oSrcImg, true);
}
imagepng($oSrcImg, $src);
break;
case 'image/wbmp':
imagewbmp($oSrcImg, $src);
break;
}
imageDestroy($oSrcImg);
imageDestroy($oWatermarkImg);
return true;
}
}
Binary file not shown.
+73
View File
@@ -0,0 +1,73 @@
<?php
$game_settings = array(
'cores' => array(
'mcpe' => array(
'Genisys_v0.13.1' => array('corepath' => 'Genisys_v0.13.1', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.0', 'text_name' => 'Genisys v0.13.1 (PHP 7.0)'),
'Genisys_v0.14.3' => array('corepath' => 'Genisys_v0.14.3', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.0', 'text_name' => 'Genisys v0.14.3 (PHP 7.0)'),
'Genisys_v0.15.х' => array('corepath' => 'Genisys_v0.15.х', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.0', 'text_name' => 'Genisys v0.15.х (PHP 7.0)'),
'Genisys_v0.16' => array('corepath' => 'Genisys_v0.16', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.0', 'text_name' => 'Genisys v0.16 (PHP 7.0)'),
'Tesseract_v1.0.0-1.0.4' => array('corepath' => 'Tesseract_v1.0.0-1.0.4', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.0', 'text_name' => 'Tesseract v1.0.0-1.0.4 (PHP 7.0)'),
'Tesseract_v1.0.5-1.0.9' => array('corepath' => 'Tesseract_v1.0.5-1.0.9', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.0', 'text_name' => 'Tesseract v1.0.5-1.0.9 (PHP 7.0)'),
'SteadFast_v1.0-1.9' => array('corepath' => 'SteadFast_v1.0-1.9', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'SteadFast v1.0-1.9 (PHP 7.2)'),
'PMMP_v1.1' => array('corepath' => 'PMMP_v1.1', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.0', 'text_name' => 'PMMP v1.1 (PHP 7.0)'),
'Genisys_v1.1.0-1.1.5' => array('corepath' => 'Genisys_v1.1.0-1.1.5', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.0', 'text_name' => 'GenisysPro 1.1.0-1.1.5 (PHP 7.0)', 'continue_select' => 1),
'GenisysPro_v1.1.0-1.1.7' => array('corepath' => 'GenisysPro_v1.1.0-1.1.7', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.0', 'text_name' => 'GenisysPro 1.1.0-1.1.7 [FIX] (PHP 7.0)'),
'Prismarine_v1.1.0' => array('corepath' => 'Prismarine_v1.1.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'Prismarine v1.1.0 (PHP 7.2)'),
'Nukkit_v1.2' => array('corepath' => 'Nukkit_v1.2', 'corename' => 'nukkit.jar', 'corebinary' => 'Java', 'text_name' => 'Nukkit v1.1.2 (Java)'),
'Nukkit_v1.3' => array('corepath' => 'Nukkit_v1.3', 'corename' => 'nukkit.jar', 'corebinary' => 'Java', 'text_name' => 'Nukkit v1.1.3 (Java)'),
'PMMP_v1.4' => array('corepath' => 'PMMP_v1.4', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP v1.4 (PHP 7.2)'),
'PMMP_v1.5' => array('corepath' => 'PMMP_v1.5', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP v1.5 (PHP 7.2)'),
'PMMP_v1.6' => array('corepath' => 'PMMP_v1.6', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP v1.6 (PHP 7.2)'),
'PMMP_v1.7' => array('corepath' => 'PMMP_v1.7', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP v1.7 (PHP 7.2)'),
'PMMP_v1.8' => array('corepath' => 'PMMP_v1.8', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP v1.8 (PHP 7.2)'),
'PMMP-BE_v1.5.0' => array('corepath' => 'PMMP-BE_v1.5.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.5.0 (PHP 7.2)'),
'PMMP-BE_v1.6.0' => array('corepath' => 'PMMP-BE_v1.6.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.6.0 (PHP 7.2)'),
'PMMP-BE_v1.7.0' => array('corepath' => 'PMMP-BE_v1.7.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.7.0 (PHP 7.2)'),
'PMMP-BE_v1.8.0' => array('corepath' => 'PMMP-BE_v1.8.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.8.0 (PHP 7.2)'),
'PMMP-BE_v1.9.0' => array('corepath' => 'PMMP-BE_v1.9.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.9.0 (PHP 7.2)'),
'PMMP-BE_v1.10.0' => array('corepath' => 'PMMP-BE_v1.10.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.10.0 (PHP 7.2)'),
'PMMP-BE_v1.11.0' => array('corepath' => 'PMMP-BE_v1.11.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.11.0 (PHP 7.2)'),
'PMMP-BE_v1.12.0' => array('corepath' => 'PMMP-BE_v1.12.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.12.0 (PHP 7.2)'),
'PMMP-BE_v1.13.0' => array('corepath' => 'PMMP-BE_v1.13.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.13.0 (PHP 7.2)'),
'latest_core' => array('corepath' => 'PMMP-BE_v1.14.0', 'corename' => 'PocketMine-MP.phar', 'corebinary' => '7.2', 'text_name' => 'PMMP Bedrock Edition v1.14.0 (PHP 7.2)')
),
'mine' => array(
'craftbukkit_1.8' => array('corepath' => 'craftbukkit_1.8', 'corename' => 'minecraft.jar', 'corebinary' => 'Java', 'text_name' => 'CraftBukkit v1.8 (Java)'),
'craftbukkit_1.13.2' => array('corepath' => 'craftbukkit_1.13.2', 'corename' => 'minecraft.jar', 'corebinary' => 'Java', 'text_name' => 'CraftBukkit v1.13.2 (Java)'),
'spigot_1.7.10' => array('corepath' => 'spigot_1.7.10', 'corename' => 'minecraft.jar', 'corebinary' => 'Java', 'text_name' => 'Spigot v1.7.10 (Java)'),
'spigot_1.9.4' => array('corepath' => 'spigot_1.9.4', 'corename' => 'minecraft.jar', 'corebinary' => 'Java', 'text_name' => 'Spigot v1.9.4 (Java)'),
'spigot_1.16.1' => array('corepath' => 'spigot_1.16.1', 'corename' => 'minecraft.jar', 'corebinary' => 'Java', 'text_name' => 'Spigot v1.16.1 (Java)'),
'vanilla_1.7.10' => array('corepath' => 'vanilla_1.7.10', 'corename' => 'minecraft.jar', 'corebinary' => 'Java', 'text_name' => 'Vanilla v1.7.10 (Java)'),
'vanilla_1.15.1' => array('corepath' => 'vanilla_1.15.1', 'corename' => 'minecraft.jar', 'corebinary' => 'Java', 'text_name' => 'Vanilla v1.15.1 (Java)'),
'latest_core' => array('corepath' => 'craftbukkit_1.7.10', 'corename' => 'minecraft.jar', 'corebinary' => 'Java', 'text_name' => 'CraftBukkit v1.7.10 (Java)')
)
),
'builds' => array(
'cs' => array(
'5787' => array('buildpath' => '5787', 'text_name' => 'Build 5787'),
'ReHLDS' => array('buildpath' => 'ReHLDS', 'text_name' => 'ReHLDS'),
'latest_build' => array('buildpath' => 'steam', 'text_name' => 'Steam [Чистый сервер]')
)
),
'node_modules' => array(
'ragemp' => array(
'base64-js' => array('modulepath' => 'base64-js', 'module_name' => 'base64-js', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'base64-js.zip'),
'bignumber.js' => array('modulepath' => 'bignumber.js', 'module_name' => 'bignumber.js', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'bignumber.js.zip'),
'charenc' => array('modulepath' => 'charenc', 'module_name' => 'charenc', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'charenc.zip'),
'core-util-is' => array('modulepath' => 'core-util-is', 'module_name' => 'core-util-is', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'core-util-is.zip'),
'crypt' => array('modulepath' => 'crypt', 'module_name' => 'crypt', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'crypt.zip'),
'ieee754' => array('modulepath' => 'ieee754', 'module_name' => 'ieee754', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'ieee754.zip'),
'inherits' => array('modulepath' => 'inherits', 'module_name' => 'inherits', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'inherits.zip'),
'isarray' => array('modulepath' => 'isarray', 'module_name' => 'isarray', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'isarray.zip'),
'lodash' => array('modulepath' => 'lodash', 'module_name' => 'isarray', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'lodash.zip'),
'md5' => array('modulepath' => 'md5', 'module_name' => 'md5', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'md5.zip'),
'mysql' => array('modulepath' => 'mysql', 'module_name' => 'mysql', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'mysql.zip'),
'process-nextick-args' => array('modulepath' => 'process-nextick-args', 'module_name' => 'process-nextick-args', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'process-nextick-args.zip'),
'readable-stream' => array('modulepath' => 'readable-stream', 'module_name' => 'readable-stream', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'readable-stream.zip'),
'safe-buffer' => array('modulepath' => 'safe-buffer', 'module_name' => 'safe-buffer', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'safe-buffer.zip'),
'sqlstring' => array('modulepath' => 'sqlstring', 'module_name' => 'sqlstring', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'sqlstring.zip'),
'util-deprecate' => array('modulepath' => 'util-deprecate', 'module_name' => 'util-deprecate', 'moduleurl' => 'http://mc.hostinpl.ru/files/ragemp/node_modules/', 'modulearchive' => 'util-deprecate.zip')
)
)
);
?>
+406
View File
@@ -0,0 +1,406 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class SampRconAPI {
private $sock = null;
private $server = null;
private $port = null;
private $password = null;
/**
* Creates a new SampRcon object.
* @param $server hostname of the server
* @param $port port of the server
* @param $password rcon password for the server
*/
public function __construct($server, $port, $password) {
$this->server = $server;
$this->port = $port;
$this->password = $password;
}
/**
* Returns an array of rcon commands.
* @return Array
* (
* Array[0] => "echo"
* ...
* )
* ...
* @see getServerVariables()
*/
public function getCommandList() {
$commands = $this->rconSend('cmdlist');
foreach($commands as &$command) {
$command = trim($command);
}
return $commands;
}
/**
* Returns an array of server variables.
* @return Array[]
* (
* ['variableName'] = variableValue
* ...
* )
* @see getCommandList
*/
public function getServerVariables() {
$aVariables = $this->rconSend('varlist');
unset($aVariables[0]);
$aReturn = array();
foreach($aVariables as $sString) {
preg_match('/(.*)=[\s]+(.*)/', $sString, $aMatches);
if($aMatches[2][0] == '"') {
preg_match('/\"(.*)\"[\s]+\(/', $aMatches[2], $aTemp);
$aReturn[trim($aMatches[1])] = $aTemp[1];
} else {
preg_match('/(.*?)\s+\(/', $aMatches[2], $aTemp);
$aReturn[trim($aMatches[1])] = $aTemp[1];
}
}
return $aReturn;
}
/**
* Sets the server's current weather, if no weather ID is given 1 is used.
* @param $weatherID weather ID
*/
public function setWeather($weatherID=1) {
$this->rconSend("weather ".$weatherID, false);
}
/**
* Sets the server's current gravity, of mp gravity is given 0.008 is used.
* @param $gravity gravity double / float
*/
public function setGravity($gravity=0.008) {
$this->rconSend("gravity ".$gravity, false);
}
/**
* Ban a player from the server.
* @param $playerID player's ID
* @return Output from ban
*/
public function ban($playerID) {
return $this->rconSend("ban ".$playerID);
}
/**
* Kick a player from the server.
* @param $playerID player's ID
* @return Output from kick
*/
public function kick($playerID) {
return $this->rconSend("kick ".$playerID);
}
/**
* Ban an IP address from the server.
* @param $address IP address
* @return Output from ban
*/
public function banAddress($address) {
return $this->rconSend("banip ".$address);
}
/**
* Unban an IP address from the server.
* @param $address IP address
* @return Output from unban
*/
public function unbanAddress($address) {
return $this->rconSend("unbanip ".$address);
}
/**
* Reload the server's log file.
*/
public function reloadLog() {
return $this->rconSend("reloadlog");
}
/**
* Reload the server's bans file.
*/
public function reloadBans() {
return $this->rconSend("reloadbans");
}
/**
* Send an admin message to players on the server.
* @param $message message to send to players
*/
public function say($message) {
$this->rconSend("say ".$message, false);
}
/**
* Change the server's current gamemode.
* @param $gameMode game mode to change to
*/
public function changeGameMode($gameMode) {
$this->rconSend("changemode ".$gameMode, false);
}
/**
* Set the server's current displayed game mode text.
* @param $gameModeText game mode text to change to
*/
public function setGameModeText($gameModeText) {
$this->rconSend("gamemodetext ".$gameModeText, false);
}
/**
* Run the server's next gamemode (gmx).
*/
public function nextGameMode() {
$this->rconSend("gmx", false);
}
/**
* Run the server's next gamemode (gmx).
*/
public function gmx() {
$this->nextGamemode();
}
/**
* Execute config file.
* @param $config config file to execute
* @return Output from exec
*/
public function execConfig($config) {
return $this->rconSend("exec ".$config);
}
/**
* Load a filterscript.
* @param $fs filterscript to load
* @return Output from filterscript load
*/
public function loadFilterscript($fs) {
return $this->rconSend("loadfs ".$fs);
}
/**
* Unload a filterscript.
* @param $fs filterscript to unload
* @return Output from filterscript unload
*/
public function unloadFilterscript($fs) {
return $this->rconSend("unloadfs ".$fs);
}
/**
* Reload a filterscript.
* @param $fs filterscript to reload
* @return Output from filterscript reload
*/
public function reloadFilterscript($fs) {
return $this->rconSend("reloadfs ".$fs);
}
/**
* Shutdown the server.
*/
public function exitGame() {
$this->rconSend("exit", false);
}
/**
* Sets the server's host name.
* @param $hostName the host name to set the server to
*/
public function setHostName($hostName) {
$this->rconSend("hostname ".$hostName, false);
}
/**
* Sets the server's map name.
* @param $mapName the map name to set the server to
*/
public function setMapname($mapName) {
$this->rconSend("mapname ".$mapName, false);
}
/**
* Sets the server's time.
* Note: This will not change the weather relative to the time.
* @param $time the time to set the server to
*/
public function setTime($time) {
$this->rconSend("worldtime ".$time, false);
}
/**
* Sets the server's web url.
* @param $url the url to set the server to
*/
public function setURL($url) {
$this->rconSend("weburl ".$url, false);
}
/**
* Sets the server's password.
* @param $password the password to set the server to
*/
public function setPassword($password) {
$this->rconSend("password ".$password, false);
}
/**
* Remove the server's password.
*/
public function removePassword() {
$this->rconSend("password 0", false);
}
/**
* Sets the server's rcon password.
* @param $password the password the rcon password should be set to
*/
public function setRconPassword($password) {
$this->rconSend("rcon_password ".$password, false);
}
/**
* Disables remote rcon to the server.
*/
public function disableRcon() {
$this->rconSend("rcon 0", false);
}
/**
* Enables remote queries to the server.
*/
public function enableQuery() {
$this->rconSend("query 1", false);
}
/**
* Disables remote queries to the server.
*/
public function disableQuery() {
$this->rconSend("query 0", false);
}
/**
* Enables the server's announce.
*/
public function enableAnnounce() {
$this->rconSend("announce 1", false);
}
/**
* Disables the server's announce.
*/
public function disableAnnounce() {
$this->rconSend("announce 0", false);
}
/**
* Sets the server's max number of NPCs.
* @param $maxNPCs the maximum numbers of NPCs
*/
public function setMaxNPCs($maxNPCs) {
$this->rconSend("maxnpc ".$maxNPCs, false);
}
/**
* Execute an rcon command.
* @param $command command to execute
* @param $delay delay time, if you don't expect any data back set this to false
* @return Output from command
*/
public function call($command, $delay=1.0) {
return $this->rconSend($command, $delay);
}
private function rconSend($command, $delay=1.0) {
fwrite($this->sock, $this->assemblePacket($command));
if ($delay === false) {
return;
}
$result = array();
$iMicrotime = microtime(true) + $delay;
while (microtime(true) < $iMicrotime) {
$temp = substr(fread($this->sock, 128), 13);
if (strlen($temp)) {
$result[] = $temp;
} else {
break;
}
}
return $result;
}
private function assemblePacket($command) {
$sPacket = "SAMP";
$sPacket .= chr(strtok($this->server, "."));
$sPacket .= chr(strtok("."));
$sPacket .= chr(strtok("."));
$sPacket .= chr(strtok("."));
$sPacket .= chr($this->port & 0xFF);
$sPacket .= chr($this->port >> 8 & 0xFF);
$sPacket .= "x";
$sPacket .= chr(strlen($this->password) & 0xFF);
$sPacket .= chr(strlen($this->password) >> 8 & 0xFF);
$sPacket .= $this->password;
$sPacket .= chr(strlen($command) & 0xFF);
$sPacket .= chr(strlen($command) >> 8 & 0xFF);
$sPacket .= $command;
return $sPacket;
}
/**
* Attempts to connect to the server and returns whether it was successful.
* @return boolean
*/
public function connect() {
$connected = false;
$packet = "SAMP";
$packet .= chr(strtok($this->server, "."));
$packet .= chr(strtok("."));
$packet .= chr(strtok("."));
$packet .= chr(strtok("."));
$packet .= chr($this->port & 0xFF);
$packet .= chr($this->port >> 8 & 0xFF);
$packet .= "p0101";
$this->sock = fsockopen("udp://".$this->server, $this->port, $errorNum, $errorString, 2);
socket_set_timeout($this->sock, 2);
fwrite($this->sock, $packet);
if(fread($this->sock, 10)) {
if(fread($this->sock, 5) == 'p0101') {
$connected = true;
}
}
return $connected;
}
/**
* Closes the connection
*/
public function close() {
@fclose($this->sock);
}
}
+71
View File
@@ -0,0 +1,71 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class mailLibrary {
protected $to;
protected $from;
protected $sender;
protected $subject;
protected $text;
public function setTo($to) {
$this->to = $to;
}
public function setFrom($from) {
$this->from = $from;
}
public function setSender($sender) {
$this->sender = $sender;
}
public function setSubject($subject) {
$this->subject = $subject;
}
public function setText($text) {
$this->text = $text;
}
public function send() {
if (!$this->to) {
exit("Ошибка: Не указан E-Mail получателя!");
}
if (!$this->from) {
exit("Ошибка: Не указан E-Mail отправителя!");
}
if (!$this->sender) {
exit("Ошибка: Не указано имя отправителя!");
}
if (!$this->subject) {
exit("Ошибка: Не указана тема сообщения!");
}
if (!$this->text) {
exit("Ошибка: Не указан текст сообщения!");
}
if (is_array($this->to)) {
$this->to = implode(',', $this->to);
}
$header = "";
$header .= "MIME-Version: 1.0\n";
$header .= "From: " . $this->sender . "<" . $this->from . ">\n";
$header .= "Reply-To: " . $this->sender . "\n";
$header .= "X-Mailer: HOSTINPL 5.6 Mailer\n";
$header .= "Return-Path: " . $this->sender . "\n";
$header .= "Content-Type: text/html; charset=\"utf-8\"\n";
return mail($this->to, $this->subject, $this->text, $header);
}
}
?>
+81
View File
@@ -0,0 +1,81 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class paginationLibrary {
public $total = 0;
public $page = 1;
public $limit = 20;
public $num_links = 10;
public $url = '';
public $text_next = '<i class="ki ki-bold-arrow-next icon-xs"></i>';
public $text_prev = '<i class="ki ki-bold-arrow-back icon-xs"></i>';
public function render() {
$total = $this->total;
if ($this->page < 1) {
$page = 1;
} else {
$page = $this->page;
}
if (!(int)$this->limit) {
$limit = 10;
} else {
$limit = $this->limit;
}
$num_links = $this->num_links;
$num_pages = ceil($total / $limit);
$output = '';
if ($page > 1) {
$output .= '<a class="btn btn-icon btn-sm btn-light mr-2 my-1" href="' . str_replace('{page}', $page - 1, $this->url) . '">' . $this->text_prev . '</a>';
}
if ($num_pages > 1) {
if ($num_pages <= $num_links) {
$start = 1;
$end = $num_pages;
} else {
$start = $page - floor($num_links / 2);
$end = $page + floor($num_links / 2);
if ($start < 1) {
$end += abs($start) + 1;
$start = 1;
}
if ($end > $num_pages) {
$start -= ($end - $num_pages);
$end = $num_pages;
}
}
if ($start > 1) {
$output .= '<li class="btn btn-icon btn-sm border-0 btn-light mr-2 my-1"><a href="javascript:;">...</a></li>';
}
for ($i = $start; $i <= $end; $i++) {
if ($page == $i) {
$output .= '<a class="btn btn-icon btn-sm border-0 btn-light btn-hover-primary active mr-2 my-1" href="javascript:;">' . $i . '</a>';
} else {
$output .= '<a class="btn btn-icon btn-sm btn-light mr-2 my-1" href="' . str_replace('{page}', $i, $this->url) . '">' . $i . '</a>';
}
}
if ($end < $num_pages) {
$output .= '<a class="btn btn-icon btn-sm border-0 btn-light mr-2 my-1" href="javascript:;">...</a>';
}
}
if ($page < $num_pages) {
$output .= '<a class="btn btn-icon btn-sm btn-light mr-2 my-1" href="' . str_replace('{page}', $page + 1, $this->url) . '">' . $this->text_next . '</a>';
}
return $output ? '<div class="d-flex justify-content-between align-items-center flex-wrap"><div class="d-flex flex-wrap py-2 mr-3">' . $output . '</div></div>' : '';
}
}
?>
+36
View File
@@ -0,0 +1,36 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class queryLibrary {
private $driver;
public function __construct($driver) {
$class = $driver . 'Query';
if(is_readable(ENGINE_DIR . 'libs/query/base.php')) {
require_once(ENGINE_DIR . 'libs/query/base.php');
} else {
exit('Ошибка: Не удалось загрузить базовый query-драйвер!');
}
if(is_readable(ENGINE_DIR . 'libs/query/' . $driver . '.driver.php')) {
require_once(ENGINE_DIR . 'libs/query/' . $driver . '.driver.php');
} else {
exit('Ошибка: Не удалось загрузить query-драйвер ' . $driver . '!');
}
$this->driver = new $class();
}
public function connect($ip, $port) {
return $this->driver->connect($ip, $port);
}
public function disconnect() {
return $this->driver->disconnect();
}
public function getInfo() {
return $this->driver->getInfo();
}
}
?>
+37
View File
@@ -0,0 +1,37 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class QueryBase {
protected $ip;
protected $port;
protected $socket;
protected function write($bytes) {
return fwrite($this->socket, $bytes);
}
protected function readInt8() {
return ord($this->read(1));
}
protected function readInt16() {
$int = unpack('Sint', $this->read(2));
return $int['int'];
}
protected function readString() {
$string = null;
while(($char = $this->read(1)) != "\x00") {
$string .= $char;
}
return $string;
}
protected function read($len) {
return fread($this->socket, $len);
}
}
?>
File diff suppressed because it is too large Load Diff
+51
View File
@@ -0,0 +1,51 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class mineQuery extends QueryBase {
public function connect($ip, $port) {
$this->ip = $ip;
$this->port = $port;
}
public function disconnect() {
}
private function sendPacket() {
}
public function getInfo() {
require_once 'lgsl/lgsl_protocol.php';
ini_set('default_socket_timeout', '10');
$server = lgsl_query_live('minecraft', $this->ip, $this->port, $this->port, $this->port, 'sep');
if(empty($server['s']['name'])) {
$data['hostname'] = 'Нет данных';
} else {
$data['hostname'] = $server['s']['name'];
}
if(empty($server['s']['map'])) {
$data['mapname'] = 'Нет данных';
} else {
$data['mapname'] = $server['s']['map'];
}
if(empty($server['s']['game'])) {
$data['gamemode'] = 'Нет данных';
} else {
$data['gamemode'] = $server['s']['game'];
}
if(empty($server['s']['players'])) {
$data['players'] = '0';
} else {
$data['players'] = $server['s']['players'];
}
if(empty($server['s']['playersmax'])) {
$data['maxplayers'] = '0';
} else {
$data['maxplayers'] = $server['s']['playersmax'];
}
return $data;
}
}
?>
+50
View File
@@ -0,0 +1,50 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class mtasaQuery extends QueryBase {
public function connect($ip, $port) {
$this->ip = $ip;
$this->port = $port;
}
public function disconnect() {
}
private function sendPacket() {
}
public function getInfo() {
require_once 'lgsl/lgsl_protocol.php';
ini_set('default_socket_timeout', '10');
$server = lgsl_query_live('mta', $this->ip, $this->port, $this->port + 123, $this->port, 'sep');
if(empty($server['s']['name'])) {
$data['hostname'] = 'Нет данных';
} else {
$data['hostname'] = htmlspecialchars(mb_convert_encoding($server['s']['name'], 'UTF-8', 'WINDOWS-1251'));
}
if(empty($server['s']['map'])) {
$data['mapname'] = 'Нет данных';
} else {
$data['mapname'] = htmlspecialchars(mb_convert_encoding($server['s']['map'], 'UTF-8', 'WINDOWS-1251'));
}
if(empty($server['e']['gamemode'])) {
$data['gamemode'] = 'Нет данных';
} else {
$data['gamemode'] = htmlspecialchars(mb_convert_encoding($server['e']['gamemode'], 'UTF-8', 'WINDOWS-1251'));
}
if(empty($server['s']['players'])) {
$data['players'] = '0';
} else {
$data['players'] = $server['s']['players'];
}
if(empty($server['s']['playersmax'])) {
$data['maxplayers'] = '0';
} else {
$data['maxplayers'] = $server['s']['playersmax'];
}
return $data;
}
}
?>
+50
View File
@@ -0,0 +1,50 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class ragempQuery extends QueryBase {
public function connect($ip, $port) {
$this->ip = $ip;
$this->port = $port;
}
public function disconnect() {
}
private function sendPacket() {
}
public function getInfo() {
require_once 'lgsl/lgsl_protocol.php';
ini_set('default_socket_timeout', '10');
$server = lgsl_query_live('ragemp', $this->ip, $this->port, $this->port, $this->port, 'sep');
if(empty($server['s']['name'])) {
$data['hostname'] = 'Нет данных';
} else {
$data['hostname'] = $server['s']['name'];
}
if(empty($server['e']['gamemode'])) {
$data['gamemode'] = 'Нет данных';
} else {
$data['gamemode'] = $server['e']['gamemode'];
}
if(empty($server['s']['map'])) {
$data['mapname'] = 'Нет данных';
} else {
$data['mapname'] = $server['s']['map'];
}
if(empty($server['s']['players'])) {
$data['players'] = '0';
} else {
$data['players'] = $server['s']['players'];
}
if(empty($server['s']['playersmax'])) {
$data['maxplayers'] = '0';
} else {
$data['maxplayers'] = $server['s']['playersmax'];
}
return $data;
}
}
?>
+50
View File
@@ -0,0 +1,50 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class sampQuery extends QueryBase {
public function connect($ip, $port) {
$this->ip = $ip;
$this->port = $port;
}
public function disconnect() {
}
private function sendPacket() {
}
public function getInfo() {
require_once 'lgsl/lgsl_protocol.php';
ini_set('default_socket_timeout', '10');
$server = lgsl_query_live('samp', $this->ip, $this->port, $this->port, $this->port, 'sep');
if(empty($server['s']['name'])) {
$data['hostname'] = 'Нет данных';
} else {
$data['hostname'] = htmlspecialchars(mb_convert_encoding($server['s']['name'], 'UTF-8', 'WINDOWS-1251'));
}
if(empty($server['s']['map'])) {
$data['mapname'] = 'Нет данных';
} else {
$data['mapname'] = htmlspecialchars(mb_convert_encoding($server['s']['map'], 'UTF-8', 'WINDOWS-1251'));
}
if(empty($server['e']['gamemode'])) {
$data['gamemode'] = 'Нет данных';
} else {
$data['gamemode'] = htmlspecialchars(mb_convert_encoding($server['e']['gamemode'], 'UTF-8', 'WINDOWS-1251'));
}
if(empty($server['s']['players'])) {
$data['players'] = '0';
} else {
$data['players'] = $server['s']['players'];
}
if(empty($server['s']['playersmax'])) {
$data['maxplayers'] = '0';
} else {
$data['maxplayers'] = $server['s']['playersmax'];
}
return $data;
}
}
?>
+50
View File
@@ -0,0 +1,50 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class valveQuery extends QueryBase {
public function connect($ip, $port) {
$this->ip = $ip;
$this->port = $port;
}
public function disconnect() {
}
private function sendPacket() {
}
public function getInfo() {
require_once 'lgsl/lgsl_protocol.php';
ini_set('default_socket_timeout', '10');
$server = lgsl_query_live('source', $this->ip, $this->port, $this->port, $this->port, 'sep');
if(empty($server['s']['name'])) {
$data['hostname'] = 'Нет данных';
} else {
$data['hostname'] = $server['s']['name'];
}
if(empty($server['s']['map'])) {
$data['mapname'] = 'Нет данных';
} else {
$data['mapname'] = $server['s']['map'];
}
if(empty($server['e']['description'])) {
$data['gamemode'] = 'Нет данных';
} else {
$data['gamemode'] = $server['e']['description'];
}
if(empty($server['s']['players'])) {
$data['players'] = '0';
} else {
$data['players'] = $server['s']['players'];
}
if(empty($server['s']['playersmax'])) {
$data['maxplayers'] = '0';
} else {
$data['maxplayers'] = $server['s']['playersmax'];
}
return $data;
}
}
?>
+196
View File
@@ -0,0 +1,196 @@
<?php
/**
* Pure-PHP implementation of AES.
*
* Uses mcrypt, if available/possible, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
* just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
* to save one include_once().
*
* If {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
* {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
* it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
* is called, again, at which point, it'll be recalculated.
*
* Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
* make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function,
* however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/AES.php';
*
* $aes = new Crypt_AES();
*
* $aes->setKey('abcdefghijklmnop');
*
* $size = 10 * 1024;
* $plaintext = '';
* for ($i = 0; $i < $size; $i++) {
* $plaintext.= 'a';
* }
*
* echo $aes->decrypt($aes->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_AES
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2008 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Rijndael
*/
if (!class_exists('Crypt_Rijndael')) {
include_once 'Rijndael.php';
}
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_AES_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_AES_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_AES_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**
* Pure-PHP implementation of AES.
*
* @package Crypt_AES
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Crypt_AES extends Crypt_Rijndael
{
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'AES';
/**
* Dummy function
*
* Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
*
* @see Crypt_Rijndael::setBlockLength()
* @access public
* @param int $length
*/
function setBlockLength($length)
{
return;
}
/**
* Sets the key length
*
* Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
*
* @see Crypt_Rijndael:setKeyLength()
* @access public
* @param int $length
*/
function setKeyLength($length)
{
switch ($length) {
case 160:
$length = 192;
break;
case 224:
$length = 256;
}
parent::setKeyLength($length);
}
/**
* Sets the key.
*
* Rijndael supports five different key lengths, AES only supports three.
*
* @see Crypt_Rijndael:setKey()
* @see setKeyLength()
* @access public
* @param string $key
*/
function setKey($key)
{
parent::setKey($key);
if (!$this->explicit_key_length) {
$length = strlen($key);
switch (true) {
case $length <= 16:
$this->key_length = 16;
break;
case $length <= 24:
$this->key_length = 24;
break;
default:
$this->key_length = 32;
}
$this->_setEngine();
}
}
}
File diff suppressed because it is too large Load Diff
+644
View File
@@ -0,0 +1,644 @@
<?php
/**
* Pure-PHP implementation of Blowfish.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://en.wikipedia.org/wiki/Blowfish_(cipher) Wikipedia description of Blowfish}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/Blowfish.php';
*
* $blowfish = new Crypt_Blowfish();
*
* $blowfish->setKey('12345678901234567890123456789012');
*
* $plaintext = str_repeat('a', 1024);
*
* echo $blowfish->decrypt($blowfish->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Blowfish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_BLOWFISH_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_BLOWFISH_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_BLOWFISH_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_BLOWFISH_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**
* Pure-PHP implementation of Blowfish.
*
* @package Crypt_Blowfish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @access public
*/
class Crypt_Blowfish extends Crypt_Base
{
/**
* Block Length of the cipher
*
* @see Crypt_Base::block_size
* @var int
* @access private
*/
var $block_size = 8;
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'BLOWFISH';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var string
* @access private
*/
var $cipher_name_mcrypt = 'blowfish';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var int
* @access private
*/
var $cfb_init_len = 500;
/**
* The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
*
* S-Box 0
*
* @access private
* @var array
*/
var $sbox0 = array(
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
);
/**
* S-Box 1
*
* @access private
* @var array
*/
var $sbox1 = array(
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
);
/**
* S-Box 2
*
* @access private
* @var array
*/
var $sbox2 = array(
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
);
/**
* S-Box 3
*
* @access private
* @var array
*/
var $sbox3 = array(
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
);
/**
* P-Array consists of 18 32-bit subkeys
*
* @var array
* @access private
*/
var $parray = array(
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
);
/**
* The BCTX-working Array
*
* Holds the expanded key [p] and the key-depended s-boxes [sb]
*
* @var array
* @access private
*/
var $bctx;
/**
* Holds the last used key
*
* @var array
* @access private
*/
var $kl;
/**
* The Key Length (in bytes)
*
* @see Crypt_Base::setKeyLength()
* @var int
* @access private
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
* because the encryption / decryption / key schedule creation requires this number and not $key_length. We could
* derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
* of that, we'll just precompute it once.
*/
var $key_length = 16;
/**
* Sets the key length.
*
* Key lengths can be between 32 and 448 bits.
*
* @access public
* @param int $length
*/
function setKeyLength($length)
{
if ($length < 32) {
$this->key_length = 4;
} elseif ($length > 448) {
$this->key_length = 56;
} else {
$this->key_length = $length >> 3;
}
parent::setKeyLength($length);
}
/**
* Test for engine validity
*
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
*
* @see Crypt_Base::isValidEngine()
* @param int $engine
* @access public
* @return bool
*/
function isValidEngine($engine)
{
if ($engine == CRYPT_ENGINE_OPENSSL) {
if (version_compare(PHP_VERSION, '5.3.7') < 0 && $this->key_length != 16) {
return false;
}
if ($this->key_length < 16) {
return false;
}
$this->cipher_name_openssl_ecb = 'bf-ecb';
$this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode();
}
return parent::isValidEngine($engine);
}
/**
* Setup the key (expansion)
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
// already expanded
return;
}
$this->kl = array('key' => $this->key);
/* key-expanding p[] and S-Box building sb[] */
$this->bctx = array(
'p' => array(),
'sb' => array(
$this->sbox0,
$this->sbox1,
$this->sbox2,
$this->sbox3
)
);
// unpack binary string in unsigned chars
$key = array_values(unpack('C*', $this->key));
$keyl = count($key);
for ($j = 0, $i = 0; $i < 18; ++$i) {
// xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
for ($data = 0, $k = 0; $k < 4; ++$k) {
$data = ($data << 8) | $key[$j];
if (++$j >= $keyl) {
$j = 0;
}
}
$this->bctx['p'][] = $this->parray[$i] ^ $data;
}
// encrypt the zero-string, replace P1 and P2 with the encrypted data,
// encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
$data = "\0\0\0\0\0\0\0\0";
for ($i = 0; $i < 18; $i += 2) {
list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
$this->bctx['p'][$i ] = $l;
$this->bctx['p'][$i + 1] = $r;
}
for ($i = 0; $i < 4; ++$i) {
for ($j = 0; $j < 256; $j += 2) {
list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
$this->bctx['sb'][$i][$j ] = $l;
$this->bctx['sb'][$i][$j + 1] = $r;
}
}
}
/**
* Encrypts a block
*
* @access private
* @param string $in
* @return string
*/
function _encryptBlock($in)
{
$p = $this->bctx["p"];
// extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower
$sb_0 = $this->bctx["sb"][0];
$sb_1 = $this->bctx["sb"][1];
$sb_2 = $this->bctx["sb"][2];
$sb_3 = $this->bctx["sb"][3];
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
for ($i = 0; $i < 16; $i+= 2) {
$l^= $p[$i];
$r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff]);
$r^= $p[$i + 1];
$l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff]);
}
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
}
/**
* Decrypts a block
*
* @access private
* @param string $in
* @return string
*/
function _decryptBlock($in)
{
$p = $this->bctx["p"];
$sb_0 = $this->bctx["sb"][0];
$sb_1 = $this->bctx["sb"][1];
$sb_2 = $this->bctx["sb"][2];
$sb_3 = $this->bctx["sb"][3];
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
for ($i = 17; $i > 2; $i-= 2) {
$l^= $p[$i];
$r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff]);
$r^= $p[$i - 1];
$l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff]);
}
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
}
/**
* Setup the performance-optimized function for de/encrypt()
*
* @see Crypt_Base::_setupInlineCrypt()
* @access private
*/
function _setupInlineCrypt()
{
$lambda_functions =& Crypt_Blowfish::_getLambdaFunctions();
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
// (Currently, for Crypt_Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
// Generation of a unique hash for our generated code
$code_hash = "Crypt_Blowfish, {$this->mode}";
if ($gen_hi_opt_code) {
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
}
$safeint = $this->safe_intval_inline();
if (!isset($lambda_functions[$code_hash])) {
switch (true) {
case $gen_hi_opt_code:
$p = $this->bctx['p'];
$init_crypt = '
static $sb_0, $sb_1, $sb_2, $sb_3;
if (!$sb_0) {
$sb_0 = $self->bctx["sb"][0];
$sb_1 = $self->bctx["sb"][1];
$sb_2 = $self->bctx["sb"][2];
$sb_3 = $self->bctx["sb"][3];
}
';
break;
default:
$p = array();
for ($i = 0; $i < 18; ++$i) {
$p[] = '$p_' . $i;
}
$init_crypt = '
list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"];
list(' . implode(',', $p) . ') = $self->bctx["p"];
';
}
// Generating encrypt code:
$encrypt_block = '
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
';
for ($i = 0; $i < 16; $i+= 2) {
$encrypt_block.= '
$l^= ' . $p[$i] . ';
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff]') . ';
$r^= ' . $p[$i + 1] . ';
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff]') . ';
';
}
$encrypt_block.= '
$in = pack("N*",
$r ^ ' . $p[17] . ',
$l ^ ' . $p[16] . '
);
';
// Generating decrypt code:
$decrypt_block = '
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
';
for ($i = 17; $i > 2; $i-= 2) {
$decrypt_block.= '
$l^= ' . $p[$i] . ';
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff]') . ';
$r^= ' . $p[$i - 1] . ';
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff]') . ';
';
}
$decrypt_block.= '
$in = pack("N*",
$r ^ ' . $p[0] . ',
$l ^ ' . $p[1] . '
);
';
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
'init_crypt' => $init_crypt,
'init_encrypt' => '',
'init_decrypt' => '',
'encrypt_block' => $encrypt_block,
'decrypt_block' => $decrypt_block
)
);
}
$this->inline_crypt = $lambda_functions[$code_hash];
}
}
File diff suppressed because it is too large Load Diff
+929
View File
@@ -0,0 +1,929 @@
<?php
/**
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
*
* Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
*
* md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
*
* If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to
* the hash. If no valid algorithm is provided, sha1 will be used.
*
* PHP versions 4 and 5
*
* {@internal The variable names are the same as those in
* {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/Hash.php';
*
* $hash = new Crypt_Hash('sha1');
*
* $hash->setKey('abcdefg');
*
* echo base64_encode($hash->hash('abcdefg'));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Hash
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**#@+
* @access private
* @see self::Crypt_Hash()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_HASH_MODE_INTERNAL', 1);
/**
* Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
*/
define('CRYPT_HASH_MODE_MHASH', 2);
/**
* Toggles the hash() implementation, which works on PHP 5.1.2+.
*/
define('CRYPT_HASH_MODE_HASH', 3);
/**#@-*/
/**
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
*
* @package Crypt_Hash
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Crypt_Hash
{
/**
* Hash Parameter
*
* @see self::setHash()
* @var int
* @access private
*/
var $hashParam;
/**
* Byte-length of compression blocks / key (Internal HMAC)
*
* @see self::setAlgorithm()
* @var int
* @access private
*/
var $b;
/**
* Byte-length of hash output (Internal HMAC)
*
* @see self::setHash()
* @var int
* @access private
*/
var $l = false;
/**
* Hash Algorithm
*
* @see self::setHash()
* @var string
* @access private
*/
var $hash;
/**
* Key
*
* @see self::setKey()
* @var string
* @access private
*/
var $key = false;
/**
* Computed Key
*
* @see self::_computeKey()
* @var string
* @access private
*/
var $computedKey = false;
/**
* Outer XOR (Internal HMAC)
*
* @see self::setKey()
* @var string
* @access private
*/
var $opad;
/**
* Inner XOR (Internal HMAC)
*
* @see self::setKey()
* @var string
* @access private
*/
var $ipad;
/**
* Engine
*
* @see self::setHash()
* @var string
* @access private
*/
var $engine;
/**
* Default Constructor.
*
* @param string $hash
* @return Crypt_Hash
* @access public
*/
function __construct($hash = 'sha1')
{
if (!defined('CRYPT_HASH_MODE')) {
switch (true) {
case extension_loaded('hash'):
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
break;
case extension_loaded('mhash'):
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
break;
default:
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
}
}
$this->setHash($hash);
}
/**
* PHP4 compatible Default Constructor.
*
* @see self::__construct()
* @param int $mode
* @access public
*/
function Crypt_Hash($hash = 'sha1')
{
$this->__construct($hash);
}
/**
* Sets the key for HMACs
*
* Keys can be of any length.
*
* @access public
* @param string $key
*/
function setKey($key = false)
{
$this->key = $key;
$this->_computeKey();
}
/**
* Pre-compute the key used by the HMAC
*
* Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
* will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
*
* As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
* when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
* every call
*
* @access private
*/
function _computeKey()
{
if ($this->key === false) {
$this->computedKey = false;
return;
}
if (strlen($this->key) <= $this->b) {
$this->computedKey = $this->key;
return;
}
switch ($this->engine) {
case CRYPT_HASH_MODE_MHASH:
$this->computedKey = mhash($this->hash, $this->key);
break;
case CRYPT_HASH_MODE_HASH:
$this->computedKey = hash($this->hash, $this->key, true);
break;
case CRYPT_HASH_MODE_INTERNAL:
$this->computedKey = call_user_func($this->hash, $this->key);
}
}
/**
* Gets the hash function.
*
* As set by the constructor or by the setHash() method.
*
* @access public
* @return string
*/
function getHash()
{
return $this->hashParam;
}
/**
* Sets the hash function.
*
* @access public
* @param string $hash
*/
function setHash($hash)
{
$this->hashParam = $hash = strtolower($hash);
switch ($hash) {
case 'md5-96':
case 'sha1-96':
case 'sha256-96':
case 'sha512-96':
$hash = substr($hash, 0, -3);
$this->l = 12; // 96 / 8 = 12
break;
case 'md2':
case 'md5':
$this->l = 16;
break;
case 'sha1':
$this->l = 20;
break;
case 'sha256':
$this->l = 32;
break;
case 'sha384':
$this->l = 48;
break;
case 'sha512':
$this->l = 64;
}
switch ($hash) {
case 'md2-96':
case 'md2':
$this->b = 16;
case 'md5-96':
case 'sha1-96':
case 'sha224-96':
case 'sha256-96':
case 'md2':
case 'md5':
case 'sha1':
case 'sha224':
case 'sha256':
$this->b = 64;
break;
default:
$this->b = 128;
}
switch ($hash) {
case 'md2':
$this->engine = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
break;
case 'sha384':
case 'sha512':
$this->engine = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
break;
default:
$this->engine = CRYPT_HASH_MODE;
}
switch ($this->engine) {
case CRYPT_HASH_MODE_MHASH:
switch ($hash) {
case 'md5':
$this->hash = MHASH_MD5;
break;
case 'sha256':
$this->hash = MHASH_SHA256;
break;
case 'sha1':
default:
$this->hash = MHASH_SHA1;
}
$this->_computeKey();
return;
case CRYPT_HASH_MODE_HASH:
switch ($hash) {
case 'md5':
$this->hash = 'md5';
return;
case 'md2':
case 'sha256':
case 'sha384':
case 'sha512':
$this->hash = $hash;
return;
case 'sha1':
default:
$this->hash = 'sha1';
}
$this->_computeKey();
return;
}
switch ($hash) {
case 'md2':
$this->hash = array($this, '_md2');
break;
case 'md5':
$this->hash = array($this, '_md5');
break;
case 'sha256':
$this->hash = array($this, '_sha256');
break;
case 'sha384':
case 'sha512':
$this->hash = array($this, '_sha512');
break;
case 'sha1':
default:
$this->hash = array($this, '_sha1');
}
$this->ipad = str_repeat(chr(0x36), $this->b);
$this->opad = str_repeat(chr(0x5C), $this->b);
$this->_computeKey();
}
/**
* Compute the HMAC.
*
* @access public
* @param string $text
* @return string
*/
function hash($text)
{
if (!empty($this->key) || is_string($this->key)) {
switch ($this->engine) {
case CRYPT_HASH_MODE_MHASH:
$output = mhash($this->hash, $text, $this->computedKey);
break;
case CRYPT_HASH_MODE_HASH:
$output = hash_hmac($this->hash, $text, $this->computedKey, true);
break;
case CRYPT_HASH_MODE_INTERNAL:
$key = str_pad($this->computedKey, $this->b, chr(0)); // step 1
$temp = $this->ipad ^ $key; // step 2
$temp .= $text; // step 3
$temp = call_user_func($this->hash, $temp); // step 4
$output = $this->opad ^ $key; // step 5
$output.= $temp; // step 6
$output = call_user_func($this->hash, $output); // step 7
}
} else {
switch ($this->engine) {
case CRYPT_HASH_MODE_MHASH:
$output = mhash($this->hash, $text);
break;
case CRYPT_HASH_MODE_HASH:
$output = hash($this->hash, $text, true);
break;
case CRYPT_HASH_MODE_INTERNAL:
$output = call_user_func($this->hash, $text);
}
}
return substr($output, 0, $this->l);
}
/**
* Returns the hash length (in bytes)
*
* @access public
* @return int
*/
function getLength()
{
return $this->l;
}
/**
* Wrapper for MD5
*
* @access private
* @param string $m
*/
function _md5($m)
{
return pack('H*', md5($m));
}
/**
* Wrapper for SHA1
*
* @access private
* @param string $m
*/
function _sha1($m)
{
return pack('H*', sha1($m));
}
/**
* Pure-PHP implementation of MD2
*
* See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
*
* @access private
* @param string $m
*/
function _md2($m)
{
static $s = array(
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
);
// Step 1. Append Padding Bytes
$pad = 16 - (strlen($m) & 0xF);
$m.= str_repeat(chr($pad), $pad);
$length = strlen($m);
// Step 2. Append Checksum
$c = str_repeat(chr(0), 16);
$l = chr(0);
for ($i = 0; $i < $length; $i+= 16) {
for ($j = 0; $j < 16; $j++) {
// RFC1319 incorrectly states that C[j] should be set to S[c xor L]
//$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
// per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
$c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
$l = $c[$j];
}
}
$m.= $c;
$length+= 16;
// Step 3. Initialize MD Buffer
$x = str_repeat(chr(0), 48);
// Step 4. Process Message in 16-Byte Blocks
for ($i = 0; $i < $length; $i+= 16) {
for ($j = 0; $j < 16; $j++) {
$x[$j + 16] = $m[$i + $j];
$x[$j + 32] = $x[$j + 16] ^ $x[$j];
}
$t = chr(0);
for ($j = 0; $j < 18; $j++) {
for ($k = 0; $k < 48; $k++) {
$x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
//$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
}
$t = chr(ord($t) + $j);
}
}
// Step 5. Output
return substr($x, 0, 16);
}
/**
* Pure-PHP implementation of SHA256
*
* See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
*
* @access private
* @param string $m
*/
function _sha256($m)
{
if (extension_loaded('suhosin')) {
return pack('H*', sha256($m));
}
// Initialize variables
$hash = array(
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
);
// Initialize table of round constants
// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
static $k = array(
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
);
// Pre-processing
$length = strlen($m);
// to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
$m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
$m[$length] = chr(0x80);
// we don't support hashing strings 512MB long
$m.= pack('N2', 0, $length << 3);
// Process the message in successive 512-bit chunks
$chunks = str_split($m, 64);
foreach ($chunks as $chunk) {
$w = array();
for ($i = 0; $i < 16; $i++) {
extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
$w[] = $temp;
}
// Extend the sixteen 32-bit words into sixty-four 32-bit words
for ($i = 16; $i < 64; $i++) {
// @codingStandardsIgnoreStart
$s0 = $this->_rightRotate($w[$i - 15], 7) ^
$this->_rightRotate($w[$i - 15], 18) ^
$this->_rightShift( $w[$i - 15], 3);
$s1 = $this->_rightRotate($w[$i - 2], 17) ^
$this->_rightRotate($w[$i - 2], 19) ^
$this->_rightShift( $w[$i - 2], 10);
// @codingStandardsIgnoreEnd
$w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
}
// Initialize hash value for this chunk
list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
// Main loop
for ($i = 0; $i < 64; $i++) {
$s0 = $this->_rightRotate($a, 2) ^
$this->_rightRotate($a, 13) ^
$this->_rightRotate($a, 22);
$maj = ($a & $b) ^
($a & $c) ^
($b & $c);
$t2 = $this->_add($s0, $maj);
$s1 = $this->_rightRotate($e, 6) ^
$this->_rightRotate($e, 11) ^
$this->_rightRotate($e, 25);
$ch = ($e & $f) ^
($this->_not($e) & $g);
$t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
$h = $g;
$g = $f;
$f = $e;
$e = $this->_add($d, $t1);
$d = $c;
$c = $b;
$b = $a;
$a = $this->_add($t1, $t2);
}
// Add this chunk's hash to result so far
$hash = array(
$this->_add($hash[0], $a),
$this->_add($hash[1], $b),
$this->_add($hash[2], $c),
$this->_add($hash[3], $d),
$this->_add($hash[4], $e),
$this->_add($hash[5], $f),
$this->_add($hash[6], $g),
$this->_add($hash[7], $h)
);
}
// Produce the final hash value (big-endian)
return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
}
/**
* Pure-PHP implementation of SHA384 and SHA512
*
* @access private
* @param string $m
*/
function _sha512($m)
{
if (!class_exists('Math_BigInteger')) {
include_once 'Math/BigInteger.php';
}
static $init384, $init512, $k;
if (!isset($k)) {
// Initialize variables
$init384 = array( // initial values for SHA384
'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
'67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
);
$init512 = array( // initial values for SHA512
'6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
'510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
);
for ($i = 0; $i < 8; $i++) {
$init384[$i] = new Math_BigInteger($init384[$i], 16);
$init384[$i]->setPrecision(64);
$init512[$i] = new Math_BigInteger($init512[$i], 16);
$init512[$i]->setPrecision(64);
}
// Initialize table of round constants
// (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
$k = array(
'428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
'3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
'72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
'2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
'983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
'27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
'650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
'19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
'391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
'748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
'90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
'06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
'28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
'4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
);
for ($i = 0; $i < 80; $i++) {
$k[$i] = new Math_BigInteger($k[$i], 16);
}
}
$hash = $this->l == 48 ? $init384 : $init512;
// Pre-processing
$length = strlen($m);
// to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
$m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
$m[$length] = chr(0x80);
// we don't support hashing strings 512MB long
$m.= pack('N4', 0, 0, 0, $length << 3);
// Process the message in successive 1024-bit chunks
$chunks = str_split($m, 128);
foreach ($chunks as $chunk) {
$w = array();
for ($i = 0; $i < 16; $i++) {
$temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
$temp->setPrecision(64);
$w[] = $temp;
}
// Extend the sixteen 32-bit words into eighty 32-bit words
for ($i = 16; $i < 80; $i++) {
$temp = array(
$w[$i - 15]->bitwise_rightRotate(1),
$w[$i - 15]->bitwise_rightRotate(8),
$w[$i - 15]->bitwise_rightShift(7)
);
$s0 = $temp[0]->bitwise_xor($temp[1]);
$s0 = $s0->bitwise_xor($temp[2]);
$temp = array(
$w[$i - 2]->bitwise_rightRotate(19),
$w[$i - 2]->bitwise_rightRotate(61),
$w[$i - 2]->bitwise_rightShift(6)
);
$s1 = $temp[0]->bitwise_xor($temp[1]);
$s1 = $s1->bitwise_xor($temp[2]);
$w[$i] = $w[$i - 16]->copy();
$w[$i] = $w[$i]->add($s0);
$w[$i] = $w[$i]->add($w[$i - 7]);
$w[$i] = $w[$i]->add($s1);
}
// Initialize hash value for this chunk
$a = $hash[0]->copy();
$b = $hash[1]->copy();
$c = $hash[2]->copy();
$d = $hash[3]->copy();
$e = $hash[4]->copy();
$f = $hash[5]->copy();
$g = $hash[6]->copy();
$h = $hash[7]->copy();
// Main loop
for ($i = 0; $i < 80; $i++) {
$temp = array(
$a->bitwise_rightRotate(28),
$a->bitwise_rightRotate(34),
$a->bitwise_rightRotate(39)
);
$s0 = $temp[0]->bitwise_xor($temp[1]);
$s0 = $s0->bitwise_xor($temp[2]);
$temp = array(
$a->bitwise_and($b),
$a->bitwise_and($c),
$b->bitwise_and($c)
);
$maj = $temp[0]->bitwise_xor($temp[1]);
$maj = $maj->bitwise_xor($temp[2]);
$t2 = $s0->add($maj);
$temp = array(
$e->bitwise_rightRotate(14),
$e->bitwise_rightRotate(18),
$e->bitwise_rightRotate(41)
);
$s1 = $temp[0]->bitwise_xor($temp[1]);
$s1 = $s1->bitwise_xor($temp[2]);
$temp = array(
$e->bitwise_and($f),
$g->bitwise_and($e->bitwise_not())
);
$ch = $temp[0]->bitwise_xor($temp[1]);
$t1 = $h->add($s1);
$t1 = $t1->add($ch);
$t1 = $t1->add($k[$i]);
$t1 = $t1->add($w[$i]);
$h = $g->copy();
$g = $f->copy();
$f = $e->copy();
$e = $d->add($t1);
$d = $c->copy();
$c = $b->copy();
$b = $a->copy();
$a = $t1->add($t2);
}
// Add this chunk's hash to result so far
$hash = array(
$hash[0]->add($a),
$hash[1]->add($b),
$hash[2]->add($c),
$hash[3]->add($d),
$hash[4]->add($e),
$hash[5]->add($f),
$hash[6]->add($g),
$hash[7]->add($h)
);
}
// Produce the final hash value (big-endian)
// (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
$temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
$hash[4]->toBytes() . $hash[5]->toBytes();
if ($this->l != 48) {
$temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
}
return $temp;
}
/**
* Right Rotate
*
* @access private
* @param int $int
* @param int $amt
* @see self::_sha256()
* @return int
*/
function _rightRotate($int, $amt)
{
$invamt = 32 - $amt;
$mask = (1 << $invamt) - 1;
return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
}
/**
* Right Shift
*
* @access private
* @param int $int
* @param int $amt
* @see self::_sha256()
* @return int
*/
function _rightShift($int, $amt)
{
$mask = (1 << (32 - $amt)) - 1;
return ($int >> $amt) & $mask;
}
/**
* Not
*
* @access private
* @param int $int
* @see self::_sha256()
* @return int
*/
function _not($int)
{
return ~$int & 0xFFFFFFFF;
}
/**
* Add
*
* _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
* possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
*
* @param int $...
* @return int
* @see self::_sha256()
* @access private
*/
function _add()
{
static $mod;
if (!isset($mod)) {
$mod = pow(2, 32);
}
$result = 0;
$arguments = func_get_args();
foreach ($arguments as $argument) {
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
}
switch (true) {
case is_int($result):
// PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
case version_compare(PHP_VERSION, '5.3.0') >= 0 && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
// PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
return fmod($result, $mod);
}
return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
((fmod(floor($result / 0x80000000), 2) & 1) << 31);
}
/**
* String Shift
*
* Inspired by array_shift
*
* @param string $string
* @param int $index
* @return string
* @access private
*/
function _string_shift(&$string, $index = 1)
{
$substr = substr($string, 0, $index);
$string = substr($string, $index);
return $substr;
}
}
+761
View File
@@ -0,0 +1,761 @@
<?php
/**
* Pure-PHP implementation of RC2.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://tools.ietf.org/html/rfc2268}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/RC2.php';
*
* $rc2 = new Crypt_RC2();
*
* $rc2->setKey('abcdefgh');
*
* $plaintext = str_repeat('a', 1024);
*
* echo $rc2->decrypt($rc2->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_RC2
* @author Patrick Monnerat <pm@datasphere.ch>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_RC2_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_RC2_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_RC2_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_RC2_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**
* Pure-PHP implementation of RC2.
*
* @package Crypt_RC2
* @access public
*/
class Crypt_RC2 extends Crypt_Base
{
/**
* Block Length of the cipher
*
* @see Crypt_Base::block_size
* @var int
* @access private
*/
var $block_size = 8;
/**
* The Key
*
* @see Crypt_Base::key
* @see self::setKey()
* @var string
* @access private
*/
var $key;
/**
* The Original (unpadded) Key
*
* @see Crypt_Base::key
* @see self::setKey()
* @see self::encrypt()
* @see self::decrypt()
* @var string
* @access private
*/
var $orig_key;
/**
* Don't truncate / null pad key
*
* @see Crypt_Base::_clearBuffers()
* @var bool
* @access private
*/
var $skip_key_adjustment = true;
/**
* Key Length (in bytes)
*
* @see Crypt_RC2::setKeyLength()
* @var int
* @access private
*/
var $key_length = 16; // = 128 bits
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'RC2';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var string
* @access private
*/
var $cipher_name_mcrypt = 'rc2';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var int
* @access private
*/
var $cfb_init_len = 500;
/**
* The key length in bits.
*
* @see self::setKeyLength()
* @see self::setKey()
* @var int
* @access private
* @internal Should be in range [1..1024].
* @internal Changing this value after setting the key has no effect.
*/
var $default_key_length = 1024;
/**
* The key length in bits.
*
* @see self::isValidEnine()
* @see self::setKey()
* @var int
* @access private
* @internal Should be in range [1..1024].
*/
var $current_key_length;
/**
* The Key Schedule
*
* @see self::_setupKey()
* @var array
* @access private
*/
var $keys;
/**
* Key expansion randomization table.
* Twice the same 256-value sequence to save a modulus in key expansion.
*
* @see self::setKey()
* @var array
* @access private
*/
var $pitable = array(
0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD,
0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD
);
/**
* Inverse key expansion randomization table.
*
* @see self::setKey()
* @var array
* @access private
*/
var $invpitable = array(
0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66,
0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4,
0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20,
0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53,
0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68,
0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B,
0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12,
0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB,
0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3,
0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26,
0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67,
0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB,
0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC,
0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60,
0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7,
0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD,
0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24,
0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31,
0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE,
0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99,
0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C,
0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA,
0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35,
0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61,
0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72,
0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3,
0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F,
0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9,
0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77,
0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75,
0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87,
0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6
);
/**
* Test for engine validity
*
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
*
* @see Crypt_Base::Crypt_Base()
* @param int $engine
* @access public
* @return bool
*/
function isValidEngine($engine)
{
switch ($engine) {
case CRYPT_ENGINE_OPENSSL:
if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
return false;
}
$this->cipher_name_openssl_ecb = 'rc2-ecb';
$this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode();
}
return parent::isValidEngine($engine);
}
/**
* Sets the key length.
*
* Valid key lengths are 8 to 1024.
* Calling this function after setting the key has no effect until the next
* Crypt_RC2::setKey() call.
*
* @access public
* @param int $length in bits
*/
function setKeyLength($length)
{
if ($length < 8) {
$this->default_key_length = 1;
} elseif ($length > 1024) {
$this->default_key_length = 128;
} else {
$this->default_key_length = $length;
}
$this->current_key_length = $this->default_key_length;
parent::setKeyLength($length);
}
/**
* Returns the current key length
*
* @access public
* @return int
*/
function getKeyLength()
{
return $this->current_key_length;
}
/**
* Sets the key.
*
* Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg.
* strlen($key) <= 128), however, we only use the first 128 bytes if $key
* has more then 128 bytes in it, and set $key to a single null byte if
* it is empty.
*
* If the key is not explicitly set, it'll be assumed to be a single
* null byte.
*
* @see Crypt_Base::setKey()
* @access public
* @param string $key
* @param int $t1 optional Effective key length in bits.
*/
function setKey($key, $t1 = 0)
{
$this->orig_key = $key;
if ($t1 <= 0) {
$t1 = $this->default_key_length;
} elseif ($t1 > 1024) {
$t1 = 1024;
}
$this->current_key_length = $t1;
// Key byte count should be 1..128.
$key = strlen($key) ? substr($key, 0, 128) : "\x00";
$t = strlen($key);
// The mcrypt RC2 implementation only supports effective key length
// of 1024 bits. It is however possible to handle effective key
// lengths in range 1..1024 by expanding the key and applying
// inverse pitable mapping to the first byte before submitting it
// to mcrypt.
// Key expansion.
$l = array_values(unpack('C*', $key));
$t8 = ($t1 + 7) >> 3;
$tm = 0xFF >> (8 * $t8 - $t1);
// Expand key.
$pitable = $this->pitable;
for ($i = $t; $i < 128; $i++) {
$l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]];
}
$i = 128 - $t8;
$l[$i] = $pitable[$l[$i] & $tm];
while ($i--) {
$l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]];
}
// Prepare the key for mcrypt.
$l[0] = $this->invpitable[$l[0]];
array_unshift($l, 'C*');
parent::setKey(call_user_func_array('pack', $l));
}
/**
* Encrypts a message.
*
* Mostly a wrapper for Crypt_Base::encrypt, with some additional OpenSSL handling code
*
* @see self::decrypt()
* @access public
* @param string $plaintext
* @return string $ciphertext
*/
function encrypt($plaintext)
{
if ($this->engine == CRYPT_ENGINE_OPENSSL) {
$temp = $this->key;
$this->key = $this->orig_key;
$result = parent::encrypt($plaintext);
$this->key = $temp;
return $result;
}
return parent::encrypt($plaintext);
}
/**
* Decrypts a message.
*
* Mostly a wrapper for Crypt_Base::decrypt, with some additional OpenSSL handling code
*
* @see self::encrypt()
* @access public
* @param string $ciphertext
* @return string $plaintext
*/
function decrypt($ciphertext)
{
if ($this->engine == CRYPT_ENGINE_OPENSSL) {
$temp = $this->key;
$this->key = $this->orig_key;
$result = parent::decrypt($ciphertext);
$this->key = $temp;
return $result;
}
return parent::decrypt($ciphertext);
}
/**
* Encrypts a block
*
* @see Crypt_Base::_encryptBlock()
* @see Crypt_Base::encrypt()
* @access private
* @param string $in
* @return string
*/
function _encryptBlock($in)
{
list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
$keys = $this->keys;
$limit = 20;
$actions = array($limit => 44, 44 => 64);
$j = 0;
for (;;) {
// Mixing round.
$r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
$r0 |= $r0 >> 16;
$r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
$r1 |= $r1 >> 16;
$r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
$r2 |= $r2 >> 16;
$r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
$r3 |= $r3 >> 16;
if ($j === $limit) {
if ($limit === 64) {
break;
}
// Mashing round.
$r0 += $keys[$r3 & 0x3F];
$r1 += $keys[$r0 & 0x3F];
$r2 += $keys[$r1 & 0x3F];
$r3 += $keys[$r2 & 0x3F];
$limit = $actions[$limit];
}
}
return pack('vvvv', $r0, $r1, $r2, $r3);
}
/**
* Decrypts a block
*
* @see Crypt_Base::_decryptBlock()
* @see Crypt_Base::decrypt()
* @access private
* @param string $in
* @return string
*/
function _decryptBlock($in)
{
list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
$keys = $this->keys;
$limit = 44;
$actions = array($limit => 20, 20 => 0);
$j = 64;
for (;;) {
// R-mixing round.
$r3 = ($r3 | ($r3 << 16)) >> 5;
$r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
$r2 = ($r2 | ($r2 << 16)) >> 3;
$r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
$r1 = ($r1 | ($r1 << 16)) >> 2;
$r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
$r0 = ($r0 | ($r0 << 16)) >> 1;
$r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;
if ($j === $limit) {
if ($limit === 0) {
break;
}
// R-mashing round.
$r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
$r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
$r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
$r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;
$limit = $actions[$limit];
}
}
return pack('vvvv', $r0, $r1, $r2, $r3);
}
/**
* Setup the CRYPT_ENGINE_MCRYPT $engine
*
* @see Crypt_Base::_setupMcrypt()
* @access private
*/
function _setupMcrypt()
{
if (!isset($this->key)) {
$this->setKey('');
}
parent::_setupMcrypt();
}
/**
* Creates the key schedule
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
if (!isset($this->key)) {
$this->setKey('');
}
// Key has already been expanded in Crypt_RC2::setKey():
// Only the first value must be altered.
$l = unpack('Ca/Cb/v*', $this->key);
array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8));
unset($l['a']);
unset($l['b']);
$this->keys = $l;
}
/**
* Setup the performance-optimized function for de/encrypt()
*
* @see Crypt_Base::_setupInlineCrypt()
* @access private
*/
function _setupInlineCrypt()
{
$lambda_functions = &Crypt_RC2::_getLambdaFunctions();
// The first 10 generated $lambda_functions will use the $keys hardcoded as integers
// for the mixing rounds, for better inline crypt performance [~20% faster].
// But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
// (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
// Generation of a unique hash for our generated code
$code_hash = "Crypt_RC2, {$this->mode}";
if ($gen_hi_opt_code) {
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
}
// Is there a re-usable $lambda_functions in there?
// If not, we have to create it.
if (!isset($lambda_functions[$code_hash])) {
// Init code for both, encrypt and decrypt.
$init_crypt = '$keys = $self->keys;';
switch (true) {
case $gen_hi_opt_code:
$keys = $this->keys;
default:
$keys = array();
foreach ($this->keys as $k => $v) {
$keys[$k] = '$keys[' . $k . ']';
}
}
// $in is the current 8 bytes block which has to be en/decrypt
$encrypt_block = $decrypt_block = '
$in = unpack("v4", $in);
$r0 = $in[1];
$r1 = $in[2];
$r2 = $in[3];
$r3 = $in[4];
';
// Create code for encryption.
$limit = 20;
$actions = array($limit => 44, 44 => 64);
$j = 0;
for (;;) {
// Mixing round.
$encrypt_block .= '
$r0 = (($r0 + ' . $keys[$j++] . ' +
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
$r0 |= $r0 >> 16;
$r1 = (($r1 + ' . $keys[$j++] . ' +
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
$r1 |= $r1 >> 16;
$r2 = (($r2 + ' . $keys[$j++] . ' +
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
$r2 |= $r2 >> 16;
$r3 = (($r3 + ' . $keys[$j++] . ' +
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
$r3 |= $r3 >> 16;';
if ($j === $limit) {
if ($limit === 64) {
break;
}
// Mashing round.
$encrypt_block .= '
$r0 += $keys[$r3 & 0x3F];
$r1 += $keys[$r0 & 0x3F];
$r2 += $keys[$r1 & 0x3F];
$r3 += $keys[$r2 & 0x3F];';
$limit = $actions[$limit];
}
}
$encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
// Create code for decryption.
$limit = 44;
$actions = array($limit => 20, 20 => 0);
$j = 64;
for (;;) {
// R-mixing round.
$decrypt_block .= '
$r3 = ($r3 | ($r3 << 16)) >> 5;
$r3 = ($r3 - ' . $keys[--$j] . ' -
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
$r2 = ($r2 | ($r2 << 16)) >> 3;
$r2 = ($r2 - ' . $keys[--$j] . ' -
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
$r1 = ($r1 | ($r1 << 16)) >> 2;
$r1 = ($r1 - ' . $keys[--$j] . ' -
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
$r0 = ($r0 | ($r0 << 16)) >> 1;
$r0 = ($r0 - ' . $keys[--$j] . ' -
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
if ($j === $limit) {
if ($limit === 0) {
break;
}
// R-mashing round.
$decrypt_block .= '
$r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
$r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
$r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
$r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;';
$limit = $actions[$limit];
}
}
$decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
// Creates the inline-crypt function
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
'init_crypt' => $init_crypt,
'encrypt_block' => $encrypt_block,
'decrypt_block' => $decrypt_block
)
);
}
// Set the inline-crypt function as callback in: $this->inline_crypt
$this->inline_crypt = $lambda_functions[$code_hash];
}
}
+366
View File
@@ -0,0 +1,366 @@
<?php
/**
* Pure-PHP implementation of RC4.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
* - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
*
* RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
* ARCFOUR or ARC4 because RC4 is how it is referred to in the SSH1 specification.
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/RC4.php';
*
* $rc4 = new Crypt_RC4();
*
* $rc4->setKey('abcdefgh');
*
* $size = 10 * 1024;
* $plaintext = '';
* for ($i = 0; $i < $size; $i++) {
* $plaintext.= 'a';
* }
*
* echo $rc4->decrypt($rc4->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_RC4
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access private
* @see self::_crypt()
*/
define('CRYPT_RC4_ENCRYPT', 0);
define('CRYPT_RC4_DECRYPT', 1);
/**#@-*/
/**
* Pure-PHP implementation of RC4.
*
* @package Crypt_RC4
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Crypt_RC4 extends Crypt_Base
{
/**
* Block Length of the cipher
*
* RC4 is a stream cipher
* so we the block_size to 0
*
* @see Crypt_Base::block_size
* @var int
* @access private
*/
var $block_size = 0;
/**
* Key Length (in bytes)
*
* @see Crypt_RC4::setKeyLength()
* @var int
* @access private
*/
var $key_length = 128; // = 1024 bits
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'RC4';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var string
* @access private
*/
var $cipher_name_mcrypt = 'arcfour';
/**
* Holds whether performance-optimized $inline_crypt() can/should be used.
*
* @see Crypt_Base::inline_crypt
* @var mixed
* @access private
*/
var $use_inline_crypt = false; // currently not available
/**
* The Key
*
* @see self::setKey()
* @var string
* @access private
*/
var $key;
/**
* The Key Stream for decryption and encryption
*
* @see self::setKey()
* @var array
* @access private
*/
var $stream;
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* @see Crypt_Base::Crypt_Base()
* @return Crypt_RC4
* @access public
*/
function __construct()
{
parent::__construct(CRYPT_MODE_STREAM);
}
/**
* PHP4 compatible Default Constructor.
*
* @see self::__construct()
* @access public
*/
function Crypt_RC4()
{
$this->__construct();
}
/**
* Test for engine validity
*
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
*
* @see Crypt_Base::Crypt_Base()
* @param int $engine
* @access public
* @return bool
*/
function isValidEngine($engine)
{
if ($engine == CRYPT_ENGINE_OPENSSL) {
if (version_compare(PHP_VERSION, '5.3.7') >= 0) {
$this->cipher_name_openssl = 'rc4-40';
} else {
switch (strlen($this->key)) {
case 5:
$this->cipher_name_openssl = 'rc4-40';
break;
case 8:
$this->cipher_name_openssl = 'rc4-64';
break;
case 16:
$this->cipher_name_openssl = 'rc4';
break;
default:
return false;
}
}
}
return parent::isValidEngine($engine);
}
/**
* Dummy function.
*
* Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
* If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
* calling setKey().
*
* [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
* the IV's are relatively easy to predict, an attack described by
* {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
* can be used to quickly guess at the rest of the key. The following links elaborate:
*
* {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
* {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
*
* @param string $iv
* @see self::setKey()
* @access public
*/
function setIV($iv)
{
}
/**
* Sets the key length
*
* Keys can be between 1 and 256 bytes long.
*
* @access public
* @param int $length
*/
function setKeyLength($length)
{
if ($length < 8) {
$this->key_length = 1;
} elseif ($length > 2048) {
$this->key_length = 256;
} else {
$this->key_length = $length >> 3;
}
parent::setKeyLength($length);
}
/**
* Encrypts a message.
*
* @see Crypt_Base::decrypt()
* @see self::_crypt()
* @access public
* @param string $plaintext
* @return string $ciphertext
*/
function encrypt($plaintext)
{
if ($this->engine != CRYPT_ENGINE_INTERNAL) {
return parent::encrypt($plaintext);
}
return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
}
/**
* Decrypts a message.
*
* $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
* At least if the continuous buffer is disabled.
*
* @see Crypt_Base::encrypt()
* @see self::_crypt()
* @access public
* @param string $ciphertext
* @return string $plaintext
*/
function decrypt($ciphertext)
{
if ($this->engine != CRYPT_ENGINE_INTERNAL) {
return parent::decrypt($ciphertext);
}
return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
}
/**
* Setup the key (expansion)
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
$key = $this->key;
$keyLength = strlen($key);
$keyStream = range(0, 255);
$j = 0;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
$temp = $keyStream[$i];
$keyStream[$i] = $keyStream[$j];
$keyStream[$j] = $temp;
}
$this->stream = array();
$this->stream[CRYPT_RC4_DECRYPT] = $this->stream[CRYPT_RC4_ENCRYPT] = array(
0, // index $i
0, // index $j
$keyStream
);
}
/**
* Encrypts or decrypts a message.
*
* @see self::encrypt()
* @see self::decrypt()
* @access private
* @param string $text
* @param int $mode
* @return string $text
*/
function _crypt($text, $mode)
{
if ($this->changed) {
$this->_setup();
$this->changed = false;
}
$stream = &$this->stream[$mode];
if ($this->continuousBuffer) {
$i = &$stream[0];
$j = &$stream[1];
$keyStream = &$stream[2];
} else {
$i = $stream[0];
$j = $stream[1];
$keyStream = $stream[2];
}
$len = strlen($text);
for ($k = 0; $k < $len; ++$k) {
$i = ($i + 1) & 255;
$ksi = $keyStream[$i];
$j = ($j + $ksi) & 255;
$ksj = $keyStream[$j];
$keyStream[$i] = $ksj;
$keyStream[$j] = $ksi;
$text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]);
}
return $text;
}
}
File diff suppressed because it is too large Load Diff
+338
View File
@@ -0,0 +1,338 @@
<?php
/**
* Random Number Generator
*
* The idea behind this function is that it can be easily replaced with your own crypt_random_string()
* function. eg. maybe you have a better source of entropy for creating the initial states or whatever.
*
* PHP versions 4 and 5
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/Random.php';
*
* echo bin2hex(crypt_random_string(8));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Random
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
// laravel is a PHP framework that utilizes phpseclib. laravel workbenches may, independently,
// have phpseclib as a requirement as well. if you're developing such a program you may encounter
// a "Cannot redeclare crypt_random_string()" error.
if (!function_exists('crypt_random_string')) {
/**
* "Is Windows" test
*
* @access private
*/
define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
/**
* Generate a random string.
*
* Although microoptimizations are generally discouraged as they impair readability this function is ripe with
* microoptimizations because this function has the potential of being called a huge number of times.
* eg. for RSA key generation.
*
* @param int $length
* @return string
* @access public
*/
function crypt_random_string($length)
{
if (!$length) {
return '';
}
if (CRYPT_RANDOM_IS_WINDOWS) {
// method 1. prior to PHP 5.3, mcrypt_create_iv() would call rand() on windows
if (extension_loaded('mcrypt') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
return @mcrypt_create_iv($length);
}
// method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
// to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
// openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both
// call php_win32_get_random_bytes():
//
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392
//
// php_win32_get_random_bytes() is defined thusly:
//
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
//
// we're calling it, all the same, in the off chance that the mcrypt extension is not available
if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
return openssl_random_pseudo_bytes($length);
}
} else {
// method 1. the fastest
if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
return openssl_random_pseudo_bytes($length);
}
// method 2
static $fp = true;
if ($fp === true) {
// warning's will be output unles the error suppression operator is used. errors such as
// "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
$fp = @fopen('/dev/urandom', 'rb');
}
if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
return fread($fp, $length);
}
// method 3. pretty much does the same thing as method 2 per the following url:
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
// surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
// not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
// restrictions or some such
if (extension_loaded('mcrypt')) {
return @mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
}
}
// at this point we have no choice but to use a pure-PHP CSPRNG
// cascade entropy across multiple PHP instances by fixing the session and collecting all
// environmental variables, including the previous session data and the current session
// data.
//
// mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
// easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
// PHP isn't low level to be able to use those as sources and on a web server there's not likely
// going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
// however, a ton of people visiting the website. obviously you don't want to base your seeding
// soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
// by the user and (2) this isn't just looking at the data sent by the current user - it's based
// on the data sent by all users. one user requests the page and a hash of their info is saved.
// another user visits the page and the serialization of their data is utilized along with the
// server envirnment stuff and a hash of the previous http request data (which itself utilizes
// a hash of the session data before that). certainly an attacker should be assumed to have
// full control over his own http requests. he, however, is not going to have control over
// everyone's http requests.
static $crypto = false, $v;
if ($crypto === false) {
// save old session data
$old_session_id = session_id();
$old_use_cookies = ini_get('session.use_cookies');
$old_session_cache_limiter = session_cache_limiter();
$_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
if ($old_session_id != '') {
session_write_close();
}
session_id(1);
ini_set('session.use_cookies', 0);
session_cache_limiter('');
session_start();
$v = $seed = $_SESSION['seed'] = pack('H*', sha1(
(isset($_SERVER) ? phpseclib_safe_serialize($_SERVER) : '') .
(isset($_POST) ? phpseclib_safe_serialize($_POST) : '') .
(isset($_GET) ? phpseclib_safe_serialize($_GET) : '') .
(isset($_COOKIE) ? phpseclib_safe_serialize($_COOKIE) : '') .
phpseclib_safe_serialize($GLOBALS) .
phpseclib_safe_serialize($_SESSION) .
phpseclib_safe_serialize($_OLD_SESSION)
));
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 0;
}
$_SESSION['count']++;
session_write_close();
// restore old session data
if ($old_session_id != '') {
session_id($old_session_id);
session_start();
ini_set('session.use_cookies', $old_use_cookies);
session_cache_limiter($old_session_cache_limiter);
} else {
if ($_OLD_SESSION !== false) {
$_SESSION = $_OLD_SESSION;
unset($_OLD_SESSION);
} else {
unset($_SESSION);
}
}
// in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
// the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
// if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
// original hash and the current hash. we'll be emulating that. for more info see the following URL:
//
// http://tools.ietf.org/html/rfc4253#section-7.2
//
// see the is_string($crypto) part for an example of how to expand the keys
$key = pack('H*', sha1($seed . 'A'));
$iv = pack('H*', sha1($seed . 'C'));
// ciphers are used as per the nist.gov link below. also, see this link:
//
// http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
switch (true) {
case phpseclib_resolve_include_path('Crypt/AES.php'):
if (!class_exists('Crypt_AES')) {
include_once 'AES.php';
}
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/Twofish.php'):
if (!class_exists('Crypt_Twofish')) {
include_once 'Twofish.php';
}
$crypto = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/Blowfish.php'):
if (!class_exists('Crypt_Blowfish')) {
include_once 'Blowfish.php';
}
$crypto = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/TripleDES.php'):
if (!class_exists('Crypt_TripleDES')) {
include_once 'TripleDES.php';
}
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/DES.php'):
if (!class_exists('Crypt_DES')) {
include_once 'DES.php';
}
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/RC4.php'):
if (!class_exists('Crypt_RC4')) {
include_once 'RC4.php';
}
$crypto = new Crypt_RC4();
break;
default:
user_error('crypt_random_string requires at least one symmetric cipher be loaded');
return false;
}
$crypto->setKey($key);
$crypto->setIV($iv);
$crypto->enableContinuousBuffer();
}
//return $crypto->encrypt(str_repeat("\0", $length));
// the following is based off of ANSI X9.31:
//
// http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
//
// OpenSSL uses that same standard for it's random numbers:
//
// http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
// (do a search for "ANS X9.31 A.2.4")
$result = '';
while (strlen($result) < $length) {
$i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
$r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
$v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
$result.= $r;
}
return substr($result, 0, $length);
}
}
if (!function_exists('phpseclib_safe_serialize')) {
/**
* Safely serialize variables
*
* If a class has a private __sleep() method it'll give a fatal error on PHP 5.2 and earlier.
* PHP 5.3 will emit a warning.
*
* @param mixed $arr
* @access public
*/
function phpseclib_safe_serialize(&$arr)
{
if (is_object($arr)) {
return '';
}
if (!is_array($arr)) {
return serialize($arr);
}
// prevent circular array recursion
if (isset($arr['__phpseclib_marker'])) {
return '';
}
$safearr = array();
$arr['__phpseclib_marker'] = true;
foreach (array_keys($arr) as $key) {
// do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage
if ($key !== '__phpseclib_marker') {
$safearr[$key] = phpseclib_safe_serialize($arr[$key]);
}
}
unset($arr['__phpseclib_marker']);
return serialize($safearr);
}
}
if (!function_exists('phpseclib_resolve_include_path')) {
/**
* Resolve filename against the include path.
*
* Wrapper around stream_resolve_include_path() (which was introduced in
* PHP 5.3.2) with fallback implementation for earlier PHP versions.
*
* @param string $filename
* @return string|false
* @access public
*/
function phpseclib_resolve_include_path($filename)
{
if (function_exists('stream_resolve_include_path')) {
return stream_resolve_include_path($filename);
}
// handle non-relative paths
if (file_exists($filename)) {
return realpath($filename);
}
$paths = PATH_SEPARATOR == ':' ?
preg_split('#(?<!phar):#', get_include_path()) :
explode(PATH_SEPARATOR, get_include_path());
foreach ($paths as $prefix) {
// path's specified in include_path don't always end in /
$ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
$file = $prefix . $ds . $filename;
if (file_exists($file)) {
return realpath($file);
}
}
return false;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,517 @@
<?php
/**
* Pure-PHP implementation of Triple DES.
*
* Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt).
*
* PHP versions 4 and 5
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/TripleDES.php';
*
* $des = new Crypt_TripleDES();
*
* $des->setKey('abcdefghijklmnopqrstuvwx');
*
* $size = 10 * 1024;
* $plaintext = '';
* for ($i = 0; $i < $size; $i++) {
* $plaintext.= 'a';
* }
*
* echo $des->decrypt($des->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_TripleDES
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_DES
*/
if (!class_exists('Crypt_DES')) {
include_once 'DES.php';
}
/**#@+
* @access public
* @see self::Crypt_TripleDES()
*/
/**
* Encrypt / decrypt using inner chaining
*
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
*/
define('CRYPT_MODE_3CBC', -2);
/**
* BC version of the above.
*/
define('CRYPT_DES_MODE_3CBC', -2);
/**
* Encrypt / decrypt using outer chaining
*
* Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
*/
define('CRYPT_MODE_CBC3', CRYPT_MODE_CBC);
/**
* BC version of the above.
*/
define('CRYPT_DES_MODE_CBC3', CRYPT_MODE_CBC3);
/**#@-*/
/**
* Pure-PHP implementation of Triple DES.
*
* @package Crypt_TripleDES
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Crypt_TripleDES extends Crypt_DES
{
/**
* Key Length (in bytes)
*
* @see Crypt_TripleDES::setKeyLength()
* @var int
* @access private
*/
var $key_length = 24;
/**
* The default salt used by setPassword()
*
* @see Crypt_Base::password_default_salt
* @see Crypt_Base::setPassword()
* @var string
* @access private
*/
var $password_default_salt = 'phpseclib';
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_DES::const_namespace
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'DES';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_DES::cipher_name_mcrypt
* @see Crypt_Base::cipher_name_mcrypt
* @var string
* @access private
*/
var $cipher_name_mcrypt = 'tripledes';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var int
* @access private
*/
var $cfb_init_len = 750;
/**
* max possible size of $key
*
* @see self::setKey()
* @see Crypt_DES::setKey()
* @var string
* @access private
*/
var $key_length_max = 24;
/**
* Internal flag whether using CRYPT_DES_MODE_3CBC or not
*
* @var bool
* @access private
*/
var $mode_3cbc;
/**
* The Crypt_DES objects
*
* Used only if $mode_3cbc === true
*
* @var array
* @access private
*/
var $des;
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - CRYPT_DES_MODE_ECB
*
* - CRYPT_DES_MODE_CBC
*
* - CRYPT_DES_MODE_CTR
*
* - CRYPT_DES_MODE_CFB
*
* - CRYPT_DES_MODE_OFB
*
* - CRYPT_DES_MODE_3CBC
*
* If not explicitly set, CRYPT_DES_MODE_CBC will be used.
*
* @see Crypt_DES::Crypt_DES()
* @see Crypt_Base::Crypt_Base()
* @param int $mode
* @access public
*/
function __construct($mode = CRYPT_MODE_CBC)
{
switch ($mode) {
// In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC
// and additional flag us internally as 3CBC
case CRYPT_DES_MODE_3CBC:
parent::Crypt_Base(CRYPT_MODE_CBC);
$this->mode_3cbc = true;
// This three $des'es will do the 3CBC work (if $key > 64bits)
$this->des = array(
new Crypt_DES(CRYPT_MODE_CBC),
new Crypt_DES(CRYPT_MODE_CBC),
new Crypt_DES(CRYPT_MODE_CBC),
);
// we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
$this->des[0]->disablePadding();
$this->des[1]->disablePadding();
$this->des[2]->disablePadding();
break;
// If not 3CBC, we init as usual
default:
parent::__construct($mode);
}
}
/**
* PHP4 compatible Default Constructor.
*
* @see self::__construct()
* @param int $mode
* @access public
*/
function Crypt_TripleDES($mode = CRYPT_MODE_CBC)
{
$this->__construct($mode);
}
/**
* Test for engine validity
*
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
*
* @see Crypt_Base::Crypt_Base()
* @param int $engine
* @access public
* @return bool
*/
function isValidEngine($engine)
{
if ($engine == CRYPT_ENGINE_OPENSSL) {
$this->cipher_name_openssl_ecb = 'des-ede3';
$mode = $this->_openssl_translate_mode();
$this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
}
return parent::isValidEngine($engine);
}
/**
* Sets the initialization vector. (optional)
*
* SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explicitly set, it'll be assumed
* to be all zero's.
*
* @see Crypt_Base::setIV()
* @access public
* @param string $iv
*/
function setIV($iv)
{
parent::setIV($iv);
if ($this->mode_3cbc) {
$this->des[0]->setIV($iv);
$this->des[1]->setIV($iv);
$this->des[2]->setIV($iv);
}
}
/**
* Sets the key length.
*
* Valid key lengths are 64, 128 and 192
*
* @see Crypt_Base:setKeyLength()
* @access public
* @param int $length
*/
function setKeyLength($length)
{
$length >>= 3;
switch (true) {
case $length <= 8:
$this->key_length = 8;
break;
case $length <= 16:
$this->key_length = 16;
break;
default:
$this->key_length = 24;
}
parent::setKeyLength($length);
}
/**
* Sets the key.
*
* Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
* 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate.
*
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
*
* If the key is not explicitly set, it'll be assumed to be all null bytes.
*
* @access public
* @see Crypt_DES::setKey()
* @see Crypt_Base::setKey()
* @param string $key
*/
function setKey($key)
{
$length = $this->explicit_key_length ? $this->key_length : strlen($key);
if ($length > 8) {
$key = str_pad(substr($key, 0, 24), 24, chr(0));
// if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
// http://php.net/function.mcrypt-encrypt#47973
$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
} else {
$key = str_pad($key, 8, chr(0));
}
parent::setKey($key);
// And in case of CRYPT_DES_MODE_3CBC:
// if key <= 64bits we not need the 3 $des to work,
// because we will then act as regular DES-CBC with just a <= 64bit key.
// So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
if ($this->mode_3cbc && $length > 8) {
$this->des[0]->setKey(substr($key, 0, 8));
$this->des[1]->setKey(substr($key, 8, 8));
$this->des[2]->setKey(substr($key, 16, 8));
}
}
/**
* Encrypts a message.
*
* @see Crypt_Base::encrypt()
* @access public
* @param string $plaintext
* @return string $cipertext
*/
function encrypt($plaintext)
{
// parent::en/decrypt() is able to do all the work for all modes and keylengths,
// except for: CRYPT_MODE_3CBC (inner chaining CBC) with a key > 64bits
// if the key is smaller then 8, do what we'd normally do
if ($this->mode_3cbc && strlen($this->key) > 8) {
return $this->des[2]->encrypt(
$this->des[1]->decrypt(
$this->des[0]->encrypt(
$this->_pad($plaintext)
)
)
);
}
return parent::encrypt($plaintext);
}
/**
* Decrypts a message.
*
* @see Crypt_Base::decrypt()
* @access public
* @param string $ciphertext
* @return string $plaintext
*/
function decrypt($ciphertext)
{
if ($this->mode_3cbc && strlen($this->key) > 8) {
return $this->_unpad(
$this->des[0]->decrypt(
$this->des[1]->encrypt(
$this->des[2]->decrypt(
str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0")
)
)
)
);
}
return parent::decrypt($ciphertext);
}
/**
* Treat consecutive "packets" as if they are a continuous buffer.
*
* Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
* will yield different outputs:
*
* <code>
* echo $des->encrypt(substr($plaintext, 0, 8));
* echo $des->encrypt(substr($plaintext, 8, 8));
* </code>
* <code>
* echo $des->encrypt($plaintext);
* </code>
*
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
* another, as demonstrated with the following:
*
* <code>
* $des->encrypt(substr($plaintext, 0, 8));
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
* </code>
* <code>
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
* </code>
*
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
*
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
* however, they are also less intuitive and more likely to cause you problems.
*
* @see Crypt_Base::enableContinuousBuffer()
* @see self::disableContinuousBuffer()
* @access public
*/
function enableContinuousBuffer()
{
parent::enableContinuousBuffer();
if ($this->mode_3cbc) {
$this->des[0]->enableContinuousBuffer();
$this->des[1]->enableContinuousBuffer();
$this->des[2]->enableContinuousBuffer();
}
}
/**
* Treat consecutive packets as if they are a discontinuous buffer.
*
* The default behavior.
*
* @see Crypt_Base::disableContinuousBuffer()
* @see self::enableContinuousBuffer()
* @access public
*/
function disableContinuousBuffer()
{
parent::disableContinuousBuffer();
if ($this->mode_3cbc) {
$this->des[0]->disableContinuousBuffer();
$this->des[1]->disableContinuousBuffer();
$this->des[2]->disableContinuousBuffer();
}
}
/**
* Creates the key schedule
*
* @see Crypt_DES::_setupKey()
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
switch (true) {
// if $key <= 64bits we configure our internal pure-php cipher engine
// to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same.
case strlen($this->key) <= 8:
$this->des_rounds = 1;
break;
// otherwise, if $key > 64bits, we configure our engine to work as 3DES.
default:
$this->des_rounds = 3;
// (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately.
if ($this->mode_3cbc) {
$this->des[0]->_setupKey();
$this->des[1]->_setupKey();
$this->des[2]->_setupKey();
// because $des[0-2] will, now, do all the work we can return here
// not need unnecessary stress parent::_setupKey() with our, now unused, $key.
return;
}
}
// setup our key
parent::_setupKey();
}
/**
* Sets the internal crypt engine
*
* @see Crypt_Base::Crypt_Base()
* @see Crypt_Base::setPreferredEngine()
* @param int $engine
* @access public
* @return int
*/
function setPreferredEngine($engine)
{
if ($this->mode_3cbc) {
$this->des[0]->setPreferredEngine($engine);
$this->des[1]->setPreferredEngine($engine);
$this->des[2]->setPreferredEngine($engine);
}
return parent::setPreferredEngine($engine);
}
}
+889
View File
@@ -0,0 +1,889 @@
<?php
/**
* Pure-PHP implementation of Twofish.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://en.wikipedia.org/wiki/Twofish Wikipedia description of Twofish}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/Twofish.php';
*
* $twofish = new Crypt_Twofish();
*
* $twofish->setKey('12345678901234567890123456789012');
*
* $plaintext = str_repeat('a', 1024);
*
* echo $twofish->decrypt($twofish->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Twofish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_TWOFISH_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_TWOFISH_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_TWOFISH_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**
* Pure-PHP implementation of Twofish.
*
* @package Crypt_Twofish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @access public
*/
class Crypt_Twofish extends Crypt_Base
{
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'TWOFISH';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var string
* @access private
*/
var $cipher_name_mcrypt = 'twofish';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var int
* @access private
*/
var $cfb_init_len = 800;
/**
* Q-Table
*
* @var array
* @access private
*/
var $q0 = array(
0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
);
/**
* Q-Table
*
* @var array
* @access private
*/
var $q1 = array(
0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
);
/**
* M-Table
*
* @var array
* @access private
*/
var $m0 = array(
0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F,
0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D,
0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3,
0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51,
0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C,
0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70,
0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC,
0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2,
0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17,
0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3,
0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149,
0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9,
0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48,
0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519,
0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5,
0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969,
0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC,
0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB,
0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2,
0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
);
/**
* M-Table
*
* @var array
* @access private
*/
var $m1 = array(
0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E,
0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060,
0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D,
0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7,
0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B,
0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8,
0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D,
0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB,
0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7,
0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B,
0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E,
0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9,
0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F,
0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED,
0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7,
0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2,
0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323,
0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA,
0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000,
0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
);
/**
* M-Table
*
* @var array
* @access private
*/
var $m2 = array(
0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE,
0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0,
0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065,
0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F,
0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF,
0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C,
0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF,
0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E,
0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC,
0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71,
0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101,
0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5,
0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A,
0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45,
0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6,
0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929,
0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB,
0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F,
0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746,
0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
);
/**
* M-Table
*
* @var array
* @access private
*/
var $m3 = array(
0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A,
0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5,
0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63,
0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123,
0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197,
0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB,
0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20,
0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137,
0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730,
0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252,
0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F,
0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A,
0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D,
0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0,
0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6,
0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38,
0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439,
0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6,
0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000,
0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
);
/**
* The Key Schedule Array
*
* @var array
* @access private
*/
var $K = array();
/**
* The Key depended S-Table 0
*
* @var array
* @access private
*/
var $S0 = array();
/**
* The Key depended S-Table 1
*
* @var array
* @access private
*/
var $S1 = array();
/**
* The Key depended S-Table 2
*
* @var array
* @access private
*/
var $S2 = array();
/**
* The Key depended S-Table 3
*
* @var array
* @access private
*/
var $S3 = array();
/**
* Holds the last used key
*
* @var array
* @access private
*/
var $kl;
/**
* The Key Length (in bytes)
*
* @see Crypt_Twofish::setKeyLength()
* @var int
* @access private
*/
var $key_length = 16;
/**
* Sets the key length.
*
* Valid key lengths are 128, 192 or 256 bits
*
* @access public
* @param int $length
*/
function setKeyLength($length)
{
switch (true) {
case $length <= 128:
$this->key_length = 16;
break;
case $length <= 192:
$this->key_length = 24;
break;
default:
$this->key_length = 32;
}
parent::setKeyLength($length);
}
/**
* Setup the key (expansion)
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
// already expanded
return;
}
$this->kl = array('key' => $this->key);
/* Key expanding and generating the key-depended s-boxes */
$le_longs = unpack('V*', $this->key);
$key = unpack('C*', $this->key);
$m0 = $this->m0;
$m1 = $this->m1;
$m2 = $this->m2;
$m3 = $this->m3;
$q0 = $this->q0;
$q1 = $this->q1;
$K = $S0 = $S1 = $S2 = $S3 = array();
switch (strlen($this->key)) {
case 16:
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
$A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
$m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
$m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
$m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]];
$B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^
$m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^
$m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
$m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
$B = ($B << 8) | ($B >> 24 & 0xff);
$A = $this->safe_intval($A + $B);
$K[] = $A;
$A = $this->safe_intval($A + $B);
$K[] = ($A << 9 | $A >> 23 & 0x1ff);
}
for ($i = 0; $i < 256; ++$i) {
$S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
$S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
$S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
$S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
}
break;
case 24:
list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
$A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
$m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
$m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
$m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
$B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
$m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
$m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
$m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
$B = ($B << 8) | ($B >> 24 & 0xff);
$A = $this->safe_intval($A + $B);
$K[] = $A;
$A = $this->safe_intval($A + $B);
$K[] = ($A << 9 | $A >> 23 & 0x1ff);
}
for ($i = 0; $i < 256; ++$i) {
$S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
$S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
$S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
$S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
}
break;
default: // 32
list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
$A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
$m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
$m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
$m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
$B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
$m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
$m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
$m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
$B = ($B << 8) | ($B >> 24 & 0xff);
$A = $this->safe_intval($A + $B);
$K[] = $A;
$A = $this->safe_intval($A + $B);
$K[] = ($A << 9 | $A >> 23 & 0x1ff);
}
for ($i = 0; $i < 256; ++$i) {
$S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
$S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
$S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
$S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
}
}
$this->K = $K;
$this->S0 = $S0;
$this->S1 = $S1;
$this->S2 = $S2;
$this->S3 = $S3;
}
/**
* _mdsrem function using by the twofish cipher algorithm
*
* @access private
* @param string $A
* @param string $B
* @return array
*/
function _mdsrem($A, $B)
{
// No gain by unrolling this loop.
for ($i = 0; $i < 8; ++$i) {
// Get most significant coefficient.
$t = 0xff & ($B >> 24);
// Shift the others up.
$B = ($B << 8) | (0xff & ($A >> 24));
$A<<= 8;
$u = $t << 1;
// Subtract the modular polynomial on overflow.
if ($t & 0x80) {
$u^= 0x14d;
}
// Remove t * (a * x^2 + 1).
$B ^= $t ^ ($u << 16);
// Form u = a*t + t/a = t*(a + 1/a).
$u^= 0x7fffffff & ($t >> 1);
// Add the modular polynomial on underflow.
if ($t & 0x01) {
$u^= 0xa6 ;
}
// Remove t * (a + 1/a) * (x^3 + x).
$B^= ($u << 24) | ($u << 8);
}
return array(
0xff & $B >> 24,
0xff & $B >> 16,
0xff & $B >> 8,
0xff & $B);
}
/**
* Encrypts a block
*
* @access private
* @param string $in
* @return string
*/
function _encryptBlock($in)
{
$S0 = $this->S0;
$S1 = $this->S1;
$S2 = $this->S2;
$S3 = $this->S3;
$K = $this->K;
$in = unpack("V4", $in);
$R0 = $K[0] ^ $in[1];
$R1 = $K[1] ^ $in[2];
$R2 = $K[2] ^ $in[3];
$R3 = $K[3] ^ $in[4];
$ki = 7;
while ($ki < 39) {
$t0 = $S0[ $R0 & 0xff] ^
$S1[($R0 >> 8) & 0xff] ^
$S2[($R0 >> 16) & 0xff] ^
$S3[($R0 >> 24) & 0xff];
$t1 = $S0[($R1 >> 24) & 0xff] ^
$S1[ $R1 & 0xff] ^
$S2[($R1 >> 8) & 0xff] ^
$S3[($R1 >> 16) & 0xff];
$R2^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
$t0 = $S0[ $R2 & 0xff] ^
$S1[($R2 >> 8) & 0xff] ^
$S2[($R2 >> 16) & 0xff] ^
$S3[($R2 >> 24) & 0xff];
$t1 = $S0[($R3 >> 24) & 0xff] ^
$S1[ $R3 & 0xff] ^
$S2[($R3 >> 8) & 0xff] ^
$S3[($R3 >> 16) & 0xff];
$R0^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
}
// @codingStandardsIgnoreStart
return pack("V4", $K[4] ^ $R2,
$K[5] ^ $R3,
$K[6] ^ $R0,
$K[7] ^ $R1);
// @codingStandardsIgnoreEnd
}
/**
* Decrypts a block
*
* @access private
* @param string $in
* @return string
*/
function _decryptBlock($in)
{
$S0 = $this->S0;
$S1 = $this->S1;
$S2 = $this->S2;
$S3 = $this->S3;
$K = $this->K;
$in = unpack("V4", $in);
$R0 = $K[4] ^ $in[1];
$R1 = $K[5] ^ $in[2];
$R2 = $K[6] ^ $in[3];
$R3 = $K[7] ^ $in[4];
$ki = 40;
while ($ki > 8) {
$t0 = $S0[$R0 & 0xff] ^
$S1[$R0 >> 8 & 0xff] ^
$S2[$R0 >> 16 & 0xff] ^
$S3[$R0 >> 24 & 0xff];
$t1 = $S0[$R1 >> 24 & 0xff] ^
$S1[$R1 & 0xff] ^
$S2[$R1 >> 8 & 0xff] ^
$S3[$R1 >> 16 & 0xff];
$R3^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
$t0 = $S0[$R2 & 0xff] ^
$S1[$R2 >> 8 & 0xff] ^
$S2[$R2 >> 16 & 0xff] ^
$S3[$R2 >> 24 & 0xff];
$t1 = $S0[$R3 >> 24 & 0xff] ^
$S1[$R3 & 0xff] ^
$S2[$R3 >> 8 & 0xff] ^
$S3[$R3 >> 16 & 0xff];
$R1^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
}
// @codingStandardsIgnoreStart
return pack("V4", $K[0] ^ $R2,
$K[1] ^ $R3,
$K[2] ^ $R0,
$K[3] ^ $R1);
// @codingStandardsIgnoreEnd
}
/**
* Setup the performance-optimized function for de/encrypt()
*
* @see Crypt_Base::_setupInlineCrypt()
* @access private
*/
function _setupInlineCrypt()
{
$lambda_functions =& Crypt_Twofish::_getLambdaFunctions();
// Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
// (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
// Generation of a unique hash for our generated code
$code_hash = "Crypt_Twofish, {$this->mode}";
if ($gen_hi_opt_code) {
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
}
$safeint = $this->safe_intval_inline();
if (!isset($lambda_functions[$code_hash])) {
switch (true) {
case $gen_hi_opt_code:
$K = $this->K;
$init_crypt = '
static $S0, $S1, $S2, $S3;
if (!$S0) {
for ($i = 0; $i < 256; ++$i) {
$S0[] = (int)$self->S0[$i];
$S1[] = (int)$self->S1[$i];
$S2[] = (int)$self->S2[$i];
$S3[] = (int)$self->S3[$i];
}
}
';
break;
default:
$K = array();
for ($i = 0; $i < 40; ++$i) {
$K[] = '$K_' . $i;
}
$init_crypt = '
$S0 = $self->S0;
$S1 = $self->S1;
$S2 = $self->S2;
$S3 = $self->S3;
list(' . implode(',', $K) . ') = $self->K;
';
}
// Generating encrypt code:
$encrypt_block = '
$in = unpack("V4", $in);
$R0 = '.$K[0].' ^ $in[1];
$R1 = '.$K[1].' ^ $in[2];
$R2 = '.$K[2].' ^ $in[3];
$R3 = '.$K[3].' ^ $in[4];
';
for ($ki = 7, $i = 0; $i < 8; ++$i) {
$encrypt_block.= '
$t0 = $S0[ $R0 & 0xff] ^
$S1[($R0 >> 8) & 0xff] ^
$S2[($R0 >> 16) & 0xff] ^
$S3[($R0 >> 24) & 0xff];
$t1 = $S0[($R1 >> 24) & 0xff] ^
$S1[ $R1 & 0xff] ^
$S2[($R1 >> 8) & 0xff] ^
$S3[($R1 >> 16) & 0xff];
$R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . ';
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
$t0 = $S0[ $R2 & 0xff] ^
$S1[($R2 >> 8) & 0xff] ^
$S2[($R2 >> 16) & 0xff] ^
$S3[($R2 >> 24) & 0xff];
$t1 = $S0[($R3 >> 24) & 0xff] ^
$S1[ $R3 & 0xff] ^
$S2[($R3 >> 8) & 0xff] ^
$S3[($R3 >> 16) & 0xff];
$R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . ';
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
';
}
$encrypt_block.= '
$in = pack("V4", ' . $K[4] . ' ^ $R2,
' . $K[5] . ' ^ $R3,
' . $K[6] . ' ^ $R0,
' . $K[7] . ' ^ $R1);
';
// Generating decrypt code:
$decrypt_block = '
$in = unpack("V4", $in);
$R0 = '.$K[4].' ^ $in[1];
$R1 = '.$K[5].' ^ $in[2];
$R2 = '.$K[6].' ^ $in[3];
$R3 = '.$K[7].' ^ $in[4];
';
for ($ki = 40, $i = 0; $i < 8; ++$i) {
$decrypt_block.= '
$t0 = $S0[$R0 & 0xff] ^
$S1[$R0 >> 8 & 0xff] ^
$S2[$R0 >> 16 & 0xff] ^
$S3[$R0 >> 24 & 0xff];
$t1 = $S0[$R1 >> 24 & 0xff] ^
$S1[$R1 & 0xff] ^
$S2[$R1 >> 8 & 0xff] ^
$S3[$R1 >> 16 & 0xff];
$R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
$t0 = $S0[$R2 & 0xff] ^
$S1[$R2 >> 8 & 0xff] ^
$S2[$R2 >> 16 & 0xff] ^
$S3[$R2 >> 24 & 0xff];
$t1 = $S0[$R3 >> 24 & 0xff] ^
$S1[$R3 & 0xff] ^
$S2[$R3 >> 8 & 0xff] ^
$S3[$R3 >> 16 & 0xff];
$R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
';
}
$decrypt_block.= '
$in = pack("V4", ' . $K[0] . ' ^ $R2,
' . $K[1] . ' ^ $R3,
' . $K[2] . ' ^ $R0,
' . $K[3] . ' ^ $R1);
';
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
'init_crypt' => $init_crypt,
'init_encrypt' => '',
'init_decrypt' => '',
'encrypt_block' => $encrypt_block,
'decrypt_block' => $decrypt_block
)
);
}
$this->inline_crypt = $lambda_functions[$code_hash];
}
}
+604
View File
@@ -0,0 +1,604 @@
<?php
/**
* Pure-PHP ANSI Decoder
*
* PHP versions 4 and 5
*
* If you call read() in Net_SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back.
* They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a
* {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what
* color to display them in, etc. File_ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator.
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category File
* @package File_ANSI
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2012 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Pure-PHP ANSI Decoder
*
* @package File_ANSI
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class File_ANSI
{
/**
* Max Width
*
* @var int
* @access private
*/
var $max_x;
/**
* Max Height
*
* @var int
* @access private
*/
var $max_y;
/**
* Max History
*
* @var int
* @access private
*/
var $max_history;
/**
* History
*
* @var array
* @access private
*/
var $history;
/**
* History Attributes
*
* @var array
* @access private
*/
var $history_attrs;
/**
* Current Column
*
* @var int
* @access private
*/
var $x;
/**
* Current Row
*
* @var int
* @access private
*/
var $y;
/**
* Old Column
*
* @var int
* @access private
*/
var $old_x;
/**
* Old Row
*
* @var int
* @access private
*/
var $old_y;
/**
* An empty attribute cell
*
* @var object
* @access private
*/
var $base_attr_cell;
/**
* The current attribute cell
*
* @var object
* @access private
*/
var $attr_cell;
/**
* An empty attribute row
*
* @var array
* @access private
*/
var $attr_row;
/**
* The current screen text
*
* @var array
* @access private
*/
var $screen;
/**
* The current screen attributes
*
* @var array
* @access private
*/
var $attrs;
/**
* Current ANSI code
*
* @var string
* @access private
*/
var $ansi;
/**
* Tokenization
*
* @var array
* @access private
*/
var $tokenization;
/**
* Default Constructor.
*
* @return File_ANSI
* @access public
*/
function __construct()
{
$attr_cell = new stdClass();
$attr_cell->bold = false;
$attr_cell->underline = false;
$attr_cell->blink = false;
$attr_cell->background = 'black';
$attr_cell->foreground = 'white';
$attr_cell->reverse = false;
$this->base_attr_cell = clone($attr_cell);
$this->attr_cell = clone($attr_cell);
$this->setHistory(200);
$this->setDimensions(80, 24);
}
/**
* PHP4 compatible Default Constructor.
*
* @see self::__construct()
* @access public
*/
function File_ANSI()
{
$this->__construct($mode);
}
/**
* Set terminal width and height
*
* Resets the screen as well
*
* @param int $x
* @param int $y
* @access public
*/
function setDimensions($x, $y)
{
$this->max_x = $x - 1;
$this->max_y = $y - 1;
$this->x = $this->y = 0;
$this->history = $this->history_attrs = array();
$this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell);
$this->screen = array_fill(0, $this->max_y + 1, '');
$this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row);
$this->ansi = '';
}
/**
* Set the number of lines that should be logged past the terminal height
*
* @param int $x
* @param int $y
* @access public
*/
function setHistory($history)
{
$this->max_history = $history;
}
/**
* Load a string
*
* @param string $source
* @access public
*/
function loadString($source)
{
$this->setDimensions($this->max_x + 1, $this->max_y + 1);
$this->appendString($source);
}
/**
* Appdend a string
*
* @param string $source
* @access public
*/
function appendString($source)
{
$this->tokenization = array('');
for ($i = 0; $i < strlen($source); $i++) {
if (strlen($this->ansi)) {
$this->ansi.= $source[$i];
$chr = ord($source[$i]);
// http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements
// single character CSI's not currently supported
switch (true) {
case $this->ansi == "\x1B=":
$this->ansi = '';
continue 2;
case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['):
case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126:
break;
default:
continue 2;
}
$this->tokenization[] = $this->ansi;
$this->tokenization[] = '';
// http://ascii-table.com/ansi-escape-sequences-vt-100.php
switch ($this->ansi) {
case "\x1B[H": // Move cursor to upper left corner
$this->old_x = $this->x;
$this->old_y = $this->y;
$this->x = $this->y = 0;
break;
case "\x1B[J": // Clear screen from cursor down
$this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y));
$this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, ''));
$this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y));
$this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row));
if (count($this->history) == $this->max_history) {
array_shift($this->history);
array_shift($this->history_attrs);
}
case "\x1B[K": // Clear screen from cursor right
$this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - $this->x - 1, $this->base_attr_cell));
break;
case "\x1B[2K": // Clear entire line
$this->screen[$this->y] = str_repeat(' ', $this->x);
$this->attrs[$this->y] = $this->attr_row;
break;
case "\x1B[?1h": // set cursor key to application
case "\x1B[?25h": // show the cursor
case "\x1B(B": // set united states g0 character set
break;
case "\x1BE": // Move to next line
$this->_newLine();
$this->x = 0;
break;
default:
switch (true) {
case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines
$this->old_y = $this->y;
$this->y+= $match[1];
break;
case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
$this->old_x = $this->x;
$this->old_y = $this->y;
$this->x = $match[2] - 1;
$this->y = $match[1] - 1;
break;
case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
$this->old_x = $this->x;
$this->x+= $match[1];
break;
case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
$this->old_x = $this->x;
$this->x-= $match[1];
if ($this->x < 0) {
$this->x = 0;
}
break;
case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
break;
case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
$attr_cell = &$this->attr_cell;
$mods = explode(';', $match[1]);
foreach ($mods as $mod) {
switch ($mod) {
case 0: // Turn off character attributes
$attr_cell = clone($this->base_attr_cell);
break;
case 1: // Turn bold mode on
$attr_cell->bold = true;
break;
case 4: // Turn underline mode on
$attr_cell->underline = true;
break;
case 5: // Turn blinking mode on
$attr_cell->blink = true;
break;
case 7: // Turn reverse video on
$attr_cell->reverse = !$attr_cell->reverse;
$temp = $attr_cell->background;
$attr_cell->background = $attr_cell->foreground;
$attr_cell->foreground = $temp;
break;
default: // set colors
//$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground;
$front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' };
//$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background;
$back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' };
switch ($mod) {
// @codingStandardsIgnoreStart
case 30: $front = 'black'; break;
case 31: $front = 'red'; break;
case 32: $front = 'green'; break;
case 33: $front = 'yellow'; break;
case 34: $front = 'blue'; break;
case 35: $front = 'magenta'; break;
case 36: $front = 'cyan'; break;
case 37: $front = 'white'; break;
case 40: $back = 'black'; break;
case 41: $back = 'red'; break;
case 42: $back = 'green'; break;
case 43: $back = 'yellow'; break;
case 44: $back = 'blue'; break;
case 45: $back = 'magenta'; break;
case 46: $back = 'cyan'; break;
case 47: $back = 'white'; break;
// @codingStandardsIgnoreEnd
default:
//user_error('Unsupported attribute: ' . $mod);
$this->ansi = '';
break 2;
}
}
}
break;
default:
//user_error("{$this->ansi} is unsupported\r\n");
}
}
$this->ansi = '';
continue;
}
$this->tokenization[count($this->tokenization) - 1].= $source[$i];
switch ($source[$i]) {
case "\r":
$this->x = 0;
break;
case "\n":
$this->_newLine();
break;
case "\x08": // backspace
if ($this->x) {
$this->x--;
$this->attrs[$this->y][$this->x] = clone($this->base_attr_cell);
$this->screen[$this->y] = substr_replace(
$this->screen[$this->y],
$source[$i],
$this->x,
1
);
}
break;
case "\x0F": // shift
break;
case "\x1B": // start ANSI escape code
$this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1);
//if (!strlen($this->tokenization[count($this->tokenization) - 1])) {
// array_pop($this->tokenization);
//}
$this->ansi.= "\x1B";
break;
default:
$this->attrs[$this->y][$this->x] = clone($this->attr_cell);
if ($this->x > strlen($this->screen[$this->y])) {
$this->screen[$this->y] = str_repeat(' ', $this->x);
}
$this->screen[$this->y] = substr_replace(
$this->screen[$this->y],
$source[$i],
$this->x,
1
);
if ($this->x > $this->max_x) {
$this->x = 0;
$this->_newLine();
} else {
$this->x++;
}
}
}
}
/**
* Add a new line
*
* Also update the $this->screen and $this->history buffers
*
* @access private
*/
function _newLine()
{
//if ($this->y < $this->max_y) {
// $this->y++;
//}
while ($this->y >= $this->max_y) {
$this->history = array_merge($this->history, array(array_shift($this->screen)));
$this->screen[] = '';
$this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
$this->attrs[] = $this->attr_row;
if (count($this->history) >= $this->max_history) {
array_shift($this->history);
array_shift($this->history_attrs);
}
$this->y--;
}
$this->y++;
}
/**
* Returns the current coordinate without preformating
*
* @access private
* @return string
*/
function _processCoordinate($last_attr, $cur_attr, $char)
{
$output = '';
if ($last_attr != $cur_attr) {
$close = $open = '';
if ($last_attr->foreground != $cur_attr->foreground) {
if ($cur_attr->foreground != 'white') {
$open.= '<span style="color: ' . $cur_attr->foreground . '">';
}
if ($last_attr->foreground != 'white') {
$close = '</span>' . $close;
}
}
if ($last_attr->background != $cur_attr->background) {
if ($cur_attr->background != 'black') {
$open.= '<span style="background: ' . $cur_attr->background . '">';
}
if ($last_attr->background != 'black') {
$close = '</span>' . $close;
}
}
if ($last_attr->bold != $cur_attr->bold) {
if ($cur_attr->bold) {
$open.= '<b>';
} else {
$close = '</b>' . $close;
}
}
if ($last_attr->underline != $cur_attr->underline) {
if ($cur_attr->underline) {
$open.= '<u>';
} else {
$close = '</u>' . $close;
}
}
if ($last_attr->blink != $cur_attr->blink) {
if ($cur_attr->blink) {
$open.= '<blink>';
} else {
$close = '</blink>' . $close;
}
}
$output.= $close . $open;
}
$output.= htmlspecialchars($char);
return $output;
}
/**
* Returns the current screen without preformating
*
* @access private
* @return string
*/
function _getScreen()
{
$output = '';
$last_attr = $this->base_attr_cell;
for ($i = 0; $i <= $this->max_y; $i++) {
for ($j = 0; $j <= $this->max_x; $j++) {
$cur_attr = $this->attrs[$i][$j];
$output.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : '');
$last_attr = $this->attrs[$i][$j];
}
$output.= "\r\n";
}
$output = substr($output, 0, -2);
// close any remaining open tags
$output.= $this->_processCoordinate($last_attr, $this->base_attr_cell, '');
return rtrim($output);
}
/**
* Returns the current screen
*
* @access public
* @return string
*/
function getScreen()
{
return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $this->_getScreen() . '</pre>';
}
/**
* Returns the current screen and the x previous lines
*
* @access public
* @return string
*/
function getHistory()
{
$scrollback = '';
$last_attr = $this->base_attr_cell;
for ($i = 0; $i < count($this->history); $i++) {
for ($j = 0; $j <= $this->max_x + 1; $j++) {
$cur_attr = $this->history_attrs[$i][$j];
$scrollback.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : '');
$last_attr = $this->history_attrs[$i][$j];
}
$scrollback.= "\r\n";
}
$base_attr_cell = $this->base_attr_cell;
$this->base_attr_cell = $last_attr;
$scrollback.= $this->_getScreen();
$this->base_attr_cell = $base_attr_cell;
return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $scrollback . '</span></pre>';
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+378
View File
@@ -0,0 +1,378 @@
<?php
/**
* Pure-PHP implementation of SCP.
*
* PHP versions 4 and 5
*
* The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Net/SCP.php';
* include 'Net/SSH2.php';
*
* $ssh = new Net_SSH2('www.domain.tld');
* if (!$ssh->login('username', 'password')) {
* exit('bad login');
* }
*
* $scp = new Net_SCP($ssh);
* $scp->put('abcd', str_repeat('x', 1024*1024));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net
* @package Net_SCP
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2010 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**#@+
* @access public
* @see self::put()
*/
/**
* Reads data from a local file.
*/
define('NET_SCP_LOCAL_FILE', 1);
/**
* Reads data from a string.
*/
define('NET_SCP_STRING', 2);
/**#@-*/
/**#@+
* @access private
* @see self::_send()
* @see self::_receive()
*/
/**
* SSH1 is being used.
*/
define('NET_SCP_SSH1', 1);
/**
* SSH2 is being used.
*/
define('NET_SCP_SSH2', 2);
/**#@-*/
/**
* Pure-PHP implementations of SCP.
*
* @package Net_SCP
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Net_SCP
{
/**
* SSH Object
*
* @var object
* @access private
*/
var $ssh;
/**
* Packet Size
*
* @var int
* @access private
*/
var $packet_size;
/**
* Mode
*
* @var int
* @access private
*/
var $mode;
/**
* Default Constructor.
*
* Connects to an SSH server
*
* @param Net_SSH1|Net_SSH2 $ssh
* @return Net_SCP
* @access public
*/
function __construct($ssh)
{
if (!is_object($ssh)) {
return;
}
switch (strtolower(get_class($ssh))) {
case 'net_ssh2':
$this->mode = NET_SCP_SSH2;
break;
case 'net_ssh1':
$this->packet_size = 50000;
$this->mode = NET_SCP_SSH1;
break;
default:
return;
}
$this->ssh = $ssh;
}
/**
* PHP4 compatible Default Constructor.
*
* @see self::__construct()
* @param Net_SSH1|Net_SSH2 $ssh
* @access public
*/
function Net_SCP($ssh)
{
$this->__construct($ssh);
}
/**
* Uploads a file to the SCP server.
*
* By default, Net_SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
* So, for example, if you set $data to 'filename.ext' and then do Net_SCP::get(), you will get a file, twelve bytes
* long, containing 'filename.ext' as its contents.
*
* Setting $mode to NET_SCP_LOCAL_FILE will change the above behavior. With NET_SCP_LOCAL_FILE, $remote_file will
* contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
* large $remote_file will be, as well.
*
* Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
* care of that, yourself.
*
* @param string $remote_file
* @param string $data
* @param int $mode
* @param callable $callback
* @return bool
* @access public
*/
function put($remote_file, $data, $mode = NET_SCP_STRING, $callback = null)
{
if (!isset($this->ssh)) {
return false;
}
if (empty($remote_file)) {
user_error('remote_file cannot be blank', E_USER_NOTICE);
return false;
}
if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
return false;
}
$temp = $this->_receive();
if ($temp !== chr(0)) {
return false;
}
if ($this->mode == NET_SCP_SSH2) {
$this->packet_size = $this->ssh->packet_size_client_to_server[NET_SSH2_CHANNEL_EXEC] - 4;
}
$remote_file = basename($remote_file);
if ($mode == NET_SCP_STRING) {
$size = strlen($data);
} else {
if (!is_file($data)) {
user_error("$data is not a valid file", E_USER_NOTICE);
return false;
}
$fp = @fopen($data, 'rb');
if (!$fp) {
return false;
}
$size = filesize($data);
}
$this->_send('C0644 ' . $size . ' ' . $remote_file . "\n");
$temp = $this->_receive();
if ($temp !== chr(0)) {
return false;
}
$sent = 0;
while ($sent < $size) {
$temp = $mode & NET_SCP_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size);
$this->_send($temp);
$sent+= strlen($temp);
if (is_callable($callback)) {
call_user_func($callback, $sent);
}
}
$this->_close();
if ($mode != NET_SCP_STRING) {
fclose($fp);
}
return true;
}
/**
* Downloads a file from the SCP server.
*
* Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
* the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the
* operation
*
* @param string $remote_file
* @param string $local_file
* @return mixed
* @access public
*/
function get($remote_file, $local_file = false)
{
if (!isset($this->ssh)) {
return false;
}
if (!$this->ssh->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from
return false;
}
$this->_send("\0");
if (!preg_match('#(?<perms>[^ ]+) (?<size>\d+) (?<name>.+)#', rtrim($this->_receive()), $info)) {
return false;
}
$this->_send("\0");
$size = 0;
if ($local_file !== false) {
$fp = @fopen($local_file, 'wb');
if (!$fp) {
return false;
}
}
$content = '';
while ($size < $info['size']) {
$data = $this->_receive();
// SCP usually seems to split stuff out into 16k chunks
$size+= strlen($data);
if ($local_file === false) {
$content.= $data;
} else {
fputs($fp, $data);
}
}
$this->_close();
if ($local_file !== false) {
fclose($fp);
return true;
}
return $content;
}
/**
* Sends a packet to an SSH server
*
* @param string $data
* @access private
*/
function _send($data)
{
switch ($this->mode) {
case NET_SCP_SSH2:
$this->ssh->_send_channel_packet(NET_SSH2_CHANNEL_EXEC, $data);
break;
case NET_SCP_SSH1:
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
$this->ssh->_send_binary_packet($data);
}
}
/**
* Receives a packet from an SSH server
*
* @return string
* @access private
*/
function _receive()
{
switch ($this->mode) {
case NET_SCP_SSH2:
return $this->ssh->_get_channel_packet(NET_SSH2_CHANNEL_EXEC, true);
case NET_SCP_SSH1:
if (!$this->ssh->bitmap) {
return false;
}
while (true) {
$response = $this->ssh->_get_binary_packet();
switch ($response[NET_SSH1_RESPONSE_TYPE]) {
case NET_SSH1_SMSG_STDOUT_DATA:
if (strlen($response[NET_SSH1_RESPONSE_DATA]) < 4) {
return false;
}
extract(unpack('Nlength', $response[NET_SSH1_RESPONSE_DATA]));
return $this->ssh->_string_shift($response[NET_SSH1_RESPONSE_DATA], $length);
case NET_SSH1_SMSG_STDERR_DATA:
break;
case NET_SSH1_SMSG_EXITSTATUS:
$this->ssh->_send_binary_packet(chr(NET_SSH1_CMSG_EXIT_CONFIRMATION));
fclose($this->ssh->fsock);
$this->ssh->bitmap = 0;
return false;
default:
user_error('Unknown packet received', E_USER_NOTICE);
return false;
}
}
}
}
/**
* Closes the connection to an SSH server
*
* @access private
*/
function _close()
{
switch ($this->mode) {
case NET_SCP_SSH2:
$this->ssh->_close_channel(NET_SSH2_CHANNEL_EXEC, true);
break;
case NET_SCP_SSH1:
$this->ssh->disconnect();
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,815 @@
<?php
/**
* SFTP Stream Wrapper
*
* Creates an sftp:// protocol handler that can be used with, for example, fopen(), dir(), etc.
*
* PHP version 5
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net
* @package Net_SFTP_Stream
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2013 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* SFTP Stream Wrapper
*
* @package Net_SFTP_Stream
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Net_SFTP_Stream
{
/**
* SFTP instances
*
* Rather than re-create the connection we re-use instances if possible
*
* @var array
*/
static $instances;
/**
* SFTP instance
*
* @var object
* @access private
*/
var $sftp;
/**
* Path
*
* @var string
* @access private
*/
var $path;
/**
* Mode
*
* @var string
* @access private
*/
var $mode;
/**
* Position
*
* @var int
* @access private
*/
var $pos;
/**
* Size
*
* @var int
* @access private
*/
var $size;
/**
* Directory entries
*
* @var array
* @access private
*/
var $entries;
/**
* EOF flag
*
* @var bool
* @access private
*/
var $eof;
/**
* Context resource
*
* Technically this needs to be publically accessible so PHP can set it directly
*
* @var resource
* @access public
*/
var $context;
/**
* Notification callback function
*
* @var callable
* @access public
*/
var $notification;
/**
* Registers this class as a URL wrapper.
*
* @param string $protocol The wrapper name to be registered.
* @return bool True on success, false otherwise.
* @access public
*/
static function register($protocol = 'sftp')
{
if (in_array($protocol, stream_get_wrappers(), true)) {
return false;
}
$class = function_exists('get_called_class') ? get_called_class() : __CLASS__;
return stream_wrapper_register($protocol, $class);
}
/**
* The Constructor
*
* @access public
*/
function __construct()
{
if (defined('NET_SFTP_STREAM_LOGGING')) {
echo "__construct()\r\n";
}
if (!class_exists('Net_SFTP')) {
include_once 'Net/SFTP.php';
}
}
/**
* Path Parser
*
* Extract a path from a URI and actually connect to an SSH server if appropriate
*
* If "notification" is set as a context parameter the message code for successful login is
* NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE.
*
* @param string $path
* @return string
* @access private
*/
function _parse_path($path)
{
$orig = $path;
extract(parse_url($path) + array('port' => 22));
if (isset($query)) {
$path.= '?' . $query;
} elseif (preg_match('/(\?|\?#)$/', $orig)) {
$path.= '?';
}
if (isset($fragment)) {
$path.= '#' . $fragment;
} elseif ($orig[strlen($orig) - 1] == '#') {
$path.= '#';
}
if (!isset($host)) {
return false;
}
if (isset($this->context)) {
$context = stream_context_get_params($this->context);
if (isset($context['notification'])) {
$this->notification = $context['notification'];
}
}
if ($host[0] == '$') {
$host = substr($host, 1);
global ${$host};
if (!is_object($$host) || get_class($$host) != 'Net_SFTP') {
return false;
}
$this->sftp = $$host;
} else {
if (isset($this->context)) {
$context = stream_context_get_options($this->context);
}
if (isset($context[$scheme]['session'])) {
$sftp = $context[$scheme]['session'];
}
if (isset($context[$scheme]['sftp'])) {
$sftp = $context[$scheme]['sftp'];
}
if (isset($sftp) && is_object($sftp) && get_class($sftp) == 'Net_SFTP') {
$this->sftp = $sftp;
return $path;
}
if (isset($context[$scheme]['username'])) {
$user = $context[$scheme]['username'];
}
if (isset($context[$scheme]['password'])) {
$pass = $context[$scheme]['password'];
}
if (isset($context[$scheme]['privkey']) && is_object($context[$scheme]['privkey']) && get_Class($context[$scheme]['privkey']) == 'Crypt_RSA') {
$pass = $context[$scheme]['privkey'];
}
if (!isset($user) || !isset($pass)) {
return false;
}
// casting $pass to a string is necessary in the event that it's a Crypt_RSA object
if (isset(self::$instances[$host][$port][$user][(string) $pass])) {
$this->sftp = self::$instances[$host][$port][$user][(string) $pass];
} else {
$this->sftp = new Net_SFTP($host, $port);
$this->sftp->disableStatCache();
if (isset($this->notification) && is_callable($this->notification)) {
/* if !is_callable($this->notification) we could do this:
user_error('fopen(): failed to call user notifier', E_USER_WARNING);
the ftp wrapper gives errors like that when the notifier isn't callable.
i've opted not to do that, however, since the ftp wrapper gives the line
on which the fopen occurred as the line number - not the line that the
user_error is on.
*/
call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
if (!$this->sftp->login($user, $pass)) {
call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0);
return false;
}
call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0);
} else {
if (!$this->sftp->login($user, $pass)) {
return false;
}
}
self::$instances[$host][$port][$user][(string) $pass] = $this->sftp;
}
}
return $path;
}
/**
* Opens file or URL
*
* @param string $path
* @param string $mode
* @param int $options
* @param string $opened_path
* @return bool
* @access public
*/
function _stream_open($path, $mode, $options, &$opened_path)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
$this->path = $path;
$this->size = $this->sftp->size($path);
$this->mode = preg_replace('#[bt]$#', '', $mode);
$this->eof = false;
if ($this->size === false) {
if ($this->mode[0] == 'r') {
return false;
} else {
$this->sftp->touch($path);
$this->size = 0;
}
} else {
switch ($this->mode[0]) {
case 'x':
return false;
case 'w':
$this->sftp->truncate($path, 0);
$this->size = 0;
}
}
$this->pos = $this->mode[0] != 'a' ? 0 : $this->size;
return true;
}
/**
* Read from stream
*
* @param int $count
* @return mixed
* @access public
*/
function _stream_read($count)
{
switch ($this->mode) {
case 'w':
case 'a':
case 'x':
case 'c':
return false;
}
// commented out because some files - eg. /dev/urandom - will say their size is 0 when in fact it's kinda infinite
//if ($this->pos >= $this->size) {
// $this->eof = true;
// return false;
//}
$result = $this->sftp->get($this->path, false, $this->pos, $count);
if (isset($this->notification) && is_callable($this->notification)) {
if ($result === false) {
call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
return 0;
}
// seems that PHP calls stream_read in 8k chunks
call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $this->size);
}
if (empty($result)) { // ie. false or empty string
$this->eof = true;
return false;
}
$this->pos+= strlen($result);
return $result;
}
/**
* Write to stream
*
* @param string $data
* @return mixed
* @access public
*/
function _stream_write($data)
{
switch ($this->mode) {
case 'r':
return false;
}
$result = $this->sftp->put($this->path, $data, NET_SFTP_STRING, $this->pos);
if (isset($this->notification) && is_callable($this->notification)) {
if (!$result) {
call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
return 0;
}
// seems that PHP splits up strings into 8k blocks before calling stream_write
call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data));
}
if ($result === false) {
return false;
}
$this->pos+= strlen($data);
if ($this->pos > $this->size) {
$this->size = $this->pos;
}
$this->eof = false;
return strlen($data);
}
/**
* Retrieve the current position of a stream
*
* @return int
* @access public
*/
function _stream_tell()
{
return $this->pos;
}
/**
* Tests for end-of-file on a file pointer
*
* In my testing there are four classes functions that normally effect the pointer:
* fseek, fputs / fwrite, fgets / fread and ftruncate.
*
* Only fgets / fread, however, results in feof() returning true. do fputs($fp, 'aaa') on a blank file and feof()
* will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof()
* will return false. do fread($fp, 1) and feof() will then return true.
*
* @return bool
* @access public
*/
function _stream_eof()
{
return $this->eof;
}
/**
* Seeks to specific location in a stream
*
* @param int $offset
* @param int $whence
* @return bool
* @access public
*/
function _stream_seek($offset, $whence)
{
switch ($whence) {
case SEEK_SET:
if ($offset >= $this->size || $offset < 0) {
return false;
}
break;
case SEEK_CUR:
$offset+= $this->pos;
break;
case SEEK_END:
$offset+= $this->size;
}
$this->pos = $offset;
$this->eof = false;
return true;
}
/**
* Change stream options
*
* @param string $path
* @param int $option
* @param mixed $var
* @return bool
* @access public
*/
function _stream_metadata($path, $option, $var)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
// stream_metadata was introduced in PHP 5.4.0 but as of 5.4.11 the constants haven't been defined
// see http://www.php.net/streamwrapper.stream-metadata and https://bugs.php.net/64246
// and https://github.com/php/php-src/blob/master/main/php_streams.h#L592
switch ($option) {
case 1: // PHP_STREAM_META_TOUCH
return $this->sftp->touch($path, $var[0], $var[1]);
case 2: // PHP_STREAM_OWNER_NAME
case 3: // PHP_STREAM_GROUP_NAME
return false;
case 4: // PHP_STREAM_META_OWNER
return $this->sftp->chown($path, $var);
case 5: // PHP_STREAM_META_GROUP
return $this->sftp->chgrp($path, $var);
case 6: // PHP_STREAM_META_ACCESS
return $this->sftp->chmod($path, $var) !== false;
}
}
/**
* Retrieve the underlaying resource
*
* @param int $cast_as
* @return resource
* @access public
*/
function _stream_cast($cast_as)
{
return $this->sftp->fsock;
}
/**
* Advisory file locking
*
* @param int $operation
* @return bool
* @access public
*/
function _stream_lock($operation)
{
return false;
}
/**
* Renames a file or directory
*
* Attempts to rename oldname to newname, moving it between directories if necessary.
* If newname exists, it will be overwritten. This is a departure from what Net_SFTP
* does.
*
* @param string $path_from
* @param string $path_to
* @return bool
* @access public
*/
function _rename($path_from, $path_to)
{
$path1 = parse_url($path_from);
$path2 = parse_url($path_to);
unset($path1['path'], $path2['path']);
if ($path1 != $path2) {
return false;
}
$path_from = $this->_parse_path($path_from);
$path_to = parse_url($path_to);
if ($path_from === false) {
return false;
}
$path_to = $path_to['path']; // the $component part of parse_url() was added in PHP 5.1.2
// "It is an error if there already exists a file with the name specified by newpath."
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5
if (!$this->sftp->rename($path_from, $path_to)) {
if ($this->sftp->stat($path_to)) {
return $this->sftp->delete($path_to, true) && $this->sftp->rename($path_from, $path_to);
}
return false;
}
return true;
}
/**
* Open directory handle
*
* The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and
* removed in 5.4 I'm just going to ignore it.
*
* Also, nlist() is the best that this function is realistically going to be able to do. When an SFTP client
* sends a SSH_FXP_READDIR packet you don't generally get info on just one file but on multiple files. Quoting
* the SFTP specs:
*
* The SSH_FXP_NAME response has the following format:
*
* uint32 id
* uint32 count
* repeats count times:
* string filename
* string longname
* ATTRS attrs
*
* @param string $path
* @param int $options
* @return bool
* @access public
*/
function _dir_opendir($path, $options)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
$this->pos = 0;
$this->entries = $this->sftp->nlist($path);
return $this->entries !== false;
}
/**
* Read entry from directory handle
*
* @return mixed
* @access public
*/
function _dir_readdir()
{
if (isset($this->entries[$this->pos])) {
return $this->entries[$this->pos++];
}
return false;
}
/**
* Rewind directory handle
*
* @return bool
* @access public
*/
function _dir_rewinddir()
{
$this->pos = 0;
return true;
}
/**
* Close directory handle
*
* @return bool
* @access public
*/
function _dir_closedir()
{
return true;
}
/**
* Create a directory
*
* Only valid $options is STREAM_MKDIR_RECURSIVE
*
* @param string $path
* @param int $mode
* @param int $options
* @return bool
* @access public
*/
function _mkdir($path, $mode, $options)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
return $this->sftp->mkdir($path, $mode, $options & STREAM_MKDIR_RECURSIVE);
}
/**
* Removes a directory
*
* Only valid $options is STREAM_MKDIR_RECURSIVE per <http://php.net/streamwrapper.rmdir>, however,
* <http://php.net/rmdir> does not have a $recursive parameter as mkdir() does so I don't know how
* STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as
* $options. What does 8 correspond to?
*
* @param string $path
* @param int $mode
* @param int $options
* @return bool
* @access public
*/
function _rmdir($path, $options)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
return $this->sftp->rmdir($path);
}
/**
* Flushes the output
*
* See <http://php.net/fflush>. Always returns true because Net_SFTP doesn't cache stuff before writing
*
* @return bool
* @access public
*/
function _stream_flush()
{
return true;
}
/**
* Retrieve information about a file resource
*
* @return mixed
* @access public
*/
function _stream_stat()
{
$results = $this->sftp->stat($this->path);
if ($results === false) {
return false;
}
return $results;
}
/**
* Delete a file
*
* @param string $path
* @return bool
* @access public
*/
function _unlink($path)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
return $this->sftp->delete($path, false);
}
/**
* Retrieve information about a file
*
* Ignores the STREAM_URL_STAT_QUIET flag because the entirety of Net_SFTP_Stream is quiet by default
* might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll
* cross that bridge when and if it's reached
*
* @param string $path
* @param int $flags
* @return mixed
* @access public
*/
function _url_stat($path, $flags)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
$results = $flags & STREAM_URL_STAT_LINK ? $this->sftp->lstat($path) : $this->sftp->stat($path);
if ($results === false) {
return false;
}
return $results;
}
/**
* Truncate stream
*
* @param int $new_size
* @return bool
* @access public
*/
function _stream_truncate($new_size)
{
if (!$this->sftp->truncate($this->path, $new_size)) {
return false;
}
$this->eof = false;
$this->size = $new_size;
return true;
}
/**
* Change stream options
*
* STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't.
* The other two aren't supported because of limitations in Net_SFTP.
*
* @param int $option
* @param int $arg1
* @param int $arg2
* @return bool
* @access public
*/
function _stream_set_option($option, $arg1, $arg2)
{
return false;
}
/**
* Close an resource
*
* @access public
*/
function _stream_close()
{
}
/**
* __call Magic Method
*
* When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you.
* Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function
* lets you figure that out.
*
* If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not
* NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method.
*
* @param string
* @param array
* @return mixed
* @access public
*/
function __call($name, $arguments)
{
if (defined('NET_SFTP_STREAM_LOGGING')) {
echo $name . '(';
$last = count($arguments) - 1;
foreach ($arguments as $i => $argument) {
var_export($argument);
if ($i != $last) {
echo ',';
}
}
echo ")\r\n";
}
$name = '_' . $name;
if (!method_exists($this, $name)) {
return false;
}
return call_user_func_array(array($this, $name), $arguments);
}
}
Net_SFTP_Stream::register();
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,561 @@
<?php
/**
* Pure-PHP ssh-agent client.
*
* PHP versions 4 and 5
*
* Here are some examples of how to use this library:
* <code>
* <?php
* include 'System/SSH/Agent.php';
* include 'Net/SSH2.php';
*
* $agent = new System_SSH_Agent();
*
* $ssh = new Net_SSH2('www.domain.tld');
* if (!$ssh->login('username', $agent)) {
* exit('Login Failed');
* }
*
* echo $ssh->exec('pwd');
* echo $ssh->exec('ls -la');
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category System
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
*/
/**#@+
* Message numbers
*
* @access private
*/
// to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1)
define('SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES', 11);
// this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2).
define('SYSTEM_SSH_AGENT_IDENTITIES_ANSWER', 12);
define('SYSTEM_SSH_AGENT_FAILURE', 5);
// the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3)
define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13);
// the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
/**#@-*/
/**@+
* Agent forwarding status
*
* @access private
*/
// no forwarding requested and not active
define('SYSTEM_SSH_AGENT_FORWARD_NONE', 0);
// request agent forwarding when opportune
define('SYSTEM_SSH_AGENT_FORWARD_REQUEST', 1);
// forwarding has been request and is active
define('SYSTEM_SSH_AGENT_FORWARD_ACTIVE', 2);
/**#@-*/
/**@+
* Signature Flags
*
* See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3
*
* @access private
*/
define('SYSTEM_SSH_AGENT_RSA2_256', 2);
define('SYSTEM_SSH_AGENT_RSA2_512', 4);
/**#@-*/
/**
* Pure-PHP ssh-agent client identity object
*
* Instantiation should only be performed by System_SSH_Agent class.
* This could be thought of as implementing an interface that Crypt_RSA
* implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
* The methods in this interface would be getPublicKey, setSignatureMode
* and sign since those are the methods phpseclib looks for to perform
* public key authentication.
*
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @access internal
*/
class System_SSH_Agent_Identity
{
/**
* Key Object
*
* @var Crypt_RSA
* @access private
* @see self::getPublicKey()
*/
var $key;
/**
* Key Blob
*
* @var string
* @access private
* @see self::sign()
*/
var $key_blob;
/**
* Socket Resource
*
* @var resource
* @access private
* @see self::sign()
*/
var $fsock;
/**
* Signature flags
*
* @var int
* @access private
* @see self::sign()
* @see self::setHash()
*/
var $flags = 0;
/**
* Default Constructor.
*
* @param resource $fsock
* @return System_SSH_Agent_Identity
* @access private
*/
function __construct($fsock)
{
$this->fsock = $fsock;
}
/**
* PHP4 compatible Default Constructor.
*
* @see self::__construct()
* @param resource $fsock
* @access public
*/
function System_SSH_Agent_Identity($fsock)
{
$this->__construct($fsock);
}
/**
* Set Public Key
*
* Called by System_SSH_Agent::requestIdentities()
*
* @param Crypt_RSA $key
* @access private
*/
function setPublicKey($key)
{
$this->key = $key;
$this->key->setPublicKey();
}
/**
* Set Public Key
*
* Called by System_SSH_Agent::requestIdentities(). The key blob could be extracted from $this->key
* but this saves a small amount of computation.
*
* @param string $key_blob
* @access private
*/
function setPublicKeyBlob($key_blob)
{
$this->key_blob = $key_blob;
}
/**
* Get Public Key
*
* Wrapper for $this->key->getPublicKey()
*
* @param int $format optional
* @return mixed
* @access public
*/
function getPublicKey($format = null)
{
return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
}
/**
* Set Signature Mode
*
* Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
* ssh-agent's only supported mode is CRYPT_RSA_SIGNATURE_PKCS1
*
* @param int $mode
* @access public
*/
function setSignatureMode($mode)
{
}
/**
* Set Hash
*
* ssh-agent doesn't support using hashes for RSA other than SHA1
*
* @param string $hash
* @access public
*/
function setHash($hash)
{
$this->flags = 0;
switch ($hash) {
case 'sha1':
break;
case 'sha256':
$this->flags = SYSTEM_SSH_AGENT_RSA2_256;
break;
case 'sha512':
$this->flags = SYSTEM_SSH_AGENT_RSA2_512;
break;
default:
user_error('The only supported hashes for RSA are sha1, sha256 and sha512');
}
}
/**
* Create a signature
*
* See "2.6.2 Protocol 2 private key signature request"
*
* @param string $message
* @return string
* @access public
*/
function sign($message)
{
// the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
$packet = pack('CNa*Na*N', SYSTEM_SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags);
$packet = pack('Na*', strlen($packet), $packet);
if (strlen($packet) != fputs($this->fsock, $packet)) {
user_error('Connection closed during signing');
}
$length = current(unpack('N', fread($this->fsock, 4)));
$type = ord(fread($this->fsock, 1));
if ($type != SYSTEM_SSH_AGENT_SIGN_RESPONSE) {
user_error('Unable to retreive signature');
}
$signature_blob = fread($this->fsock, $length - 1);
$length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
if ($length != strlen($signature_blob)) {
user_error('Malformed signature blob');
}
$length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
if ($length > strlen($signature_blob) + 4) {
user_error('Malformed signature blob');
}
$type = $this->_string_shift($signature_blob, $length);
$this->_string_shift($signature_blob, 4);
return $signature_blob;
}
/**
* String Shift
*
* Inspired by array_shift
*
* @param string $string
* @param int $index
* @return string
* @access private
*/
function _string_shift(&$string, $index = 1)
{
$substr = substr($string, 0, $index);
$string = substr($string, $index);
return $substr;
}
}
/**
* Pure-PHP ssh-agent client identity factory
*
* requestIdentities() method pumps out System_SSH_Agent_Identity objects
*
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class System_SSH_Agent
{
/**
* Socket Resource
*
* @var resource
* @access private
*/
var $fsock;
/**
* Agent forwarding status
*
* @access private
*/
var $forward_status = SYSTEM_SSH_AGENT_FORWARD_NONE;
/**
* Buffer for accumulating forwarded authentication
* agent data arriving on SSH data channel destined
* for agent unix socket
*
* @access private
*/
var $socket_buffer = '';
/**
* Tracking the number of bytes we are expecting
* to arrive for the agent socket on the SSH data
* channel
*/
var $expected_bytes = 0;
/**
* Default Constructor
*
* @return System_SSH_Agent
* @access public
*/
function __construct($address = null)
{
if (!$address) {
switch (true) {
case isset($_SERVER['SSH_AUTH_SOCK']):
$address = $_SERVER['SSH_AUTH_SOCK'];
break;
case isset($_ENV['SSH_AUTH_SOCK']):
$address = $_ENV['SSH_AUTH_SOCK'];
break;
default:
user_error('SSH_AUTH_SOCK not found');
return false;
}
}
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
if (!$this->fsock) {
user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
}
}
/**
* PHP4 compatible Default Constructor.
*
* @see self::__construct()
* @access public
*/
function System_SSH_Agent($address = null)
{
$this->__construct($address);
}
/**
* Request Identities
*
* See "2.5.2 Requesting a list of protocol 2 keys"
* Returns an array containing zero or more System_SSH_Agent_Identity objects
*
* @return array
* @access public
*/
function requestIdentities()
{
if (!$this->fsock) {
return array();
}
$packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
if (strlen($packet) != fputs($this->fsock, $packet)) {
user_error('Connection closed while requesting identities');
return array();
}
$length = current(unpack('N', fread($this->fsock, 4)));
$type = ord(fread($this->fsock, 1));
if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
user_error('Unable to request identities');
return array();
}
$identities = array();
$keyCount = current(unpack('N', fread($this->fsock, 4)));
for ($i = 0; $i < $keyCount; $i++) {
$length = current(unpack('N', fread($this->fsock, 4)));
$key_blob = fread($this->fsock, $length);
$key_str = 'ssh-rsa ' . base64_encode($key_blob);
$length = current(unpack('N', fread($this->fsock, 4)));
if ($length) {
$key_str.= ' ' . fread($this->fsock, $length);
}
$length = current(unpack('N', substr($key_blob, 0, 4)));
$key_type = substr($key_blob, 4, $length);
switch ($key_type) {
case 'ssh-rsa':
if (!class_exists('Crypt_RSA')) {
include_once 'Crypt/RSA.php';
}
$key = new Crypt_RSA();
$key->loadKey($key_str);
break;
case 'ssh-dss':
// not currently supported
break;
}
// resources are passed by reference by default
if (isset($key)) {
$identity = new System_SSH_Agent_Identity($this->fsock);
$identity->setPublicKey($key);
$identity->setPublicKeyBlob($key_blob);
$identities[] = $identity;
unset($key);
}
}
return $identities;
}
/**
* Signal that agent forwarding should
* be requested when a channel is opened
*
* @param Net_SSH2 $ssh
* @return bool
* @access public
*/
function startSSHForwarding($ssh)
{
if ($this->forward_status == SYSTEM_SSH_AGENT_FORWARD_NONE) {
$this->forward_status = SYSTEM_SSH_AGENT_FORWARD_REQUEST;
}
}
/**
* Request agent forwarding of remote server
*
* @param Net_SSH2 $ssh
* @return bool
* @access private
*/
function _request_forwarding($ssh)
{
$request_channel = $ssh->_get_open_channel();
if ($request_channel === false) {
return false;
}
$packet = pack(
'CNNa*C',
NET_SSH2_MSG_CHANNEL_REQUEST,
$ssh->server_channels[$request_channel],
strlen('auth-agent-req@openssh.com'),
'auth-agent-req@openssh.com',
1
);
$ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST;
if (!$ssh->_send_binary_packet($packet)) {
return false;
}
$response = $ssh->_get_channel_packet($request_channel);
if ($response === false) {
return false;
}
$ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN;
$this->forward_status = SYSTEM_SSH_AGENT_FORWARD_ACTIVE;
return true;
}
/**
* On successful channel open
*
* This method is called upon successful channel
* open to give the SSH Agent an opportunity
* to take further action. i.e. request agent forwarding
*
* @param Net_SSH2 $ssh
* @access private
*/
function _on_channel_open($ssh)
{
if ($this->forward_status == SYSTEM_SSH_AGENT_FORWARD_REQUEST) {
$this->_request_forwarding($ssh);
}
}
/**
* Forward data to SSH Agent and return data reply
*
* @param string $data
* @return data from SSH Agent
* @access private
*/
function _forward_data($data)
{
if ($this->expected_bytes > 0) {
$this->socket_buffer.= $data;
$this->expected_bytes -= strlen($data);
} else {
$agent_data_bytes = current(unpack('N', $data));
$current_data_bytes = strlen($data);
$this->socket_buffer = $data;
if ($current_data_bytes != $agent_data_bytes + 4) {
$this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes;
return false;
}
}
if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
user_error('Connection closed attempting to forward data to SSH agent');
}
$this->socket_buffer = '';
$this->expected_bytes = 0;
$agent_reply_bytes = current(unpack('N', fread($this->fsock, 4)));
$agent_reply_data = fread($this->fsock, $agent_reply_bytes);
$agent_reply_data = current(unpack('a*', $agent_reply_data));
return pack('Na*', $agent_reply_bytes, $agent_reply_data);
}
}
@@ -0,0 +1,39 @@
<?php
/**
* Pure-PHP ssh-agent client wrapper
*
* PHP versions 4 and 5
*
* Originally System_SSH_Agent was accessed as System/SSH_Agent.php instead of
* System/SSH/Agent.php. The problem with this is that PSR0 compatible autoloaders
* don't support that kind of directory layout hence the package being moved and
* this "alias" being created to maintain backwards compatibility.
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category System
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
*/
require_once 'SSH/Agent.php';
+16
View File
@@ -0,0 +1,16 @@
<?php
/**
* Bootstrapping File for phpseclib
*
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
if (extension_loaded('mbstring')) {
// 2 - MB_OVERLOAD_STRING
if (ini_get('mbstring.func_overload') & 2) {
throw new \UnexpectedValueException(
'Overloading of string functions using mbstring.func_overload ' .
'is not supported by phpseclib.'
);
}
}
+6
View File
@@ -0,0 +1,6 @@
# minimalist openssl.cnf file for use with phpseclib
HOME = .
RANDFILE = $ENV::HOME/.rnd
[ v3_ca ]
+38
View File
@@ -0,0 +1,38 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class sftpLibrary {
public function connect($hostname, $username, $password) {
if(is_readable(ENGINE_DIR . 'libs/seclib/Net/SFTP.php')) {
set_include_path(ENGINE_DIR . 'libs/seclib');
require_once(ENGINE_DIR . 'libs/seclib/Net/SFTP.php');
} else {
exit("Ошибка: Не удалось загрузить библиотеку для работы с sftp!");
}
$sftp = new Net_SFTP($hostname);
if ($sftp->login($username, $password)) {
return $sftp;
}
return 'Ошибка: Не удалось соединиться с сервером!';
}
public function open($sftp, $command) {
return $sftp->get($command);
}
public function write($sftp, $command, $file) {
return $sftp->put($command, $file);
}
public function files($sftp, $path) {
return @$sftp->nlist($path);
}
public function get($sftp, $path, $fun) {
return @$sftp->$fun($path);
}
}
?>
+43
View File
@@ -0,0 +1,43 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class ssh2Library {
public function connect($hostname, $username, $password) {
if($link = ssh2_connect($hostname, 22)) {
if(ssh2_auth_password($link, $username, $password)) {
return $link;
}
}
exit("Ошибка: Не удалось соединиться с сервером!");
}
public function execute($link, $cmd)
{
$stream = ssh2_exec($link, $cmd);
stream_set_blocking($stream, true);
$output = '';
while ($get = fgets($stream)) {
$output .= $get;
}
fclose($stream);
return $output;
}
function get($link, $cmd) {
if($cmd) {
$this->stream = ssh2_exec($link, $cmd);
stream_set_blocking($this->stream, true);
}
$line = '';
while($get = fgets($this->stream))
$line.= $get;
return $line;
}
public function disconnect($link) {
ssh2_exec($link, "exit");
}
}
?>
+113
View File
@@ -0,0 +1,113 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class ValidateLibrary {
public function firstname($firstname) {
/*
Разрешенные символы: А-Я а-я
Длина: 2-16
*/
return preg_match("/^([А-ЯЁ]{1})([а-яё]{1,15})$/u", $firstname);
}
public function lastname($lastname) {
/*
Разрешенные символы: А-Я а-я
Длина: 2-16
*/
return preg_match("/^([А-ЯЁ]{1})([а-яё]{1,15})$/u", $lastname);
}
public function check_for_number($str)
{
$lenght = strlen($str);
$i = 0;
if ($i < $lenght) {
return true;
}
return false;
}
public function email($email) {
return preg_match("/^([a-z0-9_\.-]+)@([a-z0-9_\.-]+)\.([a-z\.]{2,6})$/", $email);
}
public function domain($domain) {
return preg_match("/[^\.\/]+\.[^\.\/]+$/", $domain);
}
public function password($password) {
/*
Разрешенные символы: A-Z a-z 0-9
Длина: 6-32
*/
return preg_match("/^[a-zA-Z0-9,\.!?_-]{6,32}$/", $password);
}
public function password_web($password) {
/*
Разрешенные символы: A-Z a-z 0-9
Длина: 8-32
*/
return preg_match("/^[a-zA-Z0-9,\.!?_-]{8,32}$/", $password);
}
public function password_web1($password) {
return preg_match("/([0-9]+)/", $password);
}
public function password_web2($password) {
return preg_match("/([a-z]+)/", $password);
}
public function accesslevel($accesslevel) {
/*
Разрешенные символы: 0-3
Длина: 1
*/
if(0 > $accesslevel || $accesslevel > 3)
return false;
else
return true;
}
public function userstatus($status) {
/*
Разрешенные символы: 0-1
Длина: 1
*/
if(0 > $status || $status > 1)
return false;
else
return true;
}
public function money($money) {
/*
Разрешенные символы: 0-9 и .
Длина: 1
*/
return preg_match("/^([0-9]{1,10})(\.[0-9]{2})?$/", $money);
}
public function ip($ip) {
/*
Разрешенные символы: 0-9 и .
Длина: 1
*/
return preg_match("/^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/", $ip);
}
public function md5($md) {
/*
Разрешенные символы: a-f и 0-9
Длина: 1
*/
return preg_match("/^([a-f0-9]{32})$/", $md);
}
}
?>
+94
View File
@@ -0,0 +1,94 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Action {
private $registry;
private $folder;
private $controller;
private $method;
private $args;
public function __construct($registry)
{
$this->registry = $registry;
}
public function make($action) {
$this->folder = null;
$this->controller = null;
$this->method = null;
$this->args = null;
$action = preg_replace("/[^\w\d\s\/]/", '', $action);
$parts = explode('/', $action);
$parts = array_filter($parts);
foreach($parts as $item) {
$fullpath = APPLICATION_DIR . 'controllers' . $this->folder . '/' . $item;
if(is_dir($fullpath)) {
$this->folder .= '/' . $item;
array_shift($parts);
continue;
}
elseif(is_file($fullpath . '.php')) {
$this->controller = $item;
array_shift($parts);
break;
} else break;
}
// Проверка папки
if(empty($this->folder)) {
$this->folder = 'errore';
}
// Проверка контроллера
if(empty($this->controller)) {
$this->controller = 'index';
}
// Получения метода
if($c = array_shift($parts)) {
$this->method = $c;
} else {
$this->method = 'index';
}
// Получение аргументов
if(isset($parts[0])) {
$this->args = $parts;
}
}
public function go($commonEnable = false) {
$controllerFile = APPLICATION_DIR . 'controllers/' . $this->folder . '/' . $this->controller . '.php';
$controllerClass = $this->controller . 'Controller';
if($this->folder != "common" || $commonEnable == true) { // Защита папки "common"
if(is_readable($controllerFile)) {
require_once($controllerFile);
$controller = new $controllerClass($this->registry);
if(is_callable(array($controller, $this->method))) {
$this->method = $this->method;
} else {
$this->method = 'index';
}
if(empty($this->args)) {
return call_user_func(array($controller, $this->method));
} else {
return call_user_func_array(array($controller, $this->method), $this->args);
}
}
}
$error = 'Ошибка: Не удалось загрузить контроллер ' . $this->controller . '!';
require_once("application/views/main/error.php");
exit();
}
}
?>
+29
View File
@@ -0,0 +1,29 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Config {
private $data = array();
public function __construct() {
if(is_readable(APPLICATION_DIR . 'config.php')) {
require_once(APPLICATION_DIR . 'config.php');
$this->data = array_merge($this->data, $config);
return true;
}
exit('Ошибка: Не удалось загрузить файл конфигурации!');
}
public function __set($key, $val){
$this->data[$key] = $val;
}
public function __get($key){
if(isset($this->data[$key])){
return $this->data[$key];
}
return false;
}
}
?>
+29
View File
@@ -0,0 +1,29 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
abstract class Controller {
private $registry;
protected $data = array();
public function __construct($registry) {
$this->registry = $registry;
}
public function __get($key) {
return $this->registry->$key;
}
public function __set($key, $value) {
$this->registry->$key = $value;
}
public function getChild($child = array()) {
foreach($child as $item) {
$this->action->make($item);
$this->data[basename($item)] = $this->action->go(true);
}
}
}
?>
+21
View File
@@ -0,0 +1,21 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Cookie {
public $data = array();
public function __construct() {
$this->data = $_COOKIE;
}
public function set($key, $value) {
setcookie($key, $value, time() + 60 * 60 * 24 * 30 * 12, "/");
}
public function remove($key) {
setcookie($key, null, time() - 3600, "/");
}
}
?>
+37
View File
@@ -0,0 +1,37 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class DB {
private $driver;
public function __construct($driver, $hostname, $username, $password, $database) {
$class = $driver . 'Driver';
if(is_readable(ENGINE_DIR . 'database/' . $driver . '.php')) {
require_once(ENGINE_DIR . 'database/' . $driver . '.php');
} else {
exit('Ошибка: Не удалось загрузить драйвер базы данных ' . $driver . '!');
}
$this->driver = new $class($hostname, $username, $password, $database);
}
public function query($sql) {
return $this->driver->query($sql);
}
public function escape($value) {
return $this->driver->escape($value);
}
public function countAffected() {
return $this->driver->countAffected();
}
public function getLastId() {
return $this->driver->getLastId();
}
public function getCount() {
return $this->driver->getCount();
}
}
?>
+48
View File
@@ -0,0 +1,48 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Document {
private $title;
private $activeSection;
private $activeItem;
private $scripts = array();
/* Заголовок страницы */
public function setTitle($title) {
$this->title = $title;
}
public function getTitle() {
return $this->title;
}
/* Активный раздел меню */
public function setActiveSection($section) {
$this->activeSection = $section;
}
public function getActiveSection() {
return $this->activeSection;
}
/* Активный элемент меню */
public function setActiveItem($item) {
$this->activeItem = $item;
}
public function getActiveItem() {
return $this->activeItem;
}
/* Скрипты */
public function addScript($script) {
$this->scriptsarray[] = $script;
}
public function getScripts() {
return $this->scripts;
}
}
?>
+25
View File
@@ -0,0 +1,25 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Game_settings {
private $data = array();
public function __construct() {
if(is_readable(ENGINE_DIR . 'games/game_settings.php')) {
require_once(ENGINE_DIR . 'games/game_settings.php');
$this->data = array_merge($this->data, $game_settings);
return true;
}
exit('Ошибка: Не удалось загрузить файл конфигурации игр!');
}
public function __get($key){
if(isset($this->data[$key])){
return $this->data[$key];
}
return false;
}
}
?>
+64
View File
@@ -0,0 +1,64 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Load {
private $registry;
public function __construct($registry) {
$this->registry = $registry;
}
public function view($name, $vars = array()){
$file = APPLICATION_DIR . 'views/' . $name . '.php';
if(is_readable($file)){
extract($vars);
ob_start();
include($file);
$content = ob_get_contents();
ob_end_clean();
return $content;
}
$error = 'Ошибка: Не удалось загрузить шаблон ' . $name . '!';
require_once("application/views/main/error.php");
exit();
}
public function model($name){
$modelClass = $name . 'Model';
$modelPath = APPLICATION_DIR . 'models/' . $name . '.php';
if(is_readable($modelPath)){
require_once($modelPath);
if(class_exists($modelClass)){
$this->registry->$modelClass = new $modelClass($this->registry);
return true;
}
}
$error = 'Ошибка: Не удалось загрузить модель ' . $name . '!';
require_once("application/views/main/error.php");
exit();
}
public function library($name){
$libClass = $name . 'Library';
$libPath = ENGINE_DIR . 'libs/' . $name . '.php';
if(is_readable($libPath)){
require_once($libPath);
return true;
}
$error = 'Ошибка: Не удалось загрузить библиотеку ' . $name . '!';
require_once("application/views/main/error.php");
exit();
}
public function genpass($length) {
return substr(md5(microtime() . rand(0, 9999)), 0, $length);
}
}
?>
+21
View File
@@ -0,0 +1,21 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
abstract class Model {
private $registry;
public function __construct($registry) {
$this->registry = $registry;
}
public function __get($key) {
return $this->registry->$key;
}
public function __set($key, $value) {
$this->registry->$key = $value;
}
}
?>
+20
View File
@@ -0,0 +1,20 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Registry {
private $data = array();
public function __set($key, $val){
$this->data[$key] = $val;
}
public function __get($key){
if(isset($this->data[$key])){
return $this->data[$key];
}
return false;
}
}
?>
+41
View File
@@ -0,0 +1,41 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Request {
public $get = array();
public $post = array();
public $cookie = array();
public $files = array();
public $server = array();
public function __construct() {
$_GET = $this->clean($_GET);
$_POST = $this->clean($_POST);
$_REQUEST = $this->clean($_REQUEST);
$_COOKIE = $this->clean($_COOKIE);
$_FILES = $this->clean($_FILES);
$_SERVER = $this->clean($_SERVER);
$this->get = $_GET;
$this->post = $_POST;
$this->request = $_REQUEST;
$this->cookie = $_COOKIE;
$this->files = $_FILES;
$this->server = $_SERVER;
}
private function clean($data) {
if (is_array($data)) {
foreach ($data as $key => $value) {
unset($data[$key]);
$data[$this->clean($key)] = $this->clean($value);
}
} else {
$data = htmlspecialchars($data, ENT_COMPAT);
}
return $data;
}
}
?>
+29
View File
@@ -0,0 +1,29 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Response {
private $headers = array();
public function addHeader($header) {
$this->headersarray[] = $header;
}
public function redirect($url) {
header('Location: ' . $url);
exit;
}
public function output($content) {
if ($content) {
if (!headers_sent()) {
foreach($this->headers as $header) {
header($header, true);
}
}
echo $content;
}
}
}
?>
+14
View File
@@ -0,0 +1,14 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class Session {
public $data = array();
public function __construct() {
if(!session_id()) session_start();
$this->data = &$_SESSION;
}
}
?>
+176
View File
@@ -0,0 +1,176 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class User {
private $registry;
private $user_id;
private $email;
private $firstname;
private $lastname;
private $balance;
private $access_level;
private $user_img;
private $test_server;
private $user_vk_id;
public function __construct($registry) {
$this->registry = $registry;
if(isset($this->registry->cookie->data['uid'])) {
$query = $this->registry->db->query("SELECT * FROM `users_auth` LEFT JOIN `users` ON users_auth.user_id=users.user_id WHERE `auth_key` = '" . $this->registry->db->escape(@$this->registry->cookie->data['uid']) . "'");
if ($query->num_rows) {
$this->user_id = $query->row['user_id'];
$this->email = $query->row['user_email'];
$this->firstname = $query->row['user_firstname'];
$this->lastname = $query->row['user_lastname'];
$this->balance = $query->row['user_balance'];
$this->access_level = $query->row['user_access_level'];
$this->user_img = $query->row['user_img'];
$this->test_server = $query->row['test_server'];
$this->user_vk_id = $query->row['user_vk_id'];
$this->registry->db->query("UPDATE `users_auth` SET `user_ip` = '" . $this->registry->db->escape($this->getRealIpAdress()) . "', `user_last_activity` = NOW() WHERE `auth_key` = '" . @$this->registry->db->escape($this->registry->cookie->data['uid']) . "'");
} else {
$this->logout();
}
}
}
public function login($email, $password) {
$query = $this->registry->db->query("SELECT * FROM users WHERE user_email = '" . $this->registry->db->escape($email) . "' AND user_password = '" . $this->registry->db->escape($password) . "' AND user_status = '1'");
if($query->num_rows) {
$key = sha1(mt_rand(11111, 99999) . $this->GenerateHash(mt_rand(50, 200)) . microtime()) . sha1(mt_rand(11111, 99999) . $this->GenerateHash(mt_rand(50, 200)) . $query->row['user_password']) . sha1(mt_rand(11111, 99999) . $this->GenerateHash(mt_rand(50, 200)) . $query->row['user_email']) . sha1(mt_rand(11111, 99999) . $this->GenerateHash(mt_rand(50, 200)) . $query->row['user_id']);
$this->registry->cookie->set('uid', $key);
$this->user_id = $query->row['user_id'];
$this->email = $query->row['user_email'];
$this->firstname = $query->row['user_firstname'];
$this->lastname = $query->row['user_lastname'];
$this->balance = $query->row['user_balance'];
$this->access_level = $query->row['user_access_level'];
$this->user_img = $query->row['user_img'];
$this->test_server = $query->row['test_server'];
$this->registry->db->query("INSERT INTO `users_auth` SET `user_id` = '" . $query->row['user_id'] . "', `user_ip` = '" . $this->registry->db->escape($this->getRealIpAdress()) . "', `user_last_activity` = NOW(), `auth_user_email` = '" . $this->registry->db->escape($query->row['user_email']) . "', `auth_user_password` = '" . $this->registry->db->escape($query->row['user_password']) . "', `auth_key` = '" . $this->registry->db->escape($key) . "', `auth_type` = 'Password', `auth_date_add` = NOW()");
return true;
} else {
return false;
}
}
public function loginVk($vkid) {
$query = $this->registry->db->query("SELECT * FROM users WHERE user_vk_id = '" . (int)$vkid . "'");
if($query->num_rows) {
$key = sha1(mt_rand(11111, 99999) . $this->GenerateHash(mt_rand(50, 200)) . microtime()) . sha1(mt_rand(11111, 99999) . $this->GenerateHash(mt_rand(50, 200)) . $query->row['user_password']) . sha1(mt_rand(11111, 99999) . $this->GenerateHash(mt_rand(50, 200)) . $query->row['user_email']) . sha1(mt_rand(11111, 99999) . $this->GenerateHash(mt_rand(50, 200)) . $query->row['user_id']);
$this->registry->cookie->set('uid', $key);
$this->user_id = $query->row['user_id'];
$this->email = $query->row['user_email'];
$this->firstname = $query->row['user_firstname'];
$this->lastname = $query->row['user_lastname'];
$this->balance = $query->row['user_balance'];
$this->access_level = $query->row['user_access_level'];
$this->user_img = $query->row['user_img'];
$this->test_server = $query->row['test_server'];
$this->registry->db->query("INSERT INTO `users_auth` SET `user_id` = '" . $query->row['user_id'] . "', `user_ip` = '" . $this->registry->db->escape($this->getRealIpAdress()) . "', `user_last_activity` = NOW(), `auth_user_email` = '" . $this->registry->db->escape($query->row['user_email']) . "', `auth_user_password` = '" . $this->registry->db->escape($query->row['user_password']) . "', `auth_key` = '" . $this->registry->db->escape($key) . "', `auth_type` = 'Vk', `auth_date_add` = NOW()");
return true;
} else {
return false;
}
}
public function correctData() {
$query = $this->registry->db->query("SELECT * FROM `users_auth` LEFT JOIN `users` ON users_auth.user_id=users.user_id WHERE `auth_key` = '" . $this->registry->db->escape(@$this->registry->cookie->data['uid']) . "'");
if($query->num_rows) {
if($query->row['auth_user_email'] == $query->row['user_email'] && $query->row['auth_user_password'] == $query->row['user_password']) return true;
}
}
public function isLogged() {
if($this->correctData()) {
return $this->user_id;
} else {
$this->logout();
return false;
}
}
public function logout() {
$this->registry->db->query("DELETE FROM `users_auth` WHERE `auth_key` = '" . $this->registry->db->escape(@$this->registry->cookie->data['uid']) . "'");
$this->registry->cookie->remove('uid');
$this->user_id = null;
$this->email = null;
$this->firstname = null;
$this->lastname = null;
$this->balance = null;
$this->access_level = 0;
$this->user_vk_id = null;
}
public function getId() {
return $this->user_id;
}
public function getEmail() {
return $this->email;
}
public function getFirstname() {
return $this->firstname;
}
public function getLastname() {
return $this->lastname;
}
public function getUser_img() {
return $this->user_img;
}
public function getBalance() {
return $this->balance;
}
public function getUser_vk_id() {
return $this->user_vk_id;
}
public function getAccessLevel() {
return $this->access_level;
}
public function getTest_server() {
return $this->test_server;
}
public function getRealIpAdress() {
if (!empty($_SERVER["HTTP_CF_CONNECTING_IP"]) && filter_var($_SERVER["HTTP_CF_CONNECTING_IP"], FILTER_VALIDATE_IP) !== false) {
return $_SERVER["HTTP_CF_CONNECTING_IP"];
}
foreach (array('REMOTE_ADDR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED') as $key) {
if (array_key_exists($key, $_SERVER) === true) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
return $ip;
}
}
}
}
return @$_SERVER['REMOTE_ADDR'];
}
private function GenerateHash($length = 12) {
$chars="qazxswedcvfrtgbnhyujmkiolp1234567890QAZXSWEDCVFRTGBNHYUJMKIOLP0!@#$%^&*()_+";
$size = strlen($chars) - 1;
$password = null;
while($length--) {
$password .= $chars[rand(0, $size)];
}
return $password;
}
}
?>