diff --git a/agents/meshcore.js b/agents/meshcore.js
index 9621ef43..c32d243f 100644
--- a/agents/meshcore.js
+++ b/agents/meshcore.js
@@ -22,6 +22,7 @@ process.on('uncaughtException', function (ex) {
//attachDebugger({ webport: 9999, wait: 1 }).then(function (prt) { console.log('Point Browser for Debug to port: ' + prt); });
// Mesh Rights
+var MNG_ERROR = 65;
var MESHRIGHT_EDITMESH = 1;
var MESHRIGHT_MANAGEUSERS = 2;
var MESHRIGHT_MANAGECOMPUTERS = 4;
@@ -36,10 +37,12 @@ var MESHRIGHT_NOFILES = 1024;
var MESHRIGHT_NOAMT = 2048;
var MESHRIGHT_LIMITEDINPUT = 4096;
-function createMeshCore(agent) {
+function createMeshCore(agent)
+{
var obj = {};
- if (process.platform == 'darwin' && !process.versions) {
+ if (process.platform == 'darwin' && !process.versions)
+ {
// This is an older MacOS Agent, so we'll need to check the service definition so that Auto-Update will function correctly
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
@@ -48,18 +51,21 @@ function createMeshCore(agent) {
child.stdin.write(" if(c[1]==\"dict\"){ split(a[2], d, \"\"); if(split(d[1], truval, \"\")>1) { split(truval[1], kn1, \"\"); split(kn1[2], kn2, \"\"); print kn2[1]; } }");
child.stdin.write(" else { split(c[1], ka, \"/\"); if(ka[1]==\"true\") {print \"ALWAYS\";} } }'\nexit\n");
child.waitExit();
- if (child.stdout.str.trim() == 'Crashed') {
+ if (child.stdout.str.trim() == 'Crashed')
+ {
child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("launchctl list | grep 'meshagent' | awk '{ if($3==\"meshagent\"){print $1;}}'\nexit\n");
child.waitExit();
- if (parseInt(child.stdout.str.trim()) == process.pid) {
+ if (parseInt(child.stdout.str.trim()) == process.pid)
+ {
// The currently running MeshAgent is us, so we can continue with the update
var plist = require('fs').readFileSync('/Library/LaunchDaemons/meshagent_osx64_LaunchDaemon.plist').toString();
var tokens = plist.split('KeepAlive');
- if (tokens[1].split('>')[0].split('<')[1] == 'dict') {
+ if (tokens[1].split('>')[0].split('<')[1] == 'dict')
+ {
var tmp = tokens[1].split('');
tmp.shift();
tokens[1] = '\n ' + tmp.join('');
@@ -114,6 +120,133 @@ function createMeshCore(agent) {
}
}
+ // Create Secure IPC for Diagnostic Agent Communications
+ obj.DAIPC = require('net').createServer();
+ if (process.platform != 'win32') { try { require('fs').unlinkSync(process.cwd() + '/DAIPC'); } catch (ee) { } }
+ obj.DAIPC.IPCPATH = process.platform == 'win32' ? ('\\\\.\\pipe\\' + require('_agentNodeId')() + '-DAIPC') : (process.cwd() + '/DAIPC');
+ try { obj.DAIPC.listen({ path: obj.DAIPC.IPCPATH }); } catch (e) { }
+ obj.DAIPC.on('connection', function (c)
+ {
+ c._send = function (j)
+ {
+ var data = JSON.stringify(j);
+ var packet = Buffer.alloc(data.length + 4);
+ packet.writeUInt32LE(data.length + 4, 0);
+ Buffer.from(data).copy(packet, 4);
+ this.end(packet);
+ };
+ this._daipc = c;
+ c.parent = this;
+ c.on('end', function () { console.log('Connection Closed'); this.parent._daipc = null; });
+ c.on('data', function (chunk)
+ {
+ if (chunk.length < 4) { this.unshift(chunk); return; }
+ var len = chunk.readUInt32LE(0);
+ if (len > 8192) { this.parent._daipc = null; this.end(); return; }
+ if (chunk.length < len) { this.unshift(chunk); return; }
+
+ var data = chunk.slice(4, len);
+ try
+ {
+ data = JSON.parse(data.toString());
+ }
+ catch(de)
+ {
+ this.parent._daipc = null; this.end(); return;
+ }
+
+ if (!data.cmd) { this.parent._daipc = null; this.end(); return; }
+
+ try
+ {
+ switch(data.cmd)
+ {
+ case 'query':
+ switch(data.value)
+ {
+ case 'connection':
+ data.result = require('MeshAgent').ConnectedServer;
+ this._send(data);
+ break;
+ }
+ break;
+ default:
+ this.parent._daipc = null; this.end(); return;
+ break;
+ }
+ }
+ catch(xe)
+ {
+ this.parent._daipc = null; this.end(); return;
+ }
+ });
+ });
+ function diagnosticAgent_uninstall()
+ {
+ require('service-manager').manager.uninstallService('meshagentDiagnostic');
+ require('task-scheduler').delete('meshagentDiagnostic/periodicStart');
+ };
+ function diagnosticAgent_installCheck(install)
+ {
+ try
+ {
+ var diag = require('service-manager').manager.getService('meshagentDiagnostic');
+ return (diag);
+ }
+ catch (e)
+ {
+ }
+ if (!install) { return (null); }
+
+ var svc = null;
+ try
+ {
+ require('service-manager').manager.installService(
+ {
+ name: 'meshagentDiagnostic',
+ displayName: 'Mesh Agent Diagnostic Service',
+ description: 'Mesh Agent Diagnostic Service',
+ servicePath: process.execPath,
+ parameters: ['-recovery']
+ //files: [{ newName: 'diagnostic.js', _buffer: Buffer.from('LyoNCkNvcHlyaWdodCAyMDE5IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQp2YXIgaG9zdCA9IHJlcXVpcmUoJ3NlcnZpY2UtaG9zdCcpLmNyZWF0ZSgnbWVzaGFnZW50RGlhZ25vc3RpYycpOw0KdmFyIFJlY292ZXJ5QWdlbnQgPSByZXF1aXJlKCdNZXNoQWdlbnQnKTsNCg0KaG9zdC5vbignc2VydmljZVN0YXJ0JywgZnVuY3Rpb24gKCkNCnsNCiAgICBjb25zb2xlLnNldERlc3RpbmF0aW9uKGNvbnNvbGUuRGVzdGluYXRpb25zLkxPR0ZJTEUpOw0KICAgIGhvc3Quc3RvcCA9IGZ1bmN0aW9uKCkNCiAgICB7DQogICAgICAgIHJlcXVpcmUoJ3NlcnZpY2UtbWFuYWdlcicpLm1hbmFnZXIuZ2V0U2VydmljZSgnbWVzaGFnZW50RGlhZ25vc3RpYycpLnN0b3AoKTsNCiAgICB9DQogICAgUmVjb3ZlcnlBZ2VudC5vbignQ29ubmVjdGVkJywgZnVuY3Rpb24gKHN0YXR1cykNCiAgICB7DQogICAgICAgIGlmIChzdGF0dXMgPT0gMCkNCiAgICAgICAgew0KICAgICAgICAgICAgY29uc29sZS5sb2coJ0RpYWdub3N0aWMgQWdlbnQ6IFNlcnZlciBjb25uZWN0aW9uIGxvc3QuLi4nKTsNCiAgICAgICAgICAgIHJldHVybjsNCiAgICAgICAgfQ0KICAgICAgICBjb25zb2xlLmxvZygnRGlhZ25vc3RpYyBBZ2VudDogQ29ubmVjdGlvbiBFc3RhYmxpc2hlZCB3aXRoIFNlcnZlcicpOw0KICAgICAgICBzdGFydCgpOw0KICAgIH0pOw0KfSk7DQpob3N0Lm9uKCdub3JtYWxTdGFydCcsIGZ1bmN0aW9uICgpDQp7DQogICAgaG9zdC5zdG9wID0gZnVuY3Rpb24gKCkNCiAgICB7DQogICAgICAgIHByb2Nlc3MuZXhpdCgpOw0KICAgIH0NCiAgICBjb25zb2xlLmxvZygnTm9uIFNlcnZpY2UgTW9kZScpOw0KICAgIFJlY292ZXJ5QWdlbnQub24oJ0Nvbm5lY3RlZCcsIGZ1bmN0aW9uIChzdGF0dXMpDQogICAgew0KICAgICAgICBpZiAoc3RhdHVzID09IDApDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdEaWFnbm9zdGljIEFnZW50OiBTZXJ2ZXIgY29ubmVjdGlvbiBsb3N0Li4uJyk7DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCiAgICAgICAgY29uc29sZS5sb2coJ0RpYWdub3N0aWMgQWdlbnQ6IENvbm5lY3Rpb24gRXN0YWJsaXNoZWQgd2l0aCBTZXJ2ZXInKTsNCiAgICAgICAgc3RhcnQoKTsNCiAgICB9KTsNCn0pOw0KaG9zdC5vbignc2VydmljZVN0b3AnLCBmdW5jdGlvbiAoKSB7IHByb2Nlc3MuZXhpdCgpOyB9KTsNCmhvc3QucnVuKCk7DQoNCg0KZnVuY3Rpb24gc3RhcnQoKQ0Kew0KDQp9Ow0K', 'base64') }]
+ });
+ svc = require('service-manager').manager.getService('meshagentDiagnostic');
+ }
+ catch (e)
+ {
+ return (null);
+ }
+ var proxyConfig = require('global-tunnel').proxyConfig;
+ var cert = require('MeshAgent').GenerateAgentCertificate('CN=MeshNodeDiagnosticCertificate');
+ var nodeid = require('tls').loadCertificate(cert.root).getKeyHash().toString('base64');
+ ddb = require('SimpleDataStore').Create(svc.appWorkingDirectory().replace('\\', '/') + '/meshagentDiagnostic.db');
+ ddb.Put('disableUpdate', '1');
+ ddb.Put('MeshID', Buffer.from(require('MeshAgent').ServerInfo.MeshID, 'hex'));
+ ddb.Put('ServerID', require('MeshAgent').ServerInfo.ServerID);
+ ddb.Put('MeshServer', require('MeshAgent').ServerInfo.ServerUri);
+ if (cert.root.pfx) { ddb.Put('SelfNodeCert', cert.root.pfx); }
+ if (cert.tls) { ddb.Put('SelfNodeTlsCert', cert.tls.pfx); }
+ if (proxyConfig)
+ {
+ ddb.Put('WebProxy', proxyConfig.host + ':' + proxyConfig.port);
+ }
+ else
+ {
+ ddb.Put('ignoreProxyFile', '1');
+ }
+
+ require('MeshAgent').SendCommand({ action: 'diagnostic', value: { command: 'register', value: nodeid } });
+ require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: 'Diagnostic Agent Registered [' + nodeid.length + '/' + nodeid + ']' });
+
+ delete ddb;
+
+ // Set a recurrent task, to run the Diagnostic Agent every 2 days
+ require('task-scheduler').create({name: 'meshagentDiagnostic/periodicStart', daily: 2, time: require('tls').generateRandomInteger('0', '23') + ':' + require('tls').generateRandomInteger('0', '59').padStart(2, '0'), service: 'meshagentDiagnostic'});
+ //require('task-scheduler').create({ name: 'meshagentDiagnostic/periodicStart', daily: '1', time: '17:16', service: 'meshagentDiagnostic' });
+
+ return (svc);
+ }
+
/*
function borderController() {
this.container = null;
@@ -191,6 +324,8 @@ function createMeshCore(agent) {
mesh = agent.getMeshApi();
}
+ mesh.DAIPC = obj.DAIPC;
+
/*
var AMTScanner = require("AMTScanner");
var scan = new AMTScanner();
@@ -815,39 +950,7 @@ function createMeshCore(agent) {
return;
}
- // Test the console messaging system
- //this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'This is a sample test for remote terminal...' })); // Send a console message back using the console channel, "\n" is supported.
-
- // Perform notification if needed. Toast messages may not be supported on all platforms.
- if (this.httprequest.consent && (this.httprequest.consent & 2)) {
- try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote terminal session.'); } catch (ex) { }
- }
-
- // Remote terminal using native pipes
- if (process.platform == "win32")
- {
- this.httprequest._term = require('win-terminal').Start(80, 25);
- this.httprequest._term.pipe(this, { dataTypeSkip: 1 });
- this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false });
- this.prependListener('end', function () { this.httprequest._term.end(function () { console.log('Terminal was closed'); }); });
- //this.httprequest.process = childProcess.execFile("%windir%\\system32\\cmd.exe");
- } else {
- if (fs.existsSync("/bin/bash")) {
- this.httprequest.process = childProcess.execFile("/bin/bash", ["bash", "-i"], { type: childProcess.SpawnTypes.TERM });
- if (process.platform == 'linux') { this.httprequest.process.stdin.write("alias ls='ls --color=auto'\nclear\n"); }
- } else {
- this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM });
- if (process.platform == 'linux') { this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nPS1='\\u@\\h:\\w\\$ '\nclear\n"); }
- }
- //if (this.httprequest.process == null) { }
- this.httprequest.process.tunnel = this;
- this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); });
- this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
- this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
- this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
- this.prependListener('end', function () { this.httprequest.process.kill(); });
- }
-
+
this.end = function () {
if (process.platform == "win32") {
// Unpipe the web socket
@@ -868,11 +971,71 @@ function createMeshCore(agent) {
}
};
+ // Remote terminal using native pipes
+ if (process.platform == "win32") {
+ this.httprequest._term = require('win-terminal').Start(80, 25);
+ this.httprequest._term.pipe(this, { dataTypeSkip: 1 });
+ this.pipe(this.httprequest._term, { dataTypeSkip: 1, end: false });
+ this.prependListener('end', function () { this.httprequest._term.end(function () { console.log('Terminal was closed'); }); });
+ } else {
+ this.httprequest.process = childProcess.execFile("/bin/sh", ["sh"], { type: childProcess.SpawnTypes.TERM });
+ this.httprequest.process.tunnel = this;
+ this.httprequest.process.on('exit', function (ecode, sig) { this.tunnel.end(); });
+ this.httprequest.process.stderr.on('data', function (chunk) { this.parent.tunnel.write(chunk); });
+ this.httprequest.process.stdout.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
+ this.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
+ this.prependListener('end', function () { this.httprequest.process.kill(); });
+ this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nclear\n");
+ }
+
+
+
+ // Perform notification if needed. Toast messages may not be supported on all platforms.
+ if (this.httprequest.consent && (this.httprequest.consent & 16)) {
+ // User Consent Prompt is required
+
+ // Send a console message back using the console channel, "\n" is supported.
+ this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' }));
+
+ var pr = require('message-box').create('Mesh Central', this.httprequest.username + ' requesting Terminal Access. Grant access?', 10);
+ pr.ws = this;
+ this.pause();
+
+ pr.then(
+ function () {
+ // Success!
+ this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
+ if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 2)) {
+ // User Notifications is required
+ try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote terminal session.'); } catch (ex) { }
+ }
+
+ this.ws.resume();
+ },
+ function (e) {
+ // User Consent Denied/Failed!
+ this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() }));
+ this.ws.end();
+ });
+ }
+ else {
+ // User Consent Prompt is not required
+ if (this.httprequest.consent && (this.httprequest.consent & 2)) {
+ // User Notifications is required
+ try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote terminal session.'); } catch (ex) { }
+ }
+ this.resume();
+ }
+
+
+
+
+
this.removeAllListeners('data');
this.on('data', onTunnelControlData);
//this.write('MeshCore Terminal Hello');
- } else if (this.httprequest.protocol == 2) {
-
+ } else if (this.httprequest.protocol == 2)
+ {
// Check user access rights for desktop
if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0)) {
// Disengage this tunnel, user does not have the rights to do this!!
@@ -882,13 +1045,6 @@ function createMeshCore(agent) {
return;
}
- // Test the console messaging system
- //this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'This is a sample test for remote desktop...' })); // Send a console message back using the console channel, "\n" is supported.
-
- // Perform notification if needed. Toast messages may not be supported on all platforms.
- if (this.httprequest.consent && (this.httprequest.consent & 1)) {
- try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote desktop session.'); } catch (ex) { }
- }
// Remote desktop using native pipes
this.httprequest.desktop = { state: 0, kvm: mesh.getRemoteDesktopStream(), tunnel: this };
@@ -926,7 +1082,56 @@ function createMeshCore(agent) {
// TODO!!!
}
- this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. Pipe the KVM --> Browser images.
+ // Perform notification if needed. Toast messages may not be supported on all platforms.
+ if (this.httprequest.consent && (this.httprequest.consent & 8))
+ {
+ // User Consent Prompt is required
+
+ // Send a console message back using the console channel, "\n" is supported.
+ this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' }));
+
+ var pr = require('message-box').create('Mesh Central', this.httprequest.username + ' requesting KVM Access. Grant access?', 10);
+ pr.ws = this;
+ this.pause();
+
+ pr.then(
+ function ()
+ {
+ // Success!
+ this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
+ if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 1))
+ {
+ // User Notifications is required
+ try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote desktop session.'); } catch (ex) { }
+ }
+
+ this.ws.httprequest.desktop.kvm.pipe(this.ws, { dataTypeSkip: 1 });
+ this.ws.resume();
+ },
+ function (e)
+ {
+ // User Consent Denied/Failed!
+ this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() }));
+
+ //var err = 'User consent: ' + e.toString();
+ //var b = Buffer.alloc(5 + err.length);
+ //b.writeUInt16BE(MNG_ERROR, 0);
+ //b.writeUInt16BE(err.length + 4, 2);
+ //Buffer.from(err).copy(b, 4);
+ //this.ws.end(b);
+ });
+ }
+ else
+ {
+ // User Consent Prompt is not required
+ if (this.httprequest.consent && (this.httprequest.consent & 1))
+ {
+ // User Notifications is required
+ try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote desktop session.'); } catch (ex) { }
+ }
+ this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 });
+ }
+
this.removeAllListeners('data');
this.on('data', onTunnelControlData);
//this.write('MeshCore KVM Hello!1');
@@ -942,12 +1147,41 @@ function createMeshCore(agent) {
return;
}
- // Test the console messaging system
- //this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'This is a sample test for remote files...' })); // Send a console message back using the console channel, "\n" is supported.
+ // Perform notification if needed. Toast messages may not be supported on all platforms.
+ if (this.httprequest.consent && (this.httprequest.consent & 32))
+ {
+ // User Consent Prompt is required
- // Perform notification if needed
- if (this.httprequest.consent && (this.httprequest.consent & 4)) {
- try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote file access.'); } catch (ex) { }
+ // Send a console message back using the console channel, "\n" is supported.
+ this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' }));
+
+ var pr = require('message-box').create('Mesh Central', this.httprequest.username + ' requesting remote File Access. Grant access?', 10);
+ pr.ws = this;
+ this.pause();
+
+ pr.then(
+ function () {
+ // Success!
+ this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
+ if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 4))
+ {
+ // User Notifications is required
+ try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote file session.'); } catch (ex) { }
+ }
+ this.ws.resume();
+ },
+ function (e) {
+ // User Consent Denied/Failed!
+ this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() }));
+ });
+ }
+ else {
+ // User Consent Prompt is not required
+ if (this.httprequest.consent && (this.httprequest.consent & 4)) {
+ // User Notifications is required
+ try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote file session.'); } catch (ex) { }
+ }
+ this.resume();
}
// Setup files
@@ -1372,12 +1606,9 @@ function createMeshCore(agent) {
break;
}
case 'toast': {
- if (process.platform == 'win32') {
- if (args['_'].length < 1) { response = 'Proper usage: toast "message"'; } else {
- try { require('toaster').Toast('MeshCentral', args['_'][0]); response = 'ok'; } catch (ex) { response = ex; }
- }
- } else {
- response = 'Only supported on Windows.';
+ if (args['_'].length < 1) { response = 'Proper usage: toast "message"'; } else
+ {
+ require('toaster').Toast('MeshCentral', args['_'][0]).then(sendConsoleText, sendConsoleText);
}
break;
}
@@ -1763,6 +1994,48 @@ function createMeshCore(agent) {
}
break;
}
+ case 'diagnostic':
+ {
+ if (!mesh.DAIPC.listening)
+ {
+ response = 'Unable to bind to Diagnostic IPC, most likely because the path (' + process.cwd() + ') is not on a local file system';
+ break;
+ }
+ var diag = diagnosticAgent_installCheck();
+ if (diag)
+ {
+ if (args['_'].length == 1 && args['_'][0] == 'uninstall')
+ {
+ diagnosticAgent_uninstall();
+ response = 'Diagnostic Agent uninstalled';
+ }
+ else
+ {
+ response = 'Diagnostic Agent installed at: ' + diag.appLocation();
+ }
+ }
+ else
+ {
+ if (args['_'].length == 1 && args['_'][0] == 'install')
+ {
+ diag = diagnosticAgent_installCheck(true);
+ if (diag)
+ {
+ response = 'Diagnostic agent was installed at: ' + diag.appLocation();
+ }
+ else
+ {
+ response = 'Diagnostic agent installation failed';
+ }
+ }
+ else
+ {
+ response = 'Diagnostic Agent Not installed. To install: diagnostic install';
+ }
+ }
+ if (diag) { diag.close(); diag = null; }
+ break;
+ }
default: { // This is an unknown command, return an error message
response = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.';
break;