From 983a9de700d52cbad2fa4c6e91e80202d35ca772 Mon Sep 17 00:00:00 2001 From: Brian White Date: Sun, 10 Oct 2021 17:34:19 -0400 Subject: [PATCH] lib: fix server channel cleanup for bare sessions Fixes: https://github.com/mscdex/ssh2/issues/1050 --- lib/server.js | 3 +++ lib/utils.js | 16 ++++++++++------ test/test-misc-client-server.js | 22 ++++++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/server.js b/lib/server.js index 999cb7f6..4f6fd1f6 100644 --- a/lib/server.js +++ b/lib/server.js @@ -189,6 +189,7 @@ class Session extends EventEmitter { this.type = 'session'; this.subtype = undefined; + this.server = true; this._ending = false; this._channel = undefined; this._chanInfo = { @@ -556,6 +557,8 @@ class Client extends EventEmitter { reason = CHANNEL_OPEN_FAILURE.CONNECT_FAILED; } + if (localChan !== -1) + this._chanMgr.remove(localChan); proto.channelOpenFail(info.sender, reason, ''); }; const reserveChannel = () => { diff --git a/lib/utils.js b/lib/utils.js index 04d4b96d..d9ca6aef 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -32,11 +32,17 @@ function onCHANNEL_CLOSE(self, recipient, channel, err, dead) { onChannelOpenFailure(self, recipient, err, channel); return; } - if (typeof channel !== 'object' - || channel === null - || channel.incoming.state === 'closed') { + + if (typeof channel !== 'object' || channel === null) + return; + + if (channel.incoming && channel.incoming.state === 'closed') + return; + + self._chanMgr.remove(recipient); + + if (channel.server && channel.constructor.name === 'Session') return; - } channel.incoming.state = 'closed'; @@ -58,8 +64,6 @@ function onCHANNEL_CLOSE(self, recipient, channel, err, dead) { if (channel.outgoing.state === 'closing') channel.outgoing.state = 'closed'; - self._chanMgr.remove(recipient); - const readState = channel._readableState; const writeState = channel._writableState; if (writeState && !writeState.ending && !writeState.finished && !dead) diff --git a/test/test-misc-client-server.js b/test/test-misc-client-server.js index 37ca2206..fb4b8a5a 100644 --- a/test/test-misc-client-server.js +++ b/test/test-misc-client-server.js @@ -1424,3 +1424,25 @@ const setup = setupSimple.bind(undefined, debug); })); server.injectSocket(socket); } + +{ + const { client, server } = setup( + 'Server should not error when cleaning up client bare session channels' + ); + + server.on('connection', mustCall((conn) => { + conn.on('session', mustCall((accept, reject) => { + accept().on('exec', mustCall((accept, reject, info) => { + assert(info.command === 'uptime', + `Wrong exec command: ${info.command}`); + client.end(); + })); + })); + })); + + client.on('ready', mustCall(() => { + client.exec('uptime', mustCall((err) => { + assert(err instanceof Error); + })); + })); +}