mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-27 03:42:40 +00:00
Merge branch 'master' of https://github.com/phpseclib/phpseclib into pmexts
This commit is contained in:
commit
06779a92de
@ -6,7 +6,7 @@ MIT-licensed pure-PHP implementations of an arbitrary-precision integer
|
||||
arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
|
||||
AES, SSH-1, SSH-2, SFTP, and X.509
|
||||
|
||||
* [Download (0.3.0)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.0.zip/download)
|
||||
* [Download (0.3.1)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.1.zip/download)
|
||||
* [Browse Git](https://github.com/phpseclib/phpseclib)
|
||||
* [Documentation](http://phpseclib.sourceforge.net/)
|
||||
* [Support](http://www.frostjedi.com/phpbb/viewforum.php?f=46)
|
||||
|
@ -723,7 +723,7 @@ class Crypt_DES {
|
||||
mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
|
||||
}
|
||||
|
||||
return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
|
||||
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
||||
}
|
||||
|
||||
if (!is_array($this->keys)) {
|
||||
@ -937,7 +937,7 @@ class Crypt_DES {
|
||||
if (($length & 7) == 0) {
|
||||
return $text;
|
||||
} else {
|
||||
user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
|
||||
$this->_handle_error("The plaintext's length ($length) is not a multiple of the block size (8)");
|
||||
$this->padding = true;
|
||||
}
|
||||
}
|
||||
@ -1289,6 +1289,24 @@ class Crypt_DES {
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Handler
|
||||
*
|
||||
* Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined.
|
||||
* Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions.
|
||||
*
|
||||
* @param String $string
|
||||
* @access private
|
||||
*/
|
||||
function _handle_error($err_msg) {
|
||||
if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) {
|
||||
$class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception';
|
||||
throw(new $class($err_msg));
|
||||
} else {
|
||||
user_error($err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
|
@ -1166,7 +1166,8 @@ class Crypt_RSA {
|
||||
xml_set_object($xml, $this);
|
||||
xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler');
|
||||
xml_set_character_data_handler($xml, '_data_handler');
|
||||
if (!xml_parse($xml, $key)) {
|
||||
// add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
|
||||
if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1763,7 +1764,7 @@ class Crypt_RSA {
|
||||
{
|
||||
$x = $x->toBytes();
|
||||
if (strlen($x) > $xLen) {
|
||||
user_error('Integer too large', E_USER_NOTICE);
|
||||
$this->_handle_error('Integer too large');
|
||||
return false;
|
||||
}
|
||||
return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
|
||||
@ -1925,7 +1926,7 @@ class Crypt_RSA {
|
||||
function _rsaep($m)
|
||||
{
|
||||
if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
|
||||
user_error('Message representative out of range', E_USER_NOTICE);
|
||||
$this->_handle_error('Message representative out of range');
|
||||
return false;
|
||||
}
|
||||
return $this->_exponentiate($m);
|
||||
@ -1943,7 +1944,7 @@ class Crypt_RSA {
|
||||
function _rsadp($c)
|
||||
{
|
||||
if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {
|
||||
user_error('Ciphertext representative out of range', E_USER_NOTICE);
|
||||
$this->_handle_error('Ciphertext representative out of range');
|
||||
return false;
|
||||
}
|
||||
return $this->_exponentiate($c);
|
||||
@ -1961,7 +1962,7 @@ class Crypt_RSA {
|
||||
function _rsasp1($m)
|
||||
{
|
||||
if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
|
||||
user_error('Message representative out of range', E_USER_NOTICE);
|
||||
$this->_handle_error('Message representative out of range');
|
||||
return false;
|
||||
}
|
||||
return $this->_exponentiate($m);
|
||||
@ -1979,7 +1980,7 @@ class Crypt_RSA {
|
||||
function _rsavp1($s)
|
||||
{
|
||||
if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {
|
||||
user_error('Signature representative out of range', E_USER_NOTICE);
|
||||
$this->_handle_error('Signature representative out of range');
|
||||
return false;
|
||||
}
|
||||
return $this->_exponentiate($s);
|
||||
@ -2030,7 +2031,7 @@ class Crypt_RSA {
|
||||
// be output.
|
||||
|
||||
if ($mLen > $this->k - 2 * $this->hLen - 2) {
|
||||
user_error('Message too long', E_USER_NOTICE);
|
||||
$this->_handle_error('Message too long');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2091,7 +2092,7 @@ class Crypt_RSA {
|
||||
// be output.
|
||||
|
||||
if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
|
||||
user_error('Decryption error', E_USER_NOTICE);
|
||||
$this->_handle_error('Decryption error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2100,7 +2101,7 @@ class Crypt_RSA {
|
||||
$c = $this->_os2ip($c);
|
||||
$m = $this->_rsadp($c);
|
||||
if ($m === false) {
|
||||
user_error('Decryption error', E_USER_NOTICE);
|
||||
$this->_handle_error('Decryption error');
|
||||
return false;
|
||||
}
|
||||
$em = $this->_i2osp($m, $this->k);
|
||||
@ -2118,12 +2119,12 @@ class Crypt_RSA {
|
||||
$lHash2 = substr($db, 0, $this->hLen);
|
||||
$m = substr($db, $this->hLen);
|
||||
if ($lHash != $lHash2) {
|
||||
user_error('Decryption error', E_USER_NOTICE);
|
||||
$this->_handle_error('Decryption error');
|
||||
return false;
|
||||
}
|
||||
$m = ltrim($m, chr(0));
|
||||
if (ord($m[0]) != 1) {
|
||||
user_error('Decryption error', E_USER_NOTICE);
|
||||
$this->_handle_error('Decryption error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2148,7 +2149,7 @@ class Crypt_RSA {
|
||||
// Length checking
|
||||
|
||||
if ($mLen > $this->k - 11) {
|
||||
user_error('Message too long', E_USER_NOTICE);
|
||||
$this->_handle_error('Message too long');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2192,7 +2193,7 @@ class Crypt_RSA {
|
||||
// Length checking
|
||||
|
||||
if (strlen($c) != $this->k) { // or if k < 11
|
||||
user_error('Decryption error', E_USER_NOTICE);
|
||||
$this->_handle_error('Decryption error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2202,7 +2203,7 @@ class Crypt_RSA {
|
||||
$m = $this->_rsadp($c);
|
||||
|
||||
if ($m === false) {
|
||||
user_error('Decryption error', E_USER_NOTICE);
|
||||
$this->_handle_error('Decryption error');
|
||||
return false;
|
||||
}
|
||||
$em = $this->_i2osp($m, $this->k);
|
||||
@ -2210,7 +2211,7 @@ class Crypt_RSA {
|
||||
// EME-PKCS1-v1_5 decoding
|
||||
|
||||
if (ord($em[0]) != 0 || ord($em[1]) > 2) {
|
||||
user_error('Decryption error', E_USER_NOTICE);
|
||||
$this->_handle_error('Decryption error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2218,7 +2219,7 @@ class Crypt_RSA {
|
||||
$m = substr($em, strlen($ps) + 3);
|
||||
|
||||
if (strlen($ps) < 8) {
|
||||
user_error('Decryption error', E_USER_NOTICE);
|
||||
$this->_handle_error('Decryption error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2246,7 +2247,7 @@ class Crypt_RSA {
|
||||
|
||||
$mHash = $this->hash->hash($m);
|
||||
if ($emLen < $this->hLen + $sLen + 2) {
|
||||
user_error('Encoding error', E_USER_NOTICE);
|
||||
$this->_handle_error('Encoding error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2351,7 +2352,7 @@ class Crypt_RSA {
|
||||
// Length checking
|
||||
|
||||
if (strlen($s) != $this->k) {
|
||||
user_error('Invalid signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid signature');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2362,12 +2363,12 @@ class Crypt_RSA {
|
||||
$s2 = $this->_os2ip($s);
|
||||
$m2 = $this->_rsavp1($s2);
|
||||
if ($m2 === false) {
|
||||
user_error('Invalid signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid signature');
|
||||
return false;
|
||||
}
|
||||
$em = $this->_i2osp($m2, $modBits >> 3);
|
||||
if ($em === false) {
|
||||
user_error('Invalid signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid signature');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2417,7 +2418,7 @@ class Crypt_RSA {
|
||||
$tLen = strlen($t);
|
||||
|
||||
if ($emLen < $tLen + 11) {
|
||||
user_error('Intended encoded message length too short', E_USER_NOTICE);
|
||||
$this->_handle_error('Intended encoded message length too short');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2443,7 +2444,7 @@ class Crypt_RSA {
|
||||
|
||||
$em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
|
||||
if ($em === false) {
|
||||
user_error('RSA modulus too short', E_USER_NOTICE);
|
||||
$this->_handle_error('RSA modulus too short');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2472,7 +2473,7 @@ class Crypt_RSA {
|
||||
// Length checking
|
||||
|
||||
if (strlen($s) != $this->k) {
|
||||
user_error('Invalid signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid signature');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2481,12 +2482,12 @@ class Crypt_RSA {
|
||||
$s = $this->_os2ip($s);
|
||||
$m2 = $this->_rsavp1($s);
|
||||
if ($m2 === false) {
|
||||
user_error('Invalid signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid signature');
|
||||
return false;
|
||||
}
|
||||
$em = $this->_i2osp($m2, $this->k);
|
||||
if ($em === false) {
|
||||
user_error('Invalid signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid signature');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2494,12 +2495,11 @@ class Crypt_RSA {
|
||||
|
||||
$em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
|
||||
if ($em2 === false) {
|
||||
user_error('RSA modulus too short', E_USER_NOTICE);
|
||||
$this->_handle_error('RSA modulus too short');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare
|
||||
|
||||
return $this->_equals($em, $em2);
|
||||
}
|
||||
|
||||
@ -2587,6 +2587,8 @@ class Crypt_RSA {
|
||||
}
|
||||
|
||||
$ciphertext = str_split($ciphertext, $this->k);
|
||||
$ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $this->k, chr(0), STR_PAD_LEFT);
|
||||
|
||||
$plaintext = '';
|
||||
|
||||
switch ($this->encryptionMode) {
|
||||
@ -2655,4 +2657,22 @@ class Crypt_RSA {
|
||||
return $this->_rsassa_pss_verify($message, $signature);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Handler
|
||||
*
|
||||
* Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined.
|
||||
* Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions.
|
||||
*
|
||||
* @param String $string
|
||||
* @access private
|
||||
*/
|
||||
function _handle_error($err_msg) {
|
||||
if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) {
|
||||
$class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception';
|
||||
throw(new $class($err_msg));
|
||||
} else {
|
||||
user_error($err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -582,7 +582,7 @@ class Crypt_Rijndael {
|
||||
*
|
||||
* Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
|
||||
* {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
|
||||
* $hash, $salt, $count
|
||||
* $hash, $salt, $method
|
||||
* Set $dkLen by calling setKeyLength()
|
||||
*
|
||||
* @param String $password
|
||||
@ -601,7 +601,7 @@ class Crypt_Rijndael {
|
||||
}
|
||||
// WPA and WPA use the SSID as the salt
|
||||
if (!isset($salt)) {
|
||||
$salt = 'phpseclib/salt';
|
||||
$salt = 'phpseclib';
|
||||
}
|
||||
// RFC2898#section-4.2 uses 1,000 iterations by default
|
||||
// WPA and WPA2 use 4,096.
|
||||
@ -1365,7 +1365,7 @@ class Crypt_Rijndael {
|
||||
if ($length % $this->block_size == 0) {
|
||||
return $text;
|
||||
} else {
|
||||
user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})", E_USER_NOTICE);
|
||||
$this->_handle_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
|
||||
$this->padding = true;
|
||||
}
|
||||
}
|
||||
@ -1472,7 +1472,25 @@ class Crypt_Rijndael {
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Handler
|
||||
*
|
||||
* Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined.
|
||||
* Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions.
|
||||
*
|
||||
* @param String $string
|
||||
* @access private
|
||||
*/
|
||||
function _handle_error($err_msg) {
|
||||
if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) {
|
||||
$class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception';
|
||||
throw(new $class($err_msg));
|
||||
} else {
|
||||
user_error($err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
||||
// vim6: fdl=1:
|
@ -265,6 +265,7 @@ class Crypt_TripleDES {
|
||||
new Crypt_DES(CRYPT_DES_MODE_CBC),
|
||||
new Crypt_DES(CRYPT_DES_MODE_CBC)
|
||||
);
|
||||
$this->paddable = true;
|
||||
|
||||
// we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
|
||||
$this->des[0]->disablePadding();
|
||||
|
@ -409,7 +409,7 @@ class File_ANSI {
|
||||
case 47: $back = 'white'; break;
|
||||
|
||||
default:
|
||||
user_error('Unsupported attribute: ' . $mod);
|
||||
$this->_handle_error('Unsupported attribute: ' . $mod);
|
||||
$this->ansi = '';
|
||||
break 2;
|
||||
}
|
||||
@ -537,4 +537,22 @@ class File_ANSI {
|
||||
|
||||
return '<pre style="color: white; background: black" width="' . ($this->max_x + 1) . '">' . $scrollback . '</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Handler
|
||||
*
|
||||
* Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined.
|
||||
* Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions.
|
||||
*
|
||||
* @param String $string
|
||||
* @access private
|
||||
*/
|
||||
function _handle_error($err_msg) {
|
||||
if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) {
|
||||
$class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception';
|
||||
throw(new $class($err_msg));
|
||||
} else {
|
||||
user_error($err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -959,7 +959,7 @@ class File_ASN1 {
|
||||
case FILE_ASN1_TYPE_OBJECT_IDENTIFIER:
|
||||
$oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
|
||||
if ($oid === false) {
|
||||
user_error('Invalid OID', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid OID');
|
||||
return false;
|
||||
}
|
||||
$value = '';
|
||||
@ -1012,7 +1012,7 @@ class File_ASN1 {
|
||||
$filters = $filters[$part];
|
||||
}
|
||||
if ($filters === false) {
|
||||
user_error('No filters defined for ' . implode('/', $loc), E_USER_NOTICE);
|
||||
$this->_handle_error('No filters defined for ' . implode('/', $loc));
|
||||
return false;
|
||||
}
|
||||
return $this->_encode_der($source, $filters + $mapping);
|
||||
@ -1036,7 +1036,7 @@ class File_ASN1 {
|
||||
$value = $source ? "\xFF" : "\x00";
|
||||
break;
|
||||
default:
|
||||
user_error('Mapping provides no type definition for ' . implode('/', $this->location), E_USER_NOTICE);
|
||||
$this->_handle_error('Mapping provides no type definition for ' . implode('/', $this->location));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1188,7 +1188,6 @@ class File_ASN1 {
|
||||
* @return String
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function convert($in, $from = FILE_ASN1_TYPE_UTF8_STRING, $to = FILE_ASN1_TYPE_UTF8_STRING)
|
||||
{
|
||||
if (!isset($this->stringTypeSize[$from]) || !isset($this->stringTypeSize[$to])) {
|
||||
@ -1275,4 +1274,22 @@ class File_ASN1 {
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Handler
|
||||
*
|
||||
* Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined.
|
||||
* Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions.
|
||||
*
|
||||
* @param String $string
|
||||
* @access private
|
||||
*/
|
||||
function _handle_error($err_msg) {
|
||||
if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) {
|
||||
$class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception';
|
||||
throw(new $class($err_msg));
|
||||
} else {
|
||||
user_error($err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,15 +59,59 @@ if (!class_exists('File_ASN1')) {
|
||||
*/
|
||||
define('FILE_X509_VALIDATE_SIGNATURE_BY_CA', 1);
|
||||
|
||||
/**
|
||||
* Name format tokens for the getDN() method.
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see File_X509::getDN()
|
||||
*/
|
||||
define('FILE_X509_DN_ARRAY', 0); // Internal array representation.
|
||||
define('FILE_X509_DN_STRING', 1); // String.
|
||||
define('FILE_X509_DN_ASN1', 2); // ASN.1 Name string.
|
||||
define('FILE_X509_DN_OPENSSL', 3); // OpenSSL compatible array.
|
||||
define('FILE_X509_DN_CANON', 4); // Canonical ASN.1 RDNs string.
|
||||
define('FILE_X509_DN_HASH', 5); // Name hash for file indexing.
|
||||
/**
|
||||
* Return internal array representation
|
||||
*/
|
||||
define('FILE_X509_DN_ARRAY', 0);
|
||||
/**
|
||||
* Return string
|
||||
*/
|
||||
define('FILE_X509_DN_STRING', 1);
|
||||
/**
|
||||
* Return ASN.1 name string
|
||||
*/
|
||||
define('FILE_X509_DN_ASN1', 2);
|
||||
/**
|
||||
* Return OpenSSL compatible array
|
||||
*/
|
||||
define('FILE_X509_DN_OPENSSL', 3);
|
||||
/**
|
||||
* Return canonical ASN.1 RDNs string
|
||||
*/
|
||||
define('FILE_X509_DN_CANON', 4);
|
||||
/**
|
||||
* Return name hash for file indexing
|
||||
*/
|
||||
define('FILE_X509_DN_HASH', 5);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see File_X509::saveX509()
|
||||
* @see File_X509::saveCSR()
|
||||
* @see File_X509::saveCRL()
|
||||
*/
|
||||
/**
|
||||
* Save as PEM
|
||||
*
|
||||
* ie. a base64-encoded PEM with a header and a footer
|
||||
*/
|
||||
define('FILE_X509_FORMAT_PEM', 0);
|
||||
/**
|
||||
* Save as DER
|
||||
*/
|
||||
define('FILE_X509_FORMAT_DER', 1);
|
||||
/**
|
||||
* Save as a SPKAC
|
||||
*
|
||||
* Only works on CSRs. Not currently supported.
|
||||
*/
|
||||
define('FILE_X509_FORMAT_SPKAC', 2);
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Attribute value disposition.
|
||||
@ -81,7 +125,7 @@ define('FILE_X509_ATTR_REPLACE', -3); // Clear first, then add a value.
|
||||
* Pure-PHP X.509 Parser
|
||||
*
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @version 0.3.0
|
||||
* @version 0.3.1
|
||||
* @access public
|
||||
* @package File_X509
|
||||
*/
|
||||
@ -1356,9 +1400,20 @@ class File_X509 {
|
||||
function loadX509($cert)
|
||||
{
|
||||
if (is_array($cert) && isset($cert['tbsCertificate'])) {
|
||||
unset($this->currentCert);
|
||||
unset($this->currentKeyIdentifier);
|
||||
$this->dn = $cert['tbsCertificate']['subject'];
|
||||
if (!isset($this->dn)) {
|
||||
return false;
|
||||
}
|
||||
$this->currentCert = $cert;
|
||||
|
||||
$currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier');
|
||||
$this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : NULL;
|
||||
|
||||
unset($this->signatureSubject);
|
||||
return false;
|
||||
|
||||
return $cert;
|
||||
}
|
||||
|
||||
$asn1 = new File_ASN1();
|
||||
@ -1370,8 +1425,11 @@ class File_X509 {
|
||||
subject=/O=organization/OU=org unit/CN=common name
|
||||
issuer=/O=organization/CN=common name
|
||||
*/
|
||||
$cert = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $cert);
|
||||
$cert = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $cert) ? base64_decode($cert) : false;
|
||||
$temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $cert);
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
|
||||
if ($temp != false) {
|
||||
$cert = $temp;
|
||||
}
|
||||
|
||||
if ($cert === false) {
|
||||
$this->currentCert = false;
|
||||
@ -1409,21 +1467,27 @@ class File_X509 {
|
||||
* Save X.509 certificate
|
||||
*
|
||||
* @param Array $cert
|
||||
* @param Integer $format optional
|
||||
* @access public
|
||||
* @return String
|
||||
*/
|
||||
function saveX509($cert)
|
||||
function saveX509($cert, $format = FILE_X509_FORMAT_PEM)
|
||||
{
|
||||
if (!is_array($cert) || !isset($cert['tbsCertificate'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($cert['tbsCertificate']['subjectPublicKeyInfo'])) {
|
||||
switch ($cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm']) {
|
||||
case 'rsaEncryption':
|
||||
$cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] =
|
||||
base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])));
|
||||
}
|
||||
switch (true) {
|
||||
// "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()"
|
||||
case !($algorithm = $this->_subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')):
|
||||
case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']):
|
||||
break;
|
||||
default:
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] =
|
||||
base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])));
|
||||
}
|
||||
}
|
||||
|
||||
$asn1 = new File_ASN1();
|
||||
@ -1455,7 +1519,13 @@ class File_X509 {
|
||||
|
||||
$cert = $asn1->encodeDER($cert, $this->Certificate);
|
||||
|
||||
return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert)) . '-----END CERTIFICATE-----';
|
||||
switch ($format) {
|
||||
case FILE_X509_FORMAT_DER:
|
||||
return $cert;
|
||||
// case FILE_X509_FORMAT_PEM:
|
||||
default:
|
||||
return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert)) . '-----END CERTIFICATE-----';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1559,7 +1629,7 @@ class File_X509 {
|
||||
$map = $this->_getMapping($id);
|
||||
if (is_bool($map)) {
|
||||
if (!$map) {
|
||||
user_error($id . ' is not a currently supported extension', E_USER_NOTICE);
|
||||
$this->_handle_error($id . ' is not a currently supported extension');
|
||||
unset($extensions[$i]);
|
||||
}
|
||||
} else {
|
||||
@ -1664,6 +1734,10 @@ class File_X509 {
|
||||
*/
|
||||
function _getMapping($extnId)
|
||||
{
|
||||
if (!is_string($extnId)) { // eg. if it's a File_ASN1_Element object
|
||||
return true;
|
||||
}
|
||||
|
||||
switch ($extnId) {
|
||||
case 'id-ce-keyUsage':
|
||||
return $this->KeyUsage;
|
||||
@ -1756,8 +1830,18 @@ class File_X509 {
|
||||
*/
|
||||
function loadCA($cert)
|
||||
{
|
||||
$olddn = $this->dn;
|
||||
$oldcert = $this->currentCert;
|
||||
$oldsigsubj = $this->signatureSubject;
|
||||
$oldkeyid = $this->currentKeyIdentifier;
|
||||
|
||||
$cert = $this->loadX509($cert);
|
||||
if (!$cert) {
|
||||
$this->dn = $olddn;
|
||||
$this->currentCert = $oldcert;
|
||||
$this->signatureSubject = $oldsigsubj;
|
||||
$this->currentKeyIdentifier = $oldkeyid;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1786,8 +1870,10 @@ class File_X509 {
|
||||
//}
|
||||
|
||||
$this->CAs[] = $cert;
|
||||
unset($this->currentCert);
|
||||
unset($this->signatureSubject);
|
||||
|
||||
$this->dn = $olddn;
|
||||
$this->currentCert = $oldcert;
|
||||
$this->signatureSubject = $oldsigsubj;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1895,9 +1981,7 @@ class File_X509 {
|
||||
* Validate a signature
|
||||
*
|
||||
* Works on X.509 certs, CSR's and CRL's.
|
||||
* Returns 1 if the signature is verified, 0 if it is not correct or -1 on error
|
||||
*
|
||||
* To know if a signature is valid one should do validateSignature() === 1
|
||||
* Returns true if the signature is verified, false if it is not correct or NULL on error
|
||||
*
|
||||
* The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}.
|
||||
*
|
||||
@ -1947,10 +2031,10 @@ class File_X509 {
|
||||
}
|
||||
}
|
||||
if (count($this->CAs) == $i && ($options & FILE_X509_VALIDATE_SIGNATURE_BY_CA)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
} elseif (!isset($signingCert) || ($options & FILE_X509_VALIDATE_SIGNATURE_BY_CA)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return $this->_validateSignature(
|
||||
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
|
||||
@ -1984,7 +2068,7 @@ class File_X509 {
|
||||
}
|
||||
}
|
||||
if (!isset($signingCert)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return $this->_validateSignature(
|
||||
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
|
||||
@ -1994,14 +2078,14 @@ class File_X509 {
|
||||
$this->signatureSubject
|
||||
);
|
||||
default:
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a signature
|
||||
*
|
||||
* Returns 1 if the signature is verified, 0 if it is not correct or -1 on error
|
||||
* Returns true if the signature is verified, false if it is not correct or NULL on error
|
||||
*
|
||||
* @param String $publicKeyAlgorithm
|
||||
* @param String $publicKey
|
||||
@ -2033,18 +2117,18 @@ class File_X509 {
|
||||
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
||||
|
||||
if (!@$rsa->verify($signatureSubject, $signature)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2328,7 +2412,7 @@ class File_X509 {
|
||||
function getDN($format = FILE_X509_DN_ARRAY, $dn = NULL)
|
||||
{
|
||||
if (!isset($dn)) {
|
||||
$dn = $this->dn;
|
||||
$dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn;
|
||||
}
|
||||
|
||||
switch ((int) $format) {
|
||||
@ -2480,7 +2564,7 @@ class File_X509 {
|
||||
return $this->getDN($format, $this->currentCert['tbsCertList']['issuer']);
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2504,7 +2588,7 @@ class File_X509 {
|
||||
return $this->getDN($format, $this->currentCert['certificationRequestInfo']['subject']);
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2526,7 +2610,7 @@ class File_X509 {
|
||||
return $this->getDNProp($propname, $this->currentCert['tbsCertList']['issuer'], $withType);
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2550,7 +2634,52 @@ class File_X509 {
|
||||
return $this->getDNProp($propname, $this->currentCert['certificationRequestInfo']['subject'], $withType);
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the certificate chain for the current cert
|
||||
*
|
||||
* @access public
|
||||
* @return Mixed
|
||||
*/
|
||||
function getChain()
|
||||
{
|
||||
$chain = array($this->currentCert);
|
||||
|
||||
if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) {
|
||||
return false;
|
||||
}
|
||||
if (empty($this->CAs)) {
|
||||
return $chain;
|
||||
}
|
||||
while (true) {
|
||||
$currentCert = $chain[count($chain) - 1];
|
||||
for ($i = 0; $i < count($this->CAs); $i++) {
|
||||
$ca = $this->CAs[$i];
|
||||
if ($currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) {
|
||||
$authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier', $currentCert);
|
||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
||||
switch (true) {
|
||||
case !is_array($authorityKey):
|
||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||
if ($currentCert === $ca) {
|
||||
break 3;
|
||||
}
|
||||
$chain[] = $ca;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($i == count($this->CAs)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($chain as $key=>$value) {
|
||||
$chain[$key] = new File_X509();
|
||||
$chain[$key]->loadX509($value);
|
||||
}
|
||||
return $chain;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2633,12 +2762,29 @@ class File_X509 {
|
||||
*/
|
||||
function loadCSR($csr)
|
||||
{
|
||||
if (is_array($csr) && isset($csr['certificationRequestInfo'])) {
|
||||
unset($this->currentCert);
|
||||
unset($this->currentKeyIdentifier);
|
||||
$this->dn = $csr['certificationRequestInfo']['subject'];
|
||||
if (!isset($this->dn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->currentCert = $csr;
|
||||
unset($this->signatureSubject);
|
||||
return $csr;
|
||||
}
|
||||
|
||||
// see http://tools.ietf.org/html/rfc2986
|
||||
|
||||
$asn1 = new File_ASN1();
|
||||
|
||||
$csr = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $csr);
|
||||
$orig = $csr = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $csr) ? base64_decode($csr) : false;
|
||||
$temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $csr);
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
|
||||
if ($temp != false) {
|
||||
$csr = $temp;
|
||||
}
|
||||
$orig = $csr;
|
||||
|
||||
if ($csr === false) {
|
||||
$this->currentCert = false;
|
||||
@ -2691,19 +2837,26 @@ class File_X509 {
|
||||
* Save CSR request
|
||||
*
|
||||
* @param Array $csr
|
||||
* @param Integer $format optional
|
||||
* @access public
|
||||
* @return String
|
||||
*/
|
||||
function saveCSR($csr)
|
||||
function saveCSR($csr, $format = FILE_X509_FORMAT_PEM)
|
||||
{
|
||||
if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm']) {
|
||||
case 'rsaEncryption':
|
||||
$csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] =
|
||||
base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])));
|
||||
switch (true) {
|
||||
case !($algorithm = $this->_subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')):
|
||||
case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']);
|
||||
break;
|
||||
default:
|
||||
switch ($algorithm) {
|
||||
case 'rsaEncryption':
|
||||
$csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] =
|
||||
base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])));
|
||||
}
|
||||
}
|
||||
|
||||
$asn1 = new File_ASN1();
|
||||
@ -2719,7 +2872,13 @@ class File_X509 {
|
||||
$this->_mapOutAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
|
||||
$csr = $asn1->encodeDER($csr, $this->CertificationRequest);
|
||||
|
||||
return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr)) . '-----END CERTIFICATE REQUEST-----';
|
||||
switch ($format) {
|
||||
case FILE_X509_FORMAT_DER:
|
||||
return $csr;
|
||||
// case FILE_X509_FORMAT_PEM:
|
||||
default:
|
||||
return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr)) . '-----END CERTIFICATE REQUEST-----';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2731,10 +2890,20 @@ class File_X509 {
|
||||
*/
|
||||
function loadCRL($crl)
|
||||
{
|
||||
if (is_array($crl) && isset($crl['tbsCertList'])) {
|
||||
$this->currentCert = $crl;
|
||||
unset($this->signatureSubject);
|
||||
return $crl;
|
||||
}
|
||||
|
||||
$asn1 = new File_ASN1();
|
||||
|
||||
$crl = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]#', '', $crl);
|
||||
$orig = $crl = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $crl) ? base64_decode($crl) : false;
|
||||
$temp = preg_replace('#^(?:[^-].+[\r\n]+)+|-.+-|[\r\n]| #', '', $crl);
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
|
||||
if ($temp != false) {
|
||||
$crl = $temp;
|
||||
}
|
||||
$orig = $crl;
|
||||
|
||||
if ($crl === false) {
|
||||
$this->currentCert = false;
|
||||
@ -2775,10 +2944,11 @@ class File_X509 {
|
||||
* Save Certificate Revocation List.
|
||||
*
|
||||
* @param Array $crl
|
||||
* @param Integer $format optional
|
||||
* @access public
|
||||
* @return String
|
||||
*/
|
||||
function saveCRL($crl)
|
||||
function saveCRL($crl, $format = FILE_X509_FORMAT_PEM)
|
||||
{
|
||||
if (!is_array($crl) || !isset($crl['tbsCertList'])) {
|
||||
return false;
|
||||
@ -2816,7 +2986,13 @@ class File_X509 {
|
||||
|
||||
$crl = $asn1->encodeDER($crl, $this->CertificateList);
|
||||
|
||||
return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl)) . '-----END X509 CRL-----';
|
||||
switch ($format) {
|
||||
case FILE_X509_FORMAT_DER:
|
||||
return $crl;
|
||||
// case FILE_X509_FORMAT_PEM:
|
||||
default:
|
||||
return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl)) . '-----END X509 CRL-----';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3077,8 +3253,7 @@ class File_X509 {
|
||||
|
||||
if (!empty($this->endDate)) {
|
||||
$tbsCertList['nextUpdate'] = array('generalTime' => $this->endDate); // $this->setEndDate()
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
unset($tbsCertList['nextUpdate']);
|
||||
}
|
||||
|
||||
@ -3088,7 +3263,7 @@ class File_X509 {
|
||||
else {
|
||||
$crlNumber = $this->getExtension('id-ce-cRLNumber');
|
||||
$crlNumber = $crlNumber !== false ? $crlNumber->add(new Math_BigInteger(1)) : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
$this->removeExtension('id-ce-authorityKeyIdentifier');
|
||||
$this->removeExtension('id-ce-issuerAltName');
|
||||
@ -3705,10 +3880,10 @@ class File_X509 {
|
||||
/**
|
||||
* Compute a public key identifier.
|
||||
*
|
||||
* Although key identifiers may be set to any unique value, this function
|
||||
* Although key identifiers may be set to any unique value, this function
|
||||
* computes key identifiers from public key according to the two
|
||||
* recommended methods (4.2.1.2 RFC 3280).
|
||||
* Highly polymorphic: try to accept all possible forms of key:
|
||||
* Highly polymorphic: try to accept all possible forms of key:
|
||||
* - Key object
|
||||
* - File_X509 object with public or private key defined
|
||||
* - Certificate or CSR array
|
||||
@ -3776,7 +3951,7 @@ class File_X509 {
|
||||
$hash[0] = chr((ord($hash[0]) & 0x0F) | 0x40);
|
||||
}
|
||||
|
||||
return $hash;
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3839,7 +4014,6 @@ class File_X509 {
|
||||
* @access private
|
||||
* @return Integer or false
|
||||
*/
|
||||
|
||||
function _revokedCertificate(&$rclist, $serial, $create = false)
|
||||
{
|
||||
$serial = new Math_BigInteger($serial);
|
||||
@ -3945,7 +4119,7 @@ class File_X509 {
|
||||
|
||||
$result = array();
|
||||
|
||||
if (!is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) {
|
||||
if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) {
|
||||
foreach ($rclist as $rc) {
|
||||
$result[] = $rc['userCertificate']->toString();
|
||||
}
|
||||
@ -4045,4 +4219,22 @@ class File_X509 {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Handler
|
||||
*
|
||||
* Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined.
|
||||
* Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions.
|
||||
*
|
||||
* @param String $string
|
||||
* @access private
|
||||
*/
|
||||
function _handle_error($err_msg) {
|
||||
if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) {
|
||||
$class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception';
|
||||
throw(new $class($err_msg));
|
||||
} else {
|
||||
user_error($err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_VERSION) {
|
||||
user_error('Expected SSH_FXP_VERSION', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_VERSION');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -588,7 +588,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -645,7 +645,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -655,7 +655,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -731,7 +731,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -780,7 +780,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
}
|
||||
break 2;
|
||||
default:
|
||||
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -793,7 +793,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -996,7 +996,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
return false;
|
||||
}
|
||||
|
||||
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1089,7 +1089,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
*/
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1116,7 +1116,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
return false;
|
||||
}
|
||||
|
||||
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1249,7 +1249,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1288,7 +1288,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1365,7 +1365,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1374,7 +1374,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
|
||||
if ($mode & NET_SFTP_LOCAL_FILE) {
|
||||
if (!is_file($data)) {
|
||||
user_error("$data is not a valid file", E_USER_NOTICE);
|
||||
$this->_handle_error("$data is not a valid file");
|
||||
return false;
|
||||
}
|
||||
$fp = @fopen($data, 'rb');
|
||||
@ -1425,7 +1425,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1453,7 +1453,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
while ($i--) {
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1504,7 +1504,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1542,7 +1542,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
$this->_logError($response);
|
||||
break 2;
|
||||
default:
|
||||
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
|
||||
if ($local_file !== false) {
|
||||
fclose($fp);
|
||||
}
|
||||
@ -1560,7 +1560,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1604,7 +1604,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1723,7 +1723,7 @@ class Net_SFTP extends Net_SSH2 {
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
if ($this->packet_type != NET_SFTP_STATUS) {
|
||||
user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -428,7 +428,7 @@ class Net_SSH1 {
|
||||
* @var Array
|
||||
* @access private
|
||||
*/
|
||||
var $interactive_buffer = '';
|
||||
var $interactiveBuffer = '';
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
@ -467,7 +467,7 @@ class Net_SSH1 {
|
||||
|
||||
$this->fsock = @fsockopen($host, $port, $errno, $errstr, $timeout);
|
||||
if (!$this->fsock) {
|
||||
user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"), E_USER_NOTICE);
|
||||
$this->_handle_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -484,11 +484,11 @@ class Net_SSH1 {
|
||||
}
|
||||
|
||||
if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) {
|
||||
user_error('Can only connect to SSH servers', E_USER_NOTICE);
|
||||
$this->_handle_error('Can only connect to SSH servers');
|
||||
return;
|
||||
}
|
||||
if ($parts[1][0] != 1) {
|
||||
user_error("Cannot connect to SSH $parts[1] servers", E_USER_NOTICE);
|
||||
$this->_handle_error("Cannot connect to SSH $parts[1] servers");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -496,7 +496,7 @@ class Net_SSH1 {
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
|
||||
user_error('Expected SSH_SMSG_PUBLIC_KEY', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_SMSG_PUBLIC_KEY');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -584,7 +584,7 @@ class Net_SSH1 {
|
||||
$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)) {
|
||||
user_error('Error sending SSH_CMSG_SESSION_KEY', E_USER_NOTICE);
|
||||
$this->_handle_error('Error sending SSH_CMSG_SESSION_KEY');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -614,7 +614,7 @@ class Net_SSH1 {
|
||||
$response = $this->_get_binary_packet();
|
||||
|
||||
if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
|
||||
user_error('Expected SSH_SMSG_SUCCESS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_SMSG_SUCCESS');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -638,7 +638,7 @@ class Net_SSH1 {
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_USER', E_USER_NOTICE);
|
||||
$this->_handle_error('Error sending SSH_CMSG_USER');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -648,14 +648,14 @@ class Net_SSH1 {
|
||||
$this->bitmap |= NET_SSH1_MASK_LOGIN;
|
||||
return true;
|
||||
} else if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
|
||||
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_AUTH_PASSWORD', E_USER_NOTICE);
|
||||
$this->_handle_error('Error sending SSH_CMSG_AUTH_PASSWORD');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -673,7 +673,7 @@ class Net_SSH1 {
|
||||
} else if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
|
||||
return false;
|
||||
} else {
|
||||
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -701,14 +701,14 @@ class Net_SSH1 {
|
||||
function exec($cmd, $block = true)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {
|
||||
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
||||
$this->_handle_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_EXEC_CMD', E_USER_NOTICE);
|
||||
$this->_handle_error('Error sending SSH_CMSG_EXEC_CMD');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -753,21 +753,21 @@ class Net_SSH1 {
|
||||
$data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, NET_SSH1_TTY_OP_END);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_REQUEST_PTY', E_USER_NOTICE);
|
||||
$this->_handle_error('Error sending SSH_CMSG_REQUEST_PTY');
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
|
||||
if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
|
||||
user_error('Expected SSH_SMSG_SUCCESS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_SMSG_SUCCESS');
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = pack('C', NET_SSH1_CMSG_EXEC_SHELL);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_EXEC_SHELL', E_USER_NOTICE);
|
||||
$this->_handle_error('Error sending SSH_CMSG_EXEC_SHELL');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -806,12 +806,12 @@ class Net_SSH1 {
|
||||
function read($expect, $mode = NET_SSH1_READ_SIMPLE)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {
|
||||
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
||||
$this->_handle_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) {
|
||||
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
||||
$this->_handle_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -841,19 +841,19 @@ class Net_SSH1 {
|
||||
function interactiveWrite($cmd)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {
|
||||
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
||||
$this->_handle_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) {
|
||||
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
||||
$this->_handle_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_STDIN', E_USER_NOTICE);
|
||||
$this->_handle_error('Error sending SSH_CMSG_STDIN');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -876,12 +876,12 @@ class Net_SSH1 {
|
||||
function interactiveRead()
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {
|
||||
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
||||
$this->_handle_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) {
|
||||
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
||||
$this->_handle_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -960,7 +960,7 @@ class Net_SSH1 {
|
||||
function _get_binary_packet()
|
||||
{
|
||||
if (feof($this->fsock)) {
|
||||
//user_error('connection closed prematurely', E_USER_NOTICE);
|
||||
//$this->_handle_error('connection closed prematurely');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -984,7 +984,7 @@ class Net_SSH1 {
|
||||
$temp = unpack('Ncrc', substr($raw, -4));
|
||||
|
||||
//if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) {
|
||||
// user_error('Bad CRC in packet from server', E_USER_NOTICE);
|
||||
// $this->_handle_error('Bad CRC in packet from server');
|
||||
// return false;
|
||||
//}
|
||||
|
||||
@ -1017,7 +1017,7 @@ class Net_SSH1 {
|
||||
*/
|
||||
function _send_binary_packet($data) {
|
||||
if (feof($this->fsock)) {
|
||||
//user_error('connection closed prematurely', E_USER_NOTICE);
|
||||
//$this->_handle_error('connection closed prematurely');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1418,4 +1418,22 @@ class Net_SSH1 {
|
||||
{
|
||||
return rtrim($this->server_identification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Handler
|
||||
*
|
||||
* Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined.
|
||||
* Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions.
|
||||
*
|
||||
* @param String $string
|
||||
* @access private
|
||||
*/
|
||||
function _handle_error($err_msg) {
|
||||
if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) {
|
||||
$class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception';
|
||||
throw(new $class($err_msg));
|
||||
} else {
|
||||
user_error($err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -699,6 +699,13 @@ class Net_SSH2 {
|
||||
*/
|
||||
var $quiet_mode = false;
|
||||
|
||||
/**
|
||||
* Time of first network activity
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $last_packet;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
@ -712,6 +719,7 @@ class Net_SSH2 {
|
||||
*/
|
||||
function Net_SSH2($host, $port = 22, $timeout = 10)
|
||||
{
|
||||
$this->last_packet = strtok(microtime(), ' ') + strtok(''); // == microtime(true) in PHP5
|
||||
$this->message_numbers = array(
|
||||
1 => 'NET_SSH2_MSG_DISCONNECT',
|
||||
2 => 'NET_SSH2_MSG_IGNORE',
|
||||
@ -785,7 +793,7 @@ class Net_SSH2 {
|
||||
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
||||
$this->fsock = @fsockopen($host, $port, $errno, $errstr, $timeout);
|
||||
if (!$this->fsock) {
|
||||
user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"), E_USER_NOTICE);
|
||||
$this->_handle_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
|
||||
return;
|
||||
}
|
||||
$elapsed = strtok(microtime(), ' ') + strtok('') - $start;
|
||||
@ -793,7 +801,7 @@ class Net_SSH2 {
|
||||
$timeout-= $elapsed;
|
||||
|
||||
if ($timeout <= 0) {
|
||||
user_error(rtrim("Cannot connect to $host. Timeout error"), E_USER_NOTICE);
|
||||
$this->_handle_error(rtrim("Cannot connect to $host. Timeout error"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -806,7 +814,7 @@ class Net_SSH2 {
|
||||
// on windows this returns a "Warning: Invalid CRT parameters detected" error
|
||||
// the !count() is done as a workaround for <https://bugs.php.net/42682>
|
||||
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
|
||||
user_error(rtrim("Cannot connect to $host. Banner timeout"), E_USER_NOTICE);
|
||||
$this->_handle_error(rtrim("Cannot connect to $host. Banner timeout"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -828,7 +836,7 @@ class Net_SSH2 {
|
||||
}
|
||||
|
||||
if (feof($this->fsock)) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -862,7 +870,7 @@ class Net_SSH2 {
|
||||
}
|
||||
|
||||
if ($matches[1] != '1.99' && $matches[1] != '2.0') {
|
||||
user_error("Cannot connect to SSH $matches[1] servers", E_USER_NOTICE);
|
||||
$this->_handle_error("Cannot connect to SSH $matches[1] servers");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -870,12 +878,12 @@ class Net_SSH2 {
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return;
|
||||
}
|
||||
|
||||
if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
|
||||
user_error('Expected SSH_MSG_KEXINIT', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_MSG_KEXINIT');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1020,7 +1028,7 @@ class Net_SSH2 {
|
||||
// we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
|
||||
for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_server_to_client); $i++);
|
||||
if ($i == count($encryption_algorithms)) {
|
||||
user_error('No compatible server to client encryption algorithms found', E_USER_NOTICE);
|
||||
$this->_handle_error('No compatible server to client encryption algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
@ -1057,7 +1065,7 @@ class Net_SSH2 {
|
||||
|
||||
for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_client_to_server); $i++);
|
||||
if ($i == count($encryption_algorithms)) {
|
||||
user_error('No compatible client to server encryption algorithms found', E_USER_NOTICE);
|
||||
$this->_handle_error('No compatible client to server encryption algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
@ -1095,7 +1103,7 @@ class Net_SSH2 {
|
||||
// through diffie-hellman key exchange a symmetric key is obtained
|
||||
for ($i = 0; $i < count($kex_algorithms) && !in_array($kex_algorithms[$i], $this->kex_algorithms); $i++);
|
||||
if ($i == count($kex_algorithms)) {
|
||||
user_error('No compatible key exchange algorithms found', E_USER_NOTICE);
|
||||
$this->_handle_error('No compatible key exchange algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
@ -1148,19 +1156,19 @@ class Net_SSH2 {
|
||||
$data = pack('CNa*', NET_SSH2_MSG_KEXDH_INIT, strlen($eBytes), $eBytes);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
|
||||
if ($type != NET_SSH2_MSG_KEXDH_REPLY) {
|
||||
user_error('Expected SSH_MSG_KEXDH_REPLY', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_MSG_KEXDH_REPLY');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1198,12 +1206,12 @@ class Net_SSH2 {
|
||||
|
||||
for ($i = 0; $i < count($server_host_key_algorithms) && !in_array($server_host_key_algorithms[$i], $this->server_host_key_algorithms); $i++);
|
||||
if ($i == count($server_host_key_algorithms)) {
|
||||
user_error('No compatible server host key algorithms found', E_USER_NOTICE);
|
||||
$this->_handle_error('No compatible server host key algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
if ($public_key_format != $server_host_key_algorithms[$i] || $this->signature_format != $server_host_key_algorithms[$i]) {
|
||||
user_error('Sever Host Key Algorithm Mismatch', E_USER_NOTICE);
|
||||
$this->_handle_error('Sever Host Key Algorithm Mismatch');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
@ -1218,14 +1226,14 @@ class Net_SSH2 {
|
||||
$response = $this->_get_binary_packet();
|
||||
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
|
||||
if ($type != NET_SSH2_MSG_NEWKEYS) {
|
||||
user_error('Expected SSH_MSG_NEWKEYS', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_MSG_NEWKEYS');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1339,7 +1347,7 @@ class Net_SSH2 {
|
||||
|
||||
for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++);
|
||||
if ($i == count($mac_algorithms)) {
|
||||
user_error('No compatible client to server message authentication algorithms found', E_USER_NOTICE);
|
||||
$this->_handle_error('No compatible client to server message authentication algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
@ -1364,7 +1372,7 @@ class Net_SSH2 {
|
||||
|
||||
for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_server_to_client); $i++);
|
||||
if ($i == count($mac_algorithms)) {
|
||||
user_error('No compatible server to client message authentication algorithms found', E_USER_NOTICE);
|
||||
$this->_handle_error('No compatible server to client message authentication algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
@ -1406,14 +1414,14 @@ class Net_SSH2 {
|
||||
|
||||
for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_server_to_client); $i++);
|
||||
if ($i == count($compression_algorithms)) {
|
||||
user_error('No compatible server to client compression algorithms found', E_USER_NOTICE);
|
||||
$this->_handle_error('No compatible server to client compression algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
$this->decompress = $compression_algorithms[$i] == 'zlib';
|
||||
|
||||
for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_client_to_server); $i++);
|
||||
if ($i == count($compression_algorithms)) {
|
||||
user_error('No compatible client to server compression algorithms found', E_USER_NOTICE);
|
||||
$this->_handle_error('No compatible client to server compression algorithms found');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
$this->compress = $compression_algorithms[$i] == 'zlib';
|
||||
@ -1433,7 +1441,7 @@ class Net_SSH2 {
|
||||
* @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
|
||||
* by sending dummy SSH_MSG_IGNORE messages.
|
||||
*/
|
||||
function login($username, $password = '')
|
||||
function login($username, $password = null)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR)) {
|
||||
return false;
|
||||
@ -1449,14 +1457,14 @@ class Net_SSH2 {
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
|
||||
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
|
||||
user_error('Expected SSH_MSG_SERVICE_ACCEPT', E_USER_NOTICE);
|
||||
$this->_handle_error('Expected SSH_MSG_SERVICE_ACCEPT');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1465,6 +1473,34 @@ class Net_SSH2 {
|
||||
return $this->_privatekey_login($username, $password);
|
||||
}
|
||||
|
||||
if (!isset($password)) {
|
||||
$packet = pack('CNa*Na*Na*',
|
||||
NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
|
||||
strlen('none'), 'none'
|
||||
);
|
||||
|
||||
if (!$this->_send_binary_packet($packet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||
|
||||
switch ($type) {
|
||||
case NET_SSH2_MSG_USERAUTH_SUCCESS:
|
||||
$this->bitmap |= NET_SSH2_MASK_LOGIN;
|
||||
return true;
|
||||
//case NET_SSH2_MSG_USERAUTH_FAILURE:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$packet = pack('CNa*Na*Na*CNa*',
|
||||
NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
|
||||
strlen('password'), 'password', 0, strlen($password), $password
|
||||
@ -1485,7 +1521,7 @@ class Net_SSH2 {
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1557,7 +1593,7 @@ class Net_SSH2 {
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1670,7 +1706,7 @@ class Net_SSH2 {
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1705,7 +1741,7 @@ class Net_SSH2 {
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1858,7 +1894,7 @@ class Net_SSH2 {
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1869,7 +1905,7 @@ class Net_SSH2 {
|
||||
break;
|
||||
case NET_SSH2_MSG_CHANNEL_FAILURE:
|
||||
default:
|
||||
user_error('Unable to request pseudo-terminal', E_USER_NOTICE);
|
||||
$this->_handle_error('Unable to request pseudo-terminal');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
|
||||
@ -1910,12 +1946,12 @@ class Net_SSH2 {
|
||||
$this->curTimeout = $this->timeout;
|
||||
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
||||
$this->_handle_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & NET_SSH2_MASK_SHELL) && !$this->_initShell()) {
|
||||
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
||||
$this->_handle_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1923,7 +1959,7 @@ class Net_SSH2 {
|
||||
while (true) {
|
||||
if ($mode == NET_SSH2_READ_REGEX) {
|
||||
preg_match($expect, $this->interactiveBuffer, $matches);
|
||||
$match = $matches[0];
|
||||
$match = isset($matches[0]) ? $matches[0] : array();
|
||||
}
|
||||
$pos = !empty($match) ? strpos($this->interactiveBuffer, $match) : false;
|
||||
if ($pos !== false) {
|
||||
@ -1949,12 +1985,12 @@ class Net_SSH2 {
|
||||
function write($cmd)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
user_error('Operation disallowed prior to login()', E_USER_NOTICE);
|
||||
$this->_handle_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!($this->bitmap & NET_SSH2_MASK_SHELL) && !$this->_initShell()) {
|
||||
user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);
|
||||
$this->_handle_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1999,7 +2035,8 @@ class Net_SSH2 {
|
||||
function _get_binary_packet()
|
||||
{
|
||||
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
||||
user_error('Connection closed prematurely', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed prematurely');
|
||||
$this->bitmask = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2015,7 +2052,7 @@ class Net_SSH2 {
|
||||
$raw = $this->decrypt->decrypt($raw);
|
||||
}
|
||||
if ($raw === false) {
|
||||
user_error('Unable to decrypt content', E_USER_NOTICE);
|
||||
$this->_handle_error('Unable to decrypt content');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2039,7 +2076,7 @@ class Net_SSH2 {
|
||||
if ($this->hmac_check !== false) {
|
||||
$hmac = fread($this->fsock, $this->hmac_size);
|
||||
if ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
|
||||
user_error('Invalid HMAC', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid HMAC');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2051,10 +2088,12 @@ class Net_SSH2 {
|
||||
$this->get_seq_no++;
|
||||
|
||||
if (defined('NET_SSH2_LOGGING')) {
|
||||
$current = strtok(microtime(), ' ') + strtok('');
|
||||
$message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')';
|
||||
$message_number = '<- ' . $message_number .
|
||||
' (' . round($stop - $start, 4) . 's)';
|
||||
' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
|
||||
$this->_append_log($message_number, $payload);
|
||||
$this->last_packet = $current;
|
||||
}
|
||||
|
||||
return $this->_filter($payload);
|
||||
@ -2204,7 +2243,7 @@ class Net_SSH2 {
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response === false) {
|
||||
user_error('Connection closed by server', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed by server');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2226,7 +2265,7 @@ class Net_SSH2 {
|
||||
return $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended);
|
||||
//case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
|
||||
default:
|
||||
user_error('Unable to open channel', E_USER_NOTICE);
|
||||
$this->_handle_error('Unable to open channel');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
break;
|
||||
@ -2236,7 +2275,7 @@ class Net_SSH2 {
|
||||
return true;
|
||||
//case NET_SSH2_MSG_CHANNEL_FAILURE:
|
||||
default:
|
||||
user_error('Unable to request pseudo-terminal', E_USER_NOTICE);
|
||||
$this->_handle_error('Unable to request pseudo-terminal');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
case NET_SSH2_MSG_CHANNEL_CLOSE:
|
||||
@ -2325,7 +2364,7 @@ class Net_SSH2 {
|
||||
case NET_SSH2_MSG_CHANNEL_EOF:
|
||||
break;
|
||||
default:
|
||||
user_error('Error reading channel data', E_USER_NOTICE);
|
||||
$this->_handle_error('Error reading channel data');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
|
||||
}
|
||||
}
|
||||
@ -2344,7 +2383,8 @@ class Net_SSH2 {
|
||||
function _send_binary_packet($data)
|
||||
{
|
||||
if (!is_resource($this->fsock) || feof($this->fsock)) {
|
||||
user_error('Connection closed prematurely', E_USER_NOTICE);
|
||||
$this->_handle_error('Connection closed prematurely');
|
||||
$this->bitmask = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2383,10 +2423,12 @@ class Net_SSH2 {
|
||||
$stop = strtok(microtime(), ' ') + strtok('');
|
||||
|
||||
if (defined('NET_SSH2_LOGGING')) {
|
||||
$current = strtok(microtime(), ' ') + strtok('');
|
||||
$message_number = isset($this->message_numbers[ord($data[0])]) ? $this->message_numbers[ord($data[0])] : 'UNKNOWN (' . ord($data[0]) . ')';
|
||||
$message_number = '-> ' . $message_number .
|
||||
' (' . round($stop - $start, 4) . 's)';
|
||||
' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
|
||||
$this->_append_log($message_number, $data);
|
||||
$this->last_packet = $current;
|
||||
}
|
||||
|
||||
return $result;
|
||||
@ -2423,8 +2465,8 @@ class Net_SSH2 {
|
||||
// identified
|
||||
case NET_SSH2_LOG_REALTIME:
|
||||
echo "<pre>\r\n" . $this->_format_log(array($message), array($message_number)) . "\r\n</pre>\r\n";
|
||||
flush();
|
||||
ob_flush();
|
||||
@flush();
|
||||
@ob_flush();
|
||||
break;
|
||||
// basically the same thing as NET_SSH2_LOG_REALTIME with the caveat that NET_SSH2_LOG_REALTIME_FILE
|
||||
// needs to be defined and that the resultant log file will be capped out at NET_SSH2_LOG_MAX_SIZE.
|
||||
@ -2852,7 +2894,7 @@ class Net_SSH2 {
|
||||
padding, unsigned, and in network byte order). */
|
||||
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
|
||||
if ($temp['length'] != 40) {
|
||||
user_error('Invalid signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
@ -2860,7 +2902,7 @@ class Net_SSH2 {
|
||||
$s = new Math_BigInteger($this->_string_shift($signature, 20), 256);
|
||||
|
||||
if ($r->compare($q) >= 0 || $s->compare($q) >= 0) {
|
||||
user_error('Invalid signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
@ -2880,7 +2922,7 @@ class Net_SSH2 {
|
||||
list(, $v) = $v->divide($q);
|
||||
|
||||
if (!$v->equals($r)) {
|
||||
user_error('Bad server signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Bad server signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
}
|
||||
|
||||
@ -2905,7 +2947,7 @@ class Net_SSH2 {
|
||||
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
||||
$rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
|
||||
if (!$rsa->verify($this->exchange_hash, $signature)) {
|
||||
user_error('Bad server signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Bad server signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
}
|
||||
*/
|
||||
@ -2920,7 +2962,7 @@ class Net_SSH2 {
|
||||
// also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
|
||||
|
||||
if ($s->compare(new Math_BigInteger()) < 0 || $s->compare($n->subtract(new Math_BigInteger(1))) > 0) {
|
||||
user_error('Invalid signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Invalid signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||
}
|
||||
|
||||
@ -2931,15 +2973,33 @@ class Net_SSH2 {
|
||||
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 3 - strlen($h)) . $h;
|
||||
|
||||
if ($s != $h) {
|
||||
user_error('Bad server signature', E_USER_NOTICE);
|
||||
$this->_handle_error('Bad server signature');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
user_error('Unsupported signature format', E_USER_NOTICE);
|
||||
$this->_handle_error('Unsupported signature format');
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
}
|
||||
|
||||
return $this->signature_format . ' ' . base64_encode($this->server_public_host_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Handler
|
||||
*
|
||||
* Throws exceptions if PHPSECLIB_USE_EXCEPTIONS is defined.
|
||||
* Unless PHPSECLIB_EXCEPTION_CLASS is set it'll throw generic Exceptions.
|
||||
*
|
||||
* @param String $string
|
||||
* @access private
|
||||
*/
|
||||
function _handle_error($err_msg) {
|
||||
if (defined('PHPSECLIB_USE_EXCEPTIONS') && version_compare(PHP_VERSION, '5.1.0', '>=')) {
|
||||
$class = defined('PHPSECLIB_EXCEPTION_CLASS') && class_exists(PHPSECLIB_EXCEPTION_CLASS) ? PHPSECLIB_EXCEPTION_CLASS : 'Exception';
|
||||
throw(new $class($err_msg));
|
||||
} else {
|
||||
user_error($err_msg);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user