From e3aac938aa2f80583c93b94da8550a7c1fe91c77 Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Tue, 15 Jun 2021 01:23:57 +0200 Subject: [PATCH] Updates the phpseclib library. --- README.md | 2 +- admin/README.txt | 2 +- componentbuilder.xml | 2 +- libraries/phpseclib/vendor/composer/LICENSE | 69 +--- .../vendor/composer/autoload_classmap.php | 24 -- .../vendor/composer/autoload_real.php | 3 + .../vendor/composer/autoload_static.php | 28 -- .../phpseclib/vendor/composer/installed.json | 29 +- .../vendor/phpseclib/phpseclib/README.md | 22 +- .../vendor/phpseclib/phpseclib/composer.json | 3 +- .../phpseclib/phpseclib/Crypt/Base.php | 84 +++-- .../phpseclib/phpseclib/Crypt/Hash.php | 1 - .../phpseclib/phpseclib/Crypt/RSA.php | 96 ++++- .../phpseclib/phpseclib/File/ANSI.php | 48 +-- .../phpseclib/phpseclib/File/ASN1.php | 76 ++-- .../phpseclib/phpseclib/File/X509.php | 37 +- .../phpseclib/phpseclib/Math/BigInteger.php | 28 +- .../phpseclib/phpseclib/Net/SFTP.php | 146 ++++++-- .../phpseclib/phpseclib/Net/SFTP/Stream.php | 11 +- .../phpseclib/phpseclib/Net/SSH1.php | 5 +- .../phpseclib/phpseclib/Net/SSH2.php | 333 +++++++++++------- 21 files changed, 650 insertions(+), 399 deletions(-) diff --git a/README.md b/README.md index dbe790825..7a683370c 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ TODO + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](https://github.com/vdm-io/Joomla-Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 11th June, 2021 ++ *Last Build*: 14th June, 2021 + *Version*: 2.12.10 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt diff --git a/admin/README.txt b/admin/README.txt index dbe790825..7a683370c 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -143,7 +143,7 @@ TODO + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](https://github.com/vdm-io/Joomla-Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 11th June, 2021 ++ *Last Build*: 14th June, 2021 + *Version*: 2.12.10 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt diff --git a/componentbuilder.xml b/componentbuilder.xml index 0b4bff33d..fd6078e49 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,7 +1,7 @@ COM_COMPONENTBUILDER - 11th June, 2021 + 14th June, 2021 Llewellyn van der Merwe llewellyn@joomlacomponentbuilder.com http://www.joomlacomponentbuilder.com diff --git a/libraries/phpseclib/vendor/composer/LICENSE b/libraries/phpseclib/vendor/composer/LICENSE index 4b615a383..62ecfd8d0 100644 --- a/libraries/phpseclib/vendor/composer/LICENSE +++ b/libraries/phpseclib/vendor/composer/LICENSE @@ -1,56 +1,19 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: Composer -Upstream-Contact: Jordi Boggiano -Source: https://github.com/composer/composer +Copyright (c) Nils Adermann, Jordi Boggiano -Files: * -Copyright: 2016, Nils Adermann - 2016, Jordi Boggiano -License: Expat +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: -Files: src/Composer/Util/TlsHelper.php -Copyright: 2016, Nils Adermann - 2016, Jordi Boggiano - 2013, Evan Coury -License: Expat and BSD-2-Clause +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -License: BSD-2-Clause - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - . - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - . - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - . - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -License: Expat - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is furnished - to do so, subject to the following conditions: - . - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/libraries/phpseclib/vendor/composer/autoload_classmap.php b/libraries/phpseclib/vendor/composer/autoload_classmap.php index 2f4700ebd..7a91153b0 100644 --- a/libraries/phpseclib/vendor/composer/autoload_classmap.php +++ b/libraries/phpseclib/vendor/composer/autoload_classmap.php @@ -6,28 +6,4 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( - 'phpseclib\\Crypt\\AES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php', - 'phpseclib\\Crypt\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Base.php', - 'phpseclib\\Crypt\\Blowfish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php', - 'phpseclib\\Crypt\\DES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php', - 'phpseclib\\Crypt\\Hash' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php', - 'phpseclib\\Crypt\\RC2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php', - 'phpseclib\\Crypt\\RC4' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php', - 'phpseclib\\Crypt\\RSA' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php', - 'phpseclib\\Crypt\\Random' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php', - 'phpseclib\\Crypt\\Rijndael' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php', - 'phpseclib\\Crypt\\TripleDES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php', - 'phpseclib\\Crypt\\Twofish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php', - 'phpseclib\\File\\ANSI' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ANSI.php', - 'phpseclib\\File\\ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1.php', - 'phpseclib\\File\\ASN1\\Element' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php', - 'phpseclib\\File\\X509' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/X509.php', - 'phpseclib\\Math\\BigInteger' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php', - 'phpseclib\\Net\\SCP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SCP.php', - 'phpseclib\\Net\\SFTP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php', - 'phpseclib\\Net\\SFTP\\Stream' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php', - 'phpseclib\\Net\\SSH1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH1.php', - 'phpseclib\\Net\\SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php', - 'phpseclib\\System\\SSH\\Agent' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', - 'phpseclib\\System\\SSH\\Agent\\Identity' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', ); diff --git a/libraries/phpseclib/vendor/composer/autoload_real.php b/libraries/phpseclib/vendor/composer/autoload_real.php index f90786941..88b74d884 100644 --- a/libraries/phpseclib/vendor/composer/autoload_real.php +++ b/libraries/phpseclib/vendor/composer/autoload_real.php @@ -13,6 +13,9 @@ class ComposerAutoloaderInit10d22a526bd476954b93748a871e7ad4 } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { diff --git a/libraries/phpseclib/vendor/composer/autoload_static.php b/libraries/phpseclib/vendor/composer/autoload_static.php index ea6b0d7d3..09b862a0c 100644 --- a/libraries/phpseclib/vendor/composer/autoload_static.php +++ b/libraries/phpseclib/vendor/composer/autoload_static.php @@ -24,39 +24,11 @@ class ComposerStaticInit10d22a526bd476954b93748a871e7ad4 ), ); - public static $classMap = array ( - 'phpseclib\\Crypt\\AES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php', - 'phpseclib\\Crypt\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Base.php', - 'phpseclib\\Crypt\\Blowfish' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php', - 'phpseclib\\Crypt\\DES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php', - 'phpseclib\\Crypt\\Hash' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php', - 'phpseclib\\Crypt\\RC2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php', - 'phpseclib\\Crypt\\RC4' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php', - 'phpseclib\\Crypt\\RSA' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php', - 'phpseclib\\Crypt\\Random' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php', - 'phpseclib\\Crypt\\Rijndael' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php', - 'phpseclib\\Crypt\\TripleDES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php', - 'phpseclib\\Crypt\\Twofish' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php', - 'phpseclib\\File\\ANSI' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ANSI.php', - 'phpseclib\\File\\ASN1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1.php', - 'phpseclib\\File\\ASN1\\Element' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php', - 'phpseclib\\File\\X509' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/File/X509.php', - 'phpseclib\\Math\\BigInteger' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php', - 'phpseclib\\Net\\SCP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SCP.php', - 'phpseclib\\Net\\SFTP' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php', - 'phpseclib\\Net\\SFTP\\Stream' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php', - 'phpseclib\\Net\\SSH1' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SSH1.php', - 'phpseclib\\Net\\SSH2' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php', - 'phpseclib\\System\\SSH\\Agent' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', - 'phpseclib\\System\\SSH\\Agent\\Identity' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', - ); - public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInit10d22a526bd476954b93748a871e7ad4::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit10d22a526bd476954b93748a871e7ad4::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit10d22a526bd476954b93748a871e7ad4::$classMap; }, null, ClassLoader::class); } diff --git a/libraries/phpseclib/vendor/composer/installed.json b/libraries/phpseclib/vendor/composer/installed.json index 6867d0097..8d13372da 100644 --- a/libraries/phpseclib/vendor/composer/installed.json +++ b/libraries/phpseclib/vendor/composer/installed.json @@ -1,17 +1,17 @@ [ { "name": "phpseclib/phpseclib", - "version": "2.0.27", - "version_normalized": "2.0.27.0", + "version": "2.0.32", + "version_normalized": "2.0.32.0", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc" + "reference": "f5c4c19880d45d0be3e7d24ae8ac434844a898cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc", - "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/f5c4c19880d45d0be3e7d24ae8ac434844a898cd", + "reference": "f5c4c19880d45d0be3e7d24ae8ac434844a898cd", "shasum": "" }, "require": { @@ -19,8 +19,7 @@ }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "^4.8.35|^5.7|^6.0", - "sami/sami": "~2.0", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { @@ -29,7 +28,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": "2020-04-04T23:17:33+00:00", + "time": "2021-06-12T12:12:59+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -91,6 +90,20 @@ "twofish", "x.509", "x509" + ], + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } ] } ] diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/README.md b/libraries/phpseclib/vendor/phpseclib/phpseclib/README.md index ac0eb2f99..099486dc9 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/README.md +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/README.md @@ -1,6 +1,6 @@ # phpseclib - PHP Secure Communications Library -[![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=2.0)](https://travis-ci.org/phpseclib/phpseclib) +[![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=2.0)](https://travis-ci.com/phpseclib/phpseclib) ## Supporting phpseclib @@ -10,16 +10,16 @@ ## Introduction -MIT-licensed pure-PHP implementations of an arbitrary-precision integer -arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael, -AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509 +MIT-licensed pure-PHP implementations of the following: + +SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / Ed449 / Curve25519 / Curve449, ECDSA / ECDH (with support for 66 curves), RSA (PKCS#1 v2.2 compliant), DSA / DH, DES / 3DES / RC4 / Rijndael / AES / Blowfish / Twofish / Salsa20 / ChaCha20, GCM / Poly1305 * [Browse Git](https://github.com/phpseclib/phpseclib) ## Documentation -* [Documentation / Manual](http://phpseclib.sourceforge.net/) -* [API Documentation](https://api.phpseclib.org/2.0/) (generated by Sami) +* [Documentation / Manual](https://phpseclib.com/) +* [API Documentation](https://api.phpseclib.com/2.0/) (generated by Doctum) ## Branches @@ -29,6 +29,14 @@ AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509 * Unstable API * Do not use in production +### 3.0 + +* Long term support (LTS) release +* Major expansion of cryptographic primitives +* Minimum PHP version: 5.6.1 +* PSR-4 autoloading with namespace rooted at `\phpseclib3` +* Install via Composer: `composer require phpseclib/phpseclib:~3.0` + ### 2.0 * Long term support (LTS) release @@ -44,7 +52,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.18 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.18.zip/download) +* [Download 1.0.19 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.19.zip/download) ## Security contact information diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/composer.json b/libraries/phpseclib/vendor/phpseclib/phpseclib/composer.json index b4e8a1c9c..08b9c7c91 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/composer.json +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/composer.json @@ -55,8 +55,7 @@ }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "^4.8.35|^5.7|^6.0", - "sami/sami": "~2.0", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php index 03b176e7b..8822b9b88 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php @@ -413,7 +413,7 @@ abstract class Base * @var mixed * @access private */ - var $use_inline_crypt; + var $use_inline_crypt = true; /** * If OpenSSL can be used in ECB but not in CTR we can emulate CTR @@ -495,11 +495,6 @@ abstract class Base } $this->_setEngine(); - - // Determining whether inline crypting can be used by the cipher - if ($this->use_inline_crypt !== false) { - $this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function'); - } } /** @@ -784,12 +779,14 @@ abstract class Base } if ($this->engine === self::ENGINE_MCRYPT) { + set_error_handler(array($this, 'do_nothing')); + if ($this->changed) { $this->_setupMcrypt(); $this->changed = false; } if ($this->enchanged) { - @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); + mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); $this->enchanged = false; } @@ -822,15 +819,15 @@ abstract class Base if ($len >= $block_size) { if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) { if ($this->enbuffer['enmcrypt_init'] === true) { - @mcrypt_generic_init($this->enmcrypt, $this->key, $iv); + mcrypt_generic_init($this->enmcrypt, $this->key, $iv); $this->enbuffer['enmcrypt_init'] = false; } - $ciphertext.= @mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); + $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); $iv = substr($ciphertext, -$block_size); $len%= $block_size; } else { while ($len >= $block_size) { - $iv = @mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); + $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); $ciphertext.= $iv; $len-= $block_size; $i+= $block_size; @@ -839,22 +836,26 @@ abstract class Base } if ($len) { - $iv = @mcrypt_generic($this->ecb, $iv); + $iv = mcrypt_generic($this->ecb, $iv); $block = $iv ^ substr($plaintext, -$len); $iv = substr_replace($iv, $block, 0, $len); $ciphertext.= $block; $pos = $len; } + restore_error_handler(); + return $ciphertext; } - $ciphertext = @mcrypt_generic($this->enmcrypt, $plaintext); + $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); if (!$this->continuousBuffer) { - @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); + mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); } + restore_error_handler(); + return $ciphertext; } @@ -1123,13 +1124,14 @@ abstract class Base } if ($this->engine === self::ENGINE_MCRYPT) { + set_error_handler(array($this, 'do_nothing')); $block_size = $this->block_size; if ($this->changed) { $this->_setupMcrypt(); $this->changed = false; } if ($this->dechanged) { - @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); + mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); $this->dechanged = false; } @@ -1157,26 +1159,30 @@ abstract class Base } if ($len >= $block_size) { $cb = substr($ciphertext, $i, $len - $len % $block_size); - $plaintext.= @mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; + $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; $iv = substr($cb, -$block_size); $len%= $block_size; } if ($len) { - $iv = @mcrypt_generic($this->ecb, $iv); + $iv = mcrypt_generic($this->ecb, $iv); $plaintext.= $iv ^ substr($ciphertext, -$len); $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len); $pos = $len; } + restore_error_handler(); + return $plaintext; } - $plaintext = @mdecrypt_generic($this->demcrypt, $ciphertext); + $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext); if (!$this->continuousBuffer) { - @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); + mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); } + restore_error_handler(); + return $this->paddable ? $this->_unpad($plaintext) : $plaintext; } @@ -1654,9 +1660,12 @@ abstract class Base } return false; case self::ENGINE_MCRYPT: - return $this->cipher_name_mcrypt && + set_error_handler(array($this, 'do_nothing')); + $result = $this->cipher_name_mcrypt && extension_loaded('mcrypt') && - in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms()); + in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()); + restore_error_handler(); + return $result; case self::ENGINE_INTERNAL: return true; } @@ -1733,17 +1742,19 @@ abstract class Base } if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) { + set_error_handler(array($this, 'do_nothing')); // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, // (re)open them with the module named in $this->cipher_name_mcrypt - @mcrypt_module_close($this->enmcrypt); - @mcrypt_module_close($this->demcrypt); + mcrypt_module_close($this->enmcrypt); + mcrypt_module_close($this->demcrypt); $this->enmcrypt = null; $this->demcrypt = null; if ($this->ecb) { - @mcrypt_module_close($this->ecb); + mcrypt_module_close($this->ecb); $this->ecb = null; } + restore_error_handler(); } $this->changed = true; @@ -1856,19 +1867,19 @@ abstract class Base self::MODE_STREAM => MCRYPT_MODE_STREAM, ); - $this->demcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); - $this->enmcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() // to workaround mcrypt's broken ncfb implementation in buffered mode // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} if ($this->mode == self::MODE_CFB) { - $this->ecb = @mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); + $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); } } // else should mcrypt_generic_deinit be called? if ($this->mode == self::MODE_CFB) { - @mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); + mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); } } @@ -2602,12 +2613,8 @@ 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 . ' }'); + eval('$func = function ($_action, &$self, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' } };'); + return $func; } /** @@ -2636,7 +2643,7 @@ abstract class Base * * @see self::_setupInlineCrypt() * @access private - * @param $bytes + * @param string $bytes * @return string */ function _hashInlineCryptFunction($bytes) @@ -2705,4 +2712,13 @@ abstract class Base return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; } } + + /** + * Dummy error handler to suppress mcrypt errors + * + * @access private + */ + function do_nothing() + { + } } diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php index a61668209..248b65ef7 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php @@ -849,7 +849,6 @@ class Hash * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the * possibility of overflow exists, care has to be taken. BigInteger could be used but this should be faster. * - * @param int $... * @return int * @see self::_sha256() * @access private diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php index 72be6eeb1..e26fe41dd 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php @@ -537,7 +537,7 @@ class RSA * @access public * @param int $bits * @param int $timeout - * @param array $p + * @param array $partial */ function createKey($bits = 1024, $timeout = false, $partial = array()) { @@ -716,7 +716,12 @@ class RSA * * @access private * @see self::setPrivateKeyFormat() - * @param string $RSAPrivateKey + * @param Math_BigInteger $n + * @param Math_BigInteger $e + * @param Math_BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients * @return string */ function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients) @@ -997,8 +1002,9 @@ class RSA * * @access private * @see self::setPublicKeyFormat() - * @param string $RSAPrivateKey - * @return string + * @param Math_BigInteger $n + * @param Math_BigInteger $e + * @return string|array */ function _convertPublicKey($n, $e) { @@ -1213,6 +1219,7 @@ class RSA $length = $this->_decodeLength($temp); switch ($this->_string_shift($temp, $length)) { case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption + case "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0A": // rsaPSS break; case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC /* @@ -1539,6 +1546,8 @@ class RSA return $components; } + + return false; } /** @@ -1878,7 +1887,6 @@ class RSA * * @see self::getPublicKey() * @access public - * @param string $key * @param int $type optional */ function getPublicKey($type = self::PUBLIC_FORMAT_PKCS8) @@ -1936,7 +1944,6 @@ class RSA * * @see self::getPublicKey() * @access public - * @param string $key * @param int $type optional * @return mixed */ @@ -1961,8 +1968,7 @@ class RSA * * @see self::getPrivateKey() * @access private - * @param string $key - * @param int $type optional + * @param int $mode optional */ function _getPrivatePublicKey($mode = self::PUBLIC_FORMAT_PKCS8) { @@ -2179,7 +2185,7 @@ class RSA * of the hash function Hash) and 0. * * @access public - * @param int $format + * @param int $sLen */ function setSaltLength($sLen) { @@ -2212,7 +2218,7 @@ class RSA * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. * * @access private - * @param string $x + * @param int|string|resource $x * @return \phpseclib\Math\BigInteger */ function _os2ip($x) @@ -2439,7 +2445,7 @@ class RSA * * @access private * @param string $mgfSeed - * @param int $mgfLen + * @param int $maskLen * @return string */ function _mgf1($mgfSeed, $maskLen) @@ -2574,9 +2580,9 @@ class RSA $offset+= $patternMatch ? 0 : 1; } - // we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation + // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation // to protect against timing attacks - if (!$hashesMatch & !$patternMatch) { + if (!$hashesMatch | !$patternMatch) { user_error('Decryption error'); return false; } @@ -2911,6 +2917,59 @@ class RSA return $em; } + /** + * EMSA-PKCS1-V1_5-ENCODE (without NULL) + * + * Quoting https://tools.ietf.org/html/rfc8017#page-65, + * + * "The parameters field associated with id-sha1, id-sha224, id-sha256, + * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should + * generally be omitted, but if present, it shall have a value of type + * NULL" + * + * @access private + * @param string $m + * @param int $emLen + * @return string + */ + function _emsa_pkcs1_v1_5_encode_without_null($m, $emLen) + { + $h = $this->hash->hash($m); + if ($h === false) { + return false; + } + + switch ($this->hashName) { + case 'sha1': + $t = pack('H*', '301f300706052b0e03021a0414'); + break; + case 'sha256': + $t = pack('H*', '302f300b06096086480165030402010420'); + break; + case 'sha384': + $t = pack('H*', '303f300b06096086480165030402020430'); + break; + case 'sha512': + $t = pack('H*', '304f300b06096086480165030402030440'); + break; + default: + return false; + } + $t.= $h; + $tLen = strlen($t); + + if ($emLen < $tLen + 11) { + user_error('Intended encoded message length too short'); + return false; + } + + $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); + + $em = "\0\1$ps\0$t"; + + return $em; + } + /** * RSASSA-PKCS1-V1_5-SIGN * @@ -2948,6 +3007,7 @@ class RSA * * @access private * @param string $m + * @param string $s * @return string */ function _rsassa_pkcs1_v1_5_verify($m, $s) @@ -2976,13 +3036,17 @@ class RSA // EMSA-PKCS1-v1_5 encoding $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); - if ($em2 === false) { + $em3 = $this->_emsa_pkcs1_v1_5_encode_without_null($m, $this->k); + + if ($em2 === false && $em3 === false) { user_error('RSA modulus too short'); return false; } // Compare - return $this->_equals($em, $em2); + + return ($em2 !== false && $this->_equals($em, $em2)) || + ($em3 !== false && $this->_equals($em, $em3)); } /** @@ -3088,7 +3152,7 @@ class RSA * * @see self::encrypt() * @access public - * @param string $plaintext + * @param string $ciphertext * @return string */ function decrypt($ciphertext) diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php index 5ff1f2ea1..b6874d357 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php @@ -203,8 +203,7 @@ class ANSI /** * Set the number of lines that should be logged past the terminal height * - * @param int $x - * @param int $y + * @param int $history * @access public */ function setHistory($history) @@ -272,7 +271,7 @@ class ANSI case "\x1B[K": // Clear screen from cursor right $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x); - array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - $this->x - 1, $this->base_attr_cell)); + array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - ($this->x - 1), $this->base_attr_cell)); break; case "\x1B[2K": // Clear entire line $this->screen[$this->y] = str_repeat(' ', $this->x); @@ -316,19 +315,20 @@ class ANSI $mods = explode(';', $match[1]); foreach ($mods as $mod) { switch ($mod) { - case 0: // Turn off character attributes + case '': + case '0': // Turn off character attributes $attr_cell = clone $this->base_attr_cell; break; - case 1: // Turn bold mode on + case '1': // Turn bold mode on $attr_cell->bold = true; break; - case 4: // Turn underline mode on + case '4': // Turn underline mode on $attr_cell->underline = true; break; - case 5: // Turn blinking mode on + case '5': // Turn blinking mode on $attr_cell->blink = true; break; - case 7: // Turn reverse video on + case '7': // Turn reverse video on $attr_cell->reverse = !$attr_cell->reverse; $temp = $attr_cell->background; $attr_cell->background = $attr_cell->foreground; @@ -341,23 +341,23 @@ class ANSI $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' }; switch ($mod) { // @codingStandardsIgnoreStart - case 30: $front = 'black'; break; - case 31: $front = 'red'; break; - case 32: $front = 'green'; break; - case 33: $front = 'yellow'; break; - case 34: $front = 'blue'; break; - case 35: $front = 'magenta'; break; - case 36: $front = 'cyan'; break; - case 37: $front = 'white'; break; + case '30': $front = 'black'; break; + case '31': $front = 'red'; break; + case '32': $front = 'green'; break; + case '33': $front = 'yellow'; break; + case '34': $front = 'blue'; break; + case '35': $front = 'magenta'; break; + case '36': $front = 'cyan'; break; + case '37': $front = 'white'; break; - case 40: $back = 'black'; break; - case 41: $back = 'red'; break; - case 42: $back = 'green'; break; - case 43: $back = 'yellow'; break; - case 44: $back = 'blue'; break; - case 45: $back = 'magenta'; break; - case 46: $back = 'cyan'; break; - case 47: $back = 'white'; break; + case '40': $back = 'black'; break; + case '41': $back = 'red'; break; + case '42': $back = 'green'; break; + case '43': $back = 'yellow'; break; + case '44': $back = 'blue'; break; + case '45': $back = 'magenta'; break; + case '46': $back = 'cyan'; break; + case '47': $back = 'white'; break; // @codingStandardsIgnoreEnd default: diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php index a304a000a..d1a7719f8 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php @@ -235,7 +235,7 @@ class ASN1 $current = array('start' => $start); $type = ord($encoded[$encoded_pos++]); - $start++; + $startOffset = 1; $constructed = ($type >> 5) & 1; @@ -245,13 +245,20 @@ class ASN1 // process septets (since the eighth bit is ignored, it's not an octet) do { $temp = ord($encoded[$encoded_pos++]); + $startOffset++; $loop = $temp >> 7; $tag <<= 7; - $tag |= $temp & 0x7F; - $start++; + $temp &= 0x7F; + // "bits 7 to 1 of the first subsequent octet shall not all be zero" + if ($startOffset == 2 && $temp == 0) { + return false; + } + $tag |= $temp; } while ($loop); } + $start+= $startOffset; + // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13 $length = ord($encoded[$encoded_pos++]); $start++; @@ -344,13 +351,16 @@ class ASN1 switch ($tag) { case self::TYPE_BOOLEAN: // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 - //if (strlen($content) != 1) { - // return false; - //} + if ($constructed || strlen($content) != 1) { + return false; + } $current['content'] = (bool) ord($content[$content_pos]); break; case self::TYPE_INTEGER: case self::TYPE_ENUMERATED: + if ($constructed) { + return false; + } $current['content'] = new BigInteger(substr($content, $content_pos), -256); break; case self::TYPE_REAL: // not currently supported @@ -370,15 +380,15 @@ class ASN1 $last = count($temp) - 1; for ($i = 0; $i < $last; $i++) { // all subtags should be bit strings - //if ($temp[$i]['type'] != self::TYPE_BIT_STRING) { - // return false; - //} + if ($temp[$i]['type'] != self::TYPE_BIT_STRING) { + return false; + } $current['content'].= substr($temp[$i]['content'], 1); } // all subtags should be bit strings - //if ($temp[$last]['type'] != self::TYPE_BIT_STRING) { - // return false; - //} + if ($temp[$last]['type'] != self::TYPE_BIT_STRING) { + return false; + } $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1); } break; @@ -395,9 +405,9 @@ class ASN1 } $content_pos += $temp['length']; // all subtags should be octet strings - //if ($temp['type'] != self::TYPE_OCTET_STRING) { - // return false; - //} + if ($temp['type'] != self::TYPE_OCTET_STRING) { + return false; + } $current['content'].= $temp['content']; $length+= $temp['length']; } @@ -408,12 +418,15 @@ class ASN1 break; case self::TYPE_NULL: // "The contents octets shall not contain any octets." -- paragraph 8.8.2 - //if (strlen($content)) { - // return false; - //} + if ($constructed || strlen($content)) { + return false; + } break; case self::TYPE_SEQUENCE: case self::TYPE_SET: + if (!$constructed) { + return false; + } $offset = 0; $current['content'] = array(); $content_len = strlen($content); @@ -434,7 +447,13 @@ class ASN1 } break; case self::TYPE_OBJECT_IDENTIFIER: + if ($constructed) { + return false; + } $current['content'] = $this->_decodeOID(substr($content, $content_pos)); + if ($current['content'] === false) { + return false; + } break; /* Each character string type shall be encoded as if it had been declared: [UNIVERSAL x] IMPLICIT OCTET STRING @@ -464,12 +483,20 @@ class ASN1 case self::TYPE_UTF8_STRING: // ???? case self::TYPE_BMP_STRING: + if ($constructed) { + return false; + } $current['content'] = substr($content, $content_pos); break; case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: + if ($constructed) { + return false; + } $current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag); + break; default: + return false; } $start+= $length; @@ -790,7 +817,7 @@ class ASN1 * * @param string $source * @param string $mapping - * @param int $idx + * @param array $special * @return string * @access public */ @@ -806,6 +833,7 @@ class ASN1 * @param string $source * @param string $mapping * @param int $idx + * @param array $special * @return string * @access private */ @@ -965,7 +993,10 @@ class ASN1 case self::TYPE_GENERALIZED_TIME: $format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y'; $format.= 'mdHis'; + // if $source does _not_ include timezone information within it then assume that the timezone is GMT $date = new DateTime($source, new DateTimeZone('GMT')); + // if $source _does_ include timezone information within it then convert the time to GMT + $date->setTimezone(new DateTimeZone('GMT')); $value = $date->format($format) . 'Z'; break; case self::TYPE_BIT_STRING: @@ -1126,6 +1157,11 @@ class ASN1 $oid = array(); $pos = 0; $len = strlen($content); + + if (ord($content[$len - 1]) & 0x80) { + return false; + } + $n = new BigInteger(); while ($pos < $len) { $temp = ord($content[$pos++]); @@ -1161,7 +1197,7 @@ class ASN1 * Called by _encode_der() * * @access private - * @param string $content + * @param string $source * @return string */ function _encodeOID($source) diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/X509.php index ddbc61595..fa3c0264e 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/X509.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/File/X509.php @@ -1608,7 +1608,7 @@ class X509 * Map extension values from octet string to extension-specific internal * format. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1661,7 +1661,7 @@ class X509 * Map extension values from extension-specific internal format to * octet string. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1727,7 +1727,7 @@ class X509 * Map attribute values from ANY type to attribute-specific internal * format. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1768,7 +1768,7 @@ class X509 * Map attribute values from attribute-specific internal format to * ANY type. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1811,7 +1811,7 @@ class X509 * Map DN values from ANY type to DN-specific internal * format. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1841,7 +1841,7 @@ class X509 * Map DN values from DN-specific internal format to * ANY type. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -3195,7 +3195,8 @@ class X509 /** * Load a Certificate Signing Request * - * @param string $csr + * @param string|array $csr + * @param int $mode * @access public * @return mixed */ @@ -3332,7 +3333,7 @@ class X509 * * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen * - * @param string $csr + * @param string|array $spkac * @access public * @return mixed */ @@ -3403,7 +3404,7 @@ class X509 /** * Save a SPKAC CSR request * - * @param array $csr + * @param string|array $spkac * @param int $format optional * @access public * @return string @@ -3447,6 +3448,7 @@ class X509 * Load a Certificate Revocation List * * @param string $crl + * @param int $mode * @access public * @return mixed */ @@ -4043,8 +4045,7 @@ class X509 /** * X.509 certificate signing helper function. * - * @param object $key - * @param \phpseclib\File\X509 $subject + * @param \phpseclib\File\X509 $key * @param string $signatureAlgorithm * @access public * @return mixed @@ -4119,7 +4120,7 @@ class X509 * Set Serial Number * * @param string $serial - * @param $base optional + * @param int $base optional * @access public */ function setSerialNumber($serial, $base = -256) @@ -4782,7 +4783,6 @@ class X509 * Set the IP Addresses's which the cert is to be valid for * * @access public - * @param string $ipAddress optional */ function setIPAddress() { @@ -5054,11 +5054,16 @@ class X509 * subject=/O=organization/OU=org unit/CN=common name * issuer=/O=organization/CN=common name */ - $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); - // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff - $temp = preg_replace('#-+[^-]+-+#', '', $temp); + if (strlen($str) > ini_get('pcre.backtrack_limit')) { + $temp = $str; + } else { + $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); + $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $temp, 1); + } // remove new lines $temp = str_replace(array("\r", "\n", ' '), '', $temp); + // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff + $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; return $temp != false ? $temp : $str; } diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php index e7f664670..fc24b9145 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php @@ -243,7 +243,7 @@ class BigInteger * ?> * * - * @param $x base-10 number or base-$base number if $base set. + * @param int|string|resource $x base-10 number or base-$base number if $base set. * @param int $base * @return \phpseclib\Math\BigInteger * @access public @@ -658,11 +658,11 @@ class BigInteger { $hex = $this->toHex($twos_compliment); $bits = ''; - for ($i = strlen($hex) - 8, $start = strlen($hex) & 7; $i >= $start; $i-=8) { - $bits = str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT) . $bits; + for ($i = strlen($hex) - 6, $start = strlen($hex) % 6; $i >= $start; $i-=6) { + $bits = str_pad(decbin(hexdec(substr($hex, $i, 6))), 24, '0', STR_PAD_LEFT) . $bits; } if ($start) { // hexdec('') == 0 - $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8, '0', STR_PAD_LEFT) . $bits; + $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8 * $start, '0', STR_PAD_LEFT) . $bits; } $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); @@ -1994,7 +1994,7 @@ class BigInteger * * @see self::_slidingWindow() * @access private - * @param \phpseclib\Math\BigInteger + * @param \phpseclib\Math\BigInteger $n * @return \phpseclib\Math\BigInteger */ function _mod2($n) @@ -2688,7 +2688,7 @@ class BigInteger * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). * * @param \phpseclib\Math\BigInteger $y - * @return int < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @return int that is < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. * @access public * @see self::equals() * @internal Could return $this->subtract($x), but that's not as fast as what we do do. @@ -3090,7 +3090,7 @@ class BigInteger * * Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not. * - * @param int $length + * @param int $size * @return \phpseclib\Math\BigInteger * @access private */ @@ -3557,7 +3557,7 @@ class BigInteger * * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision * - * @param \phpseclib\Math\BigInteger + * @param \phpseclib\Math\BigInteger $result * @return \phpseclib\Math\BigInteger * @see self::_trim() * @access private @@ -3634,8 +3634,8 @@ class BigInteger /** * Array Repeat * - * @param $input Array - * @param $multiplier mixed + * @param array $input + * @param mixed $multiplier * @return array * @access private */ @@ -3649,8 +3649,8 @@ class BigInteger * * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. * - * @param $x String - * @param $shift Integer + * @param string $x (by reference) + * @param int $shift * @return string * @access private */ @@ -3678,8 +3678,8 @@ class BigInteger * * Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder. * - * @param $x String - * @param $shift Integer + * @param string $x (by referenc) + * @param int $shift * @return string * @access private */ diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php index bf7ef36b4..f9bb22352 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php @@ -259,6 +259,26 @@ class SFTP extends SSH2 */ var $requestBuffer = array(); + /** + * Preserve timestamps on file downloads / uploads + * + * @see self::get() + * @see self::put() + * @var bool + * @access private + */ + var $preserveTime = false; + + /** + * Was the last packet due to the channels being closed or not? + * + * @see self::get() + * @see self::get_sftp_packet() + * @var bool + * @access private + */ + var $channel_close = false; + /** * Default Constructor. * @@ -406,7 +426,6 @@ class SFTP extends SSH2 * Login * * @param string $username - * @param string $password * @return bool * @access public */ @@ -416,6 +435,17 @@ class SFTP extends SSH2 return false; } + return $this->_init_sftp_connection(); + } + + /** + * (Re)initializes the SFTP channel + * + * @return bool + * @access private + */ + function _init_sftp_connection() + { $this->window_size_server_to_client[self::CHANNEL] = $this->window_size; $packet = pack( @@ -719,7 +749,7 @@ class SFTP extends SSH2 } } - if ($path[0] != '/') { + if (!strlen($path) || $path[0] != '/') { $path = $this->pwd . '/' . $path; } @@ -1015,7 +1045,7 @@ class SFTP extends SSH2 uasort($contents, array(&$this, '_comparator')); } - return $raw ? $contents : array_keys($contents); + return $raw ? $contents : array_map('strval', array_keys($contents)); } /** @@ -1198,6 +1228,9 @@ class SFTP extends SSH2 $temp = &$this->stat_cache; $max = count($dirs) - 1; foreach ($dirs as $i => $dir) { + if (!is_array($temp)) { + return false; + } if ($i === $max) { unset($temp[$dir]); return true; @@ -1214,7 +1247,7 @@ class SFTP extends SSH2 * * Mainly used by file_exists * - * @param string $dir + * @param string $path * @return mixed * @access private */ @@ -1224,6 +1257,9 @@ class SFTP extends SSH2 $temp = &$this->stat_cache; foreach ($dirs as $dir) { + if (!is_array($temp)) { + return null; + } if (!isset($temp[$dir])) { return null; } @@ -1766,6 +1802,8 @@ class SFTP extends SSH2 * Creates a directory. * * @param string $dir + * @param int $mode + * @param bool $recursive * @return bool * @access public */ @@ -1798,6 +1836,7 @@ class SFTP extends SSH2 * Helper function for directory creation * * @param string $dir + * @param int $mode * @return bool * @access private */ @@ -2018,8 +2057,8 @@ class SFTP extends SSH2 $sent = 0; $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size; - $sftp_packet_size = 4096; // PuTTY uses 4096 - // make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header" + $sftp_packet_size = $this->max_sftp_packet; + // make the SFTP packet be exactly the SFTP packet size by including the bytes in the NET_SFTP_WRITE packets "header" $sftp_packet_size-= strlen($handle) + 25; $i = $j = 0; while ($dataCallback || ($size === 0 || $sent < $size)) { @@ -2069,7 +2108,14 @@ class SFTP extends SSH2 } if ($mode & self::SOURCE_LOCAL_FILE) { - fclose($fp); + if ($this->preserveTime) { + $stat = fstat($fp); + $this->touch($remote_file, $stat['mtime'], $stat['atime']); + } + + if (isset($fp) && is_resource($fp)) { + fclose($fp); + } } return $this->_close_handle($handle); @@ -2192,7 +2238,7 @@ class SFTP extends SSH2 $res_offset = $stat['size']; } else { $res_offset = 0; - if ($local_file !== false) { + if ($local_file !== false && !is_callable($local_file)) { $fp = fopen($local_file, 'wb'); if (!$fp) { return false; @@ -2202,7 +2248,7 @@ class SFTP extends SSH2 } } - $fclose_check = $local_file !== false && !is_resource($local_file); + $fclose_check = $local_file !== false && !is_callable($local_file) && !is_resource($local_file); $start = $offset; $read = 0; @@ -2223,9 +2269,6 @@ class SFTP extends SSH2 } $packet = null; $read+= $packet_size; - if (is_callable($progressCallback)) { - call_user_func($progressCallback, $read); - } $i++; } @@ -2252,9 +2295,14 @@ class SFTP extends SSH2 $offset+= strlen($temp); if ($local_file === false) { $content.= $temp; + } elseif (is_callable($local_file)) { + $local_file($temp); } else { fputs($fp, $temp); } + if (is_callable($progressCallback)) { + call_user_func($progressCallback, $offset); + } $temp = null; break; case NET_SFTP_STATUS: @@ -2266,7 +2314,13 @@ class SFTP extends SSH2 if ($fclose_check) { fclose($fp); } - user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS'); + // maybe the file was successfully transferred, maybe it wasn't + if ($this->channel_close) { + $this->_init_sftp_connection(); + return false; + } else { + user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS'); + } } $response = null; } @@ -2286,6 +2340,11 @@ class SFTP extends SSH2 if ($fclose_check) { fclose($fp); + + if ($this->preserveTime) { + $stat = $this->stat($remote_file); + touch($local_file, $stat['mtime'], $stat['atime']); + } } if (!$this->_close_handle($handle)) { @@ -2707,6 +2766,7 @@ class SFTP extends SSH2 * * @param string $path * @param string $prop + * @param mixed $type * @return mixed * @access private */ @@ -2947,6 +3007,7 @@ class SFTP extends SSH2 * * @param int $type * @param string $data + * @param int $request_id * @see self::_get_sftp_packet() * @see self::_send_channel_packet() * @return bool @@ -2954,6 +3015,10 @@ class SFTP extends SSH2 */ function _send_sftp_packet($type, $data, $request_id = 1) { + // in SSH2.php the timeout is cumulative per function call. eg. exec() will + // timeout after 10s. but for SFTP.php it's cumulative per packet + $this->curTimeout = $this->timeout; + $packet = $this->use_request_id ? pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) : pack('NCa*', strlen($data) + 1, $type, $data); @@ -2966,9 +3031,17 @@ class SFTP extends SSH2 $packet_type = '-> ' . $this->packet_types[$type] . ' (' . round($stop - $start, 4) . 's)'; if (NET_SFTP_LOGGING == self::LOG_REALTIME) { - echo "
\r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n
\r\n"; - flush(); - ob_flush(); + switch (PHP_SAPI) { + case 'cli': + $start = $stop = "\r\n"; + break; + default: + $start = '
';
+                        $stop = '
'; + } + echo $start . $this->_format_log(array($data), array($packet_type)) . $stop; + @flush(); + @ob_flush(); } else { $this->packet_type_log[] = $packet_type; if (NET_SFTP_LOGGING == self::LOG_COMPLEX) { @@ -3009,6 +3082,8 @@ class SFTP extends SSH2 */ function _get_sftp_packet($request_id = null) { + $this->channel_close = false; + if (isset($request_id) && isset($this->requestBuffer[$request_id])) { $this->packet_type = $this->requestBuffer[$request_id]['packet_type']; $temp = $this->requestBuffer[$request_id]['packet']; @@ -3025,7 +3100,10 @@ class SFTP extends SSH2 // SFTP packet length while (strlen($this->packet_buffer) < 4) { $temp = $this->_get_channel_packet(self::CHANNEL, true); - if (is_bool($temp)) { + if ($temp === true) { + if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) { + $this->channel_close = true; + } $this->packet_type = false; $this->packet_buffer = ''; return false; @@ -3075,9 +3153,17 @@ class SFTP extends SSH2 $packet_type = '<- ' . $this->packet_types[$this->packet_type] . ' (' . round($stop - $start, 4) . 's)'; if (NET_SFTP_LOGGING == self::LOG_REALTIME) { - echo "
\r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n
\r\n"; - flush(); - ob_flush(); + switch (PHP_SAPI) { + case 'cli': + $start = $stop = "\r\n"; + break; + default: + $start = '
';
+                        $stop = '
'; + } + echo $start . $this->_format_log(array($packet), array($packet_type)) . $stop; + @flush(); + @ob_flush(); } else { $this->packet_type_log[] = $packet_type; if (NET_SFTP_LOGGING == self::LOG_COMPLEX) { @@ -3170,4 +3256,24 @@ class SFTP extends SSH2 $this->pwd = false; parent::_disconnect($reason); } + + /** + * Enable Date Preservation + * + * @access public + */ + function enableDatePreservation() + { + $this->preserveTime = true; + } + + /** + * Disable Date Preservation + * + * @access public + */ + function disableDatePreservation() + { + $this->preserveTime = false; + } } diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php index d2c4425de..ec9e5841a 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php @@ -410,7 +410,7 @@ class Stream { switch ($whence) { case SEEK_SET: - if ($offset >= $this->size || $offset < 0) { + if ($offset < 0) { return false; } break; @@ -447,7 +447,9 @@ class Stream // and https://github.com/php/php-src/blob/master/main/php_streams.h#L592 switch ($option) { case 1: // PHP_STREAM_META_TOUCH - return $this->sftp->touch($path, $var[0], $var[1]); + $time = isset($var[0]) ? $var[0] : null; + $atime = isset($var[1]) ? $var[1] : null; + return $this->sftp->touch($path, $time, $atime); case 2: // PHP_STREAM_OWNER_NAME case 3: // PHP_STREAM_GROUP_NAME return false; @@ -626,7 +628,6 @@ class Stream * $options. What does 8 correspond to? * * @param string $path - * @param int $mode * @param int $options * @return bool * @access public @@ -768,8 +769,8 @@ class Stream * If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not * NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method. * - * @param string - * @param array + * @param string $name + * @param array $arguments * @return mixed * @access public */ diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php index ff48d5436..e372b8b92 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php @@ -812,6 +812,7 @@ class SSH1 * @see self::interactiveRead() * @see self::interactiveWrite() * @param string $cmd + * @param bool $block * @return mixed * @access public */ @@ -1385,7 +1386,6 @@ class SSH1 * named constants from it, using the value as the name of the constant and the index as the value of the constant. * If any of the constants that would be defined already exists, none of the constants will be defined. * - * @param array $array * @access private */ function _define_array() @@ -1584,7 +1584,8 @@ class SSH1 * * Makes sure that only the last 1MB worth of packets will be logged * - * @param string $data + * @param int $protocol_flags + * @param string $message * @access private */ function _append_log($protocol_flags, $message) diff --git a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php index f37a04948..e449d987a 100644 --- a/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php +++ b/libraries/phpseclib/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php @@ -687,6 +687,14 @@ class SSH2 */ var $curTimeout; + /** + * Keep Alive Interval + * + * @see self::setKeepAlive() + * @access private + */ + var $keepAlive; + /** * Real-time log file pointer * @@ -962,6 +970,14 @@ class SSH2 */ var $auth = array(); + /** + * The authentication methods that may productively continue authentication. + * + * @see https://tools.ietf.org/html/rfc4252#section-5.1 + * @var array|null + */ + private $auth_methods_to_continue = null; + /** * Default Constructor. * @@ -1339,6 +1355,7 @@ class SSH2 function _key_exchange($kexinit_payload_server = false) { $preferred = $this->preferred; + $send_kex = true; $kex_algorithms = isset($preferred['kex']) ? $preferred['kex'] : @@ -1422,7 +1439,7 @@ class SSH2 0 ); - if ($this->send_kex_first) { + if ($kexinit_payload_server === false) { if (!$this->_send_binary_packet($kexinit_payload_client)) { return false; } @@ -1438,6 +1455,8 @@ class SSH2 user_error('Expected SSH_MSG_KEXINIT'); return false; } + + $send_kex = false; } $response = $kexinit_payload_server; @@ -1510,7 +1529,7 @@ class SSH2 extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1))); $first_kex_packet_follows = $first_kex_packet_follows != 0; - if (!$this->send_kex_first && !$this->_send_binary_packet($kexinit_payload_client)) { + if ($send_kex && !$this->_send_binary_packet($kexinit_payload_client)) { return false; } @@ -1538,6 +1557,32 @@ class SSH2 return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } + $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); + if ($server_host_key_algorithm === false) { + user_error('No compatible server host key algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + + $mac_algorithm_in = $this->_array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); + if ($mac_algorithm_in === false) { + user_error('No compatible server to client message authentication algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + + $compression_algorithm_out = $this->_array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); + if ($compression_algorithm_out === false) { + user_error('No compatible client to server compression algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + //$this->decompress = $compression_algorithm_out == 'zlib'; + + $compression_algorithm_in = $this->_array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_client_to_server); + if ($compression_algorithm_in === false) { + user_error('No compatible server to client compression algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + //$this->compress = $compression_algorithm_in == 'zlib'; + // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty. $exchange_hash_rfc4419 = ''; @@ -1773,12 +1818,6 @@ class SSH2 $this->session_id = $this->exchange_hash; } - $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); - if ($server_host_key_algorithm === false) { - user_error('No compatible server host key algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - switch ($server_host_key_algorithm) { case 'ssh-dss': $expected_key_format = 'ssh-dss'; @@ -1903,14 +1942,14 @@ class SSH2 $this->decrypt->decrypt(str_repeat("\0", 1536)); } - $mac_algorithm = $this->_array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); - if ($mac_algorithm === false) { + $mac_algorithm_out = $this->_array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); + if ($mac_algorithm_out === false) { user_error('No compatible client to server message authentication algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } $createKeyLength = 0; // ie. $mac_algorithm == 'none' - switch ($mac_algorithm) { + switch ($mac_algorithm_out) { case 'hmac-sha2-256': $this->hmac_create = new Hash('sha256'); $createKeyLength = 32; @@ -1931,17 +1970,11 @@ class SSH2 $this->hmac_create = new Hash('md5-96'); $createKeyLength = 16; } - $this->hmac_create->name = $mac_algorithm; - - $mac_algorithm = $this->_array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); - if ($mac_algorithm === false) { - user_error('No compatible server to client message authentication algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } + $this->hmac_create->name = $mac_algorithm_out; $checkKeyLength = 0; $this->hmac_size = 0; - switch ($mac_algorithm) { + switch ($mac_algorithm_in) { case 'hmac-sha2-256': $this->hmac_check = new Hash('sha256'); $checkKeyLength = 32; @@ -1967,7 +2000,7 @@ class SSH2 $checkKeyLength = 16; $this->hmac_size = 12; } - $this->hmac_check->name = $mac_algorithm; + $this->hmac_check->name = $mac_algorithm_in; $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); while ($createKeyLength > strlen($key)) { @@ -1981,20 +2014,6 @@ class SSH2 } $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); - $compression_algorithm = $this->_array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); - if ($compression_algorithm === false) { - user_error('No compatible client to server compression algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - //$this->decompress = $compression_algorithm == 'zlib'; - - $compression_algorithm = $this->_array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_client_to_server); - if ($compression_algorithm === false) { - user_error('No compatible server to client compression algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - //$this->compress = $compression_algorithm == 'zlib'; - return true; } @@ -2112,8 +2131,6 @@ class SSH2 * The $password parameter can be a plaintext password, a \phpseclib\Crypt\RSA object or an array * * @param string $username - * @param mixed $password - * @param mixed $... * @return bool * @see self::_login() * @access public @@ -2125,11 +2142,13 @@ class SSH2 // try logging with 'none' as an authentication method first since that's what // PuTTY does - if ($this->_login($username)) { - return true; - } - if (count($args) == 1) { - return false; + if (substr($this->server_identifier, 0, 13) != 'SSH-2.0-CoreFTP' && $this->auth_methods_to_continue === null) { + if ($this->_login($username)) { + return true; + } + if (count($args) == 1) { + return false; + } } return call_user_func_array(array(&$this, '_login'), $args); } @@ -2138,8 +2157,6 @@ class SSH2 * Login Helper * * @param string $username - * @param mixed $password - * @param mixed $... * @return bool * @see self::_login_helper() * @access private @@ -2269,7 +2286,9 @@ class SSH2 case NET_SSH2_MSG_USERAUTH_SUCCESS: $this->bitmap |= self::MASK_LOGIN; return true; - //case NET_SSH2_MSG_USERAUTH_FAILURE: + case NET_SSH2_MSG_USERAUTH_FAILURE: + extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4))); + $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen)); default: return false; } @@ -2341,6 +2360,7 @@ class SSH2 } extract(unpack('Nlength', $this->_string_shift($response, 4))); $auth_methods = explode(',', $this->_string_shift($response, $length)); + $this->auth_methods_to_continue = $auth_methods; if (!strlen($response)) { return false; } @@ -2400,7 +2420,6 @@ class SSH2 /** * Handle the keyboard-interactive requests / responses. * - * @param string $responses... * @return bool * @access private */ @@ -2514,6 +2533,8 @@ class SSH2 case NET_SSH2_MSG_USERAUTH_SUCCESS: return true; case NET_SSH2_MSG_USERAUTH_FAILURE: + extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4))); + $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen)); return false; } @@ -2545,7 +2566,7 @@ class SSH2 * Login with an RSA private key * * @param string $username - * @param \phpseclib\Crypt\RSA $password + * @param \phpseclib\Crypt\RSA $privatekey * @return bool * @access private * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} @@ -2622,13 +2643,21 @@ class SSH2 if (strlen($response) < 4) { return false; } - extract(unpack('Nlength', $this->_string_shift($response, 4))); - $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . $this->_string_shift($response, $length); + extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4))); + $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen)); + $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE'; return false; case NET_SSH2_MSG_USERAUTH_PK_OK: // we'll just take it on faith that the public key blob and the public key algorithm name are as // they should be $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); + break; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + default: + user_error('Unexpected response to publickey authentication pt 1'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } $packet = $part1 . chr(1) . $part2; @@ -2657,13 +2686,16 @@ class SSH2 switch ($type) { case NET_SSH2_MSG_USERAUTH_FAILURE: // either the login is bad or the server employs multi-factor authentication + extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4))); + $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen)); return false; case NET_SSH2_MSG_USERAUTH_SUCCESS: $this->bitmap |= self::MASK_LOGIN; return true; } - return false; + user_error('Unexpected response to publickey authentication pt 2'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } /** @@ -2680,6 +2712,19 @@ class SSH2 $this->timeout = $this->curTimeout = $timeout; } + /** + * Set Keep Alive + * + * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. + * + * @param int $interval + * @access public + */ + function setKeepAlive($interval) + { + $this->keepAlive = $interval; + } + /** * Get the output from stdError * @@ -2909,28 +2954,6 @@ class SSH2 return false; } - $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (!strlen($response)) { - return false; - } - list(, $type) = unpack('C', $this->_string_shift($response, 1)); - - switch ($type) { - case NET_SSH2_MSG_CHANNEL_SUCCESS: - // if a pty can't be opened maybe commands can still be executed - case NET_SSH2_MSG_CHANNEL_FAILURE: - break; - default: - user_error('Unable to request pseudo-terminal'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - $packet = pack( 'CNNa*C', NET_SSH2_MSG_CHANNEL_REQUEST, @@ -2943,14 +2966,7 @@ class SSH2 return false; } - $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST; - - $response = $this->_get_channel_packet(self::CHANNEL_SHELL); - if ($response === false) { - return false; - } - - $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA; + $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_IGNORE; $this->bitmap |= self::MASK_SHELL; @@ -3004,7 +3020,7 @@ class SSH2 * @see self::write() * @param string $expect * @param int $mode - * @return string + * @return string|bool * @access public */ function read($expect = '', $mode = self::READ_SIMPLE) @@ -3318,6 +3334,54 @@ class SSH2 */ function _get_binary_packet($skip_channel_filter = false) { + if ($skip_channel_filter) { + $read = array($this->fsock); + $write = $except = null; + + if (!$this->curTimeout) { + if ($this->keepAlive <= 0) { + @stream_select($read, $write, $except, null); + } else { + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + return $this->_get_binary_packet(true); + } + } + } else { + if ($this->curTimeout < 0) { + $this->is_timeout = true; + return true; + } + + $read = array($this->fsock); + $write = $except = null; + + $start = microtime(true); + + if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + $elapsed = microtime(true) - $start; + $this->curTimeout-= $elapsed; + return $this->_get_binary_packet(true); + } + $elapsed = microtime(true) - $start; + $this->curTimeout-= $elapsed; + } + + $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; + } + } + if (!is_resource($this->fsock) || feof($this->fsock)) { $this->bitmap = 0; user_error('Connection closed prematurely'); @@ -3468,10 +3532,24 @@ class SSH2 // only called when we've already logged in if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) { + if (is_bool($payload)) { + return $payload; + } + switch (ord($payload[0])) { + case NET_SSH2_MSG_CHANNEL_REQUEST: + if (strlen($payload) == 31) { + extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); + if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { + if (ord(substr($payload, 9 + $length))) { // want reply + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); + } + $payload = $this->_get_binary_packet($skip_channel_filter); + } + } + break; 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)) { @@ -3651,8 +3729,9 @@ class SSH2 * * Returns the data as a string if it's available and false if not. * - * @param $client_channel - * @return mixed + * @param int $client_channel + * @param bool $skip_extended + * @return mixed|bool * @access private */ function _get_channel_packet($client_channel, $skip_extended = false) @@ -3666,36 +3745,13 @@ class SSH2 $response = $this->binary_packet_buffer; $this->binary_packet_buffer = false; } else { - $read = array($this->fsock); - $write = $except = null; - - if (!$this->curTimeout) { - @stream_select($read, $write, $except, null); - } else { - 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; - if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { - $this->_close_channel($client_channel); - } - return true; - } - $elapsed = microtime(true) - $start; - $this->curTimeout-= $elapsed; - } - $response = $this->_get_binary_packet(true); + if ($response === true && $this->is_timeout) { + if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { + $this->_close_channel($client_channel); + } + return true; + } if ($response === false) { $this->bitmap = 0; user_error('Connection closed by server'); @@ -3843,6 +3899,16 @@ class SSH2 return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } break; + case NET_SSH2_MSG_IGNORE: + switch ($type) { + case NET_SSH2_MSG_CHANNEL_SUCCESS: + //$this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_DATA; + continue 3; + case NET_SSH2_MSG_CHANNEL_FAILURE: + user_error('Error opening channel'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + } + break; case NET_SSH2_MSG_CHANNEL_REQUEST: switch ($type) { case NET_SSH2_MSG_CHANNEL_SUCCESS: @@ -3862,6 +3928,10 @@ class SSH2 switch ($type) { case NET_SSH2_MSG_CHANNEL_DATA: + //if ($this->channel_status[$channel] == NET_SSH2_MSG_IGNORE) { + // $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_DATA; + //} + /* if ($channel == self::CHANNEL_EXEC) { // SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server @@ -3894,7 +3964,7 @@ class SSH2 $this->channel_buffers[$channel][] = $data; break; case NET_SSH2_MSG_CHANNEL_CLOSE: - $this->curTimeout = 0; + $this->curTimeout = 5; if ($this->bitmap & self::MASK_SHELL) { $this->bitmap&= ~self::MASK_SHELL; @@ -3962,7 +4032,7 @@ class SSH2 $packet.= $hmac; $start = microtime(true); - $result = strlen($packet) == fputs($this->fsock, $packet); + $result = strlen($packet) == @fputs($this->fsock, $packet); $stop = microtime(true); if (defined('NET_SSH2_LOGGING')) { @@ -3982,7 +4052,8 @@ class SSH2 * * Makes sure that only the last 1MB worth of packets will be logged * - * @param string $data + * @param string $message_number + * @param string $message * @access private */ function _append_log($message_number, $message) @@ -4123,11 +4194,15 @@ class SSH2 $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE; - $this->curTimeout = 0; + $this->curTimeout = 5; while (!is_bool($this->_get_channel_packet($client_channel))) { } + if ($this->is_timeout) { + $this->disconnect(); + } + if ($want_reply) { $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); } @@ -4183,7 +4258,6 @@ class SSH2 * named constants from it, using the value as the name of the constant and the index as the value of the constant. * If any of the constants that would be defined already exists, none of the constants will be defined. * - * @param array $array * @access private */ function _define_array() @@ -4599,11 +4673,15 @@ class SSH2 //'none' // OPTIONAL no encryption; NOT RECOMMENDED ); - $engines = array( - Base::ENGINE_OPENSSL, - Base::ENGINE_MCRYPT, - Base::ENGINE_INTERNAL - ); + if ($this->crypto_engine) { + $engines = array($this->crypto_engine); + } else { + $engines = array( + Base::ENGINE_OPENSSL, + Base::ENGINE_MCRYPT, + Base::ENGINE_INTERNAL + ); + } $ciphers = array(); foreach ($engines as $engine) { @@ -5088,4 +5166,15 @@ class SSH2 ); } } + + /** + * Return the list of authentication methods that may productively continue authentication. + * + * @see https://tools.ietf.org/html/rfc4252#section-5.1 + * @return array|null + */ + public function getAuthMethodsToContinue() + { + return $this->auth_methods_to_continue; + } }