mirror of
https://github.com/danog/tgseclib.git
synced 2024-11-30 04:39:02 +01:00
- hopefully better handling of lengthy sessions
git-svn-id: http://phpseclib.svn.sourceforge.net/svnroot/phpseclib/trunk@84 21d32557-59b3-4da0-833f-c5933fad653e
This commit is contained in:
parent
d77c85218d
commit
61625bc8ab
@ -60,7 +60,7 @@
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @license http://www.gnu.org/licenses/lgpl.txt
|
||||
* @version $Id: SSH2.php,v 1.35 2010-02-09 06:10:26 terrafrost Exp $
|
||||
* @version $Id: SSH2.php,v 1.36 2010-02-11 07:02:51 terrafrost Exp $
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
@ -154,7 +154,7 @@ class Net_SSH2 {
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $identifier = 'SSH-2.0-phpseclib_0.1';
|
||||
var $identifier = 'SSH-2.0-phpseclib_0.2';
|
||||
|
||||
/**
|
||||
* The Socket Object
|
||||
@ -517,6 +517,29 @@ class Net_SSH2 {
|
||||
*/
|
||||
var $message_log = array();
|
||||
|
||||
/**
|
||||
* The Window Size
|
||||
*
|
||||
* Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 4GB)
|
||||
*
|
||||
* @var Integer
|
||||
* @see Net_SSH2::_send_channel_packet()
|
||||
* @see Net_SSH2::exec()
|
||||
* @access private
|
||||
*/
|
||||
var $window_size = 0x7FFFFFFF;
|
||||
|
||||
/**
|
||||
* Window size
|
||||
*
|
||||
* Window size indexed by channel
|
||||
*
|
||||
* @see Net_SSH2::_send_channel_packet()
|
||||
* @var Array
|
||||
* @access private
|
||||
*/
|
||||
var $window_size_client_to_server = array();
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
@ -620,6 +643,20 @@ class Net_SSH2 {
|
||||
$temp.= fgets($this->fsock, 255);
|
||||
}
|
||||
|
||||
$ext = array();
|
||||
if (extension_loaded('mcrypt')) {
|
||||
$ext[] = 'mcrypt';
|
||||
}
|
||||
if (extension_loaded('gmp')) {
|
||||
$ext[] = 'gmp';
|
||||
} else if (extension_loaded('bcmath')) {
|
||||
$ext[] = 'bcmath';
|
||||
}
|
||||
|
||||
if (!empty($ext)) {
|
||||
$this->identifier.= ' (' . implode(', ', $ext) . ')';
|
||||
}
|
||||
|
||||
if (defined('NET_SSH2_LOGGING')) {
|
||||
$this->message_number_log[] = '<-';
|
||||
$this->message_log[] = $temp;
|
||||
@ -943,16 +980,16 @@ class Net_SSH2 {
|
||||
$key = $f->modPow($x, $p);
|
||||
$keyBytes = $key->toBytes(true);
|
||||
|
||||
$source = pack('Na*Na*Na*Na*Na*Na*Na*Na*',
|
||||
strlen($this->identifier), $this->identifier, strlen($this->server_identifier), $this->server_identifier,
|
||||
strlen($kexinit_payload_client), $kexinit_payload_client, strlen($kexinit_payload_server),
|
||||
$kexinit_payload_server, strlen($this->server_public_host_key), $this->server_public_host_key, strlen($eBytes),
|
||||
$eBytes, strlen($fBytes), $fBytes, strlen($keyBytes), $keyBytes
|
||||
);
|
||||
|
||||
$source = pack('H*', $hash($source));
|
||||
|
||||
if ($this->session_id === false) {
|
||||
$source = pack('Na*Na*Na*Na*Na*Na*Na*Na*',
|
||||
strlen($this->identifier), $this->identifier, strlen($this->server_identifier), $this->server_identifier,
|
||||
strlen($kexinit_payload_client), $kexinit_payload_client, strlen($kexinit_payload_server),
|
||||
$kexinit_payload_server, strlen($this->server_public_host_key), $this->server_public_host_key, strlen($eBytes),
|
||||
$eBytes, strlen($fBytes), $fBytes, strlen($keyBytes), $keyBytes
|
||||
);
|
||||
|
||||
$source = pack('H*', $hash($source));
|
||||
|
||||
$this->session_id = $source;
|
||||
}
|
||||
|
||||
@ -1004,7 +1041,7 @@ class Net_SSH2 {
|
||||
|
||||
$w = $s->modInverse($q);
|
||||
|
||||
$u1 = $w->multiply(new Math_BigInteger(sha1($source), 16));
|
||||
$u1 = $w->multiply(new Math_BigInteger(sha1($this->session_id), 16));
|
||||
list(, $u1) = $u1->divide($q);
|
||||
|
||||
$u2 = $w->multiply($r);
|
||||
@ -1042,7 +1079,7 @@ class Net_SSH2 {
|
||||
$rsa = new Crypt_RSA();
|
||||
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
|
||||
$rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);
|
||||
if (!$rsa->verify($source, $signature)) {
|
||||
if (!$rsa->verify($this->session_id, $signature)) {
|
||||
user_error('Bad server signature', E_USER_NOTICE);
|
||||
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
|
||||
}
|
||||
@ -1065,7 +1102,7 @@ class Net_SSH2 {
|
||||
$s = $s->modPow($e, $n);
|
||||
$s = $s->toBytes();
|
||||
|
||||
$h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($source));
|
||||
$h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($this->session_id));
|
||||
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 3 - strlen($h)) . $h;
|
||||
|
||||
if ($s != $h) {
|
||||
@ -1160,15 +1197,15 @@ class Net_SSH2 {
|
||||
$this->encrypt->enableContinuousBuffer();
|
||||
$this->encrypt->disablePadding();
|
||||
|
||||
$iv = pack('H*', $hash($keyBytes . $source . 'A' . $this->session_id));
|
||||
$iv = pack('H*', $hash($keyBytes . $this->session_id . 'A' . $this->session_id));
|
||||
while ($this->encrypt_block_size > strlen($iv)) {
|
||||
$iv.= pack('H*', $hash($keyBytes . $source . $iv));
|
||||
$iv.= pack('H*', $hash($keyBytes . $this->session_id . $iv));
|
||||
}
|
||||
$this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
|
||||
|
||||
$key = pack('H*', $hash($keyBytes . $source . 'C' . $this->session_id));
|
||||
$key = pack('H*', $hash($keyBytes . $this->session_id . 'C' . $this->session_id));
|
||||
while ($encryptKeyLength > strlen($key)) {
|
||||
$key.= pack('H*', $hash($keyBytes . $source . $key));
|
||||
$key.= pack('H*', $hash($keyBytes . $this->session_id . $key));
|
||||
}
|
||||
$this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
|
||||
}
|
||||
@ -1177,15 +1214,15 @@ class Net_SSH2 {
|
||||
$this->decrypt->enableContinuousBuffer();
|
||||
$this->decrypt->disablePadding();
|
||||
|
||||
$iv = pack('H*', $hash($keyBytes . $source . 'B' . $this->session_id));
|
||||
$iv = pack('H*', $hash($keyBytes . $this->session_id . 'B' . $this->session_id));
|
||||
while ($this->decrypt_block_size > strlen($iv)) {
|
||||
$iv.= pack('H*', $hash($keyBytes . $source . $iv));
|
||||
$iv.= pack('H*', $hash($keyBytes . $this->session_id . $iv));
|
||||
}
|
||||
$this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
|
||||
|
||||
$key = pack('H*', $hash($keyBytes . $source . 'D' . $this->session_id));
|
||||
$key = pack('H*', $hash($keyBytes . $this->session_id . 'D' . $this->session_id));
|
||||
while ($decryptKeyLength > strlen($key)) {
|
||||
$key.= pack('H*', $hash($keyBytes . $source . $key));
|
||||
$key.= pack('H*', $hash($keyBytes . $this->session_id . $key));
|
||||
}
|
||||
$this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
|
||||
}
|
||||
@ -1259,15 +1296,15 @@ class Net_SSH2 {
|
||||
$this->hmac_size = 12;
|
||||
}
|
||||
|
||||
$key = pack('H*', $hash($keyBytes . $source . 'E' . $this->session_id));
|
||||
$key = pack('H*', $hash($keyBytes . $this->session_id . 'E' . $this->session_id));
|
||||
while ($createKeyLength > strlen($key)) {
|
||||
$key.= pack('H*', $hash($keyBytes . $source . $key));
|
||||
$key.= pack('H*', $hash($keyBytes . $this->session_id . $key));
|
||||
}
|
||||
$this->hmac_create->setKey(substr($key, 0, $createKeyLength));
|
||||
|
||||
$key = pack('H*', $hash($keyBytes . $source . 'F' . $this->session_id));
|
||||
$key = pack('H*', $hash($keyBytes . $this->session_id . 'F' . $this->session_id));
|
||||
while ($checkKeyLength > strlen($key)) {
|
||||
$key.= pack('H*', $hash($keyBytes . $source . $key));
|
||||
$key.= pack('H*', $hash($keyBytes . $this->session_id . $key));
|
||||
}
|
||||
$this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
|
||||
|
||||
@ -1895,17 +1932,38 @@ class Net_SSH2 {
|
||||
function _send_channel_packet($client_channel, $data)
|
||||
{
|
||||
while (strlen($data) > $this->packet_size_client_to_server[$client_channel]) {
|
||||
// resize the window, if appropriate
|
||||
$this->window_size_client_to_server[$client_channel]-= $this->packet_size_client_to_server[$client_channel];
|
||||
if ($this->window_size_client_to_server[$client_channel] < 0) {
|
||||
$packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$client_channel], $this->window_size);
|
||||
if (!$this->_send_binary_packet($packet)) {
|
||||
return false;
|
||||
}
|
||||
$this->window_size_client_to_server[$client_channel]+= $this->window_size;
|
||||
}
|
||||
|
||||
$packet = pack('CN2a*',
|
||||
NET_SSH2_MSG_CHANNEL_DATA,
|
||||
$this->server_channels[$client_channel],
|
||||
$this->packet_size_client_to_server[$client_channel],
|
||||
$this->_string_shift($data, $this->packet_size_client_to_server[$client_channel])
|
||||
);
|
||||
|
||||
|
||||
if (!$this->_send_binary_packet($packet)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// resize the window, if appropriate
|
||||
$this->window_size_client_to_server[$client_channel]-= strlen($data);
|
||||
if ($this->window_size_client_to_server[$client_channel] < 0) {
|
||||
$packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$client_channel], $this->window_size);
|
||||
if (!$this->_send_binary_packet($packet)) {
|
||||
return false;
|
||||
}
|
||||
$this->window_size_client_to_server[$client_channel]+= $this->window_size;
|
||||
}
|
||||
|
||||
return $this->_send_binary_packet(pack('CN2a*',
|
||||
NET_SSH2_MSG_CHANNEL_DATA,
|
||||
$this->server_channels[$client_channel],
|
||||
|
Loading…
Reference in New Issue
Block a user