mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-30 12:50:38 +00:00
Merge pull request #739 from terrafrost/exceptions-v1
Exception support * terrafrost/exceptions-v1: Exceptions: CS adjustment SSH/Agent/Identity: replace user_error's with exceptions SSH2: missed a few user_error's SCP: replace user_error's with exceptions SSH/Agent: replace user_error's with exceptions SFTP: replace user_error's with exceptions RSA: some of the exceptions being thrown weren't valid SSH2: replace user_error's with exceptions ASN1/X509: throw exceptions instead of user_errors rm unused exception RSA: replace user_error's with Exceptions Random: replace user_error with exception Crypt/Base: use the built-in spl exceptions instead Exceptions: more CS adjustments Exceptions: CS adjustment Crypt/Base: add initial exception support
This commit is contained in:
commit
09769f60fb
@ -545,6 +545,7 @@ abstract class Base
|
|||||||
* @see Crypt/Hash.php
|
* @see Crypt/Hash.php
|
||||||
* @param String $password
|
* @param String $password
|
||||||
* @param optional String $method
|
* @param optional String $method
|
||||||
|
* @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
* @internal Could, but not must, extend by the child Crypt_* class
|
* @internal Could, but not must, extend by the child Crypt_* class
|
||||||
@ -579,8 +580,7 @@ abstract class Base
|
|||||||
$hashObj = new Hash();
|
$hashObj = new Hash();
|
||||||
$hashObj->setHash($hash);
|
$hashObj->setHash($hash);
|
||||||
if ($dkLen > $hashObj->getLength()) {
|
if ($dkLen > $hashObj->getLength()) {
|
||||||
user_error('Derived key too long');
|
throw new \LengthException('Derived key length cannot be longer than the hash length');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$t = $password . $salt;
|
$t = $password . $salt;
|
||||||
for ($i = 0; $i < $count; ++$i) {
|
for ($i = 0; $i < $count; ++$i) {
|
||||||
@ -1768,6 +1768,7 @@ abstract class Base
|
|||||||
*
|
*
|
||||||
* @see \phpseclib\Crypt\Base::_unpad()
|
* @see \phpseclib\Crypt\Base::_unpad()
|
||||||
* @param String $text
|
* @param String $text
|
||||||
|
* @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size
|
||||||
* @access private
|
* @access private
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
@ -1779,8 +1780,7 @@ abstract class Base
|
|||||||
if ($length % $this->block_size == 0) {
|
if ($length % $this->block_size == 0) {
|
||||||
return $text;
|
return $text;
|
||||||
} else {
|
} else {
|
||||||
user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
|
throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding.");
|
||||||
$this->padding = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1797,6 +1797,7 @@ abstract class Base
|
|||||||
*
|
*
|
||||||
* @see \phpseclib\Crypt\Base::_pad()
|
* @see \phpseclib\Crypt\Base::_pad()
|
||||||
* @param String $text
|
* @param String $text
|
||||||
|
* @throws \LengthException if the ciphertext's length is not a multiple of the block size
|
||||||
* @access private
|
* @access private
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
@ -1809,7 +1810,7 @@ abstract class Base
|
|||||||
$length = ord($text[strlen($text) - 1]);
|
$length = ord($text[strlen($text) - 1]);
|
||||||
|
|
||||||
if (!$length || $length > $this->block_size) {
|
if (!$length || $length > $this->block_size) {
|
||||||
return false;
|
throw new \LengthException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})");
|
||||||
}
|
}
|
||||||
|
|
||||||
return substr($text, 0, -$length);
|
return substr($text, 0, -$length);
|
||||||
|
@ -2057,14 +2057,14 @@ class RSA
|
|||||||
* @access private
|
* @access private
|
||||||
* @param \phpseclib\Math\BigInteger $x
|
* @param \phpseclib\Math\BigInteger $x
|
||||||
* @param Integer $xLen
|
* @param Integer $xLen
|
||||||
|
* @throws \OutOfBoundsException if strlen($x) > $xLen
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function _i2osp($x, $xLen)
|
function _i2osp($x, $xLen)
|
||||||
{
|
{
|
||||||
$x = $x->toBytes();
|
$x = $x->toBytes();
|
||||||
if (strlen($x) > $xLen) {
|
if (strlen($x) > $xLen) {
|
||||||
user_error('Integer too large');
|
throw new \OutOfBoundsException('Integer too large');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
|
return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
|
||||||
}
|
}
|
||||||
@ -2219,13 +2219,13 @@ class RSA
|
|||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param \phpseclib\Math\BigInteger $m
|
* @param \phpseclib\Math\BigInteger $m
|
||||||
|
* @throws \OutOfRangeException if $m < 0 or $m > $this->modulus
|
||||||
* @return \phpseclib\Math\BigInteger
|
* @return \phpseclib\Math\BigInteger
|
||||||
*/
|
*/
|
||||||
function _rsaep($m)
|
function _rsaep($m)
|
||||||
{
|
{
|
||||||
if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
|
if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
|
||||||
user_error('Message representative out of range');
|
throw new \OutOfRangeException('Message representative out of range');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return $this->_exponentiate($m);
|
return $this->_exponentiate($m);
|
||||||
}
|
}
|
||||||
@ -2237,13 +2237,13 @@ class RSA
|
|||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param \phpseclib\Math\BigInteger $c
|
* @param \phpseclib\Math\BigInteger $c
|
||||||
|
* @throws \OutOfRangeException if $c < 0 or $c > $this->modulus
|
||||||
* @return \phpseclib\Math\BigInteger
|
* @return \phpseclib\Math\BigInteger
|
||||||
*/
|
*/
|
||||||
function _rsadp($c)
|
function _rsadp($c)
|
||||||
{
|
{
|
||||||
if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {
|
if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {
|
||||||
user_error('Ciphertext representative out of range');
|
throw new \OutOfRangeException('Ciphertext representative out of range');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return $this->_exponentiate($c);
|
return $this->_exponentiate($c);
|
||||||
}
|
}
|
||||||
@ -2255,13 +2255,13 @@ class RSA
|
|||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param \phpseclib\Math\BigInteger $m
|
* @param \phpseclib\Math\BigInteger $m
|
||||||
|
* @throws \OutOfRangeException if $m < 0 or $m > $this->modulus
|
||||||
* @return \phpseclib\Math\BigInteger
|
* @return \phpseclib\Math\BigInteger
|
||||||
*/
|
*/
|
||||||
function _rsasp1($m)
|
function _rsasp1($m)
|
||||||
{
|
{
|
||||||
if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
|
if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
|
||||||
user_error('Message representative out of range');
|
throw new \OutOfRangeException('Message representative out of range');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return $this->_exponentiate($m);
|
return $this->_exponentiate($m);
|
||||||
}
|
}
|
||||||
@ -2273,13 +2273,13 @@ class RSA
|
|||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param \phpseclib\Math\BigInteger $s
|
* @param \phpseclib\Math\BigInteger $s
|
||||||
|
* @throws \OutOfRangeException if $s < 0 or $s > $this->modulus
|
||||||
* @return \phpseclib\Math\BigInteger
|
* @return \phpseclib\Math\BigInteger
|
||||||
*/
|
*/
|
||||||
function _rsavp1($s)
|
function _rsavp1($s)
|
||||||
{
|
{
|
||||||
if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {
|
if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {
|
||||||
user_error('Signature representative out of range');
|
throw new \OutOfRangeException('Signature representative out of range');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return $this->_exponentiate($s);
|
return $this->_exponentiate($s);
|
||||||
}
|
}
|
||||||
@ -2317,6 +2317,7 @@ class RSA
|
|||||||
* @access private
|
* @access private
|
||||||
* @param String $m
|
* @param String $m
|
||||||
* @param String $l
|
* @param String $l
|
||||||
|
* @throws \OutOfBoundsException if strlen($m) > $this->k - 2 * $this->hLen - 2
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function _rsaes_oaep_encrypt($m, $l = '')
|
function _rsaes_oaep_encrypt($m, $l = '')
|
||||||
@ -2329,8 +2330,7 @@ class RSA
|
|||||||
// be output.
|
// be output.
|
||||||
|
|
||||||
if ($mLen > $this->k - 2 * $this->hLen - 2) {
|
if ($mLen > $this->k - 2 * $this->hLen - 2) {
|
||||||
user_error('Message too long');
|
throw new \OutOfBoundsException('Message too long');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EME-OAEP encoding
|
// EME-OAEP encoding
|
||||||
@ -2380,6 +2380,7 @@ class RSA
|
|||||||
* @access private
|
* @access private
|
||||||
* @param String $c
|
* @param String $c
|
||||||
* @param String $l
|
* @param String $l
|
||||||
|
* @throws \RuntimeException on decryption error
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function _rsaes_oaep_decrypt($c, $l = '')
|
function _rsaes_oaep_decrypt($c, $l = '')
|
||||||
@ -2390,8 +2391,7 @@ class RSA
|
|||||||
// be output.
|
// be output.
|
||||||
|
|
||||||
if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
|
if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
|
||||||
user_error('Decryption error');
|
throw new \RuntimeException('Decryption error');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSA decryption
|
// RSA decryption
|
||||||
@ -2399,8 +2399,7 @@ class RSA
|
|||||||
$c = $this->_os2ip($c);
|
$c = $this->_os2ip($c);
|
||||||
$m = $this->_rsadp($c);
|
$m = $this->_rsadp($c);
|
||||||
if ($m === false) {
|
if ($m === false) {
|
||||||
user_error('Decryption error');
|
throw new \RuntimeException('Decryption error');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$em = $this->_i2osp($m, $this->k);
|
$em = $this->_i2osp($m, $this->k);
|
||||||
|
|
||||||
@ -2417,13 +2416,11 @@ class RSA
|
|||||||
$lHash2 = substr($db, 0, $this->hLen);
|
$lHash2 = substr($db, 0, $this->hLen);
|
||||||
$m = substr($db, $this->hLen);
|
$m = substr($db, $this->hLen);
|
||||||
if ($lHash != $lHash2) {
|
if ($lHash != $lHash2) {
|
||||||
user_error('Decryption error');
|
throw new \RuntimeException('Decryption error');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$m = ltrim($m, chr(0));
|
$m = ltrim($m, chr(0));
|
||||||
if (ord($m[0]) != 1) {
|
if (ord($m[0]) != 1) {
|
||||||
user_error('Decryption error');
|
throw new \RuntimeException('Decryption error');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the message M
|
// Output the message M
|
||||||
@ -2454,6 +2451,7 @@ class RSA
|
|||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param String $m
|
* @param String $m
|
||||||
|
* @throws \OutOfBoundsException if strlen($m) > $this->k - 11
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function _rsaes_pkcs1_v1_5_encrypt($m)
|
function _rsaes_pkcs1_v1_5_encrypt($m)
|
||||||
@ -2463,8 +2461,7 @@ class RSA
|
|||||||
// Length checking
|
// Length checking
|
||||||
|
|
||||||
if ($mLen > $this->k - 11) {
|
if ($mLen > $this->k - 11) {
|
||||||
user_error('Message too long');
|
throw new \OutOfBoundsException('Message too long');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EME-PKCS1-v1_5 encoding
|
// EME-PKCS1-v1_5 encoding
|
||||||
@ -2513,6 +2510,7 @@ class RSA
|
|||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param String $c
|
* @param String $c
|
||||||
|
* @throws \RuntimeException on decryption error
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function _rsaes_pkcs1_v1_5_decrypt($c)
|
function _rsaes_pkcs1_v1_5_decrypt($c)
|
||||||
@ -2520,8 +2518,7 @@ class RSA
|
|||||||
// Length checking
|
// Length checking
|
||||||
|
|
||||||
if (strlen($c) != $this->k) { // or if k < 11
|
if (strlen($c) != $this->k) { // or if k < 11
|
||||||
user_error('Decryption error');
|
throw new \RuntimeException('Decryption error');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSA decryption
|
// RSA decryption
|
||||||
@ -2530,24 +2527,21 @@ class RSA
|
|||||||
$m = $this->_rsadp($c);
|
$m = $this->_rsadp($c);
|
||||||
|
|
||||||
if ($m === false) {
|
if ($m === false) {
|
||||||
user_error('Decryption error');
|
throw new \RuntimeException('Decryption error');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$em = $this->_i2osp($m, $this->k);
|
$em = $this->_i2osp($m, $this->k);
|
||||||
|
|
||||||
// EME-PKCS1-v1_5 decoding
|
// EME-PKCS1-v1_5 decoding
|
||||||
|
|
||||||
if (ord($em[0]) != 0 || ord($em[1]) > 2) {
|
if (ord($em[0]) != 0 || ord($em[1]) > 2) {
|
||||||
user_error('Decryption error');
|
throw new \RuntimeException('Decryption error');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
|
$ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
|
||||||
$m = substr($em, strlen($ps) + 3);
|
$m = substr($em, strlen($ps) + 3);
|
||||||
|
|
||||||
if (strlen($ps) < 8) {
|
if (strlen($ps) < 8) {
|
||||||
user_error('Decryption error');
|
throw new \RuntimeException('Decryption error');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output M
|
// Output M
|
||||||
@ -2562,6 +2556,7 @@ class RSA
|
|||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param String $m
|
* @param String $m
|
||||||
|
* @throws \RuntimeException on encoding error
|
||||||
* @param Integer $emBits
|
* @param Integer $emBits
|
||||||
*/
|
*/
|
||||||
function _emsa_pss_encode($m, $emBits)
|
function _emsa_pss_encode($m, $emBits)
|
||||||
@ -2574,8 +2569,7 @@ class RSA
|
|||||||
|
|
||||||
$mHash = $this->hash->hash($m);
|
$mHash = $this->hash->hash($m);
|
||||||
if ($emLen < $this->hLen + $sLen + 2) {
|
if ($emLen < $this->hLen + $sLen + 2) {
|
||||||
user_error('Encoding error');
|
throw new \RuntimeException('Encoding error');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$salt = Random::string($sLen);
|
$salt = Random::string($sLen);
|
||||||
@ -2672,6 +2666,7 @@ class RSA
|
|||||||
* @access private
|
* @access private
|
||||||
* @param String $m
|
* @param String $m
|
||||||
* @param String $s
|
* @param String $s
|
||||||
|
* @throws \RuntimeException on invalid signature
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function _rsassa_pss_verify($m, $s)
|
function _rsassa_pss_verify($m, $s)
|
||||||
@ -2679,8 +2674,7 @@ class RSA
|
|||||||
// Length checking
|
// Length checking
|
||||||
|
|
||||||
if (strlen($s) != $this->k) {
|
if (strlen($s) != $this->k) {
|
||||||
user_error('Invalid signature');
|
throw new \RuntimeException('Invalid signature');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSA verification
|
// RSA verification
|
||||||
@ -2690,13 +2684,11 @@ class RSA
|
|||||||
$s2 = $this->_os2ip($s);
|
$s2 = $this->_os2ip($s);
|
||||||
$m2 = $this->_rsavp1($s2);
|
$m2 = $this->_rsavp1($s2);
|
||||||
if ($m2 === false) {
|
if ($m2 === false) {
|
||||||
user_error('Invalid signature');
|
throw new \RuntimeException('Invalid signature');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$em = $this->_i2osp($m2, $modBits >> 3);
|
$em = $this->_i2osp($m2, $modBits >> 3);
|
||||||
if ($em === false) {
|
if ($em === false) {
|
||||||
user_error('Invalid signature');
|
throw new \RuntimeException('Invalid signature');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMSA-PSS verification
|
// EMSA-PSS verification
|
||||||
@ -2712,6 +2704,7 @@ class RSA
|
|||||||
* @access private
|
* @access private
|
||||||
* @param String $m
|
* @param String $m
|
||||||
* @param Integer $emLen
|
* @param Integer $emLen
|
||||||
|
* @throws \LengthException if the intended encoded message length is too short
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function _emsa_pkcs1_v1_5_encode($m, $emLen)
|
function _emsa_pkcs1_v1_5_encode($m, $emLen)
|
||||||
@ -2745,8 +2738,7 @@ class RSA
|
|||||||
$tLen = strlen($t);
|
$tLen = strlen($t);
|
||||||
|
|
||||||
if ($emLen < $tLen + 11) {
|
if ($emLen < $tLen + 11) {
|
||||||
user_error('Intended encoded message length too short');
|
throw new \LengthException('Intended encoded message length too short');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
|
$ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
|
||||||
@ -2763,6 +2755,7 @@ class RSA
|
|||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param String $m
|
* @param String $m
|
||||||
|
* @throws \LengthException if the RSA modulus is too short
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function _rsassa_pkcs1_v1_5_sign($m)
|
function _rsassa_pkcs1_v1_5_sign($m)
|
||||||
@ -2771,8 +2764,7 @@ class RSA
|
|||||||
|
|
||||||
$em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
|
$em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
|
||||||
if ($em === false) {
|
if ($em === false) {
|
||||||
user_error('RSA modulus too short');
|
throw new \LengthException('RSA modulus too short');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSA signature
|
// RSA signature
|
||||||
@ -2793,6 +2785,8 @@ class RSA
|
|||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param String $m
|
* @param String $m
|
||||||
|
* @throws \RuntimeException if the signature is invalid
|
||||||
|
* @throws \LengthException if the RSA modulus is too short
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function _rsassa_pkcs1_v1_5_verify($m, $s)
|
function _rsassa_pkcs1_v1_5_verify($m, $s)
|
||||||
@ -2800,8 +2794,7 @@ class RSA
|
|||||||
// Length checking
|
// Length checking
|
||||||
|
|
||||||
if (strlen($s) != $this->k) {
|
if (strlen($s) != $this->k) {
|
||||||
user_error('Invalid signature');
|
throw new \RuntimeException('Invalid signature');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSA verification
|
// RSA verification
|
||||||
@ -2809,21 +2802,18 @@ class RSA
|
|||||||
$s = $this->_os2ip($s);
|
$s = $this->_os2ip($s);
|
||||||
$m2 = $this->_rsavp1($s);
|
$m2 = $this->_rsavp1($s);
|
||||||
if ($m2 === false) {
|
if ($m2 === false) {
|
||||||
user_error('Invalid signature');
|
throw new \RuntimeException('Invalid signature');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$em = $this->_i2osp($m2, $this->k);
|
$em = $this->_i2osp($m2, $this->k);
|
||||||
if ($em === false) {
|
if ($em === false) {
|
||||||
user_error('Invalid signature');
|
throw new \RuntimeException('Invalid signature');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMSA-PKCS1-v1_5 encoding
|
// EMSA-PKCS1-v1_5 encoding
|
||||||
|
|
||||||
$em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
|
$em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
|
||||||
if ($em2 === false) {
|
if ($em2 === false) {
|
||||||
user_error('RSA modulus too short');
|
throw new \LengthException('RSA modulus too short');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare
|
// Compare
|
||||||
|
@ -49,6 +49,7 @@ class Random
|
|||||||
* eg. for RSA key generation.
|
* eg. for RSA key generation.
|
||||||
*
|
*
|
||||||
* @param Integer $length
|
* @param Integer $length
|
||||||
|
* @throws \RuntimeException if a symmetric cipher is needed but not loaded
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
public static function string($length)
|
public static function string($length)
|
||||||
@ -199,8 +200,7 @@ class Random
|
|||||||
$crypto = new RC4();
|
$crypto = new RC4();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded');
|
throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$crypto->setKey($key);
|
$crypto->setKey($key);
|
||||||
|
26
phpseclib/Exception/BadConfigurationException.php
Normal file
26
phpseclib/Exception/BadConfigurationException.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BadConfigurationException
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* @category Exception
|
||||||
|
* @package BadConfigurationException
|
||||||
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
|
* @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 <terrafrost@php.net>
|
||||||
|
*/
|
||||||
|
class BadConfigurationException extends \RuntimeException
|
||||||
|
{
|
||||||
|
}
|
26
phpseclib/Exception/FileNotFoundException.php
Normal file
26
phpseclib/Exception/FileNotFoundException.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileNotFoundException
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* @category Exception
|
||||||
|
* @package FileNotFoundException
|
||||||
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
|
* @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 FileNotFoundException
|
||||||
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
|
*/
|
||||||
|
class FileNotFoundException extends \RuntimeException
|
||||||
|
{
|
||||||
|
}
|
26
phpseclib/Exception/NoSupportedAlgorithmsException.php
Normal file
26
phpseclib/Exception/NoSupportedAlgorithmsException.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NoSupportedAlgorithmsException
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* @category Exception
|
||||||
|
* @package NoSupportedAlgorithmsException
|
||||||
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
|
* @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 <terrafrost@php.net>
|
||||||
|
*/
|
||||||
|
class NoSupportedAlgorithmsException extends \RuntimeException
|
||||||
|
{
|
||||||
|
}
|
26
phpseclib/Exception/UnsupportedAlgorithmException.php
Normal file
26
phpseclib/Exception/UnsupportedAlgorithmException.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UnsupportedAlgorithmException
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* @category Exception
|
||||||
|
* @package UnsupportedAlgorithmException
|
||||||
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
|
* @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 <terrafrost@php.net>
|
||||||
|
*/
|
||||||
|
class UnsupportedAlgorithmException extends \RuntimeException
|
||||||
|
{
|
||||||
|
}
|
@ -793,6 +793,7 @@ class ASN1
|
|||||||
* @param String $mapping
|
* @param String $mapping
|
||||||
* @param Integer $idx
|
* @param Integer $idx
|
||||||
* @return String
|
* @return String
|
||||||
|
* @throws \RuntimeException if the input has an error in it
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _encode_der($source, $mapping, $idx = null, $special = array())
|
function _encode_der($source, $mapping, $idx = null, $special = array())
|
||||||
@ -985,7 +986,7 @@ class ASN1
|
|||||||
case self::TYPE_OBJECT_IDENTIFIER:
|
case self::TYPE_OBJECT_IDENTIFIER:
|
||||||
$oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
|
$oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
|
||||||
if ($oid === false) {
|
if ($oid === false) {
|
||||||
user_error('Invalid OID');
|
throw new \RuntimeException('Invalid OID');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$value = '';
|
$value = '';
|
||||||
@ -1038,7 +1039,7 @@ class ASN1
|
|||||||
$filters = $filters[$part];
|
$filters = $filters[$part];
|
||||||
}
|
}
|
||||||
if ($filters === false) {
|
if ($filters === false) {
|
||||||
user_error('No filters defined for ' . implode('/', $loc));
|
throw new \RuntimeException('No filters defined for ' . implode('/', $loc));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return $this->_encode_der($source, $filters + $mapping, null, $special);
|
return $this->_encode_der($source, $filters + $mapping, null, $special);
|
||||||
@ -1062,7 +1063,7 @@ class ASN1
|
|||||||
$value = $source ? "\xFF" : "\x00";
|
$value = $source ? "\xFF" : "\x00";
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ use phpseclib\Crypt\Random;
|
|||||||
use phpseclib\File\ASN1;
|
use phpseclib\File\ASN1;
|
||||||
use phpseclib\File\ASN1\Element;
|
use phpseclib\File\ASN1\Element;
|
||||||
use phpseclib\Math\BigInteger;
|
use phpseclib\Math\BigInteger;
|
||||||
|
use phpseclib\Exception\UnsupportedAlgorithmException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pure-PHP X.509 Parser
|
* Pure-PHP X.509 Parser
|
||||||
@ -1641,7 +1642,7 @@ class X509
|
|||||||
$map = $this->_getMapping($id);
|
$map = $this->_getMapping($id);
|
||||||
if (is_bool($map)) {
|
if (is_bool($map)) {
|
||||||
if (!$map) {
|
if (!$map) {
|
||||||
user_error($id . ' is not a currently supported extension');
|
//user_error($id . ' is not a currently supported extension');
|
||||||
unset($extensions[$i]);
|
unset($extensions[$i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1714,7 +1715,7 @@ class X509
|
|||||||
$id = $attributes[$i]['type'];
|
$id = $attributes[$i]['type'];
|
||||||
$map = $this->_getMapping($id);
|
$map = $this->_getMapping($id);
|
||||||
if ($map === false) {
|
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]);
|
unset($attributes[$i]);
|
||||||
} elseif (is_array($attributes[$i]['value'])) {
|
} elseif (is_array($attributes[$i]['value'])) {
|
||||||
$values = &$attributes[$i]['value'];
|
$values = &$attributes[$i]['value'];
|
||||||
@ -2107,7 +2108,8 @@ class X509
|
|||||||
/**
|
/**
|
||||||
* Validates a signature
|
* 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 $publicKeyAlgorithm
|
||||||
* @param String $publicKey
|
* @param String $publicKey
|
||||||
@ -2115,7 +2117,8 @@ class X509
|
|||||||
* @param String $signature
|
* @param String $signature
|
||||||
* @param String $signatureSubject
|
* @param String $signatureSubject
|
||||||
* @access private
|
* @access private
|
||||||
* @return Integer
|
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
|
||||||
|
* @return Boolean
|
||||||
*/
|
*/
|
||||||
function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject)
|
function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject)
|
||||||
{
|
{
|
||||||
@ -2139,11 +2142,11 @@ class X509
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return null;
|
throw new UnsupportedAlgorithmException('Signature algorithm unsupported');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return null;
|
throw new UnsupportedAlgorithmException('Public key algorithm unsupported');
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -3628,6 +3631,7 @@ class X509
|
|||||||
* @param \phpseclib\File\X509 $subject
|
* @param \phpseclib\File\X509 $subject
|
||||||
* @param String $signatureAlgorithm
|
* @param String $signatureAlgorithm
|
||||||
* @access public
|
* @access public
|
||||||
|
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
*/
|
*/
|
||||||
function _sign($key, $signatureAlgorithm)
|
function _sign($key, $signatureAlgorithm)
|
||||||
@ -3646,10 +3650,12 @@ class X509
|
|||||||
|
|
||||||
$this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject));
|
$this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject));
|
||||||
return $this->currentCert;
|
return $this->currentCert;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedAlgorithmException('Signature algorithm unsupported');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
throw new UnsupportedAlgorithmException('Unsupported public key algorithm');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,6 +34,7 @@ namespace phpseclib\Net;
|
|||||||
|
|
||||||
use phpseclib\Net\SSH1;
|
use phpseclib\Net\SSH1;
|
||||||
use phpseclib\Net\SSH2;
|
use phpseclib\Net\SSH2;
|
||||||
|
use phpseclib\Exception\FileNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pure-PHP implementations of SCP.
|
* Pure-PHP implementations of SCP.
|
||||||
@ -140,6 +141,7 @@ class SCP
|
|||||||
* @param String $data
|
* @param String $data
|
||||||
* @param optional Integer $mode
|
* @param optional Integer $mode
|
||||||
* @param optional Callable $callback
|
* @param optional Callable $callback
|
||||||
|
* @throws \phpseclib\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
@ -168,8 +170,7 @@ class SCP
|
|||||||
$size = strlen($data);
|
$size = strlen($data);
|
||||||
} else {
|
} else {
|
||||||
if (!is_file($data)) {
|
if (!is_file($data)) {
|
||||||
user_error("$data is not a valid file", E_USER_NOTICE);
|
throw new FileNotFoundException("$data is not a valid file");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$fp = @fopen($data, 'rb');
|
$fp = @fopen($data, 'rb');
|
||||||
@ -289,6 +290,7 @@ class SCP
|
|||||||
* Receives a packet from an SSH server
|
* Receives a packet from an SSH server
|
||||||
*
|
*
|
||||||
* @return String
|
* @return String
|
||||||
|
* @throws \UnexpectedValueException on receipt of an unexpected packet
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _receive()
|
function _receive()
|
||||||
@ -314,8 +316,7 @@ class SCP
|
|||||||
$this->ssh->bitmap = 0;
|
$this->ssh->bitmap = 0;
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Unknown packet received', E_USER_NOTICE);
|
throw new \UnexpectedValueException('Unknown packet received');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
namespace phpseclib\Net;
|
namespace phpseclib\Net;
|
||||||
|
|
||||||
use phpseclib\Net\SSH2;
|
use phpseclib\Net\SSH2;
|
||||||
|
use phpseclib\Exception\FileNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pure-PHP implementations of SFTP.
|
* Pure-PHP implementations of SFTP.
|
||||||
@ -383,6 +384,7 @@ class SFTP extends SSH2
|
|||||||
*
|
*
|
||||||
* @param String $username
|
* @param String $username
|
||||||
* @param optional String $password
|
* @param optional String $password
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
@ -470,8 +472,7 @@ class SFTP extends SSH2
|
|||||||
|
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_VERSION) {
|
if ($this->packet_type != NET_SFTP_VERSION) {
|
||||||
user_error('Expected SSH_FXP_VERSION');
|
throw new \UnexpectedValueException('Expected SSH_FXP_VERSION');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Nversion', $this->_string_shift($response, 4)));
|
extract(unpack('Nversion', $this->_string_shift($response, 4)));
|
||||||
@ -610,6 +611,7 @@ class SFTP extends SSH2
|
|||||||
*
|
*
|
||||||
* @see \phpseclib\Net\SFTP::chdir()
|
* @see \phpseclib\Net\SFTP::chdir()
|
||||||
* @param String $path
|
* @param String $path
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
@ -634,8 +636,7 @@ class SFTP extends SSH2
|
|||||||
$this->_logError($response);
|
$this->_logError($response);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,6 +667,7 @@ class SFTP extends SSH2
|
|||||||
* Changes the current directory
|
* Changes the current directory
|
||||||
*
|
*
|
||||||
* @param String $dir
|
* @param String $dir
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
@ -710,8 +712,7 @@ class SFTP extends SSH2
|
|||||||
$this->_logError($response);
|
$this->_logError($response);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->_close_handle($handle)) {
|
if (!$this->_close_handle($handle)) {
|
||||||
@ -813,6 +814,7 @@ class SFTP extends SSH2
|
|||||||
* @param String $dir
|
* @param String $dir
|
||||||
* @param optional Boolean $raw
|
* @param optional Boolean $raw
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _list($dir, $raw = true)
|
function _list($dir, $raw = true)
|
||||||
@ -844,8 +846,7 @@ class SFTP extends SSH2
|
|||||||
$this->_logError($response);
|
$this->_logError($response);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_update_stat_cache($dir, array());
|
$this->_update_stat_cache($dir, array());
|
||||||
@ -899,8 +900,7 @@ class SFTP extends SSH2
|
|||||||
}
|
}
|
||||||
break 2;
|
break 2;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1259,6 +1259,7 @@ class SFTP extends SSH2
|
|||||||
*
|
*
|
||||||
* @param String $filename
|
* @param String $filename
|
||||||
* @param Integer $type
|
* @param Integer $type
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
@ -1279,8 +1280,7 @@ class SFTP extends SSH2
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1306,6 +1306,7 @@ class SFTP extends SSH2
|
|||||||
* @param String $filename
|
* @param String $filename
|
||||||
* @param optional Integer $time
|
* @param optional Integer $time
|
||||||
* @param optional Integer $atime
|
* @param optional Integer $atime
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
@ -1342,8 +1343,7 @@ class SFTP extends SSH2
|
|||||||
$this->_logError($response);
|
$this->_logError($response);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_setstat($filename, $attr, false);
|
return $this->_setstat($filename, $attr, false);
|
||||||
@ -1396,6 +1396,7 @@ class SFTP extends SSH2
|
|||||||
* @param Integer $mode
|
* @param Integer $mode
|
||||||
* @param String $filename
|
* @param String $filename
|
||||||
* @param optional Boolean $recursive
|
* @param optional Boolean $recursive
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
@ -1433,8 +1434,7 @@ class SFTP extends SSH2
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1443,6 +1443,7 @@ class SFTP extends SSH2
|
|||||||
* @param String $filename
|
* @param String $filename
|
||||||
* @param String $attr
|
* @param String $attr
|
||||||
* @param Boolean $recursive
|
* @param Boolean $recursive
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
@ -1481,8 +1482,7 @@ class SFTP extends SSH2
|
|||||||
*/
|
*/
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
@ -1570,6 +1570,7 @@ class SFTP extends SSH2
|
|||||||
* Return the target of a symbolic link
|
* Return the target of a symbolic link
|
||||||
*
|
*
|
||||||
* @param String $link
|
* @param String $link
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
@ -1593,8 +1594,7 @@ class SFTP extends SSH2
|
|||||||
$this->_logError($response);
|
$this->_logError($response);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Ncount', $this->_string_shift($response, 4)));
|
extract(unpack('Ncount', $this->_string_shift($response, 4)));
|
||||||
@ -1614,6 +1614,7 @@ class SFTP extends SSH2
|
|||||||
*
|
*
|
||||||
* @param String $target
|
* @param String $target
|
||||||
* @param String $link
|
* @param String $link
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
@ -1633,8 +1634,7 @@ class SFTP extends SSH2
|
|||||||
|
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
@ -1686,6 +1686,7 @@ class SFTP extends SSH2
|
|||||||
*
|
*
|
||||||
* @param String $dir
|
* @param String $dir
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _mkdir_helper($dir, $attr)
|
function _mkdir_helper($dir, $attr)
|
||||||
@ -1696,8 +1697,7 @@ class SFTP extends SSH2
|
|||||||
|
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
@ -1713,6 +1713,7 @@ class SFTP extends SSH2
|
|||||||
* Removes a directory.
|
* Removes a directory.
|
||||||
*
|
*
|
||||||
* @param String $dir
|
* @param String $dir
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
@ -1733,8 +1734,7 @@ class SFTP extends SSH2
|
|||||||
|
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
@ -1794,6 +1794,9 @@ class SFTP extends SSH2
|
|||||||
* @param optional Integer $start
|
* @param optional Integer $start
|
||||||
* @param optional Integer $local_start
|
* @param optional Integer $local_start
|
||||||
* @param optional callable|null $progressCallback
|
* @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
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
* @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode().
|
* @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode().
|
||||||
@ -1841,8 +1844,7 @@ class SFTP extends SSH2
|
|||||||
$this->_logError($response);
|
$this->_logError($response);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
|
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
|
||||||
@ -1850,7 +1852,7 @@ class SFTP extends SSH2
|
|||||||
switch (true) {
|
switch (true) {
|
||||||
case $mode & self::SOURCE_CALLBACK:
|
case $mode & self::SOURCE_CALLBACK:
|
||||||
if (!is_callable($data)) {
|
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;
|
$dataCallback = $data;
|
||||||
// do nothing
|
// do nothing
|
||||||
@ -1861,8 +1863,7 @@ class SFTP extends SSH2
|
|||||||
break;
|
break;
|
||||||
case $mode & self::SOURCE_LOCAL_FILE:
|
case $mode & self::SOURCE_LOCAL_FILE:
|
||||||
if (!is_file($data)) {
|
if (!is_file($data)) {
|
||||||
user_error("$data is not a valid file");
|
throw new FileNotFoundException("$data is not a valid file");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$fp = @fopen($data, 'rb');
|
$fp = @fopen($data, 'rb');
|
||||||
if (!$fp) {
|
if (!$fp) {
|
||||||
@ -1950,6 +1951,7 @@ class SFTP extends SSH2
|
|||||||
*
|
*
|
||||||
* @param Integer $i
|
* @param Integer $i
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _read_put_responses($i)
|
function _read_put_responses($i)
|
||||||
@ -1957,8 +1959,7 @@ class SFTP extends SSH2
|
|||||||
while ($i--) {
|
while ($i--) {
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
@ -1976,6 +1977,7 @@ class SFTP extends SSH2
|
|||||||
*
|
*
|
||||||
* @param String $handle
|
* @param String $handle
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _close_handle($handle)
|
function _close_handle($handle)
|
||||||
@ -1988,8 +1990,7 @@ class SFTP extends SSH2
|
|||||||
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
|
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
|
||||||
@ -2014,6 +2015,7 @@ class SFTP extends SSH2
|
|||||||
* @param optional String $local_file
|
* @param optional String $local_file
|
||||||
* @param optional Integer $offset
|
* @param optional Integer $offset
|
||||||
* @param optional Integer $length
|
* @param optional Integer $length
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
@ -2042,8 +2044,7 @@ class SFTP extends SSH2
|
|||||||
$this->_logError($response);
|
$this->_logError($response);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_resource($local_file)) {
|
if (is_resource($local_file)) {
|
||||||
@ -2091,11 +2092,10 @@ class SFTP extends SSH2
|
|||||||
$this->_logError($response);
|
$this->_logError($response);
|
||||||
break 2;
|
break 2;
|
||||||
default:
|
default:
|
||||||
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
|
|
||||||
if ($fclose_check) {
|
if ($fclose_check) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
}
|
}
|
||||||
return false;
|
throw new \UnexpectedValueException('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($length > 0 && $length <= $offset - $start) {
|
if ($length > 0 && $length <= $offset - $start) {
|
||||||
@ -2129,6 +2129,7 @@ class SFTP extends SSH2
|
|||||||
* @param String $path
|
* @param String $path
|
||||||
* @param Boolean $recursive
|
* @param Boolean $recursive
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function delete($path, $recursive = true)
|
function delete($path, $recursive = true)
|
||||||
@ -2149,8 +2150,7 @@ class SFTP extends SSH2
|
|||||||
|
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||||
@ -2482,6 +2482,7 @@ class SFTP extends SSH2
|
|||||||
* @param String $oldname
|
* @param String $oldname
|
||||||
* @param String $newname
|
* @param String $newname
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function rename($oldname, $newname)
|
function rename($oldname, $newname)
|
||||||
@ -2504,8 +2505,7 @@ class SFTP extends SSH2
|
|||||||
|
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet();
|
||||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||||
user_error('Expected SSH_FXP_STATUS');
|
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
|
||||||
|
@ -60,6 +60,7 @@ use phpseclib\Crypt\TripleDES;
|
|||||||
use phpseclib\Crypt\Twofish;
|
use phpseclib\Crypt\Twofish;
|
||||||
use phpseclib\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification.
|
use phpseclib\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification.
|
||||||
use phpseclib\System\SSH\Agent;
|
use phpseclib\System\SSH\Agent;
|
||||||
|
use phpseclib\Exception\NoSupportedAlgorithmsException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pure-PHP implementation of SSHv2.
|
* Pure-PHP implementation of SSHv2.
|
||||||
@ -989,6 +990,8 @@ class SSH2
|
|||||||
* Connect to an SSHv2 server
|
* Connect to an SSHv2 server
|
||||||
*
|
*
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
|
* @throws \RuntimeException on other errors
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _connect()
|
function _connect()
|
||||||
@ -1008,8 +1011,7 @@ class SSH2
|
|||||||
$this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout);
|
$this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout);
|
||||||
if (!$this->fsock) {
|
if (!$this->fsock) {
|
||||||
$host = $this->host . ':' . $this->port;
|
$host = $this->host . ':' . $this->port;
|
||||||
user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
|
throw new \RuntimeException(rtrim("Cannot connect to $host. Error $errno. $errstr"));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$elapsed = microtime(true) - $start;
|
$elapsed = microtime(true) - $start;
|
||||||
|
|
||||||
@ -1060,8 +1062,7 @@ class SSH2
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (feof($this->fsock)) {
|
if (feof($this->fsock)) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->identifier = $this->_generate_identifier();
|
$this->identifier = $this->_generate_identifier();
|
||||||
@ -1077,21 +1078,18 @@ class SSH2
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($matches[1] != '1.99' && $matches[1] != '2.0') {
|
if ($matches[1] != '1.99' && $matches[1] != '2.0') {
|
||||||
user_error("Cannot connect to SSH $matches[1] servers");
|
throw new \RuntimeException("Cannot connect to SSH $matches[1] servers");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs($this->fsock, $this->identifier . "\r\n");
|
fputs($this->fsock, $this->identifier . "\r\n");
|
||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
||||||
user_error('Expected SSH_MSG_KEXINIT');
|
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->_key_exchange($response)) {
|
if (!$this->_key_exchange($response)) {
|
||||||
@ -1143,6 +1141,9 @@ class SSH2
|
|||||||
* Key Exchange
|
* Key Exchange
|
||||||
*
|
*
|
||||||
* @param String $kexinit_payload_server
|
* @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
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _key_exchange($kexinit_payload_server)
|
function _key_exchange($kexinit_payload_server)
|
||||||
@ -1354,27 +1355,28 @@ class SSH2
|
|||||||
// here ends the second place.
|
// here ends the second place.
|
||||||
|
|
||||||
// we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
|
// we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
|
||||||
|
|
||||||
// we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
|
// we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
|
||||||
// diffie-hellman key exchange as fast as possible
|
// diffie-hellman key exchange as fast as possible
|
||||||
$decrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_server_to_client);
|
$decrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_server_to_client);
|
||||||
$decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt);
|
$decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt);
|
||||||
if ($decryptKeyLength === null) {
|
if ($decryptKeyLength === null) {
|
||||||
user_error('No compatible server to client encryption algorithms found');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new NoSupportedAlgorithmsException('No compatible server to client encryption algorithms found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$encrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_client_to_server);
|
$encrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_client_to_server);
|
||||||
$encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt);
|
$encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt);
|
||||||
if ($encryptKeyLength === null) {
|
if ($encryptKeyLength === null) {
|
||||||
user_error('No compatible client to server encryption algorithms found');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// through diffie-hellman key exchange a symmetric key is obtained
|
// through diffie-hellman key exchange a symmetric key is obtained
|
||||||
$kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
|
$kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
|
||||||
if ($kex_algorithm === false) {
|
if ($kex_algorithm === false) {
|
||||||
user_error('No compatible key exchange algorithms found');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty.
|
// Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty.
|
||||||
@ -1491,20 +1493,17 @@ class SSH2
|
|||||||
$data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
|
$data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
|
||||||
|
|
||||||
if (!$this->_send_binary_packet($data)) {
|
if (!$this->_send_binary_packet($data)) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||||
|
|
||||||
if ($type != $serverKexReplyMessage) {
|
if ($type != $serverKexReplyMessage) {
|
||||||
user_error('Expected SSH_MSG_KEXDH_REPLY');
|
throw new \UnexpectedValueException('Expected SSH_MSG_KEXDH_REPLY');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
$temp = unpack('Nlength', $this->_string_shift($response, 4));
|
||||||
@ -1564,13 +1563,13 @@ class SSH2
|
|||||||
|
|
||||||
$server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms);
|
$server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms);
|
||||||
if ($server_host_key_algorithm === false) {
|
if ($server_host_key_algorithm === false) {
|
||||||
user_error('No compatible server host key algorithms found');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $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_algorithm || $this->signature_format != $server_host_key_algorithm) {
|
if ($public_key_format != $server_host_key_algorithm || $this->signature_format != $server_host_key_algorithm) {
|
||||||
user_error('Server Host Key Algorithm Mismatch');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new \RuntimeException('Server Host Key Algorithm Mismatch');
|
||||||
}
|
}
|
||||||
|
|
||||||
$packet = pack(
|
$packet = pack(
|
||||||
@ -1585,15 +1584,13 @@ class SSH2
|
|||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
|
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||||
|
|
||||||
if ($type != NET_SSH2_MSG_NEWKEYS) {
|
if ($type != NET_SSH2_MSG_NEWKEYS) {
|
||||||
user_error('Expected SSH_MSG_NEWKEYS');
|
throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
|
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
|
||||||
@ -1662,8 +1659,8 @@ class SSH2
|
|||||||
|
|
||||||
$mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_client_to_server);
|
$mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_client_to_server);
|
||||||
if ($mac_algorithm === false) {
|
if ($mac_algorithm === false) {
|
||||||
user_error('No compatible client to server message authentication algorithms found');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$createKeyLength = 0; // ie. $mac_algorithm == 'none'
|
$createKeyLength = 0; // ie. $mac_algorithm == 'none'
|
||||||
@ -1691,8 +1688,8 @@ class SSH2
|
|||||||
|
|
||||||
$mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_server_to_client);
|
$mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_server_to_client);
|
||||||
if ($mac_algorithm === false) {
|
if ($mac_algorithm === false) {
|
||||||
user_error('No compatible server to client message authentication algorithms found');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$checkKeyLength = 0;
|
$checkKeyLength = 0;
|
||||||
@ -1738,15 +1735,15 @@ class SSH2
|
|||||||
|
|
||||||
$compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_server_to_client);
|
$compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_server_to_client);
|
||||||
if ($compression_algorithm === false) {
|
if ($compression_algorithm === false) {
|
||||||
user_error('No compatible server to client compression algorithms found');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found');
|
||||||
}
|
}
|
||||||
$this->decompress = $compression_algorithm == 'zlib';
|
$this->decompress = $compression_algorithm == 'zlib';
|
||||||
|
|
||||||
$compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_client_to_server);
|
$compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_client_to_server);
|
||||||
if ($compression_algorithm === false) {
|
if ($compression_algorithm === false) {
|
||||||
user_error('No compatible client to server compression algorithms found');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found');
|
||||||
}
|
}
|
||||||
$this->compress = $compression_algorithm == 'zlib';
|
$this->compress = $compression_algorithm == 'zlib';
|
||||||
|
|
||||||
@ -1891,6 +1888,8 @@ class SSH2
|
|||||||
* @param String $username
|
* @param String $username
|
||||||
* @param optional String $password
|
* @param optional String $password
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
|
* @throws \RuntimeException on other errors
|
||||||
* @access private
|
* @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}
|
* @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.
|
* by sending dummy SSH_MSG_IGNORE messages.
|
||||||
@ -1915,15 +1914,13 @@ class SSH2
|
|||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||||
|
|
||||||
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
|
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
|
||||||
user_error('Expected SSH_MSG_SERVICE_ACCEPT');
|
throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$this->bitmap |= self::MASK_LOGIN_REQ;
|
$this->bitmap |= self::MASK_LOGIN_REQ;
|
||||||
}
|
}
|
||||||
@ -1964,8 +1961,7 @@ class SSH2
|
|||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||||
@ -2019,8 +2015,7 @@ class SSH2
|
|||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||||
@ -2096,6 +2091,7 @@ class SSH2
|
|||||||
*
|
*
|
||||||
* @param String $responses...
|
* @param String $responses...
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \RuntimeException on connection error
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _keyboard_interactive_process()
|
function _keyboard_interactive_process()
|
||||||
@ -2107,8 +2103,7 @@ class SSH2
|
|||||||
} else {
|
} else {
|
||||||
$orig = $response = $this->_get_binary_packet();
|
$orig = $response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2232,6 +2227,7 @@ class SSH2
|
|||||||
* @param String $username
|
* @param String $username
|
||||||
* @param \phpseclib\Crypt\RSA $password
|
* @param \phpseclib\Crypt\RSA $password
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \RuntimeException on connection error
|
||||||
* @access private
|
* @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}
|
* @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.
|
* by sending dummy SSH_MSG_IGNORE messages.
|
||||||
@ -2277,8 +2273,7 @@ class SSH2
|
|||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||||
@ -2312,8 +2307,7 @@ class SSH2
|
|||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||||
@ -2363,6 +2357,7 @@ class SSH2
|
|||||||
* @param String $command
|
* @param String $command
|
||||||
* @param optional Callback $callback
|
* @param optional Callback $callback
|
||||||
* @return String
|
* @return String
|
||||||
|
* @throws \RuntimeException on connection error
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function exec($command, $callback = null)
|
function exec($command, $callback = null)
|
||||||
@ -2430,8 +2425,7 @@ class SSH2
|
|||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
list(, $type) = unpack('C', $this->_string_shift($response, 1));
|
list(, $type) = unpack('C', $this->_string_shift($response, 1));
|
||||||
@ -2441,8 +2435,8 @@ class SSH2
|
|||||||
break;
|
break;
|
||||||
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
||||||
default:
|
default:
|
||||||
user_error('Unable to request pseudo-terminal');
|
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
throw new \RuntimeException('Unable to request pseudo-terminal');
|
||||||
}
|
}
|
||||||
$this->in_request_pty_exec = true;
|
$this->in_request_pty_exec = true;
|
||||||
}
|
}
|
||||||
@ -2510,6 +2504,8 @@ class SSH2
|
|||||||
* @see \phpseclib\Net\SSH2::read()
|
* @see \phpseclib\Net\SSH2::read()
|
||||||
* @see \phpseclib\Net\SSH2::write()
|
* @see \phpseclib\Net\SSH2::write()
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||||
|
* @throws \RuntimeException on other errors
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _initShell()
|
function _initShell()
|
||||||
@ -2566,8 +2562,7 @@ class SSH2
|
|||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
list(, $type) = unpack('C', $this->_string_shift($response, 1));
|
list(, $type) = unpack('C', $this->_string_shift($response, 1));
|
||||||
@ -2578,8 +2573,8 @@ class SSH2
|
|||||||
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
user_error('Unable to request pseudo-terminal');
|
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
throw new \UnexpectedValueException('Unable to request pseudo-terminal');
|
||||||
}
|
}
|
||||||
|
|
||||||
$packet = pack(
|
$packet = pack(
|
||||||
@ -2656,6 +2651,7 @@ class SSH2
|
|||||||
* @param String $expect
|
* @param String $expect
|
||||||
* @param Integer $mode
|
* @param Integer $mode
|
||||||
* @return String
|
* @return String
|
||||||
|
* @throws \RuntimeException on connection error
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function read($expect = '', $mode = self::READ_SIMPLE)
|
function read($expect = '', $mode = self::READ_SIMPLE)
|
||||||
@ -2664,13 +2660,11 @@ class SSH2
|
|||||||
$this->is_timeout = false;
|
$this->is_timeout = false;
|
||||||
|
|
||||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||||
user_error('Operation disallowed prior to login()');
|
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||||
user_error('Unable to initiate an interactive shell session');
|
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$channel = $this->_get_interactive_channel();
|
$channel = $this->_get_interactive_channel();
|
||||||
@ -2701,18 +2695,17 @@ class SSH2
|
|||||||
* @see \phpseclib\Net\SSH2::read()
|
* @see \phpseclib\Net\SSH2::read()
|
||||||
* @param String $cmd
|
* @param String $cmd
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
* @throws \RuntimeException on connection error
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function write($cmd)
|
function write($cmd)
|
||||||
{
|
{
|
||||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||||
user_error('Operation disallowed prior to login()');
|
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||||
user_error('Unable to initiate an interactive shell session');
|
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_send_channel_packet($this->_get_interactive_channel(), $cmd);
|
return $this->_send_channel_packet($this->_get_interactive_channel(), $cmd);
|
||||||
@ -2869,14 +2862,14 @@ class SSH2
|
|||||||
*
|
*
|
||||||
* @see \phpseclib\Net\SSH2::_send_binary_packet()
|
* @see \phpseclib\Net\SSH2::_send_binary_packet()
|
||||||
* @return String
|
* @return String
|
||||||
|
* @throws \RuntimeException on connection errors
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _get_binary_packet()
|
function _get_binary_packet()
|
||||||
{
|
{
|
||||||
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
||||||
user_error('Connection closed prematurely');
|
|
||||||
$this->bitmap = 0;
|
$this->bitmap = 0;
|
||||||
return false;
|
throw new \RuntimeException('Connection closed prematurely');
|
||||||
}
|
}
|
||||||
|
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
@ -2890,8 +2883,7 @@ class SSH2
|
|||||||
$raw = $this->decrypt->decrypt($raw);
|
$raw = $this->decrypt->decrypt($raw);
|
||||||
}
|
}
|
||||||
if ($raw === false) {
|
if ($raw === false) {
|
||||||
user_error('Unable to decrypt content');
|
throw new \RuntimeException('Unable to decrypt content');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5)));
|
extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5)));
|
||||||
@ -2902,17 +2894,15 @@ class SSH2
|
|||||||
// "implementations SHOULD check that the packet length is reasonable"
|
// "implementations SHOULD check that the packet length is reasonable"
|
||||||
// PuTTY uses 0x9000 as the actual max packet size and so to shall we
|
// PuTTY uses 0x9000 as the actual max packet size and so to shall we
|
||||||
if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
|
if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
|
||||||
user_error('Invalid size');
|
throw new \RuntimeException('Invalid size');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$buffer = '';
|
$buffer = '';
|
||||||
while ($remaining_length > 0) {
|
while ($remaining_length > 0) {
|
||||||
$temp = fread($this->fsock, $remaining_length);
|
$temp = fread($this->fsock, $remaining_length);
|
||||||
if ($temp === false || feof($this->fsock)) {
|
if ($temp === false || feof($this->fsock)) {
|
||||||
user_error('Error reading from socket');
|
|
||||||
$this->bitmap = 0;
|
$this->bitmap = 0;
|
||||||
return false;
|
throw new \RuntimeException('Error reading from socket');
|
||||||
}
|
}
|
||||||
$buffer.= $temp;
|
$buffer.= $temp;
|
||||||
$remaining_length-= strlen($temp);
|
$remaining_length-= strlen($temp);
|
||||||
@ -2928,12 +2918,10 @@ class SSH2
|
|||||||
if ($this->hmac_check !== false) {
|
if ($this->hmac_check !== false) {
|
||||||
$hmac = fread($this->fsock, $this->hmac_size);
|
$hmac = fread($this->fsock, $this->hmac_size);
|
||||||
if ($hmac === false || strlen($hmac) != $this->hmac_size) {
|
if ($hmac === false || strlen($hmac) != $this->hmac_size) {
|
||||||
user_error('Error reading socket');
|
|
||||||
$this->bitmap = 0;
|
$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))) {
|
} elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
|
||||||
user_error('Invalid HMAC');
|
throw new \RuntimeException('Invalid HMAC');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3161,6 +3149,7 @@ class SSH2
|
|||||||
*
|
*
|
||||||
* @param $client_channel
|
* @param $client_channel
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
|
* @throws \RuntimeException on connection error
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _get_channel_packet($client_channel, $skip_extended = false)
|
function _get_channel_packet($client_channel, $skip_extended = false)
|
||||||
@ -3193,8 +3182,7 @@ class SSH2
|
|||||||
|
|
||||||
$response = $this->_get_binary_packet();
|
$response = $this->_get_binary_packet();
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
user_error('Connection closed by server');
|
throw new \RuntimeException('Connection closed by server');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if ($client_channel == -1 && $response === true) {
|
if ($client_channel == -1 && $response === true) {
|
||||||
return true;
|
return true;
|
||||||
@ -3243,8 +3231,8 @@ class SSH2
|
|||||||
return $result;
|
return $result;
|
||||||
//case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
|
//case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
|
||||||
default:
|
default:
|
||||||
user_error('Unable to open channel');
|
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
throw new \RuntimeException('Unable to open channel');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
case NET_SSH2_MSG_CHANNEL_REQUEST:
|
||||||
@ -3254,8 +3242,8 @@ class SSH2
|
|||||||
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
user_error('Unable to fulfill channel request');
|
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
throw new \RuntimeException('Unable to fulfill channel request');
|
||||||
}
|
}
|
||||||
case NET_SSH2_MSG_CHANNEL_CLOSE:
|
case NET_SSH2_MSG_CHANNEL_CLOSE:
|
||||||
return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended);
|
return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended);
|
||||||
@ -3364,8 +3352,8 @@ class SSH2
|
|||||||
case NET_SSH2_MSG_CHANNEL_EOF:
|
case NET_SSH2_MSG_CHANNEL_EOF:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
user_error('Error reading channel data');
|
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
throw new \RuntimeException('Error reading channel data');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3384,9 +3372,8 @@ class SSH2
|
|||||||
function _send_binary_packet($data, $logged = null)
|
function _send_binary_packet($data, $logged = null)
|
||||||
{
|
{
|
||||||
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
||||||
user_error('Connection closed prematurely');
|
|
||||||
$this->bitmap = 0;
|
$this->bitmap = 0;
|
||||||
return false;
|
throw new \RuntimeException('Connection closed prematurely');
|
||||||
}
|
}
|
||||||
|
|
||||||
//if ($this->compress) {
|
//if ($this->compress) {
|
||||||
@ -3945,6 +3932,8 @@ class SSH2
|
|||||||
* is recommended. Returns false if the server signature is not signed correctly with the public host key.
|
* is recommended. Returns false if the server signature is not signed correctly with the public host key.
|
||||||
*
|
*
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
|
* @throws \RuntimeException on badly formatted keys
|
||||||
|
* @throws \phpseclib\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function getServerPublicHostKey()
|
function getServerPublicHostKey()
|
||||||
@ -3990,8 +3979,8 @@ class SSH2
|
|||||||
padding, unsigned, and in network byte order). */
|
padding, unsigned, and in network byte order). */
|
||||||
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
|
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
|
||||||
if ($temp['length'] != 40) {
|
if ($temp['length'] != 40) {
|
||||||
user_error('Invalid signature');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new \RuntimeException('Invalid signature');
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = new BigInteger($this->_string_shift($signature, 20), 256);
|
$r = new BigInteger($this->_string_shift($signature, 20), 256);
|
||||||
@ -4002,8 +3991,8 @@ class SSH2
|
|||||||
case $r->compare($q) >= 0:
|
case $r->compare($q) >= 0:
|
||||||
case $s->equals($zero):
|
case $s->equals($zero):
|
||||||
case $s->compare($q) >= 0:
|
case $s->compare($q) >= 0:
|
||||||
user_error('Invalid signature');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new \RuntimeException('Invalid signature');
|
||||||
}
|
}
|
||||||
|
|
||||||
$w = $s->modInverse($q);
|
$w = $s->modInverse($q);
|
||||||
@ -4022,7 +4011,7 @@ class SSH2
|
|||||||
list(, $v) = $v->divide($q);
|
list(, $v) = $v->divide($q);
|
||||||
|
|
||||||
if (!$v->equals($r)) {
|
if (!$v->equals($r)) {
|
||||||
user_error('Bad server signature');
|
//user_error('Bad server signature');
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4044,7 +4033,7 @@ class SSH2
|
|||||||
$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
|
$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
|
||||||
$rsa->loadKey(array('e' => $e, 'n' => $n), RSA::PUBLIC_FORMAT_RAW);
|
$rsa->loadKey(array('e' => $e, 'n' => $n), RSA::PUBLIC_FORMAT_RAW);
|
||||||
if (!$rsa->verify($this->exchange_hash, $signature)) {
|
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);
|
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -4059,8 +4048,8 @@ class SSH2
|
|||||||
// also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
|
// also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
|
||||||
|
|
||||||
if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) {
|
if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) {
|
||||||
user_error('Invalid signature');
|
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
throw new \RuntimeException('Invalid signature');
|
||||||
}
|
}
|
||||||
|
|
||||||
$s = $s->modPow($e, $n);
|
$s = $s->modPow($e, $n);
|
||||||
@ -4070,13 +4059,13 @@ class SSH2
|
|||||||
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
|
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
|
||||||
|
|
||||||
if ($s != $h) {
|
if ($s != $h) {
|
||||||
user_error('Bad server signature');
|
//user_error('Bad server signature');
|
||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
user_error('Unsupported signature format');
|
$this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||||
return $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);
|
return $this->signature_format . ' ' . base64_encode($this->server_public_host_key);
|
||||||
|
@ -35,6 +35,7 @@ namespace phpseclib\System\SSH;
|
|||||||
|
|
||||||
use phpseclib\Crypt\RSA;
|
use phpseclib\Crypt\RSA;
|
||||||
use phpseclib\System\SSH\Agent\Identity;
|
use phpseclib\System\SSH\Agent\Identity;
|
||||||
|
use phpseclib\Exception\BadConfigurationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pure-PHP ssh-agent client identity factory
|
* Pure-PHP ssh-agent client identity factory
|
||||||
@ -115,6 +116,8 @@ class Agent
|
|||||||
* Default Constructor
|
* Default Constructor
|
||||||
*
|
*
|
||||||
* @return \phpseclib\System\SSH\Agent
|
* @return \phpseclib\System\SSH\Agent
|
||||||
|
* @throws \phpseclib\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found
|
||||||
|
* @throws \RuntimeException on connection errors
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function __construct()
|
function __construct()
|
||||||
@ -127,13 +130,12 @@ class Agent
|
|||||||
$address = $_ENV['SSH_AUTH_SOCK'];
|
$address = $_ENV['SSH_AUTH_SOCK'];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
user_error('SSH_AUTH_SOCK not found');
|
throw new \BadConfigurationException('SSH_AUTH_SOCK not found');
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
|
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
|
||||||
if (!$this->fsock) {
|
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
|
* Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects
|
||||||
*
|
*
|
||||||
* @return Array
|
* @return Array
|
||||||
|
* @throws \RuntimeException on receipt of unexpected packets
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function requestIdentities()
|
function requestIdentities()
|
||||||
@ -154,13 +157,13 @@ class Agent
|
|||||||
|
|
||||||
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
|
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
|
||||||
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
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)));
|
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||||
$type = ord(fread($this->fsock, 1));
|
$type = ord(fread($this->fsock, 1));
|
||||||
if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
|
if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
|
||||||
user_error('Unable to request identities');
|
throw new \RuntimeException('Unable to request identities');
|
||||||
}
|
}
|
||||||
|
|
||||||
$identities = array();
|
$identities = array();
|
||||||
@ -271,6 +274,7 @@ class Agent
|
|||||||
*
|
*
|
||||||
* @param String $data
|
* @param String $data
|
||||||
* @return data from SSH Agent
|
* @return data from SSH Agent
|
||||||
|
* @throws \RuntimeException on connection errors
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _forward_data($data)
|
function _forward_data($data)
|
||||||
@ -289,7 +293,7 @@ class Agent
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
|
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 = '';
|
$this->socket_buffer = '';
|
||||||
|
@ -134,6 +134,7 @@ class Identity
|
|||||||
*
|
*
|
||||||
* @param String $message
|
* @param String $message
|
||||||
* @return String
|
* @return String
|
||||||
|
* @throws \RuntimeException on connection errors
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function sign($message)
|
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('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);
|
$packet = pack('Na*', strlen($packet), $packet);
|
||||||
if (strlen($packet) != fputs($this->fsock, $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)));
|
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||||
$type = ord(fread($this->fsock, 1));
|
$type = ord(fread($this->fsock, 1));
|
||||||
if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
|
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);
|
$signature_blob = fread($this->fsock, $length - 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user