From c982c10e30a34b5c968ffce92ee0737f0d9d6ea7 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Mon, 29 Jun 2020 14:47:09 -0700 Subject: [PATCH] Fixed Kerberos, added redirection error messages. --- amt-desktop-0.0.2.js | 3 +- amt-redir-node-0.1.0.js | 74 ++++++++++++++---- amt-wsman-node-0.2.0.js | 5 +- index.html | 31 +++++++- webserver-0.0.1.js | 164 ++++++++++++++++++++++++++++++++-------- 5 files changed, 223 insertions(+), 54 deletions(-) diff --git a/amt-desktop-0.0.2.js b/amt-desktop-0.0.2.js index 7227b44..e7a7076 100644 --- a/amt-desktop-0.0.2.js +++ b/amt-desktop-0.0.2.js @@ -114,6 +114,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) { if (accview.getUint32(0) != 0) { return obj.Stop(); } obj.send(String.fromCharCode(1)); // Send share desktop flag obj.state = 3; + if (obj.parent) { obj.parent.disconnectCode = 50000; } // If Intel AMT disconnects at exactly this moment, indicates we need RLE8 or unsupported GPU. } else if ((obj.state == 3) && (obj.acc.byteLength >= 24)) { // Getting server init @@ -171,7 +172,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) { if (obj.bpp == 1) obj.send(String.fromCharCode(0, 0, 0, 0, 8, 8, 0, 1) + ShortToStr(7) + ShortToStr(7) + ShortToStr(3) + String.fromCharCode(5, 2, 0, 0, 0, 0)); // Setup 8 bit color RGB332 obj.state = 4; - if (obj.parent) { obj.parent.xxStateChange(3); } + if (obj.parent) { obj.parent.disconnectCode = 0; obj.parent.xxStateChange(3); } _SendRefresh(); //obj.timer = setInterval(obj.xxOnTimer, 50); diff --git a/amt-redir-node-0.1.0.js b/amt-redir-node-0.1.0.js index d03c260..a3c1532 100644 --- a/amt-redir-node-0.1.0.js +++ b/amt-redir-node-0.1.0.js @@ -28,6 +28,7 @@ var CreateAmtRedirect = function (module) { obj.authuri = '/RedirectionService'; obj.digestRealmMatch = null; obj.onStateChanged = null; + obj.disconnectCode = 0; function ToIntStr(v) { return String.fromCharCode((v & 0xFF), ((v >> 8) & 0xFF), ((v >> 16) & 0xFF), ((v >> 24) & 0xFF)); } function ToShortStr(v) { return String.fromCharCode((v & 0xFF), ((v >> 8) & 0xFF)); } @@ -95,6 +96,13 @@ var CreateAmtRedirect = function (module) { obj.xxOnSocketData = function (data) { if (!data || obj.connectstate == -1) return; + + // Redirection tracing + if (urlvars && urlvars['redirtrace']) { + var datastr = arrToStr(new Uint8Array(data)); + console.log('REDIR-RECV(' + datastr.length + '): ' + rstr2hex(datastr)); + } + //obj.inDataCount++; data = new Uint8Array(data).buffer; @@ -129,6 +137,7 @@ var CreateAmtRedirect = function (module) { cmdsize = (13 + oemlen); break; default: + obj.disconnectCode = statuscode; // 2 = BUSY, 3 = UNSUPPORTED, 0xFF = ERROR. obj.Stop(1); break; } @@ -142,20 +151,49 @@ var CreateAmtRedirect = function (module) { var authDataBuf = new Uint8Array(obj.acc.slice(9, 9 + authDataLen)); cmdsize = 9 + authDataLen; if (authType == 0) { - // Query - if (authData.indexOf(4) >= 0) { - // Good Digest Auth (With cnonce and all) - obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x04) + IntToStrX(obj.user.length + obj.authuri.length + 8) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(0x00, 0x00) + String.fromCharCode(obj.authuri.length) + obj.authuri + String.fromCharCode(0x00, 0x00, 0x00, 0x00)); + // ###BEGIN###{Mode-NodeWebkit} + if (obj.user == '*') { + if (authData.indexOf(2) >= 0) { + // Kerberos Auth + var ticket; + if (kerberos && kerberos != null) { + var ticketReturn = kerberos.getTicket('HTTP' + ((obj.tls == 1)?'S':'') + '/' + ((obj.pass == '') ? (obj.host + ':' + obj.port) : obj.pass)); + if (ticketReturn.returnCode == 0 || ticketReturn.returnCode == 0x90312) { + ticket = ticketReturn.ticket; + if (process.platform.indexOf('win') >= 0) { + // Clear kerberos tickets on both 32 and 64bit Windows platforms + try { require('child_process').exec('%windir%\\system32\\klist purge', function (error, stdout, stderr) { if (error) { require('child_process').exec('%windir%\\sysnative\\klist purge', function (error, stdout, stderr) { if (error) { console.error('Unable to purge kerberos tickets'); } }); } }); } catch (e) { console.log(e); } + } + } else { + console.error('Unexpected Kerberos error code: ' + ticketReturn.returnCode); + } + } + if (ticket) { + obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x02) + IntToStrX(ticket.length) + ticket); + } else { + obj.Stop(2); + } + } + else obj.Stop(2); + } else { + // ###END###{Mode-NodeWebkit} + // Query + if (authData.indexOf(4) >= 0) { + // Good Digest Auth (With cnonce and all) + obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x04) + IntToStrX(obj.user.length + obj.authuri.length + 8) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(0x00, 0x00) + String.fromCharCode(obj.authuri.length) + obj.authuri + String.fromCharCode(0x00, 0x00, 0x00, 0x00)); + } + else if (authData.indexOf(3) >= 0) { + // Bad Digest Auth (Not sure why this is supported, cnonce is not used!) + obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x03) + IntToStrX(obj.user.length + obj.authuri.length + 7) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(0x00, 0x00) + String.fromCharCode(obj.authuri.length) + obj.authuri + String.fromCharCode(0x00, 0x00, 0x00)); + } + else if (authData.indexOf(1) >= 0) { + // Basic Auth (Probably a good idea to not support this unless this is an old version of Intel AMT) + obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x01) + IntToStrX(obj.user.length + obj.pass.length + 2) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(obj.pass.length) + obj.pass); + } + else obj.Stop(2); + // ###BEGIN###{Mode-NodeWebkit} } - else if (authData.indexOf(3) >= 0) { - // Bad Digest Auth (Not sure why this is supported, cnonce is not used!) - obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x03) + IntToStrX(obj.user.length + obj.authuri.length + 7) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(0x00, 0x00) + String.fromCharCode(obj.authuri.length) + obj.authuri + String.fromCharCode(0x00, 0x00, 0x00)); - } - else if (authData.indexOf(1) >= 0) { - // Basic Auth (Probably a good idea to not support this unless this is an old version of Intel AMT) - obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x01) + IntToStrX(obj.user.length + obj.pass.length + 2) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(obj.pass.length) + obj.pass); - } - else obj.Stop(2); + // ###END###{Mode-NodeWebkit} } else if (((authType == 3) || (authType == 4)) && (status == 1)) { var curptr = 0; @@ -261,7 +299,15 @@ var CreateAmtRedirect = function (module) { } } - obj.directSend = function (arr) { try { obj.socket.write(new Buffer(arr)); } catch (ex) { console.log(ex); } } + obj.directSend = function (arr) { + // Redirection tracing + if (urlvars && urlvars['redirtrace']) { + var datastr = arrToStr(new Uint8Array(arr)); + console.log('REDIR-DSEND(' + datastr.length + '): ' + rstr2hex(datastr)); + } + + try { obj.socket.write(new Buffer(arr)); } catch (ex) { console.log(ex); } + } obj.xxSend = function (x) { if (urlvars && urlvars['redirtrace']) { console.log('REDIR-SEND(' + x.length + '): ' + rstr2hex(x)); } diff --git a/amt-wsman-node-0.2.0.js b/amt-wsman-node-0.2.0.js index c03cc34..6bcd37c 100644 --- a/amt-wsman-node-0.2.0.js +++ b/amt-wsman-node-0.2.0.js @@ -206,12 +206,13 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions) { } // Get the certificate of Intel AMT - obj.getPeerCertificate = function () { if (obj.xtls == 1) { return obj.socket.getPeerCertificate(); } return null; } - obj.getPeerCertificateFingerprint = function () { if (obj.xtls == 1) { return obj.socket.getPeerCertificate().fingerprint.split(':').join('').toLowerCase(); } return null; } + obj.getPeerCertificate = function () { if (obj.xtls == 1) { return obj.xtlsCertificate; } return null; } + obj.getPeerCertificateFingerprint = function () { if (obj.xtls == 1) { return obj.xtlsCertificate.fingerprint.split(':').join('').toLowerCase(); } return null; } // NODE.js specific private method obj.xxOnSocketConnected = function () { if (obj.socket == null) return; + obj.localAddress = obj.socket.localAddress; // Store the local address of this socket, useful for UEFI HTTPS boot if (obj.xtls == 1) { obj.xtlsCertificate = obj.socket.getPeerCertificate(); diff --git a/index.html b/index.html index b6ebb6a..6b534dc 100644 --- a/index.html +++ b/index.html @@ -7779,6 +7779,11 @@ // ###BEGIN###{Mode-MeshCentral2} QV('termRecordIcon', false); // ###END###{Mode-MeshCentral2} + if (terminal.disconnectCode == 2) { // BUSY + messagebox("Remote Terminal", "The remote device is busy, a session may already be open."); + } else if (terminal.disconnectCode == 3) { // UNSUPPORTED + messagebox("Remote Terminal", "The device indicated that this type of connection of not supported."); + } break; case 3: // ###BEGIN###{Mode-MeshCentral2} @@ -8180,6 +8185,13 @@ // ###BEGIN###{Mode-MeshCentral2} QV('deskRecordIcon', false); // ###END###{Mode-MeshCentral2} + if (desktop.disconnectCode == 2) { // BUSY + messagebox("Remote Desktop", "The remote device is busy, a session may already be open."); + } else if (desktop.disconnectCode == 3) { // UNSUPPORTED + messagebox("Remote Desktop", "The device indicated that this type of connection of not supported."); + } else if (desktop.disconnectCode == 50000) { // KVM-Disconnect + messagebox("Remote Desktop", "KVM disconnection, they may indicate that Intel AMT is unable to capture the display (Try RLE8 encoding), or unsupported GPU."); + } break; case 3: // ###BEGIN###{DesktopInband} @@ -8402,11 +8414,21 @@ // Toggle desktop session recording function deskClipboard() { if (xxdialogMode || (desktop == null) || (desktop.State != 3)) return; - setDialogMode(11, "Clipboard", 3, deskClipboardEx, "Enter text to send to Intel® AMT clipboard." + '