Fixed Windows Locking, MeshCentral certificates and more

Ylian Saint-Hilaire committed Jul 23, 2018 at 17:34 UTC d38cb66dda3c25adf31351f1e9facc56dd12287c
19 files changed +90 -58
agents/MeshCmd-signed.exe
Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ
agents/MeshCmd64-signed.exe
Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ
agents/MeshService-signed.exe
Binary files a/agents/MeshService-signed.exe and b/agents/MeshService-signed.exe differ
agents/MeshService.exe
Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ
agents/MeshService64-signed.exe
Binary files a/agents/MeshService64-signed.exe and b/agents/MeshService64-signed.exe differ
agents/MeshService64.exe
Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ
agents/meshcmd.js
+6 -4
@@ -1353,10 +1353,12 @@ function discoverMeshServerOnce() {
1353 multicastSockets[i] = dgram.createSocket({ type: (addr.family == "IPv4" ? "udp4" : "udp6") });
1354 multicastSockets[i].bind({ address: addr.address, exclusive: false });
1355 if (addr.family == "IPv4") {
1356 - multicastSockets[i].addMembership(membershipIPv4);
1357 - //multicastSockets[i].setMulticastLoopback(true);
1358 - multicastSockets[i].once('message', OnMulticastMessage);
1359 - multicastSockets[i].send(settings.serverId, 16989, membershipIPv4);
1356 + try {
1357 + multicastSockets[i].addMembership(membershipIPv4);
1358 + //multicastSockets[i].setMulticastLoopback(true);
1359 + multicastSockets[i].once('message', OnMulticastMessage);
1360 + multicastSockets[i].send(settings.serverId, 16989, membershipIPv4);
1361 + } catch (e) { }
1362 }
1363 }
1364 }
agents/meshcore.js
+39 -12
@@ -112,13 +112,9 @@ function createMeshCore(agent) {
112 try {
113 getIpLocationDataExInProgress = true;
114 getIpLocationDataExCounts[0]++;
115 - http.request({
116 - host: 'ipinfo.io', // TODO: Use a HTTP proxy if needed!!!!
117 - port: 80,
118 - path: 'http://ipinfo.io/json', // Use this service to get our geolocation
119 - headers: { Host: "ipinfo.io" }
120 - },
121 - function (resp) {
115 + var options = http.parseUri("http://ipinfo.io/json");
116 + options.method = 'GET';
117 + http.request(options, function (resp) {
118 if (resp.statusCode == 200) {
119 var geoData = '';
120 resp.data = function (geoipdata) { geoData += geoipdata; };
@@ -755,7 +751,7 @@ function createMeshCore(agent) {
751 function onTunnelWebRTCControlData(data) {
752 if (typeof data != 'string') return;
753 var obj;
758 - try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON on WebRTC'); return; }
754 + try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON on WebRTC: ' + data); return; }
755 if (obj.type == 'close') {
756 //sendConsoleText('Tunnel #' + this.xrtc.websocket.tunnel.index + ' WebRTC control close');
757 try { this.close(); } catch (e) { }
@@ -767,11 +763,27 @@ function createMeshCore(agent) {
763 function onTunnelControlData(data, ws) {
764 var obj;
765 if (ws == null) { ws = this; }
770 - if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON'); return; } }
766 + if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON: ' + data); return; } }
767 else if (typeof data == 'object') { obj = data; } else { return; }
768 //sendConsoleText('onTunnelControlData(' + ws.httprequest.protocol + '): ' + JSON.stringify(data));
769 //console.log('onTunnelControlData: ' + JSON.stringify(data));
770
771 + if (obj.action) {
772 + switch (obj.action) {
773 + case 'lock': {
774 + // Lock the current user out of the desktop
775 + try {
776 + if (process.platform == 'win32') {
777 + var child = require('child_process');
778 + child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 });
779 + }
780 + } catch (e) { }
781 + break;
782 + }
783 + }
784 + return;
785 + }
786 +
787 if (obj.type == 'close') {
788 // We received the close on the websocket
789 //sendConsoleText('Tunnel #' + ws.tunnel.index + ' WebSocket control close');
@@ -850,7 +862,7 @@ function createMeshCore(agent) {
862 var response = null;
863 switch (cmd) {
864 case 'help': { // Displays available commands
853 - response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast.';
865 + response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock.';
866 break;
867 }
868 case 'toast': {
@@ -1117,6 +1129,15 @@ function createMeshCore(agent) {
1129 }
1130 break;
1131 }
1132 + case 'lsx': { // Show list of files and folders
1133 + response = objToString(getDirectoryInfo(args['_'][0]), 0, ' ', true);
1134 + break;
1135 + }
1136 + case 'lock': { // Lock the current user out of the desktop
1137 + if (process.platform == 'win32') { var child = require('child_process'); child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 }); response = 'Ok'; }
1138 + else { response = 'Not supported on the platform'; }
1139 + break;
1140 + }
1141 case 'amt': { // Show Intel AMT status
1142 getAmtInfo(function (state) {
1143 var resp = 'Intel AMT not detected.';
@@ -1463,7 +1484,7 @@ function createMeshCore(agent) {
1484 if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
1485 // List all the drives in the root, or the root itself
1486 var results = null;
1466 - try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
1487 + try { results = fs.readDrivesSync(); } catch (e) { sendConsoleText(e); } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
1488 //console.log('a', objToString(results, 0, ' '));
1489 if (results != null) {
1490 for (var i = 0; i < results.length; ++i) {
@@ -1478,7 +1499,7 @@ function createMeshCore(agent) {
1499 var xpath = path.join(reqpath, '*');
1500 var results = null;
1501
1481 - try { results = fs.readdirSync(xpath); } catch (e) { }
1502 + try { results = fs.readdirSync(xpath); } catch (e) { sendConsoleText(e); }
1503 if (results != null) {
1504 for (var i = 0; i < results.length; ++i) {
1505 if ((results[i] != '.') && (results[i] != '..')) {
@@ -1514,6 +1535,7 @@ function createMeshCore(agent) {
1535 return;
1536 }
1537 //console.log('KVM Ctrl Data', cmd);
1538 + //sendConsoleText('KVM Ctrl Data: ' + cmd);
1539
1540 try { cmd = JSON.parse(cmd); } catch (ex) { console.error('Invalid JSON: ' + cmd); return; }
1541 if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
@@ -1523,6 +1545,11 @@ function createMeshCore(agent) {
1545 channel.write({ action: 'pong' });
1546 break;
1547 }
1548 + case 'lock': {
1549 + // Lock the current user out of the desktop
1550 + if (process.platform == 'win32') { var child = require('child_process'); child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 }); }
1551 + break;
1552 + }
1553 case 'ls': {
1554 /*
1555 // Close the watcher if required
amtscanner.js
+1 -1
@@ -112,7 +112,7 @@ module.exports.CreateAmtScanner = function (parent) {
112 obj.performScan = function () {
113 //console.log('performScan');
114 if (obj.action == false) { return false; }
115 - obj.parent.db.getLocalAmtNodes(10, function (err, docs) { // TODO: handler more than 10 computer scan at the same time.
115 + obj.parent.db.getLocalAmtNodes(10, function (err, docs) { // TODO: handler more than 10 computer scan at the same time. DNS resolved may need to be a seperate module.
116 for (var i in obj.scanTable) { obj.scanTable[i].present = false; }
117 if (err == null && docs.length > 0) {
118 for (var i in docs) {
certoperations.js
+6 -3
@@ -283,6 +283,9 @@ module.exports.CertificateOperations = function () {
283 // Fetch the name of the server
284 var webCertificate = obj.pki.certificateFromPem(r.web.cert);
285 r.CommonName = webCertificate.subject.getField('CN').value;
286 + r.CommonNames = [ r.CommonName.toLowerCase() ];
287 + var altNames = webCertificate.getExtension('subjectAltName')
288 + if (altNames) { for (var i in altNames.altNames) { r.CommonNames.push(altNames.altNames[i].value.toLowerCase()); } }
289 var rootCertificate = obj.pki.certificateFromPem(r.root.cert);
290 r.RootName = rootCertificate.subject.getField('CN').value;
291
@@ -294,14 +297,14 @@ module.exports.CertificateOperations = function () {
297 if (certargs == null) { commonName = r.CommonName; country = xcountry; organization = xorganization; }
298
299 // Check if we have correct certificates
297 - if ((r.CommonName == commonName) && (xcountry == country) && (xorganization == organization) && (r.AmtMpsName == mpsCommonName)) {
300 + if ((r.CommonNames.indexOf(commonName.toLowerCase()) >= 0) && (r.AmtMpsName == mpsCommonName)) {
301 // Certificate matches what we want, keep it.
302 if (func != undefined) { func(r); } return r;
303 } else {
304 // Check what certificates we really need to re-generate.
302 - if ((r.CommonName != commonName) || (xcountry != country) || (xorganization != organization)) { forceWebCertGen = 1; }
305 + if ((r.CommonNames.indexOf(commonName.toLowerCase()) < 0)) { forceWebCertGen = 1; }
306 if (r.AmtMpsName != mpsCommonName) { forceMpsCertGen = 1; }
304 - }
307 + }
308 }
309 console.log('Generating certificates, may take a few minutes...');
310 parent.updateServerState('state', 'generatingcertificates');
meshcentral.js
+1 -1
@@ -77,7 +77,7 @@ function CreateMeshCentralServer(config, args) {
77 // Start the Meshcentral server
78 obj.Start = function () {
79 try { require('./pass').hash('test', function () { }); } catch (e) { console.log('Old version of node, must upgrade.'); return; } // TODO: Not sure if this test works or not.
80 -
80 +
81 // Check for invalid arguments
82 var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'shownodes', 'showmeshes', 'showevents', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpsdebug', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbimport', 'selfupdate', 'tlsoffload', 'userallowedip', 'fastcert', 'swarmport', 'swarmdebug', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen', 'admin', 'unadmin'];
83 for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } }
meshscanner.js
+6 -10
@@ -61,13 +61,11 @@ module.exports.CreateMeshScanner = function (parent) {
61 if (server4.xxlocal != '*') { bindOptions.address = server4.xxlocal; }
62 server4.bind(bindOptions, function () {
63 try {
64 - this.setBroadcast(true);
65 - this.setMulticastTTL(128);
66 - this.addMembership(membershipIPv4);
64 + var doscan = true;
65 + try { this.setBroadcast(true); this.setMulticastTTL(128); this.addMembership(membershipIPv4); } catch (e) { doscan = false; }
66 this.on('error', function (error) { console.log('Error: ' + error); });
67 this.on('message', function (msg, info) { onUdpPacket(msg, info, this); });
69 - obj.performScan(this);
70 - obj.performScan(this);
68 + if (doscan == true) { obj.performScan(this); obj.performScan(this); }
69 } catch (e) { console.log(e); }
70 });
71 obj.servers4[localAddress] = server4;
@@ -94,13 +92,11 @@ module.exports.CreateMeshScanner = function (parent) {
92 if (server6.xxlocal != '*') { bindOptions.address = server6.xxlocal; }
93 server6.bind(bindOptions, function () {
94 try {
97 - this.setBroadcast(true);
98 - this.setMulticastTTL(128);
99 - this.addMembership(membershipIPv6);
95 + var doscan = true;
96 + try { this.setBroadcast(true); this.setMulticastTTL(128); this.addMembership(membershipIPv6); } catch (e) { doscan = false; }
97 this.on('error', function (error) { console.log('Error: ' + error); });
98 this.on('message', function (msg, info) { onUdpPacket(msg, info, this); });
102 - obj.performScan(this);
103 - obj.performScan(this);
99 + if (doscan == true) { obj.performScan(this); obj.performScan(this); }
100 } catch (e) { console.log(e); }
101 });
102 obj.servers6[localAddress] = server6;
mpsserver.js
+5 -5
@@ -414,7 +414,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
414 var WindowSize = common.ReadInt(data, 9);
415 socket.tag.activetunnels++;
416 var cirachannel = socket.tag.channels[RecipientChannel];
417 - if (cirachannel == undefined) { /*console.log("MPS Error in CHANNEL_OPEN_CONFIRMATION: Unable to find channelid " + RecipientChannel);*/ return; }
417 + if (cirachannel == undefined) { /*console.log("MPS Error in CHANNEL_OPEN_CONFIRMATION: Unable to find channelid " + RecipientChannel);*/ return 17; }
418 cirachannel.amtchannelid = SenderChannel;
419 cirachannel.sendcredits = cirachannel.amtCiraWindow = WindowSize;
420 Debug(3, 'MPS:CHANNEL_OPEN_CONFIRMATION', RecipientChannel, SenderChannel, WindowSize);
@@ -450,7 +450,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
450 var ReasonCode = common.ReadInt(data, 5);
451 Debug(3, 'MPS:CHANNEL_OPEN_FAILURE', RecipientChannel, ReasonCode);
452 var cirachannel = socket.tag.channels[RecipientChannel];
453 - if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_OPEN_FAILURE: Unable to find channelid " + RecipientChannel); return; }
453 + if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_OPEN_FAILURE: Unable to find channelid " + RecipientChannel); return 17; }
454 if (cirachannel.state > 0) {
455 cirachannel.state = 0;
456 if (cirachannel.onStateChange) { cirachannel.onStateChange(cirachannel, cirachannel.state); }
@@ -464,7 +464,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
464 var RecipientChannel = common.ReadInt(data, 1);
465 Debug(3, 'MPS:CHANNEL_CLOSE', RecipientChannel);
466 var cirachannel = socket.tag.channels[RecipientChannel];
467 - if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_CLOSE: Unable to find channelid " + RecipientChannel); return; }
467 + if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_CLOSE: Unable to find channelid " + RecipientChannel); return 5; }
468 socket.tag.activetunnels--;
469 if (cirachannel.state > 0) {
470 cirachannel.state = 0;
@@ -479,7 +479,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
479 var RecipientChannel = common.ReadInt(data, 1);
480 var ByteToAdd = common.ReadInt(data, 5);
481 var cirachannel = socket.tag.channels[RecipientChannel];
482 - if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_WINDOW_ADJUST: Unable to find channelid " + RecipientChannel); return; }
482 + if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_WINDOW_ADJUST: Unable to find channelid " + RecipientChannel); return 9; }
483 cirachannel.sendcredits += ByteToAdd;
484 Debug(3, 'MPS:CHANNEL_WINDOW_ADJUST', RecipientChannel, ByteToAdd, cirachannel.sendcredits);
485 if (cirachannel.state == 2 && cirachannel.sendBuffer != undefined) {
@@ -507,7 +507,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
507 if (len < (9 + LengthOfData)) return 0;
508 Debug(4, 'MPS:CHANNEL_DATA', RecipientChannel, LengthOfData);
509 var cirachannel = socket.tag.channels[RecipientChannel];
510 - if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_DATA: Unable to find channelid " + RecipientChannel); return; }
510 + if (cirachannel == undefined) { console.log("MPS Error in CHANNEL_DATA: Unable to find channelid " + RecipientChannel); return 9 + LengthOfData; }
511 cirachannel.amtpendingcredits += LengthOfData;
512 if (cirachannel.onData) cirachannel.onData(cirachannel, data.substring(9, 9 + LengthOfData));
513 if (cirachannel.amtpendingcredits > (cirachannel.ciraWindow / 2)) {
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.1.8-r",
3 + "version": "0.1.8-y",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
public/scripts/agent-desktop-0.0.2.js
+1 -1
@@ -272,7 +272,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
272 }
273
274 obj.SendKeyMsgKC = function (action, kc) {
275 - console.log('SendKeyMsgKC', action, kc);
275 + //console.log('SendKeyMsgKC', action, kc);
276 if (obj.State != 3) return;
277 if (typeof action == 'object') { for (var i in action) { obj.SendKeyMsgKC(action[i][0], action[i][1]); } }
278 else { obj.send(String.fromCharCode(0x00, obj.InputType.KEY, 0x00, 0x06, (action - 1), kc)); }
public/scripts/agent-redir-ws-0.1.0.js
+7 -7
@@ -63,26 +63,25 @@ 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') {
66 - sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Confirm we got end of data marker, indicates data will no longer be received on websocket.
66 + obj.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 (ex) { } } }
73 + obj.sendCtrlMsg = function (x) { if (obj.ctrlMsgAllowed == true) { if (args && args.redirtrace) { console.log('RedirSend', typeof x, x); } try { obj.socket.send(x); } catch (ex) { } } }
74
75 function performWebRtcSwitch() {
76 if ((obj.webSwitchOk == true) && (obj.webRtcActive == true)) {
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.
77 + obj.sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate to the meshagent that it can start traffic switchover
78 + obj.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 }
82 }
83
84 obj.xxOnMessage = function (e) {
85 - //if (obj.debugmode == 1) { console.log('Recv', e.data); }
85 //console.log('Recv', e.data, obj.State);
86 if (obj.State < 3) {
87 if (e.data == 'c') {
@@ -149,7 +148,6 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
148 }
149 } else {
150 // If we get a string object, it maybe the WebRTC confirm. Ignore it.
152 - //obj.debug("Agent Redir Relay - OnData - " + typeof e.data + " - " + e.data.length);
151 obj.xxOnSocketData(e.data);
152 }
153 };
@@ -164,6 +162,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
162 }
163 else if (typeof data !== 'string') return;
164 //console.log("xxOnSocketData", rstr2hex(data));
165 + if (args && args.redirtrace) { console.log("RedirRecv", typeof data, data.length, data); }
166 return obj.m.ProcessData(data);
167 }
168
@@ -175,6 +174,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
174 obj.send = function (x) {
175 //obj.debug("Agent Redir Send(" + obj.webRtcActive + ", " + x.length + "): " + rstr2hex(x));
176 //console.log("Agent Redir Send(" + obj.webRtcActive + ", " + x.length + "): " + ((typeof x == 'string')?x:rstr2hex(x)));
177 + if (args && args.redirtrace) { console.log('RedirSend', typeof x, x.length, x); }
178 try {
179 if (obj.socket != null && obj.socket.readyState == WebSocket.OPEN) {
180 if (typeof x == 'string') {
@@ -225,7 +225,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
225 //obj.debug("Agent Redir Socket Stopped");
226 obj.connectstate = -1;
227 if (obj.socket != null) {
228 - try { if (obj.socket.readyState == 1) { sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"close\"}"); obj.socket.close(); } } catch (e) { }
228 + try { if (obj.socket.readyState == 1) { obj.sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"close\"}"); obj.socket.close(); } } catch (e) { }
229 obj.socket = null;
230 }
231 obj.xxStateChange(0);
readme.txt
+1 -1
@@ -3,7 +3,7 @@ MeshCentral
3
4 For more information, [visit MeshCommander.com/MeshCentral2](http://www.meshcommander.com/meshcentral2).
5
6 -Download the [full PDF user's guide](http://info.meshcentral.com/downloads/meshcentral2/MeshCentral2UserGuide.pdf) with more information on installing, configuring and running MeshCentral2.
6 +Download the [full PDF user's guide](http://info.meshcentral.com/downloads/meshcentral2/MeshCentral2UserGuide.pdf) with more information on configuring and running MeshCentral2. In addition, the [installation guide](http://info.meshcentral.com/downloads/meshcentral2/MeshCentral2InstallGuide.pdf) can help get MeshCentral installed on Amazon AWS, Microsoft Azure, Ubuntu and the Raspberry Pi.
7
8 This is a full computer management web site. With MeshCentral, you can run your own web server to remotely manage and control computers on a local network or anywhere on the internet. Once you get the server started, create a mesh (a group of computers) and then download and install a mesh agent on each computer you want to manage. A minute later, the new computer will show up on the web site and you can take control of it. MeshCentral includes full web-based remote desktop, terminal and file management capability.
9
sample-config.json
+12 -10
@@ -1,15 +1,17 @@
1 {
2 "__comment__" : "This is a sample configuration file, edit a section and remove the _ in front of the name. Refer to the user's guide for details.",
3 - "_settings": {
4 - "MongoDb": "mongodb://127.0.0.1:27017/meshcentral",
5 - "MongoDbCol": "meshcentral",
6 - "Port": 443,
7 - "RedirPort": 80,
8 - "AllowLoginToken": true,
9 - "AllowFraming": true,
10 - "WebRTC": false,
11 - "ClickOnce": false,
12 - "UserAllowedIP" : "127.0.0.1,::1,192.168.0.100"
3 + "settings": {
4 + "_MongoDb": "mongodb://127.0.0.1:27017/meshcentral",
5 + "_MongoDbCol": "meshcentral",
6 + "_WANonly": true,
7 + "_LANonly": true,
8 + "_Port": 443,
9 + "_RedirPort": 80,
10 + "_AllowLoginToken": true,
11 + "_AllowFraming": true,
12 + "_WebRTC": false,
13 + "_ClickOnce": false,
14 + "_UserAllowedIP" : "127.0.0.1,::1,192.168.0.100"
15 },
16 "_domains": {
17 "": {
views/default.handlebars
+4 -2
@@ -3622,11 +3622,12 @@
3622 if (desktop.contype == 2) {
3623 desktop.m.sendkey([[0xffe7,1],[0x6c,1],[0x6c,0],[0xffe7,0]]); // Intel AMT: Meta-left down, 'l' press, 'l' release, Meta-left release
3624 } else {
3625 + desktop.sendCtrlMsg('{"action":"lock"}');
3626 //desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,0x5B],[desktop.m.KeyAction.DOWN,76],[desktop.m.KeyAction.UP,76],[desktop.m.KeyAction.EXUP,0x5B]]); // MeshAgent: L-Winkey press, 'L' press, 'L' release, L-Winkey release
3626 - desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXDOWN, 0x5B);
3627 + //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXDOWN, 0x5B);
3628 //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.DOWN, 76);
3629 //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.UP, 76);
3629 - desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXUP, 0x5B);
3630 + //desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXUP, 0x5B);
3631 }
3632 } else if (ks == 3) { // WIN+M arrow
3633 if (desktop.contype == 2) {
@@ -5190,6 +5191,7 @@
5191 x += '</table>';
5192 if (hiddenUsers == 1) { x += '<br />1 more user not shown, use search box to look for users...<br />'; }
5193 else if (hiddenUsers > 1) { x += '<br />' + hiddenUsers + ' more users not shown, use search box to look for users...<br />'; }
5194 + if (maxUsers == 100) { x += '<br />No users found.<br />'; }
5195 QH('p3users', x);
5196
5197 // Update current user panel if needed