Added Intel AMT features.

This commit is contained in:
Ylian Saint-Hilaire 2018-09-28 15:27:26 -07:00
parent 8d45bcdde9
commit d3902e5766
7 changed files with 219 additions and 14 deletions

View File

@ -60,6 +60,7 @@
<Compile Include="meshrelay.js" />
<Compile Include="meshuser.js" />
<Compile Include="mpsserver.js" />
<Compile Include="public\scripts\agent-redir-rtc-0.1.0.js" />
<Compile Include="swarmserver.js" />
<Compile Include="multiserver.js" />
<Compile Include="pass.js" />

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.2.1-z",
"version": "0.2.2-b",
"keywords": [
"Remote Management",
"Intel AMT",

View File

@ -0,0 +1,106 @@
/**
* @description Mesh Agent Transport Module - using websocket relay
* @author Ylian Saint-Hilaire
* @version v0.0.1
*/
// Construct a MeshServer agent direction object
var CreateKvmDataChannel = function (webchannel, module, keepalive) {
var obj = {};
obj.m = module; // This is the inner module (Terminal or Desktop)
module.parent = obj;
obj.webchannel = webchannel;
obj.State = 0;
obj.protocol = module.protocol; // 1 = SOL, 2 = KVM, 3 = IDER, 4 = Files, 5 = FileTransfer
obj.onStateChanged = null;
obj.onControlMsg = null;
obj.debugmode = 0;
obj.keepalive = keepalive;
obj.rtcKeepAlive = null;
// Private method
//obj.debug = function (msg) { console.log(msg); }
obj.Start = function () {
if (obj.debugmode == 1) { console.log('start'); }
obj.xxStateChange(3);
obj.webchannel.onmessage = obj.xxOnMessage;
obj.rtcKeepAlive = setInterval(obj.xxSendRtcKeepAlive, 30000);
}
obj.xxOnMessage = function (e) {
//if (obj.debugmode == 1) { console.log('Recv', e.data); }
//if (urlvars && urlvars['webrtctrace']) { console.log('WebRTC-Recv(' + obj.State + '): ', typeof e.data, e.data); }
if (typeof e.data == 'string') { if (obj.onControlMsg != null) { obj.onControlMsg(e.data); } return; } // If this is a control message, handle it here.
if (typeof e.data == 'object') {
var f = new FileReader();
if (f.readAsBinaryString) {
// Chrome & Firefox (Draft)
f.onload = function (e) { obj.xxOnSocketData(e.target.result); }
f.readAsBinaryString(new Blob([e.data]));
} else if (f.readAsArrayBuffer) {
// Chrome & Firefox (Spec)
f.onloadend = function (e) { obj.xxOnSocketData(e.target.result); }
f.readAsArrayBuffer(e.data);
} else {
// IE10, readAsBinaryString does not exist, use an alternative.
var binary = '', bytes = new Uint8Array(e.data), length = bytes.byteLength;
for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); }
obj.xxOnSocketData(binary);
}
} else {
// If we get a string object, it maybe the WebRTC confirm. Ignore it.
//obj.debug("Agent Redir Relay - OnData - " + typeof e.data + " - " + e.data.length);
obj.xxOnSocketData(e.data);
}
};
obj.xxOnSocketData = function (data) {
if (!data) return;
if (typeof data === 'object') {
// This is an ArrayBuffer, convert it to a string array (used in IE)
var binary = "", bytes = new Uint8Array(data), length = bytes.byteLength;
for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); }
data = binary;
}
else if (typeof data !== 'string') return;
//console.log("xxOnSocketData", rstr2hex(data));
return obj.m.ProcessData(data);
}
// Send a control message over the WebRTC data channel
obj.sendCtrlMsg = function (x) {
if (typeof x == 'string') {
obj.webchannel.send(x);
//if (urlvars && urlvars['webrtctrace']) { console.log('WebRTC-Send(' + obj.State + '): ', typeof x, x); }
if (obj.keepalive != null) obj.keepalive.sendKeepAlive();
}
}
// Send a binary message over the WebRTC data channel
obj.send = function (x) {
if (typeof x == 'string') { var b = new Uint8Array(x.length); for (var i = 0; i < x.length; ++i) { b[i] = x.charCodeAt(i); } x = b; }
//if (urlvars && urlvars['webrtctrace']) { console.log('WebRTC-Send(' + obj.State + '): ', typeof x, x); }
obj.webchannel.send(x);
}
obj.xxStateChange = function(newstate) {
if (obj.State == newstate) return;
obj.State = newstate;
obj.m.xxStateChange(obj.State);
if (obj.onStateChanged != null) obj.onStateChanged(obj, obj.State);
}
obj.Stop = function () {
if (obj.debugmode == 1) { console.log('stop'); }
if (obj.rtcKeepAlive != null) { clearInterval(obj.rtcKeepAlive); obj.rtcKeepAlive = null; }
obj.xxStateChange(0);
}
obj.xxSendRtcKeepAlive = function () {
//if (urlvars && urlvars['webrtctrace']) { console.log('WebRTC-SendKeepAlive()'); }
obj.sendCtrlMsg(JSON.stringify({ action: 'ping' }));
}
return obj;
}

View File

@ -622,7 +622,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.kvmDataSupported == false) { obj.kvmDataSupported = true; console.log('KVM Data Channel Supported.'); }
if (((obj.onKvmDataAck == -1) && (d.length == 16)) || (d.charCodeAt(15) != 0)) { obj.onKvmDataAck = true; }
//if (urlvars && urlvars['kvmdatatrace']) { console.log('KVM-Recv(' + (d.length - 16) + '): ' + d.substring(16)); }
if (d.length > 16) { obj.onKvmData(d.substring(16)); } // Event the data and ack
if (d.length >= 16) { obj.onKvmData(d.substring(16)); } // Event the data and ack
if ((obj.onKvmDataAck == true) && (obj.onKvmDataPending.length > 0)) { obj.sendKvmData(obj.onKvmDataPending.shift()); } // Send pending data
}
}
@ -635,16 +635,16 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.onKvmDataAck !== true) {
obj.onKvmDataPending.push(x);
} else {
if (urlvars && urlvars['kvmdatatrace']) { console.log('KVM-Send(' + x.length + '): ' + x); }
//if (urlvars && urlvars['kvmdatatrace']) { console.log('KVM-Send(' + x.length + '): ' + x); }
x = '\0KvmDataChannel\0' + x;
obj.Send(String.fromCharCode(6, 0, 0, 0) + IntToStr(x.length) + x);
obj.send(String.fromCharCode(6, 0, 0, 0) + IntToStr(x.length) + x);
obj.onKvmDataAck = false;
}
}
// Send a HWKVM keep alive if it's not been sent in the last 5 seconds.
obj.sendKeepAlive = function () {
if (obj.lastKeepAlive < Date.now() - 5000) { obj.lastKeepAlive = Date.now(); obj.Send(String.fromCharCode(6, 0, 0, 0) + IntToStr(16) + '\0KvmDataChannel\0'); }
if (obj.lastKeepAlive < Date.now() - 5000) { obj.lastKeepAlive = Date.now(); obj.send(String.fromCharCode(6, 0, 0, 0) + IntToStr(16) + '\0KvmDataChannel\0'); }
}
// ###END###{DesktopInband}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -22,6 +22,7 @@
<script type="text/javascript" src="scripts/amt-redir-ws-0.1.0.js"></script>
<script type="text/javascript" src="scripts/amt-wsman-ws-0.2.0.js"></script>
<script type="text/javascript" src="scripts/agent-redir-ws-0.1.0.js"></script>
<script type="text/javascript" src="scripts/agent-redir-rtc-0.1.0.js"></script>
<script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
<script keeplink=1 type="text/javascript" src="scripts/charts.js"></script>
<script keeplink=1 type="text/javascript" src="scripts/filesaver.1.1.20151003.js"></script>
@ -1958,7 +1959,7 @@
desk.m.bpp = 1;
desk.m.useZRLE = true;
desk.m.showmouse = true;
desk.m.onKvmData = function (data) { console.log('KVMData: ' + data); };
desk.m.onKvmData = function (data) { console.log('KVM Data received in multi-desktop mode, this is not supported.'); }; // KVM Data Channel not supported in multi-desktop right now.
//desk.m.onScreenSizeChange = deskAdjust;
desk.Start(nodeid, 16994, '*', '*', 0);
desk.contype = 2;
@ -3629,7 +3630,7 @@
// Show the right settings
QV('d7amtkvm', (currentNode.intelamt != null && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))) && ((deskState == 0) || (desktop.contype == 2)));
QV('d7meshkvm', (mesh.mtype == 2) && (currentNode.agent.caps & 1) && ((deskState == false) || (desktop.contype == 1)));
QV('d7meshkvm', (webRtcDesktop) || ((mesh.mtype == 2) && (currentNode.agent.caps & 1) && ((deskState == false) || (desktop.contype == 1))));
// Enable buttons
var online = ((currentNode.conn & 1) != 0); // If Agent (1) connected, enable remote desktop
@ -3666,7 +3667,77 @@
desktop.m.useZRLE = (desktopsettings.encoding < 3);
desktop.m.showmouse = desktopsettings.showmouse;
desktop.m.onScreenSizeChange = deskAdjust;
desktop.m.onKvmData = function (data) { console.log('KVMData: ' + data); };
desktop.m.onKvmData = function (x) {
//console.log('onKvmData (' + x.length + '): ' + x);
// Send the presense probe only once if needed.
if (x.length == 0) { if (!desktop.m._sentPresence) { desktop.m._sentPresence = true; desktop.m.sendKvmData(JSON.stringify({ action: 'present', ver: 1 })); } return; }
var data = null;
try { data = JSON.parse(x); } catch (e) { }
if ((data != null) && (data.action != null)) {
if (data.action == 'restart') {
// Clear WebRTC channel
webRtcDesktopReset();
desktop.m.sendKvmData(JSON.stringify({ action: 'present', ver: 1 }));
} else if ((data.action == 'present') && (webRtcDesktop == null)) {
// Setup WebRTC channel
webRtcDesktop = { platform: data.platform };
var configuration = null; //{ "iceServers": [ { 'urls': 'stun:stun.services.mozilla.com' }, { 'urls': 'stun:stun.l.google.com:19302' } ] };
if (typeof RTCPeerConnection !== 'undefined') { webRtcDesktop.webrtc = new RTCPeerConnection(configuration); }
else if (typeof webkitRTCPeerConnection !== 'undefined') { webRtcDesktop.webrtc = new webkitRTCPeerConnection(configuration); }
webRtcDesktop.webchannel = webRtcDesktop.webrtc.createDataChannel("DataChannel", {}); // { ordered: false, maxRetransmits: 2 }
webRtcDesktop.webchannel.onopen = function () {
// Switch to software KVM
//if (urlvars && urlvars['kvmdatatrace']) { console.log('WebRTC Data Channel Open'); }
console.log('WebRTC Data Channel Open');
Q('deskstatus').textContent = StatusStrs[desktop.State] + ', Soft-KVM';
desktop.m.hold(true);
webRtcDesktop.webRtcActive = true;
webRtcDesktop.softdesktop = CreateKvmDataChannel(webRtcDesktop.webchannel, CreateAgentRemoteDesktop('Desk', Q('id_mainarea')), desktop.m);
webRtcDesktop.softdesktop.m.setRotation(desktop.m.rotation);
webRtcDesktop.softdesktop.m.onScreenSizeChange = deskAdjust;
if (desktopsettings.quality) { webRtcDesktop.softdesktop.m.CompressionLevel = desktopsettings.quality; } // Number from 1 to 100. 50 or less is best.
if (desktopsettings.scaling) { webRtcDesktop.softdesktop.m.ScalingLevel = desktopsettings.scaling; }
webRtcDesktop.softdesktop.Start();
// Check if we can get remote file access
// ###BEGIN###{DesktopInbandFiles}
/*
QV('go24', true); // Files
downloadFile = null;
p24files = webRtcDesktop.softdesktop;
p24targetpath = '';
webRtcDesktop.softdesktop.onControlMsg = onFilesControlData;
webRtcDesktop.softdesktop.sendCtrlMsg(JSON.stringify({ action: 'ls', reqid: 1, path: '' })); // Ask for the root folder
*/
// ###END###{DesktopInbandFiles}
}
webRtcDesktop.webchannel.onclose = function (event) {
//if (urlvars['kvmdatatrace']) { console.log('WebRTC Data Channel Closed'); }
console.log('WebRTC Data Channel Closed');
webRtcDesktopReset();
}
webRtcDesktop.webrtc.onicecandidate = function (e) {
if (e.candidate == null) {
desktop.m.sendKvmData(JSON.stringify({ action: 'offer', ver: 1, sdp: webRtcDesktop.webrtcoffer.sdp }));
} else {
webRtcDesktop.webrtcoffer.sdp += ("a=" + e.candidate.candidate + "\r\n"); // New candidate, add it to the SDP
}
}
webRtcDesktop.webrtc.oniceconnectionstatechange = function () {
if ((webRtcDesktop != null) && (webRtcDesktop.webrtc != null) && ((webRtcDesktop.webrtc.iceConnectionState == 'disconnected') || (webRtcDesktop.webrtc.iceConnectionState == 'failed'))) { /*console.log('WebRTC ICE Failed');*/ webRtcDesktopReset(); }
}
webRtcDesktop.webrtc.createOffer(function (offer) {
// Got the offer
webRtcDesktop.webrtcoffer = offer;
webRtcDesktop.webrtc.setLocalDescription(offer, function () { }, webRtcDesktopReset);
}, webRtcDesktopReset, { mandatory: { OfferToReceiveAudio: false, OfferToReceiveVideo: false } });
} else if ((data.action == 'answer') && (webRtcDesktop != null)) {
// Complete the WebRTC channel
webRtcDesktop.webrtc.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp: data.sdp }), function () { }, webRtcDesktopReset);
}
}
};
desktop.Start(desktopNode._id, 16994, '*', '*', 0);
desktop.contype = 2;
} else {
@ -3687,10 +3758,34 @@
} else {
// Disconnect and clean up the remote desktop
desktop.Stop();
webRtcDesktopReset();
desktopNode = desktop = null;
}
}
var webRtcDesktop = null;
function webRtcDesktopReset() {
if (webRtcDesktop == null) return;
if (webRtcDesktop.softdesktop != null) { webRtcDesktop.softdesktop.Stop(); webRtcDesktop.softdesktop = null; }
if (webRtcDesktop.webchannel != null) { try { webRtcDesktop.webchannel.close(); } catch (e) { } webRtcDesktop.webchannel = null; }
if (webRtcDesktop.webrtc != null) { try { webRtcDesktop.webrtc.close(); } catch (e) { } webRtcDesktop.webrtc = null; }
webRtcDesktop = null;
// Switch back to hardware KVM
if (desktop && desktop.m) {
desktop.m.hold(false);
Q('deskstatus').textContent = StatusStrs[desktop.State];
}
// ###BEGIN###{DesktopInbandFiles}
/*
p24files = null;
p24downloadFileCancel() // If any downloads are in process, cancel them.
p24uploadFileCancel(); // If any uploads are in process, cancel them.
QV('go24', false); // Files
if (currentView == 24) { go(14); }
*/
// ###END###{DesktopInbandFiles}
}
function onDesktopStateChange(xdesktop, state) {
var xstate = state;
if ((xstate == 3) && (xdesktop.contype == 2)) { xstate++; }
@ -3707,6 +3802,7 @@
QV('termdisplays', false);
deskFocusBtn.value = 'All Focus';
if (fullscreen == true) { deskToggleFull(); }
webRtcDesktopReset();
break;
case 2:
break;
@ -3809,6 +3905,7 @@
var mh = (Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - (Q('deskarea1').clientHeight + Q('deskarea2').clientHeight + Q('deskarea4').clientHeight));
var mw = 9999;
if (desktop) { mw = (desktop.m.width / desktop.m.height) * mh; }
if (webRtcDesktop && webRtcDesktop.softdesktop) { mw = (webRtcDesktop.softdesktop.m.width / webRtcDesktop.softdesktop.m.height) * mh; }
QS('Desk')['max-height'] = mh + 'px';
QS('Desk')['max-width'] = mw + 'px';
x = 0;
@ -3821,6 +3918,7 @@
} else {
var mw = 9999, mh = (Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - (webPageFullScreen?276:290));
if (desktop) { mw = (desktop.m.width / desktop.m.height) * mh; }
if (webRtcDesktop && webRtcDesktop.softdesktop) { mw = (webRtcDesktop.softdesktop.m.width / webRtcDesktop.softdesktop.m.height) * mh; }
document.documentElement.style.overflow = 'auto';
QS('Desk')['max-height'] = mh + 'px';
QS('Desk')['max-width'] = mw + 'px';
@ -3945,10 +4043,10 @@
desktop.m.SetDisplay(display);
}
function dmousedown(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) desktop.m.mousedown(e) }
function dmouseup(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) desktop.m.mouseup(e) }
function dmousemove(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) desktop.m.mousemove(e) }
function dmousewheel(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked && desktop.m.mousewheel) { desktop.m.mousewheel(e); haltEvent(e); return true; } return false; }
function dmousedown(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedown(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedown(e); } }
function dmouseup(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mouseup(e); desktop.m.sendKeepAlive(); } else { desktop.m.mouseup(e); } }
function dmousemove(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousemove(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousemove(e); } } }
function dmousewheel(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousewheel(e); desktop.m.sendKeepAlive(); } else { if (desktop.m.mousewheel) { desktop.m.mousewheel(e); } } haltEvent(e); return true; } return false; }
function drotate(x) { if (!xxdialogMode && desktop != null) { desktop.m.setRotation(desktop.m.rotation + x); deskAdjust(); deskAdjust(); } }
function stopProcess(id, name) { setDialogMode(2, "Process Control", 3, stopProcessEx, 'Stop process #' + id + ' "' + name + '"?', id); }
function stopProcessEx(buttons, tag) { meshserver.send({ action: 'msg', type:'pskill', nodeid: currentNode._id, value: tag }); setTimeout(refreshDeskTools, 300); }