1
0
mirror of https://github.com/danog/tgseclib.git synced 2024-11-26 20:24:39 +01:00

Merge branch 'ssh2-fix-multi-channel-1.0' into 2.0

This commit is contained in:
terrafrost 2017-09-05 23:22:09 -05:00
commit eeaef39827

View File

@ -100,10 +100,10 @@ class SSH2
* @see \phpseclib\Net\SSH2::_get_channel_packet()
* @access private
*/
const CHANNEL_EXEC = 0; // PuTTy uses 0x100
const CHANNEL_SHELL = 1;
const CHANNEL_SUBSYSTEM = 2;
const CHANNEL_AGENT_FORWARD = 3;
const CHANNEL_EXEC = 1; // PuTTy uses 0x100
const CHANNEL_SHELL = 2;
const CHANNEL_SUBSYSTEM = 3;
const CHANNEL_AGENT_FORWARD = 4;
/**#@-*/
/**#@+
@ -910,6 +910,14 @@ class SSH2
*/
var $retry_connect = false;
/**
* Binary Packet Buffer
*
* @var string|false
* @access private
*/
var $binary_packet_buffer = false;
/**
* Default Constructor.
*
@ -2721,7 +2729,7 @@ class SSH2
return false;
}
$response = $this->_get_binary_packet();
$response = $this->_get_binary_packet(true);
if ($response === false) {
user_error('Connection closed by server');
return false;
@ -3203,7 +3211,7 @@ class SSH2
* @return string
* @access private
*/
function _get_binary_packet()
function _get_binary_packet($filter_channel_packets = false)
{
if (!is_resource($this->fsock) || feof($this->fsock)) {
user_error('Connection closed prematurely');
@ -3257,6 +3265,7 @@ class SSH2
$buffer.= $temp;
$remaining_length-= strlen($temp);
}
$stop = microtime(true);
if (strlen($buffer)) {
$raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;
@ -3292,7 +3301,7 @@ class SSH2
$this->last_packet = $current;
}
return $this->_filter($payload);
return $this->_filter($payload, $filter_channel_packets);
}
/**
@ -3304,7 +3313,7 @@ class SSH2
* @return string
* @access private
*/
function _filter($payload)
function _filter($payload, $filter_channel_packets)
{
switch (ord($payload[0])) {
case NET_SSH2_MSG_DISCONNECT:
@ -3354,6 +3363,17 @@ class SSH2
// only called when we've already logged in
if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
switch (ord($payload[0])) {
case NET_SSH2_MSG_CHANNEL_DATA:
case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
case NET_SSH2_MSG_CHANNEL_REQUEST:
case NET_SSH2_MSG_CHANNEL_CLOSE:
case NET_SSH2_MSG_CHANNEL_EOF:
if ($filter_channel_packets) {
$this->binary_packet_buffer = $payload;
$this->_get_channel_packet(true);
$payload = $this->_get_binary_packet(true);
}
break;
case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
if (strlen($payload) < 4) {
return false;
@ -3536,32 +3556,38 @@ class SSH2
}
while (true) {
if ($this->curTimeout) {
if ($this->curTimeout < 0) {
$this->is_timeout = true;
return true;
if ($this->binary_packet_buffer !== false) {
$response = $this->binary_packet_buffer;
$this->binary_packet_buffer = false;
} else {
if ($this->curTimeout) {
if ($this->curTimeout < 0) {
$this->is_timeout = true;
return true;
}
$read = array($this->fsock);
$write = $except = null;
$start = microtime(true);
$sec = floor($this->curTimeout);
$usec = 1000000 * ($this->curTimeout - $sec);
// on windows this returns a "Warning: Invalid CRT parameters detected" error
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
$this->is_timeout = true;
return true;
}
$elapsed = microtime(true) - $start;
$this->curTimeout-= $elapsed;
}
$read = array($this->fsock);
$write = $except = null;
$start = microtime(true);
$sec = floor($this->curTimeout);
$usec = 1000000 * ($this->curTimeout - $sec);
// on windows this returns a "Warning: Invalid CRT parameters detected" error
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
$this->is_timeout = true;
return true;
$response = $this->_get_binary_packet();
if ($response === false) {
user_error('Connection closed by server');
return false;
}
$elapsed = microtime(true) - $start;
$this->curTimeout-= $elapsed;
}
$response = $this->_get_binary_packet();
if ($response === false) {
user_error('Connection closed by server');
return false;
}
if ($client_channel == -1 && $response === true) {
return true;
}