mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-25 11:20:03 +00:00
Add DISCONNECT bitmap mask and use to prevent looping potential while disconnecting. Do not attempt disconnect packet send on closed socket.
This commit is contained in:
parent
621c73f7dc
commit
c82594e222
@ -104,6 +104,7 @@ class SSH2
|
||||
const MASK_LOGIN_REQ = 0x00000004;
|
||||
const MASK_LOGIN = 0x00000008;
|
||||
const MASK_SHELL = 0x00000010;
|
||||
const MASK_DISCONNECT = 0x00000020;
|
||||
|
||||
/*
|
||||
* Channel constants
|
||||
@ -4593,7 +4594,12 @@ class SSH2
|
||||
*/
|
||||
protected function disconnect_helper($reason)
|
||||
{
|
||||
if ($this->bitmap & self::MASK_CONNECTED) {
|
||||
if ($this->bitmap & self::MASK_DISCONNECT) {
|
||||
// Disregard subsequent disconnect requests
|
||||
return false;
|
||||
}
|
||||
$this->bitmap |= self::MASK_DISCONNECT;
|
||||
if ($this->isConnected()) {
|
||||
$data = Strings::packSSH2('CNss', NET_SSH2_MSG_DISCONNECT, $reason, '', '');
|
||||
try {
|
||||
$this->send_binary_packet($data);
|
||||
|
@ -33,6 +33,24 @@ class SSH2UnitTest extends PhpseclibTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHPUnit < 10
|
||||
* Verify that MASK_* constants remain distinct
|
||||
*/
|
||||
public function testBitmapMasks()
|
||||
{
|
||||
$reflection = new \ReflectionClass(SSH2::class);
|
||||
$masks = array_filter($reflection->getConstants(), function ($k) {
|
||||
return strpos($k, 'MASK_') === 0;
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
$bitmap = 0;
|
||||
foreach ($masks as $mask => $bit) {
|
||||
$this->assertEquals(0, $bitmap & $bit, "Got unexpected mask {$mask}");
|
||||
$bitmap |= $bit;
|
||||
$this->assertEquals($bit, $bitmap & $bit, "Absent expected mask {$mask}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider formatLogDataProvider
|
||||
* @requires PHPUnit < 10
|
||||
@ -384,6 +402,31 @@ class SSH2UnitTest extends PhpseclibTestCase
|
||||
self::callFunc($ssh, 'send_channel_packet', [1, 'hello world']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHPUnit < 10
|
||||
*/
|
||||
public function testDisconnectHelper()
|
||||
{
|
||||
$ssh = $this->getMockBuilder('phpseclib3\Net\SSH2')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['__destruct', 'isConnected', 'send_binary_packet'])
|
||||
->getMock();
|
||||
$ssh->expects($this->once())
|
||||
->method('isConnected')
|
||||
->willReturn(true);
|
||||
$ssh->expects($this->once())
|
||||
->method('send_binary_packet')
|
||||
->with($this->isType('string'))
|
||||
->willReturnCallback(function () use ($ssh) {
|
||||
self::callFunc($ssh, 'disconnect_helper', [1]);
|
||||
throw new \Exception('catch me');
|
||||
});
|
||||
|
||||
$this->assertEquals(0, self::getVar($ssh, 'bitmap'));
|
||||
self::callFunc($ssh, 'disconnect_helper', [1]);
|
||||
$this->assertEquals(0, self::getVar($ssh, 'bitmap'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SSH2
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user