Improved RDP error handling, #4022

This commit is contained in:
Ylian Saint-Hilaire 2022-05-20 21:52:03 -07:00
parent 3e97d80470
commit 783ff4be0c
6 changed files with 311 additions and 281 deletions

View File

@ -207,7 +207,8 @@ module.exports.CreateMstscRelay = function (parent, db, ws, req, args, domain) {
}).on('close', function () {
send(['rdp-close']);
}).on('error', function (err) {
send(['rdp-error', err]);
if (typeof err == 'string') { send(['rdp-error', err]); }
if ((typeof err == 'object') && (err.err) && (err.code)) { send(['rdp-error', err.err, err.code]); }
}).connect('localhost', obj.tcpServerPort);
} catch (ex) {
console.log('startRdpException', ex);

View File

@ -16,6 +16,7 @@ var CreateRDPDesktop = function (canvasid) {
obj.ScreenWidth = obj.width = 1280;
obj.ScreenHeight = obj.height = 1024;
obj.m.onClipboardChanged = null;
obj.onConsoleMessageChange = null;
function mouseButtonMap(button) {
// Swap mouse buttons if needed
@ -79,8 +80,28 @@ var CreateRDPDesktop = function (canvasid) {
break;
}
case 'rdp-error': {
var err = msg[1];
console.log('[mstsc.js] error : ' + err.code + '(' + err.message + ')');
obj.consoleMessageTimeout = 5; // Seconds
obj.consoleMessage = msg[1];
delete obj.consoleMessageArgs;
if (msg.length > 2) { obj.consoleMessageArgs = [ msg[2] ]; }
switch (msg[1]) {
case 'NODE_RDP_PROTOCOL_X224_NEG_FAILURE':
if (msg[2] == 1) { obj.consoleMessageId = 9; } // "SSL required by server";
else if (msg[2] == 2) { obj.consoleMessageId = 10; } // "SSL not allowed by server";
else if (msg[2] == 3) { obj.consoleMessageId = 11; } // "SSL certificate not on server";
else if (msg[2] == 4) { obj.consoleMessageId = 12; } // "Inconsistent flags";
else if (msg[2] == 5) { obj.consoleMessageId = 13; } // "Hybrid required by server";
else if (msg[2] == 6) { obj.consoleMessageId = 14; } // "SSL with user auth required by server";
else obj.consoleMessageId = 7; // "Protocol negotiation failed";
break;
case 'NODE_RDP_PROTOCOL_X224_NLA_NOT_SUPPORTED':
obj.consoleMessageId = 8; // "NLA not supported";
break;
default:
obj.consoleMessageId = null;
break;
}
if (obj.onConsoleMessageChange) { obj.onConsoleMessageChange(); }
obj.Stop();
break;
}

View File

@ -36,10 +36,10 @@ class Client extends Cliprdr {
this.transport.once('connect', (gccCore, userId, channelId) => {
this.connect(gccCore, userId, channelId);
}).on('close', () => {
this.emit('close');
}).on('error', (err) => {
this.emit('error', err);
}).on('close', function () {
//this.emit('close');
}).on('error', function (err) {
//this.emit('error', err);
});
this.content = '';
@ -157,7 +157,7 @@ class Client extends Cliprdr {
msgType: new type.UInt16Le(data.ClipPDUMsgType.CB_TEMP_DIRECTORY),
msgFlags: new type.UInt16Le(0x00),
dataLen: new type.UInt32Le(0x0208),
wszTempDir: new type.BinaryString(Buffer.from('D:\\Vectors' + Array(251).join('\x00'), 'ucs2'), { readLength : new type.CallableValue(520)})
wszTempDir: new type.BinaryString(Buffer.from('D:\\Vectors' + Array(251).join('\x00'), 'ucs2'), { readLength: new type.CallableValue(520) })
}));
}
@ -173,7 +173,7 @@ class Client extends Cliprdr {
dataLen: new type.UInt32Le(0x24),
formatId6: new type.UInt32Le(0xc004),
formatName6: new type.BinaryString(Buffer.from('Native\x00' , 'ucs2'), { readLength : new type.CallableValue(14)}),
formatName6: new type.BinaryString(Buffer.from('Native\x00', 'ucs2'), { readLength: new type.CallableValue(14) }),
formatId8: new type.UInt32Le(0x0d),
formatName8: new type.UInt16Le(0x00),
@ -287,13 +287,13 @@ class Client extends Cliprdr {
*/
sendFormatDataResponsePDU() {
const bufs = Buffer.from(this.content + '\x00' , 'ucs2');
const bufs = Buffer.from(this.content + '\x00', 'ucs2');
this.send(new type.Component({
msgType: new type.UInt16Le(data.ClipPDUMsgType.CB_FORMAT_DATA_RESPONSE),
msgFlags: new type.UInt16Le(0x01),
dataLen: new type.UInt32Le(bufs.length),
requestedFormatData: new type.BinaryString(bufs, { readLength : new type.CallableValue(bufs.length)})
requestedFormatData: new type.BinaryString(bufs, { readLength: new type.CallableValue(bufs.length) })
}));
}
@ -306,14 +306,14 @@ class Client extends Cliprdr {
recvFormatDataResponsePDU(s) {
s.offset = 18;
// const pdu = data.clipPDU().read(s);
const str = s.buffer.toString('ucs2', 26, s.buffer.length-2);
const str = s.buffer.toString('ucs2', 26, s.buffer.length - 2);
// console.log('recvFormatDataResponsePDU', str);
this.content = str;
this.emit('clipboard', str)
}
// =====================================================================================
// =====================================================================================
setClipboardData(content) {
this.content = content;
this.sendFormatListPDU();

View File

@ -184,12 +184,7 @@ function RdpClient(config) {
}
}).on('error', function (err) {
log.warn(err.code + '(' + err.message + ')\n' + err.stack);
if (err instanceof error.FatalError) {
throw err;
}
else {
self.emit('error', err);
}
if (err instanceof error.FatalError) { throw err; } else { self.emit('error', err); }
});
}

View File

@ -218,8 +218,9 @@ Client.prototype.recvConnectionConfirm = function(s) {
var message = serverConnectionConfirm().read(s);
if (message.obj.protocolNeg.obj.type.value == NegotiationType.TYPE_RDP_NEG_FAILURE) {
throw new error.ProtocolError('NODE_RDP_PROTOCOL_X224_NEG_FAILURE',
'Failure code:' + message.obj.protocolNeg.obj.result.value + " (see https://msdn.microsoft.com/en-us/library/cc240507.aspx)");
this.emit('error', { err: 'NODE_RDP_PROTOCOL_X224_NEG_FAILURE', code: message.obj.protocolNeg.obj.result.value });
return;
//throw new error.ProtocolError('NODE_RDP_PROTOCOL_X224_NEG_FAILURE', 'Failure code:' + message.obj.protocolNeg.obj.result.value + " (see https://msdn.microsoft.com/en-us/library/cc240507.aspx)");
}
if (message.obj.protocolNeg.obj.type.value == NegotiationType.TYPE_RDP_NEG_RSP) {
@ -227,7 +228,9 @@ Client.prototype.recvConnectionConfirm = function(s) {
}
if ([Protocols.PROTOCOL_HYBRID_EX].indexOf(this.selectedProtocol) !== -1) {
throw new error.ProtocolError('NODE_RDP_PROTOCOL_X224_NLA_NOT_SUPPORTED');
this.emit('error', 'NODE_RDP_PROTOCOL_X224_NLA_NOT_SUPPORTED');
return;
//throw new error.ProtocolError('NODE_RDP_PROTOCOL_X224_NLA_NOT_SUPPORTED');
}
if (this.selectedProtocol == Protocols.PROTOCOL_RDP) {

View File

@ -8414,7 +8414,7 @@
function autoConnectDesktop(e) { if (autoConnectDesktopTimer == null) { autoConnectDesktopTimer = setInterval(function() { connectDesktop(null, 1) }, 1000); } else { clearInterval(autoConnectDesktopTimer); autoConnectDesktopTimer = null; } }
// Used to translate incoming agent console messages
var agentConsoleMessages = [ '', "Waiting for user to grant access...", "Denied", "Failed to start remote terminal session, {0} ({1})", "Timeout", "Received invalid network data", "Unable to capture display" ];
var agentConsoleMessages = [ '', "Waiting for user to grant access...", "Denied", "Failed to start remote terminal session, {0} ({1})", "Timeout", "Received invalid network data", "Unable to capture display", "Protocol negotiation failed ({0})", "NLA not supported", "SSL required by server", "SSL not allowed by server", "SSL certificate not on server", "Inconsistent flags", "Hybrid required by server", "SSL with user auth required by server" ];
function formatAgentConsoleMessage(msg, msgid, msgargs) {
var r;
if (msgargs == null) { msgargs = []; }
@ -8569,6 +8569,16 @@
if (desktopsettings.rdpsmb) { desktop.m.SwapMouse = desktopsettings.rdpsmb; }
desktop.Start(desktopNode._id, currentNode.rdpport ? currentNode.rdpport : 3389, tsid);
desktop.contype = 4;
desktop.onConsoleMessageChange = function () {
if (desktop.consoleMessage) {
Q('p11DeskConsoleMsg').innerHTML += formatAgentConsoleMessage(desktop.consoleMessage, desktop.consoleMessageId, desktop.consoleMessageArgs);
QV('p11DeskConsoleMsg', true);
if (p11DeskConsoleMsgTimer != null) { clearTimeout(p11DeskConsoleMsgTimer); }
if (desktop.consoleMessageTimeout) { p11DeskConsoleMsgTimer = setTimeout(p11clearConsoleMsg, desktop.consoleMessageTimeout * 1000); }
} else {
p11clearConsoleMsg();
}
}
}
} else {
// Disconnect and clean up the remote desktop