From 3cb0248f9977ddd8c83c03a6a87df5f1736741ed Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 15 Jul 2015 12:50:57 -0500 Subject: [PATCH 01/16] Crypt/Base: add initial exception support To accomodate this decrypt() can no longer return false. If padding is enabled and the padding length is invalid (the only condition under which false was returned) an InvalidInputException will be thrown. Also, previously, when encrypting, if the padding was disabled and the plaintext wasn't a multiple of the block size a E_USER_NOTICE would be issued via user_error() and then padding would be enabled. Now it's not enabled - an exception is thrown suggesting that you might want to enable padding and that's that. --- phpseclib/Crypt/Base.php | 10 +++++----- phpseclib/Exception/InvalidInputException.php | 19 +++++++++++++++++++ .../Exception/KeyGenerationException.php | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 phpseclib/Exception/InvalidInputException.php create mode 100644 phpseclib/Exception/KeyGenerationException.php diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index c14cbf3e..51d68026 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -37,6 +37,8 @@ namespace phpseclib\Crypt; use phpseclib\Crypt\Hash; +use phpseclib\Exception\InvalidInputException; +use phpseclib\Exception\KeyGenerationException; /** * Base Class for all \phpseclib\Crypt\* cipher classes @@ -579,8 +581,7 @@ abstract class Base $hashObj = new Hash(); $hashObj->setHash($hash); if ($dkLen > $hashObj->getLength()) { - user_error('Derived key too long'); - return false; + throw new KeyGenerationException('Derived key too long'); } $t = $password . $salt; for ($i = 0; $i < $count; ++$i) { @@ -1779,8 +1780,7 @@ abstract class Base if ($length % $this->block_size == 0) { return $text; } else { - user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})"); - $this->padding = true; + throw new InvalidInputException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); } } @@ -1809,7 +1809,7 @@ abstract class Base $length = ord($text[strlen($text) - 1]); if (!$length || $length > $this->block_size) { - return false; + throw new InvalidInputException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})"); } return substr($text, 0, -$length); diff --git a/phpseclib/Exception/InvalidInputException.php b/phpseclib/Exception/InvalidInputException.php new file mode 100644 index 00000000..511f62b6 --- /dev/null +++ b/phpseclib/Exception/InvalidInputException.php @@ -0,0 +1,19 @@ + Date: Wed, 15 Jul 2015 13:23:22 -0500 Subject: [PATCH 02/16] Exceptions: CS adjustment --- phpseclib/Exception/InvalidInputException.php | 2 +- phpseclib/Exception/KeyGenerationException.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpseclib/Exception/InvalidInputException.php b/phpseclib/Exception/InvalidInputException.php index 511f62b6..1e76d6ff 100644 --- a/phpseclib/Exception/InvalidInputException.php +++ b/phpseclib/Exception/InvalidInputException.php @@ -16,4 +16,4 @@ namespace phpseclib\Exception; class InvalidInputException extends \Exception { -} \ No newline at end of file +} diff --git a/phpseclib/Exception/KeyGenerationException.php b/phpseclib/Exception/KeyGenerationException.php index 962d830e..43d90776 100644 --- a/phpseclib/Exception/KeyGenerationException.php +++ b/phpseclib/Exception/KeyGenerationException.php @@ -16,4 +16,4 @@ namespace phpseclib\Exception; class KeyGenerationException extends \Exception { -} \ No newline at end of file +} From 51700b60651a101396d90e593c3eaa9a56c9d003 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 15 Jul 2015 13:44:48 -0500 Subject: [PATCH 03/16] Exceptions: more CS adjustments --- phpseclib/Exception/InvalidInputException.php | 7 +++++++ phpseclib/Exception/KeyGenerationException.php | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/phpseclib/Exception/InvalidInputException.php b/phpseclib/Exception/InvalidInputException.php index 1e76d6ff..5dfd8305 100644 --- a/phpseclib/Exception/InvalidInputException.php +++ b/phpseclib/Exception/InvalidInputException.php @@ -7,6 +7,7 @@ * * @category Exception * @package InvalidInputException + * @author Jim Wigginton * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net @@ -14,6 +15,12 @@ namespace phpseclib\Exception; +/** + * InvalidInputException + * + * @package InvalidInputException + * @author Jim Wigginton + */ class InvalidInputException extends \Exception { } diff --git a/phpseclib/Exception/KeyGenerationException.php b/phpseclib/Exception/KeyGenerationException.php index 43d90776..d8171ef4 100644 --- a/phpseclib/Exception/KeyGenerationException.php +++ b/phpseclib/Exception/KeyGenerationException.php @@ -7,6 +7,7 @@ * * @category Exception * @package KeyGenerationException + * @author Jim Wigginton * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net @@ -14,6 +15,12 @@ namespace phpseclib\Exception; +/** + * KeyGenerationException + * + * @package InvalidInputException + * @author Jim Wigginton + */ class KeyGenerationException extends \Exception { } From 0565700461d5cbac83559129becb8eda34d6d559 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 17 Jul 2015 23:23:24 -0500 Subject: [PATCH 04/16] Crypt/Base: use the built-in spl exceptions instead --- phpseclib/Crypt/Base.php | 11 ++++---- phpseclib/Exception/InvalidInputException.php | 26 ------------------- .../Exception/KeyGenerationException.php | 26 ------------------- 3 files changed, 6 insertions(+), 57 deletions(-) delete mode 100644 phpseclib/Exception/InvalidInputException.php delete mode 100644 phpseclib/Exception/KeyGenerationException.php diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 51d68026..2021c00c 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -37,8 +37,6 @@ namespace phpseclib\Crypt; use phpseclib\Crypt\Hash; -use phpseclib\Exception\InvalidInputException; -use phpseclib\Exception\KeyGenerationException; /** * Base Class for all \phpseclib\Crypt\* cipher classes @@ -547,6 +545,7 @@ abstract class Base * @see Crypt/Hash.php * @param String $password * @param optional String $method + * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length * @return Boolean * @access public * @internal Could, but not must, extend by the child Crypt_* class @@ -581,7 +580,7 @@ abstract class Base $hashObj = new Hash(); $hashObj->setHash($hash); if ($dkLen > $hashObj->getLength()) { - throw new KeyGenerationException('Derived key too long'); + throw new \LengthException('Derived key length cannot be longer than the hash length'); } $t = $password . $salt; for ($i = 0; $i < $count; ++$i) { @@ -1769,6 +1768,7 @@ abstract class Base * * @see \phpseclib\Crypt\Base::_unpad() * @param String $text + * @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size * @access private * @return String */ @@ -1780,7 +1780,7 @@ abstract class Base if ($length % $this->block_size == 0) { return $text; } else { - throw new InvalidInputException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); + throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); } } @@ -1797,6 +1797,7 @@ abstract class Base * * @see \phpseclib\Crypt\Base::_pad() * @param String $text + * @throws \LengthException if the ciphertext's length is not a multiple of the block size * @access private * @return String */ @@ -1809,7 +1810,7 @@ abstract class Base $length = ord($text[strlen($text) - 1]); if (!$length || $length > $this->block_size) { - throw new InvalidInputException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})"); + throw new \LengthException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})"); } return substr($text, 0, -$length); diff --git a/phpseclib/Exception/InvalidInputException.php b/phpseclib/Exception/InvalidInputException.php deleted file mode 100644 index 5dfd8305..00000000 --- a/phpseclib/Exception/InvalidInputException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib\Exception; - -/** - * InvalidInputException - * - * @package InvalidInputException - * @author Jim Wigginton - */ -class InvalidInputException extends \Exception -{ -} diff --git a/phpseclib/Exception/KeyGenerationException.php b/phpseclib/Exception/KeyGenerationException.php deleted file mode 100644 index d8171ef4..00000000 --- a/phpseclib/Exception/KeyGenerationException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib\Exception; - -/** - * KeyGenerationException - * - * @package InvalidInputException - * @author Jim Wigginton - */ -class KeyGenerationException extends \Exception -{ -} From 081f2cb82534495ba6a6c93cf47806bba4cf911e Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 18 Jul 2015 00:50:59 -0500 Subject: [PATCH 05/16] Random: replace user_error with exception --- phpseclib/Crypt/Random.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpseclib/Crypt/Random.php b/phpseclib/Crypt/Random.php index cc134d63..1bcffe4d 100644 --- a/phpseclib/Crypt/Random.php +++ b/phpseclib/Crypt/Random.php @@ -49,6 +49,7 @@ class Random * eg. for RSA key generation. * * @param Integer $length + * @throws \RuntimeException if a symmetric cipher is needed but not loaded * @return String */ public static function string($length) @@ -199,8 +200,7 @@ class Random $crypto = new RC4(); break; default: - user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded'); - return false; + throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded'); } $crypto->setKey($key); From ebe9301efad23dde49677700e11951b7af6be5fa Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 28 Jul 2015 19:41:32 -0500 Subject: [PATCH 06/16] RSA: replace user_error's with Exceptions --- phpseclib/Crypt/RSA.php | 90 +++++++++------------ phpseclib/Exception/DecryptionException.php | 26 ++++++ 2 files changed, 66 insertions(+), 50 deletions(-) create mode 100644 phpseclib/Exception/DecryptionException.php diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 049ef222..34f65fe7 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -2010,14 +2010,14 @@ class RSA * @access private * @param \phpseclib\Math\BigInteger $x * @param Integer $xLen + * @throws \OutOfBoundsException if strlen($x) > $xLen * @return String */ function _i2osp($x, $xLen) { $x = $x->toBytes(); if (strlen($x) > $xLen) { - user_error('Integer too large'); - return false; + throw new \OutOfBoundsException('Integer too large'); } return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); } @@ -2172,13 +2172,13 @@ class RSA * * @access private * @param \phpseclib\Math\BigInteger $m + * @throws \OutOfRangeException if $m < 0 or $m > $this->modulus * @return \phpseclib\Math\BigInteger */ function _rsaep($m) { if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) { - user_error('Message representative out of range'); - return false; + throw new \OutOfRangeException('Message representative out of range'); } return $this->_exponentiate($m); } @@ -2190,13 +2190,13 @@ class RSA * * @access private * @param \phpseclib\Math\BigInteger $c + * @throws \OutOfRangeException if $c < 0 or $c > $this->modulus * @return \phpseclib\Math\BigInteger */ function _rsadp($c) { if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) { - user_error('Ciphertext representative out of range'); - return false; + throw new \OutOfRangeException('Ciphertext representative out of range'); } return $this->_exponentiate($c); } @@ -2208,13 +2208,13 @@ class RSA * * @access private * @param \phpseclib\Math\BigInteger $m + * @throws \OutOfRangeException if $m < 0 or $m > $this->modulus * @return \phpseclib\Math\BigInteger */ function _rsasp1($m) { if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) { - user_error('Message representative out of range'); - return false; + throw new \OutOfRangeException('Message representative out of range'); } return $this->_exponentiate($m); } @@ -2226,13 +2226,13 @@ class RSA * * @access private * @param \phpseclib\Math\BigInteger $s + * @throws \OutOfRangeException if $s < 0 or $s > $this->modulus * @return \phpseclib\Math\BigInteger */ function _rsavp1($s) { if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) { - user_error('Signature representative out of range'); - return false; + throw new \OutOfRangeException('Signature representative out of range'); } return $this->_exponentiate($s); } @@ -2270,6 +2270,7 @@ class RSA * @access private * @param String $m * @param String $l + * @throws \OutOfBoundsException if strlen($m) > $this->k - 2 * $this->hLen - 2 * @return String */ function _rsaes_oaep_encrypt($m, $l = '') @@ -2282,8 +2283,7 @@ class RSA // be output. if ($mLen > $this->k - 2 * $this->hLen - 2) { - user_error('Message too long'); - return false; + throw new \OutOfBoundsException('Message too long'); } // EME-OAEP encoding @@ -2333,6 +2333,7 @@ class RSA * @access private * @param String $c * @param String $l + * @throws \RuntimeException on decryption error * @return String */ function _rsaes_oaep_decrypt($c, $l = '') @@ -2343,8 +2344,7 @@ class RSA // be output. if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { - user_error('Decryption error'); - return false; + throw new \RuntimeException('Decryption error'); } // RSA decryption @@ -2352,8 +2352,7 @@ class RSA $c = $this->_os2ip($c); $m = $this->_rsadp($c); if ($m === false) { - user_error('Decryption error'); - return false; + throw new \RuntimeException('Decryption error'); } $em = $this->_i2osp($m, $this->k); @@ -2370,13 +2369,11 @@ class RSA $lHash2 = substr($db, 0, $this->hLen); $m = substr($db, $this->hLen); if ($lHash != $lHash2) { - user_error('Decryption error'); - return false; + throw new \RuntimeException('Decryption error'); } $m = ltrim($m, chr(0)); if (ord($m[0]) != 1) { - user_error('Decryption error'); - return false; + throw new \RuntimeException('Decryption error'); } // Output the message M @@ -2407,6 +2404,7 @@ class RSA * * @access private * @param String $m + * @throws \OutOfBoundsException if strlen($m) > $this->k - 11 * @return String */ function _rsaes_pkcs1_v1_5_encrypt($m) @@ -2416,8 +2414,7 @@ class RSA // Length checking if ($mLen > $this->k - 11) { - user_error('Message too long'); - return false; + throw new \OutOfBoundsException('Message too long'); } // EME-PKCS1-v1_5 encoding @@ -2466,6 +2463,7 @@ class RSA * * @access private * @param String $c + * @throws \RuntimeException on decryption error * @return String */ function _rsaes_pkcs1_v1_5_decrypt($c) @@ -2473,8 +2471,7 @@ class RSA // Length checking if (strlen($c) != $this->k) { // or if k < 11 - user_error('Decryption error'); - return false; + throw new \RuntimeException('Decryption error'); } // RSA decryption @@ -2483,24 +2480,21 @@ class RSA $m = $this->_rsadp($c); if ($m === false) { - user_error('Decryption error'); - return false; + throw new \RuntimeException('Decryption error'); } $em = $this->_i2osp($m, $this->k); // EME-PKCS1-v1_5 decoding if (ord($em[0]) != 0 || ord($em[1]) > 2) { - user_error('Decryption error'); - return false; + throw new \RuntimeException('Decryption error'); } $ps = substr($em, 2, strpos($em, chr(0), 2) - 2); $m = substr($em, strlen($ps) + 3); if (strlen($ps) < 8) { - user_error('Decryption error'); - return false; + throw new \RuntimeException('Decryption error'); } // Output M @@ -2515,6 +2509,7 @@ class RSA * * @access private * @param String $m + * @throws \RuntimeException on encoding error * @param Integer $emBits */ function _emsa_pss_encode($m, $emBits) @@ -2527,8 +2522,7 @@ class RSA $mHash = $this->hash->hash($m); if ($emLen < $this->hLen + $sLen + 2) { - user_error('Encoding error'); - return false; + throw new \RuntimeException('Encoding error'); } $salt = Random::string($sLen); @@ -2625,6 +2619,7 @@ class RSA * @access private * @param String $m * @param String $s + * @throws \RuntimeException on invalid signature * @return String */ function _rsassa_pss_verify($m, $s) @@ -2632,8 +2627,7 @@ class RSA // Length checking if (strlen($s) != $this->k) { - user_error('Invalid signature'); - return false; + throw new \RuntimeException('Invalid signature'); } // RSA verification @@ -2643,13 +2637,11 @@ class RSA $s2 = $this->_os2ip($s); $m2 = $this->_rsavp1($s2); if ($m2 === false) { - user_error('Invalid signature'); - return false; + throw new \RuntimeException('Invalid signature'); } $em = $this->_i2osp($m2, $modBits >> 3); if ($em === false) { - user_error('Invalid signature'); - return false; + throw new \RuntimeException('Invalid signature'); } // EMSA-PSS verification @@ -2665,6 +2657,7 @@ class RSA * @access private * @param String $m * @param Integer $emLen + * @throws \LengthException if the intended encoded message length is too short * @return String */ function _emsa_pkcs1_v1_5_encode($m, $emLen) @@ -2698,8 +2691,7 @@ class RSA $tLen = strlen($t); if ($emLen < $tLen + 11) { - user_error('Intended encoded message length too short'); - return false; + throw new \LengthException('Intended encoded message length too short'); } $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); @@ -2716,6 +2708,7 @@ class RSA * * @access private * @param String $m + * @throws \LengthException if the RSA modulus is too short * @return String */ function _rsassa_pkcs1_v1_5_sign($m) @@ -2724,8 +2717,7 @@ class RSA $em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); if ($em === false) { - user_error('RSA modulus too short'); - return false; + throw new \LengthException('RSA modulus too short'); } // RSA signature @@ -2746,6 +2738,8 @@ class RSA * * @access private * @param String $m + * @throws \RuntimeException if the signature is invalid + * @throws \LengthException if the RSA modulus is too short * @return String */ function _rsassa_pkcs1_v1_5_verify($m, $s) @@ -2753,8 +2747,7 @@ class RSA // Length checking if (strlen($s) != $this->k) { - user_error('Invalid signature'); - return false; + throw new \RuntimeSignature('Invalid signature'); } // RSA verification @@ -2762,21 +2755,18 @@ class RSA $s = $this->_os2ip($s); $m2 = $this->_rsavp1($s); if ($m2 === false) { - user_error('Invalid signature'); - return false; + throw new \RuntimeSignature('Invalid signature'); } $em = $this->_i2osp($m2, $this->k); if ($em === false) { - user_error('Invalid signature'); - return false; + throw new \RuntimeSignature('Invalid signature'); } // EMSA-PKCS1-v1_5 encoding $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); if ($em2 === false) { - user_error('RSA modulus too short'); - return false; + throw new \LengthException('RSA modulus too short'); } // Compare diff --git a/phpseclib/Exception/DecryptionException.php b/phpseclib/Exception/DecryptionException.php new file mode 100644 index 00000000..edc7963d --- /dev/null +++ b/phpseclib/Exception/DecryptionException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Exception; + +/** + * KeyGenerationException + * + * @package DecryptionException + * @author Jim Wigginton + */ +class DecryptionException extends \Exception +{ +} From e264a3835e2926174d98cbee8a7220b658498dee Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 28 Jul 2015 20:17:32 -0500 Subject: [PATCH 07/16] rm unused exception --- phpseclib/Exception/DecryptionException.php | 26 --------------------- 1 file changed, 26 deletions(-) delete mode 100644 phpseclib/Exception/DecryptionException.php diff --git a/phpseclib/Exception/DecryptionException.php b/phpseclib/Exception/DecryptionException.php deleted file mode 100644 index edc7963d..00000000 --- a/phpseclib/Exception/DecryptionException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib\Exception; - -/** - * KeyGenerationException - * - * @package DecryptionException - * @author Jim Wigginton - */ -class DecryptionException extends \Exception -{ -} From 80d84d10091091196bed72dff127185a48dee469 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 30 Jul 2015 07:33:19 -0500 Subject: [PATCH 08/16] ASN1/X509: throw exceptions instead of user_errors --- .../UnsupportedAlgorithmException.php | 26 +++++++++++++++++++ phpseclib/File/ASN1.php | 7 ++--- phpseclib/File/X509.php | 20 +++++++++----- 3 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 phpseclib/Exception/UnsupportedAlgorithmException.php diff --git a/phpseclib/Exception/UnsupportedAlgorithmException.php b/phpseclib/Exception/UnsupportedAlgorithmException.php new file mode 100644 index 00000000..47cc41d4 --- /dev/null +++ b/phpseclib/Exception/UnsupportedAlgorithmException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Exception; + +/** + * UnsupportedAlgorithmException + * + * @package UnsupportedAlgorithmException + * @author Jim Wigginton + */ +class UnsupportedAlgorithmException extends \RuntimeException +{ +} diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 6fb59a7c..acfa5be8 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -793,6 +793,7 @@ class ASN1 * @param String $mapping * @param Integer $idx * @return String + * @throws \RuntimeException if the input has an error in it * @access private */ function _encode_der($source, $mapping, $idx = null, $special = array()) @@ -985,7 +986,7 @@ class ASN1 case self::TYPE_OBJECT_IDENTIFIER: $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids); if ($oid === false) { - user_error('Invalid OID'); + throw new \RuntimeException('Invalid OID'); return false; } $value = ''; @@ -1038,7 +1039,7 @@ class ASN1 $filters = $filters[$part]; } if ($filters === false) { - user_error('No filters defined for ' . implode('/', $loc)); + throw new \RuntimeException('No filters defined for ' . implode('/', $loc)); return false; } return $this->_encode_der($source, $filters + $mapping, null, $special); @@ -1062,7 +1063,7 @@ class ASN1 $value = $source ? "\xFF" : "\x00"; break; default: - user_error('Mapping provides no type definition for ' . implode('/', $this->location)); + throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', $this->location)); return false; } diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index af46790f..b50e7247 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -31,6 +31,7 @@ use phpseclib\Crypt\RSA; use phpseclib\File\ASN1; use phpseclib\File\ASN1\Element; use phpseclib\Math\BigInteger; +use phpseclib\Exception\UnsupportedAlgorithmException; /** * Pure-PHP X.509 Parser @@ -1640,7 +1641,7 @@ class X509 $map = $this->_getMapping($id); if (is_bool($map)) { if (!$map) { - user_error($id . ' is not a currently supported extension'); + //user_error($id . ' is not a currently supported extension'); unset($extensions[$i]); } } else { @@ -1713,7 +1714,7 @@ class X509 $id = $attributes[$i]['type']; $map = $this->_getMapping($id); if ($map === false) { - user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); + //user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); unset($attributes[$i]); } elseif (is_array($attributes[$i]['value'])) { $values = &$attributes[$i]['value']; @@ -2106,7 +2107,8 @@ class X509 /** * Validates a signature * - * Returns true if the signature is verified, false if it is not correct or null on error + * Returns true if the signature is verified and false if it is not correct. + * If the algorithms are unsupposed an exception is thrown. * * @param String $publicKeyAlgorithm * @param String $publicKey @@ -2114,7 +2116,8 @@ class X509 * @param String $signature * @param String $signatureSubject * @access private - * @return Integer + * @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + * @return Boolean */ function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject) { @@ -2138,11 +2141,11 @@ class X509 } break; default: - return null; + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); } break; default: - return null; + throw new UnsupportedAlgorithmException('Public key algorithm unsupported'); } return true; @@ -3611,6 +3614,7 @@ class X509 * @param \phpseclib\File\X509 $subject * @param String $signatureAlgorithm * @access public + * @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported * @return Mixed */ function _sign($key, $signatureAlgorithm) @@ -3629,10 +3633,12 @@ class X509 $this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject)); return $this->currentCert; + default: + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); } } - return false; + throw new UnsupportedAlgorithmException('Unsupported public key algorithm'); } /** From f300e825b0c5018415aed803f7e0d24757a35f58 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 1 Aug 2015 08:01:43 -0500 Subject: [PATCH 09/16] SSH2: replace user_error's with exceptions --- .../NoSupportedAlgorithmsException.php | 26 +++ phpseclib/Net/SSH2.php | 177 +++++++++--------- 2 files changed, 111 insertions(+), 92 deletions(-) create mode 100644 phpseclib/Exception/NoSupportedAlgorithmsException.php diff --git a/phpseclib/Exception/NoSupportedAlgorithmsException.php b/phpseclib/Exception/NoSupportedAlgorithmsException.php new file mode 100644 index 00000000..19182fb4 --- /dev/null +++ b/phpseclib/Exception/NoSupportedAlgorithmsException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Exception; + +/** + * NoSupportedAlgorithmsException + * + * @package NoSupportedAlgorithmsException + * @author Jim Wigginton + */ +class NoSupportedAlgorithmsException extends \RuntimeException +{ +} diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index d6e13adb..4c0e33e9 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -60,6 +60,7 @@ use phpseclib\Crypt\TripleDES; use phpseclib\Crypt\Twofish; use phpseclib\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification. use phpseclib\System\SSH\Agent; +use phpseclib\Exception\NoSupportedAlgorithmsException; /** * Pure-PHP implementation of SSHv2. @@ -977,6 +978,8 @@ class SSH2 * Connect to an SSHv2 server * * @return Boolean + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors * @access private */ function _connect() @@ -996,8 +999,7 @@ class SSH2 $start = microtime(true); $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout); if (!$this->fsock) { - user_error(rtrim("Cannot connect to $host. Error $errno. $errstr")); - return false; + throw new \RuntimeException(rtrim("Cannot connect to $host. Error $errno. $errstr"))_; } $elapsed = microtime(true) - $start; @@ -1047,8 +1049,7 @@ class SSH2 } if (feof($this->fsock)) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } $this->identifier = $this->_generate_identifier(); @@ -1064,21 +1065,18 @@ class SSH2 } if ($matches[1] != '1.99' && $matches[1] != '2.0') { - user_error("Cannot connect to SSH $matches[1] servers"); - return false; + throw new \RuntimeException("Cannot connect to SSH $matches[1] servers"); } fputs($this->fsock, $this->identifier . "\r\n"); $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) { - user_error('Expected SSH_MSG_KEXINIT'); - return false; + throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); } if (!$this->_key_exchange($response)) { @@ -1126,6 +1124,9 @@ class SSH2 * Key Exchange * * @param String $kexinit_payload_server + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + * @throws \phpseclib\Exception\NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible * @access private */ function _key_exchange($kexinit_payload_server) @@ -1317,8 +1318,8 @@ class SSH2 // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_server_to_client); $i++); if ($i == count($encryption_algorithms)) { - user_error('No compatible server to client encryption algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new \RuntimeException('No compatible server to client encryption algorithms found'); } // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the @@ -1363,8 +1364,8 @@ class SSH2 for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_client_to_server); $i++); if ($i == count($encryption_algorithms)) { - user_error('No compatible client to server encryption algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found'); } $encrypt = $encryption_algorithms[$i]; @@ -1410,8 +1411,8 @@ class SSH2 // through diffie-hellman key exchange a symmetric key is obtained for ($i = 0; $i < count($kex_algorithms) && !in_array($kex_algorithms[$i], $this->kex_algorithms); $i++); if ($i == count($kex_algorithms)) { - user_error('No compatible key exchange algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found'); } if (strpos($kex_algorithms[$i], 'diffie-hellman-group-exchange') === 0) { @@ -1513,20 +1514,17 @@ class SSH2 $data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes); if (!$this->_send_binary_packet($data)) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } extract(unpack('Ctype', $this->_string_shift($response, 1))); if ($type != $serverKexReplyMessage) { - user_error('Expected SSH_MSG_KEXDH_REPLY'); - return false; + throw new \UnexpectedValueException('Expected SSH_MSG_KEXDH_REPLY'); } $temp = unpack('Nlength', $this->_string_shift($response, 4)); @@ -1568,13 +1566,13 @@ class SSH2 for ($i = 0; $i < count($server_host_key_algorithms) && !in_array($server_host_key_algorithms[$i], $this->server_host_key_algorithms); $i++); if ($i == count($server_host_key_algorithms)) { - user_error('No compatible server host key algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found'); } if ($public_key_format != $server_host_key_algorithms[$i] || $this->signature_format != $server_host_key_algorithms[$i]) { - user_error('Server Host Key Algorithm Mismatch'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new \RuntimeException('Server Host Key Algorithm Mismatch'); } $packet = pack('C', @@ -1588,15 +1586,13 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } extract(unpack('Ctype', $this->_string_shift($response, 1))); if ($type != NET_SSH2_MSG_NEWKEYS) { - user_error('Expected SSH_MSG_NEWKEYS'); - return false; + throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS'); } switch ($encrypt) { @@ -1757,8 +1753,8 @@ class SSH2 for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++); if ($i == count($mac_algorithms)) { - user_error('No compatible client to server message authentication algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found'); } $createKeyLength = 0; // ie. $mac_algorithms[$i] == 'none' @@ -1786,8 +1782,8 @@ class SSH2 for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_server_to_client); $i++); if ($i == count($mac_algorithms)) { - user_error('No compatible server to client message authentication algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found'); } $checkKeyLength = 0; @@ -1833,15 +1829,15 @@ class SSH2 for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_server_to_client); $i++); if ($i == count($compression_algorithms)) { - user_error('No compatible server to client compression algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found'); } $this->decompress = $compression_algorithms[$i] == 'zlib'; for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_client_to_server); $i++); if ($i == count($compression_algorithms)) { - user_error('No compatible client to server compression algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found'); } $this->compress = $compression_algorithms[$i] == 'zlib'; @@ -1903,6 +1899,8 @@ class SSH2 * @param String $username * @param optional String $password * @return Boolean + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors * @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} * by sending dummy SSH_MSG_IGNORE messages. @@ -1924,15 +1922,13 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } extract(unpack('Ctype', $this->_string_shift($response, 1))); if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) { - user_error('Expected SSH_MSG_SERVICE_ACCEPT'); - return false; + throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT'); } $this->bitmap |= self::MASK_LOGIN_REQ; } @@ -2004,8 +2000,7 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } extract(unpack('Ctype', $this->_string_shift($response, 1))); @@ -2071,6 +2066,7 @@ class SSH2 * * @param String $responses... * @return Boolean + * @throws \RuntimeException on connection error * @access private */ function _keyboard_interactive_process() @@ -2082,8 +2078,7 @@ class SSH2 } else { $orig = $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } } @@ -2207,6 +2202,7 @@ class SSH2 * @param String $username * @param \phpseclib\Crypt\RSA $password * @return Boolean + * @throws \RuntimeException on connection error * @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} * by sending dummy SSH_MSG_IGNORE messages. @@ -2240,8 +2236,7 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } extract(unpack('Ctype', $this->_string_shift($response, 1))); @@ -2275,8 +2270,7 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } extract(unpack('Ctype', $this->_string_shift($response, 1))); @@ -2326,6 +2320,7 @@ class SSH2 * @param String $command * @param optional Callback $callback * @return String + * @throws \RuntimeException on connection error * @access public */ function exec($command, $callback = null) @@ -2373,8 +2368,7 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } list(, $type) = unpack('C', $this->_string_shift($response, 1)); @@ -2384,8 +2378,8 @@ class SSH2 break; case NET_SSH2_MSG_CHANNEL_FAILURE: default: - user_error('Unable to request pseudo-terminal'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to request pseudo-terminal'); } $this->in_request_pty_exec = true; } @@ -2445,6 +2439,8 @@ class SSH2 * @see \phpseclib\Net\SSH2::read() * @see \phpseclib\Net\SSH2::write() * @return Boolean + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors * @access private */ function _initShell() @@ -2481,8 +2477,7 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } list(, $type) = unpack('C', $this->_string_shift($response, 1)); @@ -2493,8 +2488,8 @@ class SSH2 case NET_SSH2_MSG_CHANNEL_FAILURE: break; default: - user_error('Unable to request pseudo-terminal'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \UnexpectedValueException('Unable to request pseudo-terminal'); } $packet = pack('CNNa*C', @@ -2565,6 +2560,7 @@ class SSH2 * @param String $expect * @param Integer $mode * @return String + * @throws \RuntimeException on connection error * @access public */ function read($expect = '', $mode = self::READ_SIMPLE) @@ -2578,8 +2574,7 @@ class SSH2 } if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session'); - return false; + throw new \RuntimeException('Unable to initiate an interactive shell session'); } $channel = $this->_get_interactive_channel(); @@ -2610,18 +2605,17 @@ class SSH2 * @see \phpseclib\Net\SSH2::read() * @param String $cmd * @return Boolean + * @throws \RuntimeException on connection error * @access public */ function write($cmd) { if (!($this->bitmap & self::MASK_LOGIN)) { - user_error('Operation disallowed prior to login()'); - return false; + throw new \RuntimeException('Operation disallowed prior to login()'); } if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { - user_error('Unable to initiate an interactive shell session'); - return false; + throw new \RuntimeException('Unable to initiate an interactive shell session'); } return $this->_send_channel_packet($this->_get_interactive_channel(), $cmd); @@ -2763,14 +2757,14 @@ class SSH2 * * @see \phpseclib\Net\SSH2::_send_binary_packet() * @return String + * @throws \RuntimeException on connection errors * @access private */ function _get_binary_packet() { if (!is_resource($this->fsock) || feof($this->fsock)) { - user_error('Connection closed prematurely'); $this->bitmap = 0; - return false; + throw new \RuntimeException('Connection closed prematurely'); } $start = microtime(true); @@ -2796,17 +2790,15 @@ 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) { - user_error('Invalid size'); - return false; + throw new \RuntimeException('Invalid size'); } $buffer = ''; while ($remaining_length > 0) { $temp = fread($this->fsock, $remaining_length); if ($temp === false || feof($this->fsock)) { - user_error('Error reading from socket'); $this->bitmap = 0; - return false; + throw new \RuntimeException('Error reading from socket'); } $buffer.= $temp; $remaining_length-= strlen($temp); @@ -2822,12 +2814,10 @@ class SSH2 if ($this->hmac_check !== false) { $hmac = fread($this->fsock, $this->hmac_size); if ($hmac === false || strlen($hmac) != $this->hmac_size) { - user_error('Error reading socket'); $this->bitmap = 0; - return false; + throw new \RuntimeException('Error reading socket'); } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) { - user_error('Invalid HMAC'); - return false; + throw new \RuntimeException('Invalid HMAC'); } } @@ -3041,6 +3031,7 @@ class SSH2 * * @param $client_channel * @return Mixed + * @throws \RuntimeException on connection error * @access private */ function _get_channel_packet($client_channel, $skip_extended = false) @@ -3073,7 +3064,7 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); + throw new \RuntimeException('Connection closed by server'); return false; } if ($client_channel == -1 && $response === true) { @@ -3123,8 +3114,8 @@ class SSH2 return $result; //case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE: default: - user_error('Unable to open channel'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to open channel'); } break; case NET_SSH2_MSG_CHANNEL_REQUEST: @@ -3134,8 +3125,8 @@ class SSH2 case NET_SSH2_MSG_CHANNEL_FAILURE: return false; default: - user_error('Unable to fulfill channel request'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to fulfill channel request'); } case NET_SSH2_MSG_CHANNEL_CLOSE: return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended); @@ -3244,8 +3235,8 @@ class SSH2 case NET_SSH2_MSG_CHANNEL_EOF: break; default: - user_error('Error reading channel data'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Error reading channel data'); } } } @@ -3804,6 +3795,8 @@ class SSH2 * is recommended. Returns false if the server signature is not signed correctly with the public host key. * * @return Mixed + * @throws \RuntimeException on badly formatted keys + * @throws \phpseclib\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format * @access public */ function getServerPublicHostKey() @@ -3849,8 +3842,8 @@ class SSH2 padding, unsigned, and in network byte order). */ $temp = unpack('Nlength', $this->_string_shift($signature, 4)); if ($temp['length'] != 40) { - user_error('Invalid signature'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new \RuntimeException('Invalid signature'); } $r = new BigInteger($this->_string_shift($signature, 20), 256); @@ -3861,8 +3854,8 @@ class SSH2 case $r->compare($q) >= 0: case $s->equals($zero): case $s->compare($q) >= 0: - user_error('Invalid signature'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new \RuntimeException('Invalid signature'); } $w = $s->modInverse($q); @@ -3881,7 +3874,7 @@ class SSH2 list(, $v) = $v->divide($q); if (!$v->equals($r)) { - user_error('Bad server signature'); + //user_error('Bad server signature'); return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); } @@ -3903,7 +3896,7 @@ class SSH2 $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1); $rsa->loadKey(array('e' => $e, 'n' => $n), RSA::PUBLIC_FORMAT_RAW); if (!$rsa->verify($this->exchange_hash, $signature)) { - user_error('Bad server signature'); + //user_error('Bad server signature'); return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); } */ @@ -3918,8 +3911,8 @@ class SSH2 // also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source. if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) { - user_error('Invalid signature'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new \RuntimeException('Invalid signature'); } $s = $s->modPow($e, $n); @@ -3929,13 +3922,13 @@ class SSH2 $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h; if ($s != $h) { - user_error('Bad server signature'); + //user_error('Bad server signature'); return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); } break; default: - user_error('Unsupported signature format'); - return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + throw new NoSupportedAlgorithmsException('Unsupported signature format'); } return $this->signature_format . ' ' . base64_encode($this->server_public_host_key); From 453e6fcf1846ec8342e5188b73900320501a7b9b Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 31 Aug 2015 22:44:41 -0500 Subject: [PATCH 10/16] RSA: some of the exceptions being thrown weren't valid --- phpseclib/Crypt/RSA.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 34f65fe7..86b89dbc 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -2747,7 +2747,7 @@ class RSA // Length checking if (strlen($s) != $this->k) { - throw new \RuntimeSignature('Invalid signature'); + throw new \RuntimeException('Invalid signature'); } // RSA verification @@ -2755,11 +2755,11 @@ class RSA $s = $this->_os2ip($s); $m2 = $this->_rsavp1($s); if ($m2 === false) { - throw new \RuntimeSignature('Invalid signature'); + throw new \RuntimeException('Invalid signature'); } $em = $this->_i2osp($m2, $this->k); if ($em === false) { - throw new \RuntimeSignature('Invalid signature'); + throw new \RuntimeException('Invalid signature'); } // EMSA-PKCS1-v1_5 encoding From 2e46aec03af4a70a3deace9167d08f5633b124d5 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 31 Aug 2015 23:12:33 -0500 Subject: [PATCH 11/16] SFTP: replace user_error's with exceptions --- phpseclib/Exception/FileNotFoundException.php | 26 ++++++ phpseclib/Net/SFTP.php | 86 +++++++++---------- 2 files changed, 69 insertions(+), 43 deletions(-) create mode 100644 phpseclib/Exception/FileNotFoundException.php diff --git a/phpseclib/Exception/FileNotFoundException.php b/phpseclib/Exception/FileNotFoundException.php new file mode 100644 index 00000000..ea9755e5 --- /dev/null +++ b/phpseclib/Exception/FileNotFoundException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Exception; + +/** + * FileNotFoundException + * + * @package UnsupportedAlgorithmException + * @author Jim Wigginton + */ +class FileNotFoundException extends \RuntimeException +{ +} diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index dfd7d9f6..e22a6ae5 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -38,6 +38,7 @@ namespace phpseclib\Net; use phpseclib\Net\SSH2; +use phpseclib\Exception\FileNotFoundException; /** * Pure-PHP implementations of SFTP. @@ -383,6 +384,7 @@ class SFTP extends SSH2 * * @param String $username * @param optional String $password + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Boolean * @access public */ @@ -447,8 +449,7 @@ class SFTP extends SSH2 $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_VERSION) { - user_error('Expected SSH_FXP_VERSION'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_VERSION'); } extract(unpack('Nversion', $this->_string_shift($response, 4))); @@ -587,6 +588,7 @@ class SFTP extends SSH2 * * @see \phpseclib\Net\SFTP::chdir() * @param String $path + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Mixed * @access private */ @@ -611,8 +613,7 @@ class SFTP extends SSH2 $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); } } @@ -643,6 +644,7 @@ class SFTP extends SSH2 * Changes the current directory * * @param String $dir + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Boolean * @access public */ @@ -687,8 +689,7 @@ class SFTP extends SSH2 $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); } if (!$this->_close_handle($handle)) { @@ -790,6 +791,7 @@ class SFTP extends SSH2 * @param String $dir * @param optional Boolean $raw * @return Mixed + * @throws \UnexpectedValueException on receipt of unexpected packets * @access private */ function _list($dir, $raw = true) @@ -821,8 +823,7 @@ class SFTP extends SSH2 $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); } $this->_update_stat_cache($dir, array()); @@ -876,8 +877,7 @@ class SFTP extends SSH2 } break 2; default: - user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); } } @@ -1230,6 +1230,7 @@ class SFTP extends SSH2 * * @param String $filename * @param Integer $type + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Mixed * @access private */ @@ -1250,8 +1251,7 @@ class SFTP extends SSH2 return false; } - user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); } /** @@ -1277,6 +1277,7 @@ class SFTP extends SSH2 * @param String $filename * @param optional Integer $time * @param optional Integer $atime + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Boolean * @access public */ @@ -1313,8 +1314,7 @@ class SFTP extends SSH2 $this->_logError($response); break; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); } return $this->_setstat($filename, $attr, false); @@ -1367,6 +1367,7 @@ class SFTP extends SSH2 * @param Integer $mode * @param String $filename * @param optional Boolean $recursive + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Mixed * @access public */ @@ -1404,8 +1405,7 @@ class SFTP extends SSH2 return false; } - user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS'); } /** @@ -1414,6 +1414,7 @@ class SFTP extends SSH2 * @param String $filename * @param String $attr * @param Boolean $recursive + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Boolean * @access private */ @@ -1452,8 +1453,7 @@ class SFTP extends SSH2 */ $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_STATUS'); } extract(unpack('Nstatus', $this->_string_shift($response, 4))); @@ -1541,6 +1541,7 @@ class SFTP extends SSH2 * Return the target of a symbolic link * * @param String $link + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Mixed * @access public */ @@ -1564,8 +1565,7 @@ class SFTP extends SSH2 $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS'); } extract(unpack('Ncount', $this->_string_shift($response, 4))); @@ -1585,6 +1585,7 @@ class SFTP extends SSH2 * * @param String $target * @param String $link + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Boolean * @access public */ @@ -1604,8 +1605,7 @@ class SFTP extends SSH2 $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_STATUS'); } extract(unpack('Nstatus', $this->_string_shift($response, 4))); @@ -1657,6 +1657,7 @@ class SFTP extends SSH2 * * @param String $dir * @return Boolean + * @throws \UnexpectedValueException on receipt of unexpected packets * @access private */ function _mkdir_helper($dir, $attr) @@ -1667,8 +1668,7 @@ class SFTP extends SSH2 $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_STATUS'); } extract(unpack('Nstatus', $this->_string_shift($response, 4))); @@ -1684,6 +1684,7 @@ class SFTP extends SSH2 * Removes a directory. * * @param String $dir + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Boolean * @access public */ @@ -1704,8 +1705,7 @@ class SFTP extends SSH2 $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_STATUS'); } extract(unpack('Nstatus', $this->_string_shift($response, 4))); @@ -1765,6 +1765,9 @@ class SFTP extends SSH2 * @param optional Integer $start * @param optional Integer $local_start * @param optional callable|null $progressCallback + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid + * @throws \phpseclib\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist * @return Boolean * @access public * @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode(). @@ -1812,8 +1815,7 @@ class SFTP extends SSH2 $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3 @@ -1821,7 +1823,7 @@ class SFTP extends SSH2 switch (true) { case $mode & self::SOURCE_CALLBACK: if (!is_callable($data)) { - user_error("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); + throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); } $dataCallback = $data; // do nothing @@ -1832,8 +1834,7 @@ class SFTP extends SSH2 break; case $mode & self::SOURCE_LOCAL_FILE: if (!is_file($data)) { - user_error("$data is not a valid file"); - return false; + throw new FileNotFoundException("$data is not a valid file"); } $fp = @fopen($data, 'rb'); if (!$fp) { @@ -1921,6 +1922,7 @@ class SFTP extends SSH2 * * @param Integer $i * @return Boolean + * @throws \UnexpectedValueException on receipt of unexpected packets * @access private */ function _read_put_responses($i) @@ -1928,8 +1930,7 @@ class SFTP extends SSH2 while ($i--) { $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_STATUS'); } extract(unpack('Nstatus', $this->_string_shift($response, 4))); @@ -1947,6 +1948,7 @@ class SFTP extends SSH2 * * @param String $handle * @return Boolean + * @throws \UnexpectedValueException on receipt of unexpected packets * @access private */ function _close_handle($handle) @@ -1959,8 +1961,7 @@ class SFTP extends SSH2 // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3 $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_STATUS'); } extract(unpack('Nstatus', $this->_string_shift($response, 4))); @@ -1985,6 +1986,7 @@ class SFTP extends SSH2 * @param optional String $local_file * @param optional Integer $offset * @param optional Integer $length + * @throws \UnexpectedValueException on receipt of unexpected packets * @return Mixed * @access public */ @@ -2013,8 +2015,7 @@ class SFTP extends SSH2 $this->_logError($response); return false; default: - user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); } if (is_resource($local_file)) { @@ -2062,11 +2063,10 @@ class SFTP extends SSH2 $this->_logError($response); break 2; default: - user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS'); if ($fclose_check) { fclose($fp); } - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_DATA or SSH_FXP_STATUS'); } if ($length > 0 && $length <= $offset - $start) { @@ -2100,6 +2100,7 @@ class SFTP extends SSH2 * @param String $path * @param Boolean $recursive * @return Boolean + * @throws \UnexpectedValueException on receipt of unexpected packets * @access public */ function delete($path, $recursive = true) @@ -2120,8 +2121,7 @@ class SFTP extends SSH2 $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_STATUS'); } // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED @@ -2446,6 +2446,7 @@ class SFTP extends SSH2 * @param String $oldname * @param String $newname * @return Boolean + * @throws \UnexpectedValueException on receipt of unexpected packets * @access public */ function rename($oldname, $newname) @@ -2468,8 +2469,7 @@ class SFTP extends SSH2 $response = $this->_get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { - user_error('Expected SSH_FXP_STATUS'); - return false; + throw new \UnexpectedValueException('Expected SSH_FXP_STATUS'); } // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED From 2eb4ebf11cb9832a61444ac78a0e7495ce67c2f8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 31 Aug 2015 23:23:40 -0500 Subject: [PATCH 12/16] SSH/Agent: replace user_error's with exceptions --- .../Exception/BadConfigurationException.php | 26 +++++++++++++++++++ phpseclib/Exception/FileNotFoundException.php | 2 +- phpseclib/System/SSH/Agent.php | 16 +++++++----- 3 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 phpseclib/Exception/BadConfigurationException.php diff --git a/phpseclib/Exception/BadConfigurationException.php b/phpseclib/Exception/BadConfigurationException.php new file mode 100644 index 00000000..096148a0 --- /dev/null +++ b/phpseclib/Exception/BadConfigurationException.php @@ -0,0 +1,26 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Exception; + +/** + * BadConfigurationException + * + * @package BadConfigurationException + * @author Jim Wigginton + */ +class BadConfigurationException extends \RuntimeException +{ +} diff --git a/phpseclib/Exception/FileNotFoundException.php b/phpseclib/Exception/FileNotFoundException.php index ea9755e5..984edfcc 100644 --- a/phpseclib/Exception/FileNotFoundException.php +++ b/phpseclib/Exception/FileNotFoundException.php @@ -18,7 +18,7 @@ namespace phpseclib\Exception; /** * FileNotFoundException * - * @package UnsupportedAlgorithmException + * @package FileNotFoundException * @author Jim Wigginton */ class FileNotFoundException extends \RuntimeException diff --git a/phpseclib/System/SSH/Agent.php b/phpseclib/System/SSH/Agent.php index 0bbcc378..e53dfd5a 100644 --- a/phpseclib/System/SSH/Agent.php +++ b/phpseclib/System/SSH/Agent.php @@ -35,6 +35,7 @@ namespace phpseclib\System\SSH; use phpseclib\Crypt\RSA; use phpseclib\System\SSH\Agent\Identity; +use phpseclib\Exception\BadConfigurationException; /** * Pure-PHP ssh-agent client identity factory @@ -115,6 +116,8 @@ class Agent * Default Constructor * * @return \phpseclib\System\SSH\Agent + * @throws \phpseclib\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found + * @throws \RuntimeException on connection errors * @access public */ function __construct() @@ -127,13 +130,12 @@ class Agent $address = $_ENV['SSH_AUTH_SOCK']; break; default: - user_error('SSH_AUTH_SOCK not found'); - return false; + throw new \BadConfigurationException('SSH_AUTH_SOCK not found'); } $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr); if (!$this->fsock) { - user_error("Unable to connect to ssh-agent (Error $errno: $errstr)"); + throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)"); } } @@ -144,6 +146,7 @@ class Agent * Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects * * @return Array + * @throws \RuntimeException on receipt of unexpected packets * @access public */ function requestIdentities() @@ -154,13 +157,13 @@ class Agent $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); if (strlen($packet) != fputs($this->fsock, $packet)) { - user_error('Connection closed while requesting identities'); + throw new \RuntimeException('Connection closed while requesting identities'); } $length = current(unpack('N', fread($this->fsock, 4))); $type = ord(fread($this->fsock, 1)); if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { - user_error('Unable to request identities'); + throw new \RuntimeException('Unable to request identities'); } $identities = array(); @@ -265,6 +268,7 @@ class Agent * * @param String $data * @return data from SSH Agent + * @throws \RuntimeException on connection errors * @access private */ function _forward_data($data) @@ -283,7 +287,7 @@ class Agent } if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { - user_error('Connection closed attempting to forward data to SSH agent'); + throw new \RuntimeException('Connection closed attempting to forward data to SSH agent'); } $this->socket_buffer = ''; From a6fd9ea8b6f1e74d7db159b66705cb9e7efad392 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 31 Aug 2015 23:28:20 -0500 Subject: [PATCH 13/16] SCP: replace user_error's with exceptions --- phpseclib/Net/SCP.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/phpseclib/Net/SCP.php b/phpseclib/Net/SCP.php index e54e3c0b..6853e072 100644 --- a/phpseclib/Net/SCP.php +++ b/phpseclib/Net/SCP.php @@ -34,6 +34,7 @@ namespace phpseclib\Net; use phpseclib\Net\SSH1; use phpseclib\Net\SSH2; +use phpseclib\Exception\FileNotFoundException; /** * Pure-PHP implementations of SCP. @@ -140,6 +141,7 @@ class SCP * @param String $data * @param optional Integer $mode * @param optional Callable $callback + * @throws \phpseclib\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist * @return Boolean * @access public */ @@ -168,8 +170,7 @@ class SCP $size = strlen($data); } else { if (!is_file($data)) { - user_error("$data is not a valid file", E_USER_NOTICE); - return false; + throw new FileNotFoundException("$data is not a valid file"); } $fp = @fopen($data, 'rb'); @@ -289,6 +290,7 @@ class SCP * Receives a packet from an SSH server * * @return String + * @throws \UnexpectedValueException on receipt of an unexpected packet * @access private */ function _receive() @@ -314,8 +316,7 @@ class SCP $this->ssh->bitmap = 0; return false; default: - user_error('Unknown packet received', E_USER_NOTICE); - return false; + throw new \UnexpectedValueException('Unknown packet received'); } } } From 724ba7ccc93046b1011d8ed917c135cf268ced15 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 31 Aug 2015 23:34:33 -0500 Subject: [PATCH 14/16] SSH2: missed a few user_error's --- phpseclib/Net/SSH2.php | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 4c0e33e9..c4aa704c 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1431,13 +1431,11 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } extract(unpack('Ctype', $this->_string_shift($response, 1))); if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) { - user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP'); - return false; + throw new \UnexpectedValueException('Expected SSH_MSG_KEX_DH_GEX_GROUP'); } extract(unpack('NprimeLength', $this->_string_shift($response, 4))); @@ -1963,8 +1961,7 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { - user_error('Connection closed by server'); - return false; + throw new \RuntimeException('Connection closed by server'); } extract(unpack('Ctype', $this->_string_shift($response, 1))); @@ -2569,8 +2566,7 @@ class SSH2 $this->is_timeout = false; if (!($this->bitmap & self::MASK_LOGIN)) { - user_error('Operation disallowed prior to login()'); - return false; + throw new \RuntimeException('Operation disallowed prior to login()'); } if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) { @@ -2778,8 +2774,7 @@ class SSH2 $raw = $this->decrypt->decrypt($raw); } if ($raw === false) { - user_error('Unable to decrypt content'); - return false; + throw new \RuntimeException('Unable to decrypt content'); } extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5))); @@ -3065,7 +3060,6 @@ class SSH2 $response = $this->_get_binary_packet(); if ($response === false) { throw new \RuntimeException('Connection closed by server'); - return false; } if ($client_channel == -1 && $response === true) { return true; @@ -3255,9 +3249,8 @@ class SSH2 function _send_binary_packet($data, $logged = null) { if (!is_resource($this->fsock) || feof($this->fsock)) { - user_error('Connection closed prematurely'); $this->bitmap = 0; - return false; + throw new \RuntimeException('Connection closed prematurely'); } //if ($this->compress) { From e399a320dcaa2c7508645a4ef97f47716b62406e Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 31 Aug 2015 23:36:56 -0500 Subject: [PATCH 15/16] SSH/Agent/Identity: replace user_error's with exceptions --- phpseclib/System/SSH/Agent/Identity.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/phpseclib/System/SSH/Agent/Identity.php b/phpseclib/System/SSH/Agent/Identity.php index 490edf6e..82fd224c 100644 --- a/phpseclib/System/SSH/Agent/Identity.php +++ b/phpseclib/System/SSH/Agent/Identity.php @@ -134,6 +134,7 @@ class Identity * * @param String $message * @return String + * @throws \RuntimeException on connection errors * @access public */ function sign($message) @@ -142,13 +143,13 @@ class Identity $packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, 0); $packet = pack('Na*', strlen($packet), $packet); if (strlen($packet) != fputs($this->fsock, $packet)) { - user_error('Connection closed during signing'); + throw new \RuntimeException('Connection closed during signing'); } $length = current(unpack('N', fread($this->fsock, 4))); $type = ord(fread($this->fsock, 1)); if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { - user_error('Unable to retreive signature'); + throw new \RuntimeException('Unable to retreive signature'); } $signature_blob = fread($this->fsock, $length - 1); From c27f70c5778ab56686983fe6ae82c173d4a816a4 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 31 Aug 2015 23:54:35 -0500 Subject: [PATCH 16/16] Exceptions: CS adjustment --- phpseclib/Exception/NoSupportedAlgorithmsException.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Exception/NoSupportedAlgorithmsException.php b/phpseclib/Exception/NoSupportedAlgorithmsException.php index 19182fb4..bca9a753 100644 --- a/phpseclib/Exception/NoSupportedAlgorithmsException.php +++ b/phpseclib/Exception/NoSupportedAlgorithmsException.php @@ -1,7 +1,7 @@