Merge branch 'develop' of git@github.com:LDAPAccountManager/lam.git into develop

This commit is contained in:
Roland Gruber 2017-09-24 09:49:02 +02:00
commit d521f60f66
63 changed files with 33816 additions and 34310 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/.settings/ /.settings/
/.buildpath /.buildpath
/.project /.project
/.Readme.md.html

View File

@ -3,9 +3,16 @@ LDAP Account Manager
LDAP Account Manager (LAM) is a webfrontend for managing entries (e.g. users, groups, DHCP settings) stored in an LDAP directory. LAM was designed to make LDAP management as easy as possible for the user. It abstracts from the technical details of LDAP and allows persons without technical background to manage LDAP entries. If needed, power users may still directly edit LDAP entries via the integrated LDAP browser. LDAP Account Manager (LAM) is a webfrontend for managing entries (e.g. users, groups, DHCP settings) stored in an LDAP directory. LAM was designed to make LDAP management as easy as possible for the user. It abstracts from the technical details of LDAP and allows persons without technical background to manage LDAP entries. If needed, power users may still directly edit LDAP entries via the integrated LDAP browser.
![LAM](https://www.ldap-account-manager.org/lamcms/sites/default/files/styles/slideshow/public/userList.png)
![LAM](https://www.ldap-account-manager.org/lamcms/sites/default/files/styles/slideshow/public/user_0.png)
# Download # Download
You can get the newest version at https://www.ldap-account-manager.org/. You can get the newest version at https://www.ldap-account-manager.org/.
# Documentation
Please see the [documentation area](https://www.ldap-account-manager.org/lamcms/documentation).
# Source code # Source code
There are two modules. Usually, you only need the files inside "lam". There are two modules. Usually, you only need the files inside "lam".

View File

@ -1,3 +1,7 @@
December 2017
- PHP 5.6 and Internet Explorer 11 or later required
19.09.2017 6.1 19.09.2017 6.1
- Automatically trim input fields to avoid trailing/leading spaces - Automatically trim input fields to avoid trailing/leading spaces
- LAM Pro: - LAM Pro:
@ -8,11 +12,13 @@
-> Password modify page reports error on password change when posixAccount is present for users -> Password modify page reports error on password change when posixAccount is present for users
-> Nginx configuration files did not include "fastcgi_param SCRIPT_FILENAME $request_filename;" (193) -> Nginx configuration files did not include "fastcgi_param SCRIPT_FILENAME $request_filename;" (193)
20.07.2017 6.0.1 20.07.2017 6.0.1
- Fixed bugs: - Fixed bugs:
-> Configuration file fills up with empty values -> Configuration file fills up with empty values
-> Tool visibility settings -> Tool visibility settings
26.06.2017 6.0 26.06.2017 6.0
- Support multiple configurations for same account type - Support multiple configurations for same account type
- PHP 7.1 compatibility - PHP 7.1 compatibility

View File

@ -15,7 +15,7 @@ LAM - Readme
https://www.ldap-account-manager.org/ https://www.ldap-account-manager.org/
Copyright (C) 2003 - 2016 Roland Gruber <post@rolandgruber.de> Copyright (C) 2003 - 2017 Roland Gruber <post@rolandgruber.de>
Installation and documentation: Installation and documentation:
Please see the LAM manual in docs/manual/index.html. Please see the LAM manual in docs/manual/index.html.

View File

@ -1,4 +1,4 @@
This software is copyright (c) 2003 - 2016 by Roland Gruber This software is copyright (c) 2003 - 2017 by Roland Gruber
If you purchased a copy of LDAP Account Manager Pro then the following If you purchased a copy of LDAP Account Manager Pro then the following
files are licensed under the conditions which you accepted at purchase files are licensed under the conditions which you accepted at purchase

View File

@ -15,7 +15,7 @@
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para>Apache/Nginx webserver (SSL recommended) with PHP module (PHP <para>Apache/Nginx webserver (SSL recommended) with PHP module (PHP
(&gt;= 5.4.0) with ldap, gettext, xml, openssl and optional (&gt;= 5.6.0) with ldap, gettext, xml, openssl and optional
OpenSSL)</para> OpenSSL)</para>
</listitem> </listitem>
@ -44,7 +44,7 @@
</listitem> </listitem>
<listitem> <listitem>
<para>Internet Explorer 9 <emphasis role="bold">(compatibility <para>Internet Explorer 11 <emphasis role="bold">(compatibility
mode turned off)</emphasis></para> mode turned off)</emphasis></para>
</listitem> </listitem>

View File

@ -63,7 +63,7 @@
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para>PHP (&gt;= 5.4.0)</para> <para>PHP (&gt;= 5.6.0)</para>
</listitem> </listitem>
<listitem> <listitem>
@ -85,7 +85,7 @@
</listitem> </listitem>
<listitem> <listitem>
<para>Internet Explorer 9<emphasis role="bold"> (compatibility mode <para>Internet Explorer 11<emphasis role="bold"> (compatibility mode
turned off)</emphasis></para> turned off)</emphasis></para>
</listitem> </listitem>

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,36 +38,34 @@
* 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;
use phpseclib\Crypt\DES;
use phpseclib\Crypt\Random;
use phpseclib\Crypt\TripleDES;
use phpseclib\Math\BigInteger;
/**
* Pure-PHP implementation of SSHv1.
*
* @package SSH1
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class SSH1
{
/**#@+ /**#@+
* Encryption Methods * Encryption Methods
* *
* @see self::getSupportedCiphers() * @see \phpseclib\Net\SSH1::getSupportedCiphers()
* @access public * @access public
*/ */
/** /**
@ -75,30 +73,30 @@
* *
* 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
* *
@ -114,40 +112,40 @@ 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;
/**#@-*/ /**#@-*/
/**#@+ /**#@+
@ -156,82 +154,73 @@ define('NET_SSH1_AUTH_RHOSTS_RSA', 4);
* @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,21 +31,36 @@
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent * @internal See http://api.libssh.org/rfc/PROTOCOL.agent
*/ */
namespace phpseclib\System\SSH;
use phpseclib\Crypt\RSA;
use phpseclib\System\SSH\Agent\Identity;
/**
* Pure-PHP ssh-agent client identity factory
*
* requestIdentities() method pumps out \phpseclib\System\SSH\Agent\Identity objects
*
* @package SSH\Agent
* @author Jim Wigginton <terrafrost@php.net>
* @access internal
*/
class Agent
{
/**#@+ /**#@+
* Message numbers * Message numbers
* *
* @access private * @access private
*/ */
// to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1) // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1)
define('SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES', 11); const SSH_AGENTC_REQUEST_IDENTITIES = 11;
// this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2). // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2).
define('SYSTEM_SSH_AGENT_IDENTITIES_ANSWER', 12); const SSH_AGENT_IDENTITIES_ANSWER = 12;
define('SYSTEM_SSH_AGENT_FAILURE', 5);
// the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3) // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3)
define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13); const SSH_AGENTC_SIGN_REQUEST = 13;
// the SSH1 response is SSH_AGENT_RSA_RESPONSE (4) // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14); const SSH_AGENT_SIGN_RESPONSE = 14;
/**#@-*/
/**@+ /**@+
* Agent forwarding status * Agent forwarding status
@ -72,166 +68,18 @@ define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
* @access private * @access private
*/ */
// no forwarding requested and not active // no forwarding requested and not active
define('SYSTEM_SSH_AGENT_FORWARD_NONE', 0); const FORWARD_NONE = 0;
// request agent forwarding when opportune // request agent forwarding when opportune
define('SYSTEM_SSH_AGENT_FORWARD_REQUEST', 1); const FORWARD_REQUEST = 1;
// forwarding has been request and is active // forwarding has been request and is active
define('SYSTEM_SSH_AGENT_FORWARD_ACTIVE', 2); const FORWARD_ACTIVE = 2;
/**#@-*/ /**#@-*/
/** /**
* Pure-PHP ssh-agent client identity object * Unused
*
* 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 const SSH_AGENT_FAILURE = 5;
{
/**
* 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
*
* requestIdentities() method pumps out System_SSH_Agent_Identity objects
*
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @access internal
*/
class System_SSH_Agent
{
/** /**
* 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

@ -460,10 +460,6 @@ function get_preg($argument, $regexp) {
$language = $_SESSION['language']; $language = $_SESSION['language'];
$language2 = explode ('.', $language); $language2 = explode ('.', $language);
setlocale(LC_ALL, $language2[0]); setlocale(LC_ALL, $language2[0]);
// workaround for buggy PHP with Turkish
if (($language == 'tr_TR.utf8') && (version_compare(phpversion(), '5.5') < 0)) {
setlocale(LC_CTYPE, 'en_GB');
}
// First we check "positive" cases // First we check "positive" cases
$pregexpr = ''; $pregexpr = '';
switch ($regexp) { switch ($regexp) {
@ -592,10 +588,6 @@ function get_preg($argument, $regexp) {
if (preg_match($pregexpr, $argument)) { if (preg_match($pregexpr, $argument)) {
/* Bug in php preg_match doesn't work correct with utf8 */ /* Bug in php preg_match doesn't work correct with utf8 */
setlocale(LC_ALL, $language); setlocale(LC_ALL, $language);
// workaround for buggy PHP with Turkish
if (($language == 'tr_TR.utf8') && (version_compare(phpversion(), '5.5') < 0)) {
setlocale(LC_CTYPE, 'en_GB');
}
return true; return true;
} }
// Now we check "negative" cases, characters which are not allowed // Now we check "negative" cases, characters which are not allowed
@ -615,18 +607,10 @@ function get_preg($argument, $regexp) {
if (!preg_match($pregexpr, $argument)) { if (!preg_match($pregexpr, $argument)) {
/* Bug in php preg_match doesn't work correct with utf8 */ /* Bug in php preg_match doesn't work correct with utf8 */
setlocale(LC_ALL, $language); setlocale(LC_ALL, $language);
// workaround for buggy PHP with Turkish
if (($language == 'tr_TR.utf8') && (version_compare(phpversion(), '5.5') < 0)) {
setlocale(LC_CTYPE, 'en_GB');
}
return true; return true;
} }
/* Bug in php preg_match doesn't work correct with utf8 */ /* Bug in php preg_match doesn't work correct with utf8 */
setlocale(LC_ALL, $language); setlocale(LC_ALL, $language);
// workaround for buggy PHP with Turkish
if (($language == 'tr_TR.utf8') && (version_compare(phpversion(), '5.5') < 0)) {
setlocale(LC_CTYPE, 'en_GB');
}
return false; return false;
} }

View File

@ -36,8 +36,8 @@ include_once("../lib/status.inc");
/** config */ /** config */
include_once("../lib/config.inc"); include_once("../lib/config.inc");
// check if PHP >= 5.4.0 // check if PHP >= 5.6.0
if (version_compare(phpversion(), '5.4.0') < 0) { if (version_compare(phpversion(), '5.6.0') < 0) {
echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n\n"; echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n\n";
echo "<html>\n<head>\n"; echo "<html>\n<head>\n";
echo "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n"; echo "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n";
@ -47,7 +47,7 @@ if (version_compare(phpversion(), '5.4.0') < 0) {
echo "<link rel=\"icon\" href=\"../graphics/logo136.png\">\n"; echo "<link rel=\"icon\" href=\"../graphics/logo136.png\">\n";
echo "<title>LDAP Account Manager</title>\n"; echo "<title>LDAP Account Manager</title>\n";
echo "</head><body>\n"; echo "</head><body>\n";
StatusMessage("ERROR", "LAM needs a PHP 5 version which is greater or equal than 5.4.0.", "Please upgrade your PHP installation. The found version is " . phpversion()); StatusMessage("ERROR", "LAM needs a PHP 5 version which is greater or equal than 5.6.0.", "Please upgrade your PHP installation. The found version is " . phpversion());
echo "<br><br>"; echo "<br><br>";
echo "</body></html>"; echo "</body></html>";
exit(); exit();

View File

@ -73,10 +73,6 @@ function setlanguage() {
} }
putenv("LANG=" . $code); // e.g. LANG=de_DE putenv("LANG=" . $code); // e.g. LANG=de_DE
setlocale(LC_ALL, $code); // set LC_ALL setlocale(LC_ALL, $code); // set LC_ALL
// workaround for buggy PHP with Turkish
if (($code == 'tr_TR.utf8') && (version_compare(phpversion(), '5.5') < 0)) {
setlocale(LC_CTYPE, 'en_GB');
}
$locdir = substr(__FILE__, 0, strlen(__FILE__) - 15) . "/locale"; // set path to translations $locdir = substr(__FILE__, 0, strlen(__FILE__) - 15) . "/locale"; // set path to translations
bindtextdomain("messages", $locdir); bindtextdomain("messages", $locdir);
bind_textdomain_codeset("messages", $encoding); bind_textdomain_codeset("messages", $encoding);

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 */
@ -532,10 +532,12 @@ function buildUploadAccounts($type, $data, $ids, $selectedModules) {
} }
} }
if (sizeof($errors) > 0) { if (sizeof($errors) > 0) {
for ($i = 0; (($i < sizeof($errors)) || ($i > 49)); $i++) call_user_func_array("StatusMessage", $errors[$i]); for ($i = 0; (($i < sizeof($errors)) || ($i > 49)); $i++) {
call_user_func_array("StatusMessage", $errors[$i]);
}
return false; return false;
} }
else return $partialAccounts; return $partialAccounts;
} }
/** /**

View File

@ -475,7 +475,7 @@ class courierMailAccount extends baseModule {
'description' => _('Home directory'), 'description' => _('Home directory'),
'help' => 'homeDirectory', 'help' => 'homeDirectory',
'example' => _('/home/smiller'), 'example' => _('/home/smiller'),
'required' => 'true' 'required' => true
); );
} }
return $return; return $return;

View File

@ -248,7 +248,7 @@ By default, the nodes are configured as H-Nodes which fits for small networks. I
'help' => 'subnet', 'help' => 'subnet',
'example' => '192.168.10.0', 'example' => '192.168.10.0',
'required' => true, 'required' => true,
'unique' => 'true' 'unique' => true
), ),
array( array(
'name' => 'dhcp_settings_domainName', 'name' => 'dhcp_settings_domainName',

View File

@ -161,7 +161,7 @@ class eduPerson extends baseModule {
'description' => _('Principal name'), 'description' => _('Principal name'),
'help' => 'eduPersonPrincipalName', 'help' => 'eduPersonPrincipalName',
'example' => _('user@company.com'), 'example' => _('user@company.com'),
'unique' => 'true' 'unique' => true
), ),
array( array(
'name' => 'eduPerson_primaryAffiliation', 'name' => 'eduPerson_primaryAffiliation',

View File

@ -32,7 +32,7 @@ $Id$
* *
* @package modules * @package modules
*/ */
class kolabSharedFolder extends baseModule { // TODO folder type class kolabSharedFolder extends baseModule {
/** cache for mailHost values */ /** cache for mailHost values */
private $mailHostCache = null; private $mailHostCache = null;
@ -49,7 +49,6 @@ class kolabSharedFolder extends baseModule { // TODO folder type
// call parent constructor // call parent constructor
parent::__construct($scope); parent::__construct($scope);
$this->folderTypes = array( $this->folderTypes = array(
// TODO reactivate types when stable 3.1 is released
/*_('Shared address book') => 'addressbook', /*_('Shared address book') => 'addressbook',
_('Shared calendar') => 'calendar', _('Shared calendar') => 'calendar',
_('Shared journal') => 'journal', _('Shared journal') => 'journal',

View File

@ -186,10 +186,8 @@ class posixAccount extends baseModule implements passwordService {
$loginShellsHelp = new htmlHelpLink('loginShells', get_class($this)); $loginShellsHelp = new htmlHelpLink('loginShells', get_class($this));
$loginShellsHelp->alignment = htmlElement::ALIGN_TOP; $loginShellsHelp->alignment = htmlElement::ALIGN_TOP;
$selfServiceContainer->addElement($loginShellsHelp, true); $selfServiceContainer->addElement($loginShellsHelp, true);
if (version_compare(phpversion(), '5.4.26') >= 0) {
$selfServiceContainer->addElement(new htmlTableExtendedInputCheckbox('posixAccount_useOldPwd', false, _('Password change with old password'))); $selfServiceContainer->addElement(new htmlTableExtendedInputCheckbox('posixAccount_useOldPwd', false, _('Password change with old password')));
$selfServiceContainer->addElement(new htmlHelpLink('useOldPwd', get_class($this)), true); $selfServiceContainer->addElement(new htmlHelpLink('useOldPwd', get_class($this)), true);
}
$return['selfServiceSettings'] = $selfServiceContainer; $return['selfServiceSettings'] = $selfServiceContainer;
} }
// profile checks // profile checks
@ -734,7 +732,9 @@ class posixAccount extends baseModule implements passwordService {
elseif (!in_array($temp[0], $this->lamdaemonServers)) { elseif (!in_array($temp[0], $this->lamdaemonServers)) {
continue; continue;
} }
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -745,11 +745,11 @@ class posixAccount extends baseModule implements passwordService {
"0".$_SESSION['config']->get_scriptRights(), "0".$_SESSION['config']->get_scriptRights(),
$this->attributes['uidNumber'][0], $this->attributes['uidNumber'][0],
$this->attributes['gidNumber'][0]) $this->attributes['gidNumber'][0])
), ));
$server); $remote->disconnect();
// lamdaemon results // lamdaemon results
if (is_array($result)) { if (!empty($result)) {
$singleresult = explode(",", $result[0]); $singleresult = explode(",", $result);
if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'INFO') || ($singleresult[0] == 'WARN')) { if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'INFO') || ($singleresult[0] == 'WARN')) {
$messages[] = $singleresult; $messages[] = $singleresult;
} }
@ -769,7 +769,9 @@ class posixAccount extends baseModule implements passwordService {
} }
$temp = explode(":", $lamdaemonServers[$i]); $temp = explode(":", $lamdaemonServers[$i]);
$server = $temp[0]; $server = $temp[0];
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -779,11 +781,11 @@ class posixAccount extends baseModule implements passwordService {
$this->orig[$homeDirAttr][0], $this->orig[$homeDirAttr][0],
$this->attributes['uidNumber'][0], $this->attributes['uidNumber'][0],
$this->attributes[$homeDirAttr][0]) $this->attributes[$homeDirAttr][0])
), ));
$server); $remote->disconnect();
// lamdaemon results // lamdaemon results
if (is_array($result)) { if (!empty($result)) {
$singleresult = explode(",", $result[0]); $singleresult = explode(",", $result);
if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'INFO') || ($singleresult[0] == 'WARN')) { if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'INFO') || ($singleresult[0] == 'WARN')) {
$messages[] = $singleresult; $messages[] = $singleresult;
} }
@ -800,7 +802,9 @@ class posixAccount extends baseModule implements passwordService {
} }
$temp = explode(":", $lamdaemonServers[$i]); $temp = explode(":", $lamdaemonServers[$i]);
$server = $temp[0]; $server = $temp[0];
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -810,11 +814,11 @@ class posixAccount extends baseModule implements passwordService {
$this->orig[$homeDirAttr][0], $this->orig[$homeDirAttr][0],
$this->attributes['uidNumber'][0], $this->attributes['uidNumber'][0],
$this->attributes['gidNumber'][0]) $this->attributes['gidNumber'][0])
), ));
$server); $remote->disconnect();
// lamdaemon results // lamdaemon results
if (is_array($result)) { if (!empty($result)) {
$singleresult = explode(",", $result[0]); $singleresult = explode(",", $result);
if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'INFO') || ($singleresult[0] == 'WARN')) { if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'INFO') || ($singleresult[0] == 'WARN')) {
$messages[] = $singleresult; $messages[] = $singleresult;
} }
@ -937,7 +941,9 @@ class posixAccount extends baseModule implements passwordService {
} }
// try to delete directory on all servers // try to delete directory on all servers
for ($i = 0; $i < sizeof($lamdaemonServers); $i++) { for ($i = 0; $i < sizeof($lamdaemonServers); $i++) {
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($lamdaemonServers[$i]);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -947,12 +953,11 @@ class posixAccount extends baseModule implements passwordService {
$this->attributes[$homeDirAttr][0], $this->attributes[$homeDirAttr][0],
$this->attributes['uidNumber'][0] $this->attributes['uidNumber'][0]
) )
), ));
$lamdaemonServers[$i]); $remote->disconnect();
// lamdaemon results // lamdaemon results
if (is_array($result)) { if (!empty($result)) {
foreach ($result as $singleresult) { $singleresult = explode(",", $result);
$singleresult = explode(",", $singleresult);
if (is_array($singleresult)) { if (is_array($singleresult)) {
if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) { if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) {
$return[] = $singleresult; $return[] = $singleresult;
@ -961,7 +966,6 @@ class posixAccount extends baseModule implements passwordService {
} }
} }
} }
}
// delete sudo rights // delete sudo rights
if (isset($_POST['deleteSudoers']) && ($_POST['deleteSudoers'] == 'on')) { if (isset($_POST['deleteSudoers']) && ($_POST['deleteSudoers'] == 'on')) {
$result = searchLDAPByAttribute('sudoUser', $this->attributes['uid'][0], 'sudoRole', array('dn'), array('sudo')); $result = searchLDAPByAttribute('sudoUser', $this->attributes['uid'][0], 'sudoRole', array('dn'), array('sudo'));
@ -1272,7 +1276,9 @@ class posixAccount extends baseModule implements passwordService {
$temp = explode(":", $lamdaemonServers[$i]); $temp = explode(":", $lamdaemonServers[$i]);
$server = $temp[0]; $server = $temp[0];
if (isset($_POST['form_subpage_' . get_class($this) . '_homedir_create_' . $i])) { if (isset($_POST['form_subpage_' . get_class($this) . '_homedir_create_' . $i])) {
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -1283,12 +1289,11 @@ class posixAccount extends baseModule implements passwordService {
"0".$_SESSION['config']->get_scriptRights(), "0".$_SESSION['config']->get_scriptRights(),
$this->attributes['uidNumber'][0], $this->attributes['uidNumber'][0],
$this->attributes['gidNumber'][0]) $this->attributes['gidNumber'][0])
), ));
$server); $remote->disconnect();
// lamdaemon results // lamdaemon results
if (is_array($result)) { if (!empty($result)) {
foreach ($result as $singleresult) { $singleresult = explode(",", $result);
$singleresult = explode(",", $singleresult);
if (is_array($singleresult)) { if (is_array($singleresult)) {
if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) { if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) {
$return[] = $singleresult; $return[] = $singleresult;
@ -1296,9 +1301,10 @@ class posixAccount extends baseModule implements passwordService {
} }
} }
} }
}
elseif (isset($_POST['form_subpage_' . get_class($this) . '_homedir_delete_' . $i])) { elseif (isset($_POST['form_subpage_' . get_class($this) . '_homedir_delete_' . $i])) {
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -1308,12 +1314,11 @@ class posixAccount extends baseModule implements passwordService {
$this->attributes[$homeDirAttr][0], $this->attributes[$homeDirAttr][0],
$this->attributes['uidNumber'][0] $this->attributes['uidNumber'][0]
) )
), ));
$server); $remote->disconnect();
// lamdaemon results // lamdaemon results
if (is_array($result)) { if (!empty($result)) {
foreach ($result as $singleresult) { $singleresult = explode(",", $result);
$singleresult = explode(",", $singleresult);
if (is_array($singleresult)) { if (is_array($singleresult)) {
if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) { if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) {
$return[] = $singleresult; $return[] = $singleresult;
@ -1322,7 +1327,6 @@ class posixAccount extends baseModule implements passwordService {
} }
} }
} }
}
return $return; return $return;
} }
@ -1662,7 +1666,9 @@ class posixAccount extends baseModule implements passwordService {
if (isset($temp[1])) { if (isset($temp[1])) {
$label = $temp[1]; $label = $temp[1];
} }
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -1670,11 +1676,11 @@ class posixAccount extends baseModule implements passwordService {
"home", "home",
"check", "check",
$this->attributes[$homeDirAttr][0]) $this->attributes[$homeDirAttr][0])
), ));
$server); $remote->disconnect();
// lamdaemon results // lamdaemon results
if (is_array($result)) { if (!empty($result)) {
$returnValue = trim($result[0]); $returnValue = trim($result);
if ($returnValue == 'ok') { if ($returnValue == 'ok') {
$homeServerContainer->addElement(new htmlOutputText($label)); $homeServerContainer->addElement(new htmlOutputText($label));
$homeServerContainer->addElement(new htmlSpacer('5px', null)); $homeServerContainer->addElement(new htmlSpacer('5px', null));
@ -2533,7 +2539,9 @@ class posixAccount extends baseModule implements passwordService {
// create home directories // create home directories
elseif ($temp['counter'] < (sizeof($temp['groups']) + sizeof($temp['createHomes']))) { elseif ($temp['counter'] < (sizeof($temp['groups']) + sizeof($temp['createHomes']))) {
$pos = $temp['createHomes'][$temp['counter'] - sizeof($temp['groups'])]; $pos = $temp['createHomes'][$temp['counter'] - sizeof($temp['groups'])];
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($data[$pos][$ids['posixAccount_createHomeDir']]);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -2545,11 +2553,11 @@ class posixAccount extends baseModule implements passwordService {
$accounts[$pos]['uidNumber'], $accounts[$pos]['uidNumber'],
$accounts[$pos]['gidNumber'], $accounts[$pos]['gidNumber'],
) )
), ));
$data[$pos][$ids['posixAccount_createHomeDir']]); $remote->disconnect();
$errors = array(); $errors = array();
if (($result != false) && (sizeof($result) == 1)) { if (!empty($result)) {
$parts = explode(",", $result[0]); $parts = explode(",", $result);
if (in_array($parts[0], array('ERROR', 'WARN'))) { if (in_array($parts[0], array('ERROR', 'WARN'))) {
$errors[] = $parts; $errors[] = $parts;
} }

View File

@ -186,11 +186,14 @@ class quota extends baseModule {
$temp = explode(":", $lamdaemonServers[$s]); $temp = explode(":", $lamdaemonServers[$s]);
$server = $temp[0]; $server = $temp[0];
// get quotas // get quotas
$quotas = lamdaemon(implode(quota::$SPLIT_DELIMITER, array($userName, "quota", "get", $this->get_scope())), $server); $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$quotas = $remote->execute(implode(quota::$SPLIT_DELIMITER, array($userName, "quota", "get", $this->get_scope())));
$remote->disconnect();
if (sizeof($quotas) == 0) { if (sizeof($quotas) == 0) {
continue; continue;
} }
$allQuotas = explode(":", $quotas[0]); $allQuotas = explode(":", $quotas);
array_pop($allQuotas); // remove empty element at the end array_pop($allQuotas); // remove empty element at the end
for ($i = 0; $i < sizeof($allQuotas); $i++) { for ($i = 0; $i < sizeof($allQuotas); $i++) {
if (strpos($allQuotas[$i], quota::$QUOTA_PREFIX) !== 0) continue; if (strpos($allQuotas[$i], quota::$QUOTA_PREFIX) !== 0) continue;
@ -280,7 +283,10 @@ class quota extends baseModule {
$quotastring = $quotastring . $this->quota[$server][$i][0] . ',' . $this->quota[$server][$i][2] . ',' . $this->quota[$server][$i][3] $quotastring = $quotastring . $this->quota[$server][$i][0] . ',' . $this->quota[$server][$i][2] . ',' . $this->quota[$server][$i][3]
. ',' . $this->quota[$server][$i][6] . ',' . $this->quota[$server][$i][7] . ':'; . ',' . $this->quota[$server][$i][6] . ',' . $this->quota[$server][$i][7] . ':';
} }
lamdaemon(implode(quota::$SPLIT_DELIMITER, array($id, "quota", "set", $this->get_scope(), "$quotastring\n")), $server); $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$remote->execute(implode(quota::$SPLIT_DELIMITER, array($id, "quota", "set", $this->get_scope(), "$quotastring\n")));
$remote->disconnect();
} }
return $messages; return $messages;
} }
@ -319,7 +325,10 @@ class quota extends baseModule {
$quotastring = $quotastring . $this->quota[$server][$i][0] . ',0,0,0,0:'; $quotastring = $quotastring . $this->quota[$server][$i][0] . ',0,0,0,0:';
$i++; $i++;
} }
lamdaemon(implode(quota::$SPLIT_DELIMITER, array($id, "quota", "set", $this->get_scope(), "$quotastring\n")), $server); $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$remote->execute(implode(quota::$SPLIT_DELIMITER, array($id, "quota", "set", $this->get_scope(), "$quotastring\n")));
$remote->disconnect();
} }
return array(); return array();
} }
@ -483,11 +492,14 @@ class quota extends baseModule {
$description = $temp[1] . ' (' . $temp[0] . ')'; $description = $temp[1] . ' (' . $temp[0] . ')';
} }
// Get quotas // Get quotas
$quotas = lamdaemon(implode(quota::$SPLIT_DELIMITER, array("+", "quota", "get", $this->get_scope())), $server); $remote = new \LAM\REMOTE\Remote();
if (sizeof($quotas) == 0) { $remote->connect($server);
$quotas = $remote->execute(implode(quota::$SPLIT_DELIMITER, array("+", "quota", "get", $this->get_scope())));
$remote->disconnect();
if (empty($quotas)) {
continue; continue;
} }
$dirs = explode(":", $quotas[0]); $dirs = explode(":", $quotas);
array_pop($dirs); // remove empty element at the end array_pop($dirs); // remove empty element at the end
for ($i = 0; $i < sizeof($dirs); $i++) { for ($i = 0; $i < sizeof($dirs); $i++) {
if (strpos($dirs[$i], quota::$QUOTA_PREFIX) !== 0) { if (strpos($dirs[$i], quota::$QUOTA_PREFIX) !== 0) {
@ -556,8 +568,11 @@ class quota extends baseModule {
$server = $temp[0]; $server = $temp[0];
$id = $this->replaceSpecialChars($server); $id = $this->replaceSpecialChars($server);
// Get quotas // Get quotas
$quotas = lamdaemon(implode(quota::$SPLIT_DELIMITER, array("+", "quota", "get", $this->get_scope())), $server); $remote = new \LAM\REMOTE\Remote();
$dirs = explode(":", $quotas[0]); $remote->connect($server);
$quotas = $remote->execute(implode(quota::$SPLIT_DELIMITER, array("+", "quota", "get", $this->get_scope())));
$remote->disconnect();
$dirs = explode(":", $quotas);
array_pop($dirs); // remove empty element at the end array_pop($dirs); // remove empty element at the end
for ($i = 0; $i < sizeof($dirs); $i++) { for ($i = 0; $i < sizeof($dirs); $i++) {
if (strpos($dirs[$i], quota::$QUOTA_PREFIX) !== 0) { if (strpos($dirs[$i], quota::$QUOTA_PREFIX) !== 0) {
@ -669,8 +684,11 @@ class quota extends baseModule {
$temp = explode(":", $lamdaemonServers[$s]); $temp = explode(":", $lamdaemonServers[$s]);
$server = $temp[0]; $server = $temp[0];
// Get quotas // Get quotas
$quotas = lamdaemon(implode(quota::$SPLIT_DELIMITER, array("+", "quota", "get", $this->get_scope())), $server); $remote = new \LAM\REMOTE\Remote();
$dirs = explode(":", $quotas[0]); $remote->connect($server);
$quotas = $remote->execute(implode(quota::$SPLIT_DELIMITER, array("+", "quota", "get", $this->get_scope())));
$remote->disconnect();
$dirs = explode(":", $quotas);
array_pop($dirs); // remove empty element at the end array_pop($dirs); // remove empty element at the end
for ($i = 0; $i < sizeof($dirs); $i++) { for ($i = 0; $i < sizeof($dirs); $i++) {
if (strpos($dirs[$i], quota::$QUOTA_PREFIX) !== 0) { if (strpos($dirs[$i], quota::$QUOTA_PREFIX) !== 0) {
@ -786,16 +804,17 @@ class quota extends baseModule {
$dir = $mpParts[1]; $dir = $mpParts[1];
$quotaString = implode(quota::$SPLIT_DELIMITER, array($name, "quota", "set", $this->get_scope(), $dir . ',' . $quotaString = implode(quota::$SPLIT_DELIMITER, array($name, "quota", "set", $this->get_scope(), $dir . ',' .
implode(',', $temp['accounts'][$name][$mountPoints[$m]]) . "\n")); implode(',', $temp['accounts'][$name][$mountPoints[$m]]) . "\n"));
$result = lamdaemon($quotaString, $server); $remote = new \LAM\REMOTE\Remote();
if (is_array($result)) { $remote->connect($server);
for ($i = 0; $i < sizeof($result); $i++) { $result = $remote->execute($quotaString);
$remote->disconnect();
if (!empty($result)) {
$parts = explode(",", $result); $parts = explode(",", $result);
if ($parts[0] == 'ERROR') { if ($parts[0] == 'ERROR') {
$errors[] = array('ERROR', $parts[1], $parts[2]); $errors[] = array('ERROR', $parts[1], $parts[2]);
} }
} }
} }
}
// set counters to next account/mount point // set counters to next account/mount point
$temp['counter']++; $temp['counter']++;
return array( return array(

View File

@ -1,4 +1,5 @@
<?php <?php
/* /*
$Id$ $Id$
@ -64,7 +65,7 @@ class sambaSamAccount extends baseModule implements passwordService {
private $cachedGroupSIDList = null; private $cachedGroupSIDList = null;
/** cache for domain list */ /** cache for domain list */
private $cachedDomainList = null; private $cachedDomainList = null;
/** delimiter for lamdaemon commands */ /** delimiter for remote commands */
private static $SPLIT_DELIMITER = "###x##y##x###"; private static $SPLIT_DELIMITER = "###x##y##x###";
@ -1541,16 +1542,18 @@ class sambaSamAccount extends baseModule implements passwordService {
$return->addElement(new htmlSpacer(null, '10px'), true); $return->addElement(new htmlSpacer(null, '10px'), true);
$homeServerContainer = new htmlTable(); $homeServerContainer = new htmlTable();
$homeServerContainer->colspan = 5; $homeServerContainer->colspan = 5;
// get list of lamdaemon servers // get list of remote servers
$lamdaemonServers = explode(";", $_SESSION['config']->get_scriptServers()); $remoteServers = explode(";", $_SESSION['config']->get_scriptServers());
for ($i = 0; $i < sizeof($lamdaemonServers); $i++) { for ($i = 0; $i < sizeof($remoteServers); $i++) {
$temp = explode(":", $lamdaemonServers[$i]); $temp = explode(":", $remoteServers[$i]);
$server = $temp[0]; $server = $temp[0];
$label = $temp[0]; $label = $temp[0];
if (isset($temp[1])) { if (isset($temp[1])) {
$label = $temp[1]; $label = $temp[1];
} }
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -1558,11 +1561,11 @@ class sambaSamAccount extends baseModule implements passwordService {
"home", "home",
"check", "check",
$this->attributes['sambaProfilePath'][0]) $this->attributes['sambaProfilePath'][0])
), ));
$server); $remote->disconnect();
// lamdaemon results // remote command results
if (is_array($result)) { if (!empty($result)) {
$returnValue = trim($result[0]); $returnValue = trim($result);
if ($returnValue == 'ok') { if ($returnValue == 'ok') {
$homeServerContainer->addElement(new htmlOutputText($label)); $homeServerContainer->addElement(new htmlOutputText($label));
$homeServerContainer->addElement(new htmlSpacer('5px', null)); $homeServerContainer->addElement(new htmlSpacer('5px', null));
@ -1614,13 +1617,15 @@ class sambaSamAccount extends baseModule implements passwordService {
if (empty($uidNumber) || empty($gidNumber)) { if (empty($uidNumber) || empty($gidNumber)) {
return; return;
} }
// get list of lamdaemon servers // get list of remote servers
$lamdaemonServers = explode(";", $_SESSION['config']->get_scriptServers()); $remoteServers = explode(";", $_SESSION['config']->get_scriptServers());
for ($i = 0; $i < sizeof($lamdaemonServers); $i++) { for ($i = 0; $i < sizeof($remoteServers); $i++) {
$temp = explode(":", $lamdaemonServers[$i]); $temp = explode(":", $remoteServers[$i]);
$server = $temp[0]; $server = $temp[0];
if (isset($_POST['form_subpage_' . get_class($this) . '_homedir_create_' . $i])) { if (isset($_POST['form_subpage_' . get_class($this) . '_homedir_create_' . $i])) {
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -1631,12 +1636,11 @@ class sambaSamAccount extends baseModule implements passwordService {
"0".$_SESSION['config']->get_scriptRights(), "0".$_SESSION['config']->get_scriptRights(),
$uidNumber, $uidNumber,
$gidNumber) $gidNumber)
), ));
$server); $remote->disconnect();
// lamdaemon results // remote command results
if (is_array($result)) { if (!empty($result)) {
foreach ($result as $singleresult) { $singleresult = explode(",", $result);
$singleresult = explode(",", $singleresult);
if (is_array($singleresult)) { if (is_array($singleresult)) {
if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) { if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) {
$return[] = $singleresult; $return[] = $singleresult;
@ -1644,9 +1648,10 @@ class sambaSamAccount extends baseModule implements passwordService {
} }
} }
} }
}
elseif (isset($_POST['form_subpage_' . get_class($this) . '_homedir_delete_' . $i])) { elseif (isset($_POST['form_subpage_' . get_class($this) . '_homedir_delete_' . $i])) {
$result = lamdaemon( $remote = new \LAM\REMOTE\Remote();
$remote->connect($server);
$result = $remote->execute(
implode( implode(
self::$SPLIT_DELIMITER, self::$SPLIT_DELIMITER,
array( array(
@ -1656,12 +1661,11 @@ class sambaSamAccount extends baseModule implements passwordService {
$this->attributes['sambaProfilePath'][0], $this->attributes['sambaProfilePath'][0],
$uidNumber $uidNumber
) )
), ));
$server); $remote->disconnect();
// lamdaemon results // remote command results
if (is_array($result)) { if (!empty($result)) {
foreach ($result as $singleresult) { $singleresult = explode(",", $result);
$singleresult = explode(",", $singleresult);
if (is_array($singleresult)) { if (is_array($singleresult)) {
if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) { if (($singleresult[0] == 'ERROR') || ($singleresult[0] == 'WARN') || ($singleresult[0] == 'INFO')) {
$return[] = $singleresult; $return[] = $singleresult;
@ -1670,7 +1674,6 @@ class sambaSamAccount extends baseModule implements passwordService {
} }
} }
} }
}
return $return; return $return;
} }

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

@ -0,0 +1,164 @@
<?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)
*/
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() {
if ($this->server == null) {
return;
}
$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

@ -85,8 +85,8 @@ if (isset($_GET['DN'])) {
$result = $_SESSION['account']->load_account($DN); $result = $_SESSION['account']->load_account($DN);
if (sizeof($result) > 0) { if (sizeof($result) > 0) {
include '../main_header.php'; include '../main_header.php';
for ($i=0; $i<sizeof($result); $i++) { foreach ($result as $message) {
call_user_func_array("StatusMessage", $result[$i]); call_user_func_array("StatusMessage", $message);
} }
include '../main_footer.php'; include '../main_footer.php';
die(); die();
@ -107,14 +107,6 @@ else if (count($_POST)==0) {
$_SESSION['account']->new_account(); $_SESSION['account']->new_account();
} }
// remove double slashes if magic quotes are on
if (get_magic_quotes_gpc() == 1) {
$postKeys = array_keys($_POST);
for ($i = 0; $i < sizeof($postKeys); $i++) {
if (is_string($_POST[$postKeys[$i]])) $_POST[$postKeys[$i]] = stripslashes($_POST[$postKeys[$i]]);
}
}
// show account page // show account page
$_SESSION['account']->continue_main(); $_SESSION['account']->continue_main();

View File

@ -625,13 +625,6 @@ function checkInput() {
$conf = &$_SESSION['conf_config']; $conf = &$_SESSION['conf_config'];
$types = $conf->get_ActiveTypes(); $types = $conf->get_ActiveTypes();
// remove double slashes if magic quotes are on
if (get_magic_quotes_gpc() == 1) {
$postKeys = array_keys($_POST);
for ($i = 0; $i < sizeof($postKeys); $i++) {
if (is_string($_POST[$postKeys[$i]])) $_POST[$postKeys[$i]] = stripslashes($_POST[$postKeys[$i]]);
}
}
// check new preferences // check new preferences
$errors = array(); $errors = array();
if (!$conf->set_ServerURL($_POST['serverurl'])) { if (!$conf->set_ServerURL($_POST['serverurl'])) {

View File

@ -90,13 +90,6 @@ $errors = array();
$messages = array(); $messages = array();
// check if submit button was pressed // check if submit button was pressed
if (isset($_POST['submitFormData'])) { if (isset($_POST['submitFormData'])) {
// remove double slashes if magic quotes are on
if (get_magic_quotes_gpc() == 1) {
$postKeys = array_keys($_POST);
for ($i = 0; $i < sizeof($postKeys); $i++) {
if (is_string($_POST[$postKeys[$i]])) $_POST[$postKeys[$i]] = stripslashes($_POST[$postKeys[$i]]);
}
}
// set master password // set master password
if (isset($_POST['masterpassword']) && ($_POST['masterpassword'] != "")) { if (isset($_POST['masterpassword']) && ($_POST['masterpassword'] != "")) {
if ($_POST['masterpassword'] && $_POST['masterpassword2'] && ($_POST['masterpassword'] == $_POST['masterpassword2'])) { if ($_POST['masterpassword'] && $_POST['masterpassword2'] && ($_POST['masterpassword'] == $_POST['masterpassword2'])) {

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');
@ -105,7 +105,8 @@ if (isset($_GET['type']) && isset($_SESSION['delete_dn'])) {
echo "<b>" . _("Do you really want to remove the following accounts?") . "</b>"; echo "<b>" . _("Do you really want to remove the following accounts?") . "</b>";
echo "<br><br>\n"; echo "<br><br>\n";
echo "<table border=0>\n"; echo "<table border=0>\n";
for ($i=0; $i<count($users); $i++) { $userCount = sizeof($users);
for ($i = 0; $i < $userCount; $i++) {
echo "<tr>\n"; echo "<tr>\n";
echo "<td><b>" . _("Account name:") . "</b> " . htmlspecialchars($users[$i]) . "</td>\n"; echo "<td><b>" . _("Account name:") . "</b> " . htmlspecialchars($users[$i]) . "</td>\n";
echo "<td>&nbsp;&nbsp;<b>" . _('DN') . ":</b> " . htmlspecialchars($_SESSION['delete_dn'][$i]) . "</td>\n"; echo "<td>&nbsp;&nbsp;<b>" . _('DN') . ":</b> " . htmlspecialchars($_SESSION['delete_dn'][$i]) . "</td>\n";
@ -173,11 +174,11 @@ if (isset($_POST['delete'])) {
// Delete dns // Delete dns
$allOk = true; $allOk = true;
$allErrors = array(); $allErrors = array();
for ($m=0; $m<count($_SESSION['delete_dn']); $m++) { foreach ($_SESSION['delete_dn'] as $deleteDN) {
// Set to true if an real error has happened // Set to true if an real error has happened
$stopprocessing = false; $stopprocessing = false;
// First load DN. // First load DN.
$_SESSION['account']->load_account($_SESSION['delete_dn'][$m]); $_SESSION['account']->load_account($deleteDN);
// get commands and changes of each attribute // get commands and changes of each attribute
$moduleNames = array_keys($_SESSION['account']->getAccountModules()); $moduleNames = array_keys($_SESSION['account']->getAccountModules());
$modules = $_SESSION['account']->getAccountModules(); $modules = $_SESSION['account']->getAccountModules();
@ -188,13 +189,13 @@ if (isset($_POST['delete'])) {
foreach ($moduleNames as $singlemodule) { foreach ($moduleNames as $singlemodule) {
$success = true; $success = true;
$messages = $modules[$singlemodule]->preDeleteActions(); $messages = $modules[$singlemodule]->preDeleteActions();
for ($i = 0; $i < sizeof($messages); $i++) { foreach ($messages as $message) {
$errors[] = $messages[$i]; $errors[] = $message;
if ($messages[$i][0] == 'ERROR') { if ($message[0] == 'ERROR') {
$success = false; $success = false;
$allOk = false; $allOk = false;
} }
elseif ($messages[$i][0] == 'WARN') { elseif ($message[0] == 'WARN') {
$allOk = false; $allOk = false;
} }
} }
@ -213,20 +214,21 @@ if (isset($_POST['delete'])) {
// merge changes // merge changes
$DNs = array_keys($temp); $DNs = array_keys($temp);
$attributes = array_merge_recursive($temp, $attributes); $attributes = array_merge_recursive($temp, $attributes);
for ($i=0; $i<count($DNs); $i++) { foreach ($DNs as $dn) {
$ops = array_keys($temp[$DNs[$i]]); $ops = array_keys($temp[$dn]);
for ($j=0; $j<count($ops); $j++) { foreach ($ops as $op) {
$attrs = array_keys($temp[$DNs[$i]][$ops[$j]]); $attrs = array_keys($temp[$dn][$op]);
for ($k=0; $k<count($attrs); $k++) foreach ($attrs as $attribute) {
$attributes[$DNs[$i]][$ops[$j]][$attrs[$k]] = array_unique($attributes[$DNs[$i]][$ops[$j]][$attrs[$k]]); $attributes[$dn][$op][$attribute] = array_unique($attributes[$dn][$op][$attribute]);
}
} }
} }
} }
} }
$DNs = array_keys($attributes); $DNs = array_keys($attributes);
for ($i=0; $i<count($DNs); $i++) { foreach ($DNs as $dn) {
if (isset($attributes[$DNs[$i]]['errors'])) { if (isset($attributes[$dn]['errors'])) {
foreach ($attributes[$DNs[$i]]['errors'] as $singleerror) { foreach ($attributes[$dn]['errors'] as $singleerror) {
$errors[] = $singleerror; $errors[] = $singleerror;
if ($singleerror[0] == 'ERROR') { if ($singleerror[0] == 'ERROR') {
$stopprocessing = true; $stopprocessing = true;
@ -236,28 +238,28 @@ if (isset($_POST['delete'])) {
} }
if (!$stopprocessing) { if (!$stopprocessing) {
// modify attributes // modify attributes
if (isset($attributes[$DNs[$i]]['modify']) && !$stopprocessing) { if (isset($attributes[$dn]['modify']) && !$stopprocessing) {
$success = @ldap_mod_replace($_SESSION['ldap']->server(), $DNs[$i], $attributes[$DNs[$i]]['modify']); $success = @ldap_mod_replace($_SESSION['ldap']->server(), $dn, $attributes[$dn]['modify']);
if (!$success) { if (!$success) {
$errors[] = array ('ERROR', sprintf(_('Was unable to modify attributes from DN: %s.'), $DNs[$i]), getDefaultLDAPErrorString($_SESSION['ldap']->server())); $errors[] = array ('ERROR', sprintf(_('Was unable to modify attributes from DN: %s.'), $dn), getDefaultLDAPErrorString($_SESSION['ldap']->server()));
$stopprocessing = true; $stopprocessing = true;
$allOk = false; $allOk = false;
} }
} }
// add attributes // add attributes
if (isset($attributes[$DNs[$i]]['add']) && !$stopprocessing) { if (isset($attributes[$dn]['add']) && !$stopprocessing) {
$success = @ldap_mod_add($_SESSION['ldap']->server(), $DNs[$i], $attributes[$DNs[$i]]['add']); $success = @ldap_mod_add($_SESSION['ldap']->server(), $dn, $attributes[$dn]['add']);
if (!$success) { if (!$success) {
$errors[] = array ('ERROR', sprintf(_('Was unable to add attributes to DN: %s.'), $DNs[$i]), getDefaultLDAPErrorString($_SESSION['ldap']->server())); $errors[] = array ('ERROR', sprintf(_('Was unable to add attributes to DN: %s.'), $dn), getDefaultLDAPErrorString($_SESSION['ldap']->server()));
$stopprocessing = true; $stopprocessing = true;
$allOk = false; $allOk = false;
} }
} }
// remove attributes // remove attributes
if (isset($attributes[$DNs[$i]]['remove']) && !$stopprocessing) { if (isset($attributes[$dn]['remove']) && !$stopprocessing) {
$success = @ldap_mod_del($_SESSION['ldap']->server(), $DNs[$i], $attributes[$DNs[$i]]['remove']); $success = @ldap_mod_del($_SESSION['ldap']->server(), $dn, $attributes[$dn]['remove']);
if (!$success) { if (!$success) {
$errors[] = array ('ERROR', sprintf(_('Was unable to remove attributes from DN: %s.'), $DNs[$i]), getDefaultLDAPErrorString($_SESSION['ldap']->server())); $errors[] = array ('ERROR', sprintf(_('Was unable to remove attributes from DN: %s.'), $dn), getDefaultLDAPErrorString($_SESSION['ldap']->server()));
$stopprocessing = true; $stopprocessing = true;
$allOk = false; $allOk = false;
} }
@ -267,7 +269,7 @@ if (isset($_POST['delete'])) {
} }
if (!$stopprocessing) { if (!$stopprocessing) {
$recursive = !$_SESSION['account']->hasOnlyVirtualChildren(); $recursive = !$_SESSION['account']->hasOnlyVirtualChildren();
$messages = deleteDN($_SESSION['delete_dn'][$m], $recursive); $messages = deleteDN($deleteDN, $recursive);
$errors = array_merge($errors, $messages); $errors = array_merge($errors, $messages);
if (sizeof($errors) > 0) { if (sizeof($errors) > 0) {
$stopprocessing = true; $stopprocessing = true;
@ -278,16 +280,16 @@ if (isset($_POST['delete'])) {
if (!$stopprocessing) { if (!$stopprocessing) {
foreach ($moduleNames as $singlemodule) { foreach ($moduleNames as $singlemodule) {
$messages = $modules[$singlemodule]->postDeleteActions(); $messages = $modules[$singlemodule]->postDeleteActions();
for ($i = 0; $i < sizeof($messages); $i++) { foreach ($messages as $message) {
$errors[] = $messages[$i]; $errors[] = $message;
if (($messages[$i][0] == 'ERROR') || ($messages[$i][0] == 'WARN')) { if (($message[0] == 'ERROR') || ($message[0] == 'WARN')) {
$allOk = false; $allOk = false;
} }
} }
} }
} }
if (!$stopprocessing) { if (!$stopprocessing) {
echo sprintf(_('Deleted DN: %s'), $_SESSION['delete_dn'][$m]) . "<br>\n"; echo sprintf(_('Deleted DN: %s'), $deleteDN) . "<br>\n";
foreach ($errors as $error) { foreach ($errors as $error) {
call_user_func_array('StatusMessage', $error); call_user_func_array('StatusMessage', $error);
} }
@ -295,7 +297,7 @@ if (isset($_POST['delete'])) {
flush(); flush();
} }
else { else {
echo sprintf(_('Error while deleting DN: %s'), $_SESSION['delete_dn'][$m]) . "<br>\n"; echo sprintf(_('Error while deleting DN: %s'), $deleteDN) . "<br>\n";
foreach ($errors as $error) { foreach ($errors as $error) {
call_user_func_array('StatusMessage', $error); call_user_func_array('StatusMessage', $error);
} }

View File

@ -54,19 +54,19 @@ if (!empty($_POST)) {
// check if user already pressed button // check if user already pressed button
if (isset($_POST['add_suff']) || isset($_POST['cancel'])) { if (isset($_POST['add_suff']) || isset($_POST['cancel'])) {
if (isset($_POST['add_suff'])) { if (isset($_POST['add_suff'])) {
$fail = array(); $failedDNs = array();
$errors = array(); $error = array();
$new_suff = $_POST['new_suff']; $newSuffixes = $_POST['new_suff'];
$new_suff = str_replace("\\", "", $new_suff); $newSuffixes = str_replace("\\", "", $newSuffixes);
$new_suff = str_replace("'", "", $new_suff); $newSuffixes = str_replace("'", "", $newSuffixes);
$new_suff = explode(";", $new_suff); $newSuffixes = explode(";", $newSuffixes);
// add entries // add entries
for ($i = 0; $i < sizeof($new_suff); $i++) { foreach ($newSuffixes as $newSuffix) {
// check if entry is already present // check if entry is already present
$info = @ldap_read($_SESSION['ldap']->server(), escapeDN($new_suff[$i]), "objectclass=*", array('dn'), 0, 0, 0, LDAP_DEREF_NEVER); $info = @ldap_read($_SESSION['ldap']->server(), escapeDN($newSuffix), "objectclass=*", array('dn'), 0, 0, 0, LDAP_DEREF_NEVER);
$res = @ldap_get_entries($_SESSION['ldap']->server(), $info); $res = @ldap_get_entries($_SESSION['ldap']->server(), $info);
if ($res) continue; if ($res) continue;
$suff = $new_suff[$i]; $suff = $newSuffix;
// generate DN and attributes // generate DN and attributes
$tmp = explode(",", $suff); $tmp = explode(",", $suff);
$name = explode("=", $tmp[0]); $name = explode("=", $tmp[0]);
@ -78,7 +78,7 @@ if (isset($_POST['add_suff']) || isset($_POST['cancel'])) {
$attr['objectClass'] = 'organization'; $attr['objectClass'] = 'organization';
$dn = $suff; $dn = $suff;
if (!@ldap_add($_SESSION['ldap']->server(), $dn, $attr)) { if (!@ldap_add($_SESSION['ldap']->server(), $dn, $attr)) {
$fail[] = $suff; $failedDNs[] = $suff;
$error[] = ldap_error($_SESSION['ldap']->server()); $error[] = ldap_error($_SESSION['ldap']->server());
continue; continue;
} }
@ -117,7 +117,7 @@ if (isset($_POST['add_suff']) || isset($_POST['cancel'])) {
$attr['ou'] = $headarray[1]; $attr['ou'] = $headarray[1];
$dn = $subsuffs[$k]; $dn = $subsuffs[$k];
if (!@ldap_add($_SESSION['ldap']->server(), $dn, $attr)) { if (!@ldap_add($_SESSION['ldap']->server(), $dn, $attr)) {
$fail[] = $suff; $failedDNs[] = $suff;
$error[] = ldap_error($_SESSION['ldap']->server()); $error[] = ldap_error($_SESSION['ldap']->server());
break; break;
} }
@ -132,7 +132,7 @@ if (isset($_POST['add_suff']) || isset($_POST['cancel'])) {
} }
$dn = $subsuffs[$k]; $dn = $subsuffs[$k];
if (!@ldap_add($_SESSION['ldap']->server(), $dn, $attr)) { if (!@ldap_add($_SESSION['ldap']->server(), $dn, $attr)) {
$fail[] = $suff; $failedDNs[] = $suff;
$error[] = ldap_error($_SESSION['ldap']->server()); $error[] = ldap_error($_SESSION['ldap']->server());
break; break;
} }
@ -141,7 +141,7 @@ if (isset($_POST['add_suff']) || isset($_POST['cancel'])) {
} }
} }
else { else {
$fail[] = $suff; $failedDNs[] = $suff;
$error[] = ldap_error($_SESSION['ldap']->server()); $error[] = ldap_error($_SESSION['ldap']->server());
} }
} }
@ -151,10 +151,10 @@ if (isset($_POST['add_suff']) || isset($_POST['cancel'])) {
include 'main_header.php'; include 'main_header.php';
// print error/success messages // print error/success messages
if (isset($_POST['add_suff'])) { if (isset($_POST['add_suff'])) {
if (sizeof($fail) > 0) { if (sizeof($failedDNs) > 0) {
// print error messages // print error messages
for ($i = 0; $i < sizeof($fail); $i++) { for ($i = 0; $i < sizeof($failedDNs); $i++) {
StatusMessage("ERROR", _("Failed to create entry!") . "<br>" . htmlspecialchars($error[$i]), htmlspecialchars($fail[$i])); StatusMessage("ERROR", _("Failed to create entry!") . "<br>" . htmlspecialchars($error[$i]), htmlspecialchars($failedDNs[$i]));
} }
include 'main_footer.php'; include 'main_footer.php';
} }
@ -173,10 +173,10 @@ if (isset($_POST['add_suff']) || isset($_POST['cancel'])) {
} }
// first show of page // first show of page
$new_suff = $_GET['suffs']; $newSuffixes = $_GET['suffs'];
$new_suff = str_replace("\\", "", $new_suff); $newSuffixes = str_replace("\\", "", $newSuffixes);
$new_suff = str_replace("'", "", $new_suff); $newSuffixes = str_replace("'", "", $newSuffixes);
$new_suff = explode(";", $new_suff); $newSuffixes = explode(";", $newSuffixes);
include 'main_header.php'; include 'main_header.php';
echo '<div class="user-bright smallPaddingContent">'; echo '<div class="user-bright smallPaddingContent">';
@ -186,15 +186,15 @@ include 'main_header.php';
$container->addElement(new htmlOutputText(_("You can setup the LDAP suffixes for all account types in your LAM server profile on tab \"Account types\".")), true); $container->addElement(new htmlOutputText(_("You can setup the LDAP suffixes for all account types in your LAM server profile on tab \"Account types\".")), true);
$container->addElement(new htmlSpacer(null, '10px'), true); $container->addElement(new htmlSpacer(null, '10px'), true);
// print missing suffixes // print missing suffixes
for ($i = 0; $i < sizeof($new_suff); $i++) { foreach ($newSuffixes as $newSuffix) {
$container->addElement(new htmlOutputText($new_suff[$i]), true); $container->addElement(new htmlOutputText($newSuffix), true);
} }
$container->addElement(new htmlSpacer(null, '10px'), true); $container->addElement(new htmlSpacer(null, '10px'), true);
$buttonContainer = new htmlTable(); $buttonContainer = new htmlTable();
$buttonContainer->addElement(new htmlButton('add_suff', _("Create"))); $buttonContainer->addElement(new htmlButton('add_suff', _("Create")));
$buttonContainer->addElement(new htmlButton('cancel', _("Cancel"))); $buttonContainer->addElement(new htmlButton('cancel', _("Cancel")));
$buttonContainer->addElement(new htmlHiddenInput('new_suff', implode(";", $new_suff))); $buttonContainer->addElement(new htmlHiddenInput('new_suff', implode(";", $newSuffixes)));
$container->addElement($buttonContainer); $container->addElement($buttonContainer);
addSecurityTokenToMetaHTML($container); addSecurityTokenToMetaHTML($container);

View File

@ -177,7 +177,7 @@ $_SESSION['header'] .= "<meta http-equiv=\"pragma\" content=\"no-cache\">\n <me
* @param \LAM\ENV\LAMLicenseValidator $licenseValidator license validator * @param \LAM\ENV\LAMLicenseValidator $licenseValidator license validator
* @param string $error_message error message to display * @param string $error_message error message to display
*/ */
function display_LoginPage($config_object, $cfgMain, $licenseValidator, $error_message) { function display_LoginPage(LAMConfig $config_object, LAMCfgMain $cfgMain, $licenseValidator, $error_message) {
logNewMessage(LOG_DEBUG, "Display login page"); logNewMessage(LOG_DEBUG, "Display login page");
// generate 256 bit key and initialization vector for user/passwd-encryption // generate 256 bit key and initialization vector for user/passwd-encryption
if(function_exists('openssl_random_pseudo_bytes') && ($cfgMain->encryptSession == 'true')) { if(function_exists('openssl_random_pseudo_bytes') && ($cfgMain->encryptSession == 'true')) {
@ -582,9 +582,6 @@ if(!empty($_POST['checklogin'])) {
display_LoginPage($_SESSION['config'], $_SESSION["cfgMain"], $licenseValidator, $error_message); // Empty password submitted. Return to login page. display_LoginPage($_SESSION['config'], $_SESSION["cfgMain"], $licenseValidator, $error_message); // Empty password submitted. Return to login page.
exit(); exit();
} }
if (get_magic_quotes_gpc() == 1) {
$_POST['passwd'] = stripslashes($_POST['passwd']);
}
$username = $_POST['username']; $username = $_POST['username'];
$password = $_POST['passwd']; $password = $_POST['passwd'];
} }
@ -594,7 +591,7 @@ if(!empty($_POST['checklogin'])) {
$searchFilter = str_replace('%USER%', $username ,$searchFilter); $searchFilter = str_replace('%USER%', $username ,$searchFilter);
$searchDN = ''; $searchDN = '';
$searchPassword = ''; $searchPassword = '';
if (($_SESSION['config']->getLoginSearchDN() != null) && ($_SESSION['config']->getLoginSearchDN() != '')) { if (!empty($_SESSION['config']->getLoginSearchDN())) {
$searchDN = $_SESSION['config']->getLoginSearchDN(); $searchDN = $_SESSION['config']->getLoginSearchDN();
$searchPassword = $_SESSION['config']->getLoginSearchPassword(); $searchPassword = $_SESSION['config']->getLoginSearchPassword();
} }

View File

@ -1,4 +1,5 @@
<?php <?php
namespace LAM\AJAX;
/* /*
$Id$ $Id$
@ -47,18 +48,19 @@ if (startSecureSession(false, true) === false) {
setlanguage(); setlanguage();
lamAjax::handleRequest(); $ajax = new Ajax();
$ajax->handleRequest();
/** /**
* Manages all AJAX requests. * Manages all AJAX requests.
*/ */
class lamAjax { class Ajax {
/** /**
* Manages an AJAX request. * Manages an AJAX request.
*/ */
public static function handleRequest() { public function handleRequest() {
lamAjax::setHeader(); $this->setHeader();
// check token // check token
validateSecurityToken(false); validateSecurityToken(false);
@ -84,16 +86,16 @@ class lamAjax {
$jsonInput = $_POST['jsonInput']; $jsonInput = $_POST['jsonInput'];
if ($function == 'passwordStrengthCheck') { if ($function == 'passwordStrengthCheck') {
lamAjax::checkPasswordStrength($jsonInput); $this->checkPasswordStrength($jsonInput);
} }
enforceUserIsLoggedIn(); enforceUserIsLoggedIn();
if ($function == 'passwordChange') { if ($function == 'passwordChange') {
lamAjax::managePasswordChange($jsonInput); $this->managePasswordChange($jsonInput);
} }
elseif ($function == 'upload') { elseif ($function == 'upload') {
include_once('../../lib/upload.inc'); include_once('../../lib/upload.inc');
$typeManager = new \LAM\TYPES\TypeManager(); $typeManager = new \LAM\TYPES\TypeManager();
$uploader = new LAM\UPLOAD\Uploader($typeManager->getConfiguredType($_GET['typeId'])); $uploader = new \LAM\UPLOAD\Uploader($typeManager->getConfiguredType($_GET['typeId']));
ob_start(); ob_start();
$jsonOut = $uploader->doUpload(); $jsonOut = $uploader->doUpload();
ob_end_clean(); ob_end_clean();
@ -115,7 +117,7 @@ class lamAjax {
* *
* @param array $input input parameters * @param array $input input parameters
*/ */
public static function managePasswordChange($input) { private static function managePasswordChange($input) {
$return = $_SESSION['account']->setNewPassword($input); $return = $_SESSION['account']->setNewPassword($input);
echo json_encode($return); echo json_encode($return);
} }
@ -125,7 +127,7 @@ class lamAjax {
* *
* @param array $input input parameters * @param array $input input parameters
*/ */
public static function checkPasswordStrength($input) { private function checkPasswordStrength($input) {
$password = $input['password']; $password = $input['password'];
$result = checkPasswordStrength($password, null, null); $result = checkPasswordStrength($password, null, null);
echo json_encode(array("result" => $result)); echo json_encode(array("result" => $result));

View File

@ -81,7 +81,7 @@ if (isset($_POST['createOU']) || isset($_POST['deleteOU'])) {
// check if ou already exists // check if ou already exists
$new_dn = "ou=" . $_POST['newOU'] . "," . $_POST['parentOU']; $new_dn = "ou=" . $_POST['newOU'] . "," . $_POST['parentOU'];
$found = ldapGetDN($new_dn); $found = ldapGetDN($new_dn);
if ($found == null) { if ($found === null) {
// add new ou // add new ou
$ou = array(); $ou = array();
$ou['objectClass'] = "organizationalunit"; $ou['objectClass'] = "organizationalunit";

View File

@ -15,6 +15,7 @@ use \htmlInputFileUpload;
use \htmlHelpLink; use \htmlHelpLink;
use \htmlInputField; use \htmlInputField;
use \htmlHiddenInput; use \htmlHiddenInput;
use \LAM\TYPES\TypeManager;
/* /*
$Id$ $Id$
@ -89,7 +90,7 @@ if(isset($_POST['createNewTemplate'])) {
exit(); exit();
} }
$typeManager = new \LAM\TYPES\TypeManager(); $typeManager = new TypeManager();
$types = $typeManager->getConfiguredTypes(); $types = $typeManager->getConfiguredTypes();
$sortedTypes = array(); $sortedTypes = array();
foreach ($types as $type) { foreach ($types as $type) {
@ -141,7 +142,7 @@ if (!empty($_POST['import'])) {
} }
$errMessage = importStructures($_POST['typeId'], $options, $serverProfiles, $typeManager); $errMessage = importStructures($_POST['typeId'], $options, $serverProfiles, $typeManager);
} }
if ($errMessage != null) { if ($errMessage !== null) {
$errMessage->colspan = 10; $errMessage->colspan = 10;
$container->addElement($errMessage, true); $container->addElement($errMessage, true);
} }
@ -166,7 +167,7 @@ if (!empty($_POST['export'])) {
$name = $_POST['name_' . $typeId]; $name = $_POST['name_' . $typeId];
$errMessage = exportStructures($typeId, $name, $options, $serverProfiles, $typeManager); $errMessage = exportStructures($typeId, $name, $options, $serverProfiles, $typeManager);
} }
if ($errMessage != null) { if ($errMessage !== null) {
$errMessage->colspan = 10; $errMessage->colspan = 10;
$container->addElement($errMessage, true); $container->addElement($errMessage, true);
} }
@ -195,23 +196,18 @@ foreach ($sortedTypes as $typeId => $title) {
'scope' => $type->getScope(), 'scope' => $type->getScope(),
'title' => $title, 'title' => $title,
'icon' => $type->getIcon(), 'icon' => $type->getIcon(),
'templates' => ""); 'templates' => \LAM\PDF\getPDFStructures($type->getId()));
$availableTypes[$title] = $type->getId(); $availableTypes[$title] = $type->getId();
} }
// get list of templates for each account type
for ($i = 0; $i < sizeof($templateClasses); $i++) {
$templateClasses[$i]['templates'] = \LAM\PDF\getPDFStructures($templateClasses[$i]['typeId']);
}
// check if a template should be edited // check if a template should be edited
for ($i = 0; $i < sizeof($templateClasses); $i++) { foreach ($templateClasses as $templateClass) {
if (isset($_POST['editTemplate_' . $templateClasses[$i]['typeId']]) || isset($_POST['editTemplate_' . $templateClasses[$i]['typeId'] . '_x'])) { if (isset($_POST['editTemplate_' . $templateClass['typeId']]) || isset($_POST['editTemplate_' . $templateClass['typeId'] . '_x'])) {
metaRefresh('pdfpage.php?type=' . htmlspecialchars($templateClasses[$i]['typeId']) . '&edit=' . htmlspecialchars($_POST['template_' . $templateClasses[$i]['typeId']])); metaRefresh('pdfpage.php?type=' . htmlspecialchars($templateClass['typeId']) . '&edit=' . htmlspecialchars($_POST['template_' . $templateClass['typeId']]));
exit; exit;
} }
} }
include '../main_header.php'; include '../main_header.php';
?> ?>
<div class="user-bright smallPaddingContent"> <div class="user-bright smallPaddingContent">
<form enctype="multipart/form-data" action="pdfmain.php" method="post" name="pdfmainForm" > <form enctype="multipart/form-data" action="pdfmain.php" method="post" name="pdfmainForm" >
@ -246,38 +242,38 @@ include '../main_header.php';
// existing templates // existing templates
$container->addElement(new htmlSubTitle(_("Manage existing PDF structures")), true); $container->addElement(new htmlSubTitle(_("Manage existing PDF structures")), true);
$existingContainer = new htmlTable(); $existingContainer = new htmlTable();
for ($i = 0; $i < sizeof($templateClasses); $i++) { foreach ($templateClasses as $templateClass) {
if ($i > 0) { if ($i > 0) {
$existingContainer->addElement(new htmlSpacer(null, '10px'), true); $existingContainer->addElement(new htmlSpacer(null, '10px'), true);
} }
$existingContainer->addElement(new htmlImage('../../graphics/' . $templateClasses[$i]['icon'])); $existingContainer->addElement(new htmlImage('../../graphics/' . $templateClass['icon']));
$existingContainer->addElement(new htmlSpacer('3px', null)); $existingContainer->addElement(new htmlSpacer('3px', null));
$existingContainer->addElement(new htmlOutputText($templateClasses[$i]['title'])); $existingContainer->addElement(new htmlOutputText($templateClass['title']));
$existingContainer->addElement(new htmlSpacer('3px', null)); $existingContainer->addElement(new htmlSpacer('3px', null));
$select = new htmlSelect('template_' . $templateClasses[$i]['typeId'], $templateClasses[$i]['templates']); $select = new htmlSelect('template_' . $templateClass['typeId'], $templateClass['templates']);
$select->setWidth('15em'); $select->setWidth('15em');
$existingContainer->addElement($select); $existingContainer->addElement($select);
$existingContainer->addElement(new htmlSpacer('3px', null)); $existingContainer->addElement(new htmlSpacer('3px', null));
$exEditButton = new htmlButton('editTemplate_' . $templateClasses[$i]['typeId'], 'edit.png', true); $exEditButton = new htmlButton('editTemplate_' . $templateClass['typeId'], 'edit.png', true);
$exEditButton->setTitle(_('Edit')); $exEditButton->setTitle(_('Edit'));
$existingContainer->addElement($exEditButton); $existingContainer->addElement($exEditButton);
$deleteLink = new htmlLink(null, '#', '../../graphics/delete.png'); $deleteLink = new htmlLink(null, '#', '../../graphics/delete.png');
$deleteLink->setTitle(_('Delete')); $deleteLink->setTitle(_('Delete'));
$deleteLink->setOnClick("profileShowDeleteDialog('" . _('Delete') . "', '" . _('Ok') . "', '" . _('Cancel') . "', '" . $templateClasses[$i]['typeId'] . "', '" . 'template_' . $templateClasses[$i]['typeId'] . "');"); $deleteLink->setOnClick("profileShowDeleteDialog('" . _('Delete') . "', '" . _('Ok') . "', '" . _('Cancel') . "', '" . $templateClass['typeId'] . "', '" . 'template_' . $templateClass['typeId'] . "');");
$existingContainer->addElement($deleteLink); $existingContainer->addElement($deleteLink);
if (count($configProfiles) > 1) { if (count($configProfiles) > 1) {
$importLink = new htmlLink(null, '#', '../../graphics/import.png'); $importLink = new htmlLink(null, '#', '../../graphics/import.png');
$importLink->setTitle(_('Import PDF structures')); $importLink->setTitle(_('Import PDF structures'));
$importLink->setOnClick("showDistributionDialog('" . _("Import PDF structures") . "', '" . $importLink->setOnClick("showDistributionDialog('" . _("Import PDF structures") . "', '" .
_('Ok') . "', '" . _('Cancel') . "', '" . $templateClasses[$i]['typeId'] . "', 'import');"); _('Ok') . "', '" . _('Cancel') . "', '" . $templateClass['typeId'] . "', 'import');");
$existingContainer->addElement($importLink); $existingContainer->addElement($importLink);
} }
$exportLink = new htmlLink(null, '#', '../../graphics/export.png'); $exportLink = new htmlLink(null, '#', '../../graphics/export.png');
$exportLink->setTitle(_('Export PDF structure')); $exportLink->setTitle(_('Export PDF structure'));
$exportLink->setOnClick("showDistributionDialog('" . _("Export PDF structure") . "', '" . $exportLink->setOnClick("showDistributionDialog('" . _("Export PDF structure") . "', '" .
_('Ok') . "', '" . _('Cancel') . "', '" . $templateClasses[$i]['typeId'] . "', 'export', '" . 'template_' . $templateClasses[$i]['typeId'] . "', '" . $_SESSION['config']->getName() . "');"); _('Ok') . "', '" . _('Cancel') . "', '" . $templateClass['typeId'] . "', 'export', '" . 'template_' . $templateClass['typeId'] . "', '" . $_SESSION['config']->getName() . "');");
$existingContainer->addElement($exportLink); $existingContainer->addElement($exportLink);
$existingContainer->addNewLine(); $existingContainer->addNewLine();
} }
@ -314,12 +310,12 @@ include '../main_header.php';
echo "</form>\n"; echo "</form>\n";
echo "</div>\n"; echo "</div>\n";
for ($i = 0; $i < sizeof($templateClasses); $i++) { foreach ($templateClasses as $templateClass) {
$typeId = $templateClasses[$i]['typeId']; $typeId = $templateClass['typeId'];
$scope = $templateClasses[$i]['scope']; $scope = $templateClass['scope'];
$importOptions = array(); $importOptions = array();
foreach ($configProfiles as $profile) { foreach ($configProfiles as $profile) {
$typeManagerImport = new \LAM\TYPES\TypeManager($serverProfiles[$profile]); $typeManagerImport = new TypeManager($serverProfiles[$profile]);
$typesImport = $typeManagerImport->getConfiguredTypesForScope($scope); $typesImport = $typeManagerImport->getConfiguredTypesForScope($scope);
foreach ($typesImport as $typeImport) { foreach ($typesImport as $typeImport) {
if (($profile != $_SESSION['config']->getName()) || ($typeImport->getId() != $typeId)) { if (($profile != $_SESSION['config']->getName()) || ($typeImport->getId() != $typeId)) {
@ -374,7 +370,7 @@ include '../main_header.php';
$container->addElement(new htmlOutputText(_("Target server profile")), true); $container->addElement(new htmlOutputText(_("Target server profile")), true);
$exportOptions = array(); $exportOptions = array();
foreach ($configProfiles as $profile) { foreach ($configProfiles as $profile) {
$typeManagerExport = new \LAM\TYPES\TypeManager($serverProfiles[$profile]); $typeManagerExport = new TypeManager($serverProfiles[$profile]);
$typesExport = $typeManagerExport->getConfiguredTypesForScope($scope); $typesExport = $typeManagerExport->getConfiguredTypesForScope($scope);
foreach ($typesExport as $typeExport) { foreach ($typesExport as $typeExport) {
if (($profile != $_SESSION['config']->getName()) || ($typeExport->getId() != $typeId)) { if (($profile != $_SESSION['config']->getName()) || ($typeExport->getId() != $typeId)) {
@ -430,18 +426,18 @@ include '../main_footer.php';
* @param string $typeId type id * @param string $typeId type id
* @param array $options options * @param array $options options
* @param \LAMConfig[] $serverProfiles server profiles (name => profile object) * @param \LAMConfig[] $serverProfiles server profiles (name => profile object)
* @param \LAM\TYPES\TypeManager $typeManager type manager * @param TypeManager $typeManager type manager
* @return \htmlStatusMessage message or null * @return \htmlStatusMessage message or null
*/ */
function importStructures($typeId, $options, &$serverProfiles, &$typeManager) { function importStructures($typeId, $options, &$serverProfiles, TypeManager &$typeManager) {
foreach ($options as $option) { foreach ($options as $option) {
$sourceConfName = $option['conf']; $sourceConfName = $option['conf'];
$sourceTypeId = $option['typeId']; $sourceTypeId = $option['typeId'];
$sourceName = $option['name']; $sourceName = $option['name'];
$sourceTypeManager = new \LAM\TYPES\TypeManager($serverProfiles[$sourceConfName]); $sourceTypeManager = new TypeManager($serverProfiles[$sourceConfName]);
$sourceType = $sourceTypeManager->getConfiguredType($sourceTypeId); $sourceType = $sourceTypeManager->getConfiguredType($sourceTypeId);
$targetType = $typeManager->getConfiguredType($typeId); $targetType = $typeManager->getConfiguredType($typeId);
if (($sourceType != null) && ($targetType != null)) { if (($sourceType !== null) && ($targetType !== null)) {
try { try {
\LAM\PDF\copyStructure($sourceType, $sourceName, $targetType); \LAM\PDF\copyStructure($sourceType, $sourceName, $targetType);
} }
@ -460,12 +456,12 @@ function importStructures($typeId, $options, &$serverProfiles, &$typeManager) {
* @param string $name profile name * @param string $name profile name
* @param array $options options * @param array $options options
* @param \LAMConfig[] $serverProfiles server profiles (name => profile object) * @param \LAMConfig[] $serverProfiles server profiles (name => profile object)
* @param \LAM\TYPES\TypeManager $typeManager type manager * @param TypeManager $typeManager type manager
* @return \htmlStatusMessage message or null * @return \htmlStatusMessage message or null
*/ */
function exportStructures($typeId, $name, $options, &$serverProfiles, &$typeManager) { function exportStructures($typeId, $name, $options, &$serverProfiles, TypeManager &$typeManager) {
$sourceType = $typeManager->getConfiguredType($typeId); $sourceType = $typeManager->getConfiguredType($typeId);
if ($sourceType == null) { if ($sourceType === null) {
return null; return null;
} }
foreach ($options as $option) { foreach ($options as $option) {
@ -480,9 +476,9 @@ function exportStructures($typeId, $name, $options, &$serverProfiles, &$typeMana
} }
else { else {
$targetTypeId = $option['typeId']; $targetTypeId = $option['typeId'];
$targetTypeManager = new \LAM\TYPES\TypeManager($serverProfiles[$targetConfName]); $targetTypeManager = new TypeManager($serverProfiles[$targetConfName]);
$targetType = $targetTypeManager->getConfiguredType($targetTypeId); $targetType = $targetTypeManager->getConfiguredType($targetTypeId);
if ($targetType != null) { if ($targetType !== null) {
try { try {
\LAM\PDF\copyStructure($sourceType, $name, $targetType); \LAM\PDF\copyStructure($sourceType, $name, $targetType);
} }

View File

@ -496,7 +496,7 @@ function translateFieldIDToName($id, $scope, $availablePDFFields) {
* *
* @param PDFStructure $structure * @param PDFStructure $structure
*/ */
function updateBasicSettings(&$structure) { function updateBasicSettings(PDFStructure &$structure) {
// set headline // set headline
if (isset($_POST['headline'])) { if (isset($_POST['headline'])) {
$structure->setTitle(str_replace('<', '', str_replace('>', '', $_POST['headline']))); $structure->setTitle(str_replace('<', '', str_replace('>', '', $_POST['headline'])));
@ -516,7 +516,7 @@ function updateBasicSettings(&$structure) {
* *
* @param PDFStructure $structure * @param PDFStructure $structure
*/ */
function updateSectionTitles(&$structure) { function updateSectionTitles(PDFStructure &$structure) {
$sections = $structure->getSections(); $sections = $structure->getSections();
foreach ($_POST as $key => $value) { foreach ($_POST as $key => $value) {
if (strpos($key, 'section_') === 0) { if (strpos($key, 'section_') === 0) {
@ -531,7 +531,7 @@ function updateSectionTitles(&$structure) {
* *
* @param PDFStructure $structure * @param PDFStructure $structure
*/ */
function addSection(&$structure) { function addSection(PDFStructure &$structure) {
$sections = $structure->getSections(); $sections = $structure->getSections();
// add a new text field // add a new text field
if(isset($_POST['add_text'])) { if(isset($_POST['add_text'])) {
@ -570,7 +570,7 @@ function addSection(&$structure) {
* *
* @param PDFStructure $structure * @param PDFStructure $structure
*/ */
function addSectionEntry(&$structure) { function addSectionEntry(PDFStructure &$structure) {
if(isset($_POST['add_new_field'])) { if(isset($_POST['add_new_field'])) {
$field = new PDFSectionEntry($_POST['new_field']); $field = new PDFSectionEntry($_POST['new_field']);
$sections = $structure->getSections(); $sections = $structure->getSections();
@ -587,7 +587,7 @@ function addSectionEntry(&$structure) {
* *
* @param PDFStructure $structure * @param PDFStructure $structure
*/ */
function removeItem(&$structure) { function removeItem(PDFStructure &$structure) {
$sections = $structure->getSections(); $sections = $structure->getSections();
foreach ($_POST as $key => $value) { foreach ($_POST as $key => $value) {
// remove section // remove section
@ -617,7 +617,7 @@ function removeItem(&$structure) {
* *
* @param PDFStructure $structure * @param PDFStructure $structure
*/ */
function moveUp(&$structure) { function moveUp(PDFStructure &$structure) {
$sections = $structure->getSections(); $sections = $structure->getSections();
foreach ($_POST as $key => $value) { foreach ($_POST as $key => $value) {
// move section // move section
@ -649,7 +649,7 @@ function moveUp(&$structure) {
* *
* @param PDFStructure $structure * @param PDFStructure $structure
*/ */
function moveDown(&$structure) { function moveDown(PDFStructure &$structure) {
$sections = $structure->getSections(); $sections = $structure->getSections();
foreach ($_POST as $key => $value) { foreach ($_POST as $key => $value) {
// move section // move section

View File

@ -14,6 +14,7 @@ use \htmlOutputText;
use \htmlHelpLink; use \htmlHelpLink;
use \htmlHiddenInput; use \htmlHiddenInput;
use \htmlInputField; use \htmlInputField;
use \LAM\TYPES\TypeManager;
/* /*
$Id$ $Id$
@ -67,7 +68,7 @@ if (!empty($_POST)) {
validateSecurityToken(); validateSecurityToken();
} }
$typeManager = new \LAM\TYPES\TypeManager(); $typeManager = new TypeManager();
$types = $typeManager->getConfiguredTypes(); $types = $typeManager->getConfiguredTypes();
$profileClasses = array(); $profileClasses = array();
$profileClassesTemp = array(); $profileClassesTemp = array();
@ -158,7 +159,7 @@ if (!empty($_POST['import'])) {
} }
$errMessage = importProfiles($_POST['typeId'], $options, $serverProfiles, $typeManager); $errMessage = importProfiles($_POST['typeId'], $options, $serverProfiles, $typeManager);
} }
if ($errMessage != null) { if ($errMessage !== null) {
$errMessage->colspan = 10; $errMessage->colspan = 10;
$container->addElement($errMessage, true); $container->addElement($errMessage, true);
} }
@ -181,7 +182,7 @@ if (!empty($_POST['export'])) {
$name = $_POST['name_' . $typeId]; $name = $_POST['name_' . $typeId];
$errMessage = exportProfiles($typeId, $name, $options, $serverProfiles, $typeManager); $errMessage = exportProfiles($typeId, $name, $options, $serverProfiles, $typeManager);
} }
if ($errMessage != null) { if ($errMessage !== null) {
$errMessage->colspan = 10; $errMessage->colspan = 10;
$container->addElement($errMessage, true); $container->addElement($errMessage, true);
} }
@ -274,7 +275,7 @@ for ($i = 0; $i < sizeof($profileClasses); $i++) {
$scope = $profileClasses[$i]['scope']; $scope = $profileClasses[$i]['scope'];
$importOptions = array(); $importOptions = array();
foreach ($configProfiles as $profile) { foreach ($configProfiles as $profile) {
$typeManagerImport = new \LAM\TYPES\TypeManager($serverProfiles[$profile]); $typeManagerImport = new TypeManager($serverProfiles[$profile]);
$typesImport = $typeManagerImport->getConfiguredTypesForScope($scope); $typesImport = $typeManagerImport->getConfiguredTypesForScope($scope);
foreach ($typesImport as $typeImport) { foreach ($typesImport as $typeImport) {
if (($profile != $_SESSION['config']->getName()) || ($typeImport->getId() != $typeId)) { if (($profile != $_SESSION['config']->getName()) || ($typeImport->getId() != $typeId)) {
@ -329,7 +330,7 @@ for ($i = 0; $i < sizeof($profileClasses); $i++) {
$container->addElement(new htmlOutputText(_("Target server profile")), true); $container->addElement(new htmlOutputText(_("Target server profile")), true);
$exportOptions = array(); $exportOptions = array();
foreach ($configProfiles as $profile) { foreach ($configProfiles as $profile) {
$typeManagerExport = new \LAM\TYPES\TypeManager($serverProfiles[$profile]); $typeManagerExport = new TypeManager($serverProfiles[$profile]);
$typesExport = $typeManagerExport->getConfiguredTypesForScope($scope); $typesExport = $typeManagerExport->getConfiguredTypesForScope($scope);
foreach ($typesExport as $typeExport) { foreach ($typesExport as $typeExport) {
if (($profile != $_SESSION['config']->getName()) || ($typeExport->getId() != $typeId)) { if (($profile != $_SESSION['config']->getName()) || ($typeExport->getId() != $typeId)) {
@ -385,18 +386,18 @@ include '../main_footer.php';
* @param string $typeId type id * @param string $typeId type id
* @param array $options options * @param array $options options
* @param \LAMConfig[] $serverProfiles server profiles (name => profile object) * @param \LAMConfig[] $serverProfiles server profiles (name => profile object)
* @param \LAM\TYPES\TypeManager $typeManager type manager * @param TypeManager $typeManager type manager
* @return \htmlStatusMessage message or null * @return \htmlStatusMessage message or null
*/ */
function importProfiles($typeId, $options, &$serverProfiles, &$typeManager) { function importProfiles($typeId, $options, &$serverProfiles, TypeManager &$typeManager) {
foreach ($options as $option) { foreach ($options as $option) {
$sourceConfName = $option['conf']; $sourceConfName = $option['conf'];
$sourceTypeId = $option['typeId']; $sourceTypeId = $option['typeId'];
$sourceName = $option['name']; $sourceName = $option['name'];
$sourceTypeManager = new \LAM\TYPES\TypeManager($serverProfiles[$sourceConfName]); $sourceTypeManager = new TypeManager($serverProfiles[$sourceConfName]);
$sourceType = $sourceTypeManager->getConfiguredType($sourceTypeId); $sourceType = $sourceTypeManager->getConfiguredType($sourceTypeId);
$targetType = $typeManager->getConfiguredType($typeId); $targetType = $typeManager->getConfiguredType($typeId);
if (($sourceType != null) && ($targetType != null)) { if (($sourceType !== null) && ($targetType !== null)) {
try { try {
\LAM\PROFILES\copyAccountProfile($sourceType, $sourceName, $targetType); \LAM\PROFILES\copyAccountProfile($sourceType, $sourceName, $targetType);
} }
@ -415,12 +416,12 @@ function importProfiles($typeId, $options, &$serverProfiles, &$typeManager) {
* @param string $name profile name * @param string $name profile name
* @param array $options options * @param array $options options
* @param \LAMConfig[] $serverProfiles server profiles (name => profile object) * @param \LAMConfig[] $serverProfiles server profiles (name => profile object)
* @param \LAM\TYPES\TypeManager $typeManager type manager * @param TypeManager $typeManager type manager
* @return \htmlStatusMessage message or null * @return \htmlStatusMessage message or null
*/ */
function exportProfiles($typeId, $name, $options, &$serverProfiles, &$typeManager) { function exportProfiles($typeId, $name, $options, &$serverProfiles, TypeManager &$typeManager) {
$sourceType = $typeManager->getConfiguredType($typeId); $sourceType = $typeManager->getConfiguredType($typeId);
if ($sourceType == null) { if ($sourceType === null) {
return null; return null;
} }
foreach ($options as $option) { foreach ($options as $option) {
@ -435,9 +436,9 @@ function exportProfiles($typeId, $name, $options, &$serverProfiles, &$typeManage
} }
else { else {
$targetTypeId = $option['typeId']; $targetTypeId = $option['typeId'];
$targetTypeManager = new \LAM\TYPES\TypeManager($serverProfiles[$targetConfName]); $targetTypeManager = new TypeManager($serverProfiles[$targetConfName]);
$targetType = $targetTypeManager->getConfiguredType($targetTypeId); $targetType = $targetTypeManager->getConfiguredType($targetTypeId);
if ($targetType != null) { if ($targetType !== null) {
try { try {
\LAM\PROFILES\copyAccountProfile($sourceType, $name, $targetType); \LAM\PROFILES\copyAccountProfile($sourceType, $name, $targetType);
} }

View File

@ -125,13 +125,6 @@ if (isset($_POST['save'])) {
} }
} }
// remove double slashes if magic quotes are on
if (get_magic_quotes_gpc() == 1) {
foreach ($opt_keys as $element) {
if (isset($options[$element][0]) && is_string($options[$element][0])) $options[$element][0] = stripslashes($options[$element][0]);
}
}
// check options // check options
$errors = checkProfileOptions($_POST['accounttype'], $options); $errors = checkProfileOptions($_POST['accounttype'], $options);
if (sizeof($errors) == 0) { // input data is valid, save profile if (sizeof($errors) == 0) { // input data is valid, save profile
@ -169,13 +162,8 @@ if (isset($_POST['save'])) {
$postKeys = array_keys($_POST); $postKeys = array_keys($_POST);
for ($i = 0; $i < sizeof($postKeys); $i++) { for ($i = 0; $i < sizeof($postKeys); $i++) {
if (!is_array($_POST[$postKeys[$i]])) { if (!is_array($_POST[$postKeys[$i]])) {
if (get_magic_quotes_gpc() == 1) {
$old_options[$postKeys[$i]] = array(stripslashes($_POST[$postKeys[$i]]));
}
else {
$old_options[$postKeys[$i]] = array($_POST[$postKeys[$i]]); $old_options[$postKeys[$i]] = array($_POST[$postKeys[$i]]);
} }
}
else { else {
$old_options[$postKeys[$i]] = $_POST[$postKeys[$i]]; $old_options[$postKeys[$i]] = $_POST[$postKeys[$i]];
} }
@ -241,7 +229,7 @@ for ($m = 0; $m < sizeof($modules); $m++) {
if (sizeof($options[$modules[$m]]) < 1) continue; if (sizeof($options[$modules[$m]]) < 1) continue;
$module = new $modules[$m]($type->getScope()); $module = new $modules[$m]($type->getScope());
$icon = $module->getIcon(); $icon = $module->getIcon();
if (($icon != null) && !(strpos($icon, 'http') === 0) && !(strpos($icon, '/') === 0)) { if (!empty($icon) && !(strpos($icon, 'http') === 0) && !(strpos($icon, '/') === 0)) {
$icon = '../../graphics/' . $icon; $icon = '../../graphics/' . $icon;
} }
$container = new htmlTable(); $container = new htmlTable();

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 testRemoteCommand($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,23 +283,21 @@ 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 = testRemoteCommand("+" . $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 = testRemoteCommand("+" . $SPLIT_DELIMITER . "test" . $SPLIT_DELIMITER . "version" . $SPLIT_DELIMITER . $LAMDAEMON_PROTOCOL_VERSION, $stopTest, $remote, _("Lamdaemon version"), $container);
} }
if (!$stopTest) { if (!$stopTest) {
$handle = lamConnectSSH($serverName); $stopTest = testRemoteCommand("+" . $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 = testRemoteCommand("+" . $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 = testRemoteCommand("+" . $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);
} }
} }
$remote->disconnect();
$container->addElement(new htmlSpacer(null, '10px'), true); $container->addElement(new htmlSpacer(null, '10px'), true);
$endMessage = new htmlOutputText(_("Lamdaemon test finished.")); $endMessage = new htmlOutputText(_("Lamdaemon test finished."));

View File

@ -140,7 +140,7 @@ if ($_FILES['inputfile'] && ($_FILES['inputfile']['size'] > 0)) {
$checkcolumns = array(); $checkcolumns = array();
$columns = call_user_func_array('array_merge', $columns); $columns = call_user_func_array('array_merge', $columns);
for ($i = 0; $i < sizeof($columns); $i++) { for ($i = 0; $i < sizeof($columns); $i++) {
if (isset($columns[$i]['required']) && ($columns[$i]['required'] == true)) { if (isset($columns[$i]['required']) && ($columns[$i]['required'] === true)) {
if (isset($ids[$columns[$i]['name']])) $checkcolumns[] = $ids[$columns[$i]['name']]; if (isset($ids[$columns[$i]['name']])) $checkcolumns[] = $ids[$columns[$i]['name']];
else $errors[] = array(_("A required column is missing in your CSV file."), $columns[$i]['name']); else $errors[] = array(_("A required column is missing in your CSV file."), $columns[$i]['name']);
} }
@ -201,7 +201,7 @@ if ($_FILES['inputfile'] && ($_FILES['inputfile']['size'] > 0)) {
// let modules build accounts // let modules build accounts
else { else {
$accounts = buildUploadAccounts($type, $data, $ids, $selectedModules); $accounts = buildUploadAccounts($type, $data, $ids, $selectedModules);
if ($accounts != false) { if ($accounts !== false) {
$rdnList = getRDNAttributes($type->getId(), $selectedModules); $rdnList = getRDNAttributes($type->getId(), $selectedModules);
$suffix = $type->getSuffix(); $suffix = $type->getSuffix();
// set DN // set DN
@ -282,7 +282,7 @@ include '../main_footer.php';
* @param array $selectedModules selected modules for upload * @param array $selectedModules selected modules for upload
* @param htmlTable $container table container * @param htmlTable $container table container
*/ */
function massPrintBackButton($typeId, $selectedModules, &$container) { function massPrintBackButton($typeId, $selectedModules, htmlTable &$container) {
$backButton = new htmlButton('submit', _('Back')); $backButton = new htmlButton('submit', _('Back'));
$backButton->setIconClass('backButton'); $backButton->setIconClass('backButton');
$container->addElement($backButton); $container->addElement($backButton);

View File

@ -256,7 +256,7 @@ include '../main_footer.php';
* @param \LAM\TYPES\ConfiguredType $type account type * @param \LAM\TYPES\ConfiguredType $type account type
* @param array $selectedModules list of selected account modules * @param array $selectedModules list of selected account modules
*/ */
function showMainPage($type, $selectedModules) { function showMainPage(\LAM\TYPES\ConfiguredType $type, $selectedModules) {
$scope = $type->getScope(); $scope = $type->getScope();
echo '<div class="' . $scope . '-bright smallPaddingContent">'; echo '<div class="' . $scope . '-bright smallPaddingContent">';
// get input fields from modules // get input fields from modules
@ -382,7 +382,7 @@ function showMainPage($type, $selectedModules) {
$columnContainer->addElement(new htmlSpacer(null, '10px'), true); $columnContainer->addElement(new htmlSpacer(null, '10px'), true);
$module = moduleCache::getModule($modules[$m], $scope); $module = moduleCache::getModule($modules[$m], $scope);
$icon = $module->getIcon(); $icon = $module->getIcon();
if (($icon != null) && !(strpos($icon, 'http') === 0) && !(strpos($icon, '/') === 0)) { if (!empty($icon) && !(strpos($icon, 'http') === 0) && !(strpos($icon, '/') === 0)) {
$icon = '../../graphics/' . $icon; $icon = '../../graphics/' . $icon;
} }
$moduleTitle = new htmlSubTitle(getModuleAlias($modules[$m], $scope), $icon); $moduleTitle = new htmlSubTitle(getModuleAlias($modules[$m], $scope), $icon);
@ -413,7 +413,7 @@ function showMainPage($type, $selectedModules) {
$odd = true; $odd = true;
for ($i = 0; $i < sizeof($columns[$modules[$m]]); $i++) { for ($i = 0; $i < sizeof($columns[$modules[$m]]); $i++) {
$required = false; $required = false;
if (isset($columns[$modules[$m]][$i]['required']) && ($columns[$modules[$m]][$i]['required'] == true)) { if (isset($columns[$modules[$m]][$i]['required']) && ($columns[$modules[$m]][$i]['required'] === true)) {
$required = true; $required = true;
} }
$rowCells = array(); $rowCells = array();