Mise à jour des librairies vendor
This commit is contained in:
65
vendor/phpseclib/phpseclib/README.md
vendored
65
vendor/phpseclib/phpseclib/README.md
vendored
@@ -6,17 +6,37 @@ MIT-licensed pure-PHP implementations of an arbitrary-precision integer
|
||||
arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
|
||||
AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
|
||||
|
||||
* [Download (1.0.4)](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.4.zip/download)
|
||||
* [Browse Git](https://github.com/phpseclib/phpseclib)
|
||||
* [Code Coverage Report](http://phpseclib.bantux.org/code_coverage/2.0/latest/)
|
||||
|
||||
<img src="http://phpseclib.sourceforge.net/pear-icon.png" alt="PEAR Channel" width="16" height="16">
|
||||
PEAR Channel: [phpseclib.sourceforge.net](http://phpseclib.sourceforge.net/pear.htm)
|
||||
* [Code Coverage Report](https://coverage.phpseclib.org/2.0/latest/)
|
||||
|
||||
## Documentation
|
||||
|
||||
* [Documentation / Manual](http://phpseclib.sourceforge.net/)
|
||||
* [API Documentation](http://phpseclib.bantux.org/api/2.0/) (generated by Sami)
|
||||
* [API Documentation](https://api.phpseclib.org/2.0/) (generated by Sami)
|
||||
|
||||
## Branches
|
||||
|
||||
### master
|
||||
|
||||
* Development Branch
|
||||
* Unstable API
|
||||
* Do not use in production
|
||||
|
||||
### 2.0
|
||||
|
||||
* Modernized version of 1.0
|
||||
* Minimum PHP version: 5.3.3
|
||||
* PSR-4 autoloading with namespace rooted at `\phpseclib`
|
||||
* Install via Composer: `composer require phpseclib/phpseclib ~2.0`
|
||||
|
||||
### 1.0
|
||||
|
||||
* Long term support (LTS) release
|
||||
* PHP4 compatible
|
||||
* Composer compatible (PSR-0 autoloading)
|
||||
* Install using Composer: `composer require phpseclib/phpseclib ~1.0`
|
||||
* Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm)
|
||||
* [Download 1.0.11 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.11.zip/download)
|
||||
|
||||
## Support
|
||||
|
||||
@@ -26,40 +46,29 @@ Need Support?
|
||||
* [Create a Support Ticket on GitHub](https://github.com/phpseclib/phpseclib/issues/new)
|
||||
* [Browse the Support Forum](http://www.frostjedi.com/phpbb/viewforum.php?f=46) (no longer in use)
|
||||
|
||||
## Installing Development Dependencies
|
||||
|
||||
Dependencies are managed via Composer.
|
||||
|
||||
1. Download the [`composer.phar`](https://getcomposer.org/composer.phar) executable as per the
|
||||
[Composer Download Instructions](https://getcomposer.org/download/), e.g. by running
|
||||
|
||||
``` sh
|
||||
curl -sS https://getcomposer.org/installer | php
|
||||
```
|
||||
|
||||
2. Install Dependencies
|
||||
|
||||
``` sh
|
||||
php composer.phar install
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the Project
|
||||
|
||||
2. Install Development Dependencies
|
||||
2. Ensure you have Composer installed (see [Composer Download Instructions](https://getcomposer.org/download/))
|
||||
|
||||
3. Create a Feature Branch
|
||||
3. Install Development Dependencies
|
||||
|
||||
4. (Recommended) Run the Test Suite
|
||||
``` sh
|
||||
composer install
|
||||
```
|
||||
|
||||
4. Create a Feature Branch
|
||||
|
||||
5. (Recommended) Run the Test Suite
|
||||
|
||||
``` sh
|
||||
vendor/bin/phpunit
|
||||
```
|
||||
5. (Recommended) Check whether your code conforms to our Coding Standards by running
|
||||
6. (Recommended) Check whether your code conforms to our Coding Standards by running
|
||||
|
||||
``` sh
|
||||
vendor/bin/phing -f build/build.xml sniff
|
||||
```
|
||||
|
||||
6. Send us a Pull Request
|
||||
7. Send us a Pull Request
|
||||
|
||||
2
vendor/phpseclib/phpseclib/composer.json
vendored
2
vendor/phpseclib/phpseclib/composer.json
vendored
@@ -55,7 +55,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phing/phing": "~2.7",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"phpunit/phpunit": "^4.8.35|^5.7|^6.0",
|
||||
"sami/sami": "~2.0",
|
||||
"squizlabs/php_codesniffer": "~2.0"
|
||||
},
|
||||
|
||||
1819
vendor/phpseclib/phpseclib/composer.lock
generated
vendored
1819
vendor/phpseclib/phpseclib/composer.lock
generated
vendored
File diff suppressed because it is too large
Load Diff
159
vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
vendored
159
vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
vendored
@@ -76,6 +76,10 @@ abstract class Base
|
||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
||||
*/
|
||||
const MODE_CFB = 3;
|
||||
/**
|
||||
* Encrypt / decrypt using the Cipher Feedback mode (8bit)
|
||||
*/
|
||||
const MODE_CFB8 = 38;
|
||||
/**
|
||||
* Encrypt / decrypt using the Output Feedback mode.
|
||||
*
|
||||
@@ -479,6 +483,7 @@ abstract class Base
|
||||
break;
|
||||
case self::MODE_CTR:
|
||||
case self::MODE_CFB:
|
||||
case self::MODE_CFB8:
|
||||
case self::MODE_OFB:
|
||||
case self::MODE_STREAM:
|
||||
$this->mode = $mode;
|
||||
@@ -492,8 +497,8 @@ abstract class Base
|
||||
$this->_setEngine();
|
||||
|
||||
// Determining whether inline crypting can be used by the cipher
|
||||
if ($this->use_inline_crypt !== false && function_exists('create_function')) {
|
||||
$this->use_inline_crypt = true;
|
||||
if ($this->use_inline_crypt !== false) {
|
||||
$this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,6 +767,16 @@ abstract class Base
|
||||
$iv = substr($ciphertext, -$this->block_size);
|
||||
}
|
||||
|
||||
return $ciphertext;
|
||||
case self::MODE_CFB8:
|
||||
$ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
|
||||
if ($this->continuousBuffer) {
|
||||
if (($len = strlen($ciphertext)) >= $this->block_size) {
|
||||
$this->encryptIV = substr($ciphertext, -$this->block_size);
|
||||
} else {
|
||||
$this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len);
|
||||
}
|
||||
}
|
||||
return $ciphertext;
|
||||
case self::MODE_OFB:
|
||||
return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
|
||||
@@ -942,6 +957,24 @@ abstract class Base
|
||||
$pos = $len;
|
||||
}
|
||||
break;
|
||||
case self::MODE_CFB8:
|
||||
$ciphertext = '';
|
||||
$len = strlen($plaintext);
|
||||
$iv = $this->encryptIV;
|
||||
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
$ciphertext .= ($c = $plaintext[$i] ^ $this->_encryptBlock($iv));
|
||||
$iv = substr($iv, 1) . $c;
|
||||
}
|
||||
|
||||
if ($this->continuousBuffer) {
|
||||
if ($len >= $block_size) {
|
||||
$this->encryptIV = substr($ciphertext, -$block_size);
|
||||
} else {
|
||||
$this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case self::MODE_OFB:
|
||||
$xor = $this->encryptIV;
|
||||
if (strlen($buffer['xor'])) {
|
||||
@@ -1072,6 +1105,16 @@ abstract class Base
|
||||
$iv = substr($ciphertext, -$this->block_size);
|
||||
}
|
||||
break;
|
||||
case self::MODE_CFB8:
|
||||
$plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
|
||||
if ($this->continuousBuffer) {
|
||||
if (($len = strlen($ciphertext)) >= $this->block_size) {
|
||||
$this->decryptIV = substr($ciphertext, -$this->block_size);
|
||||
} else {
|
||||
$this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case self::MODE_OFB:
|
||||
$plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
|
||||
}
|
||||
@@ -1235,6 +1278,24 @@ abstract class Base
|
||||
$pos = $len;
|
||||
}
|
||||
break;
|
||||
case self::MODE_CFB8:
|
||||
$plaintext = '';
|
||||
$len = strlen($ciphertext);
|
||||
$iv = $this->decryptIV;
|
||||
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
$plaintext .= $ciphertext[$i] ^ $this->_encryptBlock($iv);
|
||||
$iv = substr($iv, 1) . $ciphertext[$i];
|
||||
}
|
||||
|
||||
if ($this->continuousBuffer) {
|
||||
if ($len >= $block_size) {
|
||||
$this->decryptIV = substr($ciphertext, -$block_size);
|
||||
} else {
|
||||
$this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case self::MODE_OFB:
|
||||
$xor = $this->decryptIV;
|
||||
if (strlen($buffer['xor'])) {
|
||||
@@ -1435,6 +1496,8 @@ abstract class Base
|
||||
return 'ctr';
|
||||
case self::MODE_CFB:
|
||||
return 'cfb';
|
||||
case self::MODE_CFB8:
|
||||
return 'cfb8';
|
||||
case self::MODE_OFB:
|
||||
return 'ofb';
|
||||
}
|
||||
@@ -1788,6 +1851,7 @@ abstract class Base
|
||||
self::MODE_ECB => MCRYPT_MODE_ECB,
|
||||
self::MODE_CBC => MCRYPT_MODE_CBC,
|
||||
self::MODE_CFB => 'ncfb',
|
||||
self::MODE_CFB8 => MCRYPT_MODE_CFB,
|
||||
self::MODE_OFB => MCRYPT_MODE_NOFB,
|
||||
self::MODE_STREAM => MCRYPT_MODE_STREAM,
|
||||
);
|
||||
@@ -2359,6 +2423,52 @@ abstract class Base
|
||||
$_pos = $_len;
|
||||
}
|
||||
|
||||
return $_plaintext;
|
||||
';
|
||||
break;
|
||||
case self::MODE_CFB8:
|
||||
$encrypt = $init_encrypt . '
|
||||
$_ciphertext = "";
|
||||
$_len = strlen($_text);
|
||||
$_iv = $self->encryptIV;
|
||||
|
||||
for ($_i = 0; $_i < $_len; ++$_i) {
|
||||
$in = $_iv;
|
||||
'.$encrypt_block.'
|
||||
$_ciphertext .= ($_c = $_text[$_i] ^ $in);
|
||||
$_iv = substr($_iv, 1) . $_c;
|
||||
}
|
||||
|
||||
if ($self->continuousBuffer) {
|
||||
if ($_len >= '.$block_size.') {
|
||||
$self->encryptIV = substr($_ciphertext, -'.$block_size.');
|
||||
} else {
|
||||
$self->encryptIV = substr($self->encryptIV, $_len - '.$block_size.') . substr($_ciphertext, -$_len);
|
||||
}
|
||||
}
|
||||
|
||||
return $_ciphertext;
|
||||
';
|
||||
$decrypt = $init_encrypt . '
|
||||
$_plaintext = "";
|
||||
$_len = strlen($_text);
|
||||
$_iv = $self->decryptIV;
|
||||
|
||||
for ($_i = 0; $_i < $_len; ++$_i) {
|
||||
$in = $_iv;
|
||||
'.$encrypt_block.'
|
||||
$_plaintext .= $_text[$_i] ^ $in;
|
||||
$_iv = substr($_iv, 1) . $_text[$_i];
|
||||
}
|
||||
|
||||
if ($self->continuousBuffer) {
|
||||
if ($_len >= '.$block_size.') {
|
||||
$self->decryptIV = substr($_text, -'.$block_size.');
|
||||
} else {
|
||||
$self->decryptIV = substr($self->decryptIV, $_len - '.$block_size.') . substr($_text, -$_len);
|
||||
}
|
||||
}
|
||||
|
||||
return $_plaintext;
|
||||
';
|
||||
break;
|
||||
@@ -2492,6 +2602,11 @@ abstract class Base
|
||||
}
|
||||
|
||||
// Create the $inline function and return its name as string. Ready to run!
|
||||
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
|
||||
eval('$func = function ($_action, &$self, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' } };');
|
||||
return $func;
|
||||
}
|
||||
|
||||
return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
|
||||
}
|
||||
|
||||
@@ -2550,4 +2665,44 @@ abstract class Base
|
||||
return $result . pack('H*', sha1($hash));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert float to int
|
||||
*
|
||||
* On ARM CPUs converting floats to ints doesn't always work
|
||||
*
|
||||
* @access private
|
||||
* @param string $x
|
||||
* @return int
|
||||
*/
|
||||
function safe_intval($x)
|
||||
{
|
||||
switch (true) {
|
||||
case is_int($x):
|
||||
// PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
|
||||
case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
|
||||
return $x;
|
||||
}
|
||||
return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
|
||||
((fmod(floor($x / 0x80000000), 2) & 1) << 31);
|
||||
}
|
||||
|
||||
/**
|
||||
* eval()'able string for in-line float to int
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
function safe_intval_inline()
|
||||
{
|
||||
switch (true) {
|
||||
case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8:
|
||||
case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
|
||||
return '%s';
|
||||
break;
|
||||
default:
|
||||
$safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
|
||||
return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ class Blowfish extends Base
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length < 32) {
|
||||
$this->key_length = 7;
|
||||
$this->key_length = 4;
|
||||
} elseif ($length > 448) {
|
||||
$this->key_length = 56;
|
||||
} else {
|
||||
@@ -317,7 +317,10 @@ class Blowfish extends Base
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($engine == self::ENGINE_OPENSSL) {
|
||||
if ($this->key_length != 16) {
|
||||
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';
|
||||
@@ -405,16 +408,14 @@ class Blowfish extends Base
|
||||
|
||||
for ($i = 0; $i < 16; $i+= 2) {
|
||||
$l^= $p[$i];
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$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];
|
||||
$sb_3[$l & 0xff]);
|
||||
|
||||
$r^= $p[$i + 1];
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$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];
|
||||
$sb_3[$r & 0xff]);
|
||||
}
|
||||
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
|
||||
}
|
||||
@@ -440,16 +441,14 @@ class Blowfish extends Base
|
||||
|
||||
for ($i = 17; $i > 2; $i-= 2) {
|
||||
$l^= $p[$i];
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$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];
|
||||
$sb_3[$l & 0xff]);
|
||||
|
||||
$r^= $p[$i - 1];
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$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];
|
||||
$sb_3[$r & 0xff]);
|
||||
}
|
||||
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
|
||||
}
|
||||
@@ -475,6 +474,8 @@ class Blowfish extends Base
|
||||
$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:
|
||||
@@ -510,16 +511,14 @@ class Blowfish extends Base
|
||||
for ($i = 0; $i < 16; $i+= 2) {
|
||||
$encrypt_block.= '
|
||||
$l^= ' . $p[$i] . ';
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
$sb_3[$l & 0xff]') . ';
|
||||
|
||||
$r^= ' . $p[$i + 1] . ';
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
$sb_3[$r & 0xff]') . ';
|
||||
';
|
||||
}
|
||||
$encrypt_block.= '
|
||||
@@ -539,16 +538,14 @@ class Blowfish extends Base
|
||||
for ($i = 17; $i > 2; $i-= 2) {
|
||||
$decrypt_block.= '
|
||||
$l^= ' . $p[$i] . ';
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
$sb_3[$l & 0xff]') . ';
|
||||
|
||||
$r^= ' . $p[$i - 1] . ';
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
$sb_3[$r & 0xff]') . ';
|
||||
';
|
||||
}
|
||||
|
||||
|
||||
@@ -1357,8 +1357,8 @@ class DES extends Base
|
||||
$k[self::ENCRYPT][$i] = '$ke[' . $i . ']';
|
||||
$k[self::DECRYPT][$i] = '$kd[' . $i . ']';
|
||||
}
|
||||
$init_encrypt = '$ke = $self->keys[self::ENCRYPT];';
|
||||
$init_decrypt = '$kd = $self->keys[self::DECRYPT];';
|
||||
$init_encrypt = '$ke = $self->keys[$self::ENCRYPT];';
|
||||
$init_decrypt = '$kd = $self->keys[$self::DECRYPT];';
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -802,7 +802,12 @@ class Hash
|
||||
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
||||
}
|
||||
|
||||
return fmod($result, $mod);
|
||||
if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') {
|
||||
return fmod($result, $mod);
|
||||
}
|
||||
|
||||
return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
|
||||
((fmod(floor($result / 0x80000000), 2) & 1) << 31);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -296,7 +296,7 @@ class RC2 extends Base
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length < 8) {
|
||||
$this->default_key_length = 8;
|
||||
$this->default_key_length = 1;
|
||||
} elseif ($length > 1024) {
|
||||
$this->default_key_length = 128;
|
||||
} else {
|
||||
|
||||
@@ -107,7 +107,7 @@ class RC4 extends Base
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0";
|
||||
var $key;
|
||||
|
||||
/**
|
||||
* The Key Stream for decryption and encryption
|
||||
@@ -144,8 +144,10 @@ class RC4 extends Base
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
switch ($engine) {
|
||||
case Base::ENGINE_OPENSSL:
|
||||
if ($engine == Base::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';
|
||||
@@ -159,6 +161,7 @@ class RC4 extends Base
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
|
||||
@@ -468,23 +468,27 @@ class RSA
|
||||
break;
|
||||
case extension_loaded('openssl') && file_exists($this->configFile):
|
||||
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
|
||||
ob_start();
|
||||
@phpinfo();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
|
||||
|
||||
$versions = array();
|
||||
if (!empty($matches[1])) {
|
||||
for ($i = 0; $i < count($matches[1]); $i++) {
|
||||
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
||||
|
||||
// Remove letter part in OpenSSL version
|
||||
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
||||
$versions[$matches[1][$i]] = $fullVersion;
|
||||
} else {
|
||||
$versions[$matches[1][$i]] = $m[0];
|
||||
// avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems)
|
||||
if (strpos(ini_get('disable_functions'), 'phpinfo') === false) {
|
||||
ob_start();
|
||||
@phpinfo();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
|
||||
|
||||
if (!empty($matches[1])) {
|
||||
for ($i = 0; $i < count($matches[1]); $i++) {
|
||||
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
||||
|
||||
// Remove letter part in OpenSSL version
|
||||
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
||||
$versions[$matches[1][$i]] = $fullVersion;
|
||||
} else {
|
||||
$versions[$matches[1][$i]] = $m[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1572,6 +1576,15 @@ class RSA
|
||||
}
|
||||
|
||||
if ($components === false) {
|
||||
$this->comment = null;
|
||||
$this->modulus = null;
|
||||
$this->k = null;
|
||||
$this->exponent = null;
|
||||
$this->primes = null;
|
||||
$this->exponents = null;
|
||||
$this->coefficients = null;
|
||||
$this->publicExponent = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2414,7 +2427,7 @@ class RSA
|
||||
$db = $maskedDB ^ $dbMask;
|
||||
$lHash2 = substr($db, 0, $this->hLen);
|
||||
$m = substr($db, $this->hLen);
|
||||
if ($lHash != $lHash2) {
|
||||
if (!$this->_equals($lHash, $lHash2)) {
|
||||
user_error('Decryption error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,10 @@ class Random
|
||||
*/
|
||||
static function string($length)
|
||||
{
|
||||
if (!$length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
|
||||
try {
|
||||
return \random_bytes($length);
|
||||
@@ -62,7 +66,7 @@ class Random
|
||||
// method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
|
||||
// ie. class_alias is a function that was introduced in PHP 5.3
|
||||
if (extension_loaded('mcrypt') && function_exists('class_alias')) {
|
||||
return mcrypt_create_iv($length);
|
||||
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
|
||||
@@ -101,7 +105,7 @@ class Random
|
||||
// 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);
|
||||
return @mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
|
||||
}
|
||||
}
|
||||
// at this point we have no choice but to use a pure-PHP CSPRNG
|
||||
|
||||
@@ -432,8 +432,10 @@ class Twofish extends Base
|
||||
$m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
|
||||
$m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
|
||||
$B = ($B << 8) | ($B >> 24 & 0xff);
|
||||
$K[] = $A+= $B;
|
||||
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
|
||||
$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];
|
||||
@@ -456,8 +458,10 @@ class Twofish extends Base
|
||||
$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);
|
||||
$K[] = $A+= $B;
|
||||
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
|
||||
$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];
|
||||
@@ -481,8 +485,10 @@ class Twofish extends Base
|
||||
$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);
|
||||
$K[] = $A+= $B;
|
||||
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
|
||||
$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];
|
||||
@@ -578,9 +584,9 @@ class Twofish extends Base
|
||||
$S1[ $R1 & 0xff] ^
|
||||
$S2[($R1 >> 8) & 0xff] ^
|
||||
$S3[($R1 >> 16) & 0xff];
|
||||
$R2^= $t0 + $t1 + $K[++$ki];
|
||||
$R2^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
|
||||
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
|
||||
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
|
||||
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
|
||||
|
||||
$t0 = $S0[ $R2 & 0xff] ^
|
||||
$S1[($R2 >> 8) & 0xff] ^
|
||||
@@ -590,9 +596,9 @@ class Twofish extends Base
|
||||
$S1[ $R3 & 0xff] ^
|
||||
$S2[($R3 >> 8) & 0xff] ^
|
||||
$S3[($R3 >> 16) & 0xff];
|
||||
$R0^= ($t0 + $t1 + $K[++$ki]);
|
||||
$R0^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
|
||||
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
|
||||
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
|
||||
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
@@ -634,9 +640,9 @@ class Twofish extends Base
|
||||
$S1[$R1 & 0xff] ^
|
||||
$S2[$R1 >> 8 & 0xff] ^
|
||||
$S3[$R1 >> 16 & 0xff];
|
||||
$R3^= $t0 + ($t1 << 1) + $K[--$ki];
|
||||
$R3^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
|
||||
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
|
||||
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + $K[--$ki]);
|
||||
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
|
||||
|
||||
$t0 = $S0[$R2 & 0xff] ^
|
||||
$S1[$R2 >> 8 & 0xff] ^
|
||||
@@ -646,9 +652,9 @@ class Twofish extends Base
|
||||
$S1[$R3 & 0xff] ^
|
||||
$S2[$R3 >> 8 & 0xff] ^
|
||||
$S3[$R3 >> 16 & 0xff];
|
||||
$R1^= $t0 + ($t1 << 1) + $K[--$ki];
|
||||
$R1^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
|
||||
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
|
||||
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K[--$ki]);
|
||||
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
@@ -679,6 +685,8 @@ class Twofish extends Base
|
||||
$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:
|
||||
@@ -727,9 +735,9 @@ class Twofish extends Base
|
||||
$S1[ $R1 & 0xff] ^
|
||||
$S2[($R1 >> 8) & 0xff] ^
|
||||
$S3[($R1 >> 16) & 0xff];
|
||||
$R2^= ($t0 + $t1 + '.$K[++$ki].');
|
||||
$R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . ';
|
||||
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
|
||||
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
|
||||
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
|
||||
|
||||
$t0 = $S0[ $R2 & 0xff] ^
|
||||
$S1[($R2 >> 8) & 0xff] ^
|
||||
@@ -739,16 +747,16 @@ class Twofish extends Base
|
||||
$S1[ $R3 & 0xff] ^
|
||||
$S2[($R3 >> 8) & 0xff] ^
|
||||
$S3[($R3 >> 16) & 0xff];
|
||||
$R0^= ($t0 + $t1 + '.$K[++$ki].');
|
||||
$R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . ';
|
||||
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
|
||||
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
|
||||
$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);
|
||||
$in = pack("V4", ' . $K[4] . ' ^ $R2,
|
||||
' . $K[5] . ' ^ $R3,
|
||||
' . $K[6] . ' ^ $R0,
|
||||
' . $K[7] . ' ^ $R1);
|
||||
';
|
||||
|
||||
// Generating decrypt code:
|
||||
@@ -769,9 +777,9 @@ class Twofish extends Base
|
||||
$S1[$R1 & 0xff] ^
|
||||
$S2[$R1 >> 8 & 0xff] ^
|
||||
$S3[$R1 >> 16 & 0xff];
|
||||
$R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
|
||||
$R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
|
||||
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
|
||||
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
|
||||
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
|
||||
|
||||
$t0 = $S0[$R2 & 0xff] ^
|
||||
$S1[$R2 >> 8 & 0xff] ^
|
||||
@@ -781,16 +789,16 @@ class Twofish extends Base
|
||||
$S1[$R3 & 0xff] ^
|
||||
$S2[$R3 >> 8 & 0xff] ^
|
||||
$S3[$R3 >> 16 & 0xff];
|
||||
$R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
|
||||
$R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
|
||||
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
|
||||
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
|
||||
$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);
|
||||
$in = pack("V4", ' . $K[0] . ' ^ $R2,
|
||||
' . $K[1] . ' ^ $R3,
|
||||
' . $K[2] . ' ^ $R0,
|
||||
' . $K[3] . ' ^ $R1);
|
||||
';
|
||||
|
||||
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
|
||||
|
||||
@@ -305,6 +305,9 @@ class ANSI
|
||||
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;
|
||||
@@ -416,7 +419,7 @@ class ANSI
|
||||
|
||||
if ($this->x > $this->max_x) {
|
||||
$this->x = 0;
|
||||
$this->y++;
|
||||
$this->_newLine();
|
||||
} else {
|
||||
$this->x++;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace phpseclib\File;
|
||||
|
||||
use phpseclib\File\ASN1\Element;
|
||||
use phpseclib\Math\BigInteger;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
|
||||
/**
|
||||
* Pure-PHP ASN.1 Parser
|
||||
@@ -580,7 +582,7 @@ class ASN1
|
||||
$childClass = $tempClass = self::CLASS_UNIVERSAL;
|
||||
$constant = null;
|
||||
if (isset($temp['constant'])) {
|
||||
$tempClass = isset($temp['class']) ? $temp['class'] : self::CLASS_CONTEXT_SPECIFIC;
|
||||
$tempClass = $temp['type'];
|
||||
}
|
||||
if (isset($child['class'])) {
|
||||
$childClass = $child['class'];
|
||||
@@ -643,7 +645,7 @@ class ASN1
|
||||
$temp = $decoded['content'][$i];
|
||||
$tempClass = self::CLASS_UNIVERSAL;
|
||||
if (isset($temp['constant'])) {
|
||||
$tempClass = isset($temp['class']) ? $temp['class'] : self::CLASS_CONTEXT_SPECIFIC;
|
||||
$tempClass = $temp['type'];
|
||||
}
|
||||
|
||||
foreach ($mapping['children'] as $key => $child) {
|
||||
@@ -707,7 +709,7 @@ class ASN1
|
||||
if (isset($mapping['implicit'])) {
|
||||
$decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']);
|
||||
}
|
||||
return @date($this->format, $decoded['content']);
|
||||
return $decoded['content'] ? $decoded['content']->format($this->format) : false;
|
||||
case self::TYPE_BIT_STRING:
|
||||
if (isset($mapping['mapping'])) {
|
||||
$offset = ord($decoded['content'][0]);
|
||||
@@ -956,7 +958,8 @@ class ASN1
|
||||
case self::TYPE_GENERALIZED_TIME:
|
||||
$format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y';
|
||||
$format.= 'mdHis';
|
||||
$value = @gmdate($format, strtotime($source)) . 'Z';
|
||||
$date = new DateTime($source, new DateTimeZone('GMT'));
|
||||
$value = $date->format($format) . 'Z';
|
||||
break;
|
||||
case self::TYPE_BIT_STRING:
|
||||
if (isset($mapping['mapping'])) {
|
||||
@@ -1137,33 +1140,32 @@ class ASN1
|
||||
http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
|
||||
http://www.obj-sys.com/asn1tutorial/node14.html */
|
||||
|
||||
$pattern = $tag == self::TYPE_UTC_TIME ?
|
||||
'#(..)(..)(..)(..)(..)(..)(.*)#' :
|
||||
'#(....)(..)(..)(..)(..)(..).*([Z+-].*)$#';
|
||||
|
||||
preg_match($pattern, $content, $matches);
|
||||
|
||||
list(, $year, $month, $day, $hour, $minute, $second, $timezone) = $matches;
|
||||
$format = 'YmdHis';
|
||||
|
||||
if ($tag == self::TYPE_UTC_TIME) {
|
||||
$year = $year >= 50 ? "19$year" : "20$year";
|
||||
}
|
||||
|
||||
if ($timezone == 'Z') {
|
||||
$mktime = 'gmmktime';
|
||||
$timezone = 0;
|
||||
} elseif (preg_match('#([+-])(\d\d)(\d\d)#', $timezone, $matches)) {
|
||||
$mktime = 'gmmktime';
|
||||
$timezone = 60 * $matches[3] + 3600 * $matches[2];
|
||||
if ($matches[1] == '-') {
|
||||
$timezone = -$timezone;
|
||||
// https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds
|
||||
// element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the
|
||||
// browsers parse it phpseclib ought to too
|
||||
if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) {
|
||||
$content = $matches[1] . '00' . $matches[2];
|
||||
}
|
||||
} else {
|
||||
$mktime = 'mktime';
|
||||
$timezone = 0;
|
||||
$prefix = substr($content, 0, 2) >= 50 ? '19' : '20';
|
||||
$content = $prefix . $content;
|
||||
} elseif (strpos($content, '.') !== false) {
|
||||
$format.= '.u';
|
||||
}
|
||||
|
||||
return @$mktime($hour, $minute, $second, $month, $day, $year) + $timezone;
|
||||
if ($content[strlen($content) - 1] == 'Z') {
|
||||
$content = substr($content, 0, -1) . '+0000';
|
||||
}
|
||||
|
||||
if (strpos($content, '-') !== false || strpos($content, '+') !== false) {
|
||||
$format.= 'O';
|
||||
}
|
||||
|
||||
// error supression isn't necessary as of PHP 7.0:
|
||||
// http://php.net/manual/en/migration70.other-changes.php
|
||||
return @DateTime::createFromFormat($format, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
308
vendor/phpseclib/phpseclib/phpseclib/File/X509.php
vendored
308
vendor/phpseclib/phpseclib/phpseclib/File/X509.php
vendored
@@ -31,6 +31,8 @@ use phpseclib\Crypt\Random;
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\File\ASN1\Element;
|
||||
use phpseclib\Math\BigInteger;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
|
||||
/**
|
||||
* Pure-PHP X.509 Parser
|
||||
@@ -303,6 +305,22 @@ class X509
|
||||
*/
|
||||
var $challenge;
|
||||
|
||||
/**
|
||||
* Recursion Limit
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
static $recur_limit = 5;
|
||||
|
||||
/**
|
||||
* URL fetch flag
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
static $disable_url_fetch = false;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
@@ -1907,6 +1925,9 @@ class X509
|
||||
// "SET Secure Electronic Transaction Specification"
|
||||
// http://www.maithean.com/docs/set_bk3.pdf
|
||||
case '2.23.42.7.0': // id-set-hashedRootKey
|
||||
// "Certificate Transparency"
|
||||
// https://tools.ietf.org/html/rfc6962
|
||||
case '1.3.6.1.4.1.11129.2.4.2':
|
||||
return true;
|
||||
|
||||
// CSR attributes
|
||||
@@ -2027,30 +2048,32 @@ class X509
|
||||
}
|
||||
|
||||
if ($names = $this->getExtension('id-ce-subjectAltName')) {
|
||||
foreach ($names as $key => $value) {
|
||||
$value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value);
|
||||
switch ($key) {
|
||||
case 'dNSName':
|
||||
/* From RFC2818 "HTTP over TLS":
|
||||
foreach ($names as $name) {
|
||||
foreach ($name as $key => $value) {
|
||||
$value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value);
|
||||
switch ($key) {
|
||||
case 'dNSName':
|
||||
/* From RFC2818 "HTTP over TLS":
|
||||
|
||||
If a subjectAltName extension of type dNSName is present, that MUST
|
||||
be used as the identity. Otherwise, the (most specific) Common Name
|
||||
field in the Subject field of the certificate MUST be used. Although
|
||||
the use of the Common Name is existing practice, it is deprecated and
|
||||
Certification Authorities are encouraged to use the dNSName instead. */
|
||||
if (preg_match('#^' . $value . '$#', $components['host'])) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 'iPAddress':
|
||||
/* From RFC2818 "HTTP over TLS":
|
||||
If a subjectAltName extension of type dNSName is present, that MUST
|
||||
be used as the identity. Otherwise, the (most specific) Common Name
|
||||
field in the Subject field of the certificate MUST be used. Although
|
||||
the use of the Common Name is existing practice, it is deprecated and
|
||||
Certification Authorities are encouraged to use the dNSName instead. */
|
||||
if (preg_match('#^' . $value . '$#', $components['host'])) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 'iPAddress':
|
||||
/* From RFC2818 "HTTP over TLS":
|
||||
|
||||
In some cases, the URI is specified as an IP address rather than a
|
||||
hostname. In this case, the iPAddress subjectAltName must be present
|
||||
in the certificate and must exactly match the IP in the URI. */
|
||||
if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) {
|
||||
return true;
|
||||
}
|
||||
In some cases, the URI is specified as an IP address rather than a
|
||||
hostname. In this case, the iPAddress subjectAltName must be present
|
||||
in the certificate and must exactly match the IP in the URI. */
|
||||
if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -2079,7 +2102,7 @@ class X509
|
||||
}
|
||||
|
||||
if (!isset($date)) {
|
||||
$date = time();
|
||||
$date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
|
||||
}
|
||||
|
||||
$notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
|
||||
@@ -2089,14 +2112,125 @@ class X509
|
||||
$notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
|
||||
|
||||
switch (true) {
|
||||
case $date < @strtotime($notBefore):
|
||||
case $date > @strtotime($notAfter):
|
||||
case $date < new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get())):
|
||||
case $date > new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get())):
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a URL
|
||||
*
|
||||
* @param string $url
|
||||
* @access private
|
||||
* @return bool|string
|
||||
*/
|
||||
static function _fetchURL($url)
|
||||
{
|
||||
if (self::$disable_url_fetch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parts = parse_url($url);
|
||||
$data = '';
|
||||
switch ($parts['scheme']) {
|
||||
case 'http':
|
||||
$fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80);
|
||||
if (!$fsock) {
|
||||
return false;
|
||||
}
|
||||
fputs($fsock, "GET $parts[path] HTTP/1.0\r\n");
|
||||
fputs($fsock, "Host: $parts[host]\r\n\r\n");
|
||||
$line = fgets($fsock, 1024);
|
||||
if (strlen($line) < 3) {
|
||||
return false;
|
||||
}
|
||||
preg_match('#HTTP/1.\d (\d{3})#', $line, $temp);
|
||||
if ($temp[1] != '200') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// skip the rest of the headers in the http response
|
||||
while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") {
|
||||
}
|
||||
|
||||
while (!feof($fsock)) {
|
||||
$data.= fread($fsock, 1024);
|
||||
}
|
||||
|
||||
break;
|
||||
//case 'ftp':
|
||||
//case 'ldap':
|
||||
//default:
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an intermediate cert as identified via authority info access extension
|
||||
*
|
||||
* See https://tools.ietf.org/html/rfc4325 for more info
|
||||
*
|
||||
* @param bool $caonly
|
||||
* @param int $count
|
||||
* @access private
|
||||
* @return bool
|
||||
*/
|
||||
function _testForIntermediate($caonly, $count)
|
||||
{
|
||||
$opts = $this->getExtension('id-pe-authorityInfoAccess');
|
||||
if (!is_array($opts)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($opts as $opt) {
|
||||
if ($opt['accessMethod'] == 'id-ad-caIssuers') {
|
||||
// accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP,
|
||||
// etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325
|
||||
// discusses
|
||||
if (isset($opt['accessLocation']['uniformResourceIdentifier'])) {
|
||||
$url = $opt['accessLocation']['uniformResourceIdentifier'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cert = static::_fetchURL($url);
|
||||
if (!is_string($cert)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parent = new static();
|
||||
$parent->CAs = $this->CAs;
|
||||
/*
|
||||
"Conforming applications that support HTTP or FTP for accessing
|
||||
certificates MUST be able to accept .cer files and SHOULD be able
|
||||
to accept .p7c files." -- https://tools.ietf.org/html/rfc4325
|
||||
|
||||
A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797"
|
||||
|
||||
These are currently unsupported
|
||||
*/
|
||||
if (!is_array($parent->loadX509($cert))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$parent->_validateSignatureCountable($caonly, ++$count)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->CAs[] = $parent->currentCert;
|
||||
//$this->loadCA($cert);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a signature
|
||||
*
|
||||
@@ -2113,11 +2247,30 @@ class X509
|
||||
* @return mixed
|
||||
*/
|
||||
function validateSignature($caonly = true)
|
||||
{
|
||||
return $this->_validateSignatureCountable($caonly, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a signature
|
||||
*
|
||||
* Performs said validation whilst keeping track of how many times validation method is called
|
||||
*
|
||||
* @param bool $caonly
|
||||
* @param int $count
|
||||
* @access private
|
||||
* @return mixed
|
||||
*/
|
||||
function _validateSignatureCountable($caonly, $count)
|
||||
{
|
||||
if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($count == self::$recur_limit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
"emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
|
||||
-- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
|
||||
@@ -2134,7 +2287,8 @@ class X509
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
case !$subjectKeyID:
|
||||
case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
$signingCert = $this->currentCert; // working cert
|
||||
}
|
||||
}
|
||||
@@ -2151,17 +2305,21 @@ class X509
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
case !$subjectKeyID:
|
||||
case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
|
||||
break 2; // serial mismatch - check other ca
|
||||
}
|
||||
$signingCert = $ca; // working cert
|
||||
break 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($this->CAs) == $i && $caonly) {
|
||||
return false;
|
||||
return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
|
||||
}
|
||||
} elseif (!isset($signingCert) || $caonly) {
|
||||
return false;
|
||||
return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
|
||||
}
|
||||
return $this->_validateSignature(
|
||||
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
|
||||
@@ -2197,7 +2355,11 @@ class X509
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
case !$subjectKeyID:
|
||||
case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
|
||||
break 2; // serial mismatch - check other ca
|
||||
}
|
||||
$signingCert = $ca; // working cert
|
||||
break 3;
|
||||
}
|
||||
@@ -2264,6 +2426,41 @@ class X509
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the recursion limit
|
||||
*
|
||||
* When validating a signature it may be necessary to download intermediate certs from URI's.
|
||||
* An intermediate cert that linked to itself would result in an infinite loop so to prevent
|
||||
* that we set a recursion limit. A negative number means that there is no recursion limit.
|
||||
*
|
||||
* @param int $count
|
||||
* @access public
|
||||
*/
|
||||
static function setRecurLimit($count)
|
||||
{
|
||||
self::$recur_limit = $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents URIs from being automatically retrieved
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
static function disableURLFetch()
|
||||
{
|
||||
self::$disable_url_fetch = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows URIs to be automatically retrieved
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
static function enableURLFetch()
|
||||
{
|
||||
self::$disable_url_fetch = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reformat public keys
|
||||
*
|
||||
@@ -2469,6 +2666,10 @@ class X509
|
||||
}
|
||||
|
||||
$dn = array_values($dn);
|
||||
// fix for https://bugs.php.net/75433 affecting PHP 7.2
|
||||
if (!isset($dn[0])) {
|
||||
$dn = array_splice($dn, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2712,7 +2913,9 @@ class X509
|
||||
$value = array_pop($value); // Always strip data type.
|
||||
}
|
||||
} elseif (is_object($value) && $value instanceof Element) {
|
||||
$callback = create_function('$x', 'return "\x" . bin2hex($x[0]);');
|
||||
$callback = function ($x) {
|
||||
return "\x" . bin2hex($x[0]);
|
||||
};
|
||||
$value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
|
||||
}
|
||||
$output.= $desc . '=' . $value;
|
||||
@@ -3335,7 +3538,11 @@ class X509
|
||||
*/
|
||||
function _timeField($date)
|
||||
{
|
||||
$year = @gmdate("Y", @strtotime($date)); // the same way ASN1.php parses this
|
||||
if ($date instanceof Element) {
|
||||
return $date;
|
||||
}
|
||||
$dateObj = new DateTime($date, new DateTimeZone('GMT'));
|
||||
$year = $dateObj->format('Y'); // the same way ASN1.php parses this
|
||||
if ($year < 2050) {
|
||||
return array('utcTime' => $date);
|
||||
} else {
|
||||
@@ -3400,8 +3607,12 @@ class X509
|
||||
return false;
|
||||
}
|
||||
|
||||
$startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
|
||||
$endDate = !empty($this->endDate) ? $this->endDate : @date('D, d M Y H:i:s O', strtotime('+1 year'));
|
||||
$startDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
|
||||
$startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O');
|
||||
|
||||
$endDate = new DateTime('+1 year', new DateTimeZone(@date_default_timezone_get()));
|
||||
$endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O');
|
||||
|
||||
/* "The serial number MUST be a positive integer"
|
||||
"Conforming CAs MUST NOT use serialNumber values longer than 20 octets."
|
||||
-- https://tools.ietf.org/html/rfc5280#section-4.1.2.2
|
||||
@@ -3417,7 +3628,7 @@ class X509
|
||||
'tbsCertificate' =>
|
||||
array(
|
||||
'version' => 'v3',
|
||||
'serialNumber' => $serialNumber, // $this->setserialNumber()
|
||||
'serialNumber' => $serialNumber, // $this->setSerialNumber()
|
||||
'signature' => array('algorithm' => $signatureAlgorithm),
|
||||
'issuer' => false, // this is going to be overwritten later
|
||||
'validity' => array(
|
||||
@@ -3463,8 +3674,8 @@ class X509
|
||||
|
||||
$altName = array();
|
||||
|
||||
if (isset($subject->domains) && count($subject->domains) > 1) {
|
||||
$altName = array_map(array('X509', '_dnsName'), $subject->domains);
|
||||
if (isset($subject->domains) && count($subject->domains)) {
|
||||
$altName = array_map(array('\phpseclib\File\X509', '_dnsName'), $subject->domains);
|
||||
}
|
||||
|
||||
if (isset($subject->ipAddresses) && count($subject->ipAddresses)) {
|
||||
@@ -3669,7 +3880,9 @@ class X509
|
||||
|
||||
$currentCert = isset($this->currentCert) ? $this->currentCert : null;
|
||||
$signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
|
||||
$thisUpdate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
|
||||
|
||||
$thisUpdate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
|
||||
$thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O');
|
||||
|
||||
if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
|
||||
$this->currentCert = $crl->currentCert;
|
||||
@@ -3820,7 +4033,11 @@ class X509
|
||||
*/
|
||||
function setStartDate($date)
|
||||
{
|
||||
$this->startDate = @date('D, d M Y H:i:s O', @strtotime($date));
|
||||
if (!is_object($date) || !is_a($date, 'DateTime')) {
|
||||
$date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
|
||||
}
|
||||
|
||||
$this->startDate = $date->format('D, d M Y H:i:s O');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3844,7 +4061,11 @@ class X509
|
||||
$temp = chr(ASN1::TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
|
||||
$this->endDate = new Element($temp);
|
||||
} else {
|
||||
$this->endDate = @date('D, d M Y H:i:s O', @strtotime($date));
|
||||
if (!is_object($date) || !is_a($date, 'DateTime')) {
|
||||
$date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
|
||||
}
|
||||
|
||||
$this->endDate = $date->format('D, d M Y H:i:s O');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4054,6 +4275,10 @@ class X509
|
||||
}
|
||||
|
||||
$extensions = array_values($extensions);
|
||||
// fix for https://bugs.php.net/75433 affecting PHP 7.2
|
||||
if (!isset($extensions[0])) {
|
||||
$extensions = array_splice($extensions, 0, 0);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -4574,8 +4799,9 @@ class X509
|
||||
}
|
||||
|
||||
$i = count($rclist);
|
||||
$revocationDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
|
||||
$rclist[] = array('userCertificate' => $serial,
|
||||
'revocationDate' => $this->_timeField(@date('D, d M Y H:i:s O')));
|
||||
'revocationDate' => $this->_timeField($revocationDate->format('D, d M Y H:i:s O')));
|
||||
return $i;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,23 +266,27 @@ class BigInteger
|
||||
|
||||
if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
|
||||
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
|
||||
ob_start();
|
||||
@phpinfo();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
|
||||
|
||||
$versions = array();
|
||||
if (!empty($matches[1])) {
|
||||
for ($i = 0; $i < count($matches[1]); $i++) {
|
||||
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
||||
|
||||
// Remove letter part in OpenSSL version
|
||||
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
||||
$versions[$matches[1][$i]] = $fullVersion;
|
||||
} else {
|
||||
$versions[$matches[1][$i]] = $m[0];
|
||||
// avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems)
|
||||
if (strpos(ini_get('disable_functions'), 'phpinfo') === false) {
|
||||
ob_start();
|
||||
@phpinfo();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
|
||||
|
||||
if (!empty($matches[1])) {
|
||||
for ($i = 0; $i < count($matches[1]); $i++) {
|
||||
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
||||
|
||||
// Remove letter part in OpenSSL version
|
||||
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
||||
$versions[$matches[1][$i]] = $fullVersion;
|
||||
} else {
|
||||
$versions[$matches[1][$i]] = $m[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,8 +364,12 @@ class BigInteger
|
||||
case 256:
|
||||
switch (MATH_BIGINTEGER_MODE) {
|
||||
case self::MODE_GMP:
|
||||
$sign = $this->is_negative ? '-' : '';
|
||||
$this->value = gmp_init($sign . '0x' . bin2hex($x));
|
||||
$this->value = function_exists('gmp_import') ?
|
||||
gmp_import($x) :
|
||||
gmp_init('0x' . bin2hex($x));
|
||||
if ($this->is_negative) {
|
||||
$this->value = gmp_neg($this->value);
|
||||
}
|
||||
break;
|
||||
case self::MODE_BCMATH:
|
||||
// round $len to the nearest 4 (thanks, DavidMJ!)
|
||||
@@ -531,7 +539,7 @@ class BigInteger
|
||||
$temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy();
|
||||
$bytes = $temp->toBytes();
|
||||
|
||||
if (empty($bytes)) { // eg. if the number we're trying to convert is -1
|
||||
if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1
|
||||
$bytes = chr(0);
|
||||
}
|
||||
|
||||
@@ -548,9 +556,13 @@ class BigInteger
|
||||
return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
|
||||
}
|
||||
|
||||
$temp = gmp_strval(gmp_abs($this->value), 16);
|
||||
$temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
|
||||
$temp = pack('H*', $temp);
|
||||
if (function_exists('gmp_export')) {
|
||||
$temp = gmp_export($this->value);
|
||||
} else {
|
||||
$temp = gmp_strval(gmp_abs($this->value), 16);
|
||||
$temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
|
||||
$temp = pack('H*', $temp);
|
||||
}
|
||||
|
||||
return $this->precision > 0 ?
|
||||
substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
|
||||
@@ -2860,8 +2872,7 @@ class BigInteger
|
||||
switch (MATH_BIGINTEGER_MODE) {
|
||||
case self::MODE_GMP:
|
||||
$temp = new static();
|
||||
$temp->value = gmp_xor($this->value, $x->value);
|
||||
|
||||
$temp->value = gmp_xor(gmp_abs($this->value), gmp_abs($x->value));
|
||||
return $this->_normalize($temp);
|
||||
case self::MODE_BCMATH:
|
||||
$left = $this->toBytes();
|
||||
@@ -2877,6 +2888,7 @@ class BigInteger
|
||||
|
||||
$length = max(count($this->value), count($x->value));
|
||||
$result = $this->copy();
|
||||
$result->is_negative = false;
|
||||
$result->value = array_pad($result->value, $length, 0);
|
||||
$x->value = array_pad($x->value, $length, 0);
|
||||
|
||||
@@ -2900,7 +2912,7 @@ class BigInteger
|
||||
// (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
|
||||
$temp = $this->toBytes();
|
||||
if ($temp == '') {
|
||||
return '';
|
||||
return $this->_normalize(new static());
|
||||
}
|
||||
$pre_msb = decbin(ord($temp[0]));
|
||||
$temp = ~$temp;
|
||||
@@ -3435,7 +3447,7 @@ class BigInteger
|
||||
break;
|
||||
}
|
||||
}
|
||||
$s = 26 * $i + $j - 1;
|
||||
$s = 26 * $i + $j;
|
||||
$r->_rshift($s);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ class SCP
|
||||
*
|
||||
* Connects to an SSH server
|
||||
*
|
||||
* @param \phpseclib\Net\SSH1|\phpseclin\Net\SSH2 $ssh
|
||||
* @param \phpseclib\Net\SSH1|\phpseclib\Net\SSH2 $ssh
|
||||
* @return \phpseclib\Net\SCP
|
||||
* @access public
|
||||
*/
|
||||
@@ -299,6 +299,9 @@ class SCP
|
||||
$response = $this->ssh->_get_binary_packet();
|
||||
switch ($response[SSH1::RESPONSE_TYPE]) {
|
||||
case NET_SSH1_SMSG_STDOUT_DATA:
|
||||
if (strlen($response[SSH1::RESPONSE_DATA]) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA]));
|
||||
return $this->ssh->_string_shift($response[SSH1::RESPONSE_DATA], $length);
|
||||
case NET_SSH1_SMSG_STDERR_DATA:
|
||||
|
||||
189
vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
vendored
189
vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
vendored
@@ -158,7 +158,7 @@ class SFTP extends SSH2
|
||||
* Current working directory
|
||||
*
|
||||
* @var string
|
||||
* @see self::_realpath()
|
||||
* @see self::realpath()
|
||||
* @see self::chdir()
|
||||
* @access private
|
||||
*/
|
||||
@@ -187,7 +187,7 @@ class SFTP extends SSH2
|
||||
*
|
||||
* @see self::getSFTPErrors()
|
||||
* @see self::getLastSFTPError()
|
||||
* @var string
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sftp_errors = array();
|
||||
@@ -236,6 +236,20 @@ class SFTP extends SSH2
|
||||
*/
|
||||
var $sortOptions = array();
|
||||
|
||||
/**
|
||||
* Canonicalization Flag
|
||||
*
|
||||
* Determines whether or not paths should be canonicalized before being
|
||||
* passed on to the remote server.
|
||||
*
|
||||
* @see self::enablePathCanonicalization()
|
||||
* @see self::disablePathCanonicalization()
|
||||
* @see self::realpath()
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $canonicalize_paths = true;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
@@ -335,7 +349,7 @@ class SFTP extends SSH2
|
||||
// yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
|
||||
// two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
|
||||
// that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
|
||||
-1 << 31 => 'NET_SFTP_ATTR_EXTENDED'
|
||||
(-1 << 31) & 0xFFFFFFFF => 'NET_SFTP_ATTR_EXTENDED'
|
||||
);
|
||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
|
||||
// the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name
|
||||
@@ -372,7 +386,7 @@ class SFTP extends SSH2
|
||||
);
|
||||
|
||||
if (!defined('NET_SFTP_QUEUE_SIZE')) {
|
||||
define('NET_SFTP_QUEUE_SIZE', 50);
|
||||
define('NET_SFTP_QUEUE_SIZE', 32);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,7 +423,7 @@ class SFTP extends SSH2
|
||||
|
||||
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
|
||||
|
||||
$response = $this->_get_channel_packet(self::CHANNEL);
|
||||
$response = $this->_get_channel_packet(self::CHANNEL, true);
|
||||
if ($response === false) {
|
||||
return false;
|
||||
}
|
||||
@@ -430,7 +444,7 @@ class SFTP extends SSH2
|
||||
|
||||
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
||||
|
||||
$response = $this->_get_channel_packet(self::CHANNEL);
|
||||
$response = $this->_get_channel_packet(self::CHANNEL, true);
|
||||
if ($response === false) {
|
||||
// from PuTTY's psftp.exe
|
||||
$command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
|
||||
@@ -454,7 +468,7 @@ class SFTP extends SSH2
|
||||
|
||||
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
||||
|
||||
$response = $this->_get_channel_packet(self::CHANNEL);
|
||||
$response = $this->_get_channel_packet(self::CHANNEL, true);
|
||||
if ($response === false) {
|
||||
return false;
|
||||
}
|
||||
@@ -472,11 +486,20 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nversion', $this->_string_shift($response, 4)));
|
||||
$this->version = $version;
|
||||
while (!empty($response)) {
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$key = $this->_string_shift($response, $length);
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$value = $this->_string_shift($response, $length);
|
||||
$this->extensions[$key] = $value;
|
||||
@@ -566,6 +589,26 @@ class SFTP extends SSH2
|
||||
$this->stat_cache = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable path canonicalization
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function enablePathCanonicalization()
|
||||
{
|
||||
$this->canonicalize_paths = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable path canonicalization
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function disablePathCanonicalization()
|
||||
{
|
||||
$this->canonicalize_paths = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current directory name
|
||||
*
|
||||
@@ -587,12 +630,15 @@ class SFTP extends SSH2
|
||||
function _logError($response, $status = -1)
|
||||
{
|
||||
if ($status == -1) {
|
||||
if (strlen($response) < 4) {
|
||||
return;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
}
|
||||
|
||||
$error = $this->status_codes[$status];
|
||||
|
||||
if ($this->version > 2) {
|
||||
if ($this->version > 2 || strlen($response) < 4) {
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$this->sftp_errors[] = $error . ': ' . $this->_string_shift($response, $length);
|
||||
} else {
|
||||
@@ -621,13 +667,20 @@ class SFTP extends SSH2
|
||||
* SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns
|
||||
* the absolute (canonicalized) path.
|
||||
*
|
||||
* If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is.
|
||||
*
|
||||
* @see self::chdir()
|
||||
* @see self::disablePathCanonicalization()
|
||||
* @param string $path
|
||||
* @return mixed
|
||||
* @access private
|
||||
*/
|
||||
function _realpath($path)
|
||||
{
|
||||
if (!$this->canonicalize_paths) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
if ($this->pwd === false) {
|
||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
|
||||
if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
|
||||
@@ -641,6 +694,9 @@ class SFTP extends SSH2
|
||||
// should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks
|
||||
// at is the first part and that part is defined the same in SFTP versions 3 through 6.
|
||||
$this->_string_shift($response, 4); // skip over the count - it should be 1, anyway
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
return $this->_string_shift($response, $length);
|
||||
case NET_SFTP_STATUS:
|
||||
@@ -875,10 +931,19 @@ class SFTP extends SSH2
|
||||
$response = $this->_get_sftp_packet();
|
||||
switch ($this->packet_type) {
|
||||
case NET_SFTP_NAME:
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Ncount', $this->_string_shift($response, 4)));
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$shortname = $this->_string_shift($response, $length);
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$longname = $this->_string_shift($response, $length);
|
||||
$attributes = $this->_parseAttributes($response);
|
||||
@@ -905,6 +970,9 @@ class SFTP extends SSH2
|
||||
}
|
||||
break;
|
||||
case NET_SFTP_STATUS:
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
if ($status != NET_SFTP_STATUS_EOF) {
|
||||
$this->_logError($response, $status);
|
||||
@@ -1079,7 +1147,7 @@ class SFTP extends SSH2
|
||||
$temp[$dir] = array();
|
||||
}
|
||||
if ($i === $max) {
|
||||
if (is_object($temp[$dir])) {
|
||||
if (is_object($temp[$dir]) && is_object($value)) {
|
||||
if (!isset($value->stat) && isset($temp[$dir]->stat)) {
|
||||
$value->stat = $temp[$dir]->stat;
|
||||
}
|
||||
@@ -1267,7 +1335,7 @@ class SFTP extends SSH2
|
||||
/**
|
||||
* Returns general information about a file or symbolic link
|
||||
*
|
||||
* Determines information without calling \phpseclib\Net\SFTP::_realpath().
|
||||
* Determines information without calling \phpseclib\Net\SFTP::realpath().
|
||||
* The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
|
||||
*
|
||||
* @param string $filename
|
||||
@@ -1428,7 +1496,7 @@ class SFTP extends SSH2
|
||||
return true;
|
||||
}
|
||||
|
||||
$filename = $this->_realPath($filename);
|
||||
$filename = $this->realpath($filename);
|
||||
// rather than return what the permissions *should* be, we'll return what they actually are. this will also
|
||||
// tell us if the file actually exists.
|
||||
// incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
|
||||
@@ -1499,6 +1567,9 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
if ($status != NET_SFTP_STATUS_OK) {
|
||||
$this->_logError($response, $status);
|
||||
@@ -1611,12 +1682,18 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Ncount', $this->_string_shift($response, 4)));
|
||||
// the file isn't a symlink
|
||||
if (!$count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
return $this->_string_shift($response, $length);
|
||||
}
|
||||
@@ -1651,6 +1728,9 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
if ($status != NET_SFTP_STATUS_OK) {
|
||||
$this->_logError($response, $status);
|
||||
@@ -1714,6 +1794,9 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
if ($status != NET_SFTP_STATUS_OK) {
|
||||
$this->_logError($response, $status);
|
||||
@@ -1751,6 +1834,9 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
if ($status != NET_SFTP_STATUS_OK) {
|
||||
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED?
|
||||
@@ -1871,7 +1957,14 @@ class SFTP extends SSH2
|
||||
break;
|
||||
case is_resource($data):
|
||||
$mode = $mode & ~self::SOURCE_LOCAL_FILE;
|
||||
$fp = $data;
|
||||
$info = stream_get_meta_data($data);
|
||||
if ($info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') {
|
||||
$fp = fopen('php://memory', 'w+');
|
||||
stream_copy_to_stream($data, $fp);
|
||||
rewind($fp);
|
||||
} else {
|
||||
$fp = $data;
|
||||
}
|
||||
break;
|
||||
case $mode & self::SOURCE_LOCAL_FILE:
|
||||
if (!is_file($data)) {
|
||||
@@ -1886,7 +1979,7 @@ class SFTP extends SSH2
|
||||
|
||||
if (isset($fp)) {
|
||||
$stat = fstat($fp);
|
||||
$size = $stat['size'];
|
||||
$size = !empty($stat) ? $stat['size'] : 0;
|
||||
|
||||
if ($local_start >= 0) {
|
||||
fseek($fp, $local_start);
|
||||
@@ -1976,6 +2069,9 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
if ($status != NET_SFTP_STATUS_OK) {
|
||||
$this->_logError($response, $status);
|
||||
@@ -2007,6 +2103,9 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
if ($status != NET_SFTP_STATUS_OK) {
|
||||
$this->_logError($response, $status);
|
||||
@@ -2180,6 +2279,15 @@ class SFTP extends SSH2
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_object($path)) {
|
||||
// It's an object. Cast it as string before we check anything else.
|
||||
$path = (string) $path;
|
||||
}
|
||||
|
||||
if (!is_string($path) || $path == '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$path = $this->_realpath($path);
|
||||
if ($path === false) {
|
||||
return false;
|
||||
@@ -2197,6 +2305,9 @@ class SFTP extends SSH2
|
||||
}
|
||||
|
||||
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
if ($status != NET_SFTP_STATUS_OK) {
|
||||
$this->_logError($response, $status);
|
||||
@@ -2622,6 +2733,9 @@ class SFTP extends SSH2
|
||||
}
|
||||
|
||||
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||
if ($status != NET_SFTP_STATUS_OK) {
|
||||
$this->_logError($response, $status);
|
||||
@@ -2649,6 +2763,10 @@ class SFTP extends SSH2
|
||||
function _parseAttributes(&$response)
|
||||
{
|
||||
$attr = array();
|
||||
if (strlen($response) < 4) {
|
||||
user_error('Malformed file attributes');
|
||||
return array();
|
||||
}
|
||||
extract(unpack('Nflags', $this->_string_shift($response, 4)));
|
||||
// SFTPv4+ have a type field (a byte) that follows the above flag field
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
@@ -2663,9 +2781,17 @@ class SFTP extends SSH2
|
||||
$attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8)));
|
||||
break;
|
||||
case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)
|
||||
if (strlen($response) < 8) {
|
||||
user_error('Malformed file attributes');
|
||||
return $attr;
|
||||
}
|
||||
$attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8));
|
||||
break;
|
||||
case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004
|
||||
if (strlen($response) < 4) {
|
||||
user_error('Malformed file attributes');
|
||||
return $attr;
|
||||
}
|
||||
$attr+= unpack('Npermissions', $this->_string_shift($response, 4));
|
||||
// mode == permissions; permissions was the original array key and is retained for bc purposes.
|
||||
// mode was added because that's the more industry standard terminology
|
||||
@@ -2676,13 +2802,29 @@ class SFTP extends SSH2
|
||||
}
|
||||
break;
|
||||
case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008
|
||||
if (strlen($response) < 8) {
|
||||
user_error('Malformed file attributes');
|
||||
return $attr;
|
||||
}
|
||||
$attr+= unpack('Natime/Nmtime', $this->_string_shift($response, 8));
|
||||
break;
|
||||
case NET_SFTP_ATTR_EXTENDED: // 0x80000000
|
||||
if (strlen($response) < 4) {
|
||||
user_error('Malformed file attributes');
|
||||
return $attr;
|
||||
}
|
||||
extract(unpack('Ncount', $this->_string_shift($response, 4)));
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
if (strlen($response) < 4) {
|
||||
user_error('Malformed file attributes');
|
||||
return $attr;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$key = $this->_string_shift($response, $length);
|
||||
if (strlen($response) < 4) {
|
||||
user_error('Malformed file attributes');
|
||||
return $attr;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$attr[$key] = $this->_string_shift($response, $length);
|
||||
}
|
||||
@@ -2792,13 +2934,13 @@ class SFTP extends SSH2
|
||||
if (defined('NET_SFTP_LOGGING')) {
|
||||
$packet_type = '-> ' . $this->packet_types[$type] .
|
||||
' (' . round($stop - $start, 4) . 's)';
|
||||
if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
|
||||
if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
|
||||
echo "<pre>\r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n</pre>\r\n";
|
||||
flush();
|
||||
ob_flush();
|
||||
} else {
|
||||
$this->packet_type_log[] = $packet_type;
|
||||
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
|
||||
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
|
||||
$this->packet_log[] = $data;
|
||||
}
|
||||
}
|
||||
@@ -2828,7 +2970,7 @@ class SFTP extends SSH2
|
||||
|
||||
// SFTP packet length
|
||||
while (strlen($this->packet_buffer) < 4) {
|
||||
$temp = $this->_get_channel_packet(self::CHANNEL);
|
||||
$temp = $this->_get_channel_packet(self::CHANNEL, true);
|
||||
if (is_bool($temp)) {
|
||||
$this->packet_type = false;
|
||||
$this->packet_buffer = '';
|
||||
@@ -2836,13 +2978,16 @@ class SFTP extends SSH2
|
||||
}
|
||||
$this->packet_buffer.= $temp;
|
||||
}
|
||||
if (strlen($this->packet_buffer) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($this->packet_buffer, 4)));
|
||||
$tempLength = $length;
|
||||
$tempLength-= strlen($this->packet_buffer);
|
||||
|
||||
// SFTP packet type and data payload
|
||||
while ($tempLength > 0) {
|
||||
$temp = $this->_get_channel_packet(self::CHANNEL);
|
||||
$temp = $this->_get_channel_packet(self::CHANNEL, true);
|
||||
if (is_bool($temp)) {
|
||||
$this->packet_type = false;
|
||||
$this->packet_buffer = '';
|
||||
@@ -2868,13 +3013,13 @@ class SFTP extends SSH2
|
||||
if (defined('NET_SFTP_LOGGING')) {
|
||||
$packet_type = '<- ' . $this->packet_types[$this->packet_type] .
|
||||
' (' . round($stop - $start, 4) . 's)';
|
||||
if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
|
||||
if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
|
||||
echo "<pre>\r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n</pre>\r\n";
|
||||
flush();
|
||||
ob_flush();
|
||||
} else {
|
||||
$this->packet_type_log[] = $packet_type;
|
||||
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
|
||||
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
|
||||
$this->packet_log[] = $packet;
|
||||
}
|
||||
}
|
||||
@@ -2898,10 +3043,10 @@ class SFTP extends SSH2
|
||||
}
|
||||
|
||||
switch (NET_SFTP_LOGGING) {
|
||||
case NET_SFTP_LOG_COMPLEX:
|
||||
case self::LOG_COMPLEX:
|
||||
return $this->_format_log($this->packet_log, $this->packet_type_log);
|
||||
break;
|
||||
//case NET_SFTP_LOG_SIMPLE:
|
||||
//case self::LOG_SIMPLE:
|
||||
default:
|
||||
return $this->packet_type_log;
|
||||
}
|
||||
@@ -2910,7 +3055,7 @@ class SFTP extends SSH2
|
||||
/**
|
||||
* Returns all errors
|
||||
*
|
||||
* @return string
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function getSFTPErrors()
|
||||
|
||||
@@ -179,7 +179,7 @@ class Stream
|
||||
|
||||
if ($host[0] == '$') {
|
||||
$host = substr($host, 1);
|
||||
global $$host;
|
||||
global ${$host};
|
||||
if (($$host instanceof SFTP) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -575,28 +575,46 @@ class SSH1
|
||||
|
||||
$this->_string_shift($response[self::RESPONSE_DATA], 4);
|
||||
|
||||
if (strlen($response[self::RESPONSE_DATA]) < 2) {
|
||||
return false;
|
||||
}
|
||||
$temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
|
||||
$server_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
||||
$this->server_key_public_exponent = $server_key_public_exponent;
|
||||
|
||||
if (strlen($response[self::RESPONSE_DATA]) < 2) {
|
||||
return false;
|
||||
}
|
||||
$temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
|
||||
$server_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
||||
|
||||
$this->server_key_public_modulus = $server_key_public_modulus;
|
||||
|
||||
$this->_string_shift($response[self::RESPONSE_DATA], 4);
|
||||
|
||||
if (strlen($response[self::RESPONSE_DATA]) < 2) {
|
||||
return false;
|
||||
}
|
||||
$temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
|
||||
$host_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
||||
$this->host_key_public_exponent = $host_key_public_exponent;
|
||||
|
||||
if (strlen($response[self::RESPONSE_DATA]) < 2) {
|
||||
return false;
|
||||
}
|
||||
$temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
|
||||
$host_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
|
||||
|
||||
$this->host_key_public_modulus = $host_key_public_modulus;
|
||||
|
||||
$this->_string_shift($response[self::RESPONSE_DATA], 4);
|
||||
|
||||
// get a list of the supported ciphers
|
||||
if (strlen($response[self::RESPONSE_DATA]) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
|
||||
|
||||
foreach ($this->supported_ciphers as $mask => $name) {
|
||||
if (($supported_ciphers_mask & (1 << $mask)) == 0) {
|
||||
unset($this->supported_ciphers[$mask]);
|
||||
@@ -604,6 +622,9 @@ class SSH1
|
||||
}
|
||||
|
||||
// get a list of the supported authentications
|
||||
if (strlen($response[self::RESPONSE_DATA]) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
|
||||
foreach ($this->supported_authentications as $mask => $name) {
|
||||
if (($supported_authentications_mask & (1 << $mask)) == 0) {
|
||||
@@ -895,7 +916,7 @@ class SSH1
|
||||
/**
|
||||
* Returns the output of an interactive shell when there's a match for $expect
|
||||
*
|
||||
* $expect can take the form of a string literal or, if $mode == self::READ__REGEX,
|
||||
* $expect can take the form of a string literal or, if $mode == self::READ_REGEX,
|
||||
* a regular expression.
|
||||
*
|
||||
* @see self::write()
|
||||
@@ -904,7 +925,7 @@ class SSH1
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function read($expect, $mode = self::READ__SIMPLE)
|
||||
function read($expect, $mode = self::READ_SIMPLE)
|
||||
{
|
||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||
user_error('Operation disallowed prior to login()');
|
||||
@@ -918,7 +939,7 @@ class SSH1
|
||||
|
||||
$match = $expect;
|
||||
while (true) {
|
||||
if ($mode == self::READ__REGEX) {
|
||||
if ($mode == self::READ_REGEX) {
|
||||
preg_match($expect, $this->interactiveBuffer, $matches);
|
||||
$match = isset($matches[0]) ? $matches[0] : '';
|
||||
}
|
||||
@@ -1091,7 +1112,11 @@ class SSH1
|
||||
}
|
||||
|
||||
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
||||
$temp = unpack('Nlength', fread($this->fsock, 4));
|
||||
$data = fread($this->fsock, 4);
|
||||
if (strlen($data) < 4) {
|
||||
return false;
|
||||
}
|
||||
$temp = unpack('Nlength', $data);
|
||||
|
||||
$padding_length = 8 - ($temp['length'] & 7);
|
||||
$length = $temp['length'] + $padding_length;
|
||||
@@ -1112,6 +1137,9 @@ class SSH1
|
||||
$type = $raw[$padding_length];
|
||||
$data = substr($raw, $padding_length + 1, -4);
|
||||
|
||||
if (strlen($raw) < 4) {
|
||||
return false;
|
||||
}
|
||||
$temp = unpack('Ncrc', substr($raw, -4));
|
||||
|
||||
//if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) {
|
||||
|
||||
749
vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
vendored
749
vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user