update to phpseclib 2.0.6

This commit is contained in:
Roland Gruber 2017-09-16 15:09:25 +02:00
parent aa435cecfb
commit 0e251a3244
31 changed files with 33503 additions and 33988 deletions

View File

@ -5,7 +5,7 @@
* *
* Uses mcrypt, if available/possible, and an internal implementation, otherwise. * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
* just a wrapper to Rijndael.php you may consider using Rijndael.php instead of * just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
@ -16,16 +16,16 @@
* it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()} * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
* is called, again, at which point, it'll be recalculated. * is called, again, at which point, it'll be recalculated.
* *
* Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't
* make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function, * make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function,
* however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one). * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
* *
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/AES.php'; * include 'vendor/autoload.php';
* *
* $aes = new Crypt_AES(); * $aes = new \phpseclib\Crypt\AES();
* *
* $aes->setKey('abcdefghijklmnop'); * $aes->setKey('abcdefghijklmnop');
* *
@ -39,102 +39,31 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_AES * @package AES
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2008 Jim Wigginton * @copyright 2008 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/** namespace phpseclib\Crypt;
* Include Crypt_Rijndael
*/
if (!class_exists('Crypt_Rijndael')) {
include_once 'Rijndael.php';
}
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_AES_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_AES_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_AES_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/** /**
* Pure-PHP implementation of AES. * Pure-PHP implementation of AES.
* *
* @package Crypt_AES * @package AES
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class Crypt_AES extends Crypt_Rijndael class AES extends Rijndael
{ {
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'AES';
/** /**
* Dummy function * Dummy function
* *
* Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything. * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything.
* *
* @see Crypt_Rijndael::setBlockLength() * @see \phpseclib\Crypt\Rijndael::setBlockLength()
* @access public * @access public
* @param int $length * @param int $length
*/ */
@ -149,7 +78,7 @@ class Crypt_AES extends Crypt_Rijndael
* Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to * Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount. * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
* *
* @see Crypt_Rijndael:setKeyLength() * @see \phpseclib\Crypt\Rijndael:setKeyLength()
* @access public * @access public
* @param int $length * @param int $length
*/ */
@ -170,7 +99,7 @@ class Crypt_AES extends Crypt_Rijndael
* *
* Rijndael supports five different key lengths, AES only supports three. * Rijndael supports five different key lengths, AES only supports three.
* *
* @see Crypt_Rijndael:setKey() * @see \phpseclib\Crypt\Rijndael:setKey()
* @see setKeyLength() * @see setKeyLength()
* @access public * @access public
* @param string $key * @param string $key

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
* *
* Uses mcrypt, if available, and an internal implementation, otherwise. * Uses mcrypt, if available, and an internal implementation, otherwise.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* Useful resources are as follows: * Useful resources are as follows:
* *
@ -14,9 +14,9 @@
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/Blowfish.php'; * include 'vendor/autoload.php';
* *
* $blowfish = new Crypt_Blowfish(); * $blowfish = new \phpseclib\Crypt\Blowfish();
* *
* $blowfish->setKey('12345678901234567890123456789012'); * $blowfish->setKey('12345678901234567890123456789012');
* *
@ -26,26 +26,8 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_Blowfish * @package Blowfish
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com> * @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @copyright 2007 Jim Wigginton * @copyright 2007 Jim Wigginton
@ -53,86 +35,31 @@
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/** namespace phpseclib\Crypt;
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_BLOWFISH_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_BLOWFISH_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_BLOWFISH_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_BLOWFISH_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/** /**
* Pure-PHP implementation of Blowfish. * Pure-PHP implementation of Blowfish.
* *
* @package Crypt_Blowfish * @package Blowfish
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com> * @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @access public * @access public
*/ */
class Crypt_Blowfish extends Crypt_Base class Blowfish extends Base
{ {
/** /**
* Block Length of the cipher * Block Length of the cipher
* *
* @see Crypt_Base::block_size * @see \phpseclib\Crypt\Base::block_size
* @var int * @var int
* @access private * @access private
*/ */
var $block_size = 8; var $block_size = 8;
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'BLOWFISH';
/** /**
* The mcrypt specific name of the cipher * The mcrypt specific name of the cipher
* *
* @see Crypt_Base::cipher_name_mcrypt * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
* @var string * @var string
* @access private * @access private
*/ */
@ -141,7 +68,7 @@ class Crypt_Blowfish extends Crypt_Base
/** /**
* Optimizing value while CFB-encrypting * Optimizing value while CFB-encrypting
* *
* @see Crypt_Base::cfb_init_len * @see \phpseclib\Crypt\Base::cfb_init_len
* @var int * @var int
* @access private * @access private
*/ */
@ -346,7 +273,7 @@ class Crypt_Blowfish extends Crypt_Base
/** /**
* The Key Length (in bytes) * The Key Length (in bytes)
* *
* @see Crypt_Base::setKeyLength() * @see \phpseclib\Crypt\Base::setKeyLength()
* @var int * @var int
* @access private * @access private
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
@ -380,17 +307,20 @@ class Crypt_Blowfish extends Crypt_Base
/** /**
* Test for engine validity * Test for engine validity
* *
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
* *
* @see Crypt_Base::isValidEngine() * @see \phpseclib\Crypt\Base::isValidEngine()
* @param int $engine * @param int $engine
* @access public * @access public
* @return bool * @return bool
*/ */
function isValidEngine($engine) function isValidEngine($engine)
{ {
if ($engine == CRYPT_ENGINE_OPENSSL) { if ($engine == self::ENGINE_OPENSSL) {
if ($this->key_length != 16) { if (version_compare(PHP_VERSION, '5.3.7') < 0 && $this->key_length != 16) {
return false;
}
if ($this->key_length < 16) {
return false; return false;
} }
$this->cipher_name_openssl_ecb = 'bf-ecb'; $this->cipher_name_openssl_ecb = 'bf-ecb';
@ -403,7 +333,7 @@ class Crypt_Blowfish extends Crypt_Base
/** /**
* Setup the key (expansion) * Setup the key (expansion)
* *
* @see Crypt_Base::_setupKey() * @see \phpseclib\Crypt\Base::_setupKey()
* @access private * @access private
*/ */
function _setupKey() function _setupKey()
@ -530,15 +460,15 @@ class Crypt_Blowfish extends Crypt_Base
/** /**
* Setup the performance-optimized function for de/encrypt() * Setup the performance-optimized function for de/encrypt()
* *
* @see Crypt_Base::_setupInlineCrypt() * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
* @access private * @access private
*/ */
function _setupInlineCrypt() function _setupInlineCrypt()
{ {
$lambda_functions =& Crypt_Blowfish::_getLambdaFunctions(); $lambda_functions =& self::_getLambdaFunctions();
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
// (Currently, for Crypt_Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit) // (Currently, for Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one. // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10); $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);

View File

@ -5,7 +5,7 @@
* *
* Uses mcrypt, if available, and an internal implementation, otherwise. * Uses mcrypt, if available, and an internal implementation, otherwise.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* Useful resources are as follows: * Useful resources are as follows:
* *
@ -16,9 +16,9 @@
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/DES.php'; * include 'vendor/autoload.php';
* *
* $des = new Crypt_DES(); * $des = new \phpseclib\Crypt\DES();
* *
* $des->setKey('abcdefgh'); * $des->setKey('abcdefgh');
* *
@ -32,108 +32,44 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_DES * @package DES
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton * @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/** namespace phpseclib\Crypt;
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access private
* @see self::_setupKey()
* @see self::_processBlock()
*/
/**
* Contains $keys[CRYPT_DES_ENCRYPT]
*/
define('CRYPT_DES_ENCRYPT', 0);
/**
* Contains $keys[CRYPT_DES_DECRYPT]
*/
define('CRYPT_DES_DECRYPT', 1);
/**#@-*/
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_DES_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_DES_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_DES_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_DES_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_DES_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/** /**
* Pure-PHP implementation of DES. * Pure-PHP implementation of DES.
* *
* @package Crypt_DES * @package DES
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class Crypt_DES extends Crypt_Base class DES extends Base
{ {
/**#@+
* @access private
* @see \phpseclib\Crypt\DES::_setupKey()
* @see \phpseclib\Crypt\DES::_processBlock()
*/
/**
* Contains $keys[self::ENCRYPT]
*/
const ENCRYPT = 0;
/**
* Contains $keys[self::DECRYPT]
*/
const DECRYPT = 1;
/**#@-*/
/** /**
* Block Length of the cipher * Block Length of the cipher
* *
* @see Crypt_Base::block_size * @see \phpseclib\Crypt\Base::block_size
* @var int * @var int
* @access private * @access private
*/ */
@ -142,25 +78,16 @@ class Crypt_DES extends Crypt_Base
/** /**
* Key Length (in bytes) * Key Length (in bytes)
* *
* @see Crypt_Base::setKeyLength() * @see \phpseclib\Crypt\Base::setKeyLength()
* @var int * @var int
* @access private * @access private
*/ */
var $key_length = 8; var $key_length = 8;
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'DES';
/** /**
* The mcrypt specific name of the cipher * The mcrypt specific name of the cipher
* *
* @see Crypt_Base::cipher_name_mcrypt * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
* @var string * @var string
* @access private * @access private
*/ */
@ -169,22 +96,22 @@ class Crypt_DES extends Crypt_Base
/** /**
* The OpenSSL names of the cipher / modes * The OpenSSL names of the cipher / modes
* *
* @see Crypt_Base::openssl_mode_names * @see \phpseclib\Crypt\Base::openssl_mode_names
* @var array * @var array
* @access private * @access private
*/ */
var $openssl_mode_names = array( var $openssl_mode_names = array(
CRYPT_MODE_ECB => 'des-ecb', self::MODE_ECB => 'des-ecb',
CRYPT_MODE_CBC => 'des-cbc', self::MODE_CBC => 'des-cbc',
CRYPT_MODE_CFB => 'des-cfb', self::MODE_CFB => 'des-cfb',
CRYPT_MODE_OFB => 'des-ofb' self::MODE_OFB => 'des-ofb'
// CRYPT_MODE_CTR is undefined for DES // self::MODE_CTR is undefined for DES
); );
/** /**
* Optimizing value while CFB-encrypting * Optimizing value while CFB-encrypting
* *
* @see Crypt_Base::cfb_init_len * @see \phpseclib\Crypt\Base::cfb_init_len
* @var int * @var int
* @access private * @access private
*/ */
@ -193,7 +120,7 @@ class Crypt_DES extends Crypt_Base
/** /**
* Switch for DES/3DES encryption * Switch for DES/3DES encryption
* *
* Used only if $engine == CRYPT_DES_MODE_INTERNAL * Used only if $engine == self::ENGINE_INTERNAL
* *
* @see self::_setupKey() * @see self::_setupKey()
* @see self::_processBlock() * @see self::_processBlock()
@ -654,9 +581,9 @@ class Crypt_DES extends Crypt_Base
/** /**
* Test for engine validity * Test for engine validity
* *
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
* *
* @see Crypt_Base::isValidEngine() * @see \phpseclib\Crypt\Base::isValidEngine()
* @param int $engine * @param int $engine
* @access public * @access public
* @return bool * @return bool
@ -664,7 +591,7 @@ class Crypt_DES extends Crypt_Base
function isValidEngine($engine) function isValidEngine($engine)
{ {
if ($this->key_length_max == 8) { if ($this->key_length_max == 8) {
if ($engine == CRYPT_ENGINE_OPENSSL) { if ($engine == self::ENGINE_OPENSSL) {
$this->cipher_name_openssl_ecb = 'des-ecb'; $this->cipher_name_openssl_ecb = 'des-ecb';
$this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode(); $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
} }
@ -684,7 +611,7 @@ class Crypt_DES extends Crypt_Base
* *
* If the key is not explicitly set, it'll be assumed to be all zero's. * If the key is not explicitly set, it'll be assumed to be all zero's.
* *
* @see Crypt_Base::setKey() * @see \phpseclib\Crypt\Base::setKey()
* @access public * @access public
* @param string $key * @param string $key
*/ */
@ -703,8 +630,8 @@ class Crypt_DES extends Crypt_Base
/** /**
* Encrypts a block * Encrypts a block
* *
* @see Crypt_Base::_encryptBlock() * @see \phpseclib\Crypt\Base::_encryptBlock()
* @see Crypt_Base::encrypt() * @see \phpseclib\Crypt\Base::encrypt()
* @see self::encrypt() * @see self::encrypt()
* @access private * @access private
* @param string $in * @param string $in
@ -712,14 +639,14 @@ class Crypt_DES extends Crypt_Base
*/ */
function _encryptBlock($in) function _encryptBlock($in)
{ {
return $this->_processBlock($in, CRYPT_DES_ENCRYPT); return $this->_processBlock($in, self::ENCRYPT);
} }
/** /**
* Decrypts a block * Decrypts a block
* *
* @see Crypt_Base::_decryptBlock() * @see \phpseclib\Crypt\Base::_decryptBlock()
* @see Crypt_Base::decrypt() * @see \phpseclib\Crypt\Base::decrypt()
* @see self::decrypt() * @see self::decrypt()
* @access private * @access private
* @param string $in * @param string $in
@ -727,13 +654,13 @@ class Crypt_DES extends Crypt_Base
*/ */
function _decryptBlock($in) function _decryptBlock($in)
{ {
return $this->_processBlock($in, CRYPT_DES_DECRYPT); return $this->_processBlock($in, self::DECRYPT);
} }
/** /**
* Encrypts or decrypts a 64-bit block * Encrypts or decrypts a 64-bit block
* *
* $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See * $mode should be either self::ENCRYPT or self::DECRYPT. See
* {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
* idea of what this function does. * idea of what this function does.
* *
@ -822,7 +749,7 @@ class Crypt_DES extends Crypt_Base
/** /**
* Creates the key schedule * Creates the key schedule
* *
* @see Crypt_Base::_setupKey() * @see \phpseclib\Crypt\Base::_setupKey()
* @access private * @access private
*/ */
function _setupKey() function _setupKey()
@ -1303,8 +1230,8 @@ class Crypt_DES extends Crypt_Base
$d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F); $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
$keys[$des_round] = array( $keys[$des_round] = array(
CRYPT_DES_ENCRYPT => array(), self::ENCRYPT => array(),
CRYPT_DES_DECRYPT => array_fill(0, 32, 0) self::DECRYPT => array_fill(0, 32, 0)
); );
for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) { for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) {
$c <<= $shifts[$i]; $c <<= $shifts[$i];
@ -1323,33 +1250,33 @@ class Crypt_DES extends Crypt_Base
(($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF); (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF);
$val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) | $val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
(($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF); (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF);
$keys[$des_round][CRYPT_DES_ENCRYPT][ ] = $val1; $keys[$des_round][self::ENCRYPT][ ] = $val1;
$keys[$des_round][CRYPT_DES_DECRYPT][$ki - 1] = $val1; $keys[$des_round][self::DECRYPT][$ki - 1] = $val1;
$keys[$des_round][CRYPT_DES_ENCRYPT][ ] = $val2; $keys[$des_round][self::ENCRYPT][ ] = $val2;
$keys[$des_round][CRYPT_DES_DECRYPT][$ki ] = $val2; $keys[$des_round][self::DECRYPT][$ki ] = $val2;
} }
} }
switch ($this->des_rounds) { switch ($this->des_rounds) {
case 3: // 3DES keys case 3: // 3DES keys
$this->keys = array( $this->keys = array(
CRYPT_DES_ENCRYPT => array_merge( self::ENCRYPT => array_merge(
$keys[0][CRYPT_DES_ENCRYPT], $keys[0][self::ENCRYPT],
$keys[1][CRYPT_DES_DECRYPT], $keys[1][self::DECRYPT],
$keys[2][CRYPT_DES_ENCRYPT] $keys[2][self::ENCRYPT]
), ),
CRYPT_DES_DECRYPT => array_merge( self::DECRYPT => array_merge(
$keys[2][CRYPT_DES_DECRYPT], $keys[2][self::DECRYPT],
$keys[1][CRYPT_DES_ENCRYPT], $keys[1][self::ENCRYPT],
$keys[0][CRYPT_DES_DECRYPT] $keys[0][self::DECRYPT]
) )
); );
break; break;
// case 1: // DES keys // case 1: // DES keys
default: default:
$this->keys = array( $this->keys = array(
CRYPT_DES_ENCRYPT => $keys[0][CRYPT_DES_ENCRYPT], self::ENCRYPT => $keys[0][self::ENCRYPT],
CRYPT_DES_DECRYPT => $keys[0][CRYPT_DES_DECRYPT] self::DECRYPT => $keys[0][self::DECRYPT]
); );
} }
} }
@ -1357,12 +1284,12 @@ class Crypt_DES extends Crypt_Base
/** /**
* Setup the performance-optimized function for de/encrypt() * Setup the performance-optimized function for de/encrypt()
* *
* @see Crypt_Base::_setupInlineCrypt() * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
* @access private * @access private
*/ */
function _setupInlineCrypt() function _setupInlineCrypt()
{ {
$lambda_functions =& Crypt_DES::_getLambdaFunctions(); $lambda_functions =& self::_getLambdaFunctions();
// Engine configuration for: // Engine configuration for:
// - DES ($des_rounds == 1) or // - DES ($des_rounds == 1) or
@ -1370,12 +1297,12 @@ class Crypt_DES extends Crypt_Base
$des_rounds = $this->des_rounds; $des_rounds = $this->des_rounds;
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
// (Currently, for Crypt_DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit) // (Currently, for DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
// (Currently, for Crypt_TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit) // (Currently, for TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 ); $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
// Generation of a uniqe hash for our generated code // Generation of a unique hash for our generated code
$code_hash = "Crypt_DES, $des_rounds, {$this->mode}"; $code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
if ($gen_hi_opt_code) { if ($gen_hi_opt_code) {
// For hi-optimized code, we create for each combination of // For hi-optimized code, we create for each combination of
@ -1413,8 +1340,8 @@ class Crypt_DES extends Crypt_Base
// No futher initialisation of the $keys schedule is necessary. // No futher initialisation of the $keys schedule is necessary.
// That is the extra performance boost. // That is the extra performance boost.
$k = array( $k = array(
CRYPT_DES_ENCRYPT => $this->keys[CRYPT_DES_ENCRYPT], self::ENCRYPT => $this->keys[self::ENCRYPT],
CRYPT_DES_DECRYPT => $this->keys[CRYPT_DES_DECRYPT] self::DECRYPT => $this->keys[self::DECRYPT]
); );
$init_encrypt = ''; $init_encrypt = '';
$init_decrypt = ''; $init_decrypt = '';
@ -1423,21 +1350,21 @@ class Crypt_DES extends Crypt_Base
// In generic optimized code mode, we have to use, as the best compromise [currently], // In generic optimized code mode, we have to use, as the best compromise [currently],
// our key schedule as $ke/$kd arrays. (with hardcoded indexes...) // our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
$k = array( $k = array(
CRYPT_DES_ENCRYPT => array(), self::ENCRYPT => array(),
CRYPT_DES_DECRYPT => array() self::DECRYPT => array()
); );
for ($i = 0, $c = count($this->keys[CRYPT_DES_ENCRYPT]); $i < $c; ++$i) { for ($i = 0, $c = count($this->keys[self::ENCRYPT]); $i < $c; ++$i) {
$k[CRYPT_DES_ENCRYPT][$i] = '$ke[' . $i . ']'; $k[self::ENCRYPT][$i] = '$ke[' . $i . ']';
$k[CRYPT_DES_DECRYPT][$i] = '$kd[' . $i . ']'; $k[self::DECRYPT][$i] = '$kd[' . $i . ']';
} }
$init_encrypt = '$ke = $self->keys[CRYPT_DES_ENCRYPT];'; $init_encrypt = '$ke = $self->keys[self::ENCRYPT];';
$init_decrypt = '$kd = $self->keys[CRYPT_DES_DECRYPT];'; $init_decrypt = '$kd = $self->keys[self::DECRYPT];';
break; break;
} }
// Creating code for en- and decryption. // Creating code for en- and decryption.
$crypt_block = array(); $crypt_block = array();
foreach (array(CRYPT_DES_ENCRYPT, CRYPT_DES_DECRYPT) as $c) { foreach (array(self::ENCRYPT, self::DECRYPT) as $c) {
/* Do the initial IP permutation. */ /* Do the initial IP permutation. */
$crypt_block[$c] = ' $crypt_block[$c] = '
$in = unpack("N*", $in); $in = unpack("N*", $in);
@ -1504,8 +1431,8 @@ class Crypt_DES extends Crypt_Base
'init_crypt' => $init_crypt, 'init_crypt' => $init_crypt,
'init_encrypt' => $init_encrypt, 'init_encrypt' => $init_encrypt,
'init_decrypt' => $init_decrypt, 'init_decrypt' => $init_decrypt,
'encrypt_block' => $crypt_block[CRYPT_DES_ENCRYPT], 'encrypt_block' => $crypt_block[self::ENCRYPT],
'decrypt_block' => $crypt_block[CRYPT_DES_DECRYPT] 'decrypt_block' => $crypt_block[self::DECRYPT]
) )
); );
} }

View File

@ -10,7 +10,7 @@
* If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to * If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to
* the hash. If no valid algorithm is provided, sha1 will be used. * the hash. If no valid algorithm is provided, sha1 will be used.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* {@internal The variable names are the same as those in * {@internal The variable names are the same as those in
* {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}} * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
@ -18,9 +18,9 @@
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/Hash.php'; * include 'vendor/autoload.php';
* *
* $hash = new Crypt_Hash('sha1'); * $hash = new \phpseclib\Crypt\Hash('sha1');
* *
* $hash->setKey('abcdefg'); * $hash->setKey('abcdefg');
* *
@ -28,59 +28,45 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_Hash * @package Hash
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton * @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/**#@+ namespace phpseclib\Crypt;
* @access private
* @see self::Crypt_Hash() use phpseclib\Math\BigInteger;
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_HASH_MODE_INTERNAL', 1);
/**
* Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
*/
define('CRYPT_HASH_MODE_MHASH', 2);
/**
* Toggles the hash() implementation, which works on PHP 5.1.2+.
*/
define('CRYPT_HASH_MODE_HASH', 3);
/**#@-*/
/** /**
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions. * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
* *
* @package Crypt_Hash * @package Hash
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class Crypt_Hash class Hash
{ {
/**#@+
* @access private
* @see \phpseclib\Crypt\Hash::__construct()
*/
/**
* Toggles the internal implementation
*/
const MODE_INTERNAL = 1;
/**
* Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
*/
const MODE_MHASH = 2;
/**
* Toggles the hash() implementation, which works on PHP 5.1.2+.
*/
const MODE_HASH = 3;
/**#@-*/
/** /**
* Hash Parameter * Hash Parameter
* *
@ -148,21 +134,21 @@ class Crypt_Hash
* Default Constructor. * Default Constructor.
* *
* @param string $hash * @param string $hash
* @return Crypt_Hash * @return \phpseclib\Crypt\Hash
* @access public * @access public
*/ */
function Crypt_Hash($hash = 'sha1') function __construct($hash = 'sha1')
{ {
if (!defined('CRYPT_HASH_MODE')) { if (!defined('CRYPT_HASH_MODE')) {
switch (true) { switch (true) {
case extension_loaded('hash'): case extension_loaded('hash'):
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH); define('CRYPT_HASH_MODE', self::MODE_HASH);
break; break;
case extension_loaded('mhash'): case extension_loaded('mhash'):
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH); define('CRYPT_HASH_MODE', self::MODE_MHASH);
break; break;
default: default:
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL); define('CRYPT_HASH_MODE', self::MODE_INTERNAL);
} }
} }
@ -231,19 +217,19 @@ class Crypt_Hash
switch ($hash) { switch ($hash) {
case 'md2': case 'md2':
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ? $mode = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ?
CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL; self::MODE_HASH : self::MODE_INTERNAL;
break; break;
case 'sha384': case 'sha384':
case 'sha512': case 'sha512':
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE; $mode = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
break; break;
default: default:
$mode = CRYPT_HASH_MODE; $mode = CRYPT_HASH_MODE;
} }
switch ($mode) { switch ($mode) {
case CRYPT_HASH_MODE_MHASH: case self::MODE_MHASH:
switch ($hash) { switch ($hash) {
case 'md5': case 'md5':
$this->hash = MHASH_MD5; $this->hash = MHASH_MD5;
@ -256,7 +242,7 @@ class Crypt_Hash
$this->hash = MHASH_SHA1; $this->hash = MHASH_SHA1;
} }
return; return;
case CRYPT_HASH_MODE_HASH: case self::MODE_HASH:
switch ($hash) { switch ($hash) {
case 'md5': case 'md5':
$this->hash = 'md5'; $this->hash = 'md5';
@ -311,17 +297,17 @@ class Crypt_Hash
*/ */
function hash($text) function hash($text)
{ {
$mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE; $mode = is_array($this->hash) ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
if (!empty($this->key) || is_string($this->key)) { if (!empty($this->key) || is_string($this->key)) {
switch ($mode) { switch ($mode) {
case CRYPT_HASH_MODE_MHASH: case self::MODE_MHASH:
$output = mhash($this->hash, $text, $this->key); $output = mhash($this->hash, $text, $this->key);
break; break;
case CRYPT_HASH_MODE_HASH: case self::MODE_HASH:
$output = hash_hmac($this->hash, $text, $this->key, true); $output = hash_hmac($this->hash, $text, $this->key, true);
break; break;
case CRYPT_HASH_MODE_INTERNAL: case self::MODE_INTERNAL:
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
resultant L byte string as the actual key to HMAC." resultant L byte string as the actual key to HMAC."
@ -338,13 +324,13 @@ class Crypt_Hash
} }
} else { } else {
switch ($mode) { switch ($mode) {
case CRYPT_HASH_MODE_MHASH: case self::MODE_MHASH:
$output = mhash($this->hash, $text); $output = mhash($this->hash, $text);
break; break;
case CRYPT_HASH_MODE_HASH: case self::MODE_HASH:
$output = hash($this->hash, $text, true); $output = hash($this->hash, $text, true);
break; break;
case CRYPT_HASH_MODE_INTERNAL: case self::MODE_INTERNAL:
$output = call_user_func($this->hash, $text); $output = call_user_func($this->hash, $text);
} }
} }
@ -520,7 +506,6 @@ class Crypt_Hash
$this->_rightShift( $w[$i - 2], 10); $this->_rightShift( $w[$i - 2], 10);
// @codingStandardsIgnoreEnd // @codingStandardsIgnoreEnd
$w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1); $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
} }
// Initialize hash value for this chunk // Initialize hash value for this chunk
@ -578,10 +563,6 @@ class Crypt_Hash
*/ */
function _sha512($m) function _sha512($m)
{ {
if (!class_exists('Math_BigInteger')) {
include_once 'Math/BigInteger.php';
}
static $init384, $init512, $k; static $init384, $init512, $k;
if (!isset($k)) { if (!isset($k)) {
@ -596,9 +577,9 @@ class Crypt_Hash
); );
for ($i = 0; $i < 8; $i++) { for ($i = 0; $i < 8; $i++) {
$init384[$i] = new Math_BigInteger($init384[$i], 16); $init384[$i] = new BigInteger($init384[$i], 16);
$init384[$i]->setPrecision(64); $init384[$i]->setPrecision(64);
$init512[$i] = new Math_BigInteger($init512[$i], 16); $init512[$i] = new BigInteger($init512[$i], 16);
$init512[$i]->setPrecision(64); $init512[$i]->setPrecision(64);
} }
@ -628,7 +609,7 @@ class Crypt_Hash
); );
for ($i = 0; $i < 80; $i++) { for ($i = 0; $i < 80; $i++) {
$k[$i] = new Math_BigInteger($k[$i], 16); $k[$i] = new BigInteger($k[$i], 16);
} }
} }
@ -647,7 +628,7 @@ class Crypt_Hash
foreach ($chunks as $chunk) { foreach ($chunks as $chunk) {
$w = array(); $w = array();
for ($i = 0; $i < 16; $i++) { for ($i = 0; $i < 16; $i++) {
$temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256); $temp = new BigInteger($this->_string_shift($chunk, 8), 256);
$temp->setPrecision(64); $temp->setPrecision(64);
$w[] = $temp; $w[] = $temp;
} }
@ -743,7 +724,7 @@ class Crypt_Hash
} }
// Produce the final hash value (big-endian) // Produce the final hash value (big-endian)
// (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) // (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
$temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
$hash[4]->toBytes() . $hash[5]->toBytes(); $hash[4]->toBytes() . $hash[5]->toBytes();
if ($this->l != 48) { if ($this->l != 48) {
@ -801,7 +782,7 @@ class Crypt_Hash
* Add * Add
* *
* _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
* possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster. * possibility of overflow exists, care has to be taken. BigInteger could be used but this should be faster.
* *
* @param int $... * @param int $...
* @return int * @return int

View File

@ -5,7 +5,7 @@
* *
* Uses mcrypt, if available, and an internal implementation, otherwise. * Uses mcrypt, if available, and an internal implementation, otherwise.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* Useful resources are as follows: * Useful resources are as follows:
* *
@ -14,9 +14,9 @@
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/RC2.php'; * include 'vendor/autoload.php';
* *
* $rc2 = new Crypt_RC2(); * $rc2 = new \phpseclib\Crypt\RC2();
* *
* $rc2->setKey('abcdefgh'); * $rc2->setKey('abcdefgh');
* *
@ -26,91 +26,27 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_RC2 * @package RC2
* @author Patrick Monnerat <pm@datasphere.ch> * @author Patrick Monnerat <pm@datasphere.ch>
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/** namespace phpseclib\Crypt;
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_RC2_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_RC2_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_RC2_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_RC2_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/** /**
* Pure-PHP implementation of RC2. * Pure-PHP implementation of RC2.
* *
* @package Crypt_RC2 * @package RC2
* @access public * @access public
*/ */
class Crypt_RC2 extends Crypt_Base class RC2 extends Base
{ {
/** /**
* Block Length of the cipher * Block Length of the cipher
* *
* @see Crypt_Base::block_size * @see \phpseclib\Crypt\Base::block_size
* @var int * @var int
* @access private * @access private
*/ */
@ -119,7 +55,7 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* The Key * The Key
* *
* @see Crypt_Base::key * @see \phpseclib\Crypt\Base::key
* @see self::setKey() * @see self::setKey()
* @var string * @var string
* @access private * @access private
@ -129,7 +65,7 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* The Original (unpadded) Key * The Original (unpadded) Key
* *
* @see Crypt_Base::key * @see \phpseclib\Crypt\Base::key
* @see self::setKey() * @see self::setKey()
* @see self::encrypt() * @see self::encrypt()
* @see self::decrypt() * @see self::decrypt()
@ -141,7 +77,7 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* Don't truncate / null pad key * Don't truncate / null pad key
* *
* @see Crypt_Base::_clearBuffers() * @see \phpseclib\Crypt\Base::_clearBuffers()
* @var bool * @var bool
* @access private * @access private
*/ */
@ -150,25 +86,16 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* Key Length (in bytes) * Key Length (in bytes)
* *
* @see Crypt_RC2::setKeyLength() * @see \phpseclib\Crypt\RC2::setKeyLength()
* @var int * @var int
* @access private * @access private
*/ */
var $key_length = 16; // = 128 bits var $key_length = 16; // = 128 bits
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'RC2';
/** /**
* The mcrypt specific name of the cipher * The mcrypt specific name of the cipher
* *
* @see Crypt_Base::cipher_name_mcrypt * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
* @var string * @var string
* @access private * @access private
*/ */
@ -177,7 +104,7 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* Optimizing value while CFB-encrypting * Optimizing value while CFB-encrypting
* *
* @see Crypt_Base::cfb_init_len * @see \phpseclib\Crypt\Base::cfb_init_len
* @var int * @var int
* @access private * @access private
*/ */
@ -332,40 +259,12 @@ class Crypt_RC2 extends Crypt_Base
0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6 0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6
); );
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - CRYPT_RC2_MODE_ECB
*
* - CRYPT_RC2_MODE_CBC
*
* - CRYPT_RC2_MODE_CTR
*
* - CRYPT_RC2_MODE_CFB
*
* - CRYPT_RC2_MODE_OFB
*
* If not explicitly set, CRYPT_RC2_MODE_CBC will be used.
*
* @see Crypt_Base::Crypt_Base()
* @param int $mode
* @access public
*/
function Crypt_RC2($mode = CRYPT_RC2_MODE_CBC)
{
parent::Crypt_Base($mode);
}
/** /**
* Test for engine validity * Test for engine validity
* *
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
* *
* @see Crypt_Base::Crypt_Base() * @see \phpseclib\Crypt\Base::__construct()
* @param int $engine * @param int $engine
* @access public * @access public
* @return bool * @return bool
@ -373,7 +272,7 @@ class Crypt_RC2 extends Crypt_Base
function isValidEngine($engine) function isValidEngine($engine)
{ {
switch ($engine) { switch ($engine) {
case CRYPT_ENGINE_OPENSSL: case self::ENGINE_OPENSSL:
if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) { if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
return false; return false;
} }
@ -389,7 +288,7 @@ class Crypt_RC2 extends Crypt_Base
* *
* Valid key lengths are 8 to 1024. * Valid key lengths are 8 to 1024.
* Calling this function after setting the key has no effect until the next * Calling this function after setting the key has no effect until the next
* Crypt_RC2::setKey() call. * \phpseclib\Crypt\RC2::setKey() call.
* *
* @access public * @access public
* @param int $length in bits * @param int $length in bits
@ -430,7 +329,7 @@ class Crypt_RC2 extends Crypt_Base
* If the key is not explicitly set, it'll be assumed to be a single * If the key is not explicitly set, it'll be assumed to be a single
* null byte. * null byte.
* *
* @see Crypt_Base::setKey() * @see \phpseclib\Crypt\Base::setKey()
* @access public * @access public
* @param string $key * @param string $key
* @param int $t1 optional Effective key length in bits. * @param int $t1 optional Effective key length in bits.
@ -481,7 +380,7 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* Encrypts a message. * Encrypts a message.
* *
* Mostly a wrapper for Crypt_Base::encrypt, with some additional OpenSSL handling code * Mostly a wrapper for \phpseclib\Crypt\Base::encrypt, with some additional OpenSSL handling code
* *
* @see self::decrypt() * @see self::decrypt()
* @access public * @access public
@ -490,7 +389,7 @@ class Crypt_RC2 extends Crypt_Base
*/ */
function encrypt($plaintext) function encrypt($plaintext)
{ {
if ($this->engine == CRYPT_ENGINE_OPENSSL) { if ($this->engine == self::ENGINE_OPENSSL) {
$temp = $this->key; $temp = $this->key;
$this->key = $this->orig_key; $this->key = $this->orig_key;
$result = parent::encrypt($plaintext); $result = parent::encrypt($plaintext);
@ -504,7 +403,7 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* Decrypts a message. * Decrypts a message.
* *
* Mostly a wrapper for Crypt_Base::decrypt, with some additional OpenSSL handling code * Mostly a wrapper for \phpseclib\Crypt\Base::decrypt, with some additional OpenSSL handling code
* *
* @see self::encrypt() * @see self::encrypt()
* @access public * @access public
@ -513,7 +412,7 @@ class Crypt_RC2 extends Crypt_Base
*/ */
function decrypt($ciphertext) function decrypt($ciphertext)
{ {
if ($this->engine == CRYPT_ENGINE_OPENSSL) { if ($this->engine == self::ENGINE_OPENSSL) {
$temp = $this->key; $temp = $this->key;
$this->key = $this->orig_key; $this->key = $this->orig_key;
$result = parent::decrypt($ciphertext); $result = parent::decrypt($ciphertext);
@ -527,8 +426,8 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* Encrypts a block * Encrypts a block
* *
* @see Crypt_Base::_encryptBlock() * @see \phpseclib\Crypt\Base::_encryptBlock()
* @see Crypt_Base::encrypt() * @see \phpseclib\Crypt\Base::encrypt()
* @access private * @access private
* @param string $in * @param string $in
* @return string * @return string
@ -572,8 +471,8 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* Decrypts a block * Decrypts a block
* *
* @see Crypt_Base::_decryptBlock() * @see \phpseclib\Crypt\Base::_decryptBlock()
* @see Crypt_Base::decrypt() * @see \phpseclib\Crypt\Base::decrypt()
* @access private * @access private
* @param string $in * @param string $in
* @return string * @return string
@ -615,9 +514,9 @@ class Crypt_RC2 extends Crypt_Base
} }
/** /**
* Setup the CRYPT_ENGINE_MCRYPT $engine * Setup the \phpseclib\Crypt\Base::ENGINE_MCRYPT $engine
* *
* @see Crypt_Base::_setupMcrypt() * @see \phpseclib\Crypt\Base::_setupMcrypt()
* @access private * @access private
*/ */
function _setupMcrypt() function _setupMcrypt()
@ -632,7 +531,7 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* Creates the key schedule * Creates the key schedule
* *
* @see Crypt_Base::_setupKey() * @see \phpseclib\Crypt\Base::_setupKey()
* @access private * @access private
*/ */
function _setupKey() function _setupKey()
@ -641,7 +540,7 @@ class Crypt_RC2 extends Crypt_Base
$this->setKey(''); $this->setKey('');
} }
// Key has already been expanded in Crypt_RC2::setKey(): // Key has already been expanded in \phpseclib\Crypt\RC2::setKey():
// Only the first value must be altered. // Only the first value must be altered.
$l = unpack('Ca/Cb/v*', $this->key); $l = unpack('Ca/Cb/v*', $this->key);
array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8)); array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8));
@ -653,12 +552,12 @@ class Crypt_RC2 extends Crypt_Base
/** /**
* Setup the performance-optimized function for de/encrypt() * Setup the performance-optimized function for de/encrypt()
* *
* @see Crypt_Base::_setupInlineCrypt() * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
* @access private * @access private
*/ */
function _setupInlineCrypt() function _setupInlineCrypt()
{ {
$lambda_functions = &Crypt_RC2::_getLambdaFunctions(); $lambda_functions =& self::_getLambdaFunctions();
// The first 10 generated $lambda_functions will use the $keys hardcoded as integers // The first 10 generated $lambda_functions will use the $keys hardcoded as integers
// for the mixing rounds, for better inline crypt performance [~20% faster]. // for the mixing rounds, for better inline crypt performance [~20% faster].
@ -666,7 +565,7 @@ class Crypt_RC2 extends Crypt_Base
// (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit) // (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10); $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
// Generation of a uniqe hash for our generated code // Generation of a unique hash for our generated code
$code_hash = "Crypt_RC2, {$this->mode}"; $code_hash = "Crypt_RC2, {$this->mode}";
if ($gen_hi_opt_code) { if ($gen_hi_opt_code) {
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);

View File

@ -5,7 +5,7 @@
* *
* Uses mcrypt, if available, and an internal implementation, otherwise. * Uses mcrypt, if available, and an internal implementation, otherwise.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* Useful resources are as follows: * Useful resources are as follows:
* *
@ -18,9 +18,9 @@
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/RC4.php'; * include 'vendor/autoload.php';
* *
* $rc4 = new Crypt_RC4(); * $rc4 = new \phpseclib\Crypt\RC4();
* *
* $rc4->setKey('abcdefgh'); * $rc4->setKey('abcdefgh');
* *
@ -34,65 +34,40 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_RC4 * @package RC4
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton * @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/** namespace phpseclib\Crypt;
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access private
* @see self::_crypt()
*/
define('CRYPT_RC4_ENCRYPT', 0);
define('CRYPT_RC4_DECRYPT', 1);
/**#@-*/
/** /**
* Pure-PHP implementation of RC4. * Pure-PHP implementation of RC4.
* *
* @package Crypt_RC4 * @package RC4
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class Crypt_RC4 extends Crypt_Base class RC4 extends Base
{ {
/**#@+
* @access private
* @see \phpseclib\Crypt\RC4::_crypt()
*/
const ENCRYPT = 0;
const DECRYPT = 1;
/**#@-*/
/** /**
* Block Length of the cipher * Block Length of the cipher
* *
* RC4 is a stream cipher * RC4 is a stream cipher
* so we the block_size to 0 * so we the block_size to 0
* *
* @see Crypt_Base::block_size * @see \phpseclib\Crypt\Base::block_size
* @var int * @var int
* @access private * @access private
*/ */
@ -101,25 +76,16 @@ class Crypt_RC4 extends Crypt_Base
/** /**
* Key Length (in bytes) * Key Length (in bytes)
* *
* @see Crypt_RC4::setKeyLength() * @see \phpseclib\Crypt\RC4::setKeyLength()
* @var int * @var int
* @access private * @access private
*/ */
var $key_length = 128; // = 1024 bits var $key_length = 128; // = 1024 bits
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'RC4';
/** /**
* The mcrypt specific name of the cipher * The mcrypt specific name of the cipher
* *
* @see Crypt_Base::cipher_name_mcrypt * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
* @var string * @var string
* @access private * @access private
*/ */
@ -128,7 +94,7 @@ class Crypt_RC4 extends Crypt_Base
/** /**
* Holds whether performance-optimized $inline_crypt() can/should be used. * Holds whether performance-optimized $inline_crypt() can/should be used.
* *
* @see Crypt_Base::inline_crypt * @see \phpseclib\Crypt\Base::inline_crypt
* @var mixed * @var mixed
* @access private * @access private
*/ */
@ -157,29 +123,31 @@ class Crypt_RC4 extends Crypt_Base
* *
* Determines whether or not the mcrypt extension should be used. * Determines whether or not the mcrypt extension should be used.
* *
* @see Crypt_Base::Crypt_Base() * @see \phpseclib\Crypt\Base::__construct()
* @return Crypt_RC4 * @return \phpseclib\Crypt\RC4
* @access public * @access public
*/ */
function Crypt_RC4() function __construct()
{ {
parent::Crypt_Base(CRYPT_MODE_STREAM); parent::__construct(Base::MODE_STREAM);
} }
/** /**
* Test for engine validity * Test for engine validity
* *
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
* *
* @see Crypt_Base::Crypt_Base() * @see \phpseclib\Crypt\Base::__construct()
* @param int $engine * @param int $engine
* @access public * @access public
* @return bool * @return bool
*/ */
function isValidEngine($engine) function isValidEngine($engine)
{ {
switch ($engine) { if ($engine == Base::ENGINE_OPENSSL) {
case CRYPT_ENGINE_OPENSSL: if (version_compare(PHP_VERSION, '5.3.7') >= 0) {
$this->cipher_name_openssl = 'rc4-40';
} else {
switch (strlen($this->key)) { switch (strlen($this->key)) {
case 5: case 5:
$this->cipher_name_openssl = 'rc4-40'; $this->cipher_name_openssl = 'rc4-40';
@ -194,6 +162,7 @@ class Crypt_RC4 extends Crypt_Base
return false; return false;
} }
} }
}
return parent::isValidEngine($engine); return parent::isValidEngine($engine);
} }
@ -245,7 +214,7 @@ class Crypt_RC4 extends Crypt_Base
/** /**
* Encrypts a message. * Encrypts a message.
* *
* @see Crypt_Base::decrypt() * @see \phpseclib\Crypt\Base::decrypt()
* @see self::_crypt() * @see self::_crypt()
* @access public * @access public
* @param string $plaintext * @param string $plaintext
@ -253,10 +222,10 @@ class Crypt_RC4 extends Crypt_Base
*/ */
function encrypt($plaintext) function encrypt($plaintext)
{ {
if ($this->engine != CRYPT_ENGINE_INTERNAL) { if ($this->engine != Base::ENGINE_INTERNAL) {
return parent::encrypt($plaintext); return parent::encrypt($plaintext);
} }
return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT); return $this->_crypt($plaintext, self::ENCRYPT);
} }
/** /**
@ -265,7 +234,7 @@ class Crypt_RC4 extends Crypt_Base
* $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
* At least if the continuous buffer is disabled. * At least if the continuous buffer is disabled.
* *
* @see Crypt_Base::encrypt() * @see \phpseclib\Crypt\Base::encrypt()
* @see self::_crypt() * @see self::_crypt()
* @access public * @access public
* @param string $ciphertext * @param string $ciphertext
@ -273,17 +242,38 @@ class Crypt_RC4 extends Crypt_Base
*/ */
function decrypt($ciphertext) function decrypt($ciphertext)
{ {
if ($this->engine != CRYPT_ENGINE_INTERNAL) { if ($this->engine != Base::ENGINE_INTERNAL) {
return parent::decrypt($ciphertext); return parent::decrypt($ciphertext);
} }
return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT); return $this->_crypt($ciphertext, self::DECRYPT);
} }
/**
* Encrypts a block
*
* @access private
* @param string $in
*/
function _encryptBlock($in)
{
// RC4 does not utilize this method
}
/**
* Decrypts a block
*
* @access private
* @param string $in
*/
function _decryptBlock($in)
{
// RC4 does not utilize this method
}
/** /**
* Setup the key (expansion) * Setup the key (expansion)
* *
* @see Crypt_Base::_setupKey() * @see \phpseclib\Crypt\Base::_setupKey()
* @access private * @access private
*/ */
function _setupKey() function _setupKey()
@ -300,7 +290,7 @@ class Crypt_RC4 extends Crypt_Base
} }
$this->stream = array(); $this->stream = array();
$this->stream[CRYPT_RC4_DECRYPT] = $this->stream[CRYPT_RC4_ENCRYPT] = array( $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = array(
0, // index $i 0, // index $i
0, // index $j 0, // index $j
$keyStream $keyStream

File diff suppressed because it is too large Load Diff

View File

@ -3,57 +3,36 @@
/** /**
* Random Number Generator * Random Number Generator
* *
* The idea behind this function is that it can be easily replaced with your own crypt_random_string() * PHP version 5
* function. eg. maybe you have a better source of entropy for creating the initial states or whatever.
*
* PHP versions 4 and 5
* *
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/Random.php'; * include 'vendor/autoload.php';
* *
* echo bin2hex(crypt_random_string(8)); * echo bin2hex(\phpseclib\Crypt\Random::string(8));
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_Random * @package Random
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton * @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
// laravel is a PHP framework that utilizes phpseclib. laravel workbenches may, independently, namespace phpseclib\Crypt;
// have phpseclib as a requirement as well. if you're developing such a program you may encounter
// a "Cannot redeclare crypt_random_string()" error.
if (!function_exists('crypt_random_string')) {
/**
* "Is Windows" test
*
* @access private
*/
define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
/**
* Pure-PHP Random Number Generator
*
* @package Random
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Random
{
/** /**
* Generate a random string. * Generate a random string.
* *
@ -63,14 +42,27 @@ if (!function_exists('crypt_random_string')) {
* *
* @param int $length * @param int $length
* @return string * @return string
* @access public
*/ */
function crypt_random_string($length) static function string($length)
{ {
if (CRYPT_RANDOM_IS_WINDOWS) { if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
// method 1. prior to PHP 5.3, mcrypt_create_iv() would call rand() on windows try {
if (extension_loaded('mcrypt') && version_compare(PHP_VERSION, '5.3.0', '>=')) { return \random_bytes($length);
return mcrypt_create_iv($length); } catch (\Throwable $e) {
// If a sufficient source of randomness is unavailable, random_bytes() will throw an
// object that implements the Throwable interface (Exception, TypeError, Error).
// We don't actually need to do anything here. The string() method should just continue
// as normal. Note, however, that if we don't have a sufficient source of randomness for
// random_bytes(), most of the other calls here will fail too, so we'll end up using
// the PHP implementation.
}
}
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
// method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
// ie. class_alias is a function that was introduced in PHP 5.3
if (extension_loaded('mcrypt') && function_exists('class_alias')) {
return @mcrypt_create_iv($length);
} }
// method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was, // method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
// to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4 // to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
@ -90,7 +82,7 @@ if (!function_exists('crypt_random_string')) {
} }
} else { } else {
// method 1. the fastest // method 1. the fastest
if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.0', '>=')) { if (extension_loaded('openssl')) {
return openssl_random_pseudo_bytes($length); return openssl_random_pseudo_bytes($length);
} }
// method 2 // method 2
@ -109,7 +101,7 @@ if (!function_exists('crypt_random_string')) {
// not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir // not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
// restrictions or some such // restrictions or some such
if (extension_loaded('mcrypt')) { if (extension_loaded('mcrypt')) {
return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); return @mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
} }
} }
// at this point we have no choice but to use a pure-PHP CSPRNG // at this point we have no choice but to use a pure-PHP CSPRNG
@ -193,44 +185,26 @@ if (!function_exists('crypt_random_string')) {
// //
// http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
switch (true) { switch (true) {
case phpseclib_resolve_include_path('Crypt/AES.php'): case class_exists('\phpseclib\Crypt\AES'):
if (!class_exists('Crypt_AES')) { $crypto = new AES(Base::MODE_CTR);
include_once 'AES.php';
}
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
break; break;
case phpseclib_resolve_include_path('Crypt/Twofish.php'): case class_exists('\phpseclib\Crypt\Twofish'):
if (!class_exists('Crypt_Twofish')) { $crypto = new Twofish(Base::MODE_CTR);
include_once 'Twofish.php';
}
$crypto = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
break; break;
case phpseclib_resolve_include_path('Crypt/Blowfish.php'): case class_exists('\phpseclib\Crypt\Blowfish'):
if (!class_exists('Crypt_Blowfish')) { $crypto = new Blowfish(Base::MODE_CTR);
include_once 'Blowfish.php';
}
$crypto = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
break; break;
case phpseclib_resolve_include_path('Crypt/TripleDES.php'): case class_exists('\phpseclib\Crypt\TripleDES'):
if (!class_exists('Crypt_TripleDES')) { $crypto = new TripleDES(Base::MODE_CTR);
include_once 'TripleDES.php';
}
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
break; break;
case phpseclib_resolve_include_path('Crypt/DES.php'): case class_exists('\phpseclib\Crypt\DES'):
if (!class_exists('Crypt_DES')) { $crypto = new DES(Base::MODE_CTR);
include_once 'DES.php';
}
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
break; break;
case phpseclib_resolve_include_path('Crypt/RC4.php'): case class_exists('\phpseclib\Crypt\RC4'):
if (!class_exists('Crypt_RC4')) { $crypto = new RC4();
include_once 'RC4.php';
}
$crypto = new Crypt_RC4();
break; break;
default: default:
user_error('crypt_random_string requires at least one symmetric cipher be loaded'); user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded');
return false; return false;
} }
@ -294,41 +268,3 @@ if (!function_exists('phpseclib_safe_serialize')) {
return serialize($safearr); return serialize($safearr);
} }
} }
if (!function_exists('phpseclib_resolve_include_path')) {
/**
* Resolve filename against the include path.
*
* Wrapper around stream_resolve_include_path() (which was introduced in
* PHP 5.3.2) with fallback implementation for earlier PHP versions.
*
* @param string $filename
* @return string|false
* @access public
*/
function phpseclib_resolve_include_path($filename)
{
if (function_exists('stream_resolve_include_path')) {
return stream_resolve_include_path($filename);
}
// handle non-relative paths
if (file_exists($filename)) {
return realpath($filename);
}
$paths = PATH_SEPARATOR == ':' ?
preg_split('#(?<!phar):#', get_include_path()) :
explode(PATH_SEPARATOR, get_include_path());
foreach ($paths as $prefix) {
// path's specified in include_path don't always end in /
$ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
$file = $prefix . $ds . $filename;
if (file_exists($file)) {
return realpath($file);
}
}
return false;
}
}

View File

@ -5,7 +5,7 @@
* *
* Uses mcrypt, if available/possible, and an internal implementation, otherwise. * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* If {@link self::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If * If {@link self::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
* {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from * {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
@ -28,9 +28,9 @@
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/Rijndael.php'; * include 'vendor/autoload.php';
* *
* $rijndael = new Crypt_Rijndael(); * $rijndael = new \phpseclib\Crypt\Rijndael();
* *
* $rijndael->setKey('abcdefghijklmnop'); * $rijndael->setKey('abcdefghijklmnop');
* *
@ -44,108 +44,35 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_Rijndael * @package Rijndael
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2008 Jim Wigginton * @copyright 2008 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/** namespace phpseclib\Crypt;
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_RIJNDAEL_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_RIJNDAEL_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_RIJNDAEL_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_RIJNDAEL_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_RIJNDAEL_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/** /**
* Pure-PHP implementation of Rijndael. * Pure-PHP implementation of Rijndael.
* *
* @package Crypt_Rijndael * @package Rijndael
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class Crypt_Rijndael extends Crypt_Base class Rijndael extends Base
{ {
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'RIJNDAEL';
/** /**
* The mcrypt specific name of the cipher * The mcrypt specific name of the cipher
* *
* Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not. * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not.
* Crypt_Rijndael determines automatically whether mcrypt is useable * \phpseclib\Crypt\Rijndael determines automatically whether mcrypt is useable
* or not for the current $block_size/$key_length. * or not for the current $block_size/$key_length.
* In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly. * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly.
* *
* @see Crypt_Base::cipher_name_mcrypt * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
* @see Crypt_Base::engine * @see \phpseclib\Crypt\Base::engine
* @see self::isValidEngine() * @see self::isValidEngine()
* @var string * @var string
* @access private * @access private
@ -155,8 +82,8 @@ class Crypt_Rijndael extends Crypt_Base
/** /**
* The default salt used by setPassword() * The default salt used by setPassword()
* *
* @see Crypt_Base::password_default_salt * @see \phpseclib\Crypt\Base::password_default_salt
* @see Crypt_Base::setPassword() * @see \phpseclib\Crypt\Base::setPassword()
* @var string * @var string
* @access private * @access private
*/ */
@ -242,76 +169,7 @@ class Crypt_Rijndael extends Crypt_Base
var $kl; var $kl;
/** /**
* Default Constructor. * Sets the key length.
*
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - CRYPT_RIJNDAEL_MODE_ECB
*
* - CRYPT_RIJNDAEL_MODE_CBC
*
* - CRYPT_RIJNDAEL_MODE_CTR
*
* - CRYPT_RIJNDAEL_MODE_CFB
*
* - CRYPT_RIJNDAEL_MODE_OFB
*
* If not explictly set, CRYPT_RIJNDAEL_MODE_CBC will be used.
*
* @see Crypt_Base::Crypt_Base()
* @param int $mode
* @access public
*/
function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC)
{
parent::Crypt_Base($mode);
}
/**
* Sets the key.
*
* Keys can be of any length. Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and
* whose length is a multiple of 32. If the key is less than 256-bits and the key length isn't set, we round the length
* up to the closest valid key length, padding $key with null bytes. If the key is more than 256-bits, we trim the
* excess bits.
*
* If the key is not explicitly set, it'll be assumed to be all null bytes.
*
* Note: 160/224-bit keys must explicitly set by setKeyLength(), otherwise they will be round/pad up to 192/256 bits.
*
* @see Crypt_Base:setKey()
* @see self::setKeyLength()
* @access public
* @param string $key
*/
function setKey($key)
{
if (!$this->explicit_key_length) {
$length = strlen($key);
switch (true) {
case $length <= 16:
$this->key_size = 16;
break;
case $length <= 20:
$this->key_size = 20;
break;
case $length <= 24:
$this->key_size = 24;
break;
case $length <= 28:
$this->key_size = 28;
break;
default:
$this->key_size = 32;
}
}
parent::setKey($key);
}
/**
* Sets the key length
* *
* Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to * Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount. * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
@ -378,9 +236,9 @@ class Crypt_Rijndael extends Crypt_Base
/** /**
* Test for engine validity * Test for engine validity
* *
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
* *
* @see Crypt_Base::Crypt_Base() * @see \phpseclib\Crypt\Base::__construct()
* @param int $engine * @param int $engine
* @access public * @access public
* @return bool * @return bool
@ -388,14 +246,14 @@ class Crypt_Rijndael extends Crypt_Base
function isValidEngine($engine) function isValidEngine($engine)
{ {
switch ($engine) { switch ($engine) {
case CRYPT_ENGINE_OPENSSL: case self::ENGINE_OPENSSL:
if ($this->block_size != 16) { if ($this->block_size != 16) {
return false; return false;
} }
$this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb'; $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb';
$this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode(); $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode();
break; break;
case CRYPT_ENGINE_MCRYPT: case self::ENGINE_MCRYPT:
$this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
if ($this->key_length % 8) { // is it a 160/224-bit key? if ($this->key_length % 8) { // is it a 160/224-bit key?
// mcrypt is not usable for them, only for 128/192/256-bit keys // mcrypt is not usable for them, only for 128/192/256-bit keys
@ -600,7 +458,7 @@ class Crypt_Rijndael extends Crypt_Base
/** /**
* Setup the key (expansion) * Setup the key (expansion)
* *
* @see Crypt_Base::_setupKey() * @see \phpseclib\Crypt\Base::_setupKey()
* @access private * @access private
*/ */
function _setupKey() function _setupKey()
@ -732,9 +590,9 @@ class Crypt_Rijndael extends Crypt_Base
/** /**
* Provides the mixColumns and sboxes tables * Provides the mixColumns and sboxes tables
* *
* @see Crypt_Rijndael:_encryptBlock() * @see self::_encryptBlock()
* @see Crypt_Rijndael:_setupInlineCrypt() * @see self::_setupInlineCrypt()
* @see Crypt_Rijndael:_subWord() * @see self::_subWord()
* @access private * @access private
* @return array &$tables * @return array &$tables
*/ */
@ -821,9 +679,9 @@ class Crypt_Rijndael extends Crypt_Base
/** /**
* Provides the inverse mixColumns and inverse sboxes tables * Provides the inverse mixColumns and inverse sboxes tables
* *
* @see Crypt_Rijndael:_decryptBlock() * @see self::_decryptBlock()
* @see Crypt_Rijndael:_setupInlineCrypt() * @see self::_setupInlineCrypt()
* @see Crypt_Rijndael:_setupKey() * @see self::_setupKey()
* @access private * @access private
* @return array &$tables * @return array &$tables
*/ */
@ -905,7 +763,7 @@ class Crypt_Rijndael extends Crypt_Base
/** /**
* Setup the performance-optimized function for de/encrypt() * Setup the performance-optimized function for de/encrypt()
* *
* @see Crypt_Base::_setupInlineCrypt() * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
* @access private * @access private
*/ */
function _setupInlineCrypt() function _setupInlineCrypt()
@ -914,7 +772,7 @@ class Crypt_Rijndael extends Crypt_Base
// So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt(). // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
// However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible. // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
$lambda_functions =& Crypt_Rijndael::_getLambdaFunctions(); $lambda_functions =& self::_getLambdaFunctions();
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function. // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
// (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit) // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)

View File

@ -5,14 +5,14 @@
* *
* Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt). * Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt).
* *
* PHP versions 4 and 5 * PHP version 5
* *
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/TripleDES.php'; * include 'vendor/autoload.php';
* *
* $des = new Crypt_TripleDES(); * $des = new \phpseclib\Crypt\TripleDES();
* *
* $des->setKey('abcdefghijklmnopqrstuvwx'); * $des->setKey('abcdefghijklmnopqrstuvwx');
* *
@ -26,78 +26,43 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_TripleDES * @package TripleDES
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton * @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/** namespace phpseclib\Crypt;
* Include Crypt_DES
*/
if (!class_exists('Crypt_DES')) {
include_once 'DES.php';
}
/**#@+
* @access public
* @see self::Crypt_TripleDES()
*/
/**
* Encrypt / decrypt using inner chaining
*
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
*/
define('CRYPT_MODE_3CBC', -2);
/**
* BC version of the above.
*/
define('CRYPT_DES_MODE_3CBC', -2);
/**
* Encrypt / decrypt using outer chaining
*
* Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
*/
define('CRYPT_MODE_CBC3', CRYPT_MODE_CBC);
/**
* BC version of the above.
*/
define('CRYPT_DES_MODE_CBC3', CRYPT_MODE_CBC3);
/**#@-*/
/** /**
* Pure-PHP implementation of Triple DES. * Pure-PHP implementation of Triple DES.
* *
* @package Crypt_TripleDES * @package TripleDES
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class Crypt_TripleDES extends Crypt_DES class TripleDES extends DES
{ {
/**
* Encrypt / decrypt using inner chaining
*
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3).
*/
const MODE_3CBC = -2;
/**
* Encrypt / decrypt using outer chaining
*
* Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC.
*/
const MODE_CBC3 = Base::MODE_CBC;
/** /**
* Key Length (in bytes) * Key Length (in bytes)
* *
* @see Crypt_TripleDES::setKeyLength() * @see \phpseclib\Crypt\TripleDES::setKeyLength()
* @var int * @var int
* @access private * @access private
*/ */
@ -106,28 +71,18 @@ class Crypt_TripleDES extends Crypt_DES
/** /**
* The default salt used by setPassword() * The default salt used by setPassword()
* *
* @see Crypt_Base::password_default_salt * @see \phpseclib\Crypt\Base::password_default_salt
* @see Crypt_Base::setPassword() * @see \phpseclib\Crypt\Base::setPassword()
* @var string * @var string
* @access private * @access private
*/ */
var $password_default_salt = 'phpseclib'; var $password_default_salt = 'phpseclib';
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_DES::const_namespace
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'DES';
/** /**
* The mcrypt specific name of the cipher * The mcrypt specific name of the cipher
* *
* @see Crypt_DES::cipher_name_mcrypt * @see \phpseclib\Crypt\DES::cipher_name_mcrypt
* @see Crypt_Base::cipher_name_mcrypt * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
* @var string * @var string
* @access private * @access private
*/ */
@ -136,7 +91,7 @@ class Crypt_TripleDES extends Crypt_DES
/** /**
* Optimizing value while CFB-encrypting * Optimizing value while CFB-encrypting
* *
* @see Crypt_Base::cfb_init_len * @see \phpseclib\Crypt\Base::cfb_init_len
* @var int * @var int
* @access private * @access private
*/ */
@ -146,14 +101,14 @@ class Crypt_TripleDES extends Crypt_DES
* max possible size of $key * max possible size of $key
* *
* @see self::setKey() * @see self::setKey()
* @see Crypt_DES::setKey() * @see \phpseclib\Crypt\DES::setKey()
* @var string * @var string
* @access private * @access private
*/ */
var $key_length_max = 24; var $key_length_max = 24;
/** /**
* Internal flag whether using CRYPT_DES_MODE_3CBC or not * Internal flag whether using self::MODE_3CBC or not
* *
* @var bool * @var bool
* @access private * @access private
@ -161,7 +116,7 @@ class Crypt_TripleDES extends Crypt_DES
var $mode_3cbc; var $mode_3cbc;
/** /**
* The Crypt_DES objects * The \phpseclib\Crypt\DES objects
* *
* Used only if $mode_3cbc === true * Used only if $mode_3cbc === true
* *
@ -177,65 +132,65 @@ class Crypt_TripleDES extends Crypt_DES
* *
* $mode could be: * $mode could be:
* *
* - CRYPT_DES_MODE_ECB * - \phpseclib\Crypt\Base::MODE_ECB
* *
* - CRYPT_DES_MODE_CBC * - \phpseclib\Crypt\Base::MODE_CBC
* *
* - CRYPT_DES_MODE_CTR * - \phpseclib\Crypt\Base::MODE_CTR
* *
* - CRYPT_DES_MODE_CFB * - \phpseclib\Crypt\Base::MODE_CFB
* *
* - CRYPT_DES_MODE_OFB * - \phpseclib\Crypt\Base::MODE_OFB
* *
* - CRYPT_DES_MODE_3CBC * - \phpseclib\Crypt\TripleDES::MODE_3CBC
* *
* If not explicitly set, CRYPT_DES_MODE_CBC will be used. * If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used.
* *
* @see Crypt_DES::Crypt_DES() * @see \phpseclib\Crypt\DES::__construct()
* @see Crypt_Base::Crypt_Base() * @see \phpseclib\Crypt\Base::__construct()
* @param int $mode * @param int $mode
* @access public * @access public
*/ */
function Crypt_TripleDES($mode = CRYPT_MODE_CBC) function __construct($mode = Base::MODE_CBC)
{ {
switch ($mode) { switch ($mode) {
// In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
// and additional flag us internally as 3CBC // and additional flag us internally as 3CBC
case CRYPT_DES_MODE_3CBC: case self::MODE_3CBC:
parent::Crypt_Base(CRYPT_MODE_CBC); parent::__construct(Base::MODE_CBC);
$this->mode_3cbc = true; $this->mode_3cbc = true;
// This three $des'es will do the 3CBC work (if $key > 64bits) // This three $des'es will do the 3CBC work (if $key > 64bits)
$this->des = array( $this->des = array(
new Crypt_DES(CRYPT_MODE_CBC), new DES(Base::MODE_CBC),
new Crypt_DES(CRYPT_MODE_CBC), new DES(Base::MODE_CBC),
new Crypt_DES(CRYPT_MODE_CBC), new DES(Base::MODE_CBC),
); );
// we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects // we're going to be doing the padding, ourselves, so disable it in the \phpseclib\Crypt\DES objects
$this->des[0]->disablePadding(); $this->des[0]->disablePadding();
$this->des[1]->disablePadding(); $this->des[1]->disablePadding();
$this->des[2]->disablePadding(); $this->des[2]->disablePadding();
break; break;
// If not 3CBC, we init as usual // If not 3CBC, we init as usual
default: default:
parent::Crypt_Base($mode); parent::__construct($mode);
} }
} }
/** /**
* Test for engine validity * Test for engine validity
* *
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine() * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
* *
* @see Crypt_Base::Crypt_Base() * @see \phpseclib\Crypt\Base::__construct()
* @param int $engine * @param int $engine
* @access public * @access public
* @return bool * @return bool
*/ */
function isValidEngine($engine) function isValidEngine($engine)
{ {
if ($engine == CRYPT_ENGINE_OPENSSL) { if ($engine == self::ENGINE_OPENSSL) {
$this->cipher_name_openssl_ecb = 'des-ede3'; $this->cipher_name_openssl_ecb = 'des-ede3';
$mode = $this->_openssl_translate_mode(); $mode = $this->_openssl_translate_mode();
$this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode; $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
@ -247,10 +202,10 @@ class Crypt_TripleDES extends Crypt_DES
/** /**
* Sets the initialization vector. (optional) * Sets the initialization vector. (optional)
* *
* SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explicitly set, it'll be assumed * SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used. If not explicitly set, it'll be assumed
* to be all zero's. * to be all zero's.
* *
* @see Crypt_Base::setIV() * @see \phpseclib\Crypt\Base::setIV()
* @access public * @access public
* @param string $iv * @param string $iv
*/ */
@ -269,7 +224,7 @@ class Crypt_TripleDES extends Crypt_DES
* *
* Valid key lengths are 64, 128 and 192 * Valid key lengths are 64, 128 and 192
* *
* @see Crypt_Base:setKeyLength() * @see \phpseclib\Crypt\Base:setKeyLength()
* @access public * @access public
* @param int $length * @param int $length
*/ */
@ -301,8 +256,8 @@ class Crypt_TripleDES extends Crypt_DES
* If the key is not explicitly set, it'll be assumed to be all null bytes. * If the key is not explicitly set, it'll be assumed to be all null bytes.
* *
* @access public * @access public
* @see Crypt_DES::setKey() * @see \phpseclib\Crypt\DES::setKey()
* @see Crypt_Base::setKey() * @see \phpseclib\Crypt\Base::setKey()
* @param string $key * @param string $key
*/ */
function setKey($key) function setKey($key)
@ -318,7 +273,7 @@ class Crypt_TripleDES extends Crypt_DES
} }
parent::setKey($key); parent::setKey($key);
// And in case of CRYPT_DES_MODE_3CBC: // And in case of self::MODE_3CBC:
// if key <= 64bits we not need the 3 $des to work, // if key <= 64bits we not need the 3 $des to work,
// because we will then act as regular DES-CBC with just a <= 64bit key. // because we will then act as regular DES-CBC with just a <= 64bit key.
// So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des. // So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
@ -332,7 +287,7 @@ class Crypt_TripleDES extends Crypt_DES
/** /**
* Encrypts a message. * Encrypts a message.
* *
* @see Crypt_Base::encrypt() * @see \phpseclib\Crypt\Base::encrypt()
* @access public * @access public
* @param string $plaintext * @param string $plaintext
* @return string $cipertext * @return string $cipertext
@ -340,7 +295,7 @@ class Crypt_TripleDES extends Crypt_DES
function encrypt($plaintext) function encrypt($plaintext)
{ {
// parent::en/decrypt() is able to do all the work for all modes and keylengths, // parent::en/decrypt() is able to do all the work for all modes and keylengths,
// except for: CRYPT_MODE_3CBC (inner chaining CBC) with a key > 64bits // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits
// if the key is smaller then 8, do what we'd normally do // if the key is smaller then 8, do what we'd normally do
if ($this->mode_3cbc && strlen($this->key) > 8) { if ($this->mode_3cbc && strlen($this->key) > 8) {
@ -359,7 +314,7 @@ class Crypt_TripleDES extends Crypt_DES
/** /**
* Decrypts a message. * Decrypts a message.
* *
* @see Crypt_Base::decrypt() * @see \phpseclib\Crypt\Base::decrypt()
* @access public * @access public
* @param string $ciphertext * @param string $ciphertext
* @return string $plaintext * @return string $plaintext
@ -410,12 +365,12 @@ class Crypt_TripleDES extends Crypt_DES
* outputs. The reason is due to the fact that the initialization vector's change after every encryption / * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
* *
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\DES() object changes after each
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
* however, they are also less intuitive and more likely to cause you problems. * however, they are also less intuitive and more likely to cause you problems.
* *
* @see Crypt_Base::enableContinuousBuffer() * @see \phpseclib\Crypt\Base::enableContinuousBuffer()
* @see self::disableContinuousBuffer() * @see self::disableContinuousBuffer()
* @access public * @access public
*/ */
@ -434,7 +389,7 @@ class Crypt_TripleDES extends Crypt_DES
* *
* The default behavior. * The default behavior.
* *
* @see Crypt_Base::disableContinuousBuffer() * @see \phpseclib\Crypt\Base::disableContinuousBuffer()
* @see self::enableContinuousBuffer() * @see self::enableContinuousBuffer()
* @access public * @access public
*/ */
@ -451,8 +406,8 @@ class Crypt_TripleDES extends Crypt_DES
/** /**
* Creates the key schedule * Creates the key schedule
* *
* @see Crypt_DES::_setupKey() * @see \phpseclib\Crypt\DES::_setupKey()
* @see Crypt_Base::_setupKey() * @see \phpseclib\Crypt\Base::_setupKey()
* @access private * @access private
*/ */
function _setupKey() function _setupKey()
@ -486,8 +441,8 @@ class Crypt_TripleDES extends Crypt_DES
/** /**
* Sets the internal crypt engine * Sets the internal crypt engine
* *
* @see Crypt_Base::Crypt_Base() * @see \phpseclib\Crypt\Base::__construct()
* @see Crypt_Base::setPreferredEngine() * @see \phpseclib\Crypt\Base::setPreferredEngine()
* @param int $engine * @param int $engine
* @access public * @access public
* @return int * @return int

View File

@ -5,7 +5,7 @@
* *
* Uses mcrypt, if available, and an internal implementation, otherwise. * Uses mcrypt, if available, and an internal implementation, otherwise.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* Useful resources are as follows: * Useful resources are as follows:
* *
@ -14,9 +14,9 @@
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Crypt/Twofish.php'; * include 'vendor/autoload.php';
* *
* $twofish = new Crypt_Twofish(); * $twofish = new \phpseclib\Crypt\Twofish();
* *
* $twofish->setKey('12345678901234567890123456789012'); * $twofish->setKey('12345678901234567890123456789012');
* *
@ -26,26 +26,8 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt * @category Crypt
* @package Crypt_Twofish * @package Twofish
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com> * @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @copyright 2007 Jim Wigginton * @copyright 2007 Jim Wigginton
@ -53,77 +35,22 @@
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/** namespace phpseclib\Crypt;
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see self::encrypt()
* @see self::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_TWOFISH_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_TWOFISH_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_TWOFISH_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/** /**
* Pure-PHP implementation of Twofish. * Pure-PHP implementation of Twofish.
* *
* @package Crypt_Twofish * @package Twofish
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com> * @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @access public * @access public
*/ */
class Crypt_Twofish extends Crypt_Base class Twofish extends Base
{ {
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var string
* @access private
*/
var $const_namespace = 'TWOFISH';
/** /**
* The mcrypt specific name of the cipher * The mcrypt specific name of the cipher
* *
* @see Crypt_Base::cipher_name_mcrypt * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
* @var string * @var string
* @access private * @access private
*/ */
@ -132,7 +59,7 @@ class Crypt_Twofish extends Crypt_Base
/** /**
* Optimizing value while CFB-encrypting * Optimizing value while CFB-encrypting
* *
* @see Crypt_Base::cfb_init_len * @see \phpseclib\Crypt\Base::cfb_init_len
* @var int * @var int
* @access private * @access private
*/ */
@ -468,7 +395,7 @@ class Crypt_Twofish extends Crypt_Base
/** /**
* Setup the key (expansion) * Setup the key (expansion)
* *
* @see Crypt_Base::_setupKey() * @see \phpseclib\Crypt\Base::_setupKey()
* @access private * @access private
*/ */
function _setupKey() function _setupKey()
@ -735,18 +662,18 @@ class Crypt_Twofish extends Crypt_Base
/** /**
* Setup the performance-optimized function for de/encrypt() * Setup the performance-optimized function for de/encrypt()
* *
* @see Crypt_Base::_setupInlineCrypt() * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
* @access private * @access private
*/ */
function _setupInlineCrypt() function _setupInlineCrypt()
{ {
$lambda_functions =& Crypt_Twofish::_getLambdaFunctions(); $lambda_functions =& self::_getLambdaFunctions();
// Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one. // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
// (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit) // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10); $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
// Generation of a uniqe hash for our generated code // Generation of a unique hash for our generated code
$code_hash = "Crypt_Twofish, {$this->mode}"; $code_hash = "Crypt_Twofish, {$this->mode}";
if ($gen_hi_opt_code) { if ($gen_hi_opt_code) {
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key); $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);

View File

@ -3,47 +3,31 @@
/** /**
* Pure-PHP ANSI Decoder * Pure-PHP ANSI Decoder
* *
* PHP versions 4 and 5 * PHP version 5
* *
* If you call read() in Net_SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back. * If you call read() in \phpseclib\Net\SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back.
* They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a * They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a
* {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what * {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what
* color to display them in, etc. File_ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator. * color to display them in, etc. \phpseclib\File\ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator.
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* *
* @category File * @category File
* @package File_ANSI * @package ANSI
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2012 Jim Wigginton * @copyright 2012 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
namespace phpseclib\File;
/** /**
* Pure-PHP ANSI Decoder * Pure-PHP ANSI Decoder
* *
* @package File_ANSI * @package ANSI
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class File_ANSI class ANSI
{ {
/** /**
* Max Width * Max Width
@ -176,20 +160,20 @@ class File_ANSI
/** /**
* Default Constructor. * Default Constructor.
* *
* @return File_ANSI * @return \phpseclib\File\ANSI
* @access public * @access public
*/ */
function File_ANSI() function __construct()
{ {
$attr_cell = new stdClass(); $attr_cell = new \stdClass();
$attr_cell->bold = false; $attr_cell->bold = false;
$attr_cell->underline = false; $attr_cell->underline = false;
$attr_cell->blink = false; $attr_cell->blink = false;
$attr_cell->background = 'black'; $attr_cell->background = 'black';
$attr_cell->foreground = 'white'; $attr_cell->foreground = 'white';
$attr_cell->reverse = false; $attr_cell->reverse = false;
$this->base_attr_cell = clone($attr_cell); $this->base_attr_cell = clone $attr_cell;
$this->attr_cell = clone($attr_cell); $this->attr_cell = clone $attr_cell;
$this->setHistory(200); $this->setHistory(200);
$this->setDimensions(80, 24); $this->setDimensions(80, 24);
@ -330,7 +314,7 @@ class File_ANSI
foreach ($mods as $mod) { foreach ($mods as $mod) {
switch ($mod) { switch ($mod) {
case 0: // Turn off character attributes case 0: // Turn off character attributes
$attr_cell = clone($this->base_attr_cell); $attr_cell = clone $this->base_attr_cell;
break; break;
case 1: // Turn bold mode on case 1: // Turn bold mode on
$attr_cell->bold = true; $attr_cell->bold = true;
@ -400,7 +384,7 @@ class File_ANSI
case "\x08": // backspace case "\x08": // backspace
if ($this->x) { if ($this->x) {
$this->x--; $this->x--;
$this->attrs[$this->y][$this->x] = clone($this->base_attr_cell); $this->attrs[$this->y][$this->x] = clone $this->base_attr_cell;
$this->screen[$this->y] = substr_replace( $this->screen[$this->y] = substr_replace(
$this->screen[$this->y], $this->screen[$this->y],
$source[$i], $source[$i],
@ -419,7 +403,7 @@ class File_ANSI
$this->ansi.= "\x1B"; $this->ansi.= "\x1B";
break; break;
default: default:
$this->attrs[$this->y][$this->x] = clone($this->attr_cell); $this->attrs[$this->y][$this->x] = clone $this->attr_cell;
if ($this->x > strlen($this->screen[$this->y])) { if ($this->x > strlen($this->screen[$this->y])) {
$this->screen[$this->y] = str_repeat(' ', $this->x); $this->screen[$this->y] = str_repeat(' ', $this->x);
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
<?php
/**
* Pure-PHP ASN.1 Parser
*
* PHP version 5
*
* @category File
* @package ASN1
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2012 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\File\ASN1;
/**
* ASN.1 Element
*
* Bypass normal encoding rules in phpseclib\File\ASN1::encodeDER()
*
* @package ASN1
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Element
{
/**
* Raw element value
*
* @var string
* @access private
*/
var $element;
/**
* Constructor
*
* @param string $encoded
* @return \phpseclib\File\ASN1\Element
* @access public
*/
function __construct($encoded)
{
$this->element = $encoded;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,90 +3,73 @@
/** /**
* Pure-PHP implementation of SCP. * Pure-PHP implementation of SCP.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}. * The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
* *
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Net/SCP.php'; * include 'vendor/autoload.php';
* include 'Net/SSH2.php';
* *
* $ssh = new Net_SSH2('www.domain.tld'); * $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
* if (!$ssh->login('username', 'password')) { * if (!$ssh->login('username', 'password')) {
* exit('bad login'); * exit('bad login');
* } * }
* $scp = new \phpseclib\Net\SCP($ssh);
* *
* $scp = new Net_SCP($ssh);
* $scp->put('abcd', str_repeat('x', 1024*1024)); * $scp->put('abcd', str_repeat('x', 1024*1024));
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net * @category Net
* @package Net_SCP * @package SCP
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2010 Jim Wigginton * @copyright 2010 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/**#@+ namespace phpseclib\Net;
* @access public
* @see self::put()
*/
/**
* Reads data from a local file.
*/
define('NET_SCP_LOCAL_FILE', 1);
/**
* Reads data from a string.
*/
define('NET_SCP_STRING', 2);
/**#@-*/
/**#@+
* @access private
* @see self::_send()
* @see self::_receive()
*/
/**
* SSH1 is being used.
*/
define('NET_SCP_SSH1', 1);
/**
* SSH2 is being used.
*/
define('NET_SCP_SSH2', 2);
/**#@-*/
/** /**
* Pure-PHP implementations of SCP. * Pure-PHP implementations of SCP.
* *
* @package Net_SCP * @package SCP
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class Net_SCP class SCP
{ {
/**#@+
* @access public
* @see \phpseclib\Net\SCP::put()
*/
/**
* Reads data from a local file.
*/
const SOURCE_LOCAL_FILE = 1;
/**
* Reads data from a string.
*/
const SOURCE_STRING = 2;
/**#@-*/
/**#@+
* @access private
* @see \phpseclib\Net\SCP::_send()
* @see \phpseclib\Net\SCP::_receive()
*/
/**
* SSH1 is being used.
*/
const MODE_SSH1 = 1;
/**
* SSH2 is being used.
*/
const MODE_SSH2 = 2;
/**#@-*/
/** /**
* SSH Object * SSH Object
* *
@ -116,27 +99,18 @@ class Net_SCP
* *
* Connects to an SSH server * Connects to an SSH server
* *
* @param string $host * @param \phpseclib\Net\SSH1|\phpseclib\Net\SSH2 $ssh
* @param int $port * @return \phpseclib\Net\SCP
* @param int $timeout
* @return Net_SCP
* @access public * @access public
*/ */
function Net_SCP($ssh) function __construct($ssh)
{ {
if (!is_object($ssh)) { if ($ssh instanceof SSH2) {
return; $this->mode = self::MODE_SSH2;
} } elseif ($ssh instanceof SSH1) {
switch (strtolower(get_class($ssh))) {
case 'net_ssh2':
$this->mode = NET_SCP_SSH2;
break;
case 'net_ssh1':
$this->packet_size = 50000; $this->packet_size = 50000;
$this->mode = NET_SCP_SSH1; $this->mode = self::MODE_SSH1;
break; } else {
default:
return; return;
} }
@ -146,11 +120,11 @@ class Net_SCP
/** /**
* Uploads a file to the SCP server. * Uploads a file to the SCP server.
* *
* By default, Net_SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. * By default, \phpseclib\Net\SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
* So, for example, if you set $data to 'filename.ext' and then do Net_SCP::get(), you will get a file, twelve bytes * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SCP::get(), you will get a file, twelve bytes
* long, containing 'filename.ext' as its contents. * long, containing 'filename.ext' as its contents.
* *
* Setting $mode to NET_SCP_LOCAL_FILE will change the above behavior. With NET_SCP_LOCAL_FILE, $remote_file will * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will
* contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
* large $remote_file will be, as well. * large $remote_file will be, as well.
* *
@ -164,7 +138,7 @@ class Net_SCP
* @return bool * @return bool
* @access public * @access public
*/ */
function put($remote_file, $data, $mode = NET_SCP_STRING, $callback = null) function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null)
{ {
if (!isset($this->ssh)) { if (!isset($this->ssh)) {
return false; return false;
@ -179,13 +153,13 @@ class Net_SCP
return false; return false;
} }
if ($this->mode == NET_SCP_SSH2) { if ($this->mode == self::MODE_SSH2) {
$this->packet_size = $this->ssh->packet_size_client_to_server[NET_SSH2_CHANNEL_EXEC] - 4; $this->packet_size = $this->ssh->packet_size_client_to_server[SSH2::CHANNEL_EXEC] - 4;
} }
$remote_file = basename($remote_file); $remote_file = basename($remote_file);
if ($mode == NET_SCP_STRING) { if ($mode == self::SOURCE_STRING) {
$size = strlen($data); $size = strlen($data);
} else { } else {
if (!is_file($data)) { if (!is_file($data)) {
@ -209,7 +183,7 @@ class Net_SCP
$sent = 0; $sent = 0;
while ($sent < $size) { while ($sent < $size) {
$temp = $mode & NET_SCP_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size); $temp = $mode & self::SOURCE_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size);
$this->_send($temp); $this->_send($temp);
$sent+= strlen($temp); $sent+= strlen($temp);
@ -219,7 +193,7 @@ class Net_SCP
} }
$this->_close(); $this->_close();
if ($mode != NET_SCP_STRING) { if ($mode != self::SOURCE_STRING) {
fclose($fp); fclose($fp);
} }
@ -297,10 +271,10 @@ class Net_SCP
function _send($data) function _send($data)
{ {
switch ($this->mode) { switch ($this->mode) {
case NET_SCP_SSH2: case self::MODE_SSH2:
$this->ssh->_send_channel_packet(NET_SSH2_CHANNEL_EXEC, $data); $this->ssh->_send_channel_packet(SSH2::CHANNEL_EXEC, $data);
break; break;
case NET_SCP_SSH1: case self::MODE_SSH1:
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data); $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
$this->ssh->_send_binary_packet($data); $this->ssh->_send_binary_packet($data);
} }
@ -315,18 +289,21 @@ class Net_SCP
function _receive() function _receive()
{ {
switch ($this->mode) { switch ($this->mode) {
case NET_SCP_SSH2: case self::MODE_SSH2:
return $this->ssh->_get_channel_packet(NET_SSH2_CHANNEL_EXEC, true); return $this->ssh->_get_channel_packet(SSH2::CHANNEL_EXEC, true);
case NET_SCP_SSH1: case self::MODE_SSH1:
if (!$this->ssh->bitmap) { if (!$this->ssh->bitmap) {
return false; return false;
} }
while (true) { while (true) {
$response = $this->ssh->_get_binary_packet(); $response = $this->ssh->_get_binary_packet();
switch ($response[NET_SSH1_RESPONSE_TYPE]) { switch ($response[SSH1::RESPONSE_TYPE]) {
case NET_SSH1_SMSG_STDOUT_DATA: case NET_SSH1_SMSG_STDOUT_DATA:
extract(unpack('Nlength', $response[NET_SSH1_RESPONSE_DATA])); if (strlen($response[SSH1::RESPONSE_DATA]) < 4) {
return $this->ssh->_string_shift($response[NET_SSH1_RESPONSE_DATA], $length); return false;
}
extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA]));
return $this->ssh->_string_shift($response[SSH1::RESPONSE_DATA], $length);
case NET_SSH1_SMSG_STDERR_DATA: case NET_SSH1_SMSG_STDERR_DATA:
break; break;
case NET_SSH1_SMSG_EXITSTATUS: case NET_SSH1_SMSG_EXITSTATUS:
@ -350,10 +327,10 @@ class Net_SCP
function _close() function _close()
{ {
switch ($this->mode) { switch ($this->mode) {
case NET_SCP_SSH2: case self::MODE_SSH2:
$this->ssh->_close_channel(NET_SSH2_CHANNEL_EXEC, true); $this->ssh->_close_channel(SSH2::CHANNEL_EXEC, true);
break; break;
case NET_SCP_SSH1: case self::MODE_SSH1:
$this->ssh->disconnect(); $this->ssh->disconnect();
} }
} }

View File

@ -3,7 +3,7 @@
/** /**
* Pure-PHP implementation of SFTP. * Pure-PHP implementation of SFTP.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* Currently only supports SFTPv2 and v3, which, according to wikipedia.org, "is the most widely used version, * Currently only supports SFTPv2 and v3, which, according to wikipedia.org, "is the most widely used version,
* implemented by the popular OpenSSH SFTP server". If you want SFTPv4/5/6 support, provide me with access * implemented by the popular OpenSSH SFTP server". If you want SFTPv4/5/6 support, provide me with access
@ -14,9 +14,9 @@
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Net/SFTP.php'; * include 'vendor/autoload.php';
* *
* $sftp = new Net_SFTP('www.domain.tld'); * $sftp = new \phpseclib\Net\SFTP('www.domain.tld');
* if (!$sftp->login('username', 'password')) { * if (!$sftp->login('username', 'password')) {
* exit('Login Failed'); * exit('Login Failed');
* } * }
@ -27,109 +27,68 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net * @category Net
* @package Net_SFTP * @package SFTP
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2009 Jim Wigginton * @copyright 2009 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/** namespace phpseclib\Net;
* Include Net_SSH2
*/
if (!class_exists('Net_SSH2')) {
include_once 'SSH2.php';
}
/**#@+
* @access public
* @see self::getLog()
*/
/**
* Returns the message numbers
*/
define('NET_SFTP_LOG_SIMPLE', NET_SSH2_LOG_SIMPLE);
/**
* Returns the message content
*/
define('NET_SFTP_LOG_COMPLEX', NET_SSH2_LOG_COMPLEX);
/**
* Outputs the message content in real-time.
*/
define('NET_SFTP_LOG_REALTIME', 3);
/**#@-*/
/**
* SFTP channel constant
*
* Net_SSH2::exec() uses 0 and Net_SSH2::read() / Net_SSH2::write() use 1.
*
* @see Net_SSH2::_send_channel_packet()
* @see Net_SSH2::_get_channel_packet()
* @access private
*/
define('NET_SFTP_CHANNEL', 0x100);
/**#@+
* @access public
* @see self::put()
*/
/**
* Reads data from a local file.
*/
define('NET_SFTP_LOCAL_FILE', 1);
/**
* Reads data from a string.
*/
// this value isn't really used anymore but i'm keeping it reserved for historical reasons
define('NET_SFTP_STRING', 2);
/**
* Reads data from callback:
* function callback($length) returns string to proceed, null for EOF
*/
define('NET_SFTP_CALLBACK', 16);
/**
* Resumes an upload
*/
define('NET_SFTP_RESUME', 4);
/**
* Append a local file to an already existing remote file
*/
define('NET_SFTP_RESUME_START', 8);
/**#@-*/
/** /**
* Pure-PHP implementations of SFTP. * Pure-PHP implementations of SFTP.
* *
* @package Net_SFTP * @package SFTP
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class Net_SFTP extends Net_SSH2 class SFTP extends SSH2
{ {
/**
* SFTP channel constant
*
* \phpseclib\Net\SSH2::exec() uses 0 and \phpseclib\Net\SSH2::read() / \phpseclib\Net\SSH2::write() use 1.
*
* @see \phpseclib\Net\SSH2::_send_channel_packet()
* @see \phpseclib\Net\SSH2::_get_channel_packet()
* @access private
*/
const CHANNEL = 0x100;
/**#@+
* @access public
* @see \phpseclib\Net\SFTP::put()
*/
/**
* Reads data from a local file.
*/
const SOURCE_LOCAL_FILE = 1;
/**
* Reads data from a string.
*/
// this value isn't really used anymore but i'm keeping it reserved for historical reasons
const SOURCE_STRING = 2;
/**
* Reads data from callback:
* function callback($length) returns string to proceed, null for EOF
*/
const SOURCE_CALLBACK = 16;
/**
* Resumes an upload
*/
const RESUME = 4;
/**
* Append a local file to an already existing remote file
*/
const RESUME_START = 8;
/**#@-*/
/** /**
* Packet Types * Packet Types
* *
* @see self::Net_SFTP() * @see self::__construct()
* @var array * @var array
* @access private * @access private
*/ */
@ -138,7 +97,7 @@ class Net_SFTP extends Net_SSH2
/** /**
* Status Codes * Status Codes
* *
* @see self::Net_SFTP() * @see self::__construct()
* @var array * @var array
* @access private * @access private
*/ */
@ -250,7 +209,7 @@ class Net_SFTP extends Net_SSH2
/** /**
* Max SFTP Packet Size * Max SFTP Packet Size
* *
* @see self::Net_SFTP() * @see self::__construct()
* @see self::get() * @see self::get()
* @var array * @var array
* @access private * @access private
@ -285,12 +244,12 @@ class Net_SFTP extends Net_SSH2
* @param string $host * @param string $host
* @param int $port * @param int $port
* @param int $timeout * @param int $timeout
* @return Net_SFTP * @return \phpseclib\Net\SFTP
* @access public * @access public
*/ */
function Net_SFTP($host, $port = 22, $timeout = 10) function __construct($host, $port = 22, $timeout = 10)
{ {
parent::Net_SSH2($host, $port, $timeout); parent::__construct($host, $port, $timeout);
$this->max_sftp_packet = 1 << 15; $this->max_sftp_packet = 1 << 15;
@ -366,7 +325,7 @@ class Net_SFTP extends Net_SSH2
31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK'
); );
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
// the order, in this case, matters quite a lot - see Net_SFTP::_parseAttributes() to understand why // the order, in this case, matters quite a lot - see \phpseclib\Net\SFTP::_parseAttributes() to understand why
$this->attributes = array( $this->attributes = array(
0x00000001 => 'NET_SFTP_ATTR_SIZE', 0x00000001 => 'NET_SFTP_ATTR_SIZE',
0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+
@ -380,7 +339,7 @@ class Net_SFTP extends Net_SSH2
); );
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
// the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name
// the array for that $this->open5_flags and similarily alter the constant names. // the array for that $this->open5_flags and similarly alter the constant names.
$this->open_flags = array( $this->open_flags = array(
0x00000001 => 'NET_SFTP_OPEN_READ', 0x00000001 => 'NET_SFTP_OPEN_READ',
0x00000002 => 'NET_SFTP_OPEN_WRITE', 0x00000002 => 'NET_SFTP_OPEN_WRITE',
@ -390,7 +349,7 @@ class Net_SFTP extends Net_SSH2
0x00000020 => 'NET_SFTP_OPEN_EXCL' 0x00000020 => 'NET_SFTP_OPEN_EXCL'
); );
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2
// see Net_SFTP::_parseLongname() for an explanation // see \phpseclib\Net\SFTP::_parseLongname() for an explanation
$this->file_types = array( $this->file_types = array(
1 => 'NET_SFTP_TYPE_REGULAR', 1 => 'NET_SFTP_TYPE_REGULAR',
2 => 'NET_SFTP_TYPE_DIRECTORY', 2 => 'NET_SFTP_TYPE_DIRECTORY',
@ -413,7 +372,7 @@ class Net_SFTP extends Net_SSH2
); );
if (!defined('NET_SFTP_QUEUE_SIZE')) { if (!defined('NET_SFTP_QUEUE_SIZE')) {
define('NET_SFTP_QUEUE_SIZE', 50); define('NET_SFTP_QUEUE_SIZE', 32);
} }
} }
@ -432,14 +391,14 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
$this->window_size_server_to_client[NET_SFTP_CHANNEL] = $this->window_size; $this->window_size_server_to_client[self::CHANNEL] = $this->window_size;
$packet = pack( $packet = pack(
'CNa*N3', 'CNa*N3',
NET_SSH2_MSG_CHANNEL_OPEN, NET_SSH2_MSG_CHANNEL_OPEN,
strlen('session'), strlen('session'),
'session', 'session',
NET_SFTP_CHANNEL, self::CHANNEL,
$this->window_size, $this->window_size,
0x4000 0x4000
); );
@ -448,9 +407,9 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
$this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN; $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
$response = $this->_get_channel_packet(NET_SFTP_CHANNEL); $response = $this->_get_channel_packet(self::CHANNEL);
if ($response === false) { if ($response === false) {
return false; return false;
} }
@ -458,7 +417,7 @@ class Net_SFTP extends Net_SSH2
$packet = pack( $packet = pack(
'CNNa*CNa*', 'CNNa*CNa*',
NET_SSH2_MSG_CHANNEL_REQUEST, NET_SSH2_MSG_CHANNEL_REQUEST,
$this->server_channels[NET_SFTP_CHANNEL], $this->server_channels[self::CHANNEL],
strlen('subsystem'), strlen('subsystem'),
'subsystem', 'subsystem',
1, 1,
@ -469,9 +428,9 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
$this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
$response = $this->_get_channel_packet(NET_SFTP_CHANNEL); $response = $this->_get_channel_packet(self::CHANNEL);
if ($response === false) { if ($response === false) {
// from PuTTY's psftp.exe // from PuTTY's psftp.exe
$command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" . $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
@ -482,7 +441,7 @@ class Net_SFTP extends Net_SSH2
$packet = pack( $packet = pack(
'CNNa*CNa*', 'CNNa*CNa*',
NET_SSH2_MSG_CHANNEL_REQUEST, NET_SSH2_MSG_CHANNEL_REQUEST,
$this->server_channels[NET_SFTP_CHANNEL], $this->server_channels[self::CHANNEL],
strlen('exec'), strlen('exec'),
'exec', 'exec',
1, 1,
@ -493,15 +452,15 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
$this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
$response = $this->_get_channel_packet(NET_SFTP_CHANNEL); $response = $this->_get_channel_packet(self::CHANNEL);
if ($response === false) { if ($response === false) {
return false; return false;
} }
} }
$this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA; $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA;
if (!$this->_send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) { if (!$this->_send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) {
return false; return false;
@ -513,11 +472,20 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nversion', $this->_string_shift($response, 4))); extract(unpack('Nversion', $this->_string_shift($response, 4)));
$this->version = $version; $this->version = $version;
while (!empty($response)) { while (!empty($response)) {
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nlength', $this->_string_shift($response, 4))); extract(unpack('Nlength', $this->_string_shift($response, 4)));
$key = $this->_string_shift($response, $length); $key = $this->_string_shift($response, $length);
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nlength', $this->_string_shift($response, 4))); extract(unpack('Nlength', $this->_string_shift($response, 4)));
$value = $this->_string_shift($response, $length); $value = $this->_string_shift($response, $length);
$this->extensions[$key] = $value; $this->extensions[$key] = $value;
@ -559,7 +527,7 @@ class Net_SFTP extends Net_SSH2
So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and
a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements
v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed
in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what Net_SFTP would do is close the in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib\Net\SFTP would do is close the
channel and reopen it with a new and updated SSH_FXP_INIT packet. channel and reopen it with a new and updated SSH_FXP_INIT packet.
*/ */
switch ($this->version) { switch ($this->version) {
@ -628,12 +596,15 @@ class Net_SFTP extends Net_SSH2
function _logError($response, $status = -1) function _logError($response, $status = -1)
{ {
if ($status == -1) { if ($status == -1) {
if (strlen($response) < 4) {
return;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
} }
$error = $this->status_codes[$status]; $error = $this->status_codes[$status];
if ($this->version > 2) { if ($this->version > 2 || strlen($response) < 4) {
extract(unpack('Nlength', $this->_string_shift($response, 4))); extract(unpack('Nlength', $this->_string_shift($response, 4)));
$this->sftp_errors[] = $error . ': ' . $this->_string_shift($response, $length); $this->sftp_errors[] = $error . ': ' . $this->_string_shift($response, $length);
} else { } else {
@ -641,6 +612,21 @@ class Net_SFTP extends Net_SSH2
} }
} }
/**
* Returns canonicalized absolute pathname
*
* realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input
* path and returns the canonicalized absolute pathname.
*
* @param string $path
* @return mixed
* @access public
*/
function realpath($path)
{
return $this->_realpath($path);
}
/** /**
* Canonicalize the Server-Side Path Name * Canonicalize the Server-Side Path Name
* *
@ -667,6 +653,9 @@ class Net_SFTP extends Net_SSH2
// should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks
// at is the first part and that part is defined the same in SFTP versions 3 through 6. // at is the first part and that part is defined the same in SFTP versions 3 through 6.
$this->_string_shift($response, 4); // skip over the count - it should be 1, anyway $this->_string_shift($response, 4); // skip over the count - it should be 1, anyway
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nlength', $this->_string_shift($response, 4))); extract(unpack('Nlength', $this->_string_shift($response, 4)));
return $this->_string_shift($response, $length); return $this->_string_shift($response, $length);
case NET_SFTP_STATUS: case NET_SFTP_STATUS:
@ -710,7 +699,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function chdir($dir) function chdir($dir)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -739,7 +728,7 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
// see Net_SFTP::nlist() for a more thorough explanation of the following // see \phpseclib\Net\SFTP::nlist() for a more thorough explanation of the following
$response = $this->_get_sftp_packet(); $response = $this->_get_sftp_packet();
switch ($this->packet_type) { switch ($this->packet_type) {
case NET_SFTP_HANDLE: case NET_SFTP_HANDLE:
@ -856,7 +845,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function _list($dir, $raw = true) function _list($dir, $raw = true)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -901,10 +890,19 @@ class Net_SFTP extends Net_SSH2
$response = $this->_get_sftp_packet(); $response = $this->_get_sftp_packet();
switch ($this->packet_type) { switch ($this->packet_type) {
case NET_SFTP_NAME: case NET_SFTP_NAME:
if (strlen($response) < 4) {
return false;
}
extract(unpack('Ncount', $this->_string_shift($response, 4))); extract(unpack('Ncount', $this->_string_shift($response, 4)));
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nlength', $this->_string_shift($response, 4))); extract(unpack('Nlength', $this->_string_shift($response, 4)));
$shortname = $this->_string_shift($response, $length); $shortname = $this->_string_shift($response, $length);
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nlength', $this->_string_shift($response, 4))); extract(unpack('Nlength', $this->_string_shift($response, 4)));
$longname = $this->_string_shift($response, $length); $longname = $this->_string_shift($response, $length);
$attributes = $this->_parseAttributes($response); $attributes = $this->_parseAttributes($response);
@ -931,6 +929,9 @@ class Net_SFTP extends Net_SSH2
} }
break; break;
case NET_SFTP_STATUS: case NET_SFTP_STATUS:
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_EOF) { if ($status != NET_SFTP_STATUS_EOF) {
$this->_logError($response, $status); $this->_logError($response, $status);
@ -1065,7 +1066,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function size($filename) function size($filename)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -1179,7 +1180,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function stat($filename) function stat($filename)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -1236,7 +1237,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function lstat($filename) function lstat($filename)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -1293,7 +1294,7 @@ class Net_SFTP extends Net_SSH2
/** /**
* Returns general information about a file or symbolic link * Returns general information about a file or symbolic link
* *
* Determines information without calling Net_SFTP::_realpath(). * Determines information without calling \phpseclib\Net\SFTP::_realpath().
* The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT. * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
* *
* @param string $filename * @param string $filename
@ -1350,7 +1351,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function touch($filename, $time = null, $atime = null) function touch($filename, $time = null, $atime = null)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -1488,7 +1489,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function _setstat($filename, $attr, $recursive) function _setstat($filename, $attr, $recursive)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -1525,6 +1526,9 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_OK) { if ($status != NET_SFTP_STATUS_OK) {
$this->_logError($response, $status); $this->_logError($response, $status);
@ -1615,7 +1619,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function readlink($link) function readlink($link)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -1637,12 +1641,18 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
if (strlen($response) < 4) {
return false;
}
extract(unpack('Ncount', $this->_string_shift($response, 4))); extract(unpack('Ncount', $this->_string_shift($response, 4)));
// the file isn't a symlink // the file isn't a symlink
if (!$count) { if (!$count) {
return false; return false;
} }
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nlength', $this->_string_shift($response, 4))); extract(unpack('Nlength', $this->_string_shift($response, 4)));
return $this->_string_shift($response, $length); return $this->_string_shift($response, $length);
} }
@ -1659,11 +1669,11 @@ class Net_SFTP extends Net_SSH2
*/ */
function symlink($target, $link) function symlink($target, $link)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
$target = $this->_realpath($target); //$target = $this->_realpath($target);
$link = $this->_realpath($link); $link = $this->_realpath($link);
$packet = pack('Na*Na*', strlen($target), $target, strlen($link), $link); $packet = pack('Na*Na*', strlen($target), $target, strlen($link), $link);
@ -1677,6 +1687,9 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_OK) { if ($status != NET_SFTP_STATUS_OK) {
$this->_logError($response, $status); $this->_logError($response, $status);
@ -1695,7 +1708,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function mkdir($dir, $mode = -1, $recursive = false) function mkdir($dir, $mode = -1, $recursive = false)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -1740,6 +1753,9 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_OK) { if ($status != NET_SFTP_STATUS_OK) {
$this->_logError($response, $status); $this->_logError($response, $status);
@ -1758,7 +1774,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function rmdir($dir) function rmdir($dir)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -1777,6 +1793,9 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_OK) { if ($status != NET_SFTP_STATUS_OK) {
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED? // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED?
@ -1796,39 +1815,37 @@ class Net_SFTP extends Net_SSH2
/** /**
* Uploads a file to the SFTP server. * Uploads a file to the SFTP server.
* *
* By default, Net_SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. * By default, \phpseclib\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
* So, for example, if you set $data to 'filename.ext' and then do Net_SFTP::get(), you will get a file, twelve bytes * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SFTP::get(), you will get a file, twelve bytes
* long, containing 'filename.ext' as its contents. * long, containing 'filename.ext' as its contents.
* *
* Setting $mode to NET_SFTP_LOCAL_FILE will change the above behavior. With NET_SFTP_LOCAL_FILE, $remote_file will * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will
* contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
* large $remote_file will be, as well. * large $remote_file will be, as well.
* *
* Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number of bytes to return, and returns a string if there is some data or null if there is no more data
*
* If $data is a resource then it'll be used as a resource instead. * If $data is a resource then it'll be used as a resource instead.
* *
*
* Setting $mode to NET_SFTP_CALLBACK will use $data as callback function, which gets only one parameter -- number
* of bytes to return, and returns a string if there is some data or null if there is no more data
*
* Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
* care of that, yourself. * care of that, yourself.
* *
* $mode can take an additional two parameters - NET_SFTP_RESUME and NET_SFTP_RESUME_START. These are bitwise AND'd with * $mode can take an additional two parameters - self::RESUME and self::RESUME_START. These are bitwise AND'd with
* $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following: * $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following:
* *
* NET_SFTP_LOCAL_FILE | NET_SFTP_RESUME * self::SOURCE_LOCAL_FILE | self::RESUME
* *
* If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace * If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace
* NET_SFTP_RESUME with NET_SFTP_RESUME_START. * self::RESUME with self::RESUME_START.
* *
* If $mode & (NET_SFTP_RESUME | NET_SFTP_RESUME_START) then NET_SFTP_RESUME_START will be assumed. * If $mode & (self::RESUME | self::RESUME_START) then self::RESUME_START will be assumed.
* *
* $start and $local_start give you more fine grained control over this process and take precident over NET_SFTP_RESUME * $start and $local_start give you more fine grained control over this process and take precident over self::RESUME
* when they're non-negative. ie. $start could let you write at the end of a file (like NET_SFTP_RESUME) or in the middle * when they're non-negative. ie. $start could let you write at the end of a file (like self::RESUME) or in the middle
* of one. $local_start could let you start your reading from the end of a file (like NET_SFTP_RESUME_START) or in the * of one. $local_start could let you start your reading from the end of a file (like self::RESUME_START) or in the
* middle of one. * middle of one.
* *
* Setting $local_start to > 0 or $mode | NET_SFTP_RESUME_START doesn't do anything unless $mode | NET_SFTP_LOCAL_FILE. * Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE.
* *
* @param string $remote_file * @param string $remote_file
* @param string|resource $data * @param string|resource $data
@ -1838,11 +1855,11 @@ class Net_SFTP extends Net_SSH2
* @param callable|null $progressCallback * @param callable|null $progressCallback
* @return bool * @return bool
* @access public * @access public
* @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - Net_SFTP::setMode(). * @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode().
*/ */
function put($remote_file, $data, $mode = NET_SFTP_STRING, $start = -1, $local_start = -1, $progressCallback = null) function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -1856,11 +1873,11 @@ class Net_SFTP extends Net_SSH2
$flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE; $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE;
// according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file." // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file."
// in practice, it doesn't seem to do that. // in practice, it doesn't seem to do that.
//$flags|= ($mode & NET_SFTP_RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE; //$flags|= ($mode & self::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE;
if ($start >= 0) { if ($start >= 0) {
$offset = $start; $offset = $start;
} elseif ($mode & NET_SFTP_RESUME) { } elseif ($mode & self::RESUME) {
// if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called
$size = $this->size($remote_file); $size = $this->size($remote_file);
$offset = $size !== false ? $size : 0; $offset = $size !== false ? $size : 0;
@ -1890,18 +1907,25 @@ class Net_SFTP extends Net_SSH2
// 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
$dataCallback = false; $dataCallback = false;
switch (true) { switch (true) {
case $mode & NET_SFTP_CALLBACK: case $mode & self::SOURCE_CALLBACK:
if (!is_callable($data)) { if (!is_callable($data)) {
user_error("\$data should be is_callable if you set NET_SFTP_CALLBACK flag"); user_error("\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
} }
$dataCallback = $data; $dataCallback = $data;
// do nothing // do nothing
break; break;
case is_resource($data): case is_resource($data):
$mode = $mode & ~NET_SFTP_LOCAL_FILE; $mode = $mode & ~self::SOURCE_LOCAL_FILE;
$info = stream_get_meta_data($data);
if ($info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') {
$fp = fopen('php://memory', 'w+');
stream_copy_to_stream($data, $fp);
rewind($fp);
} else {
$fp = $data; $fp = $data;
}
break; break;
case $mode & NET_SFTP_LOCAL_FILE: case $mode & self::SOURCE_LOCAL_FILE:
if (!is_file($data)) { if (!is_file($data)) {
user_error("$data is not a valid file"); user_error("$data is not a valid file");
return false; return false;
@ -1933,7 +1957,7 @@ class Net_SFTP extends Net_SSH2
// make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header" // make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
$sftp_packet_size-= strlen($handle) + 25; $sftp_packet_size-= strlen($handle) + 25;
$i = 0; $i = 0;
while ($dataCallback || ($sent < $size)) { while ($dataCallback || ($size === 0 || $sent < $size)) {
if ($dataCallback) { if ($dataCallback) {
$temp = call_user_func($dataCallback, $sftp_packet_size); $temp = call_user_func($dataCallback, $sftp_packet_size);
if (is_null($temp)) { if (is_null($temp)) {
@ -1941,11 +1965,15 @@ class Net_SFTP extends Net_SSH2
} }
} else { } else {
$temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size); $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
if ($temp === false || $temp === '') {
break;
} }
}
$subtemp = $offset + $sent; $subtemp = $offset + $sent;
$packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp); $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) { if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
if ($mode & NET_SFTP_LOCAL_FILE) { if ($mode & self::SOURCE_LOCAL_FILE) {
fclose($fp); fclose($fp);
} }
return false; return false;
@ -1967,14 +1995,14 @@ class Net_SFTP extends Net_SSH2
} }
if (!$this->_read_put_responses($i)) { if (!$this->_read_put_responses($i)) {
if ($mode & NET_SFTP_LOCAL_FILE) { if ($mode & self::SOURCE_LOCAL_FILE) {
fclose($fp); fclose($fp);
} }
$this->_close_handle($handle); $this->_close_handle($handle);
return false; return false;
} }
if ($mode & NET_SFTP_LOCAL_FILE) { if ($mode & self::SOURCE_LOCAL_FILE) {
fclose($fp); fclose($fp);
} }
@ -2000,6 +2028,9 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_OK) { if ($status != NET_SFTP_STATUS_OK) {
$this->_logError($response, $status); $this->_logError($response, $status);
@ -2031,6 +2062,9 @@ class Net_SFTP extends Net_SSH2
return false; return false;
} }
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_OK) { if ($status != NET_SFTP_STATUS_OK) {
$this->_logError($response, $status); $this->_logError($response, $status);
@ -2058,7 +2092,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function get($remote_file, $local_file = false, $offset = 0, $length = -1) function get($remote_file, $local_file = false, $offset = 0, $length = -1)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -2104,17 +2138,42 @@ class Net_SFTP extends Net_SSH2
$fclose_check = $local_file !== false && !is_resource($local_file); $fclose_check = $local_file !== false && !is_resource($local_file);
$start = $offset; $start = $offset;
$size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length; $read = 0;
while (true) { while (true) {
$packet = pack('Na*N3', strlen($handle), $handle, $offset / 4294967296, $offset, $size); $i = 0;
while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) {
$tempoffset = $start + $read;
$packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
$packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) { if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
if ($fclose_check) { if ($fclose_check) {
fclose($fp); fclose($fp);
} }
return false; return false;
} }
$packet = null;
$read+= $packet_size;
$i++;
}
if (!$i) {
break;
}
$clear_responses = false;
while ($i > 0) {
$i--;
if ($clear_responses) {
$this->_get_sftp_packet();
continue;
} else {
$response = $this->_get_sftp_packet(); $response = $this->_get_sftp_packet();
}
switch ($this->packet_type) { switch ($this->packet_type) {
case NET_SFTP_DATA: case NET_SFTP_DATA:
$temp = substr($response, 4); $temp = substr($response, 4);
@ -2124,20 +2183,23 @@ class Net_SFTP extends Net_SSH2
} else { } else {
fputs($fp, $temp); fputs($fp, $temp);
} }
$temp = null;
break; break;
case NET_SFTP_STATUS: case NET_SFTP_STATUS:
// could, in theory, return false if !strlen($content) but we'll hold off for the time being // could, in theory, return false if !strlen($content) but we'll hold off for the time being
$this->_logError($response); $this->_logError($response);
break 2; $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses
break;
default: default:
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
if ($fclose_check) { if ($fclose_check) {
fclose($fp); fclose($fp);
} }
return false; user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS');
}
$response = null;
} }
if ($length > 0 && $length <= $offset - $start) { if ($clear_responses) {
break; break;
} }
} }
@ -2172,7 +2234,16 @@ class Net_SFTP extends Net_SSH2
*/ */
function delete($path, $recursive = true) function delete($path, $recursive = true)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false;
}
if (is_object($path)) {
// It's an object. Cast it as string before we check anything else.
$path = (string) $path;
}
if (!is_string($path) || $path == '') {
return false; return false;
} }
@ -2193,6 +2264,9 @@ class Net_SFTP extends Net_SSH2
} }
// 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
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_OK) { if ($status != NET_SFTP_STATUS_OK) {
$this->_logError($response, $status); $this->_logError($response, $status);
@ -2595,7 +2669,7 @@ class Net_SFTP extends Net_SSH2
*/ */
function rename($oldname, $newname) function rename($oldname, $newname)
{ {
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) { if (!($this->bitmap & SSH2::MASK_LOGIN)) {
return false; return false;
} }
@ -2618,6 +2692,9 @@ class Net_SFTP extends Net_SSH2
} }
// 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
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4))); extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_OK) { if ($status != NET_SFTP_STATUS_OK) {
$this->_logError($response, $status); $this->_logError($response, $status);
@ -2645,6 +2722,10 @@ class Net_SFTP extends Net_SSH2
function _parseAttributes(&$response) function _parseAttributes(&$response)
{ {
$attr = array(); $attr = array();
if (strlen($response) < 4) {
user_error('Malformed file attributes');
return array();
}
extract(unpack('Nflags', $this->_string_shift($response, 4))); extract(unpack('Nflags', $this->_string_shift($response, 4)));
// SFTPv4+ have a type field (a byte) that follows the above flag field // SFTPv4+ have a type field (a byte) that follows the above flag field
foreach ($this->attributes as $key => $value) { foreach ($this->attributes as $key => $value) {
@ -2659,9 +2740,17 @@ class Net_SFTP extends Net_SSH2
$attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8))); $attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8)));
break; break;
case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only) case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)
if (strlen($response) < 8) {
user_error('Malformed file attributes');
return $attr;
}
$attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8)); $attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8));
break; break;
case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004 case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004
if (strlen($response) < 4) {
user_error('Malformed file attributes');
return $attr;
}
$attr+= unpack('Npermissions', $this->_string_shift($response, 4)); $attr+= unpack('Npermissions', $this->_string_shift($response, 4));
// mode == permissions; permissions was the original array key and is retained for bc purposes. // mode == permissions; permissions was the original array key and is retained for bc purposes.
// mode was added because that's the more industry standard terminology // mode was added because that's the more industry standard terminology
@ -2672,13 +2761,29 @@ class Net_SFTP extends Net_SSH2
} }
break; break;
case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008 case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008
if (strlen($response) < 8) {
user_error('Malformed file attributes');
return $attr;
}
$attr+= unpack('Natime/Nmtime', $this->_string_shift($response, 8)); $attr+= unpack('Natime/Nmtime', $this->_string_shift($response, 8));
break; break;
case NET_SFTP_ATTR_EXTENDED: // 0x80000000 case NET_SFTP_ATTR_EXTENDED: // 0x80000000
if (strlen($response) < 4) {
user_error('Malformed file attributes');
return $attr;
}
extract(unpack('Ncount', $this->_string_shift($response, 4))); extract(unpack('Ncount', $this->_string_shift($response, 4)));
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
if (strlen($response) < 4) {
user_error('Malformed file attributes');
return $attr;
}
extract(unpack('Nlength', $this->_string_shift($response, 4))); extract(unpack('Nlength', $this->_string_shift($response, 4)));
$key = $this->_string_shift($response, $length); $key = $this->_string_shift($response, $length);
if (strlen($response) < 4) {
user_error('Malformed file attributes');
return $attr;
}
extract(unpack('Nlength', $this->_string_shift($response, 4))); extract(unpack('Nlength', $this->_string_shift($response, 4)));
$attr[$key] = $this->_string_shift($response, $length); $attr[$key] = $this->_string_shift($response, $length);
} }
@ -2771,7 +2876,7 @@ class Net_SFTP extends Net_SSH2
* @param int $type * @param int $type
* @param string $data * @param string $data
* @see self::_get_sftp_packet() * @see self::_get_sftp_packet()
* @see Net_SSH2::_send_channel_packet() * @see self::_send_channel_packet()
* @return bool * @return bool
* @access private * @access private
*/ */
@ -2782,19 +2887,19 @@ class Net_SFTP extends Net_SSH2
pack('NCa*', strlen($data) + 1, $type, $data); pack('NCa*', strlen($data) + 1, $type, $data);
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
$result = $this->_send_channel_packet(NET_SFTP_CHANNEL, $packet); $result = $this->_send_channel_packet(self::CHANNEL, $packet);
$stop = strtok(microtime(), ' ') + strtok(''); $stop = strtok(microtime(), ' ') + strtok('');
if (defined('NET_SFTP_LOGGING')) { if (defined('NET_SFTP_LOGGING')) {
$packet_type = '-> ' . $this->packet_types[$type] . $packet_type = '-> ' . $this->packet_types[$type] .
' (' . round($stop - $start, 4) . 's)'; ' (' . round($stop - $start, 4) . 's)';
if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) { if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
echo "<pre>\r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n</pre>\r\n"; echo "<pre>\r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n</pre>\r\n";
flush(); flush();
ob_flush(); ob_flush();
} else { } else {
$this->packet_type_log[] = $packet_type; $this->packet_type_log[] = $packet_type;
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) { if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
$this->packet_log[] = $data; $this->packet_log[] = $data;
} }
} }
@ -2824,7 +2929,7 @@ class Net_SFTP extends Net_SSH2
// SFTP packet length // SFTP packet length
while (strlen($this->packet_buffer) < 4) { while (strlen($this->packet_buffer) < 4) {
$temp = $this->_get_channel_packet(NET_SFTP_CHANNEL); $temp = $this->_get_channel_packet(self::CHANNEL);
if (is_bool($temp)) { if (is_bool($temp)) {
$this->packet_type = false; $this->packet_type = false;
$this->packet_buffer = ''; $this->packet_buffer = '';
@ -2832,13 +2937,16 @@ class Net_SFTP extends Net_SSH2
} }
$this->packet_buffer.= $temp; $this->packet_buffer.= $temp;
} }
if (strlen($this->packet_buffer) < 4) {
return false;
}
extract(unpack('Nlength', $this->_string_shift($this->packet_buffer, 4))); extract(unpack('Nlength', $this->_string_shift($this->packet_buffer, 4)));
$tempLength = $length; $tempLength = $length;
$tempLength-= strlen($this->packet_buffer); $tempLength-= strlen($this->packet_buffer);
// SFTP packet type and data payload // SFTP packet type and data payload
while ($tempLength > 0) { while ($tempLength > 0) {
$temp = $this->_get_channel_packet(NET_SFTP_CHANNEL); $temp = $this->_get_channel_packet(self::CHANNEL);
if (is_bool($temp)) { if (is_bool($temp)) {
$this->packet_type = false; $this->packet_type = false;
$this->packet_buffer = ''; $this->packet_buffer = '';
@ -2864,13 +2972,13 @@ class Net_SFTP extends Net_SSH2
if (defined('NET_SFTP_LOGGING')) { if (defined('NET_SFTP_LOGGING')) {
$packet_type = '<- ' . $this->packet_types[$this->packet_type] . $packet_type = '<- ' . $this->packet_types[$this->packet_type] .
' (' . round($stop - $start, 4) . 's)'; ' (' . round($stop - $start, 4) . 's)';
if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) { if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
echo "<pre>\r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n</pre>\r\n"; echo "<pre>\r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n</pre>\r\n";
flush(); flush();
ob_flush(); ob_flush();
} else { } else {
$this->packet_type_log[] = $packet_type; $this->packet_type_log[] = $packet_type;
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) { if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
$this->packet_log[] = $packet; $this->packet_log[] = $packet;
} }
} }
@ -2894,10 +3002,10 @@ class Net_SFTP extends Net_SSH2
} }
switch (NET_SFTP_LOGGING) { switch (NET_SFTP_LOGGING) {
case NET_SFTP_LOG_COMPLEX: case self::LOG_COMPLEX:
return $this->_format_log($this->packet_log, $this->packet_type_log); return $this->_format_log($this->packet_log, $this->packet_type_log);
break; break;
//case NET_SFTP_LOG_SIMPLE: //case self::LOG_SIMPLE:
default: default:
return $this->packet_type_log; return $this->packet_type_log;
} }

View File

@ -7,40 +7,27 @@
* *
* PHP version 5 * PHP version 5
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net * @category Net
* @package Net_SFTP_Stream * @package SFTP
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2013 Jim Wigginton * @copyright 2013 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
namespace phpseclib\Net\SFTP;
use phpseclib\Crypt\RSA;
use phpseclib\Net\SFTP;
/** /**
* SFTP Stream Wrapper * SFTP Stream Wrapper
* *
* @package Net_SFTP_Stream * @package SFTP
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
class Net_SFTP_Stream class Stream
{ {
/** /**
* SFTP instances * SFTP instances
@ -137,8 +124,7 @@ class Net_SFTP_Stream
if (in_array($protocol, stream_get_wrappers(), true)) { if (in_array($protocol, stream_get_wrappers(), true)) {
return false; return false;
} }
$class = function_exists('get_called_class') ? get_called_class() : __CLASS__; return stream_wrapper_register($protocol, get_called_class());
return stream_wrapper_register($protocol, $class);
} }
/** /**
@ -146,15 +132,11 @@ class Net_SFTP_Stream
* *
* @access public * @access public
*/ */
function Net_SFTP_Stream() function __construct()
{ {
if (defined('NET_SFTP_STREAM_LOGGING')) { if (defined('NET_SFTP_STREAM_LOGGING')) {
echo "__construct()\r\n"; echo "__construct()\r\n";
} }
if (!class_exists('Net_SFTP')) {
include_once 'Net/SFTP.php';
}
} }
/** /**
@ -198,7 +180,7 @@ class Net_SFTP_Stream
if ($host[0] == '$') { if ($host[0] == '$') {
$host = substr($host, 1); $host = substr($host, 1);
global $$host; global $$host;
if (!is_object($$host) || get_class($$host) != 'Net_SFTP') { if (($$host instanceof SFTP) === false) {
return false; return false;
} }
$this->sftp = $$host; $this->sftp = $$host;
@ -212,7 +194,7 @@ class Net_SFTP_Stream
if (isset($context[$scheme]['sftp'])) { if (isset($context[$scheme]['sftp'])) {
$sftp = $context[$scheme]['sftp']; $sftp = $context[$scheme]['sftp'];
} }
if (isset($sftp) && is_object($sftp) && get_class($sftp) == 'Net_SFTP') { if (isset($sftp) && $sftp instanceof SFTP) {
$this->sftp = $sftp; $this->sftp = $sftp;
return $path; return $path;
} }
@ -222,7 +204,7 @@ class Net_SFTP_Stream
if (isset($context[$scheme]['password'])) { if (isset($context[$scheme]['password'])) {
$pass = $context[$scheme]['password']; $pass = $context[$scheme]['password'];
} }
if (isset($context[$scheme]['privkey']) && is_object($context[$scheme]['privkey']) && get_Class($context[$scheme]['privkey']) == 'Crypt_RSA') { if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof RSA) {
$pass = $context[$scheme]['privkey']; $pass = $context[$scheme]['privkey'];
} }
@ -230,11 +212,11 @@ class Net_SFTP_Stream
return false; return false;
} }
// casting $pass to a string is necessary in the event that it's a Crypt_RSA object // casting $pass to a string is necessary in the event that it's a \phpseclib\Crypt\RSA object
if (isset(self::$instances[$host][$port][$user][(string) $pass])) { if (isset(self::$instances[$host][$port][$user][(string) $pass])) {
$this->sftp = self::$instances[$host][$port][$user][(string) $pass]; $this->sftp = self::$instances[$host][$port][$user][(string) $pass];
} else { } else {
$this->sftp = new Net_SFTP($host, $port); $this->sftp = new SFTP($host, $port);
$this->sftp->disableStatCache(); $this->sftp->disableStatCache();
if (isset($this->notification) && is_callable($this->notification)) { if (isset($this->notification) && is_callable($this->notification)) {
/* if !is_callable($this->notification) we could do this: /* if !is_callable($this->notification) we could do this:
@ -366,7 +348,7 @@ class Net_SFTP_Stream
return false; return false;
} }
$result = $this->sftp->put($this->path, $data, NET_SFTP_STRING, $this->pos); $result = $this->sftp->put($this->path, $data, SFTP::SOURCE_STRING, $this->pos);
if (isset($this->notification) && is_callable($this->notification)) { if (isset($this->notification) && is_callable($this->notification)) {
if (!$result) { if (!$result) {
call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0); call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
@ -506,7 +488,7 @@ class Net_SFTP_Stream
* Renames a file or directory * Renames a file or directory
* *
* Attempts to rename oldname to newname, moving it between directories if necessary. * Attempts to rename oldname to newname, moving it between directories if necessary.
* If newname exists, it will be overwritten. This is a departure from what Net_SFTP * If newname exists, it will be overwritten. This is a departure from what \phpseclib\Net\SFTP
* does. * does.
* *
* @param string $path_from * @param string $path_from
@ -662,7 +644,7 @@ class Net_SFTP_Stream
/** /**
* Flushes the output * Flushes the output
* *
* See <http://php.net/fflush>. Always returns true because Net_SFTP doesn't cache stuff before writing * See <http://php.net/fflush>. Always returns true because \phpseclib\Net\SFTP doesn't cache stuff before writing
* *
* @return bool * @return bool
* @access public * @access public
@ -707,7 +689,7 @@ class Net_SFTP_Stream
/** /**
* Retrieve information about a file * Retrieve information about a file
* *
* Ignores the STREAM_URL_STAT_QUIET flag because the entirety of Net_SFTP_Stream is quiet by default * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib\Net\SFTP\Stream is quiet by default
* might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll
* cross that bridge when and if it's reached * cross that bridge when and if it's reached
* *
@ -754,7 +736,7 @@ class Net_SFTP_Stream
* Change stream options * Change stream options
* *
* STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't. * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't.
* The other two aren't supported because of limitations in Net_SFTP. * The other two aren't supported because of limitations in \phpseclib\Net\SFTP.
* *
* @param int $option * @param int $option
* @param int $arg1 * @param int $arg1
@ -811,5 +793,3 @@ class Net_SFTP_Stream
return call_user_func_array(array($this, $name), $arguments); return call_user_func_array(array($this, $name), $arguments);
} }
} }
Net_SFTP_Stream::register();

View File

@ -3,14 +3,14 @@
/** /**
* Pure-PHP implementation of SSHv1. * Pure-PHP implementation of SSHv1.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* Here's a short example of how to use this library: * Here's a short example of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'Net/SSH1.php'; * include 'vendor/autoload.php';
* *
* $ssh = new Net_SSH1('www.domain.tld'); * $ssh = new \phpseclib\Net\SSH1('www.domain.tld');
* if (!$ssh->login('username', 'password')) { * if (!$ssh->login('username', 'password')) {
* exit('Login Failed'); * exit('Login Failed');
* } * }
@ -22,9 +22,9 @@
* Here's another short example: * Here's another short example:
* <code> * <code>
* <?php * <?php
* include 'Net/SSH1.php'; * include 'vendor/autoload.php';
* *
* $ssh = new Net_SSH1('www.domain.tld'); * $ssh = new \phpseclib\Net\SSH1('www.domain.tld');
* if (!$ssh->login('username', 'password')) { * if (!$ssh->login('username', 'password')) {
* exit('Login Failed'); * exit('Login Failed');
* } * }
@ -38,68 +38,66 @@
* More information on the SSHv1 specification can be found by reading * More information on the SSHv1 specification can be found by reading
* {@link http://www.snailbook.com/docs/protocol-1.5.txt protocol-1.5.txt}. * {@link http://www.snailbook.com/docs/protocol-1.5.txt protocol-1.5.txt}.
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net * @category Net
* @package Net_SSH1 * @package SSH1
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton * @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net * @link http://phpseclib.sourceforge.net
*/ */
/**#@+ namespace phpseclib\Net;
* Encryption Methods
use phpseclib\Crypt\DES;
use phpseclib\Crypt\Random;
use phpseclib\Crypt\TripleDES;
use phpseclib\Math\BigInteger;
/**
* Pure-PHP implementation of SSHv1.
* *
* @see self::getSupportedCiphers() * @package SSH1
* @author Jim Wigginton <terrafrost@php.net>
* @access public * @access public
*/ */
/** class SSH1
{
/**#@+
* Encryption Methods
*
* @see \phpseclib\Net\SSH1::getSupportedCiphers()
* @access public
*/
/**
* No encryption * No encryption
* *
* Not supported. * Not supported.
*/ */
define('NET_SSH1_CIPHER_NONE', 0); const CIPHER_NONE = 0;
/** /**
* IDEA in CFB mode * IDEA in CFB mode
* *
* Not supported. * Not supported.
*/ */
define('NET_SSH1_CIPHER_IDEA', 1); const CIPHER_IDEA = 1;
/** /**
* DES in CBC mode * DES in CBC mode
*/ */
define('NET_SSH1_CIPHER_DES', 2); const CIPHER_DES = 2;
/** /**
* Triple-DES in CBC mode * Triple-DES in CBC mode
* *
* All implementations are required to support this * All implementations are required to support this
*/ */
define('NET_SSH1_CIPHER_3DES', 3); const CIPHER_3DES = 3;
/** /**
* TRI's Simple Stream encryption CBC * TRI's Simple Stream encryption CBC
* *
* Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, does define it (see cipher.h), * Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, does define it (see cipher.h),
* although it doesn't use it (see cipher.c) * although it doesn't use it (see cipher.c)
*/ */
define('NET_SSH1_CIPHER_BROKEN_TSS', 4); const CIPHER_BROKEN_TSS = 4;
/** /**
* RC4 * RC4
* *
* Not supported. * Not supported.
@ -114,124 +112,115 @@ define('NET_SSH1_CIPHER_BROKEN_TSS', 4);
* This library currently only supports encryption when the same key is being used for both directions. This is * This library currently only supports encryption when the same key is being used for both directions. This is
* because there's only one $crypto object. Two could be added ($encrypt and $decrypt, perhaps). * because there's only one $crypto object. Two could be added ($encrypt and $decrypt, perhaps).
*/ */
define('NET_SSH1_CIPHER_RC4', 5); const CIPHER_RC4 = 5;
/** /**
* Blowfish * Blowfish
* *
* Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, defines it (see cipher.h) and * Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, defines it (see cipher.h) and
* uses it (see cipher.c) * uses it (see cipher.c)
*/ */
define('NET_SSH1_CIPHER_BLOWFISH', 6); const CIPHER_BLOWFISH = 6;
/**#@-*/ /**#@-*/
/**#@+ /**#@+
* Authentication Methods * Authentication Methods
* *
* @see self::getSupportedAuthentications() * @see \phpseclib\Net\SSH1::getSupportedAuthentications()
* @access public * @access public
*/ */
/** /**
* .rhosts or /etc/hosts.equiv * .rhosts or /etc/hosts.equiv
*/ */
define('NET_SSH1_AUTH_RHOSTS', 1); const AUTH_RHOSTS = 1;
/** /**
* pure RSA authentication * pure RSA authentication
*/ */
define('NET_SSH1_AUTH_RSA', 2); const AUTH_RSA = 2;
/** /**
* password authentication * password authentication
* *
* This is the only method that is supported by this library. * This is the only method that is supported by this library.
*/ */
define('NET_SSH1_AUTH_PASSWORD', 3); const AUTH_PASSWORD = 3;
/** /**
* .rhosts with RSA host authentication * .rhosts with RSA host authentication
*/ */
define('NET_SSH1_AUTH_RHOSTS_RSA', 4); const AUTH_RHOSTS_RSA = 4;
/**#@-*/ /**#@-*/
/**#@+ /**#@+
* Terminal Modes * Terminal Modes
* *
* @link http://3sp.com/content/developer/maverick-net/docs/Maverick.SSH.PseudoTerminalModesMembers.html * @link http://3sp.com/content/developer/maverick-net/docs/Maverick.SSH.PseudoTerminalModesMembers.html
* @access private * @access private
*/ */
define('NET_SSH1_TTY_OP_END', 0); const TTY_OP_END = 0;
/**#@-*/ /**#@-*/
/** /**
* The Response Type * The Response Type
* *
* @see self::_get_binary_packet() * @see \phpseclib\Net\SSH1::_get_binary_packet()
* @access private * @access private
*/ */
define('NET_SSH1_RESPONSE_TYPE', 1); const RESPONSE_TYPE = 1;
/** /**
* The Response Data * The Response Data
* *
* @see self::_get_binary_packet() * @see \phpseclib\Net\SSH1::_get_binary_packet()
* @access private * @access private
*/ */
define('NET_SSH1_RESPONSE_DATA', 2); const RESPONSE_DATA = 2;
/**#@+ /**#@+
* Execution Bitmap Masks * Execution Bitmap Masks
* *
* @see self::bitmap * @see \phpseclib\Net\SSH1::bitmap
* @access private * @access private
*/ */
define('NET_SSH1_MASK_CONSTRUCTOR', 0x00000001); const MASK_CONSTRUCTOR = 0x00000001;
define('NET_SSH1_MASK_CONNECTED', 0x00000002); const MASK_CONNECTED = 0x00000002;
define('NET_SSH1_MASK_LOGIN', 0x00000004); const MASK_LOGIN = 0x00000004;
define('NET_SSH1_MASK_SHELL', 0x00000008); const MASK_SHELL = 0x00000008;
/**#@-*/ /**#@-*/
/**#@+ /**#@+
* @access public * @access public
* @see self::getLog() * @see \phpseclib\Net\SSH1::getLog()
*/ */
/** /**
* Returns the message numbers * Returns the message numbers
*/ */
define('NET_SSH1_LOG_SIMPLE', 1); const LOG_SIMPLE = 1;
/** /**
* Returns the message content * Returns the message content
*/ */
define('NET_SSH1_LOG_COMPLEX', 2); const LOG_COMPLEX = 2;
/** /**
* Outputs the content real-time * Outputs the content real-time
*/ */
define('NET_SSH1_LOG_REALTIME', 3); const LOG_REALTIME = 3;
/** /**
* Dumps the content real-time to a file * Dumps the content real-time to a file
*/ */
define('NET_SSH1_LOG_REALTIME_FILE', 4); const LOG_REALTIME_FILE = 4;
/**#@-*/ /**#@-*/
/**#@+ /**#@+
* @access public * @access public
* @see self::read() * @see \phpseclib\Net\SSH1::read()
*/ */
/** /**
* Returns when a string matching $expect exactly is found * Returns when a string matching $expect exactly is found
*/ */
define('NET_SSH1_READ_SIMPLE', 1); const READ_SIMPLE = 1;
/** /**
* Returns when a string matching the regular expression $expect is found * Returns when a string matching the regular expression $expect is found
*/ */
define('NET_SSH1_READ_REGEX', 2); const READ_REGEX = 2;
/**#@-*/ /**#@-*/
/**
* Pure-PHP implementation of SSHv1.
*
* @package Net_SSH1
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Net_SSH1
{
/** /**
* The SSH identifier * The SSH identifier
* *
@ -321,13 +310,13 @@ class Net_SSH1
* @access private * @access private
*/ */
var $supported_ciphers = array( var $supported_ciphers = array(
NET_SSH1_CIPHER_NONE => 'No encryption', self::CIPHER_NONE => 'No encryption',
NET_SSH1_CIPHER_IDEA => 'IDEA in CFB mode', self::CIPHER_IDEA => 'IDEA in CFB mode',
NET_SSH1_CIPHER_DES => 'DES in CBC mode', self::CIPHER_DES => 'DES in CBC mode',
NET_SSH1_CIPHER_3DES => 'Triple-DES in CBC mode', self::CIPHER_3DES => 'Triple-DES in CBC mode',
NET_SSH1_CIPHER_BROKEN_TSS => 'TRI\'s Simple Stream encryption CBC', self::CIPHER_BROKEN_TSS => 'TRI\'s Simple Stream encryption CBC',
NET_SSH1_CIPHER_RC4 => 'RC4', self::CIPHER_RC4 => 'RC4',
NET_SSH1_CIPHER_BLOWFISH => 'Blowfish' self::CIPHER_BLOWFISH => 'Blowfish'
); );
/** /**
@ -340,10 +329,10 @@ class Net_SSH1
* @access private * @access private
*/ */
var $supported_authentications = array( var $supported_authentications = array(
NET_SSH1_AUTH_RHOSTS => '.rhosts or /etc/hosts.equiv', self::AUTH_RHOSTS => '.rhosts or /etc/hosts.equiv',
NET_SSH1_AUTH_RSA => 'pure RSA authentication', self::AUTH_RSA => 'pure RSA authentication',
NET_SSH1_AUTH_PASSWORD => 'password authentication', self::AUTH_PASSWORD => 'password authentication',
NET_SSH1_AUTH_RHOSTS_RSA => '.rhosts with RSA host authentication' self::AUTH_RHOSTS_RSA => '.rhosts with RSA host authentication'
); );
/** /**
@ -358,7 +347,7 @@ class Net_SSH1
/** /**
* Protocol Flags * Protocol Flags
* *
* @see self::Net_SSH1() * @see self::__construct()
* @var array * @var array
* @access private * @access private
*/ */
@ -461,7 +450,7 @@ class Net_SSH1
/** /**
* Hostname * Hostname
* *
* @see self::Net_SSH1() * @see self::__construct()
* @see self::_connect() * @see self::_connect()
* @var string * @var string
* @access private * @access private
@ -471,7 +460,7 @@ class Net_SSH1
/** /**
* Port Number * Port Number
* *
* @see self::Net_SSH1() * @see self::__construct()
* @see self::_connect() * @see self::_connect()
* @var int * @var int
* @access private * @access private
@ -486,7 +475,7 @@ class Net_SSH1
* however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be * however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be
* 10 seconds. It is used by fsockopen() in that function. * 10 seconds. It is used by fsockopen() in that function.
* *
* @see self::Net_SSH1() * @see self::__construct()
* @see self::_connect() * @see self::_connect()
* @var int * @var int
* @access private * @access private
@ -496,7 +485,7 @@ class Net_SSH1
/** /**
* Default cipher * Default cipher
* *
* @see self::Net_SSH1() * @see self::__construct()
* @see self::_connect() * @see self::_connect()
* @var int * @var int
* @access private * @access private
@ -512,24 +501,11 @@ class Net_SSH1
* @param int $port * @param int $port
* @param int $timeout * @param int $timeout
* @param int $cipher * @param int $cipher
* @return Net_SSH1 * @return \phpseclib\Net\SSH1
* @access public * @access public
*/ */
function Net_SSH1($host, $port = 22, $timeout = 10, $cipher = NET_SSH1_CIPHER_3DES) function __construct($host, $port = 22, $timeout = 10, $cipher = self::CIPHER_3DES)
{ {
if (!class_exists('Math_BigInteger')) {
include_once 'Math/BigInteger.php';
}
// Include Crypt_Random
// the class_exists() will only be called if the crypt_random_string function hasn't been defined and
// will trigger a call to __autoload() if you're wanting to auto-load classes
// call function_exists() a second time to stop the include_once from being called outside
// of the auto loader
if (!function_exists('crypt_random_string') && !class_exists('Crypt_Random') && !function_exists('crypt_random_string')) {
include_once 'Crypt/Random.php';
}
$this->protocol_flags = array( $this->protocol_flags = array(
1 => 'NET_SSH1_MSG_DISCONNECT', 1 => 'NET_SSH1_MSG_DISCONNECT',
2 => 'NET_SSH1_SMSG_PUBLIC_KEY', 2 => 'NET_SSH1_SMSG_PUBLIC_KEY',
@ -590,37 +566,55 @@ class Net_SSH1
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[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) { if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
user_error('Expected SSH_SMSG_PUBLIC_KEY'); user_error('Expected SSH_SMSG_PUBLIC_KEY');
return false; return false;
} }
$anti_spoofing_cookie = $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 8); $anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8);
$this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4); $this->_string_shift($response[self::RESPONSE_DATA], 4);
$temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2)); if (strlen($response[self::RESPONSE_DATA]) < 2) {
$server_key_public_exponent = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256); return false;
}
$temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
$server_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
$this->server_key_public_exponent = $server_key_public_exponent; $this->server_key_public_exponent = $server_key_public_exponent;
$temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2)); if (strlen($response[self::RESPONSE_DATA]) < 2) {
$server_key_public_modulus = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256); return false;
}
$temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
$server_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
$this->server_key_public_modulus = $server_key_public_modulus; $this->server_key_public_modulus = $server_key_public_modulus;
$this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4); $this->_string_shift($response[self::RESPONSE_DATA], 4);
$temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2)); if (strlen($response[self::RESPONSE_DATA]) < 2) {
$host_key_public_exponent = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256); return false;
}
$temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
$host_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
$this->host_key_public_exponent = $host_key_public_exponent; $this->host_key_public_exponent = $host_key_public_exponent;
$temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2)); if (strlen($response[self::RESPONSE_DATA]) < 2) {
$host_key_public_modulus = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256); return false;
}
$temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
$host_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
$this->host_key_public_modulus = $host_key_public_modulus; $this->host_key_public_modulus = $host_key_public_modulus;
$this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4); $this->_string_shift($response[self::RESPONSE_DATA], 4);
// get a list of the supported ciphers // get a list of the supported ciphers
extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4))); if (strlen($response[self::RESPONSE_DATA]) < 4) {
return false;
}
extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
foreach ($this->supported_ciphers as $mask => $name) { foreach ($this->supported_ciphers as $mask => $name) {
if (($supported_ciphers_mask & (1 << $mask)) == 0) { if (($supported_ciphers_mask & (1 << $mask)) == 0) {
unset($this->supported_ciphers[$mask]); unset($this->supported_ciphers[$mask]);
@ -628,7 +622,10 @@ class Net_SSH1
} }
// get a list of the supported authentications // get a list of the supported authentications
extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4))); if (strlen($response[self::RESPONSE_DATA]) < 4) {
return false;
}
extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
foreach ($this->supported_authentications as $mask => $name) { foreach ($this->supported_authentications as $mask => $name) {
if (($supported_authentications_mask & (1 << $mask)) == 0) { if (($supported_authentications_mask & (1 << $mask)) == 0) {
unset($this->supported_authentications[$mask]); unset($this->supported_authentications[$mask]);
@ -637,7 +634,7 @@ class Net_SSH1
$session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie)); $session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie));
$session_key = crypt_random_string(32); $session_key = Random::string(32);
$double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0)); $double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0));
if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) { if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) {
@ -672,7 +669,7 @@ class Net_SSH1
); );
} }
$cipher = isset($this->supported_ciphers[$this->cipher]) ? $this->cipher : NET_SSH1_CIPHER_3DES; $cipher = isset($this->supported_ciphers[$this->cipher]) ? $this->cipher : self::CIPHER_3DES;
$data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0); $data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0);
if (!$this->_send_binary_packet($data)) { if (!$this->_send_binary_packet($data)) {
@ -681,32 +678,23 @@ class Net_SSH1
} }
switch ($cipher) { switch ($cipher) {
//case NET_SSH1_CIPHER_NONE: //case self::CIPHER_NONE:
// $this->crypto = new Crypt_Null(); // $this->crypto = new \phpseclib\Crypt\Null();
// break; // break;
case NET_SSH1_CIPHER_DES: case self::CIPHER_DES:
if (!class_exists('Crypt_DES')) { $this->crypto = new DES();
include_once 'Crypt/DES.php';
}
$this->crypto = new Crypt_DES();
$this->crypto->disablePadding(); $this->crypto->disablePadding();
$this->crypto->enableContinuousBuffer(); $this->crypto->enableContinuousBuffer();
$this->crypto->setKey(substr($session_key, 0, 8)); $this->crypto->setKey(substr($session_key, 0, 8));
break; break;
case NET_SSH1_CIPHER_3DES: case self::CIPHER_3DES:
if (!class_exists('Crypt_TripleDES')) { $this->crypto = new TripleDES(TripleDES::MODE_3CBC);
include_once 'Crypt/TripleDES.php';
}
$this->crypto = new Crypt_TripleDES(CRYPT_DES_MODE_3CBC);
$this->crypto->disablePadding(); $this->crypto->disablePadding();
$this->crypto->enableContinuousBuffer(); $this->crypto->enableContinuousBuffer();
$this->crypto->setKey(substr($session_key, 0, 24)); $this->crypto->setKey(substr($session_key, 0, 24));
break; break;
//case NET_SSH1_CIPHER_RC4: //case self::CIPHER_RC4:
// if (!class_exists('Crypt_RC4')) { // $this->crypto = new RC4();
// include_once 'Crypt/RC4.php';
// }
// $this->crypto = new Crypt_RC4();
// $this->crypto->enableContinuousBuffer(); // $this->crypto->enableContinuousBuffer();
// $this->crypto->setKey(substr($session_key, 0, 16)); // $this->crypto->setKey(substr($session_key, 0, 16));
// break; // break;
@ -714,12 +702,12 @@ class Net_SSH1
$response = $this->_get_binary_packet(); $response = $this->_get_binary_packet();
if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) { if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
user_error('Expected SSH_SMSG_SUCCESS'); user_error('Expected SSH_SMSG_SUCCESS');
return false; return false;
} }
$this->bitmap = NET_SSH1_MASK_CONNECTED; $this->bitmap = self::MASK_CONNECTED;
return true; return true;
} }
@ -734,14 +722,14 @@ class Net_SSH1
*/ */
function login($username, $password = '') function login($username, $password = '')
{ {
if (!($this->bitmap & NET_SSH1_MASK_CONSTRUCTOR)) { if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
$this->bitmap |= NET_SSH1_MASK_CONSTRUCTOR; $this->bitmap |= self::MASK_CONSTRUCTOR;
if (!$this->_connect()) { if (!$this->_connect()) {
return false; return false;
} }
} }
if (!($this->bitmap & NET_SSH1_MASK_CONNECTED)) { if (!($this->bitmap & self::MASK_CONNECTED)) {
return false; return false;
} }
@ -757,10 +745,10 @@ class Net_SSH1
if ($response === true) { if ($response === true) {
return false; return false;
} }
if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) { if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
$this->bitmap |= NET_SSH1_MASK_LOGIN; $this->bitmap |= self::MASK_LOGIN;
return true; return true;
} elseif ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) { } elseif ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE'); user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
return false; return false;
} }
@ -773,7 +761,7 @@ class Net_SSH1
} }
// remove the username and password from the last logged packet // remove the username and password from the last logged packet
if (defined('NET_SSH1_LOGGING') && NET_SSH1_LOGGING == NET_SSH1_LOG_COMPLEX) { if (defined('NET_SSH1_LOGGING') && NET_SSH1_LOGGING == self::LOG_COMPLEX) {
$data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen('password'), 'password'); $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen('password'), 'password');
$this->message_log[count($this->message_log) - 1] = $data; $this->message_log[count($this->message_log) - 1] = $data;
} }
@ -783,10 +771,10 @@ class Net_SSH1
if ($response === true) { if ($response === true) {
return false; return false;
} }
if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) { if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
$this->bitmap |= NET_SSH1_MASK_LOGIN; $this->bitmap |= self::MASK_LOGIN;
return true; return true;
} elseif ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) { } elseif ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
return false; return false;
} else { } else {
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE'); user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
@ -817,7 +805,7 @@ class Net_SSH1
* {@link http://www.faqs.org/docs/bashman/bashref_65.html http://www.faqs.org/docs/bashman/bashref_65.html} * {@link http://www.faqs.org/docs/bashman/bashref_65.html http://www.faqs.org/docs/bashman/bashref_65.html}
* {@link http://www.faqs.org/docs/bashman/bashref_62.html http://www.faqs.org/docs/bashman/bashref_62.html} * {@link http://www.faqs.org/docs/bashman/bashref_62.html http://www.faqs.org/docs/bashman/bashref_62.html}
* *
* To execute further commands, a new Net_SSH1 object will need to be created. * To execute further commands, a new \phpseclib\Net\SSH1 object will need to be created.
* *
* Returns false on failure and the output, otherwise. * Returns false on failure and the output, otherwise.
* *
@ -829,7 +817,7 @@ class Net_SSH1
*/ */
function exec($cmd, $block = true) function exec($cmd, $block = true)
{ {
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) { if (!($this->bitmap & self::MASK_LOGIN)) {
user_error('Operation disallowed prior to login()'); user_error('Operation disallowed prior to login()');
return false; return false;
} }
@ -850,9 +838,9 @@ class Net_SSH1
if ($response !== false) { if ($response !== false) {
do { do {
$output.= substr($response[NET_SSH1_RESPONSE_DATA], 4); $output.= substr($response[self::RESPONSE_DATA], 4);
$response = $this->_get_binary_packet(); $response = $this->_get_binary_packet();
} while (is_array($response) && $response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_EXITSTATUS); } while (is_array($response) && $response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_EXITSTATUS);
} }
$data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION); $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION);
@ -862,7 +850,7 @@ class Net_SSH1
fclose($this->fsock); fclose($this->fsock);
// reset the execution bitmap - a new Net_SSH1 object needs to be created. // reset the execution bitmap - a new \phpseclib\Net\SSH1 object needs to be created.
$this->bitmap = 0; $this->bitmap = 0;
return $output; return $output;
@ -881,7 +869,7 @@ class Net_SSH1
// connect using the sample parameters in protocol-1.5.txt. // connect using the sample parameters in protocol-1.5.txt.
// according to wikipedia.org's entry on text terminals, "the fundamental type of application running on a text // according to wikipedia.org's entry on text terminals, "the fundamental type of application running on a text
// terminal is a command line interpreter or shell". thus, opening a terminal session to run the shell. // terminal is a command line interpreter or shell". thus, opening a terminal session to run the shell.
$data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, NET_SSH1_TTY_OP_END); $data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, self::TTY_OP_END);
if (!$this->_send_binary_packet($data)) { if (!$this->_send_binary_packet($data)) {
user_error('Error sending SSH_CMSG_REQUEST_PTY'); user_error('Error sending SSH_CMSG_REQUEST_PTY');
@ -893,7 +881,7 @@ class Net_SSH1
if ($response === true) { if ($response === true) {
return false; return false;
} }
if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) { if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
user_error('Expected SSH_SMSG_SUCCESS'); user_error('Expected SSH_SMSG_SUCCESS');
return false; return false;
} }
@ -905,7 +893,7 @@ class Net_SSH1
return false; return false;
} }
$this->bitmap |= NET_SSH1_MASK_SHELL; $this->bitmap |= self::MASK_SHELL;
//stream_set_blocking($this->fsock, 0); //stream_set_blocking($this->fsock, 0);
@ -928,7 +916,7 @@ class Net_SSH1
/** /**
* Returns the output of an interactive shell when there's a match for $expect * Returns the output of an interactive shell when there's a match for $expect
* *
* $expect can take the form of a string literal or, if $mode == NET_SSH1_READ_REGEX, * $expect can take the form of a string literal or, if $mode == self::READ__REGEX,
* a regular expression. * a regular expression.
* *
* @see self::write() * @see self::write()
@ -937,21 +925,21 @@ class Net_SSH1
* @return bool * @return bool
* @access public * @access public
*/ */
function read($expect, $mode = NET_SSH1_READ_SIMPLE) function read($expect, $mode = self::READ__SIMPLE)
{ {
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) { if (!($this->bitmap & self::MASK_LOGIN)) {
user_error('Operation disallowed prior to login()'); user_error('Operation disallowed prior to login()');
return false; return false;
} }
if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) { if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
user_error('Unable to initiate an interactive shell session'); user_error('Unable to initiate an interactive shell session');
return false; return false;
} }
$match = $expect; $match = $expect;
while (true) { while (true) {
if ($mode == NET_SSH1_READ_REGEX) { if ($mode == self::READ__REGEX) {
preg_match($expect, $this->interactiveBuffer, $matches); preg_match($expect, $this->interactiveBuffer, $matches);
$match = isset($matches[0]) ? $matches[0] : ''; $match = isset($matches[0]) ? $matches[0] : '';
} }
@ -964,7 +952,7 @@ class Net_SSH1
if ($response === true) { if ($response === true) {
return $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer)); return $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer));
} }
$this->interactiveBuffer.= substr($response[NET_SSH1_RESPONSE_DATA], 4); $this->interactiveBuffer.= substr($response[self::RESPONSE_DATA], 4);
} }
} }
@ -978,12 +966,12 @@ class Net_SSH1
*/ */
function interactiveWrite($cmd) function interactiveWrite($cmd)
{ {
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) { if (!($this->bitmap & self::MASK_LOGIN)) {
user_error('Operation disallowed prior to login()'); user_error('Operation disallowed prior to login()');
return false; return false;
} }
if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) { if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
user_error('Unable to initiate an interactive shell session'); user_error('Unable to initiate an interactive shell session');
return false; return false;
} }
@ -1013,12 +1001,12 @@ class Net_SSH1
*/ */
function interactiveRead() function interactiveRead()
{ {
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) { if (!($this->bitmap & self::MASK_LOGIN)) {
user_error('Operation disallowed prior to login()'); user_error('Operation disallowed prior to login()');
return false; return false;
} }
if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) { if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
user_error('Unable to initiate an interactive shell session'); user_error('Unable to initiate an interactive shell session');
return false; return false;
} }
@ -1027,7 +1015,7 @@ class Net_SSH1
$write = $except = null; $write = $except = null;
if (stream_select($read, $write, $except, 0)) { if (stream_select($read, $write, $except, 0)) {
$response = $this->_get_binary_packet(); $response = $this->_get_binary_packet();
return substr($response[NET_SSH1_RESPONSE_DATA], 4); return substr($response[self::RESPONSE_DATA], 4);
} else { } else {
return ''; return '';
} }
@ -1070,9 +1058,9 @@ class Net_SSH1
/* /*
$response = $this->_get_binary_packet(); $response = $this->_get_binary_packet();
if ($response === true) { if ($response === true) {
$response = array(NET_SSH1_RESPONSE_TYPE => -1); $response = array(self::RESPONSE_TYPE => -1);
} }
switch ($response[NET_SSH1_RESPONSE_TYPE]) { switch ($response[self::RESPONSE_TYPE]) {
case NET_SSH1_SMSG_EXITSTATUS: case NET_SSH1_SMSG_EXITSTATUS:
$data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION); $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION);
break; break;
@ -1124,7 +1112,11 @@ class Net_SSH1
} }
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
$temp = unpack('Nlength', fread($this->fsock, 4)); $data = fread($this->fsock, 4);
if (strlen($data) < 4) {
return false;
}
$temp = unpack('Nlength', $data);
$padding_length = 8 - ($temp['length'] & 7); $padding_length = 8 - ($temp['length'] & 7);
$length = $temp['length'] + $padding_length; $length = $temp['length'] + $padding_length;
@ -1145,6 +1137,9 @@ class Net_SSH1
$type = $raw[$padding_length]; $type = $raw[$padding_length];
$data = substr($raw, $padding_length + 1, -4); $data = substr($raw, $padding_length + 1, -4);
if (strlen($raw) < 4) {
return false;
}
$temp = unpack('Ncrc', substr($raw, -4)); $temp = unpack('Ncrc', substr($raw, -4));
//if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) { //if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) {
@ -1162,8 +1157,8 @@ class Net_SSH1
} }
return array( return array(
NET_SSH1_RESPONSE_TYPE => $type, self::RESPONSE_TYPE => $type,
NET_SSH1_RESPONSE_DATA => $data self::RESPONSE_DATA => $data
); );
} }
@ -1186,7 +1181,7 @@ class Net_SSH1
$length = strlen($data) + 4; $length = strlen($data) + 4;
$padding = crypt_random_string(8 - ($length & 7)); $padding = Random::string(8 - ($length & 7));
$orig = $data; $orig = $data;
$data = $padding . $data; $data = $padding . $data;
@ -1336,22 +1331,18 @@ class Net_SSH1
* should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1. Could just make anything that * should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1. Could just make anything that
* calls this call modexp, instead, but I think this makes things clearer, maybe... * calls this call modexp, instead, but I think this makes things clearer, maybe...
* *
* @see self::Net_SSH1() * @see self::__construct()
* @param Math_BigInteger $m * @param BigInteger $m
* @param array $key * @param array $key
* @return Math_BigInteger * @return BigInteger
* @access private * @access private
*/ */
function _rsa_crypt($m, $key) function _rsa_crypt($m, $key)
{ {
/* /*
if (!class_exists('Crypt_RSA')) { $rsa = new RSA();
include_once 'Crypt/RSA.php'; $rsa->loadKey($key, RSA::PUBLIC_FORMAT_RAW);
} $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
$rsa = new Crypt_RSA();
$rsa->loadKey($key, CRYPT_RSA_PUBLIC_FORMAT_RAW);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
return $rsa->encrypt($m); return $rsa->encrypt($m);
*/ */
@ -1372,13 +1363,13 @@ class Net_SSH1
$length = strlen($modulus) - strlen($m) - 3; $length = strlen($modulus) - strlen($m) - 3;
$random = ''; $random = '';
while (strlen($random) != $length) { while (strlen($random) != $length) {
$block = crypt_random_string($length - strlen($random)); $block = Random::string($length - strlen($random));
$block = str_replace("\x00", '', $block); $block = str_replace("\x00", '', $block);
$random.= $block; $random.= $block;
} }
$temp = chr(0) . chr(2) . $random . chr(0) . $m; $temp = chr(0) . chr(2) . $random . chr(0) . $m;
$m = new Math_BigInteger($temp, 256); $m = new BigInteger($temp, 256);
$m = $m->modPow($key[0], $key[1]); $m = $m->modPow($key[0], $key[1]);
return $m->toBytes(); return $m->toBytes();
@ -1411,7 +1402,7 @@ class Net_SSH1
/** /**
* Returns a log of the packets that have been sent and received. * Returns a log of the packets that have been sent and received.
* *
* Returns a string if NET_SSH1_LOGGING == NET_SSH1_LOG_COMPLEX, an array if NET_SSH1_LOGGING == NET_SSH1_LOG_SIMPLE and false if !defined('NET_SSH1_LOGGING') * Returns a string if NET_SSH1_LOGGING == self::LOG_COMPLEX, an array if NET_SSH1_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH1_LOGGING')
* *
* @access public * @access public
* @return array|false|string * @return array|false|string
@ -1423,10 +1414,10 @@ class Net_SSH1
} }
switch (NET_SSH1_LOGGING) { switch (NET_SSH1_LOGGING) {
case NET_SSH1_LOG_SIMPLE: case self::LOG_SIMPLE:
return $this->message_number_log; return $this->message_number_log;
break; break;
case NET_SSH1_LOG_COMPLEX: case self::LOG_COMPLEX:
return $this->_format_log($this->message_log, $this->protocol_flags_log); return $this->_format_log($this->message_log, $this->protocol_flags_log);
break; break;
default: default:
@ -1547,7 +1538,7 @@ class Net_SSH1
* *
* Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output
* is set to true, returns, instead, an array of constants. ie. instead of array('Triple-DES in CBC mode'), you'll * is set to true, returns, instead, an array of constants. ie. instead of array('Triple-DES in CBC mode'), you'll
* get array(NET_SSH1_CIPHER_3DES). * get array(self::CIPHER_3DES).
* *
* @param bool $raw_output * @param bool $raw_output
* @return array * @return array
@ -1563,7 +1554,7 @@ class Net_SSH1
* *
* Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output
* is set to true, returns, instead, an array of constants. ie. instead of array('password authentication'), you'll * is set to true, returns, instead, an array of constants. ie. instead of array('password authentication'), you'll
* get array(NET_SSH1_AUTH_PASSWORD). * get array(self::AUTH_PASSWORD).
* *
* @param bool $raw_output * @param bool $raw_output
* @return array * @return array
@ -1597,16 +1588,16 @@ class Net_SSH1
{ {
switch (NET_SSH1_LOGGING) { switch (NET_SSH1_LOGGING) {
// useful for benchmarks // useful for benchmarks
case NET_SSH1_LOG_SIMPLE: case self::LOG_SIMPLE:
$this->protocol_flags_log[] = $protocol_flags; $this->protocol_flags_log[] = $protocol_flags;
break; break;
// the most useful log for SSH1 // the most useful log for SSH1
case NET_SSH1_LOG_COMPLEX: case self::LOG_COMPLEX:
$this->protocol_flags_log[] = $protocol_flags; $this->protocol_flags_log[] = $protocol_flags;
$this->_string_shift($message); $this->_string_shift($message);
$this->log_size+= strlen($message); $this->log_size+= strlen($message);
$this->message_log[] = $message; $this->message_log[] = $message;
while ($this->log_size > NET_SSH1_LOG_MAX_SIZE) { while ($this->log_size > self::LOG_MAX_SIZE) {
$this->log_size-= strlen(array_shift($this->message_log)); $this->log_size-= strlen(array_shift($this->message_log));
array_shift($this->protocol_flags_log); array_shift($this->protocol_flags_log);
} }
@ -1614,19 +1605,19 @@ class Net_SSH1
// dump the output out realtime; packets may be interspersed with non packets, // dump the output out realtime; packets may be interspersed with non packets,
// passwords won't be filtered out and select other packets may not be correctly // passwords won't be filtered out and select other packets may not be correctly
// identified // identified
case NET_SSH1_LOG_REALTIME: case self::LOG_REALTIME:
echo "<pre>\r\n" . $this->_format_log(array($message), array($protocol_flags)) . "\r\n</pre>\r\n"; echo "<pre>\r\n" . $this->_format_log(array($message), array($protocol_flags)) . "\r\n</pre>\r\n";
@flush(); @flush();
@ob_flush(); @ob_flush();
break; break;
// basically the same thing as NET_SSH1_LOG_REALTIME with the caveat that NET_SSH1_LOG_REALTIME_FILE // basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE
// needs to be defined and that the resultant log file will be capped out at NET_SSH1_LOG_MAX_SIZE. // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE.
// the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily
// at the beginning of the file // at the beginning of the file
case NET_SSH1_LOG_REALTIME_FILE: case self::LOG_REALTIME_FILE:
if (!isset($this->realtime_log_file)) { if (!isset($this->realtime_log_file)) {
// PHP doesn't seem to like using constants in fopen() // PHP doesn't seem to like using constants in fopen()
$filename = NET_SSH1_LOG_REALTIME_FILE; $filename = self::LOG_REALTIME_FILE;
$fp = fopen($filename, 'w'); $fp = fopen($filename, 'w');
$this->realtime_log_file = $fp; $this->realtime_log_file = $fp;
} }
@ -1640,7 +1631,7 @@ class Net_SSH1
fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp)); fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp));
} }
$this->realtime_log_size+= strlen($entry); $this->realtime_log_size+= strlen($entry);
if ($this->realtime_log_size > NET_SSH1_LOG_MAX_SIZE) { if ($this->realtime_log_size > self::LOG_MAX_SIZE) {
fseek($this->realtime_log_file, 0); fseek($this->realtime_log_file, 0);
$this->realtime_log_size = strlen($entry); $this->realtime_log_size = strlen($entry);
$this->realtime_log_wrap = true; $this->realtime_log_wrap = true;

File diff suppressed because it is too large Load Diff

View File

@ -3,17 +3,16 @@
/** /**
* Pure-PHP ssh-agent client. * Pure-PHP ssh-agent client.
* *
* PHP versions 4 and 5 * PHP version 5
* *
* Here are some examples of how to use this library: * Here are some examples of how to use this library:
* <code> * <code>
* <?php * <?php
* include 'System/SSH/Agent.php'; * include 'vendor/autoload.php';
* include 'Net/SSH2.php';
* *
* $agent = new System_SSH_Agent(); * $agent = new \phpseclib\System\SSH\Agent();
* *
* $ssh = new Net_SSH2('www.domain.tld'); * $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
* if (!$ssh->login('username', $agent)) { * if (!$ssh->login('username', $agent)) {
* exit('Login Failed'); * exit('Login Failed');
* } * }
@ -23,26 +22,8 @@
* ?> * ?>
* </code> * </code>
* *
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category System * @category System
* @package System_SSH_Agent * @package SSH\Agent
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton * @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License * @license http://www.opensource.org/licenses/mit-license.html MIT License
@ -50,188 +31,55 @@
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent * @internal See http://api.libssh.org/rfc/PROTOCOL.agent
*/ */
/**#@+ namespace phpseclib\System\SSH;
* Message numbers
*
* @access private
*/
// to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1)
define('SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES', 11);
// this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2).
define('SYSTEM_SSH_AGENT_IDENTITIES_ANSWER', 12);
define('SYSTEM_SSH_AGENT_FAILURE', 5);
// the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3)
define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13);
// the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
use phpseclib\Crypt\RSA;
/**@+ use phpseclib\System\SSH\Agent\Identity;
* Agent forwarding status
*
* @access private
*/
// no forwarding requested and not active
define('SYSTEM_SSH_AGENT_FORWARD_NONE', 0);
// request agent forwarding when opportune
define('SYSTEM_SSH_AGENT_FORWARD_REQUEST', 1);
// forwarding has been request and is active
define('SYSTEM_SSH_AGENT_FORWARD_ACTIVE', 2);
/**#@-*/
/**
* Pure-PHP ssh-agent client identity object
*
* Instantiation should only be performed by System_SSH_Agent class.
* This could be thought of as implementing an interface that Crypt_RSA
* implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
* The methods in this interface would be getPublicKey, setSignatureMode
* and sign since those are the methods phpseclib looks for to perform
* public key authentication.
*
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @access internal
*/
class System_SSH_Agent_Identity
{
/**
* Key Object
*
* @var Crypt_RSA
* @access private
* @see self::getPublicKey()
*/
var $key;
/**
* Key Blob
*
* @var string
* @access private
* @see self::sign()
*/
var $key_blob;
/**
* Socket Resource
*
* @var resource
* @access private
* @see self::sign()
*/
var $fsock;
/**
* Default Constructor.
*
* @param resource $fsock
* @return System_SSH_Agent_Identity
* @access private
*/
function System_SSH_Agent_Identity($fsock)
{
$this->fsock = $fsock;
}
/**
* Set Public Key
*
* Called by System_SSH_Agent::requestIdentities()
*
* @param Crypt_RSA $key
* @access private
*/
function setPublicKey($key)
{
$this->key = $key;
$this->key->setPublicKey();
}
/**
* Set Public Key
*
* Called by System_SSH_Agent::requestIdentities(). The key blob could be extracted from $this->key
* but this saves a small amount of computation.
*
* @param string $key_blob
* @access private
*/
function setPublicKeyBlob($key_blob)
{
$this->key_blob = $key_blob;
}
/**
* Get Public Key
*
* Wrapper for $this->key->getPublicKey()
*
* @param int $format optional
* @return mixed
* @access public
*/
function getPublicKey($format = null)
{
return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
}
/**
* Set Signature Mode
*
* Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
* ssh-agent's only supported mode is CRYPT_RSA_SIGNATURE_PKCS1
*
* @param int $mode
* @access public
*/
function setSignatureMode($mode)
{
}
/**
* Create a signature
*
* See "2.6.2 Protocol 2 private key signature request"
*
* @param string $message
* @return string
* @access public
*/
function sign($message)
{
// the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
$packet = pack('CNa*Na*N', SYSTEM_SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, 0);
$packet = pack('Na*', strlen($packet), $packet);
if (strlen($packet) != fputs($this->fsock, $packet)) {
user_error('Connection closed during signing');
}
$length = current(unpack('N', fread($this->fsock, 4)));
$type = ord(fread($this->fsock, 1));
if ($type != SYSTEM_SSH_AGENT_SIGN_RESPONSE) {
user_error('Unable to retreive signature');
}
$signature_blob = fread($this->fsock, $length - 1);
// the only other signature format defined - ssh-dss - is the same length as ssh-rsa
// the + 12 is for the other various SSH added length fields
return substr($signature_blob, strlen('ssh-rsa') + 12);
}
}
/** /**
* Pure-PHP ssh-agent client identity factory * Pure-PHP ssh-agent client identity factory
* *
* requestIdentities() method pumps out System_SSH_Agent_Identity objects * requestIdentities() method pumps out \phpseclib\System\SSH\Agent\Identity objects
* *
* @package System_SSH_Agent * @package SSH\Agent
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
* @access internal * @access internal
*/ */
class System_SSH_Agent class Agent
{ {
/**#@+
* Message numbers
*
* @access private
*/
// to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1)
const SSH_AGENTC_REQUEST_IDENTITIES = 11;
// this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2).
const SSH_AGENT_IDENTITIES_ANSWER = 12;
// the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3)
const SSH_AGENTC_SIGN_REQUEST = 13;
// the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
const SSH_AGENT_SIGN_RESPONSE = 14;
/**#@-*/
/**@+
* Agent forwarding status
*
* @access private
*/
// no forwarding requested and not active
const FORWARD_NONE = 0;
// request agent forwarding when opportune
const FORWARD_REQUEST = 1;
// forwarding has been request and is active
const FORWARD_ACTIVE = 2;
/**#@-*/
/**
* Unused
*/
const SSH_AGENT_FAILURE = 5;
/** /**
* Socket Resource * Socket Resource
* *
@ -245,7 +93,7 @@ class System_SSH_Agent
* *
* @access private * @access private
*/ */
var $forward_status = SYSTEM_SSH_AGENT_FORWARD_NONE; var $forward_status = self::FORWARD_NONE;
/** /**
* Buffer for accumulating forwarded authentication * Buffer for accumulating forwarded authentication
@ -266,10 +114,10 @@ class System_SSH_Agent
/** /**
* Default Constructor * Default Constructor
* *
* @return System_SSH_Agent * @return \phpseclib\System\SSH\Agent
* @access public * @access public
*/ */
function System_SSH_Agent() function __construct()
{ {
switch (true) { switch (true) {
case isset($_SERVER['SSH_AUTH_SOCK']): case isset($_SERVER['SSH_AUTH_SOCK']):
@ -293,7 +141,7 @@ class System_SSH_Agent
* Request Identities * Request Identities
* *
* See "2.5.2 Requesting a list of protocol 2 keys" * See "2.5.2 Requesting a list of protocol 2 keys"
* Returns an array containing zero or more System_SSH_Agent_Identity objects * Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects
* *
* @return array * @return array
* @access public * @access public
@ -304,14 +152,14 @@ class System_SSH_Agent
return array(); return array();
} }
$packet = pack('NC', 1, SYSTEM_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'); user_error('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 != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) { if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
user_error('Unable to request identities'); user_error('Unable to request identities');
} }
@ -329,10 +177,7 @@ class System_SSH_Agent
$key_type = substr($key_blob, 4, $length); $key_type = substr($key_blob, 4, $length);
switch ($key_type) { switch ($key_type) {
case 'ssh-rsa': case 'ssh-rsa':
if (!class_exists('Crypt_RSA')) { $key = new RSA();
include_once 'Crypt/RSA.php';
}
$key = new Crypt_RSA();
$key->loadKey($key_str); $key->loadKey($key_str);
break; break;
case 'ssh-dss': case 'ssh-dss':
@ -341,7 +186,7 @@ class System_SSH_Agent
} }
// resources are passed by reference by default // resources are passed by reference by default
if (isset($key)) { if (isset($key)) {
$identity = new System_SSH_Agent_Identity($this->fsock); $identity = new Identity($this->fsock);
$identity->setPublicKey($key); $identity->setPublicKey($key);
$identity->setPublicKeyBlob($key_blob); $identity->setPublicKeyBlob($key_blob);
$identities[] = $identity; $identities[] = $identity;
@ -362,8 +207,8 @@ class System_SSH_Agent
*/ */
function startSSHForwarding($ssh) function startSSHForwarding($ssh)
{ {
if ($this->forward_status == SYSTEM_SSH_AGENT_FORWARD_NONE) { if ($this->forward_status == self::FORWARD_NONE) {
$this->forward_status = SYSTEM_SSH_AGENT_FORWARD_REQUEST; $this->forward_status = self::FORWARD_REQUEST;
} }
} }
@ -402,7 +247,7 @@ class System_SSH_Agent
} }
$ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN; $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN;
$this->forward_status = SYSTEM_SSH_AGENT_FORWARD_ACTIVE; $this->forward_status = self::FORWARD_ACTIVE;
return true; return true;
} }
@ -419,7 +264,7 @@ class System_SSH_Agent
*/ */
function _on_channel_open($ssh) function _on_channel_open($ssh)
{ {
if ($this->forward_status == SYSTEM_SSH_AGENT_FORWARD_REQUEST) { if ($this->forward_status == self::FORWARD_REQUEST) {
$this->_request_forwarding($ssh); $this->_request_forwarding($ssh);
} }
} }

View File

@ -0,0 +1,158 @@
<?php
/**
* Pure-PHP ssh-agent client.
*
* PHP version 5
*
* @category System
* @package SSH\Agent
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2009 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
*/
namespace phpseclib\System\SSH\Agent;
use phpseclib\System\SSH\Agent;
/**
* Pure-PHP ssh-agent client identity object
*
* Instantiation should only be performed by \phpseclib\System\SSH\Agent class.
* This could be thought of as implementing an interface that phpseclib\Crypt\RSA
* implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
* The methods in this interface would be getPublicKey and sign since those are the
* methods phpseclib looks for to perform public key authentication.
*
* @package SSH\Agent
* @author Jim Wigginton <terrafrost@php.net>
* @access internal
*/
class Identity
{
/**
* Key Object
*
* @var \phpseclib\Crypt\RSA
* @access private
* @see self::getPublicKey()
*/
var $key;
/**
* Key Blob
*
* @var string
* @access private
* @see self::sign()
*/
var $key_blob;
/**
* Socket Resource
*
* @var resource
* @access private
* @see self::sign()
*/
var $fsock;
/**
* Default Constructor.
*
* @param resource $fsock
* @return \phpseclib\System\SSH\Agent\Identity
* @access private
*/
function __construct($fsock)
{
$this->fsock = $fsock;
}
/**
* Set Public Key
*
* Called by \phpseclib\System\SSH\Agent::requestIdentities()
*
* @param \phpseclib\Crypt\RSA $key
* @access private
*/
function setPublicKey($key)
{
$this->key = $key;
$this->key->setPublicKey();
}
/**
* Set Public Key
*
* Called by \phpseclib\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key
* but this saves a small amount of computation.
*
* @param string $key_blob
* @access private
*/
function setPublicKeyBlob($key_blob)
{
$this->key_blob = $key_blob;
}
/**
* Get Public Key
*
* Wrapper for $this->key->getPublicKey()
*
* @param int $format optional
* @return mixed
* @access public
*/
function getPublicKey($format = null)
{
return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
}
/**
* Set Signature Mode
*
* Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
* ssh-agent's only supported mode is \phpseclib\Crypt\RSA::SIGNATURE_PKCS1
*
* @param int $mode
* @access public
*/
function setSignatureMode($mode)
{
}
/**
* Create a signature
*
* See "2.6.2 Protocol 2 private key signature request"
*
* @param string $message
* @return string
* @access public
*/
function sign($message)
{
// the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
$packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, 0);
$packet = pack('Na*', strlen($packet), $packet);
if (strlen($packet) != fputs($this->fsock, $packet)) {
user_error('Connection closed during signing');
}
$length = current(unpack('N', fread($this->fsock, 4)));
$type = ord(fread($this->fsock, 1));
if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
user_error('Unable to retrieve signature');
}
$signature_blob = fread($this->fsock, $length - 1);
// the only other signature format defined - ssh-dss - is the same length as ssh-rsa
// the + 12 is for the other various SSH added length fields
return substr($signature_blob, strlen('ssh-rsa') + 12);
}
}

View File

@ -1,39 +0,0 @@
<?php
/**
* Pure-PHP ssh-agent client wrapper
*
* PHP versions 4 and 5
*
* Originally System_SSH_Agent was accessed as System/SSH_Agent.php instead of
* System/SSH/Agent.php. The problem with this is that PSR0 compatible autoloaders
* don't support that kind of directory layout hence the package being moved and
* this "alias" being created to maintain backwards compatibility.
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category System
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
*/
require_once 'SSH/Agent.php';

View File

@ -1,129 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2004 - 2016 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This file includes functions to control lamdaemon.
*
* @author Tilo Lutz
* @author Roland Gruber
* @author Thomas Manninger
*
* @package modules
*/
/**
* Sends commands to lamdaemon script.
*
* @param array $command command to execute
* @param string $server remote server
* @return array Output of lamdaemon
*
*/
function lamdaemon($command, $server) {
if ($server == '') {
return array();
}
// add phpseclib to include path
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/3rdParty/phpseclib');
include_once('Net/SSH2.php');
try {
$handle = lamConnectSSH($server);
}
catch (Exception $e) {
return array("ERROR," . $e->getMessage() . "," . $server);
}
$output = $handle->exec("sudo " . $_SESSION['config']->get_scriptPath() . ' ' . escapeshellarg($command));
return array($output);
}
/**
* Connects to the given SSH server.
*
* @param String $server server name (e.g. localhost or localhost,1234)
* @return object handle
*/
function lamConnectSSH($server) {
// add phpseclib to include path
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/3rdParty/phpseclib');
include_once('Net/SSH2.php');
include_once('Crypt/RSA.php');
$serverNameParts = explode(",", $server);
$handle = false;
if (sizeof($serverNameParts) > 1) {
$handle = @new Net_SSH2($serverNameParts[0], $serverNameParts[1]);
}
else {
$handle = @new Net_SSH2($server);
}
if (!$handle) {
throw new Exception(_("Unable to connect to remote server!"));
}
lamLoginSSH($handle);
return $handle;
}
/**
* Performs a login to the provided SSH handle.
*
* @param handle $handle SSH handle
* @throws Exception login failed
*/
function lamLoginSSH($handle) {
$username = $_SESSION['config']->getScriptUserName();
$credentials = $_SESSION['ldap']->decrypt_login();
if (empty($username)) {
// get user name from current LAM user
$sr = @ldap_read($_SESSION['ldap']->server(), $credentials[0], "objectClass=posixAccount", array('uid'), 0, 0, 0, LDAP_DEREF_NEVER);
if ($sr) {
$entry = @ldap_get_entries($_SESSION['ldap']->server(), $sr);
$username = $entry[0]['uid'][0];
}
if (empty($username)) {
throw new Exception(sprintf(_("Your LAM admin user (%s) must be a valid Unix account to work with lamdaemon!"), getAbstractDN($credentials[0])));
}
}
$password = $credentials[1];
$keyPath = $_SESSION['config']->getScriptSSHKey();
if (!empty($keyPath)) {
// use key authentication
if (!file_exists($keyPath) || !is_readable($keyPath)) {
throw new Exception(sprintf(_("Unable to read %s."), htmlspecialchars($keyPath)));
}
$key = file_get_contents($keyPath);
$rsa = new Crypt_RSA();
$keyPassword = $_SESSION['config']->getScriptSSHKeyPassword();
if (!empty($keyPassword)) {
$rsa->setPassword($keyPassword);
}
if (!$rsa->loadKey($key)) {
throw new Exception(sprintf(_("Unable to load key %s."), htmlspecialchars($keyPath)));
}
$password = $rsa;
}
$login = @$handle->login($username, $password);
if (!$login) {
throw new Exception(_("Unable to login to remote server!"));
}
}
?>

View File

@ -45,8 +45,8 @@ include_once("account.inc");
include_once("baseModule.inc"); include_once("baseModule.inc");
/** access to LDAP server */ /** access to LDAP server */
include_once("ldap.inc"); include_once("ldap.inc");
/** lamdaemon functions */ /** remote functions */
include_once("lamdaemon.inc"); include_once("remote.inc");
/** security functions */ /** security functions */
include_once("security.inc"); include_once("security.inc");
/** meta HTML classes */ /** meta HTML classes */

163
lam/lib/remote.inc Normal file
View File

@ -0,0 +1,163 @@
<?php
namespace LAM\REMOTE;
use \Exception;
use \phpseclib\Net\SSH2;
use \phpseclib\Crypt\RSA;
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This file includes functions to control LAM remote executions.
*
* @author Roland Gruber
*
* @package modules
*/
/**
* Runs remote commands.
*
* @author Roland Gruber
*/
class Remote {
/** SSH2 server handle */
private $server = null;
/**
* Constructor, include SSH library.
*/
public function __construct() {
$this->includeSshLibrary();
}
/**
* Sends commands to remote script.
*
* @param string $command command to execute
* @return string output of remote script
*
*/
public function execute($command) {
if ($this->server == null) {
return array();
}
return $this->server->exec("sudo " . $_SESSION['config']->get_scriptPath() . ' ' . escapeshellarg($command));
}
/**
* Connects to the given SSH server.
*
* @param String $server server name (e.g. localhost or localhost,1234)
* @return object handle
*/
public function connect($server) {
$serverNameParts = explode(",", $server);
$handle = false;
if (sizeof($serverNameParts) > 1) {
$handle = @new SSH2($serverNameParts[0], $serverNameParts[1]);
}
else {
$handle = @new SSH2($server);
}
if (!$handle) {
throw new Exception(_("Unable to connect to remote server!"));
}
$this->loginSSH($handle);
$this->server = $handle;
}
/**
* Closes the connection.
*/
public function disconnect() {
$this->server->disconnect();
}
/**
* Performs a login to the provided SSH handle.
*
* @param SSH2 $handle SSH handle
* @throws Exception login failed
*/
private function loginSSH($handle) {
$username = $_SESSION['config']->getScriptUserName();
$credentials = $_SESSION['ldap']->decrypt_login();
if (empty($username)) {
// get user name from current LAM user
$sr = @ldap_read($_SESSION['ldap']->server(), $credentials[0], "objectClass=posixAccount", array('uid'), 0, 0, 0, LDAP_DEREF_NEVER);
if ($sr) {
$entry = @ldap_get_entries($_SESSION['ldap']->server(), $sr);
$username = $entry[0]['uid'][0];
}
if (empty($username)) {
throw new Exception(sprintf(_("Your LAM admin user (%s) must be a valid Unix account to work with lamdaemon!"), getAbstractDN($credentials[0])));
}
}
$password = $credentials[1];
$keyPath = $_SESSION['config']->getScriptSSHKey();
if (!empty($keyPath)) {
// use key authentication
if (!file_exists($keyPath) || !is_readable($keyPath)) {
throw new Exception(sprintf(_("Unable to read %s."), htmlspecialchars($keyPath)));
}
$key = file_get_contents($keyPath);
$rsa = new RSA();
$keyPassword = $_SESSION['config']->getScriptSSHKeyPassword();
if (!empty($keyPassword)) {
$rsa->setPassword($keyPassword);
}
if (!$rsa->loadKey($key)) {
throw new Exception(sprintf(_("Unable to load key %s."), htmlspecialchars($keyPath)));
}
$password = $rsa;
}
$login = @$handle->login($username, $password);
if (!$login) {
throw new Exception(_("Unable to login to remote server!"));
}
}
/**
* Include the SSH files.
*/
private function includeSshLibrary() {
$prefix = dirname(__FILE__) . '/3rdParty/phpseclib/';
require_once($prefix . 'Crypt/Base.php');
require_once($prefix . 'Crypt/Blowfish.php');
require_once($prefix . 'Crypt/Hash.php');
require_once($prefix . 'Crypt/Random.php');
require_once($prefix . 'Crypt/RC4.php');
require_once($prefix . 'Crypt/Rijndael.php');
require_once($prefix . 'Crypt/AES.php');
require_once($prefix . 'Crypt/RSA.php');
require_once($prefix . 'Crypt/DES.php');
require_once($prefix . 'Crypt/TripleDES.php');
require_once($prefix . 'Crypt/Twofish.php');
require_once($prefix . 'Math/BigInteger.php');
require_once($prefix . 'System/SSH/Agent.php');
require_once($prefix . 'Net/SSH2.php');
}
}
?>

View File

@ -42,8 +42,8 @@ include_once('../lib/config.inc');
include_once('../lib/status.inc'); include_once('../lib/status.inc');
/** LDAP connection */ /** LDAP connection */
include_once('../lib/ldap.inc'); include_once('../lib/ldap.inc');
/** lamdaemon interface */ /** remote interface */
include_once('../lib/lamdaemon.inc'); include_once('../lib/remote.inc');
/** module interface */ /** module interface */
include_once('../lib/modules.inc'); include_once('../lib/modules.inc');

View File

@ -1,4 +1,18 @@
<?php <?php
namespace LAM\TOOLS\TESTS;
use \LAM\REMOTE\Remote;
use \htmlTable;
use \htmlTitle;
use \htmlOutputText;
use \htmlSelect;
use \htmlInputCheckbox;
use \htmlSpacer;
use \htmlButton;
use \htmlStatusMessage;
use \htmlImage;
use \htmlSubTitle;
use \Exception;
/* /*
$Id$ $Id$
@ -22,7 +36,7 @@ $Id$
*/ */
/** /**
* Tests the lamdaemon script. * Tests the remote script.
* *
* @author Roland Gruber * @author Roland Gruber
* @author Thomas Manninger * @author Thomas Manninger
@ -67,7 +81,7 @@ for ($i = 0; $i < sizeof($servers); $i++) {
} }
if (isset($_POST['runTest'])) { if (isset($_POST['runTest'])) {
lamRunLamdaemonTestSuite($_POST['server'], $serverTitles[$_POST['server']] , isset($_POST['checkQuotas']), $container); lamRunTestSuite($_POST['server'], $serverTitles[$_POST['server']] , isset($_POST['checkQuotas']), $container);
} }
else if ((sizeof($servers) > 0) && isset($servers[0]) && ($servers[0] != '')) { else if ((sizeof($servers) > 0) && isset($servers[0]) && ($servers[0] != '')) {
$container->addElement(new htmlOutputText(_("Server"))); $container->addElement(new htmlOutputText(_("Server")));
@ -111,22 +125,22 @@ include '../main_footer.php';
* *
* @param string $command test command * @param string $command test command
* @param boolean $stopTest specifies if test should be run * @param boolean $stopTest specifies if test should be run
* @param connection $handle SSH connection * @param Remote $remote SSH connection
* @param string $testText describing text * @param string $testText describing text
* @param htmlTable $container container for HTML output * @param htmlTable $container container for HTML output
* @return boolean true, if errors occured * @return boolean true, if errors occured
*/ */
function lamTestLamdaemon($command, $stopTest, $handle, $testText, $container) { function lamTestLamdaemon($command, $stopTest, $remote, $testText, $container) {
$okImage = "../../graphics/pass.png"; $okImage = "../../graphics/pass.png";
$failImage = "../../graphics/fail.png"; $failImage = "../../graphics/fail.png";
$spacer = new htmlSpacer('10px', null); $spacer = new htmlSpacer('10px', null);
// run lamdaemon and get user quotas // run remote command
if (!$stopTest) { if (!$stopTest) {
$container->addElement(new htmlOutputText($testText)); $container->addElement(new htmlOutputText($testText));
$container->addElement($spacer); $container->addElement($spacer);
flush(); flush();
$lamdaemonOk = false; $lamdaemonOk = false;
$output = $handle->exec("sudo " . $_SESSION['config']->get_scriptPath() . ' ' . escapeshellarg($command)); $output = $remote->execute($command);
if ((stripos(strtolower($output), "error") === false) && ((strpos($output, 'INFO,') === 0) || (strpos($output, 'QUOTA_ENTRY') === 0))) { if ((stripos(strtolower($output), "error") === false) && ((strpos($output, 'INFO,') === 0) || (strpos($output, 'QUOTA_ENTRY') === 0))) {
$lamdaemonOk = true; $lamdaemonOk = true;
} }
@ -170,7 +184,7 @@ function lamTestLamdaemon($command, $stopTest, $handle, $testText, $container) {
* @param boolean $testQuota true, if Quotas should be checked * @param boolean $testQuota true, if Quotas should be checked
* @param htmlTable $container container for HTML output * @param htmlTable $container container for HTML output
*/ */
function lamRunLamdaemonTestSuite($serverName, $serverTitle, $testQuota, $container) { function lamRunTestSuite($serverName, $serverTitle, $testQuota, $container) {
$SPLIT_DELIMITER = "###x##y##x###"; $SPLIT_DELIMITER = "###x##y##x###";
$LAMDAEMON_PROTOCOL_VERSION = '5'; $LAMDAEMON_PROTOCOL_VERSION = '5';
$okImage = "../../graphics/pass.png"; $okImage = "../../graphics/pass.png";
@ -246,13 +260,14 @@ function lamRunLamdaemonTestSuite($serverName, $serverTitle, $testQuota, $contai
flush(); flush();
// check SSH login // check SSH login
$remote = new Remote();
if (!$stopTest) { if (!$stopTest) {
$container->addElement(new htmlOutputText(_("SSH connection"))); $container->addElement(new htmlOutputText(_("SSH connection")));
$container->addElement($spacer); $container->addElement($spacer);
flush(); flush();
$sshOk = false; $sshOk = false;
try { try {
$handle = lamConnectSSH($serverName); $remote->connect($serverName);
$container->addElement(new htmlImage($okImage)); $container->addElement(new htmlImage($okImage));
$container->addElement($spacer); $container->addElement($spacer);
$container->addElement(new htmlOutputText(_("SSH connection established.")), true); $container->addElement(new htmlOutputText(_("SSH connection established.")), true);
@ -268,21 +283,18 @@ function lamRunLamdaemonTestSuite($serverName, $serverTitle, $testQuota, $contai
flush(); flush();
if (!$stopTest) { if (!$stopTest) {
$stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "test" . $SPLIT_DELIMITER . "basic", $stopTest, $handle, _("Execute lamdaemon"), $container); $stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "test" . $SPLIT_DELIMITER . "basic", $stopTest, $remote, _("Execute lamdaemon"), $container);
} }
if (!$stopTest) { if (!$stopTest) {
$stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "test" . $SPLIT_DELIMITER . "version" . $SPLIT_DELIMITER . $LAMDAEMON_PROTOCOL_VERSION, $stopTest, $handle, _("Lamdaemon version"), $container); $stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "test" . $SPLIT_DELIMITER . "version" . $SPLIT_DELIMITER . $LAMDAEMON_PROTOCOL_VERSION, $stopTest, $remote, _("Lamdaemon version"), $container);
} }
if (!$stopTest) { if (!$stopTest) {
$handle = lamConnectSSH($serverName); $stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "test" . $SPLIT_DELIMITER . "nss" . $SPLIT_DELIMITER . "$userName", $stopTest, $remote, _("Lamdaemon: check NSS LDAP"), $container);
$stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "test" . $SPLIT_DELIMITER . "nss" . $SPLIT_DELIMITER . "$userName", $stopTest, $handle, _("Lamdaemon: check NSS LDAP"), $container);
if (!$stopTest && $testQuota) { if (!$stopTest && $testQuota) {
$handle = lamConnectSSH($serverName); $stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "test" . $SPLIT_DELIMITER . "quota", $stopTest, $remote, _("Lamdaemon: Quota module installed"), $container);
$stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "test" . $SPLIT_DELIMITER . "quota", $stopTest, $handle, _("Lamdaemon: Quota module installed"), $container); $stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "quota" . $SPLIT_DELIMITER . "get" . $SPLIT_DELIMITER . "user", $stopTest, $remote, _("Lamdaemon: read quotas"), $container);
$handle = lamConnectSSH($serverName);
$stopTest = lamTestLamdaemon("+" . $SPLIT_DELIMITER . "quota" . $SPLIT_DELIMITER . "get" . $SPLIT_DELIMITER . "user", $stopTest, $handle, _("Lamdaemon: read quotas"), $container);
} }
} }