Add more libraries

This commit is contained in:
Kijin Sung 2016-01-20 14:15:59 +09:00
parent bde13db245
commit 8e284db3b9
5 changed files with 540 additions and 30 deletions

View file

@ -145,8 +145,11 @@ $GLOBALS['RX_AUTOLOAD_FILE_MAP'] = array_change_key_case(array(
'HintTableTag' => 'classes/xml/xmlquery/tags/table/HintTableTag.class.php',
'TableTag' => 'classes/xml/xmlquery/tags/table/TableTag.class.php',
'TablesTag' => 'classes/xml/xmlquery/tags/table/TablesTag.class.php',
'Bmp' => 'common/libraries/bmp.php',
'Ftp' => 'common/libraries/ftp.php',
'Tar' => 'common/libraries/tar.php',
'CryptoCompat' => 'common/libraries/cryptocompat.php',
'VendorPass' => 'common/libraries/vendorpass.php',
), CASE_LOWER);
/**

View file

@ -1203,36 +1203,7 @@ if(!function_exists('hexrgb'))
*/
function mysql_pre4_hash_password($password)
{
$nr = 1345345333;
$add = 7;
$nr2 = 0x12345671;
settype($password, "string");
for($i = 0; $i < strlen($password); $i++)
{
if($password[$i] == ' ' || $password[$i] == '\t')
{
continue;
}
$tmp = ord($password[$i]);
$nr ^= ((($nr & 63) + $add) * $tmp) + ($nr << 8);
$nr2 += ($nr2 << 8) ^ $nr;
$add += $tmp;
}
$result1 = sprintf("%08lx", $nr & ((1 << 31) - 1));
$result2 = sprintf("%08lx", $nr2 & ((1 << 31) - 1));
if($result1 == '80000000')
{
$nr += 0x80000000;
}
if($result2 == '80000000')
{
$nr2 += 0x80000000;
}
return sprintf("%08lx%08lx", $nr, $nr2);
return VendorPass::mysql_old_password($password);
}
/**

257
common/libraries/bmp.php Normal file
View file

@ -0,0 +1,257 @@
<?php
// Read 1,4,8,24,32bit BMP files
// Save 24bit BMP files
// Author: de77
// Licence: MIT
// Webpage: de77.com
// Article about this class: http://de77.com/php/read-and-write-bmp-in-php-imagecreatefrombmp-imagebmp
// First-version: 07.02.2010
// Version: 21.08.2010
// Modified by Kijin Sung, April 6, 2013: Remove die() and global functions
class BMP
{
public static function imagebmp(&$img, $filename = false)
{
$wid = imagesx($img);
$hei = imagesy($img);
$wid_pad = str_pad('', $wid % 4, "\0");
$size = 54 + ($wid + $wid_pad) * $hei * 3; //fixed
//prepare & save header
$header['identifier'] = 'BM';
$header['file_size'] = self::dword($size);
$header['reserved'] = self::dword(0);
$header['bitmap_data'] = self::dword(54);
$header['header_size'] = self::dword(40);
$header['width'] = self::dword($wid);
$header['height'] = self::dword($hei);
$header['planes'] = self::word(1);
$header['bits_per_pixel'] = self::word(24);
$header['compression'] = self::dword(0);
$header['data_size'] = self::dword(0);
$header['h_resolution'] = self::dword(0);
$header['v_resolution'] = self::dword(0);
$header['colors'] = self::dword(0);
$header['important_colors'] = self::dword(0);
if ($filename)
{
$f = fopen($filename, "wb");
foreach ($header AS $h)
{
fwrite($f, $h);
}
//save pixels
for ($y=$hei-1; $y>=0; $y--)
{
for ($x=0; $x<$wid; $x++)
{
$rgb = imagecolorat($img, $x, $y);
fwrite($f, byte3($rgb));
}
fwrite($f, $wid_pad);
}
fclose($f);
}
else
{
foreach ($header AS $h)
{
echo $h;
}
//save pixels
for ($y=$hei-1; $y>=0; $y--)
{
for ($x=0; $x<$wid; $x++)
{
$rgb = imagecolorat($img, $x, $y);
echo self::byte3($rgb);
}
echo $wid_pad;
}
}
}
public static function getimagesize($filename)
{
$f = fopen($filename, "rb");
//read header
$header = fread($f, 54);
$header = unpack( 'c2identifier/Vfile_size/Vreserved/Vbitmap_data/Vheader_size/' .
'Vwidth/Vheight/vplanes/vbits_per_pixel/Vcompression/Vdata_size/'.
'Vh_resolution/Vv_resolution/Vcolors/Vimportant_colors', $header);
if ($header['identifier1'] != 66 or $header['identifier2'] != 77)
{
return false;
}
if (!in_array($header['bits_per_pixel'], array(24, 32, 8, 4, 1)))
{
return false;
}
$bps = $header['bits_per_pixel']; //bits per pixel
$wid2 = ceil(($bps/8 * $header['width']) / 4) * 4;
$colors = pow(2, $bps);
$wid = $header['width'];
$hei = $header['height'];
return array($wid, $hei, 'BMP');
}
public static function imagecreatefrombmp($filename)
{
$f = fopen($filename, "rb");
//read header
$header = fread($f, 54);
$header = unpack( 'c2identifier/Vfile_size/Vreserved/Vbitmap_data/Vheader_size/' .
'Vwidth/Vheight/vplanes/vbits_per_pixel/Vcompression/Vdata_size/'.
'Vh_resolution/Vv_resolution/Vcolors/Vimportant_colors', $header);
if ($header['identifier1'] != 66 or $header['identifier2'] != 77)
{
return false;
}
if (!in_array($header['bits_per_pixel'], array(24, 32, 8, 4, 1)))
{
return false;
}
$bps = $header['bits_per_pixel']; //bits per pixel
$wid2 = ceil(($bps/8 * $header['width']) / 4) * 4;
$colors = pow(2, $bps);
$wid = $header['width'];
$hei = $header['height'];
$img = imagecreatetruecolor($header['width'], $header['height']);
//read palette
if ($bps < 9)
{
for ($i=0; $i<$colors; $i++)
{
$palette[] = self::undword(fread($f, 4));
}
}
else
{
if ($bps == 32)
{
imagealphablending($img, false);
imagesavealpha($img, true);
}
$palette = array();
}
//read pixels
for ($y=$hei-1; $y>=0; $y--)
{
$row = fread($f, $wid2);
$pixels = self::str_split2($row, $bps, $palette);
for ($x=0; $x<$wid; $x++)
{
self::makepixel($img, $x, $y, $pixels[$x], $bps);
}
}
fclose($f);
return $img;
}
private static function str_split2($row, $bps, $palette)
{
switch ($bps)
{
case 32:
case 24: return str_split($row, $bps/8);
case 8: $out = array();
$count = strlen($row);
for ($i=0; $i<$count; $i++)
{
$out[] = $palette[ ord($row[$i]) ];
}
return $out;
case 4: $out = array();
$count = strlen($row);
for ($i=0; $i<$count; $i++)
{
$roww = ord($row[$i]);
$out[] = $palette[ ($roww & 240) >> 4 ];
$out[] = $palette[ ($roww & 15) ];
}
return $out;
case 1: $out = array();
$count = strlen($row);
for ($i=0; $i<$count; $i++)
{
$roww = ord($row[$i]);
$out[] = $palette[ ($roww & 128) >> 7 ];
$out[] = $palette[ ($roww & 64) >> 6 ];
$out[] = $palette[ ($roww & 32) >> 5 ];
$out[] = $palette[ ($roww & 16) >> 4 ];
$out[] = $palette[ ($roww & 8) >> 3 ];
$out[] = $palette[ ($roww & 4) >> 2 ];
$out[] = $palette[ ($roww & 2) >> 1 ];
$out[] = $palette[ ($roww & 1) ];
}
return $out;
}
}
private static function makepixel($img, $x, $y, $str, $bps)
{
switch ($bps)
{
case 32 : $a = ord($str[0]);
$b = ord($str[1]);
$c = ord($str[2]);
$d = 256 - ord($str[3]); //TODO: gives imperfect results
$pixel = $d*256*256*256 + $c*256*256 + $b*256 + $a;
imagesetpixel($img, $x, $y, $pixel);
break;
case 24 : $a = ord($str[0]);
$b = ord($str[1]);
$c = ord($str[2]);
$pixel = $c*256*256 + $b*256 + $a;
imagesetpixel($img, $x, $y, $pixel);
break;
case 8 :
case 4 :
case 1 : imagesetpixel($img, $x, $y, $str);
break;
}
}
private static function byte3($n)
{
return chr($n & 255) . chr(($n >> 8) & 255) . chr(($n >> 16) & 255);
}
private static function undword($n)
{
$r = unpack("V", $n);
return $r[1];
}
private static function dword($n)
{
return pack("V", $n);
}
private static function word($n)
{
return pack("v", $n);
}
}

View file

@ -0,0 +1,129 @@
<?php
/**
* This class uses mcrypt to perform encryption and decryption in a way
* that is fully compatible with https://github.com/defuse/php-encryption
*/
class CryptoCompat
{
// Default configuration
const ENCRYPTION_ALGO = 'aes-128';
const ENCRYPTION_MODE = 'cbc';
const ENCRYPTION_BLOCK_SIZE = 16;
const ENCRYPTION_KEY_SIZE = 16;
const ENCRYPTION_KEY_INFO = 'DefusePHP|KeyForEncryption';
const ENCRYPTION_MAC_ALGO = 'sha256';
const ENCRYPTION_MAC_SIZE = 32;
const ENCRYPTION_MAC_INFO = 'DefusePHP|KeyForAuthentication';
// Encrypt method
public static function encrypt($plaintext, $key)
{
// Generate subkey for encryption
$enc_key = self::_defuseCompatibleHKDF($key, self::ENCRYPTION_KEY_INFO);
// Generate IV
$iv = self::_createIV();
// Encrypt the plaintext
$mcrypt_method = str_replace('aes', 'rijndael', self::ENCRYPTION_ALGO);
$plaintext = self::_applyPKCS7Padding($plaintext, self::ENCRYPTION_BLOCK_SIZE);
$ciphertext = mcrypt_encrypt($mcrypt_method, $enc_key, $plaintext, self::ENCRYPTION_MODE, $iv);
// Generate MAC
$mac_key = self::_defuseCompatibleHKDF($key, self::ENCRYPTION_MAC_INFO);
$mac = hash_hmac(self::ENCRYPTION_MAC_ALGO, ($iv . $ciphertext), $mac_key, true);
// Return the MAC, IV, and ciphertext
return $mac . $iv . $ciphertext;
}
// Decrypt method
public static function decrypt($ciphertext, $key)
{
// Extract MAC and IV from the remainder of the ciphertext
$mac = substr($ciphertext, 0, self::ENCRYPTION_MAC_SIZE);
$iv = substr($ciphertext, self::ENCRYPTION_MAC_SIZE, self::ENCRYPTION_BLOCK_SIZE);
$ciphertext = substr($ciphertext, self::ENCRYPTION_MAC_SIZE + self::ENCRYPTION_BLOCK_SIZE);
// Validate MAC
$mac_key = self::_defuseCompatibleHKDF($key, self::ENCRYPTION_MAC_INFO);
$mac_compare = hash_hmac(self::ENCRYPTION_MAC_ALGO, ($iv . $ciphertext), $mac_key, true);
if (!Password::strcmpConstantTime($mac, $mac_compare))
{
return false;
}
// Generate subkey for encryption
$enc_key = self::_defuseCompatibleHKDF($key, self::ENCRYPTION_KEY_INFO);
// Decrypt the ciphertext
$mcrypt_method = str_replace('aes', 'rijndael', self::ENCRYPTION_ALGO);
$plaintext = @mcrypt_decrypt($mcrypt_method, $enc_key, $ciphertext, self::ENCRYPTION_MODE, $iv);
if ($plaintext === false)
{
return false;
}
$plaintext = self::_stripPKCS7Padding($plaintext, self::ENCRYPTION_BLOCK_SIZE);
if ($plaintext === false)
{
return false;
}
// Return the plaintext
return $plaintext;
}
/**
* @brief Create an IV
* @return string
*/
protected static function _createIV()
{
return hex2bin(Password::createSecureSalt(self::ENCRYPTION_BLOCK_SIZE * 2, 'hex'));
}
/**
* @brief Apply PKCS#7 padding to a string
* @param string $str The string
* @param int $block_size The block size
* @return string
*/
protected static function _applyPKCS7Padding($str, $block_size)
{
$padding_size = $block_size - (strlen($str) % $block_size);
if ($padding_size === 0) $padding_size = $block_size;
return $str . str_repeat(chr($padding_size), $padding_size);
}
/**
* @brief Remove PKCS#7 padding from a string
* @param string $str The string
* @param int $block_size The block size
* @return string
*/
protected static function _stripPKCS7Padding($str, $block_size)
{
if (strlen($str) % $block_size !== 0) return false;
$padding_size = ord(substr($str, -1));
if ($padding_size < 1 || $padding_size > $block_size) return false;
if (substr($str, (-1 * $padding_size)) !== str_repeat(chr($padding_size), $padding_size)) return false;
return substr($str, 0, strlen($str) - $padding_size);
}
/**
* @brief HKDF function compatible with defuse/php-encryption
* @return string
*/
protected static function _defuseCompatibleHKDF($key, $info)
{
$salt = str_repeat("\x00", self::ENCRYPTION_MAC_SIZE);
$prk = hash_hmac(self::ENCRYPTION_MAC_ALGO, $key, $salt, true);
$t = $last_block = '';
for ($block_index = 1; strlen($t) < self::ENCRYPTION_KEY_SIZE; $block_index++)
{
$t .= $last_block = hash_hmac(self::ENCRYPTION_MAC_ALGO, ($last_block . $info . chr($block_index)), $prk, true);
}
return substr($t, 0, self::ENCRYPTION_KEY_SIZE);
}
}

View file

@ -0,0 +1,150 @@
<?php
// PHP implementation of several vendor-specific password hashing functions.
class VendorPass
{
// MySQL's OLD_PASSWORD() function.
// Minor modification of the code written by Dustin Fineout, 10/9/2009
// Source: http://stackoverflow.com/questions/260236/mysql-hashing-function-implementation
public static function mysql_old_password($password)
{
$password = strval($password);
$length = strlen($password);
$nr1 = 0x50305735; $nr2 = 0x12345671; $add = 7; $tmp = null;
for ($i = 0; $i < $length; $i++) {
$byte = substr($password, $i, 1);
if ($byte === ' ' || $byte === "\t") continue;
$tmp = ord($byte);
$nr1 ^= (($nr1 << 8) & 0x7FFFFFFF) + ((($nr1 & 63) + $add) * $tmp);
$nr2 += (($nr2 << 8) & 0x7FFFFFFF) ^ $nr1;
$add += $tmp;
}
return sprintf("%08x%08x", $nr1 & 0x7FFFFFFF, $nr2 & 0x7FFFFFFF);
}
// MySQL's PASSWORD() function.
public static function mysql_new_password($password)
{
return '*' . strtoupper(sha1(sha1($password, true)));
}
// MS SQL Server's PWDENCRYPT() function.
public static function mssql_pwdencrypt($password, $salt = null)
{
if ($salt !== null && strlen($salt) === 54)
{
$salt = substr($salt, 6, 8);
}
else
{
$salt = strtoupper(str_pad(dechex(mt_rand(0, 65535)), 4, '0') .
str_pad(dechex(mt_rand(0, 65535)), 4, '0'));
}
$password = mb_convert_encoding($password, 'UTF-16LE', 'UTF-8');
return '0x0100' . strtoupper($salt . sha1($password . pack('H*', $salt)));
}
// Drupal's SHA512-based password hashing algorithm.
public static function drupal($password, $salt = null)
{
$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if ($salt !== null && strlen($salt) > 12)
{
$iterations = intval(strpos($itoa64, substr($salt, 3, 1)));
$salt = substr($salt, 4, 8);
}
else
{
$iterations = 15;
$salt = Password::createSecureSalt(8, 'hex');
}
$count = 1 << $iterations;
$hash = hash('sha512', $salt . $password, true);
do
{
$hash = hash('sha512', $hash . $password, true);
} while (--$count);
$hash = self::drupal_base64($hash, strlen($hash), $itoa64);
return substr('$S$' . $itoa64[$iterations] . $salt . $hash, 0, 55);
}
// Drupal's own Base64 implementation.
protected static function drupal_base64($input, $count, $chars)
{
$output = '';
$i = 0;
do
{
$value = ord($input[$i++]);
$output .= $chars[$value & 0x3f];
if ($i < $count) $value |= ord($input[$i]) << 8;
$output .= $chars[($value >> 6) & 0x3f];
if ($i++ >= $count) break;
if ($i < $count) $value |= ord($input[$i]) << 16;
$output .= $chars[($value >> 12) & 0x3f];
if ($i++ >= $count) break;
$output .= $chars[($value >> 18) & 0x3f];
} while ($i < $count);
return $output;
}
// Joomla's MD5-based password hashing algorithm.
public static function joomla($password, $salt = null)
{
if ($salt !== null && strlen($salt) > 33)
{
$salt = substr($salt, 33);
}
else
{
$salt = Password::createSecureSalt(32, 'hex');
}
return md5($password . $salt) . ':' . $salt;
}
// KimsQ Rb's algorithms.
public static function kimsqrb($password, $salt = null)
{
if (preg_match('/(\$[1-4])\$([0-9]{14})$/', $salt, $matches))
{
$date = '$' . $matches[2];
$fakesalt = substr(base64_encode(substr($date, 1) . 'salt'), 0, 22);
switch ($matches[1])
{
case '$1': return self::password_hash($password, 1, ['cost' =>10, 'salt' => $fakesalt]) . '$1' . $date;
case '$2': return hash('sha512', $password . $fakesalt) . '$2' . $date;
case '$3': return hash('sha256', $password . $fakesalt) . '$3' . $date;
case '$4': return md5(sha1(md5($password . $fakesalt))) . '$4' . $date;
}
}
$date = '$' . date('YmdHis');
$fakesalt = substr(base64_encode(substr($date, 1) . 'salt'), 0, 22);
return self::password_hash($password, 1, ['cost' =>10, 'salt' => $fakesalt]) . '$1' . $date;
}
// Bcrypt wrapper for PHP 5.4.
public static function password_hash($password, $algo = 1, $options = [])
{
if (!isset($options['salt']) || !preg_match('/^[0-9a-zA-Z\.\/]{22,}$/', $options['salt']))
{
$options['salt'] = Password::createSecureSalt(22, 'alnum');
}
if (!isset($options['cost']) || $options['cost'] < 4 || $options['cost'] > 31)
{
$options['cost'] = 10;
}
$salt = '$2y$' . sprintf('%02d', $options['cost']) . '$' . $options['salt'];
return @crypt($password, $salt);
}
}