updated composer dependencies
This commit is contained in:
parent
b2c9cd19ff
commit
43d3f077ff
|
@ -189,16 +189,16 @@
|
|||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.10",
|
||||
"version": "v2.0.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d"
|
||||
"reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d",
|
||||
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
|
||||
"reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -233,20 +233,20 @@
|
|||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2017-03-13T16:27:32+00:00"
|
||||
"time": "2018-04-04T21:24:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "2.0.6",
|
||||
"version": "2.0.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpseclib/phpseclib.git",
|
||||
"reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa"
|
||||
"reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34a7699e6f31b1ef4035ee36444407cecf9f56aa",
|
||||
"reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d305b780829ea4252ed9400b3f5937c2c99b51d4",
|
||||
"reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -254,7 +254,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"
|
||||
},
|
||||
|
@ -325,20 +325,20 @@
|
|||
"x.509",
|
||||
"x509"
|
||||
],
|
||||
"time": "2017-06-05T06:31:10+00:00"
|
||||
"time": "2018-02-19T04:29:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "simplepie/simplepie",
|
||||
"version": "1.5",
|
||||
"version": "1.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simplepie/simplepie.git",
|
||||
"reference": "5de5551953f95feef12cf355a7a26a70f94aa3ab"
|
||||
"reference": "db9fff27b6d49eed3d4047cd3211ec8dba2f5d6e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/simplepie/simplepie/zipball/5de5551953f95feef12cf355a7a26a70f94aa3ab",
|
||||
"reference": "5de5551953f95feef12cf355a7a26a70f94aa3ab",
|
||||
"url": "https://api.github.com/repos/simplepie/simplepie/zipball/db9fff27b6d49eed3d4047cd3211ec8dba2f5d6e",
|
||||
"reference": "db9fff27b6d49eed3d4047cd3211ec8dba2f5d6e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -385,7 +385,7 @@
|
|||
"feeds",
|
||||
"rss"
|
||||
],
|
||||
"time": "2017-04-17T07:29:31+00:00"
|
||||
"time": "2017-11-12T02:03:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "splitbrain/php-archive",
|
||||
|
@ -440,16 +440,16 @@
|
|||
},
|
||||
{
|
||||
"name": "splitbrain/php-cli",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/splitbrain/php-cli.git",
|
||||
"reference": "4795af10ff1c3b1ac614ef380d7d810af495e6f1"
|
||||
"reference": "1d6f0bf9eccbfd79d1f4d185ef27573601185c23"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/splitbrain/php-cli/zipball/4795af10ff1c3b1ac614ef380d7d810af495e6f1",
|
||||
"reference": "4795af10ff1c3b1ac614ef380d7d810af495e6f1",
|
||||
"url": "https://api.github.com/repos/splitbrain/php-cli/zipball/1d6f0bf9eccbfd79d1f4d185ef27573601185c23",
|
||||
"reference": "1d6f0bf9eccbfd79d1f4d185ef27573601185c23",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -487,7 +487,7 @@
|
|||
"optparse",
|
||||
"terminal"
|
||||
],
|
||||
"time": "2017-10-27T16:18:07+00:00"
|
||||
"time": "2018-02-02T08:46:12+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
|
|
@ -6,6 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
|
||||
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
||||
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
|
||||
);
|
||||
|
|
|
@ -7,8 +7,8 @@ namespace Composer\Autoload;
|
|||
class ComposerStaticInita19a915ee98347a0c787119619d2ff9b
|
||||
{
|
||||
public static $files = array (
|
||||
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
|
||||
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
||||
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
|
|
|
@ -1,54 +1,4 @@
|
|||
[
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.10",
|
||||
"version_normalized": "2.0.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d",
|
||||
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"time": "2017-03-13T16:27:32+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/random.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"pseudorandom",
|
||||
"random"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "geshi/geshi",
|
||||
"version": "v1.0.9.0",
|
||||
|
@ -293,17 +243,17 @@
|
|||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "2.0.6",
|
||||
"version_normalized": "2.0.6.0",
|
||||
"version": "2.0.10",
|
||||
"version_normalized": "2.0.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpseclib/phpseclib.git",
|
||||
"reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa"
|
||||
"reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34a7699e6f31b1ef4035ee36444407cecf9f56aa",
|
||||
"reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d305b780829ea4252ed9400b3f5937c2c99b51d4",
|
||||
"reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -311,7 +261,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"
|
||||
},
|
||||
|
@ -321,7 +271,7 @@
|
|||
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
|
||||
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
|
||||
},
|
||||
"time": "2017-06-05T06:31:10+00:00",
|
||||
"time": "2018-02-19T04:29:13+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
|
@ -386,18 +336,68 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "simplepie/simplepie",
|
||||
"version": "1.5",
|
||||
"version_normalized": "1.5.0.0",
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.12",
|
||||
"version_normalized": "2.0.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simplepie/simplepie.git",
|
||||
"reference": "5de5551953f95feef12cf355a7a26a70f94aa3ab"
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/simplepie/simplepie/zipball/5de5551953f95feef12cf355a7a26a70f94aa3ab",
|
||||
"reference": "5de5551953f95feef12cf355a7a26a70f94aa3ab",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
|
||||
"reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"time": "2018-04-04T21:24:14+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/random.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"pseudorandom",
|
||||
"random"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "simplepie/simplepie",
|
||||
"version": "1.5.1",
|
||||
"version_normalized": "1.5.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simplepie/simplepie.git",
|
||||
"reference": "db9fff27b6d49eed3d4047cd3211ec8dba2f5d6e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/simplepie/simplepie/zipball/db9fff27b6d49eed3d4047cd3211ec8dba2f5d6e",
|
||||
"reference": "db9fff27b6d49eed3d4047cd3211ec8dba2f5d6e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -409,7 +409,7 @@
|
|||
"suggest": {
|
||||
"mf2/mf2": "Microformat module that allows for parsing HTML for microformats"
|
||||
},
|
||||
"time": "2017-04-17T07:29:31+00:00",
|
||||
"time": "2017-11-12T02:03:34+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
|
@ -449,17 +449,17 @@
|
|||
},
|
||||
{
|
||||
"name": "splitbrain/php-cli",
|
||||
"version": "1.1.1",
|
||||
"version_normalized": "1.1.1.0",
|
||||
"version": "1.1.2",
|
||||
"version_normalized": "1.1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/splitbrain/php-cli.git",
|
||||
"reference": "4795af10ff1c3b1ac614ef380d7d810af495e6f1"
|
||||
"reference": "1d6f0bf9eccbfd79d1f4d185ef27573601185c23"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/splitbrain/php-cli/zipball/4795af10ff1c3b1ac614ef380d7d810af495e6f1",
|
||||
"reference": "4795af10ff1c3b1ac614ef380d7d810af495e6f1",
|
||||
"url": "https://api.github.com/repos/splitbrain/php-cli/zipball/1d6f0bf9eccbfd79d1f4d185ef27573601185c23",
|
||||
"reference": "1d6f0bf9eccbfd79d1f4d185ef27573601185c23",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -471,7 +471,7 @@
|
|||
"suggest": {
|
||||
"psr/log": "Allows you to make the CLI available as PSR-3 logger"
|
||||
},
|
||||
"time": "2017-10-27T16:18:07+00:00",
|
||||
"time": "2018-02-02T08:46:12+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
|
|
|
@ -38,9 +38,10 @@ if (!is_callable('RandomCompat_intval')) {
|
|||
* through.
|
||||
*
|
||||
* @param int|float $number The number we want to convert to an int
|
||||
* @param boolean $fail_open Set to true to not throw an exception
|
||||
* @param bool $fail_open Set to true to not throw an exception
|
||||
*
|
||||
* @return float|int
|
||||
* @psalm-suppress InvalidReturnType
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
|
|
|
@ -203,8 +203,9 @@ if (!is_callable('random_bytes')) {
|
|||
* and hope the developer won't let it fail silently.
|
||||
*
|
||||
* @param mixed $length
|
||||
* @return void
|
||||
* @psalm-suppress MissingReturnType
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
function random_bytes($length)
|
||||
{
|
||||
|
@ -212,6 +213,7 @@ if (!is_callable('random_bytes')) {
|
|||
throw new Exception(
|
||||
'There is no suitable CSPRNG installed on your system'
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,10 +70,10 @@ if (!is_callable('random_bytes')) {
|
|||
$n = ($bytes - $i) > 1073741824
|
||||
? 1073741824
|
||||
: $bytes - $i;
|
||||
$buf .= Sodium::randombytes_buf($n);
|
||||
$buf .= Sodium::randombytes_buf((int) $n);
|
||||
}
|
||||
} else {
|
||||
$buf .= Sodium::randombytes_buf($bytes);
|
||||
$buf .= Sodium::randombytes_buf((int) $bytes);
|
||||
}
|
||||
|
||||
if (is_string($buf)) {
|
||||
|
|
|
@ -78,7 +78,7 @@ if (!is_callable('random_int')) {
|
|||
}
|
||||
|
||||
if ($max === $min) {
|
||||
return $min;
|
||||
return (int) $min;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,6 +185,6 @@ if (!is_callable('random_int')) {
|
|||
*/
|
||||
} while (!is_int($val) || $val > $max || $val < $min);
|
||||
|
||||
return (int)$val;
|
||||
return (int) $val;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
<directory name="lib" />
|
||||
</projectFiles>
|
||||
<issueHandlers>
|
||||
<RedundantConditionGivenDocblockType errorLevel="info" />
|
||||
<UnresolvableInclude errorLevel="info" />
|
||||
<DuplicateClass errorLevel="info" />
|
||||
<InvalidOperand errorLevel="info" />
|
||||
<UndefinedConstant errorLevel="info" />
|
||||
<MissingReturnType errorLevel="info" />
|
||||
|
|
|
@ -36,7 +36,7 @@ AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
|
|||
* 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.7 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.7.zip/download)
|
||||
* [Download 1.0.10 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.10.zip/download)
|
||||
|
||||
## Support
|
||||
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -492,8 +492,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');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2492,6 +2492,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 +2555,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 {
|
||||
|
@ -408,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]);
|
||||
}
|
||||
|
@ -443,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]);
|
||||
}
|
||||
|
@ -478,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:
|
||||
|
@ -513,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.= '
|
||||
|
@ -542,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
|
||||
|
|
|
@ -2423,7 +2423,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);
|
||||
|
|
|
@ -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
|
||||
|
@ -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((int)$hour, (int)$minute, (int)$second, (int)$month, (int)$day, (int)$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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
@ -2030,30 +2032,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;
|
||||
|
@ -2082,7 +2086,7 @@ class X509
|
|||
}
|
||||
|
||||
if (!isset($date)) {
|
||||
$date = time();
|
||||
$date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
|
||||
}
|
||||
|
||||
$notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
|
||||
|
@ -2092,8 +2096,8 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -2137,7 +2141,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
|
||||
}
|
||||
}
|
||||
|
@ -2154,7 +2159,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;
|
||||
}
|
||||
|
@ -2200,7 +2209,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;
|
||||
}
|
||||
|
@ -2472,6 +2485,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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2715,7 +2732,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;
|
||||
|
@ -3338,7 +3357,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 {
|
||||
|
@ -3403,8 +3426,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
|
||||
|
@ -3672,7 +3699,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;
|
||||
|
@ -3823,7 +3852,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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3847,7 +3880,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');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4057,6 +4094,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;
|
||||
}
|
||||
|
||||
|
@ -4577,8 +4618,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -360,8 +360,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!)
|
||||
|
@ -548,9 +552,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 +2868,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 +2884,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 +2908,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 +3443,7 @@ class BigInteger
|
|||
break;
|
||||
}
|
||||
}
|
||||
$s = 26 * $i + $j - 1;
|
||||
$s = 26 * $i + $j;
|
||||
$r->_rshift($s);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -575,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
|
||||
*
|
||||
|
@ -633,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))) {
|
||||
|
@ -1106,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;
|
||||
}
|
||||
|
@ -1294,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
|
||||
|
@ -1455,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:
|
||||
|
@ -1938,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);
|
||||
|
@ -2929,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 = '';
|
||||
|
@ -2946,7 +2987,7 @@ class SFTP extends SSH2
|
|||
|
||||
// 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 = '';
|
||||
|
@ -3014,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;
|
||||
}
|
||||
|
|
|
@ -916,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()
|
||||
|
@ -925,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()');
|
||||
|
@ -939,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] : '';
|
||||
}
|
||||
|
|
|
@ -100,10 +100,10 @@ class SSH2
|
|||
* @see \phpseclib\Net\SSH2::_get_channel_packet()
|
||||
* @access private
|
||||
*/
|
||||
const CHANNEL_EXEC = 0; // PuTTy uses 0x100
|
||||
const CHANNEL_SHELL = 1;
|
||||
const CHANNEL_SUBSYSTEM = 2;
|
||||
const CHANNEL_AGENT_FORWARD = 3;
|
||||
const CHANNEL_EXEC = 1; // PuTTy uses 0x100
|
||||
const CHANNEL_SHELL = 2;
|
||||
const CHANNEL_SUBSYSTEM = 3;
|
||||
const CHANNEL_AGENT_FORWARD = 4;
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
|
@ -126,6 +126,10 @@ class SSH2
|
|||
* Dumps the content real-time to a file
|
||||
*/
|
||||
const LOG_REALTIME_FILE = 4;
|
||||
/**
|
||||
* Make sure that the log never gets larger than this
|
||||
*/
|
||||
const LOG_MAX_SIZE = 1048576; // 1024 * 1024
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
|
@ -141,9 +145,9 @@ class SSH2
|
|||
*/
|
||||
const READ_REGEX = 2;
|
||||
/**
|
||||
* Make sure that the log never gets larger than this
|
||||
* Returns when a string matching the regular expression $expect is found
|
||||
*/
|
||||
const LOG_MAX_SIZE = 1048576; // 1024 * 1024
|
||||
const READ_NEXT = 3;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
|
@ -866,6 +870,54 @@ class SSH2
|
|||
*/
|
||||
var $agent;
|
||||
|
||||
/**
|
||||
* Send the identification string first?
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $send_id_string_first = true;
|
||||
|
||||
/**
|
||||
* Send the key exchange initiation packet first?
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $send_kex_first = true;
|
||||
|
||||
/**
|
||||
* Some versions of OpenSSH incorrectly calculate the key size
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $bad_key_size_fix = false;
|
||||
|
||||
/**
|
||||
* The selected decryption algorithm
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $decrypt_algorithm = '';
|
||||
|
||||
/**
|
||||
* Should we try to re-connect to re-establish keys?
|
||||
*
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $retry_connect = false;
|
||||
|
||||
/**
|
||||
* Binary Packet Buffer
|
||||
*
|
||||
* @var string|false
|
||||
* @access private
|
||||
*/
|
||||
var $binary_packet_buffer = false;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
|
@ -978,13 +1030,69 @@ class SSH2
|
|||
* CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT
|
||||
*
|
||||
* @param int $engine
|
||||
* @access private
|
||||
* @access public
|
||||
*/
|
||||
function setCryptoEngine($engine)
|
||||
{
|
||||
$this->crypto_engine = $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Identification String First
|
||||
*
|
||||
* https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
|
||||
* both sides MUST send an identification string". It does not say which side sends it first. In
|
||||
* theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function sendIdentificationStringFirst()
|
||||
{
|
||||
$this->send_id_string_first = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Identification String Last
|
||||
*
|
||||
* https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
|
||||
* both sides MUST send an identification string". It does not say which side sends it first. In
|
||||
* theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function sendIdentificationStringLast()
|
||||
{
|
||||
$this->send_id_string_first = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send SSH_MSG_KEXINIT First
|
||||
*
|
||||
* https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
|
||||
* sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
|
||||
* it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function sendKEXINITFirst()
|
||||
{
|
||||
$this->send_kex_first = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send SSH_MSG_KEXINIT Last
|
||||
*
|
||||
* https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
|
||||
* sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
|
||||
* it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function sendKEXINITLast()
|
||||
{
|
||||
$this->send_kex_first = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to an SSHv2 server
|
||||
*
|
||||
|
@ -1026,7 +1134,9 @@ class SSH2
|
|||
|
||||
$this->identifier = $this->_generate_identifier();
|
||||
|
||||
fputs($this->fsock, $this->identifier . "\r\n");
|
||||
if ($this->send_id_string_first) {
|
||||
fputs($this->fsock, $this->identifier . "\r\n");
|
||||
}
|
||||
|
||||
/* According to the SSH2 specs,
|
||||
|
||||
|
@ -1099,23 +1209,33 @@ class SSH2
|
|||
$this->errors[] = utf8_decode($data);
|
||||
}
|
||||
|
||||
if ($matches[3] != '1.99' && $matches[3] != '2.0') {
|
||||
if (version_compare($matches[3], '1.99', '<')) {
|
||||
user_error("Cannot connect to SSH $matches[3] servers");
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
if (!$this->send_id_string_first) {
|
||||
fputs($this->fsock, $this->identifier . "\r\n");
|
||||
}
|
||||
|
||||
if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
||||
user_error('Expected SSH_MSG_KEXINIT');
|
||||
return false;
|
||||
if (!$this->send_kex_first) {
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
||||
user_error('Expected SSH_MSG_KEXINIT');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->_key_exchange($response)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->_key_exchange($response)) {
|
||||
if ($this->send_kex_first && !$this->_key_exchange()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1137,7 +1257,7 @@ class SSH2
|
|||
$identifier = 'SSH-2.0-phpseclib_2.0';
|
||||
|
||||
$ext = array();
|
||||
if (extension_loaded('libsodium')) {
|
||||
if (function_exists('\\Sodium\\library_version_major')) {
|
||||
$ext[] = 'libsodium';
|
||||
}
|
||||
|
||||
|
@ -1163,10 +1283,10 @@ class SSH2
|
|||
/**
|
||||
* Key Exchange
|
||||
*
|
||||
* @param string $kexinit_payload_server
|
||||
* @param string $kexinit_payload_server optional
|
||||
* @access private
|
||||
*/
|
||||
function _key_exchange($kexinit_payload_server)
|
||||
function _key_exchange($kexinit_payload_server = false)
|
||||
{
|
||||
$kex_algorithms = array(
|
||||
// Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using
|
||||
|
@ -1287,8 +1407,9 @@ class SSH2
|
|||
);
|
||||
|
||||
// some SSH servers have buggy implementations of some of the above algorithms
|
||||
switch ($this->server_identifier) {
|
||||
case 'SSH-2.0-SSHD':
|
||||
switch (true) {
|
||||
case $this->server_identifier == 'SSH-2.0-SSHD':
|
||||
case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK':
|
||||
$mac_algorithms = array_values(array_diff(
|
||||
$mac_algorithms,
|
||||
array('hmac-sha1-96', 'hmac-md5-96')
|
||||
|
@ -1303,6 +1424,51 @@ class SSH2
|
|||
|
||||
$client_cookie = Random::string(16);
|
||||
|
||||
$kexinit_payload_client = pack(
|
||||
'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
|
||||
NET_SSH2_MSG_KEXINIT,
|
||||
$client_cookie,
|
||||
strlen($str_kex_algorithms),
|
||||
$str_kex_algorithms,
|
||||
strlen($str_server_host_key_algorithms),
|
||||
$str_server_host_key_algorithms,
|
||||
strlen($encryption_algorithms_client_to_server),
|
||||
$encryption_algorithms_client_to_server,
|
||||
strlen($encryption_algorithms_server_to_client),
|
||||
$encryption_algorithms_server_to_client,
|
||||
strlen($mac_algorithms_client_to_server),
|
||||
$mac_algorithms_client_to_server,
|
||||
strlen($mac_algorithms_server_to_client),
|
||||
$mac_algorithms_server_to_client,
|
||||
strlen($compression_algorithms_client_to_server),
|
||||
$compression_algorithms_client_to_server,
|
||||
strlen($compression_algorithms_server_to_client),
|
||||
$compression_algorithms_server_to_client,
|
||||
0,
|
||||
'',
|
||||
0,
|
||||
'',
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
if ($this->send_kex_first) {
|
||||
if (!$this->_send_binary_packet($kexinit_payload_client)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$kexinit_payload_server = $this->_get_binary_packet();
|
||||
if ($kexinit_payload_server === false) {
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) {
|
||||
user_error('Expected SSH_MSG_KEXINIT');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$response = $kexinit_payload_server;
|
||||
$this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)
|
||||
$server_cookie = $this->_string_shift($response, 16);
|
||||
|
@ -1373,39 +1539,9 @@ class SSH2
|
|||
extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
|
||||
$first_kex_packet_follows = $first_kex_packet_follows != 0;
|
||||
|
||||
// the sending of SSH2_MSG_KEXINIT could go in one of two places. this is the second place.
|
||||
$kexinit_payload_client = pack(
|
||||
'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
|
||||
NET_SSH2_MSG_KEXINIT,
|
||||
$client_cookie,
|
||||
strlen($str_kex_algorithms),
|
||||
$str_kex_algorithms,
|
||||
strlen($str_server_host_key_algorithms),
|
||||
$str_server_host_key_algorithms,
|
||||
strlen($encryption_algorithms_client_to_server),
|
||||
$encryption_algorithms_client_to_server,
|
||||
strlen($encryption_algorithms_server_to_client),
|
||||
$encryption_algorithms_server_to_client,
|
||||
strlen($mac_algorithms_client_to_server),
|
||||
$mac_algorithms_client_to_server,
|
||||
strlen($mac_algorithms_server_to_client),
|
||||
$mac_algorithms_server_to_client,
|
||||
strlen($compression_algorithms_client_to_server),
|
||||
$compression_algorithms_client_to_server,
|
||||
strlen($compression_algorithms_server_to_client),
|
||||
$compression_algorithms_server_to_client,
|
||||
0,
|
||||
'',
|
||||
0,
|
||||
'',
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
if (!$this->_send_binary_packet($kexinit_payload_client)) {
|
||||
if (!$this->send_kex_first && !$this->_send_binary_packet($kexinit_payload_client)) {
|
||||
return false;
|
||||
}
|
||||
// here ends the second place.
|
||||
|
||||
// we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
|
||||
// we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
|
||||
|
@ -1677,6 +1813,8 @@ class SSH2
|
|||
return false;
|
||||
}
|
||||
|
||||
$this->decrypt_algorithm = $decrypt;
|
||||
|
||||
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
|
||||
|
||||
$this->encrypt = $this->_encryption_algorithm_to_crypt_instance($encrypt);
|
||||
|
@ -1843,6 +1981,10 @@ class SSH2
|
|||
*/
|
||||
function _encryption_algorithm_to_key_size($algorithm)
|
||||
{
|
||||
if ($this->bad_key_size_fix && $this->_bad_algorithm_candidate($algorithm)) {
|
||||
return 16;
|
||||
}
|
||||
|
||||
switch ($algorithm) {
|
||||
case 'none':
|
||||
return 0;
|
||||
|
@ -1917,6 +2059,27 @@ class SSH2
|
|||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests whether or not proposed algorithm has a potential for issues
|
||||
*
|
||||
* @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html
|
||||
* @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291
|
||||
* @param string $algorithm Name of the encryption algorithm
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
function _bad_algorithm_candidate($algorithm)
|
||||
{
|
||||
switch ($algorithm) {
|
||||
case 'arcfour256':
|
||||
case 'aes192-ctr':
|
||||
case 'aes256-ctr':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login
|
||||
*
|
||||
|
@ -1996,6 +2159,13 @@ class SSH2
|
|||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
if ($this->retry_connect) {
|
||||
$this->retry_connect = false;
|
||||
if (!$this->_connect()) {
|
||||
return false;
|
||||
}
|
||||
return $this->_login_helper($username, $password);
|
||||
}
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
@ -2812,6 +2982,10 @@ class SSH2
|
|||
|
||||
$channel = $this->_get_interactive_channel();
|
||||
|
||||
if ($mode == self::READ_NEXT) {
|
||||
return $this->_get_channel_packet($channel);
|
||||
}
|
||||
|
||||
$match = $expect;
|
||||
while (true) {
|
||||
if ($mode == self::READ_REGEX) {
|
||||
|
@ -3010,6 +3184,24 @@ class SSH2
|
|||
return (bool) ($this->bitmap & self::MASK_LOGIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets a connection for re-use
|
||||
*
|
||||
* @param int $reason
|
||||
* @access private
|
||||
*/
|
||||
function _reset_connection($reason)
|
||||
{
|
||||
$this->_disconnect($reason);
|
||||
$this->decrypt = $this->encrypt = false;
|
||||
$this->decrypt_block_size = $this->encrypt_block_size = 8;
|
||||
$this->hmac_check = $this->hmac_create = false;
|
||||
$this->hmac_size = false;
|
||||
$this->session_id = false;
|
||||
$this->retry_connect = true;
|
||||
$this->get_seq_no = $this->send_seq_no = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Binary Packets
|
||||
*
|
||||
|
@ -3019,7 +3211,7 @@ class SSH2
|
|||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _get_binary_packet()
|
||||
function _get_binary_packet($skip_channel_filter = false)
|
||||
{
|
||||
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
||||
user_error('Connection closed prematurely');
|
||||
|
@ -3053,6 +3245,11 @@ class SSH2
|
|||
// "implementations SHOULD check that the packet length is reasonable"
|
||||
// PuTTY uses 0x9000 as the actual max packet size and so to shall we
|
||||
if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
|
||||
if (!$this->bad_key_size_fix && $this->_bad_algorithm_candidate($this->decrypt_algorithm) && !($this->bitmap & SSH2::MASK_LOGIN)) {
|
||||
$this->bad_key_size_fix = true;
|
||||
$this->_reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
return false;
|
||||
}
|
||||
user_error('Invalid size');
|
||||
return false;
|
||||
}
|
||||
|
@ -3068,6 +3265,7 @@ class SSH2
|
|||
$buffer.= $temp;
|
||||
$remaining_length-= strlen($temp);
|
||||
}
|
||||
|
||||
$stop = microtime(true);
|
||||
if (strlen($buffer)) {
|
||||
$raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;
|
||||
|
@ -3103,7 +3301,7 @@ class SSH2
|
|||
$this->last_packet = $current;
|
||||
}
|
||||
|
||||
return $this->_filter($payload);
|
||||
return $this->_filter($payload, $skip_channel_filter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3115,7 +3313,7 @@ class SSH2
|
|||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _filter($payload)
|
||||
function _filter($payload, $skip_channel_filter)
|
||||
{
|
||||
switch (ord($payload[0])) {
|
||||
case NET_SSH2_MSG_DISCONNECT:
|
||||
|
@ -3128,7 +3326,7 @@ class SSH2
|
|||
$this->bitmap = 0;
|
||||
return false;
|
||||
case NET_SSH2_MSG_IGNORE:
|
||||
$payload = $this->_get_binary_packet();
|
||||
$payload = $this->_get_binary_packet($skip_channel_filter);
|
||||
break;
|
||||
case NET_SSH2_MSG_DEBUG:
|
||||
$this->_string_shift($payload, 2);
|
||||
|
@ -3137,17 +3335,18 @@ class SSH2
|
|||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
|
||||
$this->errors[] = 'SSH_MSG_DEBUG: ' . utf8_decode($this->_string_shift($payload, $length));
|
||||
$payload = $this->_get_binary_packet();
|
||||
$payload = $this->_get_binary_packet($skip_channel_filter);
|
||||
break;
|
||||
case NET_SSH2_MSG_UNIMPLEMENTED:
|
||||
return false;
|
||||
case NET_SSH2_MSG_KEXINIT:
|
||||
if ($this->session_id !== false) {
|
||||
$this->send_kex_first = false;
|
||||
if (!$this->_key_exchange($payload)) {
|
||||
$this->bitmap = 0;
|
||||
return false;
|
||||
}
|
||||
$payload = $this->_get_binary_packet();
|
||||
$payload = $this->_get_binary_packet($skip_channel_filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3165,6 +3364,17 @@ class SSH2
|
|||
// only called when we've already logged in
|
||||
if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
|
||||
switch (ord($payload[0])) {
|
||||
case NET_SSH2_MSG_CHANNEL_DATA:
|
||||
case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
|
||||
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
||||
case NET_SSH2_MSG_CHANNEL_CLOSE:
|
||||
case NET_SSH2_MSG_CHANNEL_EOF:
|
||||
if (!$skip_channel_filter && !empty($this->server_channels)) {
|
||||
$this->binary_packet_buffer = $payload;
|
||||
$this->_get_channel_packet(true);
|
||||
$payload = $this->_get_binary_packet();
|
||||
}
|
||||
break;
|
||||
case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
|
||||
if (strlen($payload) < 4) {
|
||||
return false;
|
||||
|
@ -3176,7 +3386,7 @@ class SSH2
|
|||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
|
||||
$payload = $this->_get_binary_packet();
|
||||
$payload = $this->_get_binary_packet($skip_channel_filter);
|
||||
break;
|
||||
case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
|
||||
$this->_string_shift($payload, 1);
|
||||
|
@ -3239,7 +3449,7 @@ class SSH2
|
|||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
}
|
||||
$payload = $this->_get_binary_packet();
|
||||
$payload = $this->_get_binary_packet($skip_channel_filter);
|
||||
break;
|
||||
case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
||||
$this->_string_shift($payload, 1);
|
||||
|
@ -3250,7 +3460,7 @@ class SSH2
|
|||
extract(unpack('Nwindow_size', $this->_string_shift($payload, 4)));
|
||||
$this->window_size_client_to_server[$channel]+= $window_size;
|
||||
|
||||
$payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet();
|
||||
$payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet($skip_channel_filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3347,32 +3557,38 @@ class SSH2
|
|||
}
|
||||
|
||||
while (true) {
|
||||
if ($this->curTimeout) {
|
||||
if ($this->curTimeout < 0) {
|
||||
$this->is_timeout = true;
|
||||
return true;
|
||||
if ($this->binary_packet_buffer !== false) {
|
||||
$response = $this->binary_packet_buffer;
|
||||
$this->binary_packet_buffer = false;
|
||||
} else {
|
||||
if ($this->curTimeout) {
|
||||
if ($this->curTimeout < 0) {
|
||||
$this->is_timeout = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
$read = array($this->fsock);
|
||||
$write = $except = null;
|
||||
|
||||
$start = microtime(true);
|
||||
$sec = floor($this->curTimeout);
|
||||
$usec = 1000000 * ($this->curTimeout - $sec);
|
||||
// on windows this returns a "Warning: Invalid CRT parameters detected" error
|
||||
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
|
||||
$this->is_timeout = true;
|
||||
return true;
|
||||
}
|
||||
$elapsed = microtime(true) - $start;
|
||||
$this->curTimeout-= $elapsed;
|
||||
}
|
||||
|
||||
$read = array($this->fsock);
|
||||
$write = $except = null;
|
||||
|
||||
$start = microtime(true);
|
||||
$sec = floor($this->curTimeout);
|
||||
$usec = 1000000 * ($this->curTimeout - $sec);
|
||||
// on windows this returns a "Warning: Invalid CRT parameters detected" error
|
||||
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
|
||||
$this->is_timeout = true;
|
||||
return true;
|
||||
$response = $this->_get_binary_packet(true);
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
$elapsed = microtime(true) - $start;
|
||||
$this->curTimeout-= $elapsed;
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
if ($client_channel == -1 && $response === true) {
|
||||
return true;
|
||||
}
|
||||
|
@ -3407,6 +3623,82 @@ class SSH2
|
|||
$this->window_size_server_to_client[$channel]+= $this->window_size;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
|
||||
/*
|
||||
if ($client_channel == NET_SSH2_CHANNEL_EXEC) {
|
||||
$this->_send_channel_packet($client_channel, chr(0));
|
||||
}
|
||||
*/
|
||||
// currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR
|
||||
if (strlen($response) < 8) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8)));
|
||||
$data = $this->_string_shift($response, $length);
|
||||
$this->stdErrorLog.= $data;
|
||||
if ($skip_extended || $this->quiet_mode) {
|
||||
continue 2;
|
||||
}
|
||||
if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) {
|
||||
return $data;
|
||||
}
|
||||
if (!isset($this->channel_buffers[$channel])) {
|
||||
$this->channel_buffers[$channel] = array();
|
||||
}
|
||||
$this->channel_buffers[$channel][] = $data;
|
||||
|
||||
continue 2;
|
||||
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
||||
if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) {
|
||||
continue 2;
|
||||
}
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$value = $this->_string_shift($response, $length);
|
||||
switch ($value) {
|
||||
case 'exit-signal':
|
||||
$this->_string_shift($response, 1);
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length);
|
||||
$this->_string_shift($response, 1);
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
if ($length) {
|
||||
$this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length);
|
||||
}
|
||||
|
||||
$this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel]));
|
||||
$this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
|
||||
|
||||
$this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF;
|
||||
|
||||
continue 3;
|
||||
case 'exit-status':
|
||||
if (strlen($response) < 5) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Cfalse/Nexit_status', $this->_string_shift($response, 5)));
|
||||
$this->exit_status = $exit_status;
|
||||
|
||||
// "The client MAY ignore these messages."
|
||||
// -- http://tools.ietf.org/html/rfc4254#section-6.10
|
||||
|
||||
continue 3;
|
||||
default:
|
||||
// "Some systems may not implement signals, in which case they SHOULD ignore this message."
|
||||
// -- http://tools.ietf.org/html/rfc4254#section-6.9
|
||||
continue 3;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($this->channel_status[$channel]) {
|
||||
case NET_SSH2_MSG_CHANNEL_OPEN:
|
||||
switch ($type) {
|
||||
|
@ -3489,76 +3781,6 @@ class SSH2
|
|||
}
|
||||
$this->channel_buffers[$channel][] = $data;
|
||||
break;
|
||||
case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
|
||||
/*
|
||||
if ($client_channel == self::CHANNEL_EXEC) {
|
||||
$this->_send_channel_packet($client_channel, chr(0));
|
||||
}
|
||||
*/
|
||||
// currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR
|
||||
if (strlen($response) < 8) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8)));
|
||||
$data = $this->_string_shift($response, $length);
|
||||
$this->stdErrorLog.= $data;
|
||||
if ($skip_extended || $this->quiet_mode) {
|
||||
break;
|
||||
}
|
||||
if ($client_channel == $channel) {
|
||||
return $data;
|
||||
}
|
||||
if (!isset($this->channel_buffers[$channel])) {
|
||||
$this->channel_buffers[$channel] = array();
|
||||
}
|
||||
$this->channel_buffers[$channel][] = $data;
|
||||
break;
|
||||
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$value = $this->_string_shift($response, $length);
|
||||
switch ($value) {
|
||||
case 'exit-signal':
|
||||
$this->_string_shift($response, 1);
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
$this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length);
|
||||
$this->_string_shift($response, 1);
|
||||
if (strlen($response) < 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', $this->_string_shift($response, 4)));
|
||||
if ($length) {
|
||||
$this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length);
|
||||
}
|
||||
|
||||
$this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel]));
|
||||
$this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
|
||||
|
||||
$this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF;
|
||||
|
||||
break;
|
||||
case 'exit-status':
|
||||
if (strlen($response) < 5) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Cfalse/Nexit_status', $this->_string_shift($response, 5)));
|
||||
$this->exit_status = $exit_status;
|
||||
|
||||
// "The client MAY ignore these messages."
|
||||
// -- http://tools.ietf.org/html/rfc4254#section-6.10
|
||||
|
||||
break;
|
||||
default:
|
||||
// "Some systems may not implement signals, in which case they SHOULD ignore this message."
|
||||
// -- http://tools.ietf.org/html/rfc4254#section-6.9
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NET_SSH2_MSG_CHANNEL_CLOSE:
|
||||
$this->curTimeout = 0;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.5
|
||||
* @version 1.5.1
|
||||
* @copyright 2004-2017 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
|
@ -50,7 +50,7 @@ define('SIMPLEPIE_NAME', 'SimplePie');
|
|||
/**
|
||||
* SimplePie Version
|
||||
*/
|
||||
define('SIMPLEPIE_VERSION', '1.5');
|
||||
define('SIMPLEPIE_VERSION', '1.5.1');
|
||||
|
||||
/**
|
||||
* SimplePie Build
|
||||
|
@ -810,7 +810,7 @@ class SimplePie
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the the default timeout for fetching remote feeds
|
||||
* Set the default timeout for fetching remote feeds
|
||||
*
|
||||
* This allows you to change the maximum time the feed's server to respond
|
||||
* and send the feed back.
|
||||
|
@ -1320,6 +1320,11 @@ class SimplePie
|
|||
}
|
||||
}
|
||||
|
||||
// The default sanitize class gets set in the constructor, check if it has
|
||||
// changed.
|
||||
if ($this->registry->get_class('Sanitize') !== 'SimplePie_Sanitize') {
|
||||
$this->sanitize = $this->registry->create('Sanitize');
|
||||
}
|
||||
if (method_exists($this->sanitize, 'set_registry'))
|
||||
{
|
||||
$this->sanitize->set_registry($this->registry);
|
||||
|
@ -1644,33 +1649,18 @@ class SimplePie
|
|||
try
|
||||
{
|
||||
$microformats = false;
|
||||
if (function_exists('Mf2\parse')) {
|
||||
if (class_exists('DOMXpath') && function_exists('Mf2\parse')) {
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadHTML($file->body);
|
||||
$xpath = new DOMXpath($doc);
|
||||
// Check for both h-feed and h-entry, as both a feed with no entries
|
||||
// and a list of entries without an h-feed wrapper are both valid.
|
||||
$position = 0;
|
||||
while ($position = strpos($file->body, 'h-feed', $position))
|
||||
{
|
||||
$start = $position < 200 ? 0 : $position - 200;
|
||||
$check = substr($file->body, $start, 400);
|
||||
if ($microformats = preg_match('/class="[^"]*h-feed/', $check))
|
||||
{
|
||||
break;
|
||||
}
|
||||
$position += 7;
|
||||
}
|
||||
$position = 0;
|
||||
while ($position = strpos($file->body, 'h-entry', $position))
|
||||
{
|
||||
$start = $position < 200 ? 0 : $position - 200;
|
||||
$check = substr($file->body, $start, 400);
|
||||
if ($microformats = preg_match('/class="[^"]*h-entry/', $check))
|
||||
{
|
||||
break;
|
||||
}
|
||||
$position += 7;
|
||||
}
|
||||
$query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '.
|
||||
'contains(concat(" ", @class, " "), " h-entry ")]';
|
||||
$result = $xpath->query($query);
|
||||
$microformats = $result->length !== 0;
|
||||
}
|
||||
// Now also do feed discovery, but if an h-entry was found don't
|
||||
// Now also do feed discovery, but if microformats were found don't
|
||||
// overwrite the current value of file.
|
||||
$discovered = $locate->find($this->autodiscovery,
|
||||
$this->all_discovered_feeds);
|
||||
|
@ -2606,16 +2596,16 @@ class SimplePie
|
|||
}
|
||||
}
|
||||
|
||||
if (isset($this->data['links'][$rel]))
|
||||
{
|
||||
return $this->data['links'][$rel];
|
||||
}
|
||||
else if (isset($this->data['headers']['link']) &&
|
||||
preg_match('/<([^>]+)>; rel='.preg_quote($rel).'/',
|
||||
$this->data['headers']['link'], $match))
|
||||
if (isset($this->data['headers']['link']) &&
|
||||
preg_match('/<([^>]+)>; rel='.preg_quote($rel).'/',
|
||||
$this->data['headers']['link'], $match))
|
||||
{
|
||||
return array($match[1]);
|
||||
}
|
||||
else if (isset($this->data['links'][$rel]))
|
||||
{
|
||||
return $this->data['links'][$rel];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
|
@ -3155,7 +3145,7 @@ class SimplePie
|
|||
|
||||
if (($url = $this->get_link()) !== null)
|
||||
{
|
||||
return 'http://g.etfv.co/' . urlencode($url);
|
||||
return 'https://www.google.com/s2/favicons?domain=' . urlencode($url);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -136,8 +136,7 @@ class SimplePie_File
|
|||
$this->url = $info['url'];
|
||||
}
|
||||
curl_close($fp);
|
||||
$this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
|
||||
$this->headers = array_pop($this->headers);
|
||||
$this->headers = SimplePie_HTTP_Parser::prepareHeaders($this->headers, $info['redirect_count'] + 1);
|
||||
$parser = new SimplePie_HTTP_Parser($this->headers);
|
||||
if ($parser->parse())
|
||||
{
|
||||
|
|
|
@ -496,4 +496,25 @@ class SimplePie_HTTP_Parser
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare headers (take care of proxies headers)
|
||||
*
|
||||
* @param string $headers Raw headers
|
||||
* @param integer $count Redirection count. Default to 1.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function prepareHeaders($headers, $count = 1)
|
||||
{
|
||||
$data = explode("\r\n\r\n", $headers, $count);
|
||||
$data = array_pop($data);
|
||||
if (false !== stripos($data, "HTTP/1.0 200 Connection established\r\n\r\n")) {
|
||||
$data = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $data);
|
||||
}
|
||||
if (false !== stripos($data, "HTTP/1.1 200 Connection established\r\n\r\n")) {
|
||||
$data = str_ireplace("HTTP/1.1 200 Connection established\r\n\r\n", '', $data);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -477,15 +477,15 @@ class SimplePie_Item
|
|||
$label = null;
|
||||
if (isset($category['attribs']['']['term']))
|
||||
{
|
||||
$term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_HTML);
|
||||
$term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($category['attribs']['']['scheme']))
|
||||
{
|
||||
$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_HTML);
|
||||
$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($category['attribs']['']['label']))
|
||||
{
|
||||
$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_HTML);
|
||||
$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
$categories[] = $this->registry->create('Category', array($term, $scheme, $label, $type));
|
||||
}
|
||||
|
@ -493,10 +493,10 @@ class SimplePie_Item
|
|||
{
|
||||
// This is really the label, but keep this as the term also for BC.
|
||||
// Label will also work on retrieving because that falls back to term.
|
||||
$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_HTML);
|
||||
$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
if (isset($category['attribs']['']['domain']))
|
||||
{
|
||||
$scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_HTML);
|
||||
$scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -508,11 +508,11 @@ class SimplePie_Item
|
|||
$type = 'subject';
|
||||
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, $type) as $category)
|
||||
{
|
||||
$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null, $type));
|
||||
$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null, $type));
|
||||
}
|
||||
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, $type) as $category)
|
||||
{
|
||||
$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null, $type));
|
||||
$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null, $type));
|
||||
}
|
||||
|
||||
if (!empty($categories))
|
||||
|
@ -649,7 +649,7 @@ class SimplePie_Item
|
|||
$email = null;
|
||||
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
|
||||
$name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
|
||||
{
|
||||
|
@ -657,7 +657,7 @@ class SimplePie_Item
|
|||
}
|
||||
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
|
||||
$email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $uri !== null)
|
||||
{
|
||||
|
@ -671,7 +671,7 @@ class SimplePie_Item
|
|||
$email = null;
|
||||
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
|
||||
$name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
|
||||
{
|
||||
|
@ -679,7 +679,7 @@ class SimplePie_Item
|
|||
}
|
||||
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
|
||||
$email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $url !== null)
|
||||
{
|
||||
|
@ -688,19 +688,19 @@ class SimplePie_Item
|
|||
}
|
||||
if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
|
||||
{
|
||||
$authors[] = $this->registry->create('Author', array(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_HTML)));
|
||||
$authors[] = $this->registry->create('Author', array(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)));
|
||||
}
|
||||
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
|
||||
{
|
||||
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null));
|
||||
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
|
||||
}
|
||||
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
|
||||
{
|
||||
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null));
|
||||
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
|
||||
}
|
||||
foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
|
||||
{
|
||||
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_HTML), null, null));
|
||||
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
|
||||
}
|
||||
|
||||
if (!empty($authors))
|
||||
|
|
|
@ -76,26 +76,17 @@ class SimplePie_Parser
|
|||
|
||||
public function parse(&$data, $encoding, $url = '')
|
||||
{
|
||||
if (function_exists('Mf2\parse')) {
|
||||
if (class_exists('DOMXpath') && function_exists('Mf2\parse')) {
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadHTML($data);
|
||||
$xpath = new DOMXpath($doc);
|
||||
// Check for both h-feed and h-entry, as both a feed with no entries
|
||||
// and a list of entries without an h-feed wrapper are both valid.
|
||||
$position = 0;
|
||||
while ($position = strpos($data, 'h-feed', $position)) {
|
||||
$start = $position < 200 ? 0 : $position - 200;
|
||||
$check = substr($data, $start, 400);
|
||||
if (preg_match('/class="[^"]*h-feed/', $check)) {
|
||||
return $this->parse_microformats($data, $url);
|
||||
}
|
||||
$position += 7;
|
||||
}
|
||||
$position = 0;
|
||||
while ($position = strpos($data, 'h-entry', $position)) {
|
||||
$start = $position < 200 ? 0 : $position - 200;
|
||||
$check = substr($data, $start, 400);
|
||||
if (preg_match('/class="[^"]*h-entry/', $check)) {
|
||||
return $this->parse_microformats($data, $url);
|
||||
}
|
||||
$position += 7;
|
||||
$query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '.
|
||||
'contains(concat(" ", @class, " "), " h-entry ")]';
|
||||
$result = $xpath->query($query);
|
||||
if ($result->length !== 0) {
|
||||
return $this->parse_microformats($data, $url);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -465,7 +456,7 @@ class SimplePie_Parser
|
|||
$h_feed = $mf_item;
|
||||
break;
|
||||
}
|
||||
// Also look for an h-feed in the children of each top level item.
|
||||
// Also look for h-feed or h-entry in the children of each top level item.
|
||||
if (!isset($mf_item['children'][0]['type'])) continue;
|
||||
if (in_array('h-feed', $mf_item['children'][0]['type'])) {
|
||||
$h_feed = $mf_item['children'][0];
|
||||
|
@ -474,6 +465,13 @@ class SimplePie_Parser
|
|||
if (in_array('h-card', $mf_item['type'])) $feed_author = $mf_item;
|
||||
break;
|
||||
}
|
||||
else if (in_array('h-entry', $mf_item['children'][0]['type'])) {
|
||||
$entries = $mf_item['children'];
|
||||
// In this case the parent of the h-entry list may be an h-card, so use
|
||||
// it as the feed_author.
|
||||
if (in_array('h-card', $mf_item['type'])) $feed_author = $mf_item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isset($h_feed['children'])) {
|
||||
$entries = $h_feed['children'];
|
||||
|
@ -485,7 +483,7 @@ class SimplePie_Parser
|
|||
$feed_author = $mf['items'][0]['properties']['author'][0];
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (count($entries) === 0) {
|
||||
$entries = $mf['items'];
|
||||
}
|
||||
for ($i = 0; $i < count($entries); $i++) {
|
||||
|
@ -554,18 +552,21 @@ class SimplePie_Parser
|
|||
$photo_list = array();
|
||||
for ($j = 0; $j < count($entry['properties']['photo']); $j++) {
|
||||
$photo = $entry['properties']['photo'][$j];
|
||||
if (strpos($content, $photo) === false) {
|
||||
if (!empty($photo) && strpos($content, $photo) === false) {
|
||||
$photo_list[] = $photo;
|
||||
}
|
||||
}
|
||||
// When there's more than one photo show the first and use a lightbox.
|
||||
// Need a permanent, unique name for the image set, but don't have
|
||||
// anything unique except for the content itself, so use that.
|
||||
$count = count($photo_list);
|
||||
if ($count > 1) {
|
||||
$image_set_id = preg_replace('/[[:^alnum:]]/', '', $photo_list[0]);
|
||||
$description = '<p>';
|
||||
for ($j = 0; $j < $count; $j++) {
|
||||
$hidden = $j === 0 ? '' : 'class="hidden" ';
|
||||
$description .= '<a href="'.$photo_list[$j].'" '.$hidden.
|
||||
'data-lightbox="image-set-'.$i.'">'.
|
||||
'data-lightbox="image-set-'.$image_set_id.'">'.
|
||||
'<img src="'.$photo_list[$j].'"></a>';
|
||||
}
|
||||
$description .= '<br><b>'.$count.' photos</b></p>';
|
||||
|
@ -583,10 +584,18 @@ class SimplePie_Parser
|
|||
$item['title'] = array(array('data' => $title));
|
||||
}
|
||||
$description .= $entry['properties']['content'][0]['html'];
|
||||
if (isset($entry['properties']['in-reply-to'][0]['value'])) {
|
||||
$in_reply_to = $entry['properties']['in-reply-to'][0]['value'];
|
||||
$description .= '<p><span class="in-reply-to"></span> '.
|
||||
'<a href="'.$in_reply_to.'">'.$in_reply_to.'</a><p>';
|
||||
if (isset($entry['properties']['in-reply-to'][0])) {
|
||||
$in_reply_to = '';
|
||||
if (is_string($entry['properties']['in-reply-to'][0])) {
|
||||
$in_reply_to = $entry['properties']['in-reply-to'][0];
|
||||
}
|
||||
else if (isset($entry['properties']['in-reply-to'][0]['value'])) {
|
||||
$in_reply_to = $entry['properties']['in-reply-to'][0]['value'];
|
||||
}
|
||||
if ($in_reply_to !== '') {
|
||||
$description .= '<p><span class="in-reply-to"></span> '.
|
||||
'<a href="'.$in_reply_to.'">'.$in_reply_to.'</a><p>';
|
||||
}
|
||||
}
|
||||
$item['description'] = array(array('data' => $description));
|
||||
}
|
||||
|
@ -627,7 +636,7 @@ class SimplePie_Parser
|
|||
$image = array(array('child' => array('' => array('url' =>
|
||||
array(array('data' => $feed_author['properties']['photo'][0]))))));
|
||||
}
|
||||
// Use the a name given for the h-feed, or get the title from the html.
|
||||
// Use the name given for the h-feed, or get the title from the html.
|
||||
if ($feed_title !== '') {
|
||||
$feed_title = array(array('data' => htmlspecialchars($feed_title)));
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ The basic usage is simple:
|
|||
- ``$options->setHelp()`` adds a general description
|
||||
- ``$options->registerOption()`` adds an option
|
||||
- ``$options->registerArgument()`` adds an argument
|
||||
- ``$options->registerComman()`` adds a sub command
|
||||
- ``$options->registerCommand()`` adds a sub command
|
||||
- implement the ```main($options)``` method and do your business logic there
|
||||
- ``$options->getOpts`` lets you access set options
|
||||
- ``$options->getArgs()`` returns the remaining arguments after removing the options
|
||||
|
|
|
@ -56,6 +56,8 @@ abstract class CLI
|
|||
*
|
||||
* @param Options $options
|
||||
* @return void
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract protected function setup(Options $options);
|
||||
|
||||
|
@ -66,6 +68,8 @@ abstract class CLI
|
|||
*
|
||||
* @param Options $options
|
||||
* @return void
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract protected function main(Options $options);
|
||||
|
||||
|
@ -74,6 +78,8 @@ abstract class CLI
|
|||
*
|
||||
* Executes the setup() routine, adds default options, initiate the options parsing and argument checking
|
||||
* and finally executes main()
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
|
|
|
@ -99,9 +99,11 @@ class Colors
|
|||
/**
|
||||
* Convenience function to print a line in a given color
|
||||
*
|
||||
* @param string $line the line to print, a new line is added automatically
|
||||
* @param string $color one of the available color names
|
||||
* @param string $line the line to print, a new line is added automatically
|
||||
* @param string $color one of the available color names
|
||||
* @param resource $channel file descriptor to write to
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function ptln($line, $color, $channel = STDOUT)
|
||||
{
|
||||
|
@ -158,6 +160,8 @@ class Colors
|
|||
* reset the terminal color
|
||||
*
|
||||
* @param resource $channel file descriptor to write to
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function reset($channel = STDOUT)
|
||||
{
|
||||
|
|
|
@ -285,7 +285,7 @@ class Options
|
|||
*
|
||||
* @param mixed $option
|
||||
* @param bool|string $default what to return if the option was not set
|
||||
* @return bool|string
|
||||
* @return bool|string|string[]
|
||||
*/
|
||||
public function getOpt($option = null, $default = false)
|
||||
{
|
||||
|
@ -325,6 +325,8 @@ class Options
|
|||
* Builds a help screen from the available options. You may want to call it from -h or on error
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function help()
|
||||
{
|
||||
|
|
|
@ -39,7 +39,7 @@ class TableFormatter
|
|||
$width = @exec('tput cols');
|
||||
}
|
||||
if ($width) {
|
||||
$this->max = $width;
|
||||
$this->max = $width - 1;
|
||||
}
|
||||
|
||||
if ($colors) {
|
||||
|
|
Loading…
Reference in New Issue