Improved file transfers, added file downloads over WebRTC.

Ylian Saint-Hilaire committed Feb 11, 2018 at 17:13 UTC 0c3c0973bc61091bc94f67e03a9fcfe8008ebb33
28 files changed +579 -230
agents/MeshService.exe
Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ
agents/MeshService64.exe
Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ
agents/meshagent_arm
Binary files a/agents/meshagent_arm and b/agents/meshagent_arm differ
agents/meshagent_pi
Binary files a/agents/meshagent_pi and b/agents/meshagent_pi differ
agents/meshagent_pogo
Binary files a/agents/meshagent_pogo and b/agents/meshagent_pogo differ
agents/meshagent_poky
Binary files a/agents/meshagent_poky and b/agents/meshagent_poky differ
agents/meshagent_poky64
Binary files a/agents/meshagent_poky64 and b/agents/meshagent_poky64 differ
agents/meshagent_x86
Binary files a/agents/meshagent_x86 and b/agents/meshagent_x86 differ
agents/meshagent_x86-64
Binary files a/agents/meshagent_x86-64 and b/agents/meshagent_x86-64 differ
agents/meshagent_x86-64_nokvm
Binary files a/agents/meshagent_x86-64_nokvm and b/agents/meshagent_x86-64_nokvm differ
agents/meshagent_x86_nokvm
Binary files a/agents/meshagent_x86_nokvm and b/agents/meshagent_x86_nokvm differ
agents/meshcmd.js
+1 -1
@@ -391,7 +391,7 @@ function startLms(func) {
391 //var xx = AllWsman[4];
392 //console.log(xx);
393 //osamtstack.Get(AllWsmanRequests.shift(), startLmsWsmanResponse, null, true);
394 - osamtstack.Get('IPS_SecIOService', startLmsWsmanResponse, null, true);
394 + //osamtstack.Get('IPS_SecIOService', startLmsWsmanResponse, null, true);
395 //osamtstack.BatchEnum(null, ['IPS_KVMRedirectionSettingData', 'CIM_SoftwareIdentity'], startLmsWsmanResponse, null, true);
396 //osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true);
397 });
agents/meshcore.js
+114 -83
@@ -31,7 +31,7 @@ function createMeshCore(agent) {
31 var fs = require('fs');
32 var rtc = require('ILibWebRTC');
33 var amtMei = null, amtLms = null, amtLmsState = 0;
34 - var amtMeiConnected = 0, amtMeiState = null, amtMeiTmpState = null;
34 + var amtMeiConnected = 0, amtMeiTmpState = null;
35 var wifiScannerLib = null;
36 var wifiScanner = null;
37 var networkMonitor = null;
@@ -77,7 +77,7 @@ function createMeshCore(agent) {
77 amtMeiConnected = 1;
78 amtMei = new amtMeiLib();
79 amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; sendPeriodicServerUpdate(); });
80 - amtMei.on('connect', function () { amtMeiConnected = 2; getAmtInfo(); });
80 + amtMei.on('connect', function () { amtMeiConnected = 2; sendPeriodicServerUpdate(); });
81 } catch (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; }
82
83 // Try to load up the WIFI scanner
@@ -403,7 +403,7 @@ function createMeshCore(agent) {
403 // List all the drives in the root, or the root itself
404 var results = null;
405 try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
406 - //console.log('a', objToString(results, 0, '.'));
406 + //console.log('a', objToString(results, 0, ' '));
407 if (results != null) {
408 for (var i = 0; i < results.length; ++i) {
409 var drive = { n: results[i].name, t: 1 };
@@ -515,6 +515,7 @@ function createMeshCore(agent) {
515 this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data
516 return;
517 }
518 + /*
519 // If this is a download, send more of the file
520 if (this.httprequest.downloadFile) {
521 var buf = new Buffer(4096);
@@ -523,14 +524,15 @@ function createMeshCore(agent) {
524 if (len > 0) { this.write(buf.slice(0, len)); } else { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; this.end(); }
525 return;
526 }
526 -
527 + */
528 +
529 if (this.httprequest.state == 0) {
530 // Check if this is a relay connection
531 if (data == 'c') { this.httprequest.state = 1; sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid); }
532 } else {
533 // Handle tunnel data
534 if (this.httprequest.protocol == 0) { // 1 = SOL, 2 = KVM, 3 = IDER, 4 = Files, 5 = FileTransfer
533 - // Take a look at the protocolab
535 + // Take a look at the protocol
536 this.httprequest.protocol = parseInt(data);
537 if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; }
538 if (this.httprequest.protocol == 1) {
@@ -550,8 +552,7 @@ function createMeshCore(agent) {
552 this.on('data', onTunnelControlData);
553 //this.write('MeshCore Terminal Hello');
554 if (process.platform != 'win32') { this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nclear\n"); }
553 - }
554 - if (this.httprequest.protocol == 2) {
555 + } else if (this.httprequest.protocol == 2) {
556 // Remote desktop using native pipes
557 this.httprequest.desktop = { state: 0, kvm: mesh.getRemoteDesktopStream(), tunnel: this };
558 this.httprequest.desktop.kvm.parent = this.httprequest.desktop;
@@ -568,8 +569,7 @@ function createMeshCore(agent) {
569 this.removeAllListeners('data');
570 this.on('data', onTunnelControlData);
571 //this.write('MeshCore KVM Hello!1');
571 - }
572 - else if (this.httprequest.protocol == 5) {
572 + } else if (this.httprequest.protocol == 5) {
573 // Setup files
574 // NOP
575 }
@@ -579,7 +579,6 @@ function createMeshCore(agent) {
579 this.httprequest.process.write(data);
580 } else if (this.httprequest.protocol == 2) {
581 // Send data into remote desktop
582 - // TODO ADD REMOTE DESKTOP (This is test code)
582 if (this.httprequest.desktop.state == 0) {
583 this.write(new Buffer(String.fromCharCode(0x11, 0xFE, 0x00, 0x00, 0x4D, 0x45, 0x53, 0x48, 0x00, 0x00, 0x00, 0x00, 0x02)));
584 this.httprequest.desktop.state = 1;
@@ -590,9 +589,13 @@ function createMeshCore(agent) {
589 // Process files commands
590 var cmd = null;
591 try { cmd = JSON.parse(data); } catch (e) { };
593 - if ((cmd == null) || (cmd.action == undefined)) { return; }
592 + if (cmd == null) { return; }
593 + if ((cmd.ctrlChannel == '102938') || ((cmd.type == 'offer') && (cmd.sdp != null))) { onTunnelControlData(cmd, this); return; } // If this is control data, handle it now.
594 + if (cmd.action == undefined) { return; }
595 + //sendConsoleText('CMD: ' + JSON.stringify(cmd));
596 +
597 if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
595 - //console.log(objToString(cmd, 0, '.'));
598 + //console.log(objToString(cmd, 0, ' '));
599 switch (cmd.action) {
600 case 'ls': {
601 /*
@@ -642,6 +645,36 @@ function createMeshCore(agent) {
645 try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
646 break;
647 }
648 + case 'download': {
649 + // Download a file
650 + var sendNextBlock = 0;
651 + if (cmd.sub == 'start') { // Setup the download
652 + if (this.filedownload != null) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
653 + this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
654 + try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
655 + if (this.filedownload) { this.write({ action: 'download', sub: 'start', id: cmd.id }); }
656 + } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
657 + if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
658 + }
659 + // Send the next download block(s)
660 + while (sendNextBlock > 0) {
661 + sendNextBlock--;
662 + var buf = new Buffer(4096);
663 + buf.writeInt32BE(0x01020304, 0);
664 + var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null);
665 + this.filedownload.ptr += len;
666 + if (len > 0) {
667 + this.write(buf.slice(0, len + 4)); // Write as binary
668 + } else {
669 + fs.closeSync(this.filedownload.f);
670 + this.write({ action: 'download', sub: 'done', id: this.filedownload.id });
671 + delete this.filedownload;
672 + sendNextBlock = 0;
673 + }
674 + }
675 + break;
676 + }
677 + /*
678 case 'download': {
679 // Packet download of a file, agent to browser
680 if (cmd.path == undefined) break;
@@ -662,6 +695,7 @@ function createMeshCore(agent) {
695 this.httprequest.downloadFile.end = function () { }
696 break;
697 }
698 + */
699 case 'upload': {
700 // Upload a file, browser to agent
701 if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
@@ -691,65 +725,61 @@ function createMeshCore(agent) {
725 }
726
727 // Called when receiving control data on websocket
694 - function onTunnelControlData(data) {
695 - if (typeof data != 'string') return;
696 - //sendConsoleText('onTunnelControlData: ' + data);
697 - //console.log('onTunnelControlData: ' + data);
698 -
728 + function onTunnelControlData(data, ws) {
729 var obj;
700 - try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON'); return; }
730 + if (ws == null) { ws = this; }
731 + if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON'); return; } }
732 + else if (typeof data == 'object') { obj = data; } else { return; }
733 + //sendConsoleText('onTunnelControlData(' + ws.httprequest.protocol + '): ' + JSON.stringify(data));
734 + //console.log('onTunnelControlData: ' + JSON.stringify(data));
735
736 if (obj.type == 'close') {
737 // We received the close on the websocket
704 - //sendConsoleText('Tunnel #' + this.tunnel.index + ' WebSocket control close');
705 - try { this.close(); } catch (e) { }
738 + //sendConsoleText('Tunnel #' + ws.tunnel.index + ' WebSocket control close');
739 + try { ws.close(); } catch (e) { }
740 } else if (obj.type == 'webrtc0') { // Browser indicates we can start WebRTC switch-over.
707 - if (this.websocket.httprequest.protocol == 1) { // Terminal
741 + if (ws.httprequest.protocol == 1) { // Terminal
742 // This is a terminal data stream, unpipe the terminal now and indicate to the other side that terminal data will no longer be received over WebSocket
709 - this.websocket.httprequest.process.stdout.unpipe(this.websocket);
710 - this.websocket.httprequest.process.stderr.unpipe(this.websocket);
711 - this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker
712 - } else if (this.websocket.httprequest.protocol == 2) { // Desktop
743 + ws.httprequest.process.stdout.unpipe(ws);
744 + ws.httprequest.process.stderr.unpipe(ws);
745 + } else if (ws.httprequest.protocol == 2) { // Desktop
746 // This is a KVM data stream, unpipe the KVM now and indicate to the other side that KVM data will no longer be received over WebSocket
714 - this.websocket.httprequest.desktop.kvm.unpipe(this.websocket);
715 - this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker
716 - }
717 - /*
718 - else {
719 - // Debug, just display on agent console
720 - rtcchannel.on('data', function (buffer) { sendConsoleText("RTCReceived: " + buffer.length + " bytes"); });
721 - rtcchannel.on('end', function () { sendConsoleText("RTCChannel: " + this.name + " was closed"); });
722 - channel.write('WebRTC HELLO!');
747 + ws.httprequest.desktop.kvm.unpipe(ws);
748 + } else {
749 + // Switch things around so all WebRTC data goes to onTunnelData().
750 + ws.rtcchannel.httprequest = ws.httprequest;
751 + ws.rtcchannel.removeAllListeners('data');
752 + ws.rtcchannel.on('data', onTunnelData);
753 }
724 - */
754 + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc1\"}"); // End of data marker
755 } else if (obj.type == 'webrtc1') {
726 - if (this.httprequest.protocol == 1) { // Terminal
756 + if (ws.httprequest.protocol == 1) { // Terminal
757 // Switch the user input from websocket to webrtc at this point.
728 - this.unpipe(this.httprequest.process.stdin);
729 - this.rtcchannel.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
730 - this.resume(); // Resume the websocket to keep receiving control data
731 - } else if (this.httprequest.protocol == 2) { // Desktop
758 + ws.unpipe(ws.httprequest.process.stdin);
759 + ws.rtcchannel.pipe(ws.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
760 + ws.resume(); // Resume the websocket to keep receiving control data
761 + } else if (ws.httprequest.protocol == 2) { // Desktop
762 // Switch the user input from websocket to webrtc at this point.
733 - this.unpipe(this.httprequest.desktop.kvm);
734 - try { this.webrtc.rtcchannel.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1 }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text.
735 - this.resume(); // Resume the websocket to keep receiving control data
763 + ws.unpipe(ws.httprequest.desktop.kvm);
764 + try { ws.webrtc.rtcchannel.pipe(ws.httprequest.desktop.kvm, { dataTypeSkip: 1 }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text.
765 + ws.resume(); // Resume the websocket to keep receiving control data
766 }
737 - this.write("{\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point.
767 + ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point.
768 } else if (obj.type == 'webrtc2') {
769 // Other side received websocket end of data marker, start sending data on WebRTC channel
740 - if (this.httprequest.protocol == 1) { // Terminal
741 - this.httprequest.process.stdout.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
742 - this.httprequest.process.stderr.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
743 - } else if (this.httprequest.protocol == 2) { // Desktop
744 - this.httprequest.desktop.kvm.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
770 + if (ws.httprequest.protocol == 1) { // Terminal
771 + ws.httprequest.process.stdout.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
772 + ws.httprequest.process.stderr.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
773 + } else if (ws.httprequest.protocol == 2) { // Desktop
774 + ws.httprequest.desktop.kvm.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
775 }
776 } else if (obj.type == 'offer') {
777 // This is a WebRTC offer.
748 - this.webrtc = rtc.createConnection();
749 - this.webrtc.websocket = this;
750 - this.webrtc.on('connected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected');*/ });
751 - this.webrtc.on('disconnected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected');*/ });
752 - this.webrtc.on('dataChannel', function (rtcchannel) {
778 + ws.webrtc = rtc.createConnection();
779 + ws.webrtc.websocket = ws;
780 + ws.webrtc.on('connected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected');*/ });
781 + ws.webrtc.on('disconnected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected');*/ });
782 + ws.webrtc.on('dataChannel', function (rtcchannel) {
783 //sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
784 rtcchannel.xrtc = this;
785 rtcchannel.websocket = this.websocket;
@@ -757,9 +787,9 @@ function createMeshCore(agent) {
787 this.websocket.rtcchannel = rtcchannel;
788 this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData);
789 this.websocket.rtcchannel.on('end', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed');*/ });
760 - this.websocket.write("{\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over.
790 + this.websocket.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over.
791 });
762 - this.write({ type: "answer", sdp: this.webrtc.setOffer(obj.sdp) });
792 + ws.write({ type: 'answer', ctrlChannel: '102938', sdp: ws.webrtc.setOffer(obj.sdp) });
793 }
794 }
795
@@ -804,19 +834,19 @@ function createMeshCore(agent) {
834 case 'info': { // Return information about the agent and agent core module
835 response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform Info: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nServer URL: ' + mesh.ServerUrl + '.';
836 if (amtLmsState >= 0) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; }
807 - response += '\r\nModules: ' + JSON.stringify(addedModules) + '';
808 - response += '\r\nServerConnected: ' + mesh.isControlChannelConnected + '';
837 + response += '\r\nModules: ' + addedModules.join(', ');
838 + response += '\r\nServerConnected: ' + mesh.isControlChannelConnected;
839 var oldNodeId = db.Get('OldNodeId');
840 if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; }
841 response += '\r\ServerState: ' + meshServerConnectionState + '.';
842 break;
843 }
844 case 'selfinfo': { // Return self information block
815 - response = JSON.stringify(buildSelfInfo());
845 + buildSelfInfo(function (info) { sendConsoleText(objToString(info, 0, ' '), sessionid); });
846 break;
847 }
848 case 'args': { // Displays parsed command arguments
819 - response = 'args ' + objToString(args, 0, '.');
849 + response = 'args ' + objToString(args, 0, ' ');
850 break;
851 }
852 case 'print': { // Print a message on the mesh agent console, does nothing when running in the background
@@ -986,17 +1016,17 @@ function createMeshCore(agent) {
1016 break;
1017 }
1018 case 'amt': { // Show Intel AMT status
989 - if (amtMeiState != null) {
990 - response = objToString(amtMeiState, 0, '.');
991 - } else {
992 - response = 'This mesh agent does not support Intel AMT.';
993 - }
1019 + getAmtInfo(function (state) {
1020 + var resp = 'Intel AMT not detected.';
1021 + if (state != null) { resp = objToString(state, 0, ' '); }
1022 + sendConsoleText(resp, sessionid);
1023 + });
1024 break;
1025 }
1026 case 'netinfo': { // Show network interface information
997 - //response = objToString(mesh.NetInfo, 0, '.');
1027 + //response = objToString(mesh.NetInfo, 0, ' ');
1028 var interfaces = require('os').networkInterfaces();
999 - response = objToString(interfaces, 0, '.');
1029 + response = objToString(interfaces, 0, ' ');
1030 break;
1031 }
1032 case 'wakeonlan': { // Send wake-on-lan
@@ -1027,7 +1057,7 @@ function createMeshCore(agent) {
1057 }
1058 case 'location': {
1059 getIpLocationData(function (location) {
1030 - sendConsoleText(objToString({ "action": "iplocation", "type": "publicip", "value": location }, 0, '.'));
1060 + sendConsoleText(objToString({ "action": "iplocation", "type": "publicip", "value": location }, 0, ' '));
1061 });
1062 break;
1063 }
@@ -1108,20 +1138,19 @@ function createMeshCore(agent) {
1138
1139 // Build a bunch a self information data that will be sent to the server
1140 // We need to do this periodically and if anything changes, send the update to the server.
1111 - function buildSelfInfo() {
1112 - var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities };
1113 - if (mesh.hasHECI == 1) {
1114 - var meinfo = amtMeiState;
1115 - var amtPresent = false, intelamt = {};
1141 + function buildSelfInfo(func) {
1142 + getAmtInfo(function (meinfo) {
1143 + var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities };
1144 if (meinfo != null) {
1117 - if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; amtPresent = true; }
1118 - if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; amtPresent = true; }
1119 - if (meinfo.flags) { intelamt.flags = meinfo.Flags; amtPresent = true; }
1120 - if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; amtPresent = true; }
1121 - if (amtPresent == true) { r.intelamt = intelamt }
1145 + var intelamt = {}, p = false;
1146 + if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; p = true; }
1147 + if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
1148 + if (meinfo.flags) { intelamt.flags = meinfo.Flags; p = true; }
1149 + if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; }
1150 + if (p == true) { r.intelamt = intelamt }
1151 }
1123 - }
1124 - return JSON.stringify(r);
1152 + func(r);
1153 + });
1154 }
1155
1156 // Update the server with the latest network interface information
@@ -1141,8 +1170,10 @@ function createMeshCore(agent) {
1170 function sendPeriodicServerUpdate(force) {
1171 if ((amtMeiConnected != 1) || (force == true)) { // If we are pending MEI connection, hold off on updating the server on self-info
1172 // Update the self information data
1144 - var selfInfo = buildSelfInfo(), selfInfoStr = JSON.stringify(selfInfo);
1145 - if ((force == true) || (selfInfoStr != lastSelfInfo)) { mesh.SendCommand(selfInfo); lastSelfInfo = selfInfoStr; }
1173 + buildSelfInfo(function (selfInfo) {
1174 + selfInfoStr = JSON.stringify(selfInfo);
1175 + if ((force == true) || (selfInfoStr != lastSelfInfo)) { mesh.SendCommand(selfInfo); lastSelfInfo = selfInfoStr; }
1176 + });
1177 }
1178
1179 // Update network information
@@ -1160,7 +1191,7 @@ function createMeshCore(agent) {
1191 amtMei.getEHBCState(function (result) { if (result.EHBC == true) { amtMeiTmpState.Flags += 1; } });
1192 amtMei.getControlMode(function (result) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } });
1193 //amtMei.getMACAddresses(function (result) { amtMeiTmpState.mac = result; });
1163 - amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } amtMeiState = amtMeiTmpState; sendPeriodicServerUpdate(); if (func != null) { func(amtMeiState); } });
1194 + amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } if (func != null) { func(amtMeiTmpState); } });
1195 }
1196
1197 // Called on MicroLMS Intel AMT user notification
agents/meshinstall-initd.sh new
+78
@@ -0,0 +1,78 @@
1 +#!/bin/sh
2 +### BEGIN INIT INFO
3 +# Provides: <NAME>
4 +# Required-Start: $local_fs $network $named $time $syslog
5 +# Required-Stop: $local_fs $network $named $time $syslog
6 +# Default-Start: 2 3 4 5
7 +# Default-Stop: 0 1 6
8 +# Description: <DESCRIPTION>
9 +### END INIT INFO
10 +
11 +SCRIPT=/usr/local/mesh/meshagent
12 +RUNAS=root
13 +
14 +PIDFILE=/var/run/meshagent.pid
15 +LOGFILE=/var/log/meshagent.log
16 +
17 +start() {
18 + if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then
19 + echo 'Service already running' >&2
20 + return 1
21 + fi
22 + echo 'Starting service…' >&2
23 + local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
24 + su -c "$CMD" $RUNAS > "$PIDFILE"
25 + echo 'Service started' >&2
26 +}
27 +
28 +stop() {
29 + if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
30 + echo 'Service not running' >&2
31 + return 1
32 + fi
33 + echo 'Stopping service…' >&2
34 + kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE"
35 + echo 'Service stopped' >&2
36 +}
37 +
38 +uninstall() {
39 + echo -n "Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] "
40 + local SURE
41 + read SURE
42 + if [ "$SURE" = "yes" ]; then
43 + stop
44 + rm -f "$PIDFILE"
45 + echo "Notice: log file will not be removed: '$LOGFILE'" >&2
46 + update-rc.d -f <NAME> remove
47 + rm -fv "$0"
48 + fi
49 +}
50 +
51 +forceuninstall() {
52 + stop
53 + rm -f "$PIDFILE"
54 + rm -f "$LOGFILE"
55 + update-rc.d -f <NAME> remove
56 + rm -fv "$0"
57 +}
58 +
59 +case "$1" in
60 + start)
61 + start
62 + ;;
63 + stop)
64 + stop
65 + ;;
66 + uninstall)
67 + uninstall
68 + ;;
69 + forceuninstall)
70 + uninstall
71 + ;;
72 + restart)
73 + stop
74 + start
75 + ;;
76 + *)
77 + echo "Usage: $0 {start|stop|restart|uninstall}"
78 +esac
agents/meshinstall-linux-old.sh new
+164
@@ -0,0 +1,164 @@
1 +#!/bin/bash
2 +
3 +CheckStartupType() {
4 +# echo "Checking process autostart system..."
5 + if [[ `systemctl` =~ -\.mount ]]; then return 1; # systemd;
6 + elif [[ `/sbin/init --version` =~ upstart ]]; then return 2; # upstart;
7 + elif [[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]]; then return 3; # sysv-init;
8 + fi
9 + return 0;
10 +}
11 +
12 +# Add "StartupType=(type)" to .msh file
13 +UpdateMshFile() {
14 + # Remove all lines that start with "StartupType="
15 + sed '/^StartupType=/ d' < /usr/local/mesh/meshagent.msh >> /usr/local/mesh/meshagent2.msh
16 + # Add the startup type to the file
17 + echo "StartupType=$starttype" >> /usr/local/mesh/meshagent2.msh
18 + mv /usr/local/mesh/meshagent2.msh /usr/local/mesh/meshagent.msh
19 +}
20 +
21 +CheckInstallAgent() {
22 +# echo "Checking mesh identifier..."
23 + if [ -e "/usr/local" ]
24 + then
25 + installpath="/usr/local/mesh"
26 + else
27 + installpath="/usr/mesh"
28 + fi
29 + if [ $# -eq 2 ]
30 + then
31 + url=$1
32 + meshid=$2
33 + meshidlen=${#meshid}
34 + if [ $meshidlen -eq 64 ]
35 + then
36 +# echo "Detecting computer type..."
37 + machinetype=$( uname -m )
38 + machineid=0
39 + if [ $machinetype == 'x86_64' ]
40 + then
41 +# Linux x86, 64 bit
42 + machineid=6
43 + fi
44 + if [ $machinetype == 'x86' ]
45 + then
46 +# Linux x86, 32 bit
47 + machineid=5
48 + fi
49 + if [ $machinetype == 'armv6l' ] || [ $machinetype == 'armv7l' ]
50 + then
51 +# RaspberryPi 1 (armv6l) or RaspberryPi 2/3 (armv7l)
52 + machineid=25
53 + fi
54 +# TODO: Add more machine types, detect KVM support, etc.
55 + if [ $machineid -eq 0 ]
56 + then
57 + echo "Unsupported machine type: $machinetype, check with server administrator."
58 + else
59 + DownloadAgent $url $meshid $machineid
60 + fi
61 + else
62 + echo "MeshID is not correct, must be 64 characters long."
63 + fi
64 + else
65 + echo "URI and/or MeshID have not been specified, must be passed in as arguments."
66 + return 0;
67 + fi
68 +}
69 +
70 +DownloadAgent() {
71 + url=$1
72 + meshid=$2
73 + machineid=$3
74 +# Create folder
75 + mkdir -p /usr/local/mesh
76 + cd /usr/local/mesh
77 +# echo "Downloading mesh agent..."
78 + wget $url/meshagents?id=$machineid -q --no-check-certificate -O /usr/local/mesh/meshagent
79 + if [ $? -eq 0 ]
80 + then
81 + echo "Mesh agent downloaded."
82 +# TODO: We could check the meshagent sha256 hash, but best to authenticate the server.
83 + chmod 755 /usr/local/mesh/meshagent
84 + wget $url/meshsettings?id=$meshid -q --no-check-certificate -O /usr/local/mesh/meshagent.msh
85 + if [ $? -eq 0 ]
86 + then
87 + UpdateMshFile
88 + if [ $starttype -eq 1 ]
89 + then
90 + echo -e "[Unit]\nDescription=MeshCentral Agent\n[Service]\nExecStart=/usr/local/mesh/meshagent\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=meshagent.service\n" > /lib/systemd/system/meshagent.service
91 + systemctl enable meshagent
92 + systemctl start meshagent
93 + else
94 + ./meshagent start
95 + ln -s /usr/local/mesh/meshagent /sbin/meshcmd
96 + ln -s /usr/local/mesh/meshagent /etc/rc2.d/S20mesh
97 + ln -s /usr/local/mesh/meshagent /etc/rc3.d/S20mesh
98 + ln -s /usr/local/mesh/meshagent /etc/rc5.d/S20mesh
99 + fi
100 + echo "Mesh agent started."
101 + else
102 + echo "Unable to download mesh settings at: $url/meshsettings?id=$meshid."
103 + fi
104 + else
105 + echo "Unable to download mesh agent at: $url/meshagents?id=$machineid."
106 + fi
107 +}
108 +
109 +UninstallAgent() {
110 +# Uninstall agent
111 + if [ -e "/usr/local" ]
112 + then
113 + installpath="/usr/local/mesh"
114 + else
115 + installpath="/usr/mesh"
116 + fi
117 +
118 + if [ $starttype -eq 1 ]
119 + then
120 + rm -f /sbin/meshcmd /lib/systemd/system/meshagent.service
121 + systemctl disable meshagent
122 + systemctl stop meshagent
123 + else
124 + rm -f /sbin/meshcmd /etc/rc2.d/S20mesh /etc/rc3.d/S20mesh /etc/rc5.d/S20mesh
125 + fi
126 +
127 + if [ -e $installpath ]
128 + then
129 + cd $installpath
130 + if [ -e "$installpath/meshagent" ]
131 + then
132 + ./meshagent stop
133 + fi
134 + rm -rf $installpath/*
135 + rmdir $installpath
136 + fi
137 + echo "Agent uninstalled."
138 +}
139 +
140 +
141 +CheckStartupType
142 +starttype=$?
143 +#echo "Type: $starttype"
144 +
145 +currentuser=$( whoami )
146 +if [ $currentuser == 'root' ]
147 +then
148 + if [ $# -eq 0 ]
149 + then
150 + echo -e "This script will install or uninstall a mesh agent, usage:\n $0 [serverurl] [meshid]\n $0 uninstall"
151 + else
152 + if [ $# -eq 1 ]
153 + then
154 + if [ $1 == 'uninstall' ] || [ $1 == 'UNINSTALL' ]
155 + then
156 + UninstallAgent
157 + fi
158 + else
159 + CheckInstallAgent $1 $2
160 + fi
161 + fi
162 +else
163 + echo "Must be root to install or uninstall mesh agent."
164 +fi
agents/meshinstall-linux.sh
+36 -6
@@ -1,6 +1,16 @@
1 #!/bin/bash
2
3 CheckStartupType() {
4 +# echo "Checking process autostart system..."
5 + starttype=`ps -p 1 | awk '/1/ {print $4}'`
6 + if [[ $starttype == 'systemd' ]]; then return 1; # systemd;
7 + elif [[ $starttype == 'init' ]]; then return 3; # sysv-init;
8 + elif [[ `/sbin/init --version` =~ upstart ]]; then return 2; # upstart;
9 + fi
10 + return 0;
11 +}
12 +
13 +CheckStartupTypeOld() {
14 # echo "Checking process autostart system..."
15 if [[ `systemctl` =~ -\.mount ]]; then return 1; # systemd;
16 elif [[ `/sbin/init --version` =~ upstart ]]; then return 2; # upstart;
@@ -87,15 +97,26 @@ DownloadAgent() {
97 UpdateMshFile
98 if [ $starttype -eq 1 ]
99 then
100 + # systemd
101 echo -e "[Unit]\nDescription=MeshCentral Agent\n[Service]\nExecStart=/usr/local/mesh/meshagent\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=meshagent.service\n" > /lib/systemd/system/meshagent.service
102 systemctl enable meshagent
103 systemctl start meshagent
104 else
94 - ./meshagent start
95 - ln -s /usr/local/mesh/meshagent /sbin/meshcmd
96 - ln -s /usr/local/mesh/meshagent /etc/rc2.d/S20mesh
97 - ln -s /usr/local/mesh/meshagent /etc/rc3.d/S20mesh
98 - ln -s /usr/local/mesh/meshagent /etc/rc5.d/S20mesh
105 + if [ $starttype -eq 3 ]
106 + then
107 + # initd
108 + wget $url/meshagents?script=2 -q --no-check-certificate -O /etc/init.d/meshagent
109 + chmod +x /etc/init.d/meshagent
110 + update-rc.d meshagent default # creates symlinks for rc.d
111 + service meshagent start
112 + else
113 + # upstart / others (???)
114 + ./meshagent start
115 + ln -s /usr/local/mesh/meshagent /sbin/meshcmd
116 + ln -s /usr/local/mesh/meshagent /etc/rc2.d/S20mesh
117 + ln -s /usr/local/mesh/meshagent /etc/rc3.d/S20mesh
118 + ln -s /usr/local/mesh/meshagent /etc/rc5.d/S20mesh
119 + fi
120 fi
121 echo "Mesh agent started."
122 else
@@ -117,11 +138,20 @@ UninstallAgent() {
138
139 if [ $starttype -eq 1 ]
140 then
141 + # systemd
142 rm -f /sbin/meshcmd /lib/systemd/system/meshagent.service
143 systemctl disable meshagent
144 systemctl stop meshagent
145 else
124 - rm -f /sbin/meshcmd /etc/rc2.d/S20mesh /etc/rc3.d/S20mesh /etc/rc5.d/S20mesh
146 + if [ $starttype -eq 3 ]
147 + then
148 + # initd
149 + service meshagent forceuninstall
150 + rm -f /sbin/meshcmd /etc/init.d/meshagent
151 + else
152 + # upstart / others (???)
153 + rm -f /sbin/meshcmd /etc/rc2.d/S20mesh /etc/rc3.d/S20mesh /etc/rc5.d/S20mesh
154 + fi
155 fi
156
157 if [ -e $installpath ]
agents/modules_meshcmd/amt.js
+1
@@ -357,6 +357,7 @@ function AmtStackCreateService(wsmanStack) {
357 obj.IPS_HostBasedSetupService_DisableClientControlMode = function (_method_dummy, callback_func) { obj.Exec("IPS_HostBasedSetupService", "DisableClientControlMode", { "_method_dummy": _method_dummy }, callback_func); }
358 obj.IPS_KVMRedirectionSettingData_TerminateSession = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "TerminateSession", {}, callback_func); }
359 obj.IPS_KVMRedirectionSettingData_DataChannelRead = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelRead", {}, callback_func); }
360 + obj.IPS_KVMRedirectionSettingData_DataChannelWrite = function (Data, callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelWrite", { "DataMessage": Data }, callback_func); }
361 obj.IPS_OptInService_StartOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "StartOptIn", {}, callback_func); }
362 obj.IPS_OptInService_CancelOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "CancelOptIn", {}, callback_func); }
363 obj.IPS_OptInService_SendOptInCode = function (OptInCode, callback_func) { obj.Exec("IPS_OptInService", "SendOptInCode", { "OptInCode": OptInCode }, callback_func); }
meshcentral.js
+2 -1
@@ -809,7 +809,8 @@ function CreateMeshCentralServer(config) {
809
810 // List of possible mesh agent install scripts
811 var meshAgentsInstallScriptList = {
812 - 1: { id: 1, localname: 'meshinstall-linux.sh', rname: 'meshinstall.sh' }
812 + 1: { id: 1, localname: 'meshinstall-linux.sh', rname: 'meshinstall.sh' },
813 + 2: { id: 2, localname: 'meshinstall-initd.sh', rname: 'meshagent' }
814 };
815
816 // Update the list of available mesh agents
mpsserver.js
+1 -1
@@ -374,7 +374,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
374 var WindowSize = common.ReadInt(data, 9);
375 socket.tag.activetunnels++;
376 var cirachannel = socket.tag.channels[RecipientChannel];
377 - if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_OPEN_CONFIRMATION: Unable to find channelid " + RecipientChannel); return; }
377 + if (cirachannel == undefined) { /*console.log("MPS Error in CHANNEL_OPEN_CONFIRMATION: Unable to find channelid " + RecipientChannel);*/ return; }
378 cirachannel.amtchannelid = SenderChannel;
379 cirachannel.sendcredits = cirachannel.amtCiraWindow = WindowSize;
380 Debug(3, 'MPS:CHANNEL_OPEN_CONFIRMATION', RecipientChannel, SenderChannel, WindowSize);
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.1.4-f",
3 + "version": "0.1.4-g",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
public/commander.htm
+18 -20
@@ -539,8 +539,8 @@ th {
539 </div>
540 <div id="dialog12" style="margin:auto;margin:3px">
541 <br>
542 - <div style='height:26px'><input id="idx_d12name" style="float:right;width:200px" onkeyup="updateWifiDialog()"><div>Profile Name</div></div>
543 - <div style='height:26px'><input id="idx_d12ssid" style="float:right;width:200px" onkeyup="updateWifiDialog()"><div>SSID</div></div>
542 + <div style='height:26px'><input id="idx_d12name" style="float:right;width:200px" maxlength="32" onkeyup="updateWifiDialog()" title="Maximum 32 characters"><div title="Maximum 32 characters">Profile Name</div></div>
543 + <div style='height:26px'><input id="idx_d12ssid" style="float:right;width:200px" maxlength="32" onkeyup="updateWifiDialog()" title="Maximum 32 characters"><div title="Maximum 32 characters">SSID</div></div>
544 <div style='height:26px'>
545 <select id="idx_d12pri" style="float:right;width:200px" onclick="updateWifiDialog()"></select>
546 <div>Priority</div>
@@ -565,8 +565,8 @@ th {
565 </select>
566 <div>Encryption</div>
567 </div>
568 - <div style='height:26px'><input id="idx_d12password1" type="password" style="float:right;width:200px" onkeyup="updateWifiDialog()"><div>Password*</div></div>
569 - <div style='height:26px'><input id="idx_d12password2" type="password" style="float:right;width:200px" onkeyup="updateWifiDialog()"><div>Confirm Password</div></div>
568 + <div style='height:26px'><input id="idx_d12password1" type="password" style="float:right;width:200px" maxlength="63" onkeyup="updateWifiDialog()" title="Length between 8 and 63 characters"><div title="Length between 8 and 63 characters">Password*</div></div>
569 + <div style='height:26px'><input id="idx_d12password2" type="password" style="float:right;width:200px" maxlength="63" onkeyup="updateWifiDialog()" title="Length between 8 and 63 characters"><div title="Length between 8 and 63 characters">Confirm Password</div></div>
570 </div>
571 <div id="dialog19" style="margin:auto;margin:3px">
572 This will save the entire state of Intel&reg; AMT for this machine into file. Passwords will not be saved, but some sensitive data may be included.<br><br>
@@ -1504,7 +1504,7 @@ var WsmanStackCreateService = function (host, port, user, pass, tls, extra) {
1504
1505 // Perform a WSMAN PULL operation
1506 obj.ExecPull = function (resuri, enumctx, callback, tag, pri) {
1507 - obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\"><EnumerationContext>" + enumctx + "</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>", callback, tag, pri);
1507 + obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\"><EnumerationContext>" + enumctx + "</EnumerationContext></Pull></Body></Envelope>", callback, tag, pri); // </EnumerationContext>--<MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters>--</Pull>
1508 }
1509
1510 // Private method
@@ -1644,9 +1644,8 @@ var WsmanStackCreateService = function (host, port, user, pass, tls, extra) {
1644 function _turnToXml(text) {
1645 if (window.DOMParser) {
1646 return new DOMParser().parseFromString(text, "text/xml");
1647 - }
1648 - else // Internet Explorer
1649 - {
1647 + } else {
1648 + // Internet Explorer
1649 var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
1650 xmlDoc.async = false;
1651 xmlDoc.loadXML(text);
@@ -1823,9 +1822,9 @@ function AmtStackCreateService(wsmanStack) {
1822 if (response == null || response.Header["Method"] != "PullResponse") { callback(obj, name, null, 604, tag); _EnumDoNext(1); return; }
1823 for (var i in response.Body["Items"]) {
1824 if (response.Body["Items"][i] instanceof Array) {
1826 - for (var j in response.Body["Items"][i]) { items.push(response.Body["Items"][i][j]); }
1825 + for (var j in response.Body["Items"][i]) { if (typeof response.Body["Items"][i][j] != 'function') { items.push(response.Body["Items"][i][j]); } }
1826 } else {
1828 - items.push(response.Body["Items"][i]);
1827 + if (typeof response.Body["Items"][i] != 'function') { items.push(response.Body["Items"][i]); }
1828 }
1829 }
1830 if (response.Body["EnumerationContext"]) {
@@ -2078,6 +2077,8 @@ function AmtStackCreateService(wsmanStack) {
2077 obj.IPS_HostBasedSetupService_UpgradeClientToAdmin = function (McNonce, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "UpgradeClientToAdmin", { "McNonce": McNonce, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); }
2078 obj.IPS_HostBasedSetupService_DisableClientControlMode = function (_method_dummy, callback_func) { obj.Exec("IPS_HostBasedSetupService", "DisableClientControlMode", { "_method_dummy": _method_dummy }, callback_func); }
2079 obj.IPS_KVMRedirectionSettingData_TerminateSession = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "TerminateSession", {}, callback_func); }
2080 + obj.IPS_KVMRedirectionSettingData_DataChannelRead = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelRead", {}, callback_func); }
2081 + obj.IPS_KVMRedirectionSettingData_DataChannelWrite = function (Data, callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelWrite", { "DataMessage": Data }, callback_func); }
2082 obj.IPS_OptInService_StartOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "StartOptIn", {}, callback_func); }
2083 obj.IPS_OptInService_CancelOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "CancelOptIn", {}, callback_func); }
2084 obj.IPS_OptInService_SendOptInCode = function (OptInCode, callback_func) { obj.Exec("IPS_OptInService", "SendOptInCode", { "OptInCode": OptInCode }, callback_func); }
@@ -33061,7 +33062,7 @@ if (typeof module !== "undefined" && module.exports) {
33062 });
33063 }
33064
33064 - var version = '0.5.8';
33065 + var version = '0.6.0';
33066 var urlvars = null;
33067 var amtstack;
33068 var wsstack = null;
@@ -33398,7 +33399,7 @@ if (typeof module !== "undefined" && module.exports) {
33399 }
33400 }
33401 }
33401 - if (amtlogicalelements.length == 0) { disconnect(); return; } // Could not get Intel AMT version, disconnect();
33402 + if (amtlogicalelements.length == 0) { console.error('ERROR: Could not get Intel AMT version.'); disconnect(); return; } // Could not get Intel AMT version, disconnect();
33403 var v = getInstance(amtlogicalelements, "AMT")["VersionString"];
33404 amtversion = parseInt(v.split('.')[0]);
33405 amtversionmin = parseInt(v.split('.')[1]);
@@ -34602,9 +34603,7 @@ if (typeof module !== "undefined" && module.exports) {
34603 xx += getWatchdogTransitionStr(t['OldState']) + " &rarr; " + getWatchdogTransitionStr(t['NewState']);
34604 if (t.actions) {
34605 var action = t.actions[0];
34605 - if (action['EventOnTransition'] == true) {
34606 - xx += " : Event to log";
34607 - }
34606 + if (action['EventOnTransition'] == true) { xx += " : Event to log"; }
34607 }
34608 }
34609 if (xx != '') { x += "<div style=padding:12px>" + xx + "</div>"; }
@@ -35298,8 +35297,7 @@ if (typeof module !== "undefined" && module.exports) {
35297 '__parameterType': 'reference',
35298 '__resourceUri': amtstack.CompleteName('CIM_WiFiEndpoint'),
35299 'Name': 'WiFi Endpoint 0'
35301 - },
35302 - {
35300 + }, {
35301 '__parameterType': 'instance',
35302 '__namespace': amtstack.CompleteName('CIM_WiFiEndpointSettings'),
35303 'ElementName': idx_d12name.value,
@@ -35328,7 +35326,7 @@ if (typeof module !== "undefined" && module.exports) {
35326 // Check if there is already a profile with this name
35327 for (var j in xxWireless['CIM_WiFiEndpointSettings'].responses) { if (xxWireless['CIM_WiFiEndpointSettings'].responses[j]['ElementName'] == idx_d12name.value) { r = false; } }
35328
35331 - QE('idx_dlgOkButton', r == true && idx_d12name.value.length > 0 && idx_d12ssid.value.length > 0 && idx_d12password1.value.length > 0 && idx_d12password1.value == idx_d12password2.value);
35329 + QE('idx_dlgOkButton', r == true && (idx_d12name.value.length > 0) && (idx_d12ssid.value.length > 0) && (idx_d12password1.value.length > 7) && (idx_d12password1.value == idx_d12password2.value));
35330 }
35331
35332
@@ -35598,7 +35596,7 @@ if (typeof module !== "undefined" && module.exports) {
35596 QE('idx_dlgOkButton', ok);
35597 }
35598
35601 - var xxUserPermissions = [ 'Local only' , 'Network only', 'All (Local & Network)'];
35599 + var xxUserPermissions = ['Local only' , 'Network only', 'All (Local & Network)'];
35600 function showUserDetails(h) {
35601 if (xxdialogMode) return;
35602 var a = xxAccountRealmInfo[h], x = '<div style=text-align:left>';
@@ -36275,7 +36273,7 @@ if (typeof module !== "undefined" && module.exports) {
36273 delete x["DefaultGateway"];
36274 delete x["PrimaryDNS"];
36275 delete x["SecondaryDNS"];
36278 - if (!y) {
36276 + if (d21o1.checked == false) {
36277 x["IPAddress"] = idx_d21address.value;
36278 x["SubnetMask"] = idx_d21subnet.value;
36279 x["DefaultGateway"] = idx_d21gateway.value;
public/scripts/agent-desktop-0.0.2.js
+16 -16
@@ -83,9 +83,9 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
83 }
84 }
85
86 - obj.Send = function (x) {
86 + obj.send = function (x) {
87 //console.log("KSend(" + x.length + "): " + rstr2hex(x));
88 - obj.parent.Send(x);
88 + obj.parent.send(x);
89 }
90
91 // KVM Control.
@@ -138,24 +138,24 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
138 obj.SendUnPause = function () {
139 //obj.Debug("SendUnPause");
140 //obj.xxStateChange(3);
141 - obj.Send(String.fromCharCode(0x00, 0x08, 0x00, 0x05, 0x00));
141 + obj.send(String.fromCharCode(0x00, 0x08, 0x00, 0x05, 0x00));
142 }
143
144 obj.SendPause = function () {
145 //obj.Debug("SendPause");
146 //obj.xxStateChange(2);
147 - obj.Send(String.fromCharCode(0x00, 0x08, 0x00, 0x05, 0x01));
147 + obj.send(String.fromCharCode(0x00, 0x08, 0x00, 0x05, 0x01));
148 }
149
150 obj.SendCompressionLevel = function (type, level, scaling, frametimer) {
151 if (level) { obj.CompressionLevel = level; }
152 if (scaling) { obj.ScalingLevel = scaling; }
153 if (frametimer) { obj.FrameRateTimer = frametimer; }
154 - obj.Send(String.fromCharCode(0x00, 0x05, 0x00, 0x0A, type, obj.CompressionLevel) + obj.shortToStr(obj.ScalingLevel) + obj.shortToStr(obj.FrameRateTimer));
154 + obj.send(String.fromCharCode(0x00, 0x05, 0x00, 0x0A, type, obj.CompressionLevel) + obj.shortToStr(obj.ScalingLevel) + obj.shortToStr(obj.FrameRateTimer));
155 }
156
157 obj.SendRefresh = function () {
158 - obj.Send(String.fromCharCode(0x00, 0x06, 0x00, 0x04));
158 + obj.send(String.fromCharCode(0x00, 0x06, 0x00, 0x04));
159 }
160
161 obj.ProcessScreenMsg = function (width, height) {
@@ -214,7 +214,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
214 obj.SendKeyMsgKC(obj.KeyAction.UP, 91); // Left-Windows
215 obj.SendKeyMsgKC(obj.KeyAction.UP, 92); // Right-Windows
216 obj.SendKeyMsgKC(obj.KeyAction.UP, 16); // Shift
217 - obj.Send(String.fromCharCode(0x00, 0x0E, 0x00, 0x04));
217 + obj.send(String.fromCharCode(0x00, 0x0E, 0x00, 0x04));
218 break;
219 case 11: // GetDisplays
220 var myOptions = [], dcount = ((str.charCodeAt(4) & 0xFF) << 8) + (str.charCodeAt(5) & 0xFF);
@@ -268,21 +268,21 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
268 }
269
270 obj.SendMessage = function (msg) {
271 - if (obj.State == 3) obj.Send(String.fromCharCode(0x00, 0x11) + obj.shortToStr(4 + msg.length) + msg); // 0x11 = 17 MNG_KVM_MESSAGE
271 + if (obj.State == 3) obj.send(String.fromCharCode(0x00, 0x11) + obj.shortToStr(4 + msg.length) + msg); // 0x11 = 17 MNG_KVM_MESSAGE
272 }
273
274 obj.SendKeyMsgKC = function (action, kc) {
275 - if (obj.State == 3) obj.Send(String.fromCharCode(0x00, obj.InputType.KEY, 0x00, 0x06, (action - 1), kc));
275 + if (obj.State == 3) obj.send(String.fromCharCode(0x00, obj.InputType.KEY, 0x00, 0x06, (action - 1), kc));
276 }
277
278 obj.sendcad = function() { obj.SendCtrlAltDelMsg(); }
279
280 obj.SendCtrlAltDelMsg = function () {
281 - if (obj.State == 3) { obj.Send(String.fromCharCode(0x00, obj.InputType.CTRLALTDEL, 0x00, 0x04)); }
281 + if (obj.State == 3) { obj.send(String.fromCharCode(0x00, obj.InputType.CTRLALTDEL, 0x00, 0x04)); }
282 }
283
284 obj.SendEscKey = function () {
285 - if (obj.State == 3) obj.Send(String.fromCharCode(0x00, obj.InputType.KEY, 0x00, 0x06, 0x00, 0x1B, 0x00, obj.InputType.KEY, 0x00, 0x06, 0x01, 0x1B));
285 + if (obj.State == 3) obj.send(String.fromCharCode(0x00, obj.InputType.KEY, 0x00, 0x06, 0x00, 0x1B, 0x00, obj.InputType.KEY, 0x00, 0x06, 0x01, 0x1B));
286 }
287
288 obj.SendStartMsg = function () {
@@ -298,7 +298,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
298 }
299
300 obj.SendTouchMsg1 = function (id, flags, x, y) {
301 - if (obj.State == 3) obj.Send(String.fromCharCode(0x00, obj.InputType.TOUCH) + obj.shortToStr(14) + String.fromCharCode(0x01, id) + obj.intToStr(flags) + obj.shortToStr(x) + obj.shortToStr(y));
301 + if (obj.State == 3) obj.send(String.fromCharCode(0x00, obj.InputType.TOUCH) + obj.shortToStr(14) + String.fromCharCode(0x01, id) + obj.intToStr(flags) + obj.shortToStr(x) + obj.shortToStr(y));
302 }
303
304 obj.SendTouchMsg2 = function (id, flags) {
@@ -314,7 +314,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
314 msg += String.fromCharCode(k) + obj.intToStr(flags2) + obj.shortToStr(obj.TouchArray[k].x) + obj.shortToStr(obj.TouchArray[k].y);
315 if (obj.TouchArray[k].f == 2) delete obj.TouchArray[k];
316 }
317 - if (obj.State == 3) obj.Send(String.fromCharCode(0x00, obj.InputType.TOUCH) + obj.shortToStr(5 + msg.length) + String.fromCharCode(0x02) + msg);
317 + if (obj.State == 3) obj.send(String.fromCharCode(0x00, obj.InputType.TOUCH) + obj.shortToStr(5 + msg.length) + String.fromCharCode(0x02) + msg);
318 if (Object.keys(obj.TouchArray).length == 0 && obj.touchtimer != null) { clearInterval(obj.touchtimer); obj.touchtimer = null; }
319 }
320
@@ -342,13 +342,13 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
342 var MouseMsg = "";
343 if (Action == obj.KeyAction.SCROLL) MouseMsg = String.fromCharCode(0x00, obj.InputType.MOUSE, 0x00, 0x0C, 0x00, ((Action == obj.KeyAction.DOWN) ? Button : ((Button * 2) & 0xFF)), ((X / 256) & 0xFF), (X & 0xFF), ((Y / 256) & 0xFF), (Y & 0xFF), ((Delta / 256) & 0xFF), (Delta & 0xFF));
344 else MouseMsg = String.fromCharCode(0x00, obj.InputType.MOUSE, 0x00, 0x0A, 0x00, ((Action == obj.KeyAction.DOWN) ? Button : ((Button * 2) & 0xFF)), ((X / 256) & 0xFF), (X & 0xFF), ((Y / 256) & 0xFF), (Y & 0xFF));
345 - if (obj.Action == obj.KeyAction.NONE) { if (obj.Alternate == 0 || obj.ipad) { obj.Send(MouseMsg); obj.Alternate = 1; } else { obj.Alternate = 0; } } else { obj.Send(MouseMsg); }
345 + if (obj.Action == obj.KeyAction.NONE) { if (obj.Alternate == 0 || obj.ipad) { obj.send(MouseMsg); obj.Alternate = 1; } else { obj.Alternate = 0; } } else { obj.send(MouseMsg); }
346 }
347 }
348 }
349
350 - obj.GetDisplayNumbers = function () { obj.Send(String.fromCharCode(0x00, 0x0B, 0x00, 0x04)); } // Get Terminal display
351 - obj.SetDisplay = function (number) { obj.Send(String.fromCharCode(0x00, 0x0C, 0x00, 0x06, number >> 8, number & 0xFF)); } // Set Terminal display
350 + obj.GetDisplayNumbers = function () { obj.send(String.fromCharCode(0x00, 0x0B, 0x00, 0x04)); } // Get Terminal display
351 + obj.SetDisplay = function (number) { obj.send(String.fromCharCode(0x00, 0x0C, 0x00, 0x06, number >> 8, number & 0xFF)); } // Set Terminal display
352 obj.intToStr = function (x) { return String.fromCharCode((x >> 24) & 0xFF, (x >> 16) & 0xFF, (x >> 8) & 0xFF, x & 0xFF); }
353 obj.shortToStr = function (x) { return String.fromCharCode((x >> 8) & 0xFF, x & 0xFF); }
354
public/scripts/agent-redir-ws-0.1.0.js
+17 -12
@@ -10,18 +10,19 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
10 obj.m = module; // This is the inner module (Terminal or Desktop)
11 module.parent = obj;
12 obj.meshserver = meshserver;
13 - obj.nodeid = null;
13 obj.State = 0;
14 + obj.nodeid = null;
15 obj.socket = null;
16 obj.connectstate = -1;
17 obj.tunnelid = Math.random().toString(36).substring(2); // Generate a random client tunnel id
18 obj.protocol = module.protocol; // 1 = SOL, 2 = KVM, 3 = IDER, 4 = Files, 5 = FileTransfer
19 + obj.onStateChanged = null;
20 + obj.ctrlMsgAllowed = true;
21 obj.attemptWebRTC = false;
22 obj.webRtcActive = false;
23 obj.webSwitchOk = false;
22 - obj.webrtc = null;
24 obj.webchannel = null;
24 - obj.onStateChanged = null;
25 + obj.webrtc = null;
26 obj.debugmode = 0;
27
28 // Private method
@@ -38,8 +39,8 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
39 obj.socket.onerror = function (e) { console.error(e); }
40 obj.socket.onclose = obj.xxOnSocketClosed;
41 obj.xxStateChange(1);
41 - //obj.meshserver.Send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: url2 });
42 - obj.meshserver.Send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: "*/meshrelay.ashx?id=" + obj.tunnelid });
42 + //obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: url2 });
43 + obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: "*/meshrelay.ashx?id=" + obj.tunnelid });
44 //obj.debug("Agent Redir Start: " + url);
45 }
46
@@ -53,6 +54,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
54 obj.xxOnControlCommand = function (msg) {
55 var controlMsg;
56 try { controlMsg = JSON.parse(msg); } catch (e) { return; }
57 + if (controlMsg.ctrlChannel != '102938') { obj.xxOnSocketData(msg); return; }
58 //console.log(controlMsg);
59 if (obj.webrtc != null) {
60 if (controlMsg.type == 'answer') {
@@ -61,16 +63,19 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
63 obj.webSwitchOk = true; // Other side is ready for switch over
64 performWebRtcSwitch();
65 } else if (controlMsg.type == 'webrtc1') {
64 - obj.socket.send("{\"type\":\"webrtc2\"}"); // Confirm we got end of data marker, indicates data will no longer be received on websocket.
66 + sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Confirm we got end of data marker, indicates data will no longer be received on websocket.
67 } else if (controlMsg.type == 'webrtc2') {
68 // TODO: Resume/Start sending data over WebRTC
69 }
70 }
71 }
72
73 + function sendCtrlMsg(x) { if (obj.ctrlMsgAllowed == true) { try { obj.socket.send(x); } catch (e) { } } }
74 +
75 function performWebRtcSwitch() {
76 if ((obj.webSwitchOk == true) && (obj.webRtcActive == true)) {
73 - obj.socket.send("{\"type\":\"webrtc1\"}"); // Indicate to the other side that data traffic will no longer be sent over websocket.
77 + sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate to the meshagent that it can start traffic switchover
78 + sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc1\"}"); // Indicate to the meshagent that data traffic will no longer be sent over websocket.
79 // TODO: Hold/Stop sending data over websocket
80 if (obj.onStateChanged != null) { obj.onStateChanged(obj, obj.State); }
81 }
@@ -78,7 +83,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
83
84 // Close the WebRTC connection, should be called if a problem occurs during WebRTC setup.
85 obj.xxCloseWebRTC = function () {
81 - try { obj.webchannel.send("{\"type\":\"close\"}"); } catch (e) { }
86 + sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"close\"}");
87 if (obj.webchannel != null) { try { obj.webchannel.close(); } catch (e) { } obj.webchannel = null; }
88 if (obj.webrtc != null) { try { obj.webrtc.close(); } catch (e) { } obj.webrtc = null; }
89 obj.webRtcActive = false;
@@ -86,6 +91,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
91
92 obj.xxOnMessage = function (e) {
93 //if (obj.debugmode == 1) { console.log('Recv', e.data); }
94 + //console.log('Recv', e.data, obj.State);
95 if (obj.State < 3) {
96 if (e.data == 'c') {
97 obj.socket.send(obj.protocol);
@@ -120,7 +126,6 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
126 }, obj.xxCloseWebRTC, { mandatory: { OfferToReceiveAudio: false, OfferToReceiveVideo: false } });
127 }
128 }
123 -
129 return;
130 }
131 }
@@ -169,9 +174,9 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
174 return obj.m.ProcessData(data);
175 }
176
172 - obj.Send = function (x) {
177 + obj.send = function (x) {
178 //obj.debug("Agent Redir Send(" + obj.webRtcActive + ", " + x.length + "): " + rstr2hex(x));
174 - //console.log("Agent Redir Send(" + obj.webRtcActive + ", " + x.length + "): " + rstr2hex(x));
179 + //console.log("Agent Redir Send(" + obj.webRtcActive + ", " + x.length + "): " + ((typeof x == 'string')?x:rstr2hex(x)));
180 if (obj.socket != null && obj.socket.readyState == WebSocket.OPEN) {
181 if (typeof x == 'string') {
182 if (obj.debugmode == 1) {
@@ -210,7 +215,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
215 obj.connectstate = -1;
216 obj.xxCloseWebRTC();
217 if (obj.socket != null) {
213 - try { if (obj.socket.readyState == 1) { obj.socket.send("{\"type\":\"close\"}"); obj.socket.close(); } } catch (e) { }
218 + try { if (obj.socket.readyState == 1) { sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"close\"}"); obj.socket.close(); } } catch (e) { }
219 obj.socket = null;
220 }
221 obj.xxStateChange(0);
public/scripts/amt-desktop-0.0.2.js
+13 -13
@@ -81,19 +81,19 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
81 //var version = parseFloat(obj.acc.substring(4, 11));
82 //obj.Debug("KVersion: " + version);
83 obj.state = 1;
84 - obj.Send("RFB 003.008\n");
84 + obj.send("RFB 003.008\n");
85 }
86 else if (obj.state == 1 && obj.acc.length >= 1) {
87 // Getting security options
88 cmdsize = obj.acc.charCodeAt(0) + 1;
89 - obj.Send(String.fromCharCode(1)); // Send the "None" security type. Since we already authenticated using redirection digest auth, we don't need to do this again.
89 + obj.send(String.fromCharCode(1)); // Send the "None" security type. Since we already authenticated using redirection digest auth, we don't need to do this again.
90 obj.state = 2;
91 }
92 else if (obj.state == 2 && obj.acc.length >= 4) {
93 // Getting security response
94 cmdsize = 4;
95 if (ReadInt(obj.acc, 0) != 0) { return obj.Stop(); }
96 - obj.Send(String.fromCharCode(1)); // Send share desktop flag
96 + obj.send(String.fromCharCode(1)); // Send share desktop flag
97 obj.state = 3;
98 }
99 else if (obj.state == 3 && obj.acc.length >= 24) {
@@ -138,11 +138,11 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
138 if (obj.useZRLE) supportedEncodings += IntToStr(16);
139 supportedEncodings += IntToStr(0);
140
141 - obj.Send(String.fromCharCode(2, 0) + ShortToStr((supportedEncodings.length / 4) + 1) + supportedEncodings + IntToStr(-223)); // Supported Encodings + Desktop Size
141 + obj.send(String.fromCharCode(2, 0) + ShortToStr((supportedEncodings.length / 4) + 1) + supportedEncodings + IntToStr(-223)); // Supported Encodings + Desktop Size
142
143 // Set the pixel encoding to something much smaller
144 - // obj.Send(String.fromCharCode(0, 0, 0, 0, 16, 16, 0, 1) + ShortToStr(31) + ShortToStr(63) + ShortToStr(31) + String.fromCharCode(11, 5, 0, 0, 0, 0)); // Setup 16 bit color RGB565 (This is the default, so we don't need to set it)
145 - 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
144 + // obj.send(String.fromCharCode(0, 0, 0, 0, 16, 16, 0, 1) + ShortToStr(31) + ShortToStr(63) + ShortToStr(31) + String.fromCharCode(11, 5, 0, 0, 0, 0)); // Setup 16 bit color RGB565 (This is the default, so we don't need to set it)
145 + 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
146
147 obj.state = 4;
148 obj.parent.xxStateChange(3);
@@ -194,7 +194,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
194 // Desktop Size (0xFFFFFF21, -223)
195 obj.canvas.canvas.width = obj.rwidth = obj.width = width;
196 obj.canvas.canvas.height = obj.rheight = obj.height = height;
197 - obj.Send(String.fromCharCode(3, 0, 0, 0, 0, 0) + ShortToStr(obj.width) + ShortToStr(obj.height)); // FramebufferUpdateRequest
197 + obj.send(String.fromCharCode(3, 0, 0, 0, 0, 0) + ShortToStr(obj.width) + ShortToStr(obj.height)); // FramebufferUpdateRequest
198 cmdsize = 12;
199 if (obj.onScreenSizeChange != null) { obj.onScreenSizeChange(obj, obj.ScreenWidth, obj.ScreenHeight); }
200 // obj.Debug("New desktop width: " + obj.width + ", height: " + obj.height);
@@ -454,13 +454,13 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
454 if (obj.focusmode > 0) {
455 // Request only pixels around the last mouse position
456 var df = obj.focusmode * 2;
457 - obj.Send(String.fromCharCode(3, 1) + ShortToStr(Math.max(Math.min(obj.ox, obj.mx) - obj.focusmode, 0)) + ShortToStr(Math.max(Math.min(obj.oy, obj.my) - obj.focusmode, 0)) + ShortToStr(df + Math.abs(obj.ox - obj.mx)) + ShortToStr(df + Math.abs(obj.oy - obj.my))); // FramebufferUpdateRequest
457 + obj.send(String.fromCharCode(3, 1) + ShortToStr(Math.max(Math.min(obj.ox, obj.mx) - obj.focusmode, 0)) + ShortToStr(Math.max(Math.min(obj.oy, obj.my) - obj.focusmode, 0)) + ShortToStr(df + Math.abs(obj.ox - obj.mx)) + ShortToStr(df + Math.abs(obj.oy - obj.my))); // FramebufferUpdateRequest
458 obj.ox = obj.mx;
459 obj.oy = obj.my;
460 } else {
461 // ###END###{DesktopFocus}
462 // Request the entire screen
463 - obj.Send(String.fromCharCode(3, 1, 0, 0, 0, 0) + ShortToStr(obj.rwidth) + ShortToStr(obj.rheight)); // FramebufferUpdateRequest
463 + obj.send(String.fromCharCode(3, 1, 0, 0, 0, 0) + ShortToStr(obj.rwidth) + ShortToStr(obj.rheight)); // FramebufferUpdateRequest
464 // ###BEGIN###{DesktopFocus}
465 }
466 // ###END###{DesktopFocus}
@@ -485,10 +485,10 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
485 obj.parent.Stop();
486 }
487
488 - obj.Send = function (x) {
488 + obj.send = function (x) {
489 //obj.Debug("KSend(" + x.length + "): " + rstr2hex(x));
490 //obj.outbytes += x.length;
491 - obj.parent.Send(x);
491 + obj.parent.send(x);
492 }
493
494 /*
@@ -552,7 +552,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
552 return obj.haltEvent(e);
553 }
554
555 - obj.sendkey = function (k, d) { obj.Send(String.fromCharCode(4, d, 0, 0) + IntToStr(k)); }
555 + obj.sendkey = function (k, d) { obj.send(String.fromCharCode(4, d, 0, 0) + IntToStr(k)); }
556
557 obj.SendCtrlAltDelMsg = function () { obj.sendcad(); }
558 obj.sendcad = function () {
@@ -625,7 +625,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
625 }
626 // ###END###{DesktopRotation}
627
628 - obj.Send(String.fromCharCode(5, obj.buttonmask) + ShortToStr(obj.mx) + ShortToStr(obj.my));
628 + obj.send(String.fromCharCode(5, obj.buttonmask) + ShortToStr(obj.mx) + ShortToStr(obj.my));
629
630 // ###BEGIN###{DesktopFocus}
631 // Update focus area if we are in focus mode
public/scripts/amt-redir-ws-0.1.0.js
+1 -1
@@ -253,7 +253,7 @@ var CreateAmtRedirect = function (module) {
253 }
254 }
255
256 - obj.Send = function (x) {
256 + obj.send = function (x) {
257 if (obj.socket == null || obj.connectstate != 1) return;
258 if (obj.protocol == 1) { obj.xxSend(String.fromCharCode(0x28, 0x00, 0x00, 0x00) + IntToStrX(obj.amtsequence++) + ShortToStrX(x.length) + x); } else { obj.xxSend(x); }
259 }
public/scripts/amt-terminal-0.0.2.js
+2 -2
@@ -554,8 +554,8 @@ var CreateAmtRemoteTerminal = function (divid) {
554 }
555 }
556
557 - obj.TermSendKeys = function(keys) { obj.parent.Send(keys); }
558 - obj.TermSendKey = function(key) { obj.parent.Send(String.fromCharCode(key)); }
557 + obj.TermSendKeys = function(keys) { obj.parent.send(keys); }
558 + obj.TermSendKey = function(key) { obj.parent.send(String.fromCharCode(key)); }
559
560 function _TermMoveUp(linecount) {
561 var x, y;
public/scripts/meshcentral.js
+1 -1
@@ -37,7 +37,7 @@ var MeshServerCreateControl = function (domain) {
37 if (obj.onMessage) obj.onMessage(obj, message);
38 };
39
40 - obj.Send = function (x) { if (obj.socket != null && obj.connectstate == 1) { obj.socket.send(JSON.stringify(x)); } }
40 + obj.send = function (x) { if (obj.socket != null && obj.connectstate == 1) { obj.socket.send(JSON.stringify(x)); } }
41
42 return obj;
43 }
views/default.handlebars
+113 -72
@@ -777,9 +777,9 @@
777 setTimeout(serverPoll, 5000);
778 } else if (state == 2) {
779 // Fetch list of meshes, nodes, files
780 - meshserver.Send({ action: 'meshes' });
781 - meshserver.Send({ action: 'nodes' });
782 - meshserver.Send({ action: 'files' });
780 + meshserver.send({ action: 'meshes' });
781 + meshserver.send({ action: 'nodes' });
782 + meshserver.send({ action: 'files' });
783 }
784 }
785
@@ -821,8 +821,8 @@
821 if ((userinfo.siteadmin & 2) != 0)
822 {
823 // We are user administrator
824 - if (users == null) { meshserver.Send({ action: 'users' }); }
825 - if (wssessions == null) { meshserver.Send({ action: 'wssessioncount' }); }
824 + if (users == null) { meshserver.send({ action: 'users' }); }
825 + if (wssessions == null) { meshserver.send({ action: 'wssessioncount' }); }
826 } else {
827 // We are not user administrator
828 users = null;
@@ -830,7 +830,7 @@
830 updateUsers();
831 if (xxcurrentView == 4) go(1);
832 }
833 - meshserver.Send({ action: 'events', limit: parseInt(p3limitdropdown.value) });
833 + meshserver.send({ action: 'events', limit: parseInt(p3limitdropdown.value) });
834 QV('p2deleteall', userinfo.siteadmin == 0xFFFFFFFF);
835 }
836
@@ -996,7 +996,7 @@
996 if (userinfo.name == message.event.account.name) {
997 var newsiteadmin = message.event.account.siteadmin?message.event.account.siteadmin:0;
998 var oldsiteadmin = userinfo.siteadmin?userinfo.siteadmin:0;
999 - if ((message.event.account.quota != userinfo.quota) || (((userinfo.siteadmin & 8) == 0) && ((message.event.account.siteadmin & 8) != 0))) { meshserver.Send({ action: 'files' }); }
999 + if ((message.event.account.quota != userinfo.quota) || (((userinfo.siteadmin & 8) == 0) && ((message.event.account.siteadmin & 8) != 0))) { meshserver.send({ action: 'files' }); }
1000 userinfo = message.event.account;
1001 if (oldsiteadmin != newsiteadmin) updateSiteAdmin();
1002 QV('verifyEmailId', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
@@ -1020,7 +1020,7 @@
1020 meshes[message.event.meshid] = { _id: message.event.meshid, name: message.event.name, mtype: message.event.mtype, desc: message.event.desc, links: message.event.links };
1021 updateMeshes();
1022 updateDevices();
1023 - meshserver.Send({ action: 'files' });
1023 + meshserver.send({ action: 'files' });
1024 }
1025 break;
1026 }
@@ -1029,7 +1029,7 @@
1029 if (meshes[message.event.meshid] == null) {
1030 // This is a new mesh for us
1031 meshes[message.event.meshid] = { _id: message.event.meshid, name: message.event.name, mtype: message.event.mtype, desc: message.event.desc, links: message.event.links };
1032 - meshserver.Send({ action: 'nodes' }); // Request a refresh of all nodes (TODO: We could optimize this to only request nodes for the new mesh).
1032 + meshserver.send({ action: 'nodes' }); // Request a refresh of all nodes (TODO: We could optimize this to only request nodes for the new mesh).
1033 } else {
1034 // This is an existing mesh
1035 meshes[message.event.meshid].name = message.event.name;
@@ -1052,7 +1052,7 @@
1052 }
1053 updateMeshes();
1054 updateDevices();
1055 - meshserver.Send({ action: 'files' });
1055 + meshserver.send({ action: 'files' });
1056
1057 // If we are looking at a mesh that is now deleted, move back to "My Account"
1058 if (xxcurrentView == 20 && currentMesh._id == message.event.meshid) { p20updateMesh(); }
@@ -1063,7 +1063,7 @@
1063 if (meshes[message.event.meshid]) {
1064 delete meshes[message.event.meshid];
1065 updateMeshes();
1066 - meshserver.Send({ action: 'files' });
1066 + meshserver.send({ action: 'files' });
1067 }
1068
1069 // Delete all nodes in that mesh
@@ -1505,7 +1505,7 @@
1505 if (elements[i].checked) {
1506 var ipaddr = elements[i].getAttribute('tag');
1507 var amtinfo = amtScanResults[ipaddr];
1508 - meshserver.Send({ action: 'addamtdevice', meshid: meshid, devicename: ipaddr, hostname: amtinfo.hostname, amtusername: '', amtpassword: '', amttls: amtinfo.tls });
1508 + meshserver.send({ action: 'addamtdevice', meshid: meshid, devicename: ipaddr, hostname: amtinfo.hostname, amtusername: '', amtpassword: '', amttls: amtinfo.tls });
1509 }
1510 }
1511 }
@@ -1515,7 +1515,7 @@
1515 QE('dp1range', false);
1516 QE('dp1rangebutton', false);
1517 QH('dp1results', '<div style=width:100%;text-align:center;margin-top:12px>Scanning...</div>');
1518 - meshserver.Send({ action: 'scanamtdevice', range: Q('dp1range').value });
1518 + meshserver.send({ action: 'scanamtdevice', range: Q('dp1range').value });
1519 }
1520
1521 // Called when a scanned computer is checked or unchecked.
@@ -1596,7 +1596,7 @@
1596 }
1597
1598 function performAgentInvite(button, meshid) {
1599 - meshserver.Send({ action: 'inviteAgent', meshid: meshid, email: Q('agentInviteEmail').value });
1599 + meshserver.send({ action: 'inviteAgent', meshid: meshid, email: Q('agentInviteEmail').value });
1600 }
1601
1602 function addAgentToMesh(meshid) {
@@ -1660,7 +1660,7 @@
1660 if (amtuser == '') amtuser = 'admin';
1661 var host = Q('dp1hostname').value;
1662 if (host == '') host = Q('dp1devicename').value;
1663 - meshserver.Send({ action: 'addamtdevice', meshid: meshid, devicename: Q('dp1devicename').value, hostname: host, amtusername: amtuser, amtpassword: Q('dp1password').value, amttls: Q('dp1tls').value });
1663 + meshserver.send({ action: 'addamtdevice', meshid: meshid, devicename: Q('dp1devicename').value, hostname: host, amtusername: amtuser, amtpassword: Q('dp1password').value, amttls: Q('dp1tls').value });
1664 }
1665
1666 function deviceHeaderSet() {
@@ -1735,7 +1735,7 @@
1735 // Group wake
1736 var nodeids = [], elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
1737 for (var i in elements) { if (elements[i].checked) { nodeids.push(elements[i].value.substring(6)); } }
1738 - meshserver.Send({ action: 'wakedevices', nodeids: nodeids });
1738 + meshserver.send({ action: 'wakedevices', nodeids: nodeids });
1739 } else if (op == 101) {
1740 // Group delete, ask for confirmation
1741 var x = "Confirm delete selected devices(s)?<br /><br />";
@@ -1746,7 +1746,7 @@
1746 // Power operation
1747 var nodeids = [], elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
1748 for (var i in elements) { if (elements[i].checked) { nodeids.push(elements[i].value.substring(6)); } }
1749 - meshserver.Send({ action: 'poweraction', nodeids: nodeids, actiontype: op });
1749 + meshserver.send({ action: 'poweraction', nodeids: nodeids, actiontype: op });
1750 }
1751 }
1752
@@ -1755,7 +1755,7 @@
1755 function groupActionFunctionDelEx() {
1756 var nodeids = [], elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
1757 for (var i in elements) { if (elements[i].checked) { nodeids.push(elements[i].value.substring(6)); } }
1758 - meshserver.Send({ action: 'removedevices', nodeids: nodeids });
1758 + meshserver.send({ action: 'removedevices', nodeids: nodeids });
1759 }
1760
1761 function onSortSelectChange(skipsave) {
@@ -1875,7 +1875,7 @@
1875
1876 // Clear Marker item
1877 var map_cm_clearMarker = { text: "Remove node location", callback: function (obj) {
1878 - meshserver.Send({ action: 'changedevice', nodeid: obj.data.a, userloc: [] }); // Clear the user position marker
1878 + meshserver.send({ action: 'changedevice', nodeid: obj.data.a, userloc: [] }); // Clear the user position marker
1879 }};
1880
1881 // Save Marker item
@@ -2085,7 +2085,7 @@
2085 var coord = ft.getGeometry().getCoordinates();
2086 var v = ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326');
2087 var vx = [ v[1], v[0] ]; // Flip the coordinates around, lat/long
2088 - meshserver.Send({ action: 'changedevice', nodeid: featid, userloc: vx }); // Send them to server to save changes
2088 + meshserver.send({ action: 'changedevice', nodeid: featid, userloc: vx }); // Send them to server to save changes
2089 }
2090 }
2091 }
@@ -2241,10 +2241,10 @@
2241 if (activeInteraction) {
2242 saveMarkerloc(feature);
2243 } else { // If this feature is not saved after its location is changed, then send updated coords to server.
2244 - meshserver.Send({ action: 'changedevice', nodeid: node._id, userloc: vx }); // Send them to server to save changes
2244 + meshserver.send({ action: 'changedevice', nodeid: node._id, userloc: vx }); // Send them to server to save changes
2245 }
2246 } else {
2247 - meshserver.Send({ action: 'changedevice', nodeid: node._id, userloc: vx }); // This Node is not yet added to maps.
2247 + meshserver.send({ action: 'changedevice', nodeid: node._id, userloc: vx }); // This Node is not yet added to maps.
2248 }
2249 }
2250 }
@@ -2616,7 +2616,7 @@
2616 QV('filesActionsBtn', (meshrights & 72) != 0);
2617
2618 // Request the power timeline
2619 - if ((powerTimelineNode != currentNode._id) && (powerTimelineReq != currentNode._id)) { powerTimelineReq = currentNode._id; meshserver.Send({ action: 'powertimeline', nodeid: currentNode._id }); }
2619 + if ((powerTimelineNode != currentNode._id) && (powerTimelineReq != currentNode._id)) { powerTimelineReq = currentNode._id; meshserver.send({ action: 'powertimeline', nodeid: currentNode._id }); }
2620 }
2621 if (!panel) panel = 10;
2622 go(panel);
@@ -2637,10 +2637,10 @@
2637 var op = Q('d2deviceop').value;
2638 if (op == 100) {
2639 // Device wake
2640 - meshserver.Send({ action: 'wakedevices', nodeids: [ currentNode._id ] });
2640 + meshserver.send({ action: 'wakedevices', nodeids: [ currentNode._id ] });
2641 } else {
2642 // Power operation
2643 - meshserver.Send({ action: 'poweraction', nodeids: [ currentNode._id ], actiontype: op });
2643 + meshserver.send({ action: 'poweraction', nodeids: [ currentNode._id ], actiontype: op });
2644 }
2645 }
2646
@@ -2661,7 +2661,7 @@
2661 // Look to see if we need to update the device timeline
2662 function updateDeviceTimeline() {
2663 if ((meshserver.State != 2) || (powerTimelineNode == null) || (powerTimelineUpdate == null) || (currentNode == null)) return;
2664 - if ((powerTimelineNode == powerTimelineReq) && (currentNode._id == powerTimelineNode) && (powerTimelineUpdate < Date.now())) { powerTimelineUpdate = null; meshserver.Send({ action: 'powertimeline', nodeid: currentNode._id }); }
2664 + if ((powerTimelineNode == powerTimelineReq) && (currentNode._id == powerTimelineNode) && (powerTimelineUpdate < Date.now())) { powerTimelineUpdate = null; meshserver.send({ action: 'powertimeline', nodeid: currentNode._id }); }
2665 }
2666
2667 // Draw device power bars. The bars are 766px wide.
@@ -2746,14 +2746,14 @@
2746 function editDeviceAmtSettingsEx(button, tag) {
2747 if (button == 2) {
2748 // Delete button pressed, remove credentials
2749 - meshserver.Send({ action: 'changedevice', nodeid: tag.node._id, intelamt: { user: '', pass: '' } });
2749 + meshserver.send({ action: 'changedevice', nodeid: tag.node._id, intelamt: { user: '', pass: '' } });
2750 } else {
2751 // Change Intel AMT credentials
2752 var amtuser = Q('dp10username').value;
2753 if (amtuser == '') amtuser = 'admin';
2754 var amtpass = Q('dp10password').value;
2755 if (amtpass == '') amtuser = '';
2756 - meshserver.Send({ action: 'changedevice', nodeid: tag.node._id, intelamt: { user: amtuser, pass: amtpass, tls: Q('dp10tls').value } });
2756 + meshserver.send({ action: 'changedevice', nodeid: tag.node._id, intelamt: { user: amtuser, pass: amtpass, tls: Q('dp10tls').value } });
2757 tag.node.intelamt.user = amtuser;
2758 tag.node.intelamt.tls = Q('dp10tls').value;
2759 if (tag.func) { setTimeout(tag.func, 300); }
@@ -2773,11 +2773,11 @@
2773 }
2774
2775 function p10showDeleteNodeDialogEx(buttons, nodeid) {
2776 - meshserver.Send({ action: 'removedevices', nodeids: [ nodeid ] });
2776 + meshserver.send({ action: 'removedevices', nodeids: [ nodeid ] });
2777 }
2778
2779 function p10clickOnce(nodeid, protocol, port) {
2780 - meshserver.Send({ action: 'getcookie', nodeid: nodeid, tcpport: port, tag: 'clickonce', protocol: protocol });
2780 + meshserver.send({ action: 'getcookie', nodeid: nodeid, tcpport: port, tag: 'clickonce', protocol: protocol });
2781 }
2782
2783 // Show current location
@@ -2831,7 +2831,7 @@
2831 function p10showNodeNetInfoDialog() {
2832 if (xxdialogMode) return;
2833 setDialogMode(2, "Network Interfaces", 1, null, "<div id=d2netinfo>Loading...</div>", 'if' + currentNode._id );
2834 - meshserver.Send({ action: 'getnetworkinfo', nodeid: currentNode._id });
2834 + meshserver.send({ action: 'getnetworkinfo', nodeid: currentNode._id });
2835 }
2836
2837 // Show router dialog
@@ -2888,7 +2888,7 @@
2888
2889 function p10setIcon(icon) {
2890 setDialogMode(0);
2891 - meshserver.Send({ action: 'changedevice', nodeid: currentNode._id, icon: icon });
2891 + meshserver.send({ action: 'changedevice', nodeid: currentNode._id, icon: icon });
2892 }
2893
2894 var showEditNodeValueDialog_modes = ['Device Name', 'Hostname', 'Description'];
@@ -2907,7 +2907,7 @@
2907 function showEditNodeValueDialogEx(button, mode) {
2908 var x = { action: 'changedevice', nodeid: currentNode._id };
2909 x[showEditNodeValueDialog_modes2[mode]] = Q('dp10devicevalue').value;
2910 - meshserver.Send(x);
2910 + meshserver.send(x);
2911 }
2912
2913 function p10editdevicevalueValidate(mode, e) {
@@ -3314,7 +3314,7 @@
3314 break;
3315 case 3:
3316 p13targetpath = '';
3317 - files.Send(JSON.stringify({ action: 'ls', reqid: 1, path: '' }));
3317 + files.send(JSON.stringify({ action: 'ls', reqid: 1, path: '' }));
3318 break;
3319 }
3320 }
@@ -3335,7 +3335,7 @@
3335 if (!files) {
3336 // Setup a mesh agent files
3337 files = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotFiles), serverPublicNamePort);
3338 - files.attemptWebRTC = false;
3338 + files.attemptWebRTC = attemptWebRTC;
3339 files.onStateChanged = onFilesStateChange;
3340 files.Start(filesNode._id);
3341 } else {
@@ -3351,7 +3351,11 @@
3351 var p13filetreelocation = [];
3352
3353 function p13gotFiles(data) {
3354 + //console.log('p13gotFiles', data);
3355 + if ((data.length > 0) && (data.charCodeAt(0) != 123)) { p13gotDownloadBinaryData(data); return; }
3356 + //console.log('p13gotFiles', data);
3357 data = JSON.parse(data);
3358 + if (data.action == 'download') { p13gotDownloadCommand(data); return; }
3359 data.path = data.path.replace(/\//g, "\\");
3360 if ((p13filetree != null) && (data.path == p13filetree.path)) {
3361 // This is an update to the same folder
@@ -3450,13 +3454,13 @@
3454
3455 function p13folderset(x) {
3456 p13targetpath = joinPaths(p13filetree.path, p13filetree.dir[x].n).split('\\').join('/');
3453 - files.Send(JSON.stringify({ action: 'ls', reqid: 1, path: p13targetpath }));
3457 + files.send(JSON.stringify({ action: 'ls', reqid: 1, path: p13targetpath }));
3458 }
3459
3460 function p13folderup(x) {
3461 if (x == null) { p13filetreelocation.pop(); } else { while (p13filetreelocation.length > x) { p13filetreelocation.pop(); } }
3462 p13targetpath = p13filetreelocation.join('/');
3459 - files.Send(JSON.stringify({ action: 'ls', reqid: 1, path: p13targetpath }));
3463 + files.send(JSON.stringify({ action: 'ls', reqid: 1, path: p13targetpath }));
3464 }
3465
3466 var p13sortorder;
@@ -3501,11 +3505,11 @@
3505 function p13getFileCount() { var cc = 0; var checkboxes = document.getElementsByName('fd'); return checkboxes.length; }
3506 function p13selectallfile() { var nv = (p13getFileSelCount() == 0), checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = nv; } p13setActions(); }
3507 function p13createfolder() { setDialogMode(2, "New Folder", 3, p13createfolderEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% />'); focusTextBox('p13renameinput'); p13fileNameCheck(); }
3504 - function p13createfolderEx() { files.Send(JSON.stringify({ action: 'mkdir', reqid: 1, path: p13filetreelocation.join('/') + '/' + Q('p13renameinput').value })); p13folderup(999); }
3508 + function p13createfolderEx() { files.send(JSON.stringify({ action: 'mkdir', reqid: 1, path: p13filetreelocation.join('/') + '/' + Q('p13renameinput').value })); p13folderup(999); }
3509 function p13deletefile() { var cc = getFileSelCount(); setDialogMode(2, "Delete", 3, p13deletefileEx, (cc > 1)?('Delete ' + cc + ' selected items?'):('Delete selected item?')); }
3506 - function p13deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(p13filetree.dir[checkboxes[i].value].n); } } files.Send(JSON.stringify({ action: 'rm', reqid: 1, path: p13filetreelocation.join('/'), delfiles: delfiles })); p13folderup(999); }
3510 + function p13deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(p13filetree.dir[checkboxes[i].value].n); } } files.send(JSON.stringify({ action: 'rm', reqid: 1, path: p13filetreelocation.join('/'), delfiles: delfiles })); p13folderup(999); }
3511 function p13renamefile() { var renamefile, checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { renamefile = p13filetree.dir[checkboxes[i].value].n; } } setDialogMode(2, "Rename", 3, p13renamefileEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% value="' + renamefile + '" />', { action: 'rename', path: p13filetreelocation.join('/'), oldname: renamefile}); focusTextBox('p13renameinput'); p13fileNameCheck(); }
3508 - function p13renamefileEx(b, t) { t.newname = Q('p13renameinput').value; files.Send(JSON.stringify(t)); p13folderup(999); }
3512 + function p13renamefileEx(b, t) { t.newname = Q('p13renameinput').value; files.send(JSON.stringify(t)); p13folderup(999); }
3513 function p13fileNameCheck(e) { var x = isFilenameValid(Q('p13renameinput').value); QE('idx_dlgOkButton', x); if ((x == true) && (e.keyCode == 13)) { dialogclose(1); } }
3514 function p13uploadFile() { setDialogMode(2, "Upload File", 3, p13uploadFileEx, '<input type=file name=files id=p13uploadinput style=width:100% multiple=multiple onchange="updateUploadDialogOk(\'p13uploadinput\')" />'); updateUploadDialogOk('p13uploadinput'); }
3515 function p13uploadFileEx() { p13doUploadFiles(Q('p13uploadinput').files); }
@@ -3545,8 +3549,42 @@
3549
3550 // Called by the html page to start a download, arguments are: path, file name and file size.
3551 function p13downloadfile(x, y, z) {
3548 - downloadFile = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotDownloadData), serverPublicNamePort); // Create our file transport
3549 - downloadFile.attemptWebRTC = false;
3552 + if (xxdialogMode || downloadFile || !files) return;
3553 + downloadFile = { path: decodeURIComponent(x), file: decodeURIComponent(y), size: z, tsize: 0, data: '', state: 0, id: Math.random() }
3554 + //console.log('p13downloadFileCancel', downloadFile);
3555 + files.send(JSON.stringify({ action: 'download', sub: 'start', id: downloadFile.id, path: downloadFile.path }));
3556 + setDialogMode(2, "Download File", 10, p13downloadFileCancel, '<div>' + downloadFile.file + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=' + z + ' />');
3557 + }
3558 +
3559 + // Called by the html page to cancel the download
3560 + function p13downloadFileCancel() { setDialogMode(0); files.send(JSON.stringify({ action: 'download', sub: 'cancel', id: downloadFile.id })); downloadFile = null; }
3561 +
3562 + // Called by the transport when download control command is received
3563 + function p13gotDownloadCommand(cmd) {
3564 + //console.log('p13gotDownloadCommand', cmd);
3565 + if ((downloadFile == null) || (cmd.id != downloadFile.id)) return;
3566 + if (cmd.sub == 'start') { downloadFile.state = 1; files.send(JSON.stringify({ action: 'download', sub: 'startack', id: downloadFile.id })); }
3567 + else if (cmd.sub == 'cancel') { downloadFile = null; setDialogMode(0); }
3568 + else if (cmd.sub == 'done') { saveAs(data2blob(downloadFile.data), downloadFile.file); downloadFile = null; setDialogMode(0); } // Save the file
3569 + }
3570 +
3571 + // Called by the transport when binary data is received
3572 + function p13gotDownloadBinaryData(data) {
3573 + if (!downloadFile || downloadFile.state == 0) return;
3574 + downloadFile.tsize += (data.length - 4); // Add to the total bytes received
3575 + downloadFile.data += data.substring(4); // Append the data
3576 + Q('d2progressBar').value = downloadFile.tsize; // Change the progress bar
3577 + files.send(JSON.stringify({ action: 'download', sub: 'ack', id: downloadFile.id })); // Send the ACK
3578 + }
3579 +
3580 + /*
3581 + var downloadFile; // Global state for file download
3582 +
3583 + // Called by the html page to start a download, arguments are: path, file name and file size.
3584 + function p13downloadfile(x, y, z) {
3585 + if (xxdialogMode) return;
3586 + downloadFile = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotDownloadData), serverPublicNamePort); // Create our websocket file transport
3587 + downloadFile.ctrlMsgAllowed = false;
3588 downloadFile.onStateChanged = onFileDownloadStateChange;
3589 downloadFile.xpath = decodeURIComponent(x);
3590 downloadFile.xfile = decodeURIComponent(y);
@@ -3573,7 +3611,7 @@
3611 if ((downloadFile != null) && (downloadFile.xstate == 1)) { saveAs(data2blob(downloadFile.xdata), downloadFile.xfile); } // Save the file
3612 break;
3613 case 3: // Transport as connected, send a command to indicate we want to start a file download
3576 - downloadFile.Send(JSON.stringify({ action: 'download', reqid: 1, path: downloadFile.xpath }));
3614 + downloadFile.send(JSON.stringify({ action: 'download', reqid: 1, path: downloadFile.xpath }));
3615 break;
3616 }
3617 }
@@ -3585,7 +3623,7 @@
3623 if (cmd.action == 'downloadstart') { // Yes, the file is about to start
3624 downloadFile.xstate = 1; // Switch to state 1, we will start receiving the file data
3625 downloadFile.xdata = ''; // Start with empty data
3588 - downloadFile.Send('a'); // Send the first ACK
3626 + downloadFile.send('a'); // Send the first ACK
3627 } else if (cmd.action == 'downloaderror') { // Problem opening this file, cancel
3628 p13downloadFileCancel();
3629 }
@@ -3593,9 +3631,10 @@
3631 downloadFile.xtsize += (data.length); // Add to the total bytes received
3632 downloadFile.xdata += data; // Append the data
3633 Q('d2progressBar').value = downloadFile.xtsize; // Change the progress bar
3596 - downloadFile.Send('a'); // Send the ACK
3634 + downloadFile.send('a'); // Send the ACK
3635 }
3636 }
3637 + */
3638
3639 //
3640 // FILES UPLOAD
@@ -3603,6 +3642,7 @@
3642
3643 var uploadFile;
3644 function p13doUploadFiles(files) {
3645 + if (xxdialogMode) return;
3646 uploadFile = {};
3647 uploadFile.xpath = p13filetreelocation.join('/');
3648 uploadFile.xfiles = files;
@@ -3626,6 +3666,7 @@
3666 function p13uploadReconnect() {
3667 uploadFile.ws = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotUploadData), serverPublicNamePort);
3668 uploadFile.ws.attemptWebRTC = false;
3669 + uploadFile.ws.ctrlMsgAllowed = false;
3670 uploadFile.ws.onStateChanged = onFileUploadStateChange;
3671 uploadFile.ws.Start(filesNode._id);
3672 }
@@ -3643,7 +3684,7 @@
3684 uploadFile.xreader = new FileReader();
3685 uploadFile.xreader.onload = function() {
3686 uploadFile.xdata = uploadFile.xreader.result;
3646 - uploadFile.ws.Send(JSON.stringify({ action: 'upload', reqid: uploadFile.xfilePtr, path: uploadFile.xpath, name: file.name, size: uploadFile.xdata.byteLength }));
3687 + uploadFile.ws.send(JSON.stringify({ action: 'upload', reqid: uploadFile.xfilePtr, path: uploadFile.xpath, name: file.name, size: uploadFile.xdata.byteLength }));
3688 };
3689 uploadFile.xreader.readAsArrayBuffer(file);
3690 } else {
@@ -3689,7 +3730,7 @@
3730 if (uploadFile.xfiles.length > uploadFile.xfilePtr + 1) { p13uploadReconnect(); } else { p13uploadFileCancel(); }
3731 } else {
3732 var datapart = data.slice(start, end);
3692 - uploadFile.ws.Send(datapart);
3733 + uploadFile.ws.send(datapart);
3734 uploadFile.xptr = end;
3735 Q('d2progressBar').value = end;
3736 }
@@ -3777,7 +3818,7 @@
3818 Q('p15consoleText').value = '';
3819
3820 // Send the command to the mesh agent
3780 - meshserver.Send({ action: 'msg', type:'console', nodeid: consoleNode._id, value: v });
3821 + meshserver.send({ action: 'msg', type:'console', nodeid: consoleNode._id, value: v });
3822
3823 // Add command to history list
3824 if (v.length > 0) {
@@ -3802,8 +3843,8 @@
3843 // Called then user presses the "Change Core" button
3844 function p15uploadCore(e) {
3845 if (xxdialogMode) return;
3805 - if (e.shiftKey == true) { meshserver.Send({ action: 'uploadagentcore', nodeid: consoleNode._id, path:'*' }); } // Upload default core
3806 - else if (e.altKey == true) { meshserver.Send({ action: 'uploadagentcore', nodeid: consoleNode._id }); } // Clear the core
3846 + if (e.shiftKey == true) { meshserver.send({ action: 'uploadagentcore', nodeid: consoleNode._id, path:'*' }); } // Upload default core
3847 + else if (e.altKey == true) { meshserver.send({ action: 'uploadagentcore', nodeid: consoleNode._id }); } // Clear the core
3848 else if (e.ctrlKey == true) { p15uploadCore2(); } // Upload the core from a file
3849 else { setDialogMode(2, "Change Mesh Agent Core", 3, p15uploadCoreEx, '<select id=d3coreMode style=float:right;width:260px><option value=1>Upload default server core</option><option value=2>Clear the core</option><option value=3>Upload a core file</option><option value=4>Soft disconnect agent</option><option value=5>Hard disconnect agent</option></select><div>Change Core</div>'); }
3850 }
@@ -3811,19 +3852,19 @@
3852 function p15uploadCoreEx() {
3853 if (Q('d3coreMode').value == 1) {
3854 // Upload default core
3814 - meshserver.Send({ action: 'uploadagentcore', nodeid: consoleNode._id, path:'*' });
3855 + meshserver.send({ action: 'uploadagentcore', nodeid: consoleNode._id, path:'*' });
3856 } else if (Q('d3coreMode').value == 2) {
3857 // Clear the core
3817 - meshserver.Send({ action: 'uploadagentcore', nodeid: consoleNode._id });
3858 + meshserver.send({ action: 'uploadagentcore', nodeid: consoleNode._id });
3859 } else if (Q('d3coreMode').value == 3) {
3860 // Upload file as core
3861 p15uploadCore2();
3862 } else if (Q('d3coreMode').value == 4) {
3863 // Soft disconnect the mesh agent
3823 - meshserver.Send({ action: 'agentdisconnect', nodeid: consoleNode._id, disconnectMode: 1 });
3864 + meshserver.send({ action: 'agentdisconnect', nodeid: consoleNode._id, disconnectMode: 1 });
3865 } else if (Q('d3coreMode').value == 5) {
3866 // Hard disconnect the mesh agent
3826 - meshserver.Send({ action: 'agentdisconnect', nodeid: consoleNode._id, disconnectMode: 2 });
3867 + meshserver.send({ action: 'agentdisconnect', nodeid: consoleNode._id, disconnectMode: 2 });
3868 }
3869 }
3870
@@ -3844,7 +3885,7 @@
3885 } else {
3886 // Upload server mesh agent code
3887 var files = d3getFileSel();
3847 - if (files.length == 1) { meshserver.Send({ action: 'uploadagentcore', nodeid: consoleNode._id, path: d3filetreelocation.join('/') + '/' + files[0] }); }
3888 + if (files.length == 1) { meshserver.send({ action: 'uploadagentcore', nodeid: consoleNode._id, path: d3filetreelocation.join('/') + '/' + files[0] }); }
3889 }
3890 }
3891
@@ -3859,7 +3900,7 @@
3900 }
3901
3902 function account_showVerifyEmailEx() {
3862 - meshserver.Send({ action: 'verifyemail', email: userinfo.email });
3903 + meshserver.send({ action: 'verifyemail', email: userinfo.email });
3904 }
3905
3906 function account_showChangeEmail() {
@@ -3880,7 +3921,7 @@
3921 }
3922
3923 function account_changeEmail() {
3883 - meshserver.Send({ action: 'changeemail', email: Q('dp2email').value });
3924 + meshserver.send({ action: 'changeemail', email: Q('dp2email').value });
3925 }
3926
3927 function account_showDeleteAccount() {
@@ -3933,7 +3974,7 @@
3974 }
3975
3976 function account_createMeshEx(button, tag) {
3936 - meshserver.Send({ action: 'createmesh', meshname: Q('dp2meshname').value, meshtype: Q('dp2meshtype').value, desc: Q('dp2meshdesc').value });
3977 + meshserver.send({ action: 'createmesh', meshname: Q('dp2meshname').value, meshtype: Q('dp2meshtype').value, desc: Q('dp2meshdesc').value });
3978 }
3979
3980 function account_validateDeleteAccount() {
@@ -4004,11 +4045,11 @@
4045 function server_showVersionDlg() {
4046 if (xxdialogMode) return;
4047 setDialogMode(2, "MeshCentral Version", 1, null, "Loading...", 'MeshCentralServerUpdate');
4007 - meshserver.Send({ action: 'serverversion' });
4048 + meshserver.send({ action: 'serverversion' });
4049 }
4050
4051 function server_showVersionDlgEx() {
4011 - meshserver.Send({ action: 'serverupdate' });
4052 + meshserver.send({ action: 'serverupdate' });
4053 }
4054
4055 //
@@ -4091,7 +4132,7 @@
4132 }
4133
4134 function p20showDeleteMeshDialogEx(buttons, tag) {
4094 - meshserver.Send({ action: 'deletemesh', meshid: currentMesh._id, meshname: currentMesh.name });
4135 + meshserver.send({ action: 'deletemesh', meshid: currentMesh._id, meshname: currentMesh.name });
4136 }
4137
4138 function p20editmesh(focus) {
@@ -4107,7 +4148,7 @@
4148 }
4149
4150 function p20editmeshEx() {
4110 - meshserver.Send({ action: 'editmesh', meshid: currentMesh._id, meshname: Q('dp20meshname').value, desc: Q('dp20meshdesc').value });
4151 + meshserver.send({ action: 'editmesh', meshid: currentMesh._id, meshname: Q('dp20meshname').value, desc: Q('dp20meshdesc').value });
4152 }
4153
4154 function p20editmeshValidate() {
@@ -4157,7 +4198,7 @@
4198 if (Q('p20meshserverfiles').checked == true) meshadmin += 32;
4199 if (Q('p20wakedevices').checked == true) meshadmin += 64;
4200 }
4160 - meshserver.Send({ action: 'addmeshuser', meshid: currentMesh._id, meshname: currentMesh.name, username: Q('dp20username').value , meshadmin: meshadmin});
4201 + meshserver.send({ action: 'addmeshuser', meshid: currentMesh._id, meshname: currentMesh.name, username: Q('dp20username').value , meshadmin: meshadmin});
4202 }
4203
4204 function p20viewuser(userid) {
@@ -4193,7 +4234,7 @@
4234 }
4235
4236 function p20viewuserEx2(button, userid) {
4196 - meshserver.Send({ action: 'removemeshuser', meshid: currentMesh._id, meshname: currentMesh.name, userid: userid});
4237 + meshserver.send({ action: 'removemeshuser', meshid: currentMesh._id, meshname: currentMesh.name, userid: userid});
4238 }
4239
4240 //
@@ -4331,11 +4372,11 @@
4372 function p5folderup(x) { if (x == null) { filetreelocation.pop(); } else { while (filetreelocation.length > x) { filetreelocation.pop(); } } updateFiles(); }
4373 function p5folderset(x) { filetreelocation.push(decodeURIComponent(x)); updateFiles(); }
4374 function p5createfolder() { setDialogMode(2, "New Folder", 3, p5createfolderEx, '<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% />'); focusTextBox('p5renameinput'); p5fileNameCheck(); }
4334 - function p5createfolderEx() { meshserver.Send({ action: 'fileoperation', fileop: 'createfolder', path: filetreelocation, newfolder: Q('p5renameinput').value}); }
4375 + function p5createfolderEx() { meshserver.send({ action: 'fileoperation', fileop: 'createfolder', path: filetreelocation, newfolder: Q('p5renameinput').value}); }
4376 function p5deletefile() { var cc = getFileSelCount(); setDialogMode(2, "Delete", 3, p5deletefileEx, (cc > 1)?('Delete ' + cc + ' selected items?'):('Delete selected item?')); }
4336 - function p5deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(checkboxes[i].value); } } meshserver.Send({ action: 'fileoperation', fileop: 'delete', path: filetreelocation, delfiles: delfiles}); }
4377 + function p5deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(checkboxes[i].value); } } meshserver.send({ action: 'fileoperation', fileop: 'delete', path: filetreelocation, delfiles: delfiles}); }
4378 function p5renamefile() { var renamefile, checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { renamefile = checkboxes[i].value; } } setDialogMode(2, "Rename", 3, p5renamefileEx, '<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% value="' + renamefile + '" />', { action: 'fileoperation', fileop: 'rename', path: filetreelocation, oldname: renamefile}); focusTextBox('p5renameinput'); p5fileNameCheck(); }
4338 - function p5renamefileEx(b, t) { t.newname = Q('p5renameinput').value; meshserver.Send(t); }
4379 + function p5renamefileEx(b, t) { t.newname = Q('p5renameinput').value; meshserver.send(t); }
4380 function p5fileNameCheck(e) { var x = isFilenameValid(Q('p5renameinput').value); QE('idx_dlgOkButton', x); if ((x == true) && (e.keyCode == 13)) { dialogclose(1); } }
4381 var isFilenameValid = (function(){ var x1=/^[^\\/:\*\?"<>\|]+$/, x2=/^\./, x3=/^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname){ return x1.test(fname)&&!x2.test(fname)&&!x3.test(fname)&&(fname[0] != '.'); } })();
4382 function p5uploadFile() { setDialogMode(2, "Upload File", 3, p5uploadFileEx, '<form method=post enctype=multipart/form-data action=uploadfile.ashx target=fileUploadFrame><input type=text name=link style=display:none id=p5uploadpath value=\"' + encodeURIComponent(filetreelinkpath) + '\" /><input type=file name=files id=p5uploadinput style=width:100% multiple=multiple onchange="updateUploadDialogOk(\'p5uploadinput\')" /><input type=submit id=p5loginSubmit style=display:none /></form>'); updateUploadDialogOk('p5uploadinput'); }
@@ -4439,11 +4480,11 @@
4480 }
4481
4482 function showDeleteAllEventsDialogEx(buttons, tag) {
4442 - meshserver.Send({ action: 'clearevents' });
4483 + meshserver.send({ action: 'clearevents' });
4484 }
4485
4486 function refreshEvents() {
4446 - meshserver.Send({ action: 'events', limit: parseInt(p3limitdropdown.value) });
4487 + meshserver.send({ action: 'events', limit: parseInt(p3limitdropdown.value) });
4488 }
4489
4490 //
@@ -4506,7 +4547,7 @@
4547 }
4548
4549 function showUserInfoDialogDelete(button, user) {
4509 - if (button == 2) { meshserver.Send({ action: 'deleteuser', userid: user._id, username: user.name }); }
4550 + if (button == 2) { meshserver.send({ action: 'deleteuser', userid: user._id, username: user.name }); }
4551 }
4552
4553 function showCreateNewAccountDialog() {
@@ -4526,7 +4567,7 @@
4567 }
4568
4569 function showCreateNewAccountDialogEx() {
4529 - meshserver.Send({ action: 'adduser', username: Q('p4name').value, email: Q('p4email').value, pass: Q('p4pass1').value });
4570 + meshserver.send({ action: 'adduser', username: Q('p4name').value, email: Q('p4email').value, pass: Q('p4pass1').value });
4571 }
4572
4573 function showUserAdminDialog(e, userid) {
@@ -4583,7 +4624,7 @@
4624 }
4625 var x = { action: 'edituser', name: user.name, siteadmin: siteadmin };
4626 if (isNaN(quota) == false) { x.quota = (quota * 1024); }
4586 - meshserver.Send(x);
4627 + meshserver.send(x);
4628 }
4629
4630 //