diff --git a/agents/meshcore.js b/agents/meshcore.js
index 071d0a6f..5f898a1b 100644
--- a/agents/meshcore.js
+++ b/agents/meshcore.js
@@ -41,11 +41,9 @@ var MESHRIGHT_CHATNOTIFY = 16384;
var MESHRIGHT_UNINSTALL = 32768;
var MESHRIGHT_NODESKTOP = 65536;
-if (require('MeshAgent').ARCHID == null)
-{
+if (require('MeshAgent').ARCHID == null) {
var id = null;
- switch (process.platform)
- {
+ switch (process.platform) {
case 'win32':
id = require('_GenericMarshal').PointerSize == 4 ? 3 : 4;
break;
@@ -53,12 +51,10 @@ if (require('MeshAgent').ARCHID == null)
id = require('_GenericMarshal').PointerSize == 4 ? 31 : 30;
break;
case 'darwin':
- try
- {
+ try {
id = require('os').arch() == 'x64' ? 16 : 29;
}
- catch (xx)
- {
+ catch (xx) {
id = 16;
}
break; break;
@@ -66,18 +62,15 @@ if (require('MeshAgent').ARCHID == null)
if (id != null) { Object.defineProperty(require('MeshAgent'), 'ARCHID', { value: id }); }
}
-function createMeshCore(agent)
-{
+function createMeshCore(agent) {
var obj = {};
var agentFileHttpRequests = {}; // Currently active agent HTTPS GET requests from the server.
var agentFileHttpPendingRequests = []; // Pending HTTPS GET requests from the server.
var debugConsole = (_MSH().debugConsole == 1);
- if (process.platform == 'win32' && require('user-sessions').isRoot())
- {
+ if (process.platform == 'win32' && require('user-sessions').isRoot()) {
// Check the Agent Uninstall MetaData for correctness, as the installer may have written an incorrect value
- try
- {
+ try {
var writtenSize = 0, actualSize = Math.floor(require('fs').statSync(process.execPath).size / 1024);
try { writtenSize = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MeshCentralAgent', 'EstimatedSize'); } catch (e) { }
if (writtenSize != actualSize) { try { require('win-registry').WriteKey(require('win-registry').HKEY.LocalMachine, 'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MeshCentralAgent', 'EstimatedSize', actualSize); } catch (e) { } }
@@ -85,24 +78,20 @@ function createMeshCore(agent)
// Check to see if we are the Installed Mesh Agent Service, if we are, make sure we can run in Safe Mode
var svcname = process.platform == 'win32' ? 'Mesh Agent' : 'meshagent';
- try
- {
+ try {
svcname = require('MeshAgent').serviceName;
}
- catch (x)
- {
+ catch (x) {
}
- try
- {
+ try {
var meshCheck = false;
try { meshCheck = require('service-manager').manager.getService(svcname).isMe(); } catch (e) { }
if (meshCheck && require('win-bcd').isSafeModeService && !require('win-bcd').isSafeModeService(svcname)) { require('win-bcd').enableSafeModeService(svcname); }
} catch (e) { }
}
- 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 = '';
@@ -111,21 +100,18 @@ 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('');
@@ -181,8 +167,7 @@ function createMeshCore(agent)
}
// Add an Intel AMT event to the log
- function addAmtEvent(msg)
- {
+ function addAmtEvent(msg) {
if (obj.amtevents == null) { obj.amtevents = []; }
var d = new Date();
obj.amtevents.push(zeroPad(d.getHours(), 2) + ':' + zeroPad(d.getMinutes(), 2) + ':' + zeroPad(d.getSeconds(), 2) + ', ' + msg);
@@ -197,10 +182,8 @@ function createMeshCore(agent)
obj.DAIPC.IPCPATH = process.platform == 'win32' ? ('\\\\.\\pipe\\' + require('_agentNodeId')() + '-DAIPC') : (process.cwd() + '/DAIPC');
try { obj.DAIPC.listen({ path: obj.DAIPC.IPCPATH, writableAll: true, maxConnections: 5 }); } catch (e) { }
obj.DAIPC._daipc = [];
- obj.DAIPC.on('connection', function (c)
- {
- c._send = function (j)
- {
+ 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);
@@ -210,8 +193,7 @@ function createMeshCore(agent)
this._daipc.push(c);
c.parent = this;
c.on('end', function () { removeRegisteredApp(this); });
- c.on('data', function (chunk)
- {
+ c.on('data', function (chunk) {
if (chunk.length < 4) { this.unshift(chunk); return; }
var len = chunk.readUInt32LE(0);
if (len > 8192) { removeRegisteredApp(this); this.end(); return; }
@@ -221,10 +203,8 @@ function createMeshCore(agent)
try { data = JSON.parse(data.toString()); } catch (e) { }
if ((data == null) || (typeof data.cmd != 'string')) return;
- try
- {
- switch (data.cmd)
- {
+ try {
+ switch (data.cmd) {
case 'requesthelp':
if (this._registered == null) return;
sendConsoleText('Request Help (' + this._registered + '): ' + data.value);
@@ -239,8 +219,7 @@ function createMeshCore(agent)
try { mesh.SendCommand({ action: 'sessions', type: 'help', value: {} }); } catch (e) { }
break;
case 'register':
- if (typeof data.value == 'string')
- {
+ if (typeof data.value == 'string') {
this._registered = data.value;
var apps = {};
apps[data.value] = 1;
@@ -249,15 +228,13 @@ function createMeshCore(agent)
}
break;
case 'query':
- switch (data.value)
- {
+ switch (data.value) {
case 'connection':
data.result = require('MeshAgent').ConnectedServer;
this._send(data);
break;
case 'descriptors':
- require('ChainViewer').getSnapshot().then(function (f)
- {
+ require('ChainViewer').getSnapshot().then(function (f) {
this.tag.payload.result = f;
this.tag.ipc._send(this.tag.payload);
}).parentPromise.tag = { ipc: this, payload: data };
@@ -281,8 +258,7 @@ function createMeshCore(agent)
try { mesh.SendCommand({ action: 'meshToolInfo', name: data.name, hash: data.hash, cookie: data.cookie ? true : false, pipe: true }); } catch (e) { }
break;
case 'console':
- if (debugConsole)
- {
+ if (debugConsole) {
var args = splitArgs(data.value);
processConsoleCommand(args[0].toLowerCase(), parseArgs(args), 0, 'pipe');
}
@@ -294,28 +270,24 @@ function createMeshCore(agent)
});
// Send current sessions to registered apps
- function broadcastSessionsToRegisteredApps(x)
- {
+ function broadcastSessionsToRegisteredApps(x) {
broadcastToRegisteredApps({ cmd: 'sessions', sessions: tunnelUserCount });
}
// Send this object to all registered local applications
- function broadcastToRegisteredApps(x)
- {
+ function broadcastToRegisteredApps(x) {
if ((obj.DAIPC == null) || (obj.DAIPC._daipc == null)) return;
for (var i in obj.DAIPC._daipc) { if (obj.DAIPC._daipc[i]._registered != null) { obj.DAIPC._daipc[i]._send(x); } }
}
// Send this object to a specific registered local applications
- function sendToRegisteredApp(appid, x)
- {
+ function sendToRegisteredApp(appid, x) {
if ((obj.DAIPC == null) || (obj.DAIPC._daipc == null)) return;
for (var i in obj.DAIPC._daipc) { if (obj.DAIPC._daipc[i]._registered == appid) { obj.DAIPC._daipc[i]._send(x); } }
}
// Send list of registered apps to the server
- function updateRegisteredAppsToServer()
- {
+ function updateRegisteredAppsToServer() {
if ((obj.DAIPC == null) || (obj.DAIPC._daipc == null)) return;
var apps = {};
for (var i in obj.DAIPC._daipc) { if (apps[obj.DAIPC._daipc[i]._registered] == null) { apps[obj.DAIPC._daipc[i]._registered] = 1; } else { apps[obj.DAIPC._daipc[i]._registered]++; } }
@@ -323,32 +295,26 @@ function createMeshCore(agent)
}
// Remove a registered app
- function removeRegisteredApp(pipe)
- {
+ function removeRegisteredApp(pipe) {
for (var i = obj.DAIPC._daipc.length - 1; i >= 0; i--) { if (obj.DAIPC._daipc[i] === pipe) { obj.DAIPC._daipc.splice(i, 1); } }
if (pipe._registered != null) updateRegisteredAppsToServer();
}
- function diagnosticAgent_uninstall()
- {
+ function diagnosticAgent_uninstall() {
require('service-manager').manager.uninstallService('meshagentDiagnostic');
require('task-scheduler').delete('meshagentDiagnostic/periodicStart');
};
- function diagnosticAgent_installCheck(install)
- {
- try
- {
+ function diagnosticAgent_installCheck(install) {
+ try {
var diag = require('service-manager').manager.getService('meshagentDiagnostic');
return (diag);
}
- catch (e)
- {
+ catch (e) {
}
if (!install) { return (null); }
var svc = null;
- try
- {
+ try {
require('service-manager').manager.installService(
{
name: 'meshagentDiagnostic',
@@ -360,8 +326,7 @@ function createMeshCore(agent)
});
svc = require('service-manager').manager.getService('meshagentDiagnostic');
}
- catch (e)
- {
+ catch (e) {
return (null);
}
var proxyConfig = require('global-tunnel').proxyConfig;
@@ -374,11 +339,9 @@ function createMeshCore(agent)
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)
- {
+ if (proxyConfig) {
ddb.Put('WebProxy', proxyConfig.host + ':' + proxyConfig.port);
- } else
- {
+ } else {
ddb.Put('ignoreProxyFile', '1');
}
@@ -395,24 +358,18 @@ function createMeshCore(agent)
}
// Monitor the file 'batterystate.txt' in the agent's folder and sends battery update when this file is changed.
- if ((require('fs').existsSync(process.cwd() + 'batterystate.txt')) && (require('fs').watch != null))
- {
+ if ((require('fs').existsSync(process.cwd() + 'batterystate.txt')) && (require('fs').watch != null)) {
// Setup manual battery monitoring
- require('MeshAgent')._batteryFileWatcher = require('fs').watch(process.cwd(), function ()
- {
+ require('MeshAgent')._batteryFileWatcher = require('fs').watch(process.cwd(), function () {
if (require('MeshAgent')._batteryFileTimer != null) return;
- require('MeshAgent')._batteryFileTimer = setTimeout(function ()
- {
- try
- {
+ require('MeshAgent')._batteryFileTimer = setTimeout(function () {
+ try {
require('MeshAgent')._batteryFileTimer = null;
var data = null;
try { data = require('fs').readFileSync(process.cwd() + 'batterystate.txt').toString(); } catch (e) { }
- if ((data != null) && (data.length < 10))
- {
+ if ((data != null) && (data.length < 10)) {
data = data.split(',');
- if ((data.length == 2) && ((data[0] == 'ac') || (data[0] == 'dc')))
- {
+ if ((data.length == 2) && ((data[0] == 'ac') || (data[0] == 'dc'))) {
var level = parseInt(data[1]);
if ((level >= 0) && (level <= 100)) { require('MeshAgent').SendCommand({ action: 'battery', state: data[0], level: level }); }
}
@@ -420,31 +377,24 @@ function createMeshCore(agent)
} catch (e) { }
}, 1000);
});
- } else
- {
+ } else {
// Setup normal battery monitoring
- if (require('identifiers').isBatteryPowered && require('identifiers').isBatteryPowered())
- {
- require('MeshAgent')._battLevelChanged = function _battLevelChanged(val)
- {
+ if (require('identifiers').isBatteryPowered && require('identifiers').isBatteryPowered()) {
+ require('MeshAgent')._battLevelChanged = function _battLevelChanged(val) {
_battLevelChanged.self._currentBatteryLevel = val;
_battLevelChanged.self.SendCommand({ action: 'battery', state: _battLevelChanged.self._currentPowerState, level: val });
};
require('MeshAgent')._battLevelChanged.self = require('MeshAgent');
- require('MeshAgent')._powerChanged = function _powerChanged(val)
- {
+ require('MeshAgent')._powerChanged = function _powerChanged(val) {
_powerChanged.self._currentPowerState = (val == 'AC' ? 'ac' : 'dc');
_powerChanged.self.SendCommand({ action: 'battery', state: (val == 'AC' ? 'ac' : 'dc'), level: _powerChanged.self._currentBatteryLevel });
};
require('MeshAgent')._powerChanged.self = require('MeshAgent');
- require('MeshAgent').on('Connected', function (status)
- {
- if (status == 0)
- {
+ require('MeshAgent').on('Connected', function (status) {
+ if (status == 0) {
require('power-monitor').removeListener('acdc', this._powerChanged);
require('power-monitor').removeListener('batteryLevel', this._battLevelChanged);
- } else
- {
+ } else {
require('power-monitor').on('acdc', this._powerChanged);
require('power-monitor').on('batteryLevel', this._battLevelChanged);
}
@@ -494,16 +444,12 @@ function createMeshCore(agent)
try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; meshCoreObjChanged(); }); } catch (e) { }
// Setup logged in user monitoring (THIS IS BROKEN IN WIN7)
- try
- {
+ try {
var userSession = require('user-sessions');
- userSession.on('changed', function onUserSessionChanged()
- {
- userSession.enumerateUsers().then(function (users)
- {
+ userSession.on('changed', function onUserSessionChanged() {
+ userSession.enumerateUsers().then(function (users) {
var u = [], a = users.Active;
- for (var i = 0; i < a.length; i++)
- {
+ for (var i = 0; i < a.length; i++) {
var un = a[i].Domain ? (a[i].Domain + '\\' + a[i].Username) : (a[i].Username);
if (u.indexOf(un) == -1) { u.push(un); } // Only push users in the list once.
}
@@ -535,11 +481,9 @@ function createMeshCore(agent)
var tunnelUserCount = { terminal: {}, files: {}, tcp: {}, udp: {}, msg: {} }; // List of userid->count sessions for terminal, files and TCP/UDP routing
// Add to the server event log
- function MeshServerLog(msg, state)
- {
+ function MeshServerLog(msg, state) {
if (typeof msg == 'string') { msg = { action: 'log', msg: msg }; } else { msg.action = 'log'; }
- if (state)
- {
+ if (state) {
if (state.userid) { msg.userid = state.userid; }
if (state.username) { msg.username = state.username; }
if (state.sessionid) { msg.sessionid = state.sessionid; }
@@ -549,11 +493,9 @@ function createMeshCore(agent)
}
// Add to the server event log, use internationalized events
- function MeshServerLogEx(id, args, msg, state)
- {
+ function MeshServerLogEx(id, args, msg, state) {
var msg = { action: 'log', msgid: id, msgArgs: args, msg: msg };
- if (state)
- {
+ if (state) {
if (state.userid) { msg.userid = state.userid; }
if (state.username) { msg.username = state.username; }
if (state.sessionid) { msg.sessionid = state.sessionid; }
@@ -567,16 +509,12 @@ function createMeshCore(agent)
sha = require('SHA256Stream');
mesh = require('MeshAgent');
childProcess = require('child_process');
- if (mesh.hasKVM == 1)
- { // if the agent is compiled with KVM support
+ if (mesh.hasKVM == 1) { // if the agent is compiled with KVM support
// Check if this computer supports a desktop
- try
- {
- if ((process.platform == 'win32') || (process.platform == 'darwin') || (require('monitor-info').kvm_x11_support))
- {
+ try {
+ if ((process.platform == 'win32') || (process.platform == 'darwin') || (require('monitor-info').kvm_x11_support)) {
meshCoreObj.caps |= 1; meshCoreObjChanged();
- } else if (process.platform == 'linux' || process.platform == 'freebsd')
- {
+ } else if (process.platform == 'linux' || process.platform == 'freebsd') {
require('monitor-info').on('kvmSupportDetected', function (value) { meshCoreObj.caps |= 1; meshCoreObjChanged(); });
}
} catch (e) { }
@@ -596,23 +534,18 @@ function createMeshCore(agent)
// Fetch the SMBios Tables
var SMBiosTables = null;
var SMBiosTablesRaw = null;
- try
- {
+ try {
var SMBiosModule = null;
try { SMBiosModule = require('smbios'); } catch (e) { }
- if (SMBiosModule != null)
- {
- SMBiosModule.get(function (data)
- {
- if (data != null)
- {
+ if (SMBiosModule != null) {
+ SMBiosModule.get(function (data) {
+ if (data != null) {
SMBiosTablesRaw = data;
SMBiosTables = require('smbios').parse(data)
if (mesh.isControlChannelConnected) { mesh.SendCommand({ action: 'smbios', value: SMBiosTablesRaw }); }
// If SMBios tables say that Intel AMT is present, try to connect MEI
- if (SMBiosTables.amtInfo && (SMBiosTables.amtInfo.AMT == true))
- {
+ if (SMBiosTables.amtInfo && (SMBiosTables.amtInfo.AMT == true)) {
var amtmodule = require('amt-manage');
amt = new amtmodule(mesh, db, false);
amt.on('portBinding_LMS', function (map) { mesh.SendCommand({ action: 'lmsinfo', value: { ports: map.keys() } }); });
@@ -626,8 +559,7 @@ function createMeshCore(agent)
} catch (e) { sendConsoleText("ex1: " + e); }
// Try to load up the WIFI scanner
- try
- {
+ try {
var wifiScannerLib = require('wifi-scanner');
wifiScanner = new wifiScannerLib();
wifiScanner.on('accessPoint', function (data) { sendConsoleText("wifiScanner: " + data); });
@@ -636,28 +568,21 @@ function createMeshCore(agent)
// Get our location (lat/long) using our public IP address
var getIpLocationDataExInProgress = false;
var getIpLocationDataExCounts = [0, 0];
- function getIpLocationDataEx(func)
- {
+ function getIpLocationDataEx(func) {
if (getIpLocationDataExInProgress == true) { return false; }
- try
- {
+ try {
getIpLocationDataExInProgress = true;
getIpLocationDataExCounts[0]++;
var options = http.parseUri("http://ipinfo.io/json");
options.method = 'GET';
- http.request(options, function (resp)
- {
- if (resp.statusCode == 200)
- {
+ http.request(options, function (resp) {
+ if (resp.statusCode == 200) {
var geoData = '';
resp.data = function (geoipdata) { geoData += geoipdata; };
- resp.end = function ()
- {
+ resp.end = function () {
var location = null;
- try
- {
- if (typeof geoData == 'string')
- {
+ try {
+ if (typeof geoData == 'string') {
var result = JSON.parse(geoData);
if (result.ip && result.loc) { location = result; }
}
@@ -674,57 +599,45 @@ function createMeshCore(agent)
}
// Remove all Gateway MAC addresses for interface list. This is useful because the gateway MAC is not always populated reliably.
- function clearGatewayMac(str)
- {
+ function clearGatewayMac(str) {
if (str == null) return null;
var x = JSON.parse(str);
for (var i in x.netif) { if (x.netif[i].gatewaymac) { delete x.netif[i].gatewaymac } }
return JSON.stringify(x);
}
- function getIpLocationData(func)
- {
+ function getIpLocationData(func) {
// Get the location information for the cache if possible
var publicLocationInfo = db.Get('publicLocationInfo');
if (publicLocationInfo != null) { publicLocationInfo = JSON.parse(publicLocationInfo); }
- if (publicLocationInfo == null)
- {
+ if (publicLocationInfo == null) {
// Nothing in the cache, fetch the data
- getIpLocationDataEx(function (locationData)
- {
- if (locationData != null)
- {
+ getIpLocationDataEx(function (locationData) {
+ if (locationData != null) {
publicLocationInfo = {};
publicLocationInfo.netInfoStr = lastNetworkInfo;
publicLocationInfo.locationData = locationData;
var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database
if (func) func(locationData); // Report the new location
- } else
- {
+ } else {
if (func) func(null); // Report no location
}
});
- } else
- {
+ } else {
// Check the cache
- if (clearGatewayMac(publicLocationInfo.netInfoStr) == clearGatewayMac(lastNetworkInfo))
- {
+ if (clearGatewayMac(publicLocationInfo.netInfoStr) == clearGatewayMac(lastNetworkInfo)) {
// Cache match
if (func) func(publicLocationInfo.locationData);
- } else
- {
+ } else {
// Cache mismatch
- getIpLocationDataEx(function (locationData)
- {
- if (locationData != null)
- {
+ getIpLocationDataEx(function (locationData) {
+ if (locationData != null) {
publicLocationInfo = {};
publicLocationInfo.netInfoStr = lastNetworkInfo;
publicLocationInfo.locationData = locationData;
var x = db.Put('publicLocationInfo', JSON.stringify(publicLocationInfo)); // Save to database
if (func) func(locationData); // Report the new location
- } else
- {
+ } else {
if (func) func(publicLocationInfo.locationData); // Can't get new location, report the old location
}
});
@@ -733,10 +646,8 @@ function createMeshCore(agent)
}
// Polyfill String.endsWith
- if (!String.prototype.endsWith)
- {
- String.prototype.endsWith = function (searchString, position)
- {
+ if (!String.prototype.endsWith) {
+ String.prototype.endsWith = function (searchString, position) {
var subjectString = this.toString();
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { position = subjectString.length; }
position -= searchString.length;
@@ -747,17 +658,13 @@ function createMeshCore(agent)
// Polyfill path.join
obj.path = {
- join: function ()
- {
+ join: function () {
var x = [];
- for (var i in arguments)
- {
+ for (var i in arguments) {
var w = arguments[i];
- if (w != null)
- {
+ if (w != null) {
while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
- if (i != 0)
- {
+ if (i != 0) {
while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
}
x.push(w);
@@ -781,8 +688,7 @@ function createMeshCore(agent)
function buf2rstr(buf) { var r = ''; for (var i = 0; i < buf.length; i++) { r += String.fromCharCode(buf[i]); } return r; }
// Convert a hex string to a raw string // TODO: Do this using Buffer(), will be MUCH faster
- function hex2rstr(d)
- {
+ function hex2rstr(d) {
if (typeof d != "string" || d.length == 0) return '';
var r = '', m = ('' + d).match(/../g), t;
while (t = m.shift()) r += String.fromCharCode('0x' + t);
@@ -790,8 +696,7 @@ function createMeshCore(agent)
}
// Convert an object to string with all functions
- function objToString(x, p, pad, ret)
- {
+ function objToString(x, p, pad, ret) {
if (ret == undefined) ret = '';
if (p == undefined) p = 0;
if (x == null) { return '[null]'; }
@@ -809,26 +714,21 @@ function createMeshCore(agent)
function addPad(p, ret) { var r = ''; for (var i = 0; i < p; i++) { r += ret; } return r; }
// Split a string taking into account the quoats. Used for command line parsing
- function splitArgs(str)
- {
+ function splitArgs(str) {
var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi;
do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null);
return myArray;
}
// Parse arguments string array into an object
- function parseArgs(argv)
- {
+ function parseArgs(argv) {
var results = { '_': [] }, current = null;
- for (var i = 1, len = argv.length; i < len; i++)
- {
+ for (var i = 1, len = argv.length; i < len; i++) {
var x = argv[i];
- if (x.length > 2 && x[0] == '-' && x[1] == '-')
- {
+ if (x.length > 2 && x[0] == '-' && x[1] == '-') {
if (current != null) { results[current] = true; }
current = x.substring(2);
- } else
- {
+ } else {
if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); }
}
}
@@ -837,8 +737,7 @@ function createMeshCore(agent)
}
// Get server target url with a custom path
- function getServerTargetUrl(path)
- {
+ function getServerTargetUrl(path) {
var x = mesh.ServerUrl;
//sendConsoleText("mesh.ServerUrl: " + mesh.ServerUrl);
if (x == null) { return null; }
@@ -849,35 +748,27 @@ function createMeshCore(agent)
}
// Get server url. If the url starts with "*/..." change it, it not use the url as is.
- function getServerTargetUrlEx(url)
- {
+ function getServerTargetUrlEx(url) {
if (url.substring(0, 2) == '*/') { return getServerTargetUrl(url.substring(2)); }
return url;
}
// Send a wake-on-lan packet
- function sendWakeOnLan(hexMac)
- {
+ function sendWakeOnLan(hexMac) {
hexMac = hexMac.split(':').join('');
var count = 0;
- try
- {
+ try {
var interfaces = require('os').networkInterfaces();
var magic = 'FFFFFFFFFFFF';
for (var x = 1; x <= 16; ++x) { magic += hexMac; }
var magicbin = Buffer.from(magic, 'hex');
- for (var adapter in interfaces)
- {
- if (interfaces.hasOwnProperty(adapter))
- {
- for (var i = 0; i < interfaces[adapter].length; ++i)
- {
+ for (var adapter in interfaces) {
+ if (interfaces.hasOwnProperty(adapter)) {
+ for (var i = 0; i < interfaces[adapter].length; ++i) {
var addr = interfaces[adapter][i];
- if ((addr.family == 'IPv4') && (addr.mac != '00:00:00:00:00:00'))
- {
- try
- {
+ if ((addr.family == 'IPv4') && (addr.mac != '00:00:00:00:00:00')) {
+ try {
var socket = require('dgram').createSocket({ type: 'udp4' });
socket.bind({ address: addr.address });
socket.setBroadcast(true);
@@ -897,22 +788,17 @@ function createMeshCore(agent)
}
// Handle a mesh agent command
- function handleServerCommand(data)
- {
- if (typeof data == 'object')
- {
+ function handleServerCommand(data) {
+ if (typeof data == 'object') {
// If this is a console command, parse it and call the console handler
- switch (data.action)
- {
+ switch (data.action) {
case 'agentupdate':
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash, sessionid: data.sessionid });
break;
case 'msg': {
- switch (data.type)
- {
+ switch (data.type) {
case 'console': { // Process a console command
- if (data.value && data.sessionid)
- {
+ if (data.value && data.sessionid) {
MeshServerLogEx(17, [data.value], "Processing console command: " + data.value, data);
var args = splitArgs(data.value);
processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
@@ -920,12 +806,10 @@ function createMeshCore(agent)
break;
}
case 'tunnel': {
- if (data.value != null)
- { // Process a new tunnel connection request
+ if (data.value != null) { // Process a new tunnel connection request
// Create a new tunnel object
var xurl = getServerTargetUrlEx(data.value);
- if (xurl != null)
- {
+ if (xurl != null) {
xurl = xurl.split('$').join('%24').split('@').join('%40'); // Escape the $ and @ characters
var woptions = http.parseUri(xurl);
woptions.perMessageDeflate = false;
@@ -933,8 +817,7 @@ function createMeshCore(agent)
// Perform manual server TLS certificate checking based on the certificate hash given by the server.
woptions.rejectUnauthorized = 0;
- woptions.checkServerIdentity = function checkServerIdentity(certs)
- {
+ woptions.checkServerIdentity = function checkServerIdentity(certs) {
// If the tunnel certificate matches the control channel certificate, accept the connection
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.digest == certs[0].digest) return; } catch (ex) { }
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.fingerprint == certs[0].fingerprint) return; } catch (ex) { }
@@ -977,8 +860,7 @@ function createMeshCore(agent)
}
case 'messagebox': {
// Display a message box
- if (data.title && data.msg)
- {
+ if (data.title && data.msg) {
MeshServerLogEx(18, [data.title, data.msg], "Displaying message box, title=" + data.title + ", message=" + data.msg, data);
data.msg = data.msg.split('\r').join('\\r').split('\n').join('\\n');
try { require('message-box').create(data.title, data.msg, 120); } catch (e) { }
@@ -987,10 +869,8 @@ function createMeshCore(agent)
}
case 'ps': {
// Return the list of running processes
- if (data.sessionid)
- {
- processManager.getProcesses(function (plist)
- {
+ if (data.sessionid) {
+ processManager.getProcesses(function (plist) {
mesh.SendCommand({ action: 'msg', type: 'ps', value: JSON.stringify(plist), sessionid: data.sessionid });
});
}
@@ -998,8 +878,7 @@ function createMeshCore(agent)
}
case 'pskill': {
// Kill a process
- if (data.value)
- {
+ if (data.value) {
MeshServerLogEx(19, [data.value], "Killing process " + data.value, data);
try { process.kill(data.value); } catch (e) { sendConsoleText("pskill: " + JSON.stringify(e)); }
}
@@ -1014,8 +893,7 @@ function createMeshCore(agent)
}
case 'serviceStop': {
// Stop a service
- try
- {
+ try {
var service = require('service-manager').manager.getService(data.serviceName);
if (service != null) { service.stop(); }
} catch (e) { }
@@ -1023,8 +901,7 @@ function createMeshCore(agent)
}
case 'serviceStart': {
// Start a service
- try
- {
+ try {
var service = require('service-manager').manager.getService(data.serviceName);
if (service != null) { service.start(); }
} catch (e) { }
@@ -1032,8 +909,7 @@ function createMeshCore(agent)
}
case 'serviceRestart': {
// Restart a service
- try
- {
+ try {
var service = require('service-manager').manager.getService(data.serviceName);
if (service != null) { service.restart(); }
} catch (e) { }
@@ -1042,16 +918,12 @@ function createMeshCore(agent)
case 'deskBackground':
{
// Toggle desktop background
- try
- {
- if (process.platform == 'win32')
- {
+ try {
+ if (process.platform == 'win32') {
var stype = require('user-sessions').getProcessOwnerName(process.pid).tsid == 0 ? 1 : 0;
var sid = undefined;
- if (stype == 1)
- {
- if (require('MeshAgent')._tsid != null)
- {
+ if (stype == 1) {
+ if (require('MeshAgent')._tsid != null) {
stype = 5;
sid = require('MeshAgent')._tsid;
}
@@ -1067,15 +939,13 @@ function createMeshCore(agent)
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stderr.on('data', function () { });
child.waitExit();
- } else
- {
+ } else {
var id = require('user-sessions').consoleUid();
var current = require('linux-gnome-helpers').getDesktopWallpaper(id);
if (current != '/dev/null') { require('MeshAgent')._wallpaper = current; }
require('linux-gnome-helpers').setDesktopWallpaper(id, current != '/dev/null' ? undefined : require('MeshAgent')._wallpaper);
}
- } catch (e)
- {
+ } catch (e) {
sendConsoleText(e);
}
break;
@@ -1090,22 +960,16 @@ function createMeshCore(agent)
case 'getclip': {
// Send the load clipboard back to the user
//sendConsoleText('getClip: ' + JSON.stringify(data));
- if (require('MeshAgent').isService)
- {
- require('clipboard').dispatchRead().then(function (str)
- {
- if (str)
- {
+ if (require('MeshAgent').isService) {
+ require('clipboard').dispatchRead().then(function (str) {
+ if (str) {
MeshServerLogEx(21, [str.length], "Getting clipboard content, " + str.length + " byte(s)", data);
mesh.SendCommand({ action: 'msg', type: 'getclip', sessionid: data.sessionid, data: str, tag: data.tag });
}
});
- } else
- {
- require("clipboard").read().then(function (str)
- {
- if (str)
- {
+ } else {
+ require("clipboard").read().then(function (str) {
+ if (str) {
MeshServerLogEx(21, [str.length], "Getting clipboard content, " + str.length + " byte(s)", data);
mesh.SendCommand({ action: 'msg', type: 'getclip', sessionid: data.sessionid, data: str, tag: data.tag });
}
@@ -1116,8 +980,7 @@ function createMeshCore(agent)
case 'setclip': {
// Set the load clipboard to a user value
//sendConsoleText('setClip: ' + JSON.stringify(data));
- if (typeof data.data == 'string')
- {
+ if (typeof data.data == 'string') {
MeshServerLogEx(22, [data.data.length], "Setting clipboard content, " + data.data.length + " byte(s)", data);
if (require('MeshAgent').isService) { require('clipboard').dispatchWrite(data.data); } else { require("clipboard")(data.data); } // Set the clipboard
mesh.SendCommand({ action: 'msg', type: 'setclip', sessionid: data.sessionid, success: true });
@@ -1152,8 +1015,7 @@ function createMeshCore(agent)
break;
}
case 'acmactivate': {
- if (amt != null)
- {
+ if (amt != null) {
MeshServerLogEx(23, null, "Attempting Intel AMT ACM mode activation", data);
amt.setAcmResponse(data);
}
@@ -1171,21 +1033,17 @@ function createMeshCore(agent)
// data.runAsUser: 0=Agent,1=UserOrAgent,2=UserOnly
var options = {};
- if (data.runAsUser > 0)
- {
+ if (data.runAsUser > 0) {
try { options.uid = require('user-sessions').consoleUid(); } catch (e) { }
options.type = require('child_process').SpawnTypes.TERM;
}
- if (data.runAsUser == 2)
- {
+ if (data.runAsUser == 2) {
if (options.uid == null) break;
if (((require('user-sessions').minUid != null) && (options.uid < require('user-sessions').minUid()))) break; // This command can only run as user.
}
- if (process.platform == 'win32')
- {
- if (data.type == 1)
- {
+ if (process.platform == 'win32') {
+ if (data.type == 1) {
// Windows command shell
mesh.cmdchild = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ['cmd'], options);
mesh.cmdchild.descriptorMetadata = 'UserCommandsShell';
@@ -1193,8 +1051,7 @@ function createMeshCore(agent)
mesh.cmdchild.stderr.on('data', function (c) { sendConsoleText(c.toString()); });
mesh.cmdchild.stdin.write(data.cmds + '\r\nexit\r\n');
mesh.cmdchild.on('exit', function () { sendConsoleText("Run commands completed."); delete mesh.cmdchild; });
- } else if (data.type == 2)
- {
+ } else if (data.type == 2) {
// Windows Powershell
mesh.cmdchild = require('child_process').execFile(process.env['windir'] + '\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', ['powershell', '-noprofile', '-nologo', '-command', '-'], options);
mesh.cmdchild.descriptorMetadata = 'UserCommandsPowerShell';
@@ -1203,8 +1060,7 @@ function createMeshCore(agent)
mesh.cmdchild.stdin.write(data.cmds + '\r\nexit\r\n');
mesh.cmdchild.on('exit', function () { sendConsoleText("Run commands completed."); delete mesh.cmdchild; });
}
- } else if (data.type == 3)
- {
+ } else if (data.type == 3) {
// Linux shell
mesh.cmdchild = require('child_process').execFile('/bin/sh', ['sh'], options);
mesh.cmdchild.descriptorMetadata = 'UserCommandsShell';
@@ -1218,16 +1074,13 @@ function createMeshCore(agent)
case 'uninstallagent':
// Uninstall this agent
var agentName = process.platform == 'win32' ? 'Mesh Agent' : 'meshagent';
- try
- {
+ try {
agentName = require('MeshAgent').serviceName;
}
- catch (x)
- {
+ catch (x) {
}
- if (require('service-manager').manager.getService(agentName).isMe())
- {
+ if (require('service-manager').manager.getService(agentName).isMe()) {
try { diagnosticAgent_uninstall(); } catch (e) { }
var js = "require('service-manager').manager.getService('" + agentName + "').stop(); require('service-manager').manager.uninstallService('" + agentName + "'); process.exit();";
this.child = require('child_process').execFile(process.execPath, [process.platform == 'win32' ? (process.execPath.split('\\').pop()) : (process.execPath.split('/').pop()), '-b64exec', Buffer.from(js).toString('base64')], { type: 4, detached: true });
@@ -1235,8 +1088,7 @@ function createMeshCore(agent)
break;
case 'poweraction': {
// Server telling us to execute a power action
- if ((mesh.ExecPowerState != undefined) && (data.actiontype))
- {
+ if ((mesh.ExecPowerState != undefined) && (data.actiontype)) {
var forced = 0;
if (data.forced == 1) { forced = 1; }
data.actiontype = parseInt(data.actiontype);
@@ -1254,8 +1106,7 @@ function createMeshCore(agent)
}
case 'toast': {
// Display a toast message
- if (data.title && data.msg)
- {
+ if (data.title && data.msg) {
MeshServerLogEx(26, [data.title, data.msg], "Displaying toast message, title=" + data.title + ", message=" + data.msg, data);
data.msg = data.msg.split('\r').join('\\r').split('\n').join('\\n');
try { require('toaster').Toast(data.title, data.msg); } catch (e) { }
@@ -1272,8 +1123,7 @@ function createMeshCore(agent)
case 'amtconfig': {
// Perform Intel AMT activation and/or configuration
if ((apftunnel != null) || (amt == null) || (typeof data.user != 'string') || (typeof data.pass != 'string')) break;
- amt.getMeiState(15, function (state)
- {
+ amt.getMeiState(15, function (state) {
if ((apftunnel != null) || (amt == null)) return;
if ((state == null) || (state.ProvisioningState == null)) return;
if ((state.UUID == null) || (state.UUID.length != 36)) return; // Bad UUID
@@ -1290,12 +1140,10 @@ function createMeshCore(agent)
};
addAmtEvent('LMS tunnel start.');
apftunnel = require('amt-apfclient')({ debug: false }, apfarg);
- apftunnel.onJsonControl = function (data)
- {
+ apftunnel.onJsonControl = function (data) {
if (data.action == 'console') { addAmtEvent(data.msg); } // Add console message to AMT event log
if (data.action == 'mestate') { amt.getMeiState(15, function (state) { apftunnel.updateMeiState(state); }); } // Update the MEI state
- if (data.action == 'deactivate')
- { // Request CCM deactivation
+ if (data.action == 'deactivate') { // Request CCM deactivation
var amtMeiModule, amtMei;
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { if (apftunnel) apftunnel.sendMeiDeactivationState(1); return; }
amtMei.on('error', function (e) { if (apftunnel) apftunnel.sendMeiDeactivationState(1); });
@@ -1315,8 +1163,7 @@ function createMeshCore(agent)
}
case 'sysinfo': {
// Fetch system information
- getSystemInformation(function (results)
- {
+ getSystemInformation(function (results) {
if ((results != null) && (data.hash != results.hash)) { mesh.SendCommand({ action: 'sysinfo', sessionid: this.sessionid, data: results }); }
});
break;
@@ -1329,18 +1176,14 @@ function createMeshCore(agent)
}
case 'coredump':
// Set the current agent coredump situation.
- if (data.value === true)
- {
- if (process.platform == 'win32')
- {
+ if (data.value === true) {
+ if (process.platform == 'win32') {
// TODO: This replace() below is not ideal, would be better to remove the .exe at the end instead of replace.
process.coreDumpLocation = process.execPath.replace('.exe', '.dmp');
- } else
- {
+ } else {
process.coreDumpLocation = (process.cwd() != '//') ? (process.cwd() + 'core') : null;
}
- } else if (data.value === false)
- {
+ } else if (data.value === false) {
process.coreDumpLocation = null;
}
break;
@@ -1349,18 +1192,15 @@ function createMeshCore(agent)
var r = { action: 'getcoredump', value: (process.coreDumpLocation != null) };
var coreDumpPath = null;
if (process.platform == 'win32') { coreDumpPath = process.coreDumpLocation; } else { coreDumpPath = (process.cwd() != '//') ? fs.existsSync(process.cwd() + 'core') : null; }
- if ((coreDumpPath != null) && (fs.existsSync(coreDumpPath)))
- {
- try
- {
+ if ((coreDumpPath != null) && (fs.existsSync(coreDumpPath))) {
+ try {
var coredate = fs.statSync(coreDumpPath).mtime;
var coretime = new Date(coredate).getTime();
var agenttime = new Date(fs.statSync(process.execPath).mtime).getTime();
if (coretime > agenttime) { r.exists = (db.Get('CoreDumpTime') != coredate); }
} catch (ex) { }
}
- if (r.exists == true)
- {
+ if (r.exists == true) {
r.agenthashhex = getSHA384FileHash(process.execPath).toString('hex'); // Hash of current agent
r.corehashhex = getSHA384FileHash(coreDumpPath).toString('hex'); // Hash of core dump file
}
@@ -1381,8 +1221,7 @@ function createMeshCore(agent)
}
// Agent just get a file from the server and save it locally.
- function serverFetchFile()
- {
+ function serverFetchFile() {
if ((Object.keys(agentFileHttpRequests).length > 4) || (agentFileHttpPendingRequests.length == 0)) return; // No more than 4 active HTTPS requests to the server.
var data = agentFileHttpPendingRequests.shift();
if ((data.overwrite !== true) && fs.existsSync(data.path)) return; // Don't overwrite an existing file.
@@ -1393,8 +1232,7 @@ function createMeshCore(agent)
// Perform manual server TLS certificate checking based on the certificate hash given by the server.
agentFileHttpOptions.rejectUnauthorized = 0;
- agentFileHttpOptions.checkServerIdentity = function checkServerIdentity(certs)
- {
+ agentFileHttpOptions.checkServerIdentity = function checkServerIdentity(certs) {
// If the tunnel certificate matches the control channel certificate, accept the connection
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.digest == certs[0].digest) return; } catch (ex) { }
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.fingerprint == certs[0].fingerprint) return; } catch (ex) { }
@@ -1405,11 +1243,9 @@ function createMeshCore(agent)
if (agentFileHttpOptions == null) return;
var agentFileHttpRequest = http.request(agentFileHttpOptions,
- function (response)
- {
+ function (response) {
response.xparent = this;
- try
- {
+ try {
response.xfile = fs.createWriteStream(this.xpath, { flags: 'wbN' })
response.pipe(response.xfile);
response.end = function () { delete agentFileHttpRequests[this.xparent.xurlpath]; delete this.xparent; serverFetchFile(); }
@@ -1432,13 +1268,10 @@ function createMeshCore(agent)
}
*/
- function getSystemInformation(func)
- {
- try
- {
+ function getSystemInformation(func) {
+ try {
var results = { hardware: require('identifiers').get() }; // Hardware info
- if (results.hardware && results.hardware.windows)
- {
+ if (results.hardware && results.hardware.windows) {
// Remove extra entries and things that change quickly
var x = results.hardware.windows.osinfo;
try { delete x.FreePhysicalMemory; } catch (e) { }
@@ -1448,8 +1281,7 @@ function createMeshCore(agent)
try { delete x.MaxProcessMemorySize; } catch (e) { }
try { delete x.TotalVirtualMemorySize; } catch (e) { }
try { delete x.TotalVisibleMemorySize; } catch (e) { }
- try
- {
+ try {
if (results.hardware.windows.memory) { for (var i in results.hardware.windows.memory) { delete results.hardware.windows.memory[i].Node; } }
if (results.hardware.windows.osinfo) { delete results.hardware.windows.osinfo.Node; }
if (results.hardware.windows.partitions) { for (var i in results.hardware.windows.partitions) { delete results.hardware.windows.partitions[i].Node; } }
@@ -1485,46 +1317,35 @@ function createMeshCore(agent)
}
// Get a formated response for a given directory path
- function getDirectoryInfo(reqpath)
- {
+ function getDirectoryInfo(reqpath) {
var response = { path: reqpath, dir: [] };
- if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32'))
- {
+ if (((reqpath == undefined) || (reqpath == '')) && (process.platform == 'win32')) {
// List all the drives in the root, or the root itself
var results = null;
try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
- if (results != null)
- {
- for (var i = 0; i < results.length; ++i)
- {
+ if (results != null) {
+ for (var i = 0; i < results.length; ++i) {
var drive = { n: results[i].name, t: 1 };
if (results[i].type == 'REMOVABLE') { drive.dt = 'removable'; } // TODO: See if this is USB/CDROM or something else, we can draw icons.
response.dir.push(drive);
}
}
- } else
- {
+ } else {
// List all the files and folders in this path
if (reqpath == '') { reqpath = '/'; }
var results = null, xpath = obj.path.join(reqpath, '*');
//if (process.platform == "win32") { xpath = xpath.split('/').join('\\'); }
try { results = fs.readdirSync(xpath); } catch (e) { }
- if (results != null)
- {
- for (var i = 0; i < results.length; ++i)
- {
- if ((results[i] != '.') && (results[i] != '..'))
- {
+ if (results != null) {
+ for (var i = 0; i < results.length; ++i) {
+ if ((results[i] != '.') && (results[i] != '..')) {
var stat = null, p = obj.path.join(reqpath, results[i]);
//if (process.platform == "win32") { p = p.split('/').join('\\'); }
try { stat = fs.statSync(p); } catch (e) { } // TODO: Get file size/date
- if ((stat != null) && (stat != undefined))
- {
- if (stat.isDirectory() == true)
- {
+ if ((stat != null) && (stat != undefined)) {
+ if (stat.isDirectory() == true) {
response.dir.push({ n: results[i], t: 2, d: stat.mtime });
- } else
- {
+ } else {
response.dir.push({ n: results[i], t: 3, s: stat.size, d: stat.mtime });
}
}
@@ -1536,19 +1357,16 @@ function createMeshCore(agent)
}
// Tunnel callback operations
- function onTunnelUpgrade(response, s, head)
- {
+ function onTunnelUpgrade(response, s, head) {
this.s = s;
s.httprequest = this;
s.end = onTunnelClosed;
s.tunnel = this;
s.descriptorMetadata = "MeshAgent_relayTunnel";
- if (require('MeshAgent').idleTimeout != null)
- {
+ if (require('MeshAgent').idleTimeout != null) {
s.setTimeout(require('MeshAgent').idleTimeout * 1000);
- s.on('timeout', function ()
- {
+ s.on('timeout', function () {
this.ping();
this.setTimeout(require('MeshAgent').idleTimeout * 1000);
});
@@ -1556,8 +1374,7 @@ function createMeshCore(agent)
//sendConsoleText('onTunnelUpgrade - ' + this.tcpport + ' - ' + this.udpport);
- if (this.tcpport != null)
- {
+ if (this.tcpport != null) {
// This is a TCP relay connection, pause now and try to connect to the target.
s.pause();
s.data = onTcpRelayServerTunnelData;
@@ -1567,14 +1384,12 @@ function createMeshCore(agent)
s.tcprelay.peerindex = this.index;
// Add the TCP session to the count and update the server
- if (s.httprequest.userid != null)
- {
+ if (s.httprequest.userid != null) {
if (tunnelUserCount.tcp[s.httprequest.userid] == null) { tunnelUserCount.tcp[s.httprequest.userid] = 1; } else { tunnelUserCount.tcp[s.httprequest.userid]++; }
try { mesh.SendCommand({ action: 'sessions', type: 'tcp', value: tunnelUserCount.tcp }); } catch (e) { }
broadcastSessionsToRegisteredApps();
}
- } if (this.udpport != null)
- {
+ } if (this.udpport != null) {
// This is a UDP relay connection, get the UDP socket setup. // TODO: ***************
s.data = onUdpRelayServerTunnelData;
s.udprelay = require('dgram').createSocket({ type: 'udp4' });
@@ -1586,41 +1401,34 @@ function createMeshCore(agent)
s.udprelay.first = true;
// Add the UDP session to the count and update the server
- if (s.httprequest.userid != null)
- {
+ if (s.httprequest.userid != null) {
if (tunnelUserCount.udp[s.httprequest.userid] == null) { tunnelUserCount.udp[s.httprequest.userid] = 1; } else { tunnelUserCount.udp[s.httprequest.userid]++; }
try { mesh.SendCommand({ action: 'sessions', type: 'udp', value: tunnelUserCount.tcp }); } catch (e) { }
broadcastSessionsToRegisteredApps();
}
- } else
- {
+ } else {
// This is a normal connect for KVM/Terminal/Files
s.data = onTunnelData;
}
}
// Called when UDP relay data is received // TODO****
- function onUdpRelayTargetTunnelConnect(data)
- {
+ function onUdpRelayTargetTunnelConnect(data) {
var peerTunnel = tunnels[this.peerindex];
peerTunnel.s.write(data);
}
// Called when we get data from the server for a TCP relay (We have to skip the first received 'c' and pipe the rest)
- function onUdpRelayServerTunnelData(data)
- {
- if (this.udprelay.first === true)
- {
+ function onUdpRelayServerTunnelData(data) {
+ if (this.udprelay.first === true) {
delete this.udprelay.first; // Skip the first 'c' that is received.
- } else
- {
+ } else {
this.udprelay.send(data, parseInt(this.udprelay.udpport), this.udprelay.udpaddr ? this.udprelay.udpaddr : '127.0.0.1');
}
}
// Called when the TCP relay target is connected
- function onTcpRelayTargetTunnelConnect()
- {
+ function onTcpRelayTargetTunnelConnect() {
var peerTunnel = tunnels[this.peerindex];
this.pipe(peerTunnel.s); // Pipe Target --> Server
peerTunnel.s.first = true;
@@ -1628,30 +1436,24 @@ function createMeshCore(agent)
}
// Called when we get data from the server for a TCP relay (We have to skip the first received 'c' and pipe the rest)
- function onTcpRelayServerTunnelData(data)
- {
- if (this.first == true)
- {
+ function onTcpRelayServerTunnelData(data) {
+ if (this.first == true) {
this.first = false;
this.pipe(this.tcprelay, { dataTypeSkip: 1 }); // Pipe Server --> Target (don't pipe text type websocket frames)
}
}
- function onTunnelClosed()
- {
+ function onTunnelClosed() {
var tunnel = tunnels[this.httprequest.index];
if (tunnel == null) return; // Stop duplicate calls.
// If this is a routing session, clean up and send the new session counts.
- if (this.httprequest.userid != null)
- {
- if (this.httprequest.tcpport != null)
- {
+ if (this.httprequest.userid != null) {
+ if (this.httprequest.tcpport != null) {
if (tunnelUserCount.tcp[this.httprequest.userid] != null) { tunnelUserCount.tcp[this.httprequest.userid]--; if (tunnelUserCount.tcp[this.httprequest.userid] <= 0) { delete tunnelUserCount.tcp[this.httprequest.userid]; } }
try { mesh.SendCommand({ action: 'sessions', type: 'tcp', value: tunnelUserCount.tcp }); } catch (e) { }
broadcastSessionsToRegisteredApps();
- } else if (this.httprequest.udpport != null)
- {
+ } else if (this.httprequest.udpport != null) {
if (tunnelUserCount.udp[this.httprequest.userid] != null) { tunnelUserCount.udp[this.httprequest.userid]--; if (tunnelUserCount.udp[this.httprequest.userid] <= 0) { delete tunnelUserCount.udp[this.httprequest.userid]; } }
try { mesh.SendCommand({ action: 'sessions', type: 'udp', value: tunnelUserCount.udp }); } catch (e) { }
broadcastSessionsToRegisteredApps();
@@ -1659,8 +1461,7 @@ function createMeshCore(agent)
}
// Sent tunnel statistics to the server, only send this if compression was used.
- if ((this.bytesSent_uncompressed) && (this.bytesSent_uncompressed.toString() != this.bytesSent_actual.toString()))
- {
+ if ((this.bytesSent_uncompressed) && (this.bytesSent_uncompressed.toString() != this.bytesSent_actual.toString())) {
mesh.SendCommand({
action: 'tunnelCloseStats',
url: tunnel.url,
@@ -1693,8 +1494,7 @@ function createMeshCore(agent)
if (this.httprequest.downloadFile) { delete this.httprequest.downloadFile; }
// Clean up WebRTC
- if (this.webrtc != null)
- {
+ if (this.webrtc != null) {
if (this.webrtc.rtcchannel) { try { this.webrtc.rtcchannel.close(); } catch (e) { } this.webrtc.rtcchannel.removeAllListeners('data'); this.webrtc.rtcchannel.removeAllListeners('end'); delete this.webrtc.rtcchannel; }
if (this.webrtc.websocket) { delete this.webrtc.websocket; }
try { this.webrtc.close(); } catch (e) { }
@@ -1708,21 +1508,17 @@ function createMeshCore(agent)
this.removeAllListeners('data');
}
function onTunnelSendOk() { /*sendConsoleText("Tunnel #" + this.index + " SendOK.", this.sessionid);*/ }
- function onTunnelData(data)
- {
+ function onTunnelData(data) {
//console.log("OnTunnelData");
//sendConsoleText('OnTunnelData, ' + data.length + ', ' + typeof data + ', ' + data);
// If this is upload data, save it to file
- if ((this.httprequest.uploadFile) && (typeof data == 'object') && (data[0] != 123))
- {
+ if ((this.httprequest.uploadFile) && (typeof data == 'object') && (data[0] != 123)) {
// Save the data to file being uploaded.
- if (data[0] == 0)
- {
+ if (data[0] == 0) {
// If data starts with zero, skip the first byte. This is used to escape binary file data from JSON.
try { fs.writeSync(this.httprequest.uploadFile, data, 1, data.length - 1); } catch (e) { sendConsoleText('FileUpload Error'); this.write(Buffer.from(JSON.stringify({ action: 'uploaderror' }))); return; } // Write to the file, if there is a problem, error out.
- } else
- {
+ } else {
// If data does not start with zero, save as-is.
try { fs.writeSync(this.httprequest.uploadFile, data); } catch (e) { sendConsoleText('FileUpload Error'); this.write(Buffer.from(JSON.stringify({ action: 'uploaderror' }))); return; } // Write to the file, if there is a problem, error out.
}
@@ -1730,22 +1526,18 @@ function createMeshCore(agent)
return;
}
- if (this.httprequest.state == 0)
- {
+ if (this.httprequest.state == 0) {
// Check if this is a relay connection
if ((data == 'c') || (data == 'cr')) { this.httprequest.state = 1; /*sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid);*/ }
}
- else
- {
+ else {
// Handle tunnel data
- if (this.httprequest.protocol == 0)
- { // 1 = Terminal (admin), 2 = Desktop, 5 = Files, 6 = PowerShell (admin), 7 = Plugin Data Exchange, 8 = Terminal (user), 9 = PowerShell (user), 10 = FileTransfer
+ if (this.httprequest.protocol == 0) { // 1 = Terminal (admin), 2 = Desktop, 5 = Files, 6 = PowerShell (admin), 7 = Plugin Data Exchange, 8 = Terminal (user), 9 = PowerShell (user), 10 = FileTransfer
// Take a look at the protocol
if ((data.length > 3) && (data[0] == '{')) { onTunnelControlData(data, this); return; }
this.httprequest.protocol = parseInt(data);
if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; }
- if (this.httprequest.protocol == 10)
- {
+ if (this.httprequest.protocol == 10) {
//
// Basic file transfer
//
@@ -1753,27 +1545,23 @@ function createMeshCore(agent)
if ((process.platform != 'win32') && (this.httprequest.xoptions.file.startsWith('/') == false)) { this.httprequest.xoptions.file = '/' + this.httprequest.xoptions.file; }
try { stats = require('fs').statSync(this.httprequest.xoptions.file) } catch (e) { }
try { if (stats) { this.httprequest.downloadFile = fs.createReadStream(this.httprequest.xoptions.file, { flags: 'rbN' }); } } catch (e) { }
- if (this.httprequest.downloadFile)
- {
+ if (this.httprequest.downloadFile) {
//sendConsoleText('BasicFileTransfer, ok, ' + this.httprequest.xoptions.file + ', ' + JSON.stringify(stats));
this.write(JSON.stringify({ op: 'ok', size: stats.size }));
this.httprequest.downloadFile.pipe(this);
this.httprequest.downloadFile.end = function () { }
- } else
- {
+ } else {
//sendConsoleText('BasicFileTransfer, cancel, ' + this.httprequest.xoptions.file);
this.write(JSON.stringify({ op: 'cancel' }));
}
}
- else if ((this.httprequest.protocol == 1) || (this.httprequest.protocol == 6) || (this.httprequest.protocol == 8) || (this.httprequest.protocol == 9))
- {
+ else if ((this.httprequest.protocol == 1) || (this.httprequest.protocol == 6) || (this.httprequest.protocol == 8) || (this.httprequest.protocol == 9)) {
//
// Remote Terminal
//
// Check user access rights for terminal
- if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOTERMINAL) != 0)))
- {
+ if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOTERMINAL) != 0))) {
// Disengage this tunnel, user does not have the rights to do this!!
this.httprequest.protocol = 999999;
this.httprequest.s.end();
@@ -1783,10 +1571,8 @@ function createMeshCore(agent)
this.descriptorMetadata = "Remote Terminal";
- if (process.platform == 'win32')
- {
- if (!require('win-terminal').PowerShellCapable() && (this.httprequest.protocol == 6 || this.httprequest.protocol == 9))
- {
+ if (process.platform == 'win32') {
+ if (!require('win-terminal').PowerShellCapable() && (this.httprequest.protocol == 6 || this.httprequest.protocol == 9)) {
this.httprequest.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'PowerShell is not supported on this version of windows', msgid: 1 }));
this.httprequest.s.end();
return;
@@ -1798,28 +1584,24 @@ function createMeshCore(agent)
this.httprequest.tpromise.that = this;
this.httprequest.tpromise.httprequest = this.httprequest;
- this.end = function ()
- {
+ this.end = function () {
if (this.httprequest.tpromise._consent) { this.httprequest.tpromise._consent.close(); }
if (this.httprequest.connectionPromise) { this.httprequest.connectionPromise._rej('Closed'); }
// Remove the terminal session to the count to update the server
- if (this.httprequest.userid != null)
- {
+ if (this.httprequest.userid != null) {
if (tunnelUserCount.terminal[this.httprequest.userid] != null) { tunnelUserCount.terminal[this.httprequest.userid]--; if (tunnelUserCount.terminal[this.httprequest.userid] <= 0) { delete tunnelUserCount.terminal[this.httprequest.userid]; } }
try { mesh.SendCommand({ action: 'sessions', type: 'terminal', value: tunnelUserCount.terminal }); } catch (e) { }
broadcastSessionsToRegisteredApps();
}
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
// Unpipe the web socket
this.unpipe(this.httprequest._term);
if (this.httprequest._term) { this.httprequest._term.unpipe(this); }
// Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends).
- if (this.rtcchannel)
- {
+ if (this.rtcchannel) {
this.rtcchannel.unpipe(this.httprequest._term);
if (this.httprequest._term) { this.httprequest._term.unpipe(this.rtcchannel); }
}
@@ -1831,118 +1613,95 @@ function createMeshCore(agent)
};
// Perform User-Consent if needed.
- if (this.httprequest.consent && (this.httprequest.consent & 16))
- {
+ if (this.httprequest.consent && (this.httprequest.consent & 16)) {
this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: "Waiting for user to grant access...", msgid: 1 }));
var consentMessage = this.httprequest.username + " requesting remote terminal access. Grant access?", consentTitle = 'MeshCentral';
- if (this.httprequest.soptions != null)
- {
+ if (this.httprequest.soptions != null) {
if (this.httprequest.soptions.consentTitle != null) { consentTitle = this.httprequest.soptions.consentTitle; }
if (this.httprequest.soptions.consentMsgTerminal != null) { consentMessage = this.httprequest.soptions.consentMsgTerminal.replace('{0}', this.httprequest.realname).replace('{1}', this.httprequest.username); }
}
this.httprequest.tpromise._consent = require('message-box').create(consentTitle, consentMessage, 30);
this.httprequest.tpromise._consent.retPromise = this.httprequest.tpromise;
this.httprequest.tpromise._consent.then(
- function ()
- {
+ function () {
// Success
MeshServerLogEx(27, null, "Local user accepted remote terminal request (" + this.retPromise.httprequest.remoteaddr + ")", this.retPromise.that.httprequest);
this.retPromise.that.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null, msgid: 0 }));
this.retPromise._consent = null;
this.retPromise._res();
},
- function (e)
- {
+ function (e) {
// Denied
MeshServerLogEx(28, null, "Local user rejected remote terminal request (" + this.retPromise.that.httprequest.remoteaddr + ")", this.retPromise.that.httprequest);
this.retPromise.that.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString(), msgid: 2 }));
this.retPromise._rej(e.toString());
});
}
- else
- {
+ else {
// User-Consent is not required, so just resolve this promise
this.httprequest.tpromise._res();
}
this.httprequest.tpromise.then(
- function ()
- {
+ function () {
this.httprequest.connectionPromise = new prom(function (res, rej) { this._res = res; this._rej = rej; });
this.httprequest.connectionPromise.ws = this.that;
// Start Terminal
- if (process.platform == 'win32')
- {
- try
- {
+ if (process.platform == 'win32') {
+ try {
var cols = 80, rows = 25;
- if (this.httprequest.xoptions)
- {
+ if (this.httprequest.xoptions) {
if (this.httprequest.xoptions.rows) { rows = this.httprequest.xoptions.rows; }
if (this.httprequest.xoptions.cols) { cols = this.httprequest.xoptions.cols; }
}
- if ((this.httprequest.protocol == 1) || (this.httprequest.protocol == 6))
- {
+ if ((this.httprequest.protocol == 1) || (this.httprequest.protocol == 6)) {
// Admin Terminal
- if (require('win-virtual-terminal').supported)
- {
+ if (require('win-virtual-terminal').supported) {
// ConPTY PseudoTerminal
// this.httprequest._term = require('win-virtual-terminal')[this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'](80, 25);
// The above line is commented out, because there is a bug with ClosePseudoConsole() API, so this is the workaround
this.httprequest._dispatcher = require('win-dispatcher').dispatch({ modules: [{ name: 'win-virtual-terminal', script: getJSModule('win-virtual-terminal') }], launch: { module: 'win-virtual-terminal', method: (this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'), args: [cols, rows] } });
this.httprequest._dispatcher.httprequest = this.httprequest;
- this.httprequest._dispatcher.on('connection', function (c)
- {
- if (this.httprequest.connectionPromise.completed)
- {
+ this.httprequest._dispatcher.on('connection', function (c) {
+ if (this.httprequest.connectionPromise.completed) {
c.end();
}
- else
- {
+ else {
this.httprequest.connectionPromise._res(c);
}
});
}
- else
- {
+ else {
// Legacy Terminal
this.httprequest.connectionPromise._res(require('win-terminal')[this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'](cols, rows));
}
}
- else
- {
+ else {
// Logged in user
var userPromise = require('user-sessions').enumerateUsers();
userPromise.that = this;
- userPromise.then(function (u)
- {
+ userPromise.then(function (u) {
var that = this.that;
- if (u.Active.length > 0)
- {
+ if (u.Active.length > 0) {
var username = u.Active[0].Username;
- if (require('win-virtual-terminal').supported)
- {
+ if (require('win-virtual-terminal').supported) {
// ConPTY PseudoTerminal
that.httprequest._dispatcher = require('win-dispatcher').dispatch({ user: username, modules: [{ name: 'win-virtual-terminal', script: getJSModule('win-virtual-terminal') }], launch: { module: 'win-virtual-terminal', method: (that.httprequest.protocol == 9 ? 'StartPowerShell' : 'Start'), args: [cols, rows] } });
}
- else
- {
+ else {
// Legacy Terminal
that.httprequest._dispatcher = require('win-dispatcher').dispatch({ user: username, modules: [{ name: 'win-terminal', script: getJSModule('win-terminal') }], launch: { module: 'win-terminal', method: (that.httprequest.protocol == 9 ? 'StartPowerShell' : 'Start'), args: [cols, rows] } });
}
that.httprequest._dispatcher.ws = that;
- that.httprequest._dispatcher.on('connection', function (c)
- {
- if (this.ws.httprequest.connectionPromise.completed)
- {
+ that.httprequest._dispatcher.on('connection', function (c) {
+ if (this.ws.httprequest.connectionPromise.completed) {
c.end();
}
- else
- {
+ else {
this.ws.httprequest.connectionPromise._res(c);
}
});
@@ -1950,70 +1709,58 @@ function createMeshCore(agent)
});
}
}
- catch (e)
- {
+ catch (e) {
this.httprequest.connectionPromise._rej('Failed to start remote terminal session, ' + e.toString());
}
}
- else
- {
- try
- {
+ else {
+ try {
var bash = fs.existsSync('/bin/bash') ? '/bin/bash' : false;
var sh = fs.existsSync('/bin/sh') ? '/bin/sh' : false;
var login = process.platform == 'linux' ? '/bin/login' : '/usr/bin/login';
var env = { HISTCONTROL: 'ignoreboth' };
- if (this.httprequest.xoptions)
- {
+ if (this.httprequest.xoptions) {
if (this.httprequest.xoptions.rows) { env.LINES = ('' + this.httprequest.xoptions.rows); }
if (this.httprequest.xoptions.cols) { env.COLUMNS = ('' + this.httprequest.xoptions.cols); }
}
var options = { type: childProcess.SpawnTypes.TERM, uid: (this.httprequest.protocol == 8) ? require('user-sessions').consoleUid() : null, env: env };
- if (this.httprequest.xoptions && this.httprequest.xoptions.requireLogin)
- {
+ if (this.httprequest.xoptions && this.httprequest.xoptions.requireLogin) {
if (!require('fs').existsSync(login)) { throw ('Unable to spawn login process'); }
this.httprequest.connectionPromise._res(childProcess.execFile(login, ['login'], options)); // Start login shell
}
- else if (bash)
- {
+ else if (bash) {
var p = childProcess.execFile(bash, ['bash'], options); // Start bash
// Spaces at the beginning of lines are needed to hide commands from the command history
if (process.platform == 'linux') { p.stdin.write(' alias ls=\'ls --color=auto\';clear\n'); }
this.httprequest.connectionPromise._res(p);
}
- else if (sh)
- {
+ else if (sh) {
var p = childProcess.execFile(sh, ['sh'], options); // Start sh
// Spaces at the beginning of lines are needed to hide commands from the command history
if (process.platform == 'linux') { p.stdin.write(' alias ls=\'ls --color=auto\';clear\n'); }
this.httprequest.connectionPromise._res(p);
}
- else
- {
+ else {
this.httprequest.connectionPromise._rej('Failed to start remote terminal session, no shell found');
}
}
- catch (e)
- {
+ catch (e) {
this.httprequest.connectionPromise._rej('Failed to start remote terminal session, ' + e.toString());
}
}
this.httprequest.connectionPromise.then(
- function (term)
- {
+ function (term) {
// SUCCESS
var stdoutstream;
var stdinstream;
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
this.ws.httprequest._term = term;
this.ws.httprequest._term.tunnel = this.ws;
stdoutstream = stdinstream = term;
}
- else
- {
+ else {
term.descriptorMetadata = 'Remote Terminal';
this.ws.httprequest.process = term;
this.ws.httprequest.process.tunnel = this.ws;
@@ -2032,49 +1779,42 @@ function createMeshCore(agent)
this.ws.pipe(stdinstream, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
// Add the terminal session to the count to update the server
- if (this.ws.httprequest.userid != null)
- {
+ if (this.ws.httprequest.userid != null) {
if (tunnelUserCount.terminal[this.ws.httprequest.userid] == null) { tunnelUserCount.terminal[this.ws.httprequest.userid] = 1; } else { tunnelUserCount.terminal[this.ws.httprequest.userid]++; }
try { mesh.SendCommand({ action: 'sessions', type: 'terminal', value: tunnelUserCount.terminal }); } catch (e) { }
broadcastSessionsToRegisteredApps();
}
// Toast Notification, if required
- if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 2))
- {
+ if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 2)) {
// User Notifications is required
var notifyMessage = this.ws.httprequest.username + " started a remote terminal session.", notifyTitle = "MeshCentral";
- if (this.ws.httprequest.soptions != null)
- {
+ if (this.ws.httprequest.soptions != null) {
if (this.ws.httprequest.soptions.notifyTitle != null) { notifyTitle = this.ws.httprequest.soptions.notifyTitle; }
if (this.ws.httprequest.soptions.notifyMsgTerminal != null) { notifyMessage = this.ws.httprequest.soptions.notifyMsgTerminal.replace('{0}', this.ws.httprequest.realname).replace('{1}', this.ws.httprequest.username); }
}
try { require('toaster').Toast(notifyTitle, notifyMessage); } catch (e) { }
}
},
- function (e)
- {
+ function (e) {
// FAILED to connect terminal
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString(), msgid: 2 }));
this.ws.end();
});
},
- function (e)
- {
+ function (e) {
// DO NOT start terminal
this.that.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString(), msgid: 2 }));
this.that.end();
});
}
- else if (this.httprequest.protocol == 2)
- {
+ else if (this.httprequest.protocol == 2) {
//
// Remote KVM
//
// Check user access rights for desktop
- if ((((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0)) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NODESKTOP) != 0)))
- {
+ if ((((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0)) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NODESKTOP) != 0))) {
// Disengage this tunnel, user does not have the rights to do this!!
this.httprequest.protocol = 999999;
this.httprequest.s.end();
@@ -2100,8 +1840,7 @@ function createMeshCore(agent)
// Send a metadata update to all desktop sessions
var users = {};
- if (this.httprequest.desktop.kvm.tunnels != null)
- {
+ if (this.httprequest.desktop.kvm.tunnels != null) {
for (var i in this.httprequest.desktop.kvm.tunnels) { try { var userid = this.httprequest.desktop.kvm.tunnels[i].httprequest.userid; if (users[userid] == null) { users[userid] = 1; } else { users[userid]++; } } catch (e) { } }
for (var i in this.httprequest.desktop.kvm.tunnels) { try { this.httprequest.desktop.kvm.tunnels[i].write(JSON.stringify({ ctrlChannel: '102938', type: 'metadata', users: users })); } catch (e) { } }
tunnelUserCount.desktop = users;
@@ -2109,8 +1848,7 @@ function createMeshCore(agent)
broadcastSessionsToRegisteredApps();
}
- this.end = function ()
- {
+ this.end = function () {
--this.desktop.kvm.connectionCount;
// Remove ourself from the list of remote desktop session
@@ -2119,8 +1857,7 @@ function createMeshCore(agent)
// Send a metadata update to all desktop sessions
var users = {};
- if (this.httprequest.desktop.kvm.tunnels != null)
- {
+ if (this.httprequest.desktop.kvm.tunnels != null) {
for (var i in this.httprequest.desktop.kvm.tunnels) { try { var userid = this.httprequest.desktop.kvm.tunnels[i].httprequest.userid; if (users[userid] == null) { users[userid] = 1; } else { users[userid]++; } } catch (e) { } }
for (var i in this.httprequest.desktop.kvm.tunnels) { try { this.httprequest.desktop.kvm.tunnels[i].write(JSON.stringify({ ctrlChannel: '102938', type: 'metadata', users: users })); } catch (e) { } }
tunnelUserCount.desktop = users;
@@ -2129,18 +1866,15 @@ function createMeshCore(agent)
}
// Unpipe the web socket
- try
- {
+ try {
this.unpipe(this.httprequest.desktop.kvm);
this.httprequest.desktop.kvm.unpipe(this);
}
catch (e) { }
// Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends).
- if (this.rtcchannel)
- {
- try
- {
+ if (this.rtcchannel) {
+ try {
this.rtcchannel.unpipe(this.httprequest.desktop.kvm);
this.httprequest.desktop.kvm.unpipe(this.rtcchannel);
}
@@ -2150,35 +1884,28 @@ function createMeshCore(agent)
// Place wallpaper back if needed
// TODO
- if (this.desktop.kvm.connectionCount == 0)
- {
+ if (this.desktop.kvm.connectionCount == 0) {
// Display a toast message. This may not be supported on all platforms.
// try { require('toaster').Toast('MeshCentral', 'Remote Desktop Control Ended.'); } catch (e) { }
this.httprequest.desktop.kvm.end();
- if (this.httprequest.desktop.kvm.connectionBar)
- {
+ if (this.httprequest.desktop.kvm.connectionBar) {
this.httprequest.desktop.kvm.connectionBar.removeAllListeners('close');
this.httprequest.desktop.kvm.connectionBar.close();
this.httprequest.desktop.kvm.connectionBar = null;
}
- } else
- {
- for (var i in this.httprequest.desktop.kvm.users)
- {
- if ((this.httprequest.desktop.kvm.users[i] == this.httprequest.username) && this.httprequest.desktop.kvm.connectionBar)
- {
+ } else {
+ for (var i in this.httprequest.desktop.kvm.users) {
+ if ((this.httprequest.desktop.kvm.users[i] == this.httprequest.username) && this.httprequest.desktop.kvm.connectionBar) {
for (var j in this.httprequest.desktop.kvm.rusers) { if (this.httprequest.desktop.kvm.rusers[j] == this.httprequest.realname) { this.httprequest.desktop.kvm.rusers.splice(j, 1); break; } }
this.httprequest.desktop.kvm.users.splice(i, 1);
this.httprequest.desktop.kvm.connectionBar.removeAllListeners('close');
this.httprequest.desktop.kvm.connectionBar.close();
this.httprequest.desktop.kvm.connectionBar = require('notifybar-desktop')(this.httprequest.privacybartext.replace('{0}', this.httprequest.desktop.kvm.users.join(', ')).replace('{1}', this.httprequest.desktop.kvm.rusers.join(', ')), require('MeshAgent')._tsid);
this.httprequest.desktop.kvm.connectionBar.httprequest = this.httprequest;
- this.httprequest.desktop.kvm.connectionBar.on('close', function ()
- {
+ this.httprequest.desktop.kvm.connectionBar.on('close', function () {
MeshServerLogEx(29, null, "Remote Desktop Connection forcefully closed by local user (" + this.httprequest.remoteaddr + ")", this.httprequest);
- for (var i in this.httprequest.desktop.kvm._pipedStreams)
- {
+ for (var i in this.httprequest.desktop.kvm._pipedStreams) {
this.httprequest.desktop.kvm._pipedStreams[i].end();
}
this.httprequest.desktop.kvm.end();
@@ -2188,40 +1915,34 @@ function createMeshCore(agent)
}
}
};
- if (this.httprequest.desktop.kvm.hasOwnProperty('connectionCount'))
- {
+ if (this.httprequest.desktop.kvm.hasOwnProperty('connectionCount')) {
this.httprequest.desktop.kvm.connectionCount++;
this.httprequest.desktop.kvm.rusers.push(this.httprequest.realname);
this.httprequest.desktop.kvm.users.push(this.httprequest.username);
this.httprequest.desktop.kvm.rusers.sort();
this.httprequest.desktop.kvm.users.sort();
- } else
- {
+ } else {
this.httprequest.desktop.kvm.connectionCount = 1;
this.httprequest.desktop.kvm.rusers = [this.httprequest.realname];
this.httprequest.desktop.kvm.users = [this.httprequest.username];
}
- if ((this.httprequest.rights == 0xFFFFFFFF) || (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) != 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0)))
- {
+ if ((this.httprequest.rights == 0xFFFFFFFF) || (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) != 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0))) {
// If we have remote control rights, pipe the KVM input
this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. Pipe the Browser --> KVM input.
- } else
- {
+ } else {
// We need to only pipe non-mouse & non-keyboard inputs.
//sendConsoleText('Warning: No Remote Desktop Input Rights.');
// TODO!!!
}
// Perform notification if needed. Toast messages may not be supported on all platforms.
- if (this.httprequest.consent && (this.httprequest.consent & 8))
- {
+ 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...", msgid: 1 }));
var consentMessage = this.httprequest.realname + " requesting remote desktop access. Grant access?", consentTitle = 'MeshCentral';
- if (this.httprequest.soptions != null)
- {
+ if (this.httprequest.soptions != null) {
if (this.httprequest.soptions.consentTitle != null) { consentTitle = this.httprequest.soptions.consentTitle; }
if (this.httprequest.soptions.consentMsgDesktop != null) { consentMessage = this.httprequest.soptions.consentMsgDesktop.replace('{0}', this.httprequest.realname).replace('{1}', this.httprequest.username); }
}
@@ -2231,51 +1952,40 @@ function createMeshCore(agent)
this._consentpromise = pr;
this.prependOnceListener('end', function () { if (this._consentpromise && this._consentpromise.close) { this._consentpromise.close(); } });
pr.then(
- function ()
- {
+ function () {
// Success
this.ws._consentpromise = null;
MeshServerLogEx(30, null, "Starting remote desktop after local user accepted (" + this.ws.httprequest.remoteaddr + ")", this.ws.httprequest);
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null, msgid: 0 }));
- if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 1))
- {
+ if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 1)) {
// User Notifications is required
var notifyMessage = this.ws.httprequest.realname + " started a remote desktop session.", notifyTitle = "MeshCentral";
- if (this.ws.httprequest.soptions != null)
- {
+ if (this.ws.httprequest.soptions != null) {
if (this.ws.httprequest.soptions.notifyTitle != null) { notifyTitle = this.ws.httprequest.soptions.notifyTitle; }
if (this.ws.httprequest.soptions.notifyMsgDesktop != null) { notifyMessage = this.ws.httprequest.soptions.notifyMsgDesktop.replace('{0}', this.ws.httprequest.realname).replace('{1}', this.ws.httprequest.username); }
}
try { require('toaster').Toast(notifyTitle, notifyMessage, tsid); } catch (e) { }
}
- if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 0x40))
- {
+ if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 0x40)) {
// Connection Bar is required
- if (this.ws.httprequest.desktop.kvm.connectionBar)
- {
+ if (this.ws.httprequest.desktop.kvm.connectionBar) {
this.ws.httprequest.desktop.kvm.connectionBar.removeAllListeners('close');
this.ws.httprequest.desktop.kvm.connectionBar.close();
}
- try
- {
+ try {
this.ws.httprequest.desktop.kvm.connectionBar = require('notifybar-desktop')(this.ws.httprequest.privacybartext.replace('{0}', this.ws.httprequest.desktop.kvm.users.join(', ')).replace('{1}', this.ws.httprequest.desktop.kvm.rusers.join(', ')), require('MeshAgent')._tsid);
MeshServerLogEx(31, null, "Remote Desktop Connection Bar Activated/Updated (" + this.ws.httprequest.remoteaddr + ")", this.ws.httprequest);
}
- catch (e)
- {
- if (process.platform != 'darwin')
- {
+ catch (e) {
+ if (process.platform != 'darwin') {
MeshServerLogEx(32, null, "Remote Desktop Connection Bar Failed or Not Supported (" + this.ws.httprequest.remoteaddr + ")", this.ws.httprequest);
}
}
- if (this.ws.httprequest.desktop.kvm.connectionBar)
- {
+ if (this.ws.httprequest.desktop.kvm.connectionBar) {
this.ws.httprequest.desktop.kvm.connectionBar.httprequest = this.ws.httprequest;
- this.ws.httprequest.desktop.kvm.connectionBar.on('close', function ()
- {
+ this.ws.httprequest.desktop.kvm.connectionBar.on('close', function () {
MeshServerLogEx(33, null, "Remote Desktop Connection forcefully closed by local user (" + this.httprequest.remoteaddr + ")", this.httprequest);
- for (var i in this.httprequest.desktop.kvm._pipedStreams)
- {
+ for (var i in this.httprequest.desktop.kvm._pipedStreams) {
this.httprequest.desktop.kvm._pipedStreams[i].end();
}
this.httprequest.desktop.kvm.end();
@@ -2285,56 +1995,44 @@ function createMeshCore(agent)
this.ws.httprequest.desktop.kvm.pipe(this.ws, { dataTypeSkip: 1 });
this.ws.resume();
},
- function (e)
- {
+ function (e) {
// User Consent Denied/Failed
this.ws._consentpromise = null;
MeshServerLogEx(34, null, "Failed to start remote desktop after local user rejected (" + this.ws.httprequest.remoteaddr + ")", this.ws.httprequest);
this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString(), msgid: 2 }));
});
- } else
- {
+ } else {
// User Consent Prompt is not required
- if (this.httprequest.consent && (this.httprequest.consent & 1))
- {
+ if (this.httprequest.consent && (this.httprequest.consent & 1)) {
// User Notifications is required
MeshServerLogEx(35, null, "Started remote desktop with toast notification (" + this.httprequest.remoteaddr + ")", this.httprequest);
var notifyMessage = this.httprequest.realname + " started a remote desktop session.", notifyTitle = "MeshCentral";
- if (this.httprequest.soptions != null)
- {
+ if (this.httprequest.soptions != null) {
if (this.httprequest.soptions.notifyTitle != null) { notifyTitle = this.httprequest.soptions.notifyTitle; }
if (this.httprequest.soptions.notifyMsgDesktop != null) { notifyMessage = this.httprequest.soptions.notifyMsgDesktop.replace('{0}', this.httprequest.realname).replace('{1}', this.httprequest.username); }
}
try { require('toaster').Toast(notifyTitle, notifyMessage, tsid); } catch (e) { }
- } else
- {
+ } else {
MeshServerLogEx(36, null, "Started remote desktop without notification (" + this.httprequest.remoteaddr + ")", this.httprequest);
}
- if (this.httprequest.consent && (this.httprequest.consent & 0x40))
- {
+ if (this.httprequest.consent && (this.httprequest.consent & 0x40)) {
// Connection Bar is required
- if (this.httprequest.desktop.kvm.connectionBar)
- {
+ if (this.httprequest.desktop.kvm.connectionBar) {
this.httprequest.desktop.kvm.connectionBar.removeAllListeners('close');
this.httprequest.desktop.kvm.connectionBar.close();
}
- try
- {
+ try {
this.httprequest.desktop.kvm.connectionBar = require('notifybar-desktop')(this.httprequest.privacybartext.replace('{0}', this.httprequest.desktop.kvm.rusers.join(', ')).replace('{1}', this.httprequest.desktop.kvm.users.join(', ')), require('MeshAgent')._tsid);
MeshServerLogEx(37, null, "Remote Desktop Connection Bar Activated/Updated (" + this.httprequest.remoteaddr + ")", this.httprequest);
}
- catch (e)
- {
+ catch (e) {
MeshServerLogEx(38, null, "Remote Desktop Connection Bar Failed or not Supported (" + this.httprequest.remoteaddr + ")", this.httprequest);
}
- if (this.httprequest.desktop.kvm.connectionBar)
- {
+ if (this.httprequest.desktop.kvm.connectionBar) {
this.httprequest.desktop.kvm.connectionBar.httprequest = this.httprequest;
- this.httprequest.desktop.kvm.connectionBar.on('close', function ()
- {
+ this.httprequest.desktop.kvm.connectionBar.on('close', function () {
MeshServerLogEx(39, null, "Remote Desktop Connection forcefully closed by local user (" + this.httprequest.remoteaddr + ")", this.httprequest);
- for (var i in this.httprequest.desktop.kvm._pipedStreams)
- {
+ for (var i in this.httprequest.desktop.kvm._pipedStreams) {
this.httprequest.desktop.kvm._pipedStreams[i].end();
}
this.httprequest.desktop.kvm.end();
@@ -2348,15 +2046,13 @@ function createMeshCore(agent)
this.on('data', onTunnelControlData);
//this.write('MeshCore KVM Hello!1');
- } else if (this.httprequest.protocol == 5)
- {
+ } else if (this.httprequest.protocol == 5) {
//
// Remote Files
//
// Check user access rights for files
- if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOFILES) != 0)))
- {
+ if (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) == 0) || ((this.httprequest.rights != 0xFFFFFFFF) && ((this.httprequest.rights & MESHRIGHT_NOFILES) != 0))) {
// Disengage this tunnel, user does not have the rights to do this!!
this.httprequest.protocol = 999999;
this.httprequest.s.end();
@@ -2367,18 +2063,15 @@ function createMeshCore(agent)
this.descriptorMetadata = "Remote Files";
// Add the files session to the count to update the server
- if (this.httprequest.userid != null)
- {
+ if (this.httprequest.userid != null) {
if (tunnelUserCount.files[this.httprequest.userid] == null) { tunnelUserCount.files[this.httprequest.userid] = 1; } else { tunnelUserCount.files[this.httprequest.userid]++; }
try { mesh.SendCommand({ action: 'sessions', type: 'files', value: tunnelUserCount.files }); } catch (e) { }
broadcastSessionsToRegisteredApps();
}
- this.end = function ()
- {
+ this.end = function () {
// Remove the files session from the count to update the server
- if (this.httprequest.userid != null)
- {
+ if (this.httprequest.userid != null) {
if (tunnelUserCount.files[this.httprequest.userid] != null) { tunnelUserCount.files[this.httprequest.userid]--; if (tunnelUserCount.files[this.httprequest.userid] <= 0) { delete tunnelUserCount.files[this.httprequest.userid]; } }
try { mesh.SendCommand({ action: 'sessions', type: 'files', value: tunnelUserCount.files }); } catch (e) { }
broadcastSessionsToRegisteredApps();
@@ -2386,14 +2079,12 @@ function createMeshCore(agent)
};
// Perform notification if needed. Toast messages may not be supported on all platforms.
- if (this.httprequest.consent && (this.httprequest.consent & 32))
- {
+ if (this.httprequest.consent && (this.httprequest.consent & 32)) {
// 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...", msgid: 1 }));
var consentMessage = this.httprequest.realname + " requesting remote file Access. Grant access?", consentTitle = 'MeshCentral';
- if (this.httprequest.soptions != null)
- {
+ if (this.httprequest.soptions != null) {
if (this.httprequest.soptions.consentTitle != null) { consentTitle = this.httprequest.soptions.consentTitle; }
if (this.httprequest.soptions.consentMsgFiles != null) { consentMessage = this.httprequest.soptions.consentMsgFiles.replace('{0}', this.httprequest.realname).replace('{1}', this.httprequest.username); }
}
@@ -2403,18 +2094,15 @@ function createMeshCore(agent)
this._consentpromise = pr;
this.prependOnceListener('end', function () { if (this._consentpromise && this._consentpromise.close) { this._consentpromise.close(); } });
pr.then(
- function ()
- {
+ function () {
// Success
this.ws._consentpromise = null;
MeshServerLogEx(40, null, "Starting remote files after local user accepted (" + this.ws.httprequest.remoteaddr + ")", this.ws.httprequest);
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
- if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 4))
- {
+ if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 4)) {
// User Notifications is required
var notifyMessage = this.ws.httprequest.realname + " started a remote file session.", notifyTitle = "MeshCentral";
- if (this.ws.httprequest.soptions != null)
- {
+ if (this.ws.httprequest.soptions != null) {
if (this.ws.httprequest.soptions.notifyTitle != null) { notifyTitle = this.ws.httprequest.soptions.notifyTitle; }
if (this.ws.httprequest.soptions.notifyMsgFiles != null) { notifyMessage = this.ws.httprequest.soptions.notifyMsgFiles.replace('{0}', this.ws.httprequest.realname).replace('{1}', this.ws.httprequest.username); }
}
@@ -2422,29 +2110,24 @@ function createMeshCore(agent)
}
this.ws.resume();
},
- function (e)
- {
+ function (e) {
// User Consent Denied/Failed
this.ws._consentpromise = null;
MeshServerLogEx(41, null, "Failed to start remote files after local user rejected (" + this.ws.httprequest.remoteaddr + ")", this.ws.httprequest);
this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString(), msgid: 2 }));
});
- } else
- {
+ } else {
// User Consent Prompt is not required
- if (this.httprequest.consent && (this.httprequest.consent & 4))
- {
+ if (this.httprequest.consent && (this.httprequest.consent & 4)) {
// User Notifications is required
MeshServerLogEx(42, null, "Started remote files with toast notification (" + this.httprequest.remoteaddr + ")", this.httprequest);
var notifyMessage = this.httprequest.realname + " started a remote file session.", notifyTitle = "MeshCentral";
- if (this.httprequest.soptions != null)
- {
+ if (this.httprequest.soptions != null) {
if (this.httprequest.soptions.notifyTitle != null) { notifyTitle = this.httprequest.soptions.notifyTitle; }
if (this.httprequest.soptions.notifyMsgFiles != null) { notifyMessage = this.httprequest.soptions.notifyMsgFiles.replace('{0}', this.httprequest.realname).replace('{1}', this.httprequest.username); }
}
try { require('toaster').Toast(notifyTitle, notifyMessage); } catch (e) { }
- } else
- {
+ } else {
MeshServerLogEx(43, null, "Started remote files without notification (" + this.httprequest.remoteaddr + ")", this.httprequest);
}
this.resume();
@@ -2453,23 +2136,18 @@ function createMeshCore(agent)
// Setup files
// NOP
}
- } else if (this.httprequest.protocol == 1)
- {
+ } else if (this.httprequest.protocol == 1) {
// Send data into terminal stdin
//this.write(data); // Echo back the keys (Does not seem to be a good idea)
- } else if (this.httprequest.protocol == 2)
- {
+ } else if (this.httprequest.protocol == 2) {
// Send data into remote desktop
- if (this.httprequest.desktop.state == 0)
- {
+ if (this.httprequest.desktop.state == 0) {
this.write(Buffer.from(String.fromCharCode(0x11, 0xFE, 0x00, 0x00, 0x4D, 0x45, 0x53, 0x48, 0x00, 0x00, 0x00, 0x00, 0x02)));
this.httprequest.desktop.state = 1;
- } else
- {
+ } else {
this.httprequest.desktop.write(data);
}
- } else if (this.httprequest.protocol == 5)
- {
+ } else if (this.httprequest.protocol == 5) {
// Process files commands
var cmd = null;
try { cmd = JSON.parse(data); } catch (e) { };
@@ -2480,8 +2158,7 @@ function createMeshCore(agent)
if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
//console.log(objToString(cmd, 0, ' '));
- switch (cmd.action)
- {
+ switch (cmd.action) {
case 'ls': {
/*
// Close the watcher if required
@@ -2518,20 +2195,15 @@ function createMeshCore(agent)
}
case 'rm': {
// Delete, possibly recursive delete
- for (var i in cmd.delfiles)
- {
+ for (var i in cmd.delfiles) {
var p = obj.path.join(cmd.path, cmd.delfiles[i]), delcount = 0;
try { delcount = deleteFolderRecursive(p, cmd.rec); } catch (e) { }
- if ((delcount == 1) && !cmd.rec)
- {
+ if ((delcount == 1) && !cmd.rec) {
MeshServerLogEx(45, [p], "Delete: \"" + p + "\"", this.httprequest);
- } else
- {
- if (cmd.rec)
- {
+ } else {
+ if (cmd.rec) {
MeshServerLogEx(46, [p, delcount], "Delete recursive: \"" + p + "\", " + delcount + " element(s) removed", this.httprequest);
- } else
- {
+ } else {
MeshServerLogEx(47, [p, delcount], "Delete: \"" + p + "\", " + delcount + " element(s) removed", this.httprequest);
}
}
@@ -2541,11 +2213,9 @@ function createMeshCore(agent)
case 'markcoredump': {
// If we are asking for the coredump file, set the right path.
var coreDumpPath = null;
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
if (fs.existsSync(process.coreDumpLocation)) { coreDumpPath = process.coreDumpLocation; }
- } else
- {
+ } else {
if ((process.cwd() != '//') && fs.existsSync(process.cwd() + 'core')) { coreDumpPath = process.cwd() + 'core'; }
}
if (coreDumpPath != null) { db.Put('CoreDumpTime', require('fs').statSync(coreDumpPath).mtime); }
@@ -2582,15 +2252,11 @@ function createMeshCore(agent)
{
// Download a file
var sendNextBlock = 0;
- if (cmd.sub == 'start')
- { // Setup the download
- if ((cmd.path == null) && (cmd.ask == 'coredump'))
- { // If we are asking for the coredump file, set the right path.
- if (process.platform == 'win32')
- {
+ if (cmd.sub == 'start') { // Setup the download
+ if ((cmd.path == null) && (cmd.ask == 'coredump')) { // If we are asking for the coredump file, set the right path.
+ if (process.platform == 'win32') {
if (fs.existsSync(process.coreDumpLocation)) { cmd.path = process.coreDumpLocation; }
- } else
- {
+ } else {
if ((process.cwd() != '//') && fs.existsSync(process.cwd() + 'core')) { cmd.path = process.cwd() + 'core'; }
}
}
@@ -2599,13 +2265,11 @@ function createMeshCore(agent)
this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
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; }
if (this.filedownload) { this.write({ action: 'download', sub: 'start', id: cmd.id }); }
- } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id))
- { // Download commands
+ } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
if (cmd.sub == 'startack') { sendNextBlock = ((typeof cmd.ack == 'number') ? cmd.ack : 8); } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
}
// Send the next download block(s)
- while (sendNextBlock > 0)
- {
+ while (sendNextBlock > 0) {
sendNextBlock--;
var buf = Buffer.alloc(16384);
var len = fs.readSync(this.filedownload.f, buf, 4, 16380, null);
@@ -2631,8 +2295,7 @@ function createMeshCore(agent)
case 'uploaddone':
{
// Indicates that an upload is done
- if (this.httprequest.uploadFile)
- {
+ if (this.httprequest.uploadFile) {
fs.closeSync(this.httprequest.uploadFile);
this.write(Buffer.from(JSON.stringify({ action: 'uploaddone', reqid: this.httprequest.uploadFileid }))); // Indicate that we closed the file.
delete this.httprequest.uploadFile;
@@ -2644,8 +2307,7 @@ function createMeshCore(agent)
case 'uploadcancel':
{
// Indicates that an upload is canceled
- if (this.httprequest.uploadFile)
- {
+ if (this.httprequest.uploadFile) {
fs.closeSync(this.httprequest.uploadFile);
fs.unlinkSync(this.httprequest.uploadFilePath);
this.write(Buffer.from(JSON.stringify({ action: 'uploadcancel', reqid: this.httprequest.uploadFileid }))); // Indicate that we closed the file.
@@ -2658,8 +2320,7 @@ function createMeshCore(agent)
case 'copy':
{
// Copy a bunch of files from scpath to dspath
- for (var i in cmd.names)
- {
+ for (var i in cmd.names) {
var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
MeshServerLogEx(51, [sc, ds], 'Copy: \"' + sc + '\" to \"' + ds + '\"', this.httprequest);
if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
@@ -2669,8 +2330,7 @@ function createMeshCore(agent)
case 'move':
{
// Move a bunch of files from scpath to dspath
- for (var i in cmd.names)
- {
+ for (var i in cmd.names) {
var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
MeshServerLogEx(52, [sc, ds], 'Move: \"' + sc + '\" to \"' + ds + '\"', this.httprequest);
if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
@@ -2693,8 +2353,7 @@ function createMeshCore(agent)
delete this.zipcancel;
var out = require('fs').createWriteStream(ofile, { flags: 'wb' });
out.xws = this;
- out.on('close', function ()
- {
+ out.on('close', function () {
this.xws.write(Buffer.from(JSON.stringify({ action: 'dialogmessage', msg: null })));
this.xws.write(Buffer.from(JSON.stringify({ action: 'refresh' })));
if (this.xws.zipcancel === true) { fs.unlinkSync(this.xws.zipfile); } // Delete the complete file.
@@ -2716,16 +2375,14 @@ function createMeshCore(agent)
// Unknown action, ignore it.
break;
}
- } else if (this.httprequest.protocol == 7)
- { // Plugin data exchange
+ } else if (this.httprequest.protocol == 7) { // Plugin data exchange
var cmd = null;
try { cmd = JSON.parse(data); } catch (e) { };
if (cmd == null) { return; }
if ((cmd.ctrlChannel == '102938') || ((cmd.type == 'offer') && (cmd.sdp != null))) { onTunnelControlData(cmd, this); return; } // If this is control data, handle it now.
if (cmd.action == undefined) return;
- switch (cmd.action)
- {
+ switch (cmd.action) {
case 'plugin': {
try { require(cmd.plugin).consoleaction(cmd, null, null, this); } catch (e) { throw e; }
break;
@@ -2741,21 +2398,15 @@ function createMeshCore(agent)
}
// Delete a directory with a files and directories within it
- function deleteFolderRecursive(path, rec)
- {
+ function deleteFolderRecursive(path, rec) {
var count = 0;
- if (fs.existsSync(path))
- {
- if (rec == true)
- {
- fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index)
- {
+ if (fs.existsSync(path)) {
+ if (rec == true) {
+ fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) {
var curPath = obj.path.join(path, file);
- if (fs.statSync(curPath).isDirectory())
- { // recurse
+ if (fs.statSync(curPath).isDirectory()) { // recurse
count += deleteFolderRecursive(curPath, true);
- } else
- { // delete file
+ } else { // delete file
fs.unlinkSync(curPath);
count++;
}
@@ -2768,13 +2419,11 @@ function createMeshCore(agent)
};
// Called when receiving control data on WebRTC
- function onTunnelWebRTCControlData(data)
- {
+ function onTunnelWebRTCControlData(data) {
if (typeof data != 'string') return;
var obj;
try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON on WebRTC: ' + data); return; }
- if (obj.type == 'close')
- {
+ if (obj.type == 'close') {
//sendConsoleText('Tunnel #' + this.xrtc.websocket.tunnel.index + ' WebRTC control close');
try { this.close(); } catch (e) { }
try { this.xrtc.close(); } catch (e) { }
@@ -2782,8 +2431,7 @@ function createMeshCore(agent)
}
// Called when receiving control data on websocket
- function onTunnelControlData(data, ws)
- {
+ function onTunnelControlData(data, ws) {
var obj;
if (ws == null) { ws = this; }
if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON: ' + data); return; } }
@@ -2791,16 +2439,12 @@ function createMeshCore(agent)
//sendConsoleText('onTunnelControlData(' + ws.httprequest.protocol + '): ' + JSON.stringify(data));
//console.log('onTunnelControlData: ' + JSON.stringify(data));
- if (obj.action)
- {
- switch (obj.action)
- {
+ if (obj.action) {
+ switch (obj.action) {
case 'lock': {
// Lock the current user out of the desktop
- try
- {
- if (process.platform == 'win32')
- {
+ try {
+ if (process.platform == 'win32') {
MeshServerLogEx(53, null, "Locking remote user out of desktop", ws.httprequest);
var child = require('child_process');
child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 });
@@ -2815,8 +2459,7 @@ function createMeshCore(agent)
return;
}
- switch (obj.type)
- {
+ switch (obj.type) {
case 'options': {
// These are additional connection options passed in the control channel.
//sendConsoleText('options: ' + JSON.stringify(obj));
@@ -2836,13 +2479,11 @@ function createMeshCore(agent)
}
case 'termsize': {
// Indicates a change in terminal size
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
if (ws.httprequest._dispatcher == null) return;
//sendConsoleText('Win32-TermSize: ' + obj.cols + 'x' + obj.rows);
if (ws.httprequest._dispatcher.invoke) { ws.httprequest._dispatcher.invoke('resizeTerminal', [obj.cols, obj.rows]); }
- } else
- {
+ } else {
if (ws.httprequest.process == null || ws.httprequest.process.pty == 0) return;
//sendConsoleText('Linux Resize: ' + obj.cols + 'x' + obj.rows);
@@ -2851,23 +2492,18 @@ function createMeshCore(agent)
break;
}
case 'webrtc0': { // Browser indicates we can start WebRTC switch-over.
- if (ws.httprequest.protocol == 1)
- { // Terminal
+ if (ws.httprequest.protocol == 1) { // Terminal
// 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
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
ws.httprequest._term.unpipe(ws);
- } else
- {
+ } else {
ws.httprequest.process.stdout.unpipe(ws);
ws.httprequest.process.stderr.unpipe(ws);
}
- } else if (ws.httprequest.protocol == 2)
- { // Desktop
+ } else if (ws.httprequest.protocol == 2) { // Desktop
// 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
ws.httprequest.desktop.kvm.unpipe(ws);
- } else
- {
+ } else {
// Switch things around so all WebRTC data goes to onTunnelData().
ws.rtcchannel.httprequest = ws.httprequest;
ws.rtcchannel.removeAllListeners('data');
@@ -2877,21 +2513,17 @@ function createMeshCore(agent)
break;
}
case 'webrtc1': {
- if ((ws.httprequest.protocol == 1) || (ws.httprequest.protocol == 6))
- { // Terminal
+ if ((ws.httprequest.protocol == 1) || (ws.httprequest.protocol == 6)) { // Terminal
// Switch the user input from websocket to webrtc at this point.
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
ws.unpipe(ws.httprequest._term);
ws.rtcchannel.pipe(ws.httprequest._term, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
- } else
- {
+ } else {
ws.unpipe(ws.httprequest.process.stdin);
ws.rtcchannel.pipe(ws.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
}
ws.resume(); // Resume the websocket to keep receiving control data
- } else if (ws.httprequest.protocol == 2)
- { // Desktop
+ } else if (ws.httprequest.protocol == 2) { // Desktop
// Switch the user input from websocket to webrtc at this point.
ws.unpipe(ws.httprequest.desktop.kvm);
try { ws.webrtc.rtcchannel.pipe(ws.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text.
@@ -2902,18 +2534,14 @@ function createMeshCore(agent)
}
case 'webrtc2': {
// Other side received websocket end of data marker, start sending data on WebRTC channel
- if ((ws.httprequest.protocol == 1) || (ws.httprequest.protocol == 6))
- { // Terminal
- if (process.platform == 'win32')
- {
+ if ((ws.httprequest.protocol == 1) || (ws.httprequest.protocol == 6)) { // Terminal
+ if (process.platform == 'win32') {
ws.httprequest._term.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
- } else
- {
+ } else {
ws.httprequest.process.stdout.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
ws.httprequest.process.stderr.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
}
- } else if (ws.httprequest.protocol == 2)
- { // Desktop
+ } else if (ws.httprequest.protocol == 2) { // Desktop
ws.httprequest.desktop.kvm.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
}
break;
@@ -2925,8 +2553,7 @@ function createMeshCore(agent)
ws.webrtc.websocket = ws;
ws.webrtc.on('connected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected');*/ });
ws.webrtc.on('disconnected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected');*/ });
- ws.webrtc.on('dataChannel', function (rtcchannel)
- {
+ ws.webrtc.on('dataChannel', function (rtcchannel) {
//sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
rtcchannel.maxFragmentSize = 32768;
rtcchannel.xrtc = this;
@@ -2934,14 +2561,11 @@ function createMeshCore(agent)
this.rtcchannel = rtcchannel;
this.websocket.rtcchannel = rtcchannel;
this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData);
- this.websocket.rtcchannel.on('end', function ()
- {
+ this.websocket.rtcchannel.on('end', function () {
// The WebRTC channel closed, unpipe the KVM now. This is also done when the web socket closes.
//sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed');
- if (this.websocket.desktop && this.websocket.desktop.kvm)
- {
- try
- {
+ if (this.websocket.desktop && this.websocket.desktop.kvm) {
+ try {
this.unpipe(this.websocket.desktop.kvm);
this.websocket.httprequest.desktop.kvm.unpipe(this);
}
@@ -2974,21 +2598,17 @@ function createMeshCore(agent)
var consoleHttpRequest = null;
// Console HTTP response
- function consoleHttpResponse(response)
- {
+ function consoleHttpResponse(response) {
response.data = function (data) { sendConsoleText(rstr2hex(buf2rstr(data)), this.sessionid); consoleHttpRequest = null; }
response.close = function () { sendConsoleText('httprequest.response.close', this.sessionid); consoleHttpRequest = null; }
};
// Open a web browser to a specified URL on current user's desktop
- function openUserDesktopUrl(url)
- {
+ function openUserDesktopUrl(url) {
if ((url.toLowerCase().startsWith('http://') == false) && (url.toLowerCase().startsWith('https://') == false)) { return null; }
var child = null;
- try
- {
- switch (process.platform)
- {
+ try {
+ switch (process.platform) {
case 'win32':
var user = require('user-sessions').getUsername(require('user-sessions').consoleUid());
child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ['cmd']);
@@ -3015,13 +2635,10 @@ function createMeshCore(agent)
}
// Process a mesh agent console command
- function processConsoleCommand(cmd, args, rights, sessionid)
- {
- try
- {
+ function processConsoleCommand(cmd, args, rights, sessionid) {
+ try {
var response = null;
- switch (cmd)
- {
+ switch (cmd) {
case 'help': { // Displays available commands
var fin = '', f = '', availcommands = 'agentupdate,msh,timerinfo,coreinfo,coredump,service,fdsnapshot,fdcount,startupoptions,alert,agentsize,versions,help,info,osinfo,args,print,type,dbkeys,dbget,dbset,dbcompact,eval,parseuri,httpget,nwslist,plugin,wsconnect,wssend,wsclose,notify,ls,ps,kill,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,openurl,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,wallpaper,agentmsg';
if (process.platform == 'win32') { availcommands += ',safemode,wpfhwacceleration,uac'; }
@@ -3031,8 +2648,7 @@ function createMeshCore(agent)
try { require('zip-reader'); availcommands += ',zip,unzip'; } catch (e) { }
availcommands = availcommands.split(',').sort();
- while (availcommands.length > 0)
- {
+ while (availcommands.length > 0) {
if (f.length > 90) { fin += (f + ',\r\n'); f = ''; }
f += (((f != '') ? ', ' : ' ') + availcommands.shift());
}
@@ -3054,12 +2670,10 @@ function createMeshCore(agent)
response = require('ChainViewer').getTimerInfo();
break;
case 'find':
- if (args['_'].length <= 1)
- {
+ if (args['_'].length <= 1) {
response = "Proper usage:\r\n find root criteria [criteria2] [criteria n...]";
}
- else
- {
+ else {
var root = args['_'][0];
var p = args['_'].slice(1);
var r = require('file-search').find(root, p);
@@ -3078,26 +2692,21 @@ function createMeshCore(agent)
break;
}
case 'agentmsg': {
- if (args['_'].length == 0)
- {
+ if (args['_'].length == 0) {
response = "Proper usage:\r\n agentmsg add \"[message]\" [iconIndex]\r\n agentmsg remove [index]\r\n agentmsg list"; // Display usage
- } else
- {
- if ((args['_'][0] == 'add') && (args['_'].length > 1))
- {
+ } else {
+ if ((args['_'][0] == 'add') && (args['_'].length > 1)) {
var msgIndex = 1, iconIndex = 0;
while (tunnelUserCount.msg[msgIndex] != null) { msgIndex++; }
if (args['_'].length >= 3) { try { iconIndex = parseInt(args['_'][2]); } catch (e) { } }
if (typeof iconIndex != 'number') { iconIndex = 0; }
tunnelUserCount.msg[msgIndex] = { msg: args['_'][1], icon: iconIndex };
response = 'Agent message ' + msgIndex + ' added.';
- } else if ((args['_'][0] == 'remove') && (args['_'].length > 1))
- {
+ } else if ((args['_'][0] == 'remove') && (args['_'].length > 1)) {
var msgIndex = 0;
try { msgIndex = parseInt(args['_'][1]); } catch (x) { }
if (tunnelUserCount.msg[msgIndex] == null) { response = "Message not found."; } else { delete tunnelUserCount.msg[msgIndex]; response = "Message removed."; }
- } else if (args['_'][0] == 'list')
- {
+ } else if (args['_'][0] == 'list') {
response = JSON.stringify(tunnelUserCount.msg, null, 2);
}
try { mesh.SendCommand({ action: 'sessions', type: 'msg', value: tunnelUserCount.msg }); } catch (x) { }
@@ -3112,13 +2721,10 @@ function createMeshCore(agent)
break;
}
case 'coredump':
- if (args['_'].length != 1)
- {
+ if (args['_'].length != 1) {
response = "Proper usage: coredump on|off|status|clear"; // Display usage
- } else
- {
- switch (args['_'][0].toLowerCase())
- {
+ } else {
+ switch (args['_'][0].toLowerCase()) {
case 'on':
process.coreDumpLocation = (process.platform == 'win32') ? (process.execPath.replace('.exe', '.dmp')) : (process.execPath + '.dmp');
response = 'coredump is now on';
@@ -3129,20 +2735,15 @@ function createMeshCore(agent)
break;
case 'status':
response = 'coredump is: ' + ((process.coreDumpLocation == null) ? 'off' : 'on');
- if (process.coreDumpLocation != null)
- {
- if (process.platform == 'win32')
- {
- if (fs.existsSync(process.coreDumpLocation))
- {
+ if (process.coreDumpLocation != null) {
+ if (process.platform == 'win32') {
+ if (fs.existsSync(process.coreDumpLocation)) {
response += '\r\n CoreDump present at: ' + process.coreDumpLocation;
response += '\r\n CoreDump Time: ' + new Date(fs.statSync(process.coreDumpLocation).mtime).getTime();
response += '\r\n Agent Time : ' + new Date(fs.statSync(process.execPath).mtime).getTime();
}
- } else
- {
- if ((process.cwd() != '//') && fs.existsSync(process.cwd() + 'core'))
- {
+ } else {
+ if ((process.cwd() != '//') && fs.existsSync(process.cwd() + 'core')) {
response += '\r\n CoreDump present at: ' + process.cwd() + 'core';
response += '\r\n CoreDump Time: ' + new Date(fs.statSync(process.cwd() + 'core').mtime).getTime();
response += '\r\n Agent Time : ' + new Date(fs.statSync(process.execPath).mtime).getTime();
@@ -3161,33 +2762,26 @@ function createMeshCore(agent)
}
break;
case 'service':
- if (args['_'].length != 1)
- {
+ if (args['_'].length != 1) {
response = "Proper usage: service status|restart"; // Display usage
}
- else
- {
+ else {
var svcname = process.platform == 'win32' ? 'Mesh Agent' : 'meshagent';
- try
- {
+ try {
svcname = require('MeshAgent').serviceName;
}
- catch (x)
- {
+ catch (x) {
}
var s = require('service-manager').manager.getService(svcname);
- switch (args['_'][0].toLowerCase())
- {
+ switch (args['_'][0].toLowerCase()) {
case 'status':
response = 'Service ' + (s.isRunning() ? (s.isMe() ? '[SELF]' : '[RUNNING]') : ('[NOT RUNNING]'));
break;
case 'restart':
- if (s.isMe())
- {
+ if (s.isMe()) {
s.restart();
}
- else
- {
+ else {
response = 'Restarting another agent instance is not allowed';
}
break;
@@ -3199,11 +2793,9 @@ function createMeshCore(agent)
}
break;
case 'zip':
- if (args['_'].length == 0)
- {
+ if (args['_'].length == 0) {
response = "Proper usage: zip (output file name), input1 [, input n]"; // Display usage
- } else
- {
+ } else {
var p = args['_'].join(' ').split(',');
var ofile = p.shift();
sendConsoleText('Writing ' + ofile + '...');
@@ -3216,19 +2808,16 @@ function createMeshCore(agent)
}
break;
case 'unzip':
- if (args['_'].length == 0)
- {
+ if (args['_'].length == 0) {
response = "Proper usage: unzip input, destination"; // Display usage
- } else
- {
+ } else {
var p = args['_'].join(' ').split(',');
if (p.length != 2) { response = "Proper usage: unzip input, destination"; break; } // Display usage
var prom = require('zip-reader').read(p[0]);
prom._dest = p[1];
prom.self = this;
prom.sessionid = sessionid;
- prom.then(function (zipped)
- {
+ prom.then(function (zipped) {
sendConsoleText('Extracting to ' + this._dest + '...', this.sessionid);
zipped.extractAll(this._dest).then(function () { sendConsoleText('finished unzipping', this.sessionid); }, function (e) { sendConsoleText('Error unzipping: ' + e, this.sessionid); }).parentPromise.sessionid = this.sessionid;
}, function (e) { sendConsoleText('Error unzipping: ' + e, this.sessionid); });
@@ -3236,13 +2825,11 @@ function createMeshCore(agent)
break;
case 'setbattery':
// require('MeshAgent').SendCommand({ action: 'battery', state: 'dc', level: 55 });
- if ((args['_'].length > 0) && ((args['_'][0] == 'ac') || (args['_'][0] == 'dc')))
- {
+ if ((args['_'].length > 0) && ((args['_'][0] == 'ac') || (args['_'][0] == 'dc'))) {
var b = { action: 'battery', state: args['_'][0] };
if (args['_'].length == 2) { b.level = parseInt(args['_'][1]); }
require('MeshAgent').SendCommand(b);
- } else
- {
+ } else {
require('MeshAgent').SendCommand({ action: 'battery' });
}
break;
@@ -3251,51 +2838,41 @@ function createMeshCore(agent)
break;
case 'fdcount':
require('DescriptorEvents').getDescriptorCount().then(
- function (c)
- {
+ function (c) {
sendConsoleText('Descriptor Count: ' + c, this.sessionid);
- }, function (e)
- {
+ }, function (e) {
sendConsoleText('Error fetching descriptor count: ' + e, this.sessionid);
}).parentPromise.sessionid = sessionid;
break;
case 'uac':
- if (process.platform != 'win32')
- {
+ if (process.platform != 'win32') {
response = 'Unknown command "uac", type "help" for list of avaialble commands.';
break;
}
- if (args['_'].length != 1)
- {
+ if (args['_'].length != 1) {
response = 'Proper usage: uac [get|interactive|secure]';
}
- else
- {
- switch (args['_'][0].toUpperCase())
- {
+ else {
+ switch (args['_'][0].toUpperCase()) {
case 'GET':
var secd = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System', 'PromptOnSecureDesktop');
response = "UAC mode: " + (secd == 0 ? "Interactive Desktop" : "Secure Desktop");
break;
case 'INTERACTIVE':
- try
- {
+ try {
require('win-registry').WriteKey(require('win-registry').HKEY.LocalMachine, 'Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System', 'PromptOnSecureDesktop', 0);
response = 'UAC mode changed to: Interactive Desktop';
}
- catch (e)
- {
+ catch (e) {
response = "Unable to change UAC Mode";
}
break;
case 'SECURE':
- try
- {
+ try {
require('win-registry').WriteKey(require('win-registry').HKEY.LocalMachine, 'Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System', 'PromptOnSecureDesktop', 1);
response = 'UAC mode changed to: Secure Desktop';
}
- catch (e)
- {
+ catch (e) {
response = "Unable to change UAC Mode";
}
break;
@@ -3312,50 +2889,40 @@ function createMeshCore(agent)
response = JSON.stringify(require('MeshAgent').getStartupOptions());
break;
case 'kvmmode':
- if (require('MeshAgent').maxKvmTileSize == null)
- {
+ if (require('MeshAgent').maxKvmTileSize == null) {
response = "Unknown command \"kvmmode\", type \"help\" for list of avaialble commands.";
}
- else
- {
- if (require('MeshAgent').maxKvmTileSize == 0)
- {
+ else {
+ if (require('MeshAgent').maxKvmTileSize == 0) {
response = 'KVM Mode: Full JUMBO';
}
- else
- {
+ else {
response = 'KVM Mode: ' + (require('MeshAgent').maxKvmTileSize <= 65500 ? 'NO JUMBO' : 'Partial JUMBO');
response += (', TileLimit: ' + (require('MeshAgent').maxKvmTileSize < 1024 ? (require('MeshAgent').maxKvmTileSize + ' bytes') : (Math.round(require('MeshAgent').maxKvmTileSize / 1024) + ' Kbytes')));
}
}
break;
case 'alert':
- if (args['_'].length == 0)
- {
+ if (args['_'].length == 0) {
response = "Proper usage: alert TITLE, CAPTION [, TIMEOUT]"; // Display usage
}
- else
- {
+ else {
var p = args['_'].join(' ').split(',');
- if (p.length < 2)
- {
+ if (p.length < 2) {
response = "Proper usage: alert TITLE, CAPTION [, TIMEOUT]"; // Display usage
}
- else
- {
+ else {
this._alert = require('message-box').create(p[0], p[1], p.length == 3 ? parseInt(p[2]) : 9999, 1);
}
}
break;
case 'agentsize':
var actualSize = Math.floor(require('fs').statSync(process.execPath).size / 1024);
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
// Check the Agent Uninstall MetaData for correctness, as the installer may have written an incorrect value
var writtenSize = 0;
try { writtenSize = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MeshCentralAgent', 'EstimatedSize'); } catch (e) { response = e; }
- if (writtenSize != actualSize)
- {
+ if (writtenSize != actualSize) {
response = "Size updated from: " + writtenSize + " to: " + actualSize;
try { require('win-registry').WriteKey(require('win-registry').HKEY.LocalMachine, 'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MeshCentralAgent', 'EstimatedSize', actualSize); } catch (e) { response = e; }
} else
@@ -3368,31 +2935,26 @@ function createMeshCore(agent)
break;
case 'wpfhwacceleration':
if (process.platform != 'win32') { throw ("wpfhwacceleration setting is only supported on Windows"); }
- if (args['_'].length != 1)
- {
+ if (args['_'].length != 1) {
response = "Proper usage: wpfhwacceleration (ON|OFF|STATUS)"; // Display usage
}
- else
- {
+ else {
var reg = require('win-registry');
var uname = require('user-sessions').getUsername(require('user-sessions').consoleUid());
var key = reg.usernameToUserKey(uname);
- switch (args['_'][0].toUpperCase())
- {
+ switch (args['_'][0].toUpperCase()) {
default:
response = "Proper usage: wpfhwacceleration (ON|OFF|STATUS|DEFAULT)"; // Display usage
break;
case 'ON':
- try
- {
+ try {
reg.WriteKey(reg.HKEY.Users, key + '\\SOFTWARE\\Microsoft\\Avalon.Graphics', 'DisableHWAcceleration', 0);
response = "OK";
} catch (e) { response = "FAILED"; }
break;
case 'OFF':
- try
- {
+ try {
reg.WriteKey(reg.HKEY.Users, key + '\\SOFTWARE\\Microsoft\\Avalon.Graphics', 'DisableHWAcceleration', 1);
response = 'OK';
} catch (e) { response = 'FAILED'; }
@@ -3410,13 +2972,10 @@ function createMeshCore(agent)
}
break;
case 'tsid':
- if (process.platform == 'win32')
- {
- if (args['_'].length != 1)
- {
+ if (process.platform == 'win32') {
+ if (args['_'].length != 1) {
response = "TSID: " + (require('MeshAgent')._tsid == null ? "console" : require('MeshAgent')._tsid);
- } else
- {
+ } else {
var i = parseInt(args['_'][0]);
require('MeshAgent')._tsid = (isNaN(i) ? null : i);
response = "TSID set to: " + (require('MeshAgent')._tsid == null ? "console" : require('MeshAgent')._tsid);
@@ -3425,15 +2984,12 @@ function createMeshCore(agent)
{ response = "TSID command only supported on Windows"; }
break;
case 'activeusers':
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
var p = require('user-sessions').enumerateUsers();
p.sessionid = sessionid;
- p.then(function (u)
- {
+ p.then(function (u) {
var v = [];
- for (var i in u)
- {
+ for (var i in u) {
if (u[i].State == 'Active') { v.push({ tsid: i, type: u[i].StationName, user: u[i].Username, domain: u[i].Domain }); }
}
sendConsoleText(JSON.stringify(v, null, 1), this.sessionid);
@@ -3442,44 +2998,35 @@ function createMeshCore(agent)
{ response = "activeusers command only supported on Windows"; }
break;
case 'wallpaper':
- if (process.platform != 'win32' && !(process.platform == 'linux' && require('linux-gnome-helpers').available))
- {
+ if (process.platform != 'win32' && !(process.platform == 'linux' && require('linux-gnome-helpers').available)) {
response = "wallpaper command not supported on this platform";
}
- else
- {
- if (args['_'].length != 1)
- {
+ else {
+ if (args['_'].length != 1) {
response = 'Proper usage: wallpaper (GET|TOGGLE)'; // Display usage
}
- else
- {
- switch (args['_'][0].toUpperCase())
- {
+ else {
+ switch (args['_'][0].toUpperCase()) {
default:
response = 'Proper usage: wallpaper (GET|TOGGLE)'; // Display usage
break;
case 'GET':
case 'TOGGLE':
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
var id = require('user-sessions').getProcessOwnerName(process.pid).tsid == 0 ? 1 : 0;
var child = require('child_process').execFile(process.execPath, [process.execPath.split('\\').pop(), '-b64exec', 'dmFyIFNQSV9HRVRERVNLV0FMTFBBUEVSID0gMHgwMDczOwp2YXIgU1BJX1NFVERFU0tXQUxMUEFQRVIgPSAweDAwMTQ7CnZhciBHTSA9IHJlcXVpcmUoJ19HZW5lcmljTWFyc2hhbCcpOwp2YXIgdXNlcjMyID0gR00uQ3JlYXRlTmF0aXZlUHJveHkoJ3VzZXIzMi5kbGwnKTsKdXNlcjMyLkNyZWF0ZU1ldGhvZCgnU3lzdGVtUGFyYW1ldGVyc0luZm9BJyk7CgppZiAocHJvY2Vzcy5hcmd2Lmxlbmd0aCA9PSAzKQp7CiAgICB2YXIgdiA9IEdNLkNyZWF0ZVZhcmlhYmxlKDEwMjQpOwogICAgdXNlcjMyLlN5c3RlbVBhcmFtZXRlcnNJbmZvQShTUElfR0VUREVTS1dBTExQQVBFUiwgdi5fc2l6ZSwgdiwgMCk7CiAgICBjb25zb2xlLmxvZyh2LlN0cmluZyk7CiAgICBwcm9jZXNzLmV4aXQoKTsKfQplbHNlCnsKICAgIHZhciBuYiA9IEdNLkNyZWF0ZVZhcmlhYmxlKHByb2Nlc3MuYXJndlszXSk7CiAgICB1c2VyMzIuU3lzdGVtUGFyYW1ldGVyc0luZm9BKFNQSV9TRVRERVNLV0FMTFBBUEVSLCBuYi5fc2l6ZSwgbmIsIDApOwogICAgcHJvY2Vzcy5leGl0KCk7Cn0='], { type: id });
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stderr.on('data', function () { });
child.waitExit();
var current = child.stdout.str.trim();
- if (args['_'][0].toUpperCase() == 'GET')
- {
+ if (args['_'][0].toUpperCase() == 'GET') {
response = current;
break;
}
- if (current != '')
- {
+ if (current != '') {
require('MeshAgent')._wallpaper = current;
response = 'Wallpaper cleared';
- } else
- {
+ } else {
response = 'Wallpaper restored';
}
child = require('child_process').execFile(process.execPath, [process.execPath.split('\\').pop(), '-b64exec', 'dmFyIFNQSV9HRVRERVNLV0FMTFBBUEVSID0gMHgwMDczOwp2YXIgU1BJX1NFVERFU0tXQUxMUEFQRVIgPSAweDAwMTQ7CnZhciBHTSA9IHJlcXVpcmUoJ19HZW5lcmljTWFyc2hhbCcpOwp2YXIgdXNlcjMyID0gR00uQ3JlYXRlTmF0aXZlUHJveHkoJ3VzZXIzMi5kbGwnKTsKdXNlcjMyLkNyZWF0ZU1ldGhvZCgnU3lzdGVtUGFyYW1ldGVyc0luZm9BJyk7CgppZiAocHJvY2Vzcy5hcmd2Lmxlbmd0aCA9PSAzKQp7CiAgICB2YXIgdiA9IEdNLkNyZWF0ZVZhcmlhYmxlKDEwMjQpOwogICAgdXNlcjMyLlN5c3RlbVBhcmFtZXRlcnNJbmZvQShTUElfR0VUREVTS1dBTExQQVBFUiwgdi5fc2l6ZSwgdiwgMCk7CiAgICBjb25zb2xlLmxvZyh2LlN0cmluZyk7CiAgICBwcm9jZXNzLmV4aXQoKTsKfQplbHNlCnsKICAgIHZhciBuYiA9IEdNLkNyZWF0ZVZhcmlhYmxlKHByb2Nlc3MuYXJndlszXSk7CiAgICB1c2VyMzIuU3lzdGVtUGFyYW1ldGVyc0luZm9BKFNQSV9TRVRERVNLV0FMTFBBUEVSLCBuYi5fc2l6ZSwgbmIsIDApOwogICAgcHJvY2Vzcy5leGl0KCk7Cn0=', current != '' ? '""' : require('MeshAgent')._wallpaper], { type: id });
@@ -3487,21 +3034,17 @@ function createMeshCore(agent)
child.stderr.on('data', function () { });
child.waitExit();
}
- else
- {
+ else {
var id = require('user-sessions').consoleUid();
var current = require('linux-gnome-helpers').getDesktopWallpaper(id);
- if (args['_'][0].toUpperCase() == 'GET')
- {
+ if (args['_'][0].toUpperCase() == 'GET') {
response = current;
break;
}
- if (current != '/dev/null')
- {
+ if (current != '/dev/null') {
require('MeshAgent')._wallpaper = current;
response = 'Wallpaper cleared';
- } else
- {
+ } else {
response = 'Wallpaper restored';
}
require('linux-gnome-helpers').setDesktopWallpaper(id, current != '/dev/null' ? undefined : require('MeshAgent')._wallpaper);
@@ -3512,29 +3055,22 @@ function createMeshCore(agent)
}
break;
case 'safemode':
- if (process.platform != 'win32')
- {
+ if (process.platform != 'win32') {
response = 'safemode only supported on Windows Platforms'
}
- else
- {
- if (args['_'].length != 1)
- {
+ else {
+ if (args['_'].length != 1) {
response = 'Proper usage: safemode (ON|OFF|STATUS)'; // Display usage
}
- else
- {
+ else {
var svcname = process.platform == 'win32' ? 'Mesh Agent' : 'meshagent';
- try
- {
+ try {
svcname = require('MeshAgent').serviceName;
}
- catch (x)
- {
+ catch (x) {
}
- switch (args['_'][0].toUpperCase())
- {
+ switch (args['_'][0].toUpperCase()) {
default:
response = 'Proper usage: safemode (ON|OFF|STATUS)'; // Display usage
break;
@@ -3547,10 +3083,8 @@ function createMeshCore(agent)
break;
case 'STATUS':
var nextboot = require('win-bcd').getKey('safeboot');
- if (nextboot)
- {
- switch (nextboot)
- {
+ if (nextboot) {
+ switch (nextboot) {
case 'Network':
case 'network':
nextboot = 'SAFE_MODE_NETWORK';
@@ -3566,32 +3100,30 @@ function createMeshCore(agent)
}
}
break;
- /*
- case 'border':
- {
- if ((args['_'].length == 1) && (args['_'][0] == 'on')) {
- if (meshCoreObj.users.length > 0) {
- obj.borderManager.Start(meshCoreObj.users[0]);
- response = 'Border blinking is on.';
- } else {
- response = 'Cannot turn on border blinking, no logged in users.';
- }
- } else if ((args['_'].length == 1) && (args['_'][0] == 'off')) {
- obj.borderManager.Stop();
- response = 'Border blinking is off.';
- } else {
- response = 'Proper usage: border "on|off"'; // Display correct command usage
- }
- }
- break;
- */
- case 'av':
- if (process.platform == 'win32')
+ /*
+ case 'border':
{
+ if ((args['_'].length == 1) && (args['_'][0] == 'on')) {
+ if (meshCoreObj.users.length > 0) {
+ obj.borderManager.Start(meshCoreObj.users[0]);
+ response = 'Border blinking is on.';
+ } else {
+ response = 'Cannot turn on border blinking, no logged in users.';
+ }
+ } else if ((args['_'].length == 1) && (args['_'][0] == 'off')) {
+ obj.borderManager.Stop();
+ response = 'Border blinking is off.';
+ } else {
+ response = 'Proper usage: border "on|off"'; // Display correct command usage
+ }
+ }
+ break;
+ */
+ case 'av':
+ if (process.platform == 'win32') {
// Windows Command: "wmic /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct get /FORMAT:CSV"
response = JSON.stringify(require('win-info').av(), null, 1);
- } else
- {
+ } else {
response = 'Not supported on the platform';
}
break;
@@ -3599,27 +3131,21 @@ function createMeshCore(agent)
if (args['_'].length != 1) { response = 'Proper usage: log "sample text"'; } else { MeshServerLog(args['_'][0]); response = 'ok'; }
break;
case 'getclip':
- if (require('MeshAgent').isService)
- {
+ if (require('MeshAgent').isService) {
require('clipboard').dispatchRead().then(function (str) { sendConsoleText(str, sessionid); });
- } else
- {
+ } else {
require("clipboard").read().then(function (str) { sendConsoleText(str, sessionid); });
}
break;
case 'setclip': {
- if (args['_'].length != 1)
- {
+ if (args['_'].length != 1) {
response = 'Proper usage: setclip "sample text"';
- } else
- {
- if (require('MeshAgent').isService)
- {
+ } else {
+ if (require('MeshAgent').isService) {
require('clipboard').dispatchWrite(args['_'][0]);
response = 'Setting clipboard to: "' + args['_'][0] + '"';
}
- else
- {
+ else {
require("clipboard")(args['_'][0]); response = 'Setting clipboard to: "' + args['_'][0] + '"';
}
}
@@ -3637,12 +3163,10 @@ function createMeshCore(agent)
}
case 'toast': {
if (args['_'].length < 1) { response = 'Proper usage: toast "message"'; } else {
- if (require('MeshAgent')._tsid == null)
- {
+ if (require('MeshAgent')._tsid == null) {
require('toaster').Toast('MeshCentral', args['_'][0]).then(sendConsoleText, sendConsoleText);
}
- else
- {
+ else {
require('toaster').Toast('MeshCentral', args['_'][0], require('MeshAgent')._tsid).then(sendConsoleText, sendConsoleText);
}
}
@@ -3654,8 +3178,7 @@ function createMeshCore(agent)
break;
}
case 'ps': {
- processManager.getProcesses(function (plist)
- {
+ processManager.getProcesses(function (plist) {
var x = '';
for (var i in plist) { x += i + ((plist[i].user) ? (', ' + plist[i].user) : '') + ', ' + plist[i].cmd + '\r\n'; }
sendConsoleText(x, sessionid);
@@ -3663,11 +3186,9 @@ function createMeshCore(agent)
break;
}
case 'kill': {
- if ((args['_'].length < 1))
- {
+ if ((args['_'].length < 1)) {
response = 'Proper usage: kill [pid]'; // Display correct command usage
- } else
- {
+ } else {
process.kill(parseInt(args['_'][0]));
response = 'Killed process ' + args['_'][0] + '.';
}
@@ -3680,13 +3201,10 @@ function createMeshCore(agent)
case 'rawsmbios': {
if (SMBiosTablesRaw == null) { response = 'SMBios tables not available.'; } else {
response = '';
- for (var i in SMBiosTablesRaw)
- {
+ for (var i in SMBiosTablesRaw) {
var header = false;
- for (var j in SMBiosTablesRaw[i])
- {
- if (SMBiosTablesRaw[i][j].length > 0)
- {
+ for (var j in SMBiosTablesRaw[i]) {
+ if (SMBiosTablesRaw[i][j].length > 0) {
if (header == false) { response += ('Table type #' + i + ((require('smbios').smTableTypes[i] == null) ? '' : (', ' + require('smbios').smTableTypes[i]))) + '\r\n'; header = true; }
response += (' ' + SMBiosTablesRaw[i][j].toString('hex')) + '\r\n';
}
@@ -3696,41 +3214,33 @@ function createMeshCore(agent)
break;
}
case 'eval': { // Eval JavaScript
- if (args['_'].length < 1)
- {
+ if (args['_'].length < 1) {
response = 'Proper usage: eval "JavaScript code"'; // Display correct command usage
- } else
- {
+ } else {
response = JSON.stringify(mesh.eval(args['_'][0])); // This can only be run by trusted administrator.
}
break;
}
case 'uninstallagent': // Uninstall this agent
var agentName = process.platform == 'win32' ? 'Mesh Agent' : 'meshagent';
- try
- {
+ try {
agentName = require('MeshAgent').serviceName;
}
- catch (x)
- {
+ catch (x) {
}
- if (!require('service-manager').manager.getService(agentName).isMe())
- {
+ if (!require('service-manager').manager.getService(agentName).isMe()) {
response = 'Uininstall failed, this instance is not the service instance';
- } else
- {
+ } else {
try { diagnosticAgent_uninstall(); } catch (e) { }
var js = "require('service-manager').manager.getService('" + agentName + "').stop(); require('service-manager').manager.uninstallService('" + agentName + "'); process.exit();";
this.child = require('child_process').execFile(process.execPath, [process.platform == 'win32' ? (process.execPath.split('\\').pop()) : (process.execPath.split('/').pop()), '-b64exec', Buffer.from(js).toString('base64')], { type: 4, detached: true });
}
break;
case 'notify': { // Send a notification message to the mesh
- if (args['_'].length != 1)
- {
+ if (args['_'].length != 1) {
response = 'Proper usage: notify "message" [--session]'; // Display correct command usage
- } else
- {
+ } else {
var notification = { action: 'msg', type: 'notify', value: args['_'][0], tag: 'console' };
if (args.session) { notification.sessionid = sessionid; } // If "--session" is specified, notify only this session, if not, the server will notify the mesh
mesh.SendCommand(notification); // no sessionid or userid specified, notification will go to the entire mesh
@@ -3742,18 +3252,15 @@ function createMeshCore(agent)
// CPU & memory utilization
pr = require('sysinfo').cpuUtilization();
pr.sessionid = sessionid;
- pr.then(function (data)
- {
+ pr.then(function (data) {
sendConsoleText(JSON.stringify({ cpu: data, memory: require('sysinfo').memUtilization() }, null, 1), this.sessionid);
- }, function (e)
- {
- sendConsoleText(e);
- });
+ }, function (e) {
+ sendConsoleText(e);
+ });
break;
}
case 'sysinfo': { // Return system information
- getSystemInformation(function (results, err)
- {
+ getSystemInformation(function (results, err) {
if (results == null) { sendConsoleText(err, this.sessionid); } else {
sendConsoleText(JSON.stringify(results, null, 1), this.sessionid);
}
@@ -3775,12 +3282,10 @@ function createMeshCore(agent)
case 'osinfo': { // Return the operating system information
var i = 1;
if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; }
- for (var j = 0; j < i; j++)
- {
+ for (var j = 0; j < i; j++) {
var pr = require('os').name();
pr.sessionid = sessionid;
- pr.then(function (v)
- {
+ pr.then(function (v) {
sendConsoleText("OS: " + v + (process.platform == 'win32' ? (require('win-virtual-terminal').supported ? ' [ConPTY: YES]' : ' [ConPTY: NO]') : ''), this.sessionid);
});
}
@@ -3798,11 +3303,9 @@ function createMeshCore(agent)
break;
}
case 'type': { // Returns the content of a file
- if (args['_'].length == 0)
- {
+ if (args['_'].length == 0) {
response = 'Proper usage: type (filepath) [maxlength]'; // Display correct command usage
- } else
- {
+ } else {
var max = 4096;
if ((args['_'].length > 1) && (typeof args['_'][1] == 'number')) { max = args['_'][1]; }
if (max > 4096) max = 4096;
@@ -3821,22 +3324,18 @@ function createMeshCore(agent)
}
case 'dbget': { // Return the data store value for a given key
if (db == null) { response = 'Database not accessible.'; break; }
- if (args['_'].length != 1)
- {
+ if (args['_'].length != 1) {
response = 'Proper usage: dbget (key)'; // Display the value for a given database key
- } else
- {
+ } else {
response = db.Get(args['_'][0]);
}
break;
}
case 'dbset': { // Set a data store key and value pair
if (db == null) { response = 'Database not accessible.'; break; }
- if (args['_'].length != 2)
- {
+ if (args['_'].length != 2) {
response = 'Proper usage: dbset (key) (value)'; // Set a database key
- } else
- {
+ } else {
var r = db.Put(args['_'][0], args['_'][1]);
response = 'Key set: ' + r;
}
@@ -3849,27 +3348,20 @@ function createMeshCore(agent)
break;
}
case 'httpget': {
- if (consoleHttpRequest != null)
- {
+ if (consoleHttpRequest != null) {
response = 'HTTP operation already in progress.';
- } else
- {
- if (args['_'].length != 1)
- {
+ } else {
+ if (args['_'].length != 1) {
response = 'Proper usage: httpget (url)';
- } else
- {
+ } else {
var options = http.parseUri(args['_'][0]);
options.method = 'GET';
- if (options == null)
- {
+ if (options == null) {
response = 'Invalid url.';
- } else
- {
+ } else {
try { consoleHttpRequest = http.request(options, consoleHttpResponse); } catch (e) { response = 'Invalid HTTP GET request'; }
consoleHttpRequest.sessionid = sessionid;
- if (consoleHttpRequest != null)
- {
+ if (consoleHttpRequest != null) {
consoleHttpRequest.end();
response = 'HTTPGET ' + options.protocol + '//' + options.host + ':' + options.port + options.path;
}
@@ -3880,8 +3372,7 @@ function createMeshCore(agent)
}
case 'wslist': { // List all web sockets
response = '';
- for (var i in consoleWebSockets)
- {
+ for (var i in consoleWebSockets) {
var httprequest = consoleWebSockets[i];
response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n';
}
@@ -3889,20 +3380,16 @@ function createMeshCore(agent)
break;
}
case 'wsconnect': { // Setup a web socket
- if (args['_'].length == 0)
- {
+ if (args['_'].length == 0) {
response = 'Proper usage: wsconnect (url)\r\nFor example: wsconnect wss://localhost:443/meshrelay.ashx?id=abc'; // Display correct command usage
- } else
- {
+ } else {
var httprequest = null;
- try
- {
+ try {
var options = http.parseUri(args['_'][0].split('$').join('%24').split('@').join('%40')); // Escape the $ and @ characters in the URL
options.rejectUnauthorized = 0;
httprequest = http.request(options);
} catch (e) { response = 'Invalid HTTP websocket request'; }
- if (httprequest != null)
- {
+ if (httprequest != null) {
httprequest.upgrade = onWebSocketUpgrade;
httprequest.on('error', function (e) { sendConsoleText("ERROR: Unable to connect to: " + this.url + ", " + JSON.stringify(e)); });
@@ -3918,43 +3405,34 @@ function createMeshCore(agent)
break;
}
case 'wssend': { // Send data on a web socket
- if (args['_'].length == 0)
- {
+ if (args['_'].length == 0) {
response = 'Proper usage: wssend (socketnumber)\r\n'; // Display correct command usage
- for (var i in consoleWebSockets)
- {
+ for (var i in consoleWebSockets) {
var httprequest = consoleWebSockets[i];
response += 'Websocket #' + i + ', ' + httprequest.url + '\r\n';
}
- } else
- {
+ } else {
var i = parseInt(args['_'][0]);
var httprequest = consoleWebSockets[i];
- if (httprequest != undefined)
- {
+ if (httprequest != undefined) {
httprequest.s.write(args['_'][1]);
response = 'ok';
- } else
- {
+ } else {
response = 'Invalid web socket number';
}
}
break;
}
case 'wsclose': { // Close a websocket
- if (args['_'].length == 0)
- {
+ if (args['_'].length == 0) {
response = 'Proper usage: wsclose (socketnumber)'; // Display correct command usage
- } else
- {
+ } else {
var i = parseInt(args['_'][0]);
var httprequest = consoleWebSockets[i];
- if (httprequest != undefined)
- {
+ if (httprequest != undefined) {
if (httprequest.s != null) { httprequest.s.end(); } else { httprequest.end(); }
response = 'ok';
- } else
- {
+ } else {
response = 'Invalid web socket number';
}
}
@@ -3972,15 +3450,12 @@ function createMeshCore(agent)
if (args['_'].length > 0) { xpath = obj.path.join(args['_'][0], '*'); }
response = 'List of ' + xpath + '\r\n';
var results = fs.readdirSync(xpath);
- for (var i = 0; i < results.length; ++i)
- {
+ for (var i = 0; i < results.length; ++i) {
var stat = null, p = obj.path.join(args['_'][0], results[i]);
try { stat = fs.statSync(p); } catch (e) { }
- if ((stat == null) || (stat == undefined))
- {
+ if ((stat == null) || (stat == undefined)) {
response += (results[i] + "\r\n");
- } else
- {
+ } else {
response += (results[i] + " " + ((stat.isDirectory()) ? "(Folder)" : "(File)") + "\r\n");
}
}
@@ -3996,16 +3471,13 @@ function createMeshCore(agent)
break;
}
case 'amt': { // Show Intel AMT status
- if (amt != null)
- {
- amt.getMeiState(9, function (state)
- {
+ if (amt != null) {
+ amt.getMeiState(9, function (state) {
var resp = "Intel AMT not detected.";
if (state != null) { resp = objToString(state, 0, ' ', true); }
sendConsoleText(resp, sessionid);
});
- } else
- {
+ } else {
response = "Intel AMT not detected.";
}
break;
@@ -4016,11 +3488,9 @@ function createMeshCore(agent)
break;
}
case 'wakeonlan': { // Send wake-on-lan
- if ((args['_'].length != 1) || (args['_'][0].length != 12))
- {
+ if ((args['_'].length != 1) || (args['_'][0].length != 12)) {
response = 'Proper usage: wakeonlan [mac], for example "wakeonlan 010203040506".';
- } else
- {
+ } else {
var count = sendWakeOnLan(args['_'][0]);
response = 'Sent wake-on-lan on ' + count + ' interface(s).';
}
@@ -4031,16 +3501,12 @@ function createMeshCore(agent)
break;
}
case 'power': { // Execute a power action on this computer
- if (mesh.ExecPowerState == undefined)
- {
+ if (mesh.ExecPowerState == undefined) {
response = 'Power command not supported on this agent.';
- } else
- {
- if ((args['_'].length == 0) || isNaN(Number(args['_'][0])))
- {
+ } else {
+ if ((args['_'].length == 0) || isNaN(Number(args['_'][0]))) {
response = 'Proper usage: power (actionNumber), where actionNumber is:\r\n LOGOFF = 1\r\n SHUTDOWN = 2\r\n REBOOT = 3\r\n SLEEP = 4\r\n HIBERNATE = 5\r\n DISPLAYON = 6\r\n KEEPAWAKE = 7\r\n BEEP = 8\r\n CTRLALTDEL = 9\r\n VIBRATE = 13\r\n FLASH = 14'; // Display correct command usage
- } else
- {
+ } else {
var r = mesh.ExecPowerState(Number(args['_'][0]), Number(args['_'][1]));
response = 'Power action executed with return code: ' + r + '.';
}
@@ -4048,8 +3514,7 @@ function createMeshCore(agent)
break;
}
case 'location': {
- getIpLocationData(function (location)
- {
+ getIpLocationData(function (location) {
sendConsoleText(objToString({ action: 'iplocation', type: 'publicip', value: location }, 0, ' '));
});
break;
@@ -4059,8 +3524,7 @@ function createMeshCore(agent)
break;
}
case 'scanwifi': {
- if (wifiScanner != null)
- {
+ if (wifiScanner != null) {
var wifiPresent = wifiScanner.hasWireless;
if (wifiPresent) { response = "Perfoming Wifi scan..."; wifiScanner.Scan(); } else { response = "Wifi absent."; }
} else
@@ -4077,51 +3541,40 @@ function createMeshCore(agent)
break;
}
case 'getscript': {
- if (args['_'].length != 1)
- {
+ if (args['_'].length != 1) {
response = "Proper usage: getscript [scriptNumber].";
- } else
- {
+ } else {
mesh.SendCommand({ action: 'getScript', type: args['_'][0] });
}
break;
}
case 'diagnostic':
{
- if (!mesh.DAIPC.listening)
- {
+ 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')
- {
+ if (diag) {
+ if (args['_'].length == 1 && args['_'][0] == 'uninstall') {
diagnosticAgent_uninstall();
response = 'Diagnostic Agent uninstalled';
}
- else
- {
+ else {
response = 'Diagnostic Agent installed at: ' + diag.appLocation();
}
}
- else
- {
- if (args['_'].length == 1 && args['_'][0] == 'install')
- {
+ else {
+ if (args['_'].length == 1 && args['_'][0] == 'install') {
diag = diagnosticAgent_installCheck(true);
- if (diag)
- {
+ if (diag) {
response = 'Diagnostic agent was installed at: ' + diag.appLocation();
}
- else
- {
+ else {
response = 'Diagnostic agent installation failed';
}
}
- else
- {
+ else {
response = 'Diagnostic Agent Not installed. To install: diagnostic install';
}
}
@@ -4135,8 +3588,7 @@ function createMeshCore(agent)
case 'amtconfig': {
if (amt == null) { response = "Intel AMT not detected."; break; }
if (apftunnel != null) { response = "Intel AMT server tunnel already active"; break; }
- amt.getMeiState(15, function (state)
- {
+ amt.getMeiState(15, function (state) {
var rx = '';
if ((state == null) || (state.ProvisioningState == null)) { rx = "Intel AMT not ready for configuration."; } else {
var apfarg = {
@@ -4150,19 +3602,15 @@ function createMeshCore(agent)
conntype: 2, // 0 = CIRA, 1 = Relay, 2 = LMS. The correct value is 2 since we are performing an LMS relay, other values for testing.
meiState: state // MEI state will be passed to MPS server
};
- if ((state.UUID == null) || (state.UUID.length != 36))
- {
+ if ((state.UUID == null) || (state.UUID.length != 36)) {
rx = "Unable to get Intel AMT UUID";
- } else
- {
+ } else {
addAmtEvent('User LMS tunnel start.');
apftunnel = require('amt-apfclient')({ debug: false }, apfarg);
- apftunnel.onJsonControl = function (data)
- {
+ apftunnel.onJsonControl = function (data) {
if (data.action == 'console') { addAmtEvent(data.msg); require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: data.msg }); } // Display a console message
if (data.action == 'mestate') { amt.getMeiState(15, function (state) { apftunnel.updateMeiState(state); }); } // Update the MEI state
- if (data.action == 'deactivate')
- { // Request CCM deactivation
+ if (data.action == 'deactivate') { // Request CCM deactivation
var amtMeiModule, amtMei;
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { apftunnel.sendMeiDeactivationState(1); return; }
amtMei.on('error', function (e) { apftunnel.sendMeiDeactivationState(1); });
@@ -4171,12 +3619,10 @@ function createMeshCore(agent)
if (data.action == 'close') { try { apftunnel.disconnect(); } catch (e) { } apftunnel = null; } // Close the CIRA-LMS connection
}
apftunnel.onChannelClosed = function () { addAmtEvent('User LMS tunnel closed.'); apftunnel = null; }
- try
- {
+ try {
apftunnel.connect();
rx = "Started Intel AMT configuration";
- } catch (ex)
- {
+ } catch (ex) {
rx = JSON.stringify(ex);
}
}
@@ -4186,17 +3632,14 @@ function createMeshCore(agent)
break;
}
case 'apf': {
- if (meshCoreObj.intelamt !== null)
- {
- if (args['_'].length == 1)
- {
+ if (meshCoreObj.intelamt !== null) {
+ if (args['_'].length == 1) {
var connType = -1, connTypeStr = args['_'][0].toLowerCase();
if (connTypeStr == 'lms') { connType = 2; }
if (connTypeStr == 'relay') { connType = 1; }
if (connTypeStr == 'cira') { connType = 0; }
if (connTypeStr == 'off') { connType = -2; }
- if (connType >= 0)
- { // Connect
+ if (connType >= 0) { // Connect
var apfarg = {
mpsurl: mesh.ServerUrl.replace('agent.ashx', 'apf.ashx'),
mpsuser: Buffer.from(mesh.ServerInfo.MeshID, 'hex').toString('base64').substring(0, 16),
@@ -4207,67 +3650,52 @@ function createMeshCore(agent)
clientuuid: meshCoreObj.intelamt.uuid,
conntype: connType // 0 = CIRA, 1 = Relay, 2 = LMS. The correct value is 2 since we are performing an LMS relay, other values for testing.
};
- if ((apfarg.clientuuid == null) || (apfarg.clientuuid.length != 36))
- {
+ if ((apfarg.clientuuid == null) || (apfarg.clientuuid.length != 36)) {
response = "Unable to get Intel AMT UUID: " + apfarg.clientuuid;
- } else
- {
+ } else {
apftunnel = require('amt-apfclient')({ debug: false }, apfarg);
- apftunnel.onJsonControl = function (data)
- {
+ apftunnel.onJsonControl = function (data) {
if (data.action == 'console') { require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: data.msg }); }
if (data.action == 'close') { try { apftunnel.disconnect(); } catch (e) { } apftunnel = null; }
}
apftunnel.onChannelClosed = function () { apftunnel = null; }
- try
- {
+ try {
apftunnel.connect();
response = "Started APF tunnel";
- } catch (e)
- {
+ } catch (e) {
response = JSON.stringify(e);
}
}
- } else if (connType == -2)
- { // Disconnect
- try
- {
+ } else if (connType == -2) { // Disconnect
+ try {
apftunnel.disconnect();
response = "Stopped APF tunnel";
- } catch (e)
- {
+ } catch (e) {
response = JSON.stringify(e);
}
apftunnel = null;
- } else
- {
+ } else {
response = "Invalid command.\r\nUse: apf lms|relay|cira|off";
}
- } else
- {
+ } else {
response = "APF tunnel is " + (apftunnel == null ? "off" : "on") + "\r\nUse: apf lms|relay|cira|off";
}
- } else
- {
+ } else {
response = "APF tunnel requires Intel AMT";
}
break;
}
case 'plugin': {
- if (typeof args['_'][0] == 'string')
- {
- try
- {
+ if (typeof args['_'][0] == 'string') {
+ try {
// Pass off the action to the plugin
// for plugin creators, you'll want to have a plugindir/modules_meshcore/plugin.js
// to control the output / actions here.
response = require(args['_'][0]).consoleaction(args, rights, sessionid, mesh);
- } catch (e)
- {
+ } catch (e) {
response = "There was an error in the plugin (" + e + ")";
}
- } else
- {
+ } else {
response = "Proper usage: plugin [pluginName] [args].";
}
break;
@@ -4282,18 +3710,15 @@ function createMeshCore(agent)
}
// Send a mesh agent console command
- function sendConsoleText(text, sessionid)
- {
+ function sendConsoleText(text, sessionid) {
if (typeof text == 'object') { text = JSON.stringify(text); }
if (debugConsole && ((sessionid == null) || (sessionid == 'pipe'))) { broadcastToRegisteredApps({ cmd: 'console', value: text }); }
if (sessionid != 'pipe') { require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: text, sessionid: sessionid }); }
}
// Send a mesh agent message to server, placing a bubble/badge on the agent device
- function sendAgentMessage(msg, icon)
- {
- if (sendAgentMessage.messages == null)
- {
+ function sendAgentMessage(msg, icon) {
+ if (sendAgentMessage.messages == null) {
sendAgentMessage.messages = {};
sendAgentMessage.nextid = 1;
}
@@ -4301,16 +3726,13 @@ function createMeshCore(agent)
require('MeshAgent').SendCommand({ action: 'sessions', type: 'msg', value: sendAgentMessage.messages });
}
- function windows_execve(name, agentfilename, sessionid)
- {
+ function windows_execve(name, agentfilename, sessionid) {
var libc;
- try
- {
+ try {
libc = require('_GenericMarshal').CreateNativeProxy('msvcrt.dll');
libc.CreateMethod('_wexecve');
}
- catch (xx)
- {
+ catch (xx) {
sendConsoleText('Self Update failed because msvcrt.dll is missing', sessionid);
sendAgentMessage('Self Update failed because msvcrt.dll is missing', 3);
return;
@@ -4328,41 +3750,33 @@ function createMeshCore(agent)
}
// Start a JavaScript based Agent Self-Update
- function agentUpdate_Start(updateurl, updateoptions)
- {
+ function agentUpdate_Start(updateurl, updateoptions) {
// If this value is null
var sessionid = (updateoptions != null) ? updateoptions.sessionid : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
- if (this._selfupdate != null)
- {
+ if (this._selfupdate != null) {
// We were already called, so we will ignore this duplicate request
if (sessionid != null) { sendConsoleText('Self update already in progress...', sessionid); }
}
- else
- {
- if (require('MeshAgent').ARCHID == null && updateurl == null)
- {
+ else {
+ if (require('MeshAgent').ARCHID == null && updateurl == null) {
// This agent doesn't have the ability to tell us which ARCHID it is, so we don't know which agent to pull
- sendConsoleText('Unable to initiate update, agent ARCHID is not defined', sessionid);
+ sendConsoleText('Unable to initiate update, agent ARCHID is not defined', sessionid);
}
- else
- {
+ else {
var agentfilename = process.execPath.split(process.platform == 'win32' ? '\\' : '/').pop(); // Local File Name, ie: MeshAgent.exe
var name = require('MeshAgent').serviceName;
if (name == null) { name = process.platform == 'win32' ? 'Mesh Agent' : 'meshagent'; } // This is an older agent that doesn't expose the service name, so use the default
- try
- {
+ try {
var s = require('service-manager').manager.getService(name);
- if (!s.isMe())
- {
+ if (!s.isMe()) {
if (process.platform == 'win32') { s.close(); }
- sendConsoleText('Self Update cannot continue, this agent is not an instance of (' + name + ')', sessionid);
+ sendConsoleText('Self Update cannot continue, this agent is not an instance of (' + name + ')', sessionid);
return;
}
if (process.platform == 'win32') { s.close(); }
}
- catch (zz)
- {
+ catch (zz) {
sendConsoleText('Self Update Failed because this agent is not an instance of (' + name + ')', sessionid);
sendAgentMessage('Self Update Failed because this agent is not an instance of (' + name + ')', 3);
return;
@@ -4373,23 +3787,20 @@ function createMeshCore(agent)
options.protocol = 'https:';
if (updateurl == null) { options.path = ('/meshagents?id=' + require('MeshAgent').ARCHID); }
options.rejectUnauthorized = false;
- options.checkServerIdentity = function checkServerIdentity(certs)
- {
+ options.checkServerIdentity = function checkServerIdentity(certs) {
// If the tunnel certificate matches the control channel certificate, accept the connection
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.digest == certs[0].digest) return; } catch (ex) { }
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.fingerprint == certs[0].fingerprint) return; } catch (ex) { }
// Check that the certificate is the one expected by the server, fail if not.
- if (checkServerIdentity.servertlshash == null)
- {
+ if (checkServerIdentity.servertlshash == null) {
if (require('MeshAgent').ServerInfo == null || require('MeshAgent').ServerInfo.ControlChannelCertificate == null) { return; }
sendConsoleText('Self Update failed, because the url cannot be verified', sessionid);
sendAgentMessage('Self Update failed, because the url cannot be verified', 3);
throw new Error('BadCert');
}
- if ((checkServerIdentity.servertlshash != null) && (checkServerIdentity.servertlshash.toLowerCase() != certs[0].digest.split(':').join('').toLowerCase()))
- {
+ if ((checkServerIdentity.servertlshash != null) && (checkServerIdentity.servertlshash.toLowerCase() != certs[0].digest.split(':').join('').toLowerCase())) {
sendConsoleText('Self Update failed, because the supplied certificate does not match', sessionid);
sendAgentMessage('Self Update failed, because the supplied certificate does not match', 3);
throw new Error('BadCert')
@@ -4397,32 +3808,25 @@ function createMeshCore(agent)
}
options.checkServerIdentity.servertlshash = (updateoptions != null ? updateoptions.tlshash : null);
this._selfupdate = require('https').get(options);
- this._selfupdate.on('error', function (e)
- {
+ this._selfupdate.on('error', function (e) {
sendConsoleText('Self Update failed, because there was a problem trying to download the update', sessionid);
sendAgentMessage('Self Update failed, because there was a problem trying to download the update', 3);
});
- this._selfupdate.on('response', function (img)
- {
+ this._selfupdate.on('response', function (img) {
this._file = require('fs').createWriteStream(agentfilename + '.update', { flags: 'wb' });
this._filehash = require('SHA384Stream').create();
- this._filehash.on('hash', function (h)
- {
- if (updateoptions != null && updateoptions.hash != null)
- {
- if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase())
- {
+ this._filehash.on('hash', function (h) {
+ if (updateoptions != null && updateoptions.hash != null) {
+ if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase()) {
if (sessionid != null) { sendConsoleText('Download complete. HASH verified.', sessionid); }
}
- else
- {
+ else {
sendConsoleText('Self Update FAILED because the downloaded agent FAILED hash check', sessionid);
sendAgentMessage('Self Update FAILED because the downloaded agent FAILED hash check', 3);
return;
}
}
- else
- {
+ else {
if (sessionid != null) { sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid); }
}
@@ -4430,13 +3834,11 @@ function createMeshCore(agent)
try { mesh.SendCommand({ action: 'agentupdatedownloaded' }); } catch (e) { }
if (sessionid != null) { sendConsoleText('Updating and restarting agent...', sessionid); }
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
// Use _wexecve() equivalent to perform the update
windows_execve(name, agentfilename, sessionid);
}
- else
- {
+ else {
// remove binary
require('fs').unlinkSync(process.execPath);
@@ -4452,14 +3854,12 @@ function createMeshCore(agent)
require('fs').chmodSync(process.execPath, m);
if (sessionid != null) { sendConsoleText('Restarting service...', sessionid); }
- try
- {
+ try {
// restart service
var s = require('service-manager').manager.getService(name);
s.restart();
}
- catch (zz)
- {
+ catch (zz) {
sendConsoleText('Self Update encountered an error trying to restart service', sessionid);
sendAgentMessage('Self Update encountered an error trying to restart service', 3);
}
@@ -4479,16 +3879,13 @@ function createMeshCore(agent)
//process.exit = function (code) { console.log("Exit with code: " + code.toString()); }
// Called when the server connection state changes
- function handleServerConnection(state)
- {
+ function handleServerConnection(state) {
meshServerConnectionState = state;
- if (meshServerConnectionState == 0)
- {
+ if (meshServerConnectionState == 0) {
// Server disconnected
if (selfInfoUpdateTimer != null) { clearInterval(selfInfoUpdateTimer); selfInfoUpdateTimer = null; }
lastSelfInfo = null;
- } else
- {
+ } else {
// Server connected, send mesh core information
var oldNodeId = db.Get('OldNodeId');
if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); }
@@ -4499,15 +3896,13 @@ function createMeshCore(agent)
// Update the server on with basic info, logged in users and more advanced stuff, like Intel ME and Network Settings
meInfoStr = null;
sendPeriodicServerUpdate(null, true);
- if (selfInfoUpdateTimer == null)
- {
+ if (selfInfoUpdateTimer == null) {
selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); // 20 minutes
selfInfoUpdateTimer.metadata = 'meshcore (InfoUpdate Timer)';
}
// Send any state messages
- if (Object.keys(tunnelUserCount.msg).length > 0)
- {
+ if (Object.keys(tunnelUserCount.msg).length > 0) {
try { mesh.SendCommand({ action: 'sessions', type: 'msg', value: tunnelUserCount.msg }); } catch (e) { }
broadcastSessionsToRegisteredApps();
}
@@ -4523,14 +3918,12 @@ function createMeshCore(agent)
// Update the server with the latest network interface information
var sendNetworkUpdateNagleTimer = null;
function sendNetworkUpdateNagle() { if (sendNetworkUpdateNagleTimer != null) { clearTimeout(sendNetworkUpdateNagleTimer); sendNetworkUpdateNagleTimer = null; } sendNetworkUpdateNagleTimer = setTimeout(sendNetworkUpdate, 5000); }
- function sendNetworkUpdate(force)
- {
+ function sendNetworkUpdate(force) {
sendNetworkUpdateNagleTimer = null;
// Update the network interfaces information data
var netInfo = { netif2: require('os').networkInterfaces() };
- if (netInfo.netif2)
- {
+ if (netInfo.netif2) {
netInfo.action = 'netinfo';
var netInfoStr = JSON.stringify(netInfo);
if ((force == true) || (clearGatewayMac(netInfoStr) != clearGatewayMac(lastNetworkInfo))) { mesh.SendCommand(netInfo); lastNetworkInfo = netInfoStr; }
@@ -4538,17 +3931,14 @@ function createMeshCore(agent)
}
// Called periodically to check if we need to send updates to the server
- function sendPeriodicServerUpdate(flags, force)
- {
+ function sendPeriodicServerUpdate(flags, force) {
if (meshServerConnectionState == 0) return; // Not connected to server, do nothing.
if (!flags) { flags = 0xFFFFFFFF; }
// If we have a connected MEI, get Intel ME information
- if ((flags & 1) && (amt != null) && (amt.state == 2))
- {
+ if ((flags & 1) && (amt != null) && (amt.state == 2)) {
delete meshCoreObj.intelamt;
- amt.getMeiState(9, function (meinfo)
- {
+ amt.getMeiState(9, function (meinfo) {
meshCoreObj.intelamt = meinfo;
meshCoreObj.intelamt.microlms = amt.lmsstate;
meshCoreObjChanged();
@@ -4559,20 +3949,17 @@ function createMeshCore(agent)
if (flags & 2) { sendNetworkUpdateNagle(false); }
// Update anti-virus information
- if ((flags & 4) && (process.platform == 'win32'))
- {
+ if ((flags & 4) && (process.platform == 'win32')) {
// Windows Command: "wmic /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct get /FORMAT:CSV"
try { meshCoreObj.av = require('win-info').av(); meshCoreObjChanged(); } catch (e) { av = null; } // Antivirus
//if (process.platform == 'win32') { try { meshCoreObj.pr = require('win-info').pendingReboot(); meshCoreObjChanged(); } catch (e) { meshCoreObj.pr = null; } } // Pending reboot
}
// Send available data right now
- if (force)
- {
+ if (force) {
meshCoreObj = sortObjRec(meshCoreObj);
var x = JSON.stringify(meshCoreObj);
- if (x != LastPeriodicServerUpdate)
- {
+ if (x != LastPeriodicServerUpdate) {
LastPeriodicServerUpdate = x;
mesh.SendCommand(meshCoreObj);
}
@@ -4583,13 +3970,11 @@ function createMeshCore(agent)
var LastPeriodicServerUpdate = null;
var PeriodicServerUpdateNagleTimer = null;
function meshCoreObjChanged() { if (PeriodicServerUpdateNagleTimer == null) { PeriodicServerUpdateNagleTimer = setTimeout(meshCoreObjChangedEx, 500); } }
- function meshCoreObjChangedEx()
- {
+ function meshCoreObjChangedEx() {
PeriodicServerUpdateNagleTimer = null;
meshCoreObj = sortObjRec(meshCoreObj);
var x = JSON.stringify(meshCoreObj);
- if (x != LastPeriodicServerUpdate)
- {
+ if (x != LastPeriodicServerUpdate) {
try { LastPeriodicServerUpdate = x; mesh.SendCommand(meshCoreObj); } catch (ex) { }
}
}
@@ -4598,15 +3983,13 @@ function createMeshCore(agent)
function sortObj(o) { return Object.keys(o).sort().reduce(function (result, key) { result[key] = o[key]; return result; }, {}); }
// Starting function
- obj.start = function ()
- {
+ obj.start = function () {
// Setup the mesh agent event handlers
mesh.AddCommandHandler(handleServerCommand);
mesh.AddConnectHandler(handleServerConnection);
}
- obj.stop = function ()
- {
+ obj.stop = function () {
mesh.AddCommandHandler(null);
mesh.AddConnectHandler(null);
}
@@ -4615,8 +3998,7 @@ function createMeshCore(agent)
function onWebSocketData(data) { sendConsoleText("Got WebSocket #" + this.httprequest.index + " data: " + data, this.httprequest.sessionid); }
function onWebSocketSendOk() { sendConsoleText("WebSocket #" + this.index + " SendOK.", this.sessionid); }
- function onWebSocketUpgrade(response, s, head)
- {
+ function onWebSocketUpgrade(response, s, head) {
sendConsoleText("WebSocket #" + this.index + " connected.", this.sessionid);
this.s = s;
s.httprequest = this;
@@ -4630,11 +4012,9 @@ function createMeshCore(agent)
//
// Startup for Duktape only. This file is not intended to run in NodeJS.
//
-try
-{
+try {
mainMeshCore = createMeshCore();
mainMeshCore.start(null);
-} catch (e)
-{
+} catch (e) {
require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: "uncaughtException2: " + ex });
}
diff --git a/agents/recoverycore.js b/agents/recoverycore.js
index 0cda7a95..7149137c 100644
--- a/agents/recoverycore.js
+++ b/agents/recoverycore.js
@@ -6,11 +6,9 @@ var nextTunnelIndex = 1;
var tunnels = {};
var fs = require('fs');
-if (require('MeshAgent').ARCHID == null)
-{
+if (require('MeshAgent').ARCHID == null) {
var id = null;
- switch (process.platform)
- {
+ switch (process.platform) {
case 'win32':
id = require('_GenericMarshal').PointerSize == 4 ? 3 : 4;
break;
@@ -18,12 +16,10 @@ if (require('MeshAgent').ARCHID == null)
id = require('_GenericMarshal').PointerSize == 4 ? 31 : 30;
break;
case 'darwin':
- try
- {
+ try {
id = require('os').arch() == 'x64' ? 16 : 29;
}
- catch(xx)
- {
+ catch (xx) {
id = 16;
}
break;
@@ -33,22 +29,17 @@ if (require('MeshAgent').ARCHID == null)
//attachDebugger({ webport: 9994, wait: 1 }).then(function (p) { console.log('Debug on port: ' + p); });
-function sendConsoleText(msg, sessionid)
-{
- if (sessionid != null)
- {
+function sendConsoleText(msg, sessionid) {
+ if (sessionid != null) {
require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: msg, sessionid: sessionid });
}
- else
- {
+ else {
require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: msg });
}
}
-function sendAgentMessage(msg, icon)
-{
- if (sendAgentMessage.messages == null)
- {
+function sendAgentMessage(msg, icon) {
+ if (sendAgentMessage.messages == null) {
sendAgentMessage.messages = {};
sendAgentMessage.nextid = 1;
}
@@ -57,11 +48,9 @@ function sendAgentMessage(msg, icon)
}
// Add to the server event log
-function MeshServerLog(msg, state)
-{
+function MeshServerLog(msg, state) {
if (typeof msg == 'string') { msg = { action: 'log', msg: msg }; } else { msg.action = 'log'; }
- if (state)
- {
+ if (state) {
if (state.userid) { msg.userid = state.userid; }
if (state.username) { msg.username = state.username; }
if (state.sessionid) { msg.sessionid = state.sessionid; }
@@ -71,11 +60,9 @@ function MeshServerLog(msg, state)
}
// Add to the server event log, use internationalized events
-function MeshServerLogEx(id, args, msg, state)
-{
+function MeshServerLogEx(id, args, msg, state) {
var msg = { action: 'log', msgid: id, msgArgs: args, msg: msg };
- if (state)
- {
+ if (state) {
if (state.userid) { msg.userid = state.userid; }
if (state.username) { msg.username = state.username; }
if (state.sessionid) { msg.sessionid = state.sessionid; }
@@ -84,17 +71,13 @@ function MeshServerLogEx(id, args, msg, state)
require('MeshAgent').SendCommand(msg);
}
-function pathjoin()
-{
+function pathjoin() {
var x = [];
- for (var i in arguments)
- {
+ for (var i in arguments) {
var w = arguments[i];
- if (w != null)
- {
+ if (w != null) {
while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); }
- if (i != 0)
- {
+ if (i != 0) {
while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); }
}
x.push(w);
@@ -106,9 +89,70 @@ function pathjoin()
// Replace a string with a number if the string is an exact number
function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) === x)) { x = parseInt(x); } return x; }
+function linux_execv(name, agentfilename, sessionid) {
+ var libs = require('monitor-info').getLibInfo('libc');
+ var libc = null;
-function bsd_execv(name, agentfilename, sessionid)
-{
+ while (libs.length > 0) {
+ try {
+ libc = require('_GenericMarshal').CreateNativeProxy(libs.pop().path);
+ break;
+ }
+ catch (e) {
+ libc = null;
+ continue;
+ }
+ }
+ if (libc != null) {
+ try {
+ libc.CreateMethod('execv');
+ }
+ catch (e) {
+ libc = null;
+ }
+ }
+
+ if (libc == null) {
+ // Couldn't find libc.so, fallback to using service manager to restart agent
+ if (sessionid != null) { sendConsoleText('Restarting service via service-manager...', sessionid) }
+ try {
+ // restart service
+ var s = require('service-manager').manager.getService(name);
+ s.restart();
+ }
+ catch (zz) {
+ sendConsoleText('Self Update encountered an error trying to restart service', sessionid);
+ sendAgentMessage('Self Update encountered an error trying to restart service', 3);
+ }
+ return;
+ }
+
+ if (sessionid != null) { sendConsoleText('Restarting service via execv()...', sessionid) }
+
+ var i;
+ var args;
+ var argarr = [];
+ var path = require('_GenericMarshal').CreateVariable(process.execPath);
+
+ if (require('MeshAgent').getStartupOptions != null) {
+ var options = require('MeshAgent').getStartupOptions();
+ for (i in options) {
+ argarr.push('--' + i + '="' + options[i] + '"');
+ }
+ }
+
+ args = require('_GenericMarshal').CreateVariable((1 + argarr.length) * require('_GenericMarshal').PointerSize);
+ for (i = 0; i < argarr.length; ++i) {
+ var arg = require('_GenericMarshal').CreateVariable(argarr[i]);
+ arg.pointerBuffer().copy(args.toBuffer(), i * require('_GenericMarshal').PointerSize);
+ }
+
+ libc.execv(path, args);
+ if (sessionid != null) { sendConsoleText('Self Update failed because execv() failed', sessionid) }
+ sendAgentMessage('Self Update failed because execv() failed', 3);
+}
+
+function bsd_execv(name, agentfilename, sessionid) {
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stderr.str = ''; child.stderr.on('data', function (c) { this.str += c.toString(); });
@@ -123,21 +167,18 @@ function bsd_execv(name, agentfilename, sessionid)
child.stdin.write(' }');
child.stdin.write("}'\nexit\n");
child.waitExit();
- if (child.stdout.str.trim() == '')
- {
+ if (child.stdout.str.trim() == '') {
if (sessionid != null) { sendConsoleText('Self Update failed because cannot find libc.so', sessionid) }
sendAgentMessage('Self Update failed because cannot find libc.so', 3);
return;
}
var libc = null;
- try
- {
+ try {
libc = require('_GenericMarshal').CreateNativeProxy(child.stdout.str.trim());
libc.CreateMethod('execv');
}
- catch(e)
- {
+ catch (e) {
if (sessionid != null) { sendConsoleText('Self Update failed: ' + e.toString(), sessionid) }
sendAgentMessage('Self Update failed: ' + e.toString(), 3);
return;
@@ -148,32 +189,28 @@ function bsd_execv(name, agentfilename, sessionid)
var argarr = [];
var args;
var options = require('MeshAgent').getStartupOptions();
- for(i in options)
- {
+ for (i in options) {
argarr.push('--' + i + '="' + options[i] + '"');
}
args = require('_GenericMarshal').CreateVariable((1 + argarr.length) * require('_GenericMarshal').PointerSize);
- for (i = 0; i < argarr.length; ++i)
- {
+ for (i = 0; i < argarr.length; ++i) {
var arg = require('_GenericMarshal').CreateVariable(argarr[i]);
arg.pointerBuffer().copy(args.toBuffer(), i * require('_GenericMarshal').PointerSize);
}
-
+
+ if (sessionid != null) { sendConsoleText('Restarting service via service-manager', sessionid) }
libc.execv(path, args);
if (sessionid != null) { sendConsoleText('Self Update failed because execv() failed', sessionid) }
sendAgentMessage('Self Update failed because execv() failed', 3);
}
-function windows_execve(name, agentfilename, sessionid)
-{
+function windows_execve(name, agentfilename, sessionid) {
var libc;
- try
- {
+ try {
libc = require('_GenericMarshal').CreateNativeProxy('msvcrt.dll');
libc.CreateMethod('_wexecve');
}
- catch (xx)
- {
+ catch (xx) {
sendConsoleText('Self Update failed because msvcrt.dll is missing', sessionid);
sendAgentMessage('Self Update failed because msvcrt.dll is missing', 3);
return;
@@ -191,43 +228,33 @@ function windows_execve(name, agentfilename, sessionid)
}
// Start a JavaScript based Agent Self-Update
-function agentUpdate_Start(updateurl, updateoptions)
-{
- sendConsoleText('agentUpdate_Start: ' + updateurl + ', ' + JSON.stringify(updateoptions));
-
+function agentUpdate_Start(updateurl, updateoptions) {
// If this value is null
var sessionid = (updateoptions != null) ? updateoptions.sessionid : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
- if (this._selfupdate != null)
- {
+ if (this._selfupdate != null) {
// We were already called, so we will ignore this duplicate request
if (sessionid != null) { sendConsoleText('Self update already in progress...', sessionid); }
}
- else
- {
- if (require('MeshAgent').ARCHID == null && updateurl == null)
- {
+ else {
+ if (require('MeshAgent').ARCHID == null && updateurl == null) {
// This agent doesn't have the ability to tell us which ARCHID it is, so we don't know which agent to pull
sendConsoleText('Unable to initiate update, agent ARCHID is not defined', sessionid);
}
- else
- {
+ else {
var agentfilename = process.execPath.split(process.platform == 'win32' ? '\\' : '/').pop(); // Local File Name, ie: MeshAgent.exe
var name = require('MeshAgent').serviceName;
if (name == null) { name = process.platform == 'win32' ? 'Mesh Agent' : 'meshagent'; } // This is an older agent that doesn't expose the service name, so use the default
- try
- {
+ try {
var s = require('service-manager').manager.getService(name);
- if (!s.isMe())
- {
+ if (!s.isMe()) {
if (process.platform == 'win32') { s.close(); }
sendConsoleText('Self Update cannot continue, this agent is not an instance of (' + name + ')', sessionid);
return;
}
if (process.platform == 'win32') { s.close(); }
}
- catch (zz)
- {
+ catch (zz) {
sendConsoleText('Self Update Failed because this agent is not an instance of (' + name + ')', sessionid);
sendAgentMessage('Self Update Failed because this agent is not an instance of (' + name + ')', 3);
return;
@@ -238,65 +265,47 @@ function agentUpdate_Start(updateurl, updateoptions)
options.protocol = 'https:';
if (updateurl == null) { options.path = ('/meshagents?id=' + require('MeshAgent').ARCHID); }
options.rejectUnauthorized = false;
- options.checkServerIdentity = function checkServerIdentity(certs)
- {
+ options.checkServerIdentity = function checkServerIdentity(certs) {
// If the tunnel certificate matches the control channel certificate, accept the connection
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.digest == certs[0].digest) return; } catch (ex) { }
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.fingerprint == certs[0].fingerprint) return; } catch (ex) { }
// Check that the certificate is the one expected by the server, fail if not.
- sendConsoleText('hashx: ' + checkServerIdentity.servertlshash);
if (checkServerIdentity.servertlshash == null) {
- sendConsoleText('1a');
if (require('MeshAgent').ServerInfo == null || require('MeshAgent').ServerInfo.ControlChannelCertificate == null) { return; }
- sendConsoleText('1b');
sendConsoleText('Self Update failed, because the url cannot be verified', sessionid);
sendAgentMessage('Self Update failed, because the url cannot be verified', 3);
throw new Error('BadCert');
}
- sendConsoleText('2t: ' + checkServerIdentity.servertlshash);
- sendConsoleText('2y: ' + checkServerIdentity.servertlshash.toLowerCase());
- sendConsoleText('2z: ' + certs[0].digest);
- sendConsoleText('2r: ' + certs[0].fingerprint);
+ if (certs[0].digest == null) { return; }
if ((checkServerIdentity.servertlshash != null) && (checkServerIdentity.servertlshash.toLowerCase() != certs[0].digest.split(':').join('').toLowerCase())) {
- sendConsoleText('2b');
sendConsoleText('Self Update failed, because the supplied certificate does not match', sessionid);
sendAgentMessage('Self Update failed, because the supplied certificate does not match', 3);
throw new Error('BadCert')
}
- sendConsoleText('3');
}
options.checkServerIdentity.servertlshash = (updateoptions != null ? updateoptions.tlshash : null);
- sendConsoleText('Downloading1: ' + JSON.stringify(options));
- sendConsoleText('Downloading2: ' + JSON.stringify(updateoptions));
this._selfupdate = require('https').get(options);
- this._selfupdate.on('error', function (e)
- {
+ this._selfupdate.on('error', function (e) {
sendConsoleText('Self Update failed, because there was a problem trying to download the update', sessionid);
sendAgentMessage('Self Update failed, because there was a problem trying to download the update', 3);
});
- this._selfupdate.on('response', function (img)
- {
+ this._selfupdate.on('response', function (img) {
this._file = require('fs').createWriteStream(agentfilename + '.update', { flags: 'wb' });
this._filehash = require('SHA384Stream').create();
- this._filehash.on('hash', function (h)
- {
- if (updateoptions != null && updateoptions.hash != null)
- {
- if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase())
- {
+ this._filehash.on('hash', function (h) {
+ if (updateoptions != null && updateoptions.hash != null) {
+ if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase()) {
if (sessionid != null) { sendConsoleText('Download complete. HASH verified.', sessionid); }
}
- else
- {
+ else {
sendConsoleText('Self Update FAILED because the downloaded agent FAILED hash check', sessionid);
sendAgentMessage('Self Update FAILED because the downloaded agent FAILED hash check', 3);
return;
}
}
- else
- {
+ else {
sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid);
}
@@ -304,13 +313,11 @@ function agentUpdate_Start(updateurl, updateoptions)
try { require('MeshAgent').SendCommand({ action: 'agentupdatedownloaded' }); } catch (e) { }
if (sessionid != null) { sendConsoleText('Updating and restarting agent...', sessionid); }
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
// Use _wexecve() equivalent to perform the update
windows_execve(name, agentfilename, sessionid);
}
- else
- {
+ else {
var m = require('fs').statSync(process.execPath).mode;
require('fs').chmodSync(process.cwd() + agentfilename + '.update', m);
@@ -324,24 +331,24 @@ function agentUpdate_Start(updateurl, updateoptions)
// erase update
require('fs').unlinkSync(process.cwd() + agentfilename + '.update');
- if (sessionid != null) { sendConsoleText('Restarting service...', sessionid); }
- if (process.platform == 'freebsd')
- {
- bsd_execv(name, agentfilename, sessionid);
- }
- else
- {
- try
- {
- // restart service
- var s = require('service-manager').manager.getService(name);
- s.restart();
- }
- catch (zz)
- {
- sendConsoleText('Self Update encountered an error trying to restart service', sessionid);
- sendAgentMessage('Self Update encountered an error trying to restart service', 3);
- }
+ switch (process.platform) {
+ case 'freebsd':
+ bsd_execv(name, agentfilename, sessionid);
+ break;
+ case 'linux':
+ linux_execv(name, agentfilename, sessionid);
+ break;
+ default:
+ try {
+ // restart service
+ var s = require('service-manager').manager.getService(name);
+ s.restart();
+ }
+ catch (zz) {
+ sendConsoleText('Self Update encountered an error trying to restart service', sessionid);
+ sendAgentMessage('Self Update encountered an error trying to restart service', 3);
+ }
+ break;
}
}
});
@@ -396,18 +403,14 @@ function splitArgs(str) {
}
// Parse arguments string array into an object
-function parseArgs(argv)
-{
+function parseArgs(argv) {
var results = { '_': [] }, current = null;
- for (var i = 1, len = argv.length; i < len; i++)
- {
+ for (var i = 1, len = argv.length; i < len; i++) {
var x = argv[i];
- if (x.length > 2 && x[0] == '-' && x[1] == '-')
- {
+ if (x.length > 2 && x[0] == '-' && x[1] == '-') {
if (current != null) { results[current] = true; }
current = x.substring(2);
- } else
- {
+ } else {
if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); }
}
}
@@ -440,8 +443,7 @@ require('MeshAgent').on('Connected', function () {
});
// Called when receiving control data on websocket
-function onTunnelControlData(data, ws)
-{
+function onTunnelControlData(data, ws) {
var obj;
if (ws == null) { ws = this; }
if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON: ' + data); return; } }
@@ -449,16 +451,12 @@ function onTunnelControlData(data, ws)
//sendConsoleText('onTunnelControlData(' + ws.httprequest.protocol + '): ' + JSON.stringify(data));
//console.log('onTunnelControlData: ' + JSON.stringify(data));
- if (obj.action)
- {
- switch (obj.action)
- {
+ if (obj.action) {
+ switch (obj.action) {
case 'lock': {
// Lock the current user out of the desktop
- try
- {
- if (process.platform == 'win32')
- {
+ try {
+ if (process.platform == 'win32') {
MeshServerLog("Locking remote user out of desktop", ws.httprequest);
var child = require('child_process');
child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 });
@@ -473,8 +471,7 @@ function onTunnelControlData(data, ws)
return;
}
- switch (obj.type)
- {
+ switch (obj.type) {
case 'options': {
// These are additional connection options passed in the control channel.
//sendConsoleText('options: ' + JSON.stringify(obj));
@@ -494,13 +491,11 @@ function onTunnelControlData(data, ws)
}
case 'termsize': {
// Indicates a change in terminal size
- if (process.platform == 'win32')
- {
+ if (process.platform == 'win32') {
if (ws.httprequest._dispatcher == null) return;
if (ws.httprequest._dispatcher.invoke) { ws.httprequest._dispatcher.invoke('resizeTerminal', [obj.cols, obj.rows]); }
}
- else
- {
+ else {
if (ws.httprequest.process == null || ws.httprequest.process.pty == 0) return;
if (ws.httprequest.process.tcsetsize) { ws.httprequest.process.tcsetsize(obj.rows, obj.cols); }
}
@@ -510,23 +505,18 @@ function onTunnelControlData(data, ws)
}
-require('MeshAgent').AddCommandHandler(function (data)
-{
- if (typeof data == 'object')
- {
+require('MeshAgent').AddCommandHandler(function (data) {
+ if (typeof data == 'object') {
// If this is a console command, parse it and call the console handler
- switch (data.action)
- {
+ switch (data.action) {
case 'agentupdate':
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash, sessionid: data.sessionid });
break;
case 'msg':
{
- switch (data.type)
- {
+ switch (data.type) {
case 'console': { // Process a console command
- if (data.value && data.sessionid)
- {
+ if (data.value && data.sessionid) {
var args = splitArgs(data.value);
processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
}
@@ -534,23 +524,19 @@ require('MeshAgent').AddCommandHandler(function (data)
}
case 'tunnel':
{
- if (data.value != null)
- { // Process a new tunnel connection request
+ if (data.value != null) { // Process a new tunnel connection request
// Create a new tunnel object
- if (data.rights != 4294967295)
- {
+ if (data.rights != 4294967295) {
MeshServerLog('Tunnel Error: RecoveryCore requires admin rights for tunnels');
break;
}
var xurl = getServerTargetUrlEx(data.value);
- if (xurl != null)
- {
+ if (xurl != null) {
var woptions = http.parseUri(xurl);
woptions.rejectUnauthorized = 0;
woptions.perMessageDeflate = false;
- woptions.checkServerIdentity = function checkServerIdentity(certs)
- {
+ woptions.checkServerIdentity = function checkServerIdentity(certs) {
// If the tunnel certificate matches the control channel certificate, accept the connection
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.digest == certs[0].digest) return; } catch (ex) { }
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.fingerprint == certs[0].fingerprint) return; } catch (ex) { }
@@ -563,13 +549,10 @@ require('MeshAgent').AddCommandHandler(function (data)
//sendConsoleText(JSON.stringify(woptions));
var tunnel = http.request(woptions);
- tunnel.on('upgrade', function (response, s, head)
- {
- if (require('MeshAgent').idleTimeout != null)
- {
+ tunnel.on('upgrade', function (response, s, head) {
+ if (require('MeshAgent').idleTimeout != null) {
s.setTimeout(require('MeshAgent').idleTimeout * 1000);
- s.on('timeout', function ()
- {
+ s.on('timeout', function () {
this.ping();
this.setTimeout(require('MeshAgent').idleTimeout * 1000);
});
@@ -578,8 +561,7 @@ require('MeshAgent').AddCommandHandler(function (data)
this.s = s;
s.httprequest = this;
s.tunnel = this;
- s.on('end', function ()
- {
+ s.on('end', function () {
if (tunnels[this.httprequest.index] == null) return; // Stop duplicate calls.
// If there is a upload or download active on this connection, close the file
@@ -592,18 +574,14 @@ require('MeshAgent').AddCommandHandler(function (data)
// Clean up WebSocket
this.removeAllListeners('data');
});
- s.on('data', function (data)
- {
+ s.on('data', function (data) {
// If this is upload data, save it to file
- if ((this.httprequest.uploadFile) && (typeof data == 'object') && (data[0] != 123))
- {
+ if ((this.httprequest.uploadFile) && (typeof data == 'object') && (data[0] != 123)) {
// Save the data to file being uploaded.
- if (data[0] == 0)
- {
+ if (data[0] == 0) {
// If data starts with zero, skip the first byte. This is used to escape binary file data from JSON.
try { fs.writeSync(this.httprequest.uploadFile, data, 1, data.length - 1); } catch (e) { sendConsoleText('FileUpload Error'); this.write(Buffer.from(JSON.stringify({ action: 'uploaderror' }))); return; } // Write to the file, if there is a problem, error out.
- } else
- {
+ } else {
// If data does not start with zero, save as-is.
try { fs.writeSync(this.httprequest.uploadFile, data); } catch (e) { sendConsoleText('FileUpload Error'); this.write(Buffer.from(JSON.stringify({ action: 'uploaderror' }))); return; } // Write to the file, if there is a problem, error out.
}
@@ -611,22 +589,18 @@ require('MeshAgent').AddCommandHandler(function (data)
return;
}
- if (this.httprequest.state == 0)
- {
+ if (this.httprequest.state == 0) {
// Check if this is a relay connection
if ((data == 'c') || (data == 'cr')) { this.httprequest.state = 1; /*sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid);*/ }
}
- else
- {
+ else {
// Handle tunnel data
- if (this.httprequest.protocol == 0)
- { // 1 = Terminal (admin), 2 = Desktop, 5 = Files, 6 = PowerShell (admin), 7 = Plugin Data Exchange, 8 = Terminal (user), 9 = PowerShell (user), 10 = FileTransfer
+ if (this.httprequest.protocol == 0) { // 1 = Terminal (admin), 2 = Desktop, 5 = Files, 6 = PowerShell (admin), 7 = Plugin Data Exchange, 8 = Terminal (user), 9 = PowerShell (user), 10 = FileTransfer
// Take a look at the protocol
if ((data.length > 3) && (data[0] == '{')) { onTunnelControlData(data, this); return; }
this.httprequest.protocol = parseInt(data);
if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; }
- if (this.httprequest.protocol == 10)
- {
+ if (this.httprequest.protocol == 10) {
//
// Basic file transfer
//
@@ -634,50 +608,42 @@ require('MeshAgent').AddCommandHandler(function (data)
if ((process.platform != 'win32') && (this.httprequest.xoptions.file.startsWith('/') == false)) { this.httprequest.xoptions.file = '/' + this.httprequest.xoptions.file; }
try { stats = require('fs').statSync(this.httprequest.xoptions.file) } catch (e) { }
try { if (stats) { this.httprequest.downloadFile = fs.createReadStream(this.httprequest.xoptions.file, { flags: 'rbN' }); } } catch (e) { }
- if (this.httprequest.downloadFile)
- {
+ if (this.httprequest.downloadFile) {
//sendConsoleText('BasicFileTransfer, ok, ' + this.httprequest.xoptions.file + ', ' + JSON.stringify(stats));
this.write(JSON.stringify({ op: 'ok', size: stats.size }));
this.httprequest.downloadFile.pipe(this);
this.httprequest.downloadFile.end = function () { }
- } else
- {
+ } else {
//sendConsoleText('BasicFileTransfer, cancel, ' + this.httprequest.xoptions.file);
this.write(JSON.stringify({ op: 'cancel' }));
}
}
- else if ((this.httprequest.protocol == 1) || (this.httprequest.protocol == 6) || (this.httprequest.protocol == 8) || (this.httprequest.protocol == 9))
- {
+ else if ((this.httprequest.protocol == 1) || (this.httprequest.protocol == 6) || (this.httprequest.protocol == 8) || (this.httprequest.protocol == 9)) {
//
// Remote Terminal
//
- if (process.platform == "win32")
- {
+ if (process.platform == "win32") {
var cols = 80, rows = 25;
- if (this.httprequest.xoptions)
- {
+ if (this.httprequest.xoptions) {
if (this.httprequest.xoptions.rows) { rows = this.httprequest.xoptions.rows; }
if (this.httprequest.xoptions.cols) { cols = this.httprequest.xoptions.cols; }
}
// Admin Terminal
- if (require('win-virtual-terminal').supported)
- {
+ if (require('win-virtual-terminal').supported) {
// ConPTY PseudoTerminal
// this.httprequest._term = require('win-virtual-terminal')[this.httprequest.protocol == 6 ? 'StartPowerShell' : 'Start'](80, 25);
// The above line is commented out, because there is a bug with ClosePseudoConsole() API, so this is the workaround
this.httprequest._dispatcher = require('win-dispatcher').dispatch({ modules: [{ name: 'win-virtual-terminal', script: getJSModule('win-virtual-terminal') }], launch: { module: 'win-virtual-terminal', method: 'Start', args: [cols, rows] } });
this.httprequest._dispatcher.ws = this;
- this.httprequest._dispatcher.on('connection', function (c)
- {
+ this.httprequest._dispatcher.on('connection', function (c) {
this.ws._term = c;
c.pipe(this.ws, { dataTypeSkip: 1 });
this.ws.pipe(c, { dataTypeSkip: 1 });
});
}
- else
- {
+ else {
// Legacy Terminal
this.httprequest._term = require('win-terminal').Start(80, 25);
this.httprequest._term.pipe(this, { dataTypeSkip: 1 });
@@ -685,22 +651,18 @@ require('MeshAgent').AddCommandHandler(function (data)
this.prependListener('end', function () { this.httprequest._term.end(function () { sendConsoleText('Terminal was closed'); }); });
}
}
- else
- {
+ else {
var env = { HISTCONTROL: 'ignoreboth' };
- if (this.httprequest.xoptions)
- {
+ if (this.httprequest.xoptions) {
if (this.httprequest.xoptions.rows) { env.LINES = ('' + this.httprequest.xoptions.rows); }
if (this.httprequest.xoptions.cols) { env.COLUMNS = ('' + this.httprequest.xoptions.cols); }
}
var options = { type: childProcess.SpawnTypes.TERM, env: env };
- if (require('fs').existsSync('/bin/bash'))
- {
+ if (require('fs').existsSync('/bin/bash')) {
this.httprequest.process = childProcess.execFile('/bin/bash', ['bash'], options); // Start bash
}
- else
- {
+ else {
this.httprequest.process = childProcess.execFile('/bin/sh', ['sh'], options); // Start sh
}
@@ -715,8 +677,7 @@ require('MeshAgent').AddCommandHandler(function (data)
}
}
}
- else if (this.httprequest.protocol == 5)
- {
+ else if (this.httprequest.protocol == 5) {
// Process files commands
var cmd = null;
try { cmd = JSON.parse(data); } catch (e) { };
@@ -729,8 +690,7 @@ require('MeshAgent').AddCommandHandler(function (data)
if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
//console.log(objToString(cmd, 0, ' '));
- switch (cmd.action)
- {
+ switch (cmd.action) {
case 'ls':
// Send the folder content to the browser
var response = getDirectoryInfo(cmd.path);
@@ -746,8 +706,7 @@ require('MeshAgent').AddCommandHandler(function (data)
case 'rm':
{
// Delete, possibly recursive delete
- for (var i in cmd.delfiles)
- {
+ for (var i in cmd.delfiles) {
try { deleteFolderRecursive(path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { }
}
break;
@@ -782,15 +741,11 @@ require('MeshAgent').AddCommandHandler(function (data)
{
// Download a file
var sendNextBlock = 0;
- if (cmd.sub == 'start')
- { // Setup the download
- if ((cmd.path == null) && (cmd.ask == 'coredump'))
- { // If we are asking for the coredump file, set the right path.
- if (process.platform == 'win32')
- {
+ if (cmd.sub == 'start') { // Setup the download
+ if ((cmd.path == null) && (cmd.ask == 'coredump')) { // If we are asking for the coredump file, set the right path.
+ if (process.platform == 'win32') {
if (fs.existsSync(process.coreDumpLocation)) { cmd.path = process.coreDumpLocation; }
- } else
- {
+ } else {
if ((process.cwd() != '//') && fs.existsSync(process.cwd() + 'core')) { cmd.path = process.cwd() + 'core'; }
}
}
@@ -799,13 +754,11 @@ require('MeshAgent').AddCommandHandler(function (data)
this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
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; }
if (this.filedownload) { this.write({ action: 'download', sub: 'start', id: cmd.id }); }
- } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id))
- { // Download commands
+ } else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
if (cmd.sub == 'startack') { sendNextBlock = ((typeof cmd.ack == 'number') ? cmd.ack : 8); } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
}
// Send the next download block(s)
- while (sendNextBlock > 0)
- {
+ while (sendNextBlock > 0) {
sendNextBlock--;
var buf = Buffer.alloc(16384);
var len = fs.readSync(this.filedownload.f, buf, 4, 16380, null);
@@ -831,8 +784,7 @@ require('MeshAgent').AddCommandHandler(function (data)
case 'uploaddone':
{
// Indicates that an upload is done
- if (this.httprequest.uploadFile)
- {
+ if (this.httprequest.uploadFile) {
fs.closeSync(this.httprequest.uploadFile);
this.write(Buffer.from(JSON.stringify({ action: 'uploaddone', reqid: this.httprequest.uploadFileid }))); // Indicate that we closed the file.
delete this.httprequest.uploadFile;
@@ -844,8 +796,7 @@ require('MeshAgent').AddCommandHandler(function (data)
case 'uploadcancel':
{
// Indicates that an upload is canceled
- if (this.httprequest.uploadFile)
- {
+ if (this.httprequest.uploadFile) {
fs.closeSync(this.httprequest.uploadFile);
fs.unlinkSync(this.httprequest.uploadFilePath);
this.write(Buffer.from(JSON.stringify({ action: 'uploadcancel', reqid: this.httprequest.uploadFileid }))); // Indicate that we closed the file.
@@ -857,8 +808,7 @@ require('MeshAgent').AddCommandHandler(function (data)
}
case 'copy': {
// Copy a bunch of files from scpath to dspath
- for (var i in cmd.names)
- {
+ for (var i in cmd.names) {
var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
}
@@ -866,8 +816,7 @@ require('MeshAgent').AddCommandHandler(function (data)
}
case 'move': {
// Move a bunch of files from scpath to dspath
- for (var i in cmd.names)
- {
+ for (var i in cmd.names) {
var sc = path.join(cmd.scpath, cmd.names[i]), ds = path.join(cmd.dspath, cmd.names[i]);
if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
}
@@ -931,11 +880,9 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
break;
case 'eval':
{ // Eval JavaScript
- if (args['_'].length < 1)
- {
+ if (args['_'].length < 1) {
response = 'Proper usage: eval "JavaScript code"'; // Display correct command usage
- } else
- {
+ } else {
response = JSON.stringify(require('MeshAgent').eval(args['_'][0])); // This can only be run by trusted administrator.
}
break;
@@ -949,12 +896,10 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
case 'osinfo': { // Return the operating system information
var i = 1;
if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; }
- for (var j = 0; j < i; j++)
- {
+ for (var j = 0; j < i; j++) {
var pr = require('os').name();
pr.sessionid = sessionid;
- pr.then(function (v)
- {
+ pr.then(function (v) {
sendConsoleText("OS: " + v + (process.platform == 'win32' ? (require('win-virtual-terminal').supported ? ' [ConPTY: YES]' : ' [ConPTY: NO]') : ''), this.sessionid);
});
}