diff --git a/MeshCentralServer.njsproj b/MeshCentralServer.njsproj index f2f03f17..3c791b13 100644 --- a/MeshCentralServer.njsproj +++ b/MeshCentralServer.njsproj @@ -60,13 +60,16 @@ + + + diff --git a/agents/meshcore.js b/agents/meshcore.js index 05975e7a..d68fc305 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -822,6 +822,53 @@ function createMeshCore(agent) sendConsoleText('getScript: ' + JSON.stringify(data)); break; } + case 'sysinfo': { + // Fetch system information + if (process.platform != 'win32') break; // Remove this when Linux/MacOS support this. + try { + var results = { hardware: require('identifiers').get(), pendingReboot: require('win-info').pendingReboot() }; // Hardware & pending reboot + if (results.hardware.windows) { + var x = results.hardware.windows.osinfo; + try { delete x.FreePhysicalMemory; } catch (ex) { } + try { delete x.FreeSpaceInPagingFiles; } catch (ex) { } + try { delete x.FreeVirtualMemory; } catch (ex) { } + try { delete x.LocalDateTime; } catch (ex) { } + try { delete x.MaxProcessMemorySize; } catch (ex) { } + try { delete x.TotalVirtualMemorySize; } catch (ex) { } + try { delete x.TotalVisibleMemorySize; } catch (ex) { } + } + /* + if (process.platform == 'win32') + { + var defragResult = function (r) + { + if (typeof r == 'object') { results[this.callname] = r; } + if (this.callname == 'defrag') + { + var pr = require('win-info').installedApps(); // Installed apps + pr.callname = 'installedApps'; + pr.sessionid = data.sessionid; + pr.then(defragResult, defragResult); + } + else + { + results.winpatches = require('win-info').qfe(); // Windows patches + results.hash = require('SHA384Stream').create().syncHash(JSON.stringify(results)).toString('hex'); + if (data.hash != results.hash) { mesh.SendCommand({ "action": "sysinfo", "sessionid": this.sessionid, "data": results }); } + } + } + var pr = require('win-info').defrag({ volume: 'C:' }); // Defrag + pr.callname = 'defrag'; + pr.sessionid = data.sessionid; + pr.then(defragResult, defragResult); + } else { + */ + results.hash = require('SHA384Stream').create().syncHash(JSON.stringify(results)).toString('hex'); + if (data.hash != results.hash) { mesh.SendCommand({ "action": "sysinfo", "sessionid": this.sessionid, "data": results }); } + //} + } catch (ex) { } + break; + } case 'ping': { mesh.SendCommand('{"action":"pong"}'); break; } case 'pong': { break; } default: @@ -1603,7 +1650,7 @@ function createMeshCore(agent) var response = null; switch (cmd) { case 'help': { // Displays available commands - response = 'Available commands: help, info, osinfo, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl, amtreset, amtccm, amtacm,\r\namtdeactivate, amtpolicy, getscript, getclip, setclip, log, av.'; + response = 'Available commands: help, info, osinfo, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl, amtreset, amtccm, amtacm,\r\namtdeactivate, amtpolicy, getscript, getclip, setclip, log, av, cpuinfo, sysinfo.'; break; } /* @@ -1626,7 +1673,11 @@ function createMeshCore(agent) break; */ case 'av': - if (process.platform == 'win32') { response = JSON.stringify(require('win-info').av()); } else { response = 'Not supported on the platform'; } + if (process.platform == 'win32') { + response = JSON.stringify(require('win-info').av(), null, 1); + } else { + response = 'Not supported on the platform'; + } break; case 'log': if (args['_'].length != 1) { response = 'Proper usage: log "sample text"'; } else { MeshServerLog(args['_'][0]); response = 'ok'; } @@ -1763,6 +1814,41 @@ function createMeshCore(agent) } break; } + case 'cpuinfo': { // Return system information + // CPU & memory utilization + pr = require('sysinfo').cpuUtilization(); + pr.sessionid = sessionid; + pr.then(function (data) { + sendConsoleText(JSON.stringify({ cpu: data, memory: require('sysinfo').memUtilization() }, null, 1), this.sessionid); + }, function (e) { + sendConsoleText(e); + }); + break; + } + case 'sysinfo': { // Return system information + var results = { hardware: require('identifiers').get(), pendingReboot: require('win-info').pendingReboot() }; // Hardware && pending reboot + if (process.platform == 'win32') { + var defragResult = function (r) { + if (typeof r == 'object') { results[this.callname] = r; } + if (this.callname == 'defrag') { + var pr = require('win-info').installedApps(); // Installed apps + pr.sessionid = sessionid; + pr.callname = 'installedApps'; + pr.then(defragResult, defragResult); + } else { + results.winpatches = require('win-info').qfe(); // Windows patches + sendConsoleText(JSON.stringify(results, null, 1), this.sessionid); + } + } + var pr = require('win-info').defrag({ volume: 'C:' }); // Defrag + pr.sessionid = sessionid; + pr.callname = 'defrag'; + pr.then(defragResult, defragResult); + } else { + response = JSON.stringify(results, null, 1); + } + break; + } case 'info': { // Return information about the agent and agent core module response = 'Current Core: ' + meshCoreObj.value + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform: ' + process.platform + '.\r\nCapabilities: ' + meshCoreObj.caps + '.\r\nServer URL: ' + mesh.ServerUrl + '.'; if (amt != null) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amt.lmsstate] + '.'; } @@ -2241,8 +2327,9 @@ function createMeshCore(agent) if ((flags & 4) && (process.platform == 'win32')) { // Update anti-virus information - var av; - try { av = require('win-info').av(); } catch (ex) { av = []; } + var av, pr; + try { av = require('win-info').av(); } catch (ex) { av = []; } // Antivirus + //if (process.platform == 'win32') { try { pr = require('win-info').pendingReboot(); } catch (ex) { pr = null; } } // Pending reboot if ((meshCoreObj.av == null) || (JSON.stringify(meshCoreObj.av) != JSON.stringify(av))) { meshCoreObj.av = av; mesh.SendCommand(meshCoreObj); } } } diff --git a/agents/meshcore.min.js b/agents/meshcore.min.js index 05975e7a..d68fc305 100644 --- a/agents/meshcore.min.js +++ b/agents/meshcore.min.js @@ -822,6 +822,53 @@ function createMeshCore(agent) sendConsoleText('getScript: ' + JSON.stringify(data)); break; } + case 'sysinfo': { + // Fetch system information + if (process.platform != 'win32') break; // Remove this when Linux/MacOS support this. + try { + var results = { hardware: require('identifiers').get(), pendingReboot: require('win-info').pendingReboot() }; // Hardware & pending reboot + if (results.hardware.windows) { + var x = results.hardware.windows.osinfo; + try { delete x.FreePhysicalMemory; } catch (ex) { } + try { delete x.FreeSpaceInPagingFiles; } catch (ex) { } + try { delete x.FreeVirtualMemory; } catch (ex) { } + try { delete x.LocalDateTime; } catch (ex) { } + try { delete x.MaxProcessMemorySize; } catch (ex) { } + try { delete x.TotalVirtualMemorySize; } catch (ex) { } + try { delete x.TotalVisibleMemorySize; } catch (ex) { } + } + /* + if (process.platform == 'win32') + { + var defragResult = function (r) + { + if (typeof r == 'object') { results[this.callname] = r; } + if (this.callname == 'defrag') + { + var pr = require('win-info').installedApps(); // Installed apps + pr.callname = 'installedApps'; + pr.sessionid = data.sessionid; + pr.then(defragResult, defragResult); + } + else + { + results.winpatches = require('win-info').qfe(); // Windows patches + results.hash = require('SHA384Stream').create().syncHash(JSON.stringify(results)).toString('hex'); + if (data.hash != results.hash) { mesh.SendCommand({ "action": "sysinfo", "sessionid": this.sessionid, "data": results }); } + } + } + var pr = require('win-info').defrag({ volume: 'C:' }); // Defrag + pr.callname = 'defrag'; + pr.sessionid = data.sessionid; + pr.then(defragResult, defragResult); + } else { + */ + results.hash = require('SHA384Stream').create().syncHash(JSON.stringify(results)).toString('hex'); + if (data.hash != results.hash) { mesh.SendCommand({ "action": "sysinfo", "sessionid": this.sessionid, "data": results }); } + //} + } catch (ex) { } + break; + } case 'ping': { mesh.SendCommand('{"action":"pong"}'); break; } case 'pong': { break; } default: @@ -1603,7 +1650,7 @@ function createMeshCore(agent) var response = null; switch (cmd) { case 'help': { // Displays available commands - response = 'Available commands: help, info, osinfo, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl, amtreset, amtccm, amtacm,\r\namtdeactivate, amtpolicy, getscript, getclip, setclip, log, av.'; + response = 'Available commands: help, info, osinfo, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl, amtreset, amtccm, amtacm,\r\namtdeactivate, amtpolicy, getscript, getclip, setclip, log, av, cpuinfo, sysinfo.'; break; } /* @@ -1626,7 +1673,11 @@ function createMeshCore(agent) break; */ case 'av': - if (process.platform == 'win32') { response = JSON.stringify(require('win-info').av()); } else { response = 'Not supported on the platform'; } + if (process.platform == 'win32') { + response = JSON.stringify(require('win-info').av(), null, 1); + } else { + response = 'Not supported on the platform'; + } break; case 'log': if (args['_'].length != 1) { response = 'Proper usage: log "sample text"'; } else { MeshServerLog(args['_'][0]); response = 'ok'; } @@ -1763,6 +1814,41 @@ function createMeshCore(agent) } break; } + case 'cpuinfo': { // Return system information + // CPU & memory utilization + pr = require('sysinfo').cpuUtilization(); + pr.sessionid = sessionid; + pr.then(function (data) { + sendConsoleText(JSON.stringify({ cpu: data, memory: require('sysinfo').memUtilization() }, null, 1), this.sessionid); + }, function (e) { + sendConsoleText(e); + }); + break; + } + case 'sysinfo': { // Return system information + var results = { hardware: require('identifiers').get(), pendingReboot: require('win-info').pendingReboot() }; // Hardware && pending reboot + if (process.platform == 'win32') { + var defragResult = function (r) { + if (typeof r == 'object') { results[this.callname] = r; } + if (this.callname == 'defrag') { + var pr = require('win-info').installedApps(); // Installed apps + pr.sessionid = sessionid; + pr.callname = 'installedApps'; + pr.then(defragResult, defragResult); + } else { + results.winpatches = require('win-info').qfe(); // Windows patches + sendConsoleText(JSON.stringify(results, null, 1), this.sessionid); + } + } + var pr = require('win-info').defrag({ volume: 'C:' }); // Defrag + pr.sessionid = sessionid; + pr.callname = 'defrag'; + pr.then(defragResult, defragResult); + } else { + response = JSON.stringify(results, null, 1); + } + break; + } case 'info': { // Return information about the agent and agent core module response = 'Current Core: ' + meshCoreObj.value + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform: ' + process.platform + '.\r\nCapabilities: ' + meshCoreObj.caps + '.\r\nServer URL: ' + mesh.ServerUrl + '.'; if (amt != null) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amt.lmsstate] + '.'; } @@ -2241,8 +2327,9 @@ function createMeshCore(agent) if ((flags & 4) && (process.platform == 'win32')) { // Update anti-virus information - var av; - try { av = require('win-info').av(); } catch (ex) { av = []; } + var av, pr; + try { av = require('win-info').av(); } catch (ex) { av = []; } // Antivirus + //if (process.platform == 'win32') { try { pr = require('win-info').pendingReboot(); } catch (ex) { pr = null; } } // Pending reboot if ((meshCoreObj.av == null) || (JSON.stringify(meshCoreObj.av) != JSON.stringify(av))) { meshCoreObj.av = av; mesh.SendCommand(meshCoreObj); } } } diff --git a/agents/modules_meshcmd/identifiers.js b/agents/modules_meshcmd/identifiers.js new file mode 100644 index 00000000..b0fdb6c2 --- /dev/null +++ b/agents/modules_meshcmd/identifiers.js @@ -0,0 +1,208 @@ +/* +Copyright 2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +function trimIdentifiers(val) +{ + for(var v in val) + { + if (!val[v] || val[v] == 'None' || val[v] == '') { delete val[v]; } + } +} + +function linux_identifiers() +{ + var identifiers = {}; + var ret = {}; + var values = {}; + if (!require('fs').existsSync('/sys/class/dmi/id')) { throw ('this platform does not have DMI statistics'); } + var entries = require('fs').readdirSync('/sys/class/dmi/id'); + for(var i in entries) + { + if (require('fs').statSync('/sys/class/dmi/id/' + entries[i]).isFile()) + { + ret[entries[i]] = require('fs').readFileSync('/sys/class/dmi/id/' + entries[i]).toString().trim(); + + if (ret[entries[i]] == 'None') { delete ret[entries[i]];} + } + } + identifiers['bios_date'] = ret['bios_date']; + identifiers['bios_vendor'] = ret['bios_vendor']; + identifiers['bios_version'] = ret['bios_version']; + identifiers['board_name'] = ret['board_name']; + identifiers['board_serial'] = ret['board_serial']; + identifiers['board_vendor'] = ret['board_vendor']; + identifiers['board_version'] = ret['board_version']; + identifiers['product_uuid'] = ret['product_uuid']; + + values.identifiers = identifiers; + values.linux = ret; + trimIdentifiers(values.identifiers); + return (values); +} + +function windows_wmic_results(str) +{ + var lines = str.trim().split('\r\n'); + var keys = lines[0].split(','); + var i, key, keyval; + var tokens; + var result = []; + + for (i = 1; i < lines.length; ++i) + { + var obj = {}; + tokens = lines[i].split(','); + for (key = 0; key < keys.length; ++key) + { + if (tokens[key].trim()) + { + obj[keys[key].trim()] = tokens[key].trim(); + } + } + result.push(obj); + } + return (result); +} + + +function windows_identifiers() +{ + var ret = { windows: {}}; values = {}; var items; var i; var item; + var child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'bios', 'get', '/VALUE']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + + var items = child.stdout.str.split('\r\r\n'); + for(i in items) + { + item = items[i].split('='); + values[item[0]] = item[1]; + } + + ret['identifiers'] = {}; + ret['identifiers']['bios_date'] = values['ReleaseDate']; + ret['identifiers']['bios_vendor'] = values['Manufacturer']; + ret['identifiers']['bios_version'] = values['SMBIOSBIOSVersion']; + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'BASEBOARD', 'get', '/VALUE']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + + var items = child.stdout.str.split('\r\r\n'); + for (i in items) + { + item = items[i].split('='); + values[item[0]] = item[1]; + } + ret['identifiers']['board_name'] = values['Product']; + ret['identifiers']['board_serial'] = values['SerialNumber']; + ret['identifiers']['board_vendor'] = values['Manufacturer']; + ret['identifiers']['board_version'] = values['Version']; + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'CSProduct', 'get', '/VALUE']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + + var items = child.stdout.str.split('\r\r\n'); + for (i in items) + { + item = items[i].split('='); + values[item[0]] = item[1]; + } + ret['identifiers']['product_uuid'] = values['UUID']; + trimIdentifiers(ret.identifiers); + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'MEMORYCHIP', 'LIST', '/FORMAT:CSV']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + ret.windows.memory = windows_wmic_results(child.stdout.str); + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'OS', 'GET', '/FORMAT:CSV']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + ret.windows.osinfo = windows_wmic_results(child.stdout.str)[0]; + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'PARTITION', 'LIST', '/FORMAT:CSV']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + ret.windows.partitions = windows_wmic_results(child.stdout.str); + + return (ret); +} +function macos_identifiers() +{ + var ret = { identifiers: {} }; + var child; + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep board-id | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.board_name = child.stdout.str.trim(); + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep IOPlatformSerialNumber | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.board_serial = child.stdout.str.trim(); + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep manufacturer | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.board_vendor = child.stdout.str.trim(); + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep version | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.board_version = child.stdout.str.trim(); + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep IOPlatformUUID | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.product_uuid = child.stdout.str.trim(); + + trimIdentifiers(ret.identifiers); + return (ret); +} + +switch(process.platform) +{ + case 'linux': + module.exports = { _ObjectID: 'identifiers', get: linux_identifiers }; + break; + case 'win32': + module.exports = { _ObjectID: 'identifiers', get: windows_identifiers }; + break; + case 'darwin': + module.exports = { _ObjectID: 'identifiers', get: macos_identifiers }; + break; + default: + module.exports = { get: function () { throw ('Unsupported Platform'); } }; + break; +} + + +// bios_date = BIOS->ReleaseDate +// bios_vendor = BIOS->Manufacturer +// bios_version = BIOS->SMBIOSBIOSVersion +// board_name = BASEBOARD->Product = ioreg/board-id +// board_serial = BASEBOARD->SerialNumber = ioreg/serial-number | ioreg/IOPlatformSerialNumber +// board_vendor = BASEBOARD->Manufacturer = ioreg/manufacturer +// board_version = BASEBOARD->Version + diff --git a/agents/modules_meshcmd/sysinfo.js b/agents/modules_meshcmd/sysinfo.js new file mode 100644 index 00000000..5b73b4fb --- /dev/null +++ b/agents/modules_meshcmd/sysinfo.js @@ -0,0 +1,230 @@ +/* +Copyright 2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +const PDH_FMT_LONG = 0x00000100; +const PDH_FMT_DOUBLE = 0x00000200; + +var promise = require('promise'); +if (process.platform == 'win32') +{ + var GM = require('_GenericMarshal'); + GM.kernel32 = GM.CreateNativeProxy('kernel32.dll'); + GM.kernel32.CreateMethod('GlobalMemoryStatusEx'); + + GM.pdh = GM.CreateNativeProxy('pdh.dll'); + GM.pdh.CreateMethod('PdhAddEnglishCounterA'); + GM.pdh.CreateMethod('PdhCloseQuery'); + GM.pdh.CreateMethod('PdhCollectQueryData'); + GM.pdh.CreateMethod('PdhGetFormattedCounterValue'); + GM.pdh.CreateMethod('PdhGetFormattedCounterArrayA'); + GM.pdh.CreateMethod('PdhOpenQueryA'); + GM.pdh.CreateMethod('PdhRemoveCounter'); +} + +function windows_cpuUtilization() +{ + var p = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + p.counter = GM.CreateVariable(16); + p.cpu = GM.CreatePointer(); + p.cpuTotal = GM.CreatePointer(); + var err = 0; + if ((err = GM.pdh.PdhOpenQueryA(0, 0, p.cpu).Val) != 0) { p._rej(err); return; } + + // This gets the CPU Utilization for each proc + if ((err = GM.pdh.PdhAddEnglishCounterA(p.cpu.Deref(), GM.CreateVariable('\\Processor(*)\\% Processor Time'), 0, p.cpuTotal).Val) != 0) { p._rej(err); return; } + + if ((err = GM.pdh.PdhCollectQueryData(p.cpu.Deref()).Val != 0)) { p._rej(err); return; } + p._timeout = setTimeout(function (po) + { + var u = { cpus: [] }; + var bufSize = GM.CreateVariable(4); + var itemCount = GM.CreateVariable(4); + var buffer, szName, item; + var e; + if ((e = GM.pdh.PdhCollectQueryData(po.cpu.Deref()).Val != 0)) { po._rej(e); return; } + + if ((e = GM.pdh.PdhGetFormattedCounterArrayA(po.cpuTotal.Deref(), PDH_FMT_DOUBLE, bufSize, itemCount, 0).Val) == -2147481646) + { + buffer = GM.CreateVariable(bufSize.toBuffer().readUInt32LE()); + } + else + { + po._rej(e); + return; + } + if ((e = GM.pdh.PdhGetFormattedCounterArrayA(po.cpuTotal.Deref(), PDH_FMT_DOUBLE, bufSize, itemCount, buffer).Val) != 0) { po._rej(e); return; } + for(var i=0;i 0) + { + var usage = lines[0].split(':')[1]; + var bdown = usage.split(','); + + var tot = parseFloat(bdown[0].split('%')[0].trim()) + parseFloat(bdown[1].split('%')[0].trim()); + ret._res({total: tot, cpus: []}); + } + else + { + ret._rej('parse error'); + } + + return (ret); +} +function macos_memUtilization() +{ + var mem = { }; + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('top -l 1 | grep -E "^Phys"\nexit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + if (lines[0].length > 0) + { + var usage = lines[0].split(':')[1]; + var bdown = usage.split(','); + + mem.MemTotal = parseInt(bdown[0].trim().split(' ')[0]); + mem.MemFree = parseInt(bdown[1].trim().split(' ')[0]); + mem.percentFree = ((mem.MemFree / mem.MemTotal) * 100).toFixed(2); + mem.percentConsumed = (((mem.MemTotal - mem.MemFree)/ mem.MemTotal) * 100).toFixed(2); + return (mem); + } + else + { + throw ('Parse Error'); + } +} + +switch(process.platform) +{ + case 'linux': + module.exports = { cpuUtilization: linux_cpuUtilization, memUtilization: linux_memUtilization }; + break; + case 'win32': + module.exports = { cpuUtilization: windows_cpuUtilization, memUtilization: windows_memUtilization }; + break; + case 'darwin': + module.exports = { cpuUtilization: macos_cpuUtilization, memUtilization: macos_memUtilization }; + break; +} + diff --git a/agents/modules_meshcmd_min/identifiers.min.js b/agents/modules_meshcmd_min/identifiers.min.js new file mode 100644 index 00000000..b2f733af --- /dev/null +++ b/agents/modules_meshcmd_min/identifiers.min.js @@ -0,0 +1 @@ +function trimIdentifiers(b){for(var a in b){if(!b[a]||b[a]=="None"||b[a]==""){delete b[a]}}}function linux_identifiers(){var c={};var d={};var e={};if(!require("fs").existsSync("/sys/class/dmi/id")){throw ("this platform does not have DMI statistics")}var a=require("fs").readdirSync("/sys/class/dmi/id");for(var b in a){if(require("fs").statSync("/sys/class/dmi/id/"+a[b]).isFile()){d[a[b]]=require("fs").readFileSync("/sys/class/dmi/id/"+a[b]).toString().trim();if(d[a[b]]=="None"){delete d[a[b]]}}}c.bios_date=d.bios_date;c.bios_vendor=d.bios_vendor;c.bios_version=d.bios_version;c.board_name=d.board_name;c.board_serial=d.board_serial;c.board_vendor=d.board_vendor;c.board_version=d.board_version;c.product_uuid=d.product_uuid;e.identifiers=c;e.linux=d;trimIdentifiers(e.identifiers);return(e)}function windows_wmic_results(h){var e=h.trim().split("\r\n");var c=e[0].split(",");var a,b,d;var j;var g=[];for(a=1;a= 0) {printf \"%s:%s\\n\", $1, $3}' /etc/passwd\nexit\n");o.waitExit();var p=o.stdout.str.split("\n");var r={},s;for(var q in p){s=p[q].split(":");if(s[0]){r[s[0]]=s[1]}}return(r)};this._uids=function c(){var o=require("child_process").execFile("/bin/sh",["sh"]);o.stdout.str="";o.stdout.on("data",function(t){this.str+=t.toString()});o.stdin.write("awk -F: '($3 >= 0) {printf \"%s:%s\\n\", $1, $3}' /etc/passwd\nexit\n");o.waitExit();var p=o.stdout.str.split("\n");var r={},s;for(var q in p){s=p[q].split(":");if(s[0]){r[s[1]]=s[0]}}return(r)};this.Self=function m(){var q=require("promise");var o=new q(function(r,p){this.__resolver=r;this.__rejector=p;this.__child=require("child_process").execFile("/usr/bin/id",["id","-u"]);this.__child.promise=this;this.__child.stdout._txt="";this.__child.stdout.on("data",function(s){this._txt+=s.toString()});this.__child.on("exit",function(s){try{parseInt(this.stdout._txt)}catch(t){this.promise.__rejector("invalid uid");return}var u=parseInt(this.stdout._txt);this.promise.__resolver(u)})});return(o)};this.Current=function f(o){var p={};p._ObjectID="UserSession";Object.defineProperty(p,"_callback",{value:o});Object.defineProperty(p,"_child",{value:require("child_process").execFile("/usr/bin/last",["last","-f","/var/run/utmp"])});p._child.Parent=p;p._child._txt="";p._child.on("exit",function(q){var u=this._txt.split("\n");var A=[];var D={};for(var t in u){if(u[t]){var B=getTokens(u[t]);var z={Username:B[0],SessionId:B[1]};if(B[3].includes("still logged in")){z.State="Active"}else{z.LastActive=B[3]}A.push(z)}}A.pop();var C={};var y=[];for(var t in A){if(A[t].Username!="reboot"){D[A[t].SessionId]=A[t];if(C[A[t].Username]==null){C[A[t].Username]=-1}}}try{require("promise")}catch(r){Object.defineProperty(D,"Active",{value:showActiveOnly(D)});if(this.Parent._callback){this.Parent._callback.call(this.Parent,D)}return}var x=require("promise");for(var v in C){var w=new x(function(E,s){this.__username=v;this.__resolver=E;this.__rejector=s;this.__child=require("child_process").execFile("/usr/bin/id",["id","-u",v]);this.__child.promise=this;this.__child.stdout._txt="";this.__child.stdout.on("data",function(F){this._txt+=F.toString()});this.__child.on("exit",function(F){try{parseInt(this.stdout._txt)}catch(G){this.promise.__rejector("invalid uid");return}var H=parseInt(this.stdout._txt);this.promise.__resolver(H)})});y.push(w)}x.all(y).then(function(E){var F={};for(var s in E){F[E[s].__username]=E[s]._internal.completedArgs[0]}for(var s in D){D[s].uid=F[D[s].Username]}Object.defineProperty(D,"Active",{value:showActiveOnly(D)});if(p._callback){p._callback.call(p,D)}},function(s){Object.defineProperty(D,"Active",{value:showActiveOnly(D)});if(p._callback){p._callback.call(p,D)}})});p._child.stdout.Parent=p._child;p._child.stdout.on("data",function(q){this.Parent._txt+=q.toString()});return(p)};this._recheckLoggedInUsers=function a(){this.enumerateUsers().then(function(o){if(o.Active.length>0){if(this.parent._linux_lock_watcher!=null&&this.parent._linux_lock_watcher.uid!=o.Active[0].uid){delete this.parent._linux_lock_watcher}this.parent._linux_lock_watcher=new g(process.env.XDG_CURRENT_DESKTOP=="Unity"?"com.ubuntu.Upstart0_6":"org.gnome.ScreenSaver",o.Active[0].uid);this.parent._linux_lock_watcher.user_session=this.parent;this.parent._linux_lock_watcher.on("signal",function(r){var q=this.user_session.enumerateUsers();q.signalData=r.data[0];q.then(function(p){switch(this.signalData){case true:case"desktop-lock":this.parent.emit("locked",p.Active[0]);break;case false:case"desktop-unlock":this.parent.emit("unlocked",p.Active[0]);break}})})}else{if(this.parent._linux_lock_watcher!=null){delete this.parent._linux_lock_watcher}}})};this.on("changed",this._recheckLoggedInUsers);this._recheckLoggedInUsers()}else{if(process.platform=="darwin"){this._users=function(){var o=require("child_process").execFile("/usr/bin/dscl",["dscl",".","list","/Users","UniqueID"]);o.stdout.str="";o.stdout.on("data",function(t){this.str+=t.toString()});o.stdin.write("exit\n");o.waitExit();var q=o.stdout.str.split("\n");var r,p;var s={};for(p=0;p0;++r){if(!u[s[r].split(" ")[0]]){try{u[s[r].split(" ")[0]]={Username:s[r].split(" ")[0],State:s[r].split("still logged in").length>1?"Active":"Inactive",uid:t.uid[s[r].split(" ")[0]]}}catch(q){}}else{if(u[s[r].split(" ")[0]].State!="Active"&&s[r].split("still logged in").length>1){u[s[r].split(" ")[0]].State="Active"}}}Object.defineProperty(u,"Active",{value:showActiveOnly(u)});if(o){o.call(this,u)}}}}}if(process.platform=="linux"||process.platform=="darwin"){this._self=function b(){var o=require("child_process").execFile("/usr/bin/id",["id","-u"]);o.stdout.str="";o.stdout.on("data",function(p){this.str+=p.toString()});o.waitExit();return(parseInt(o.stdout.str))};this.isRoot=function k(){return(this._self()==0)};this.consoleUid=function e(){var o=process.platform=="darwin"?"console":((process.env.DISPLAY)?process.env.DISPLAY:":0");var p=require("child_process").execFile("/bin/sh",["sh"]);p.stdout.str="";p.stdout.on("data",function(u){this.str+=u.toString()});p.stdin.write("who\nexit\n");p.waitExit();var s=p.stdout.str.split("\n");var t,q,r;for(q in s){t=s[q].split(" ");for(r=1;r0){return(parseInt(this._users()[t[0]]))}}}throw ("nobody logged into console")}}}function showActiveOnly(c){var b=[];var e={};var f=[];var d;for(var a in c){if(c[a].State=="Active"){b.push(c[a]);d=(c[a].Domain?(c[a].Domain+"\\"):"")+c[a].Username;if(!e[d]){e[d]=d}}}for(var a in e){f.push(a)}Object.defineProperty(b,"usernames",{value:f});return(b)}function getTokens(d){var a=[];var b;a.push(d.substring(0,(b=d.indexOf(" "))));while(d[++b]==" "){}a.push(d.substring(b,(b=d.substring(b).indexOf(" ")+b)));while(d[++b]==" "){}a.push(d.substring(b,(b=d.substring(b).indexOf(" ")+b)));while(d[++b]==" "){}var c=d.substring(b).trim();a.push(c);return(a)}module.exports=new UserSessions(); \ No newline at end of file diff --git a/agents/modules_meshcore/identifiers.js b/agents/modules_meshcore/identifiers.js new file mode 100644 index 00000000..b0fdb6c2 --- /dev/null +++ b/agents/modules_meshcore/identifiers.js @@ -0,0 +1,208 @@ +/* +Copyright 2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +function trimIdentifiers(val) +{ + for(var v in val) + { + if (!val[v] || val[v] == 'None' || val[v] == '') { delete val[v]; } + } +} + +function linux_identifiers() +{ + var identifiers = {}; + var ret = {}; + var values = {}; + if (!require('fs').existsSync('/sys/class/dmi/id')) { throw ('this platform does not have DMI statistics'); } + var entries = require('fs').readdirSync('/sys/class/dmi/id'); + for(var i in entries) + { + if (require('fs').statSync('/sys/class/dmi/id/' + entries[i]).isFile()) + { + ret[entries[i]] = require('fs').readFileSync('/sys/class/dmi/id/' + entries[i]).toString().trim(); + + if (ret[entries[i]] == 'None') { delete ret[entries[i]];} + } + } + identifiers['bios_date'] = ret['bios_date']; + identifiers['bios_vendor'] = ret['bios_vendor']; + identifiers['bios_version'] = ret['bios_version']; + identifiers['board_name'] = ret['board_name']; + identifiers['board_serial'] = ret['board_serial']; + identifiers['board_vendor'] = ret['board_vendor']; + identifiers['board_version'] = ret['board_version']; + identifiers['product_uuid'] = ret['product_uuid']; + + values.identifiers = identifiers; + values.linux = ret; + trimIdentifiers(values.identifiers); + return (values); +} + +function windows_wmic_results(str) +{ + var lines = str.trim().split('\r\n'); + var keys = lines[0].split(','); + var i, key, keyval; + var tokens; + var result = []; + + for (i = 1; i < lines.length; ++i) + { + var obj = {}; + tokens = lines[i].split(','); + for (key = 0; key < keys.length; ++key) + { + if (tokens[key].trim()) + { + obj[keys[key].trim()] = tokens[key].trim(); + } + } + result.push(obj); + } + return (result); +} + + +function windows_identifiers() +{ + var ret = { windows: {}}; values = {}; var items; var i; var item; + var child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'bios', 'get', '/VALUE']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + + var items = child.stdout.str.split('\r\r\n'); + for(i in items) + { + item = items[i].split('='); + values[item[0]] = item[1]; + } + + ret['identifiers'] = {}; + ret['identifiers']['bios_date'] = values['ReleaseDate']; + ret['identifiers']['bios_vendor'] = values['Manufacturer']; + ret['identifiers']['bios_version'] = values['SMBIOSBIOSVersion']; + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'BASEBOARD', 'get', '/VALUE']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + + var items = child.stdout.str.split('\r\r\n'); + for (i in items) + { + item = items[i].split('='); + values[item[0]] = item[1]; + } + ret['identifiers']['board_name'] = values['Product']; + ret['identifiers']['board_serial'] = values['SerialNumber']; + ret['identifiers']['board_vendor'] = values['Manufacturer']; + ret['identifiers']['board_version'] = values['Version']; + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'CSProduct', 'get', '/VALUE']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + + var items = child.stdout.str.split('\r\r\n'); + for (i in items) + { + item = items[i].split('='); + values[item[0]] = item[1]; + } + ret['identifiers']['product_uuid'] = values['UUID']; + trimIdentifiers(ret.identifiers); + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'MEMORYCHIP', 'LIST', '/FORMAT:CSV']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + ret.windows.memory = windows_wmic_results(child.stdout.str); + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'OS', 'GET', '/FORMAT:CSV']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + ret.windows.osinfo = windows_wmic_results(child.stdout.str)[0]; + + child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'PARTITION', 'LIST', '/FORMAT:CSV']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + ret.windows.partitions = windows_wmic_results(child.stdout.str); + + return (ret); +} +function macos_identifiers() +{ + var ret = { identifiers: {} }; + var child; + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep board-id | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.board_name = child.stdout.str.trim(); + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep IOPlatformSerialNumber | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.board_serial = child.stdout.str.trim(); + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep manufacturer | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.board_vendor = child.stdout.str.trim(); + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep version | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.board_version = child.stdout.str.trim(); + + child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep IOPlatformUUID | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n'); + child.waitExit(); + ret.identifiers.product_uuid = child.stdout.str.trim(); + + trimIdentifiers(ret.identifiers); + return (ret); +} + +switch(process.platform) +{ + case 'linux': + module.exports = { _ObjectID: 'identifiers', get: linux_identifiers }; + break; + case 'win32': + module.exports = { _ObjectID: 'identifiers', get: windows_identifiers }; + break; + case 'darwin': + module.exports = { _ObjectID: 'identifiers', get: macos_identifiers }; + break; + default: + module.exports = { get: function () { throw ('Unsupported Platform'); } }; + break; +} + + +// bios_date = BIOS->ReleaseDate +// bios_vendor = BIOS->Manufacturer +// bios_version = BIOS->SMBIOSBIOSVersion +// board_name = BASEBOARD->Product = ioreg/board-id +// board_serial = BASEBOARD->SerialNumber = ioreg/serial-number | ioreg/IOPlatformSerialNumber +// board_vendor = BASEBOARD->Manufacturer = ioreg/manufacturer +// board_version = BASEBOARD->Version + diff --git a/agents/modules_meshcore/sysinfo.js b/agents/modules_meshcore/sysinfo.js new file mode 100644 index 00000000..a146fd80 --- /dev/null +++ b/agents/modules_meshcore/sysinfo.js @@ -0,0 +1,230 @@ +/* +Copyright 2019 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +const PDH_FMT_LONG = 0x00000100; +const PDH_FMT_DOUBLE = 0x00000200; + +var promise = require('promise'); +if (process.platform == 'win32') +{ + var GM = require('_GenericMarshal'); + GM.kernel32 = GM.CreateNativeProxy('kernel32.dll'); + GM.kernel32.CreateMethod('GlobalMemoryStatusEx'); + + GM.pdh = GM.CreateNativeProxy('pdh.dll'); + GM.pdh.CreateMethod('PdhAddEnglishCounterA'); + GM.pdh.CreateMethod('PdhCloseQuery'); + GM.pdh.CreateMethod('PdhCollectQueryData'); + GM.pdh.CreateMethod('PdhGetFormattedCounterValue'); + GM.pdh.CreateMethod('PdhGetFormattedCounterArrayA'); + GM.pdh.CreateMethod('PdhOpenQueryA'); + GM.pdh.CreateMethod('PdhRemoveCounter'); +} + +function windows_cpuUtilization() +{ + var p = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + p.counter = GM.CreateVariable(16); + p.cpu = GM.CreatePointer(); + p.cpuTotal = GM.CreatePointer(); + var err = 0; + if ((err = GM.pdh.PdhOpenQueryA(0, 0, p.cpu).Val) != 0) { p._rej(err); return; } + + // This gets the CPU Utilization for each proc + if ((err = GM.pdh.PdhAddEnglishCounterA(p.cpu.Deref(), GM.CreateVariable('\\Processor(*)\\% Processor Time'), 0, p.cpuTotal).Val) != 0) { p._rej(err); return; } + + if ((err = GM.pdh.PdhCollectQueryData(p.cpu.Deref()).Val != 0)) { p._rej(err); return; } + p._timeout = setTimeout(function (po) + { + var u = { cpus: [] }; + var bufSize = GM.CreateVariable(4); + var itemCount = GM.CreateVariable(4); + var buffer, szName, item; + var e; + if ((e = GM.pdh.PdhCollectQueryData(po.cpu.Deref()).Val != 0)) { po._rej(e); return; } + + if ((e = GM.pdh.PdhGetFormattedCounterArrayA(po.cpuTotal.Deref(), PDH_FMT_DOUBLE, bufSize, itemCount, 0).Val) == -2147481646) + { + buffer = GM.CreateVariable(bufSize.toBuffer().readUInt32LE()); + } + else + { + po._rej(e); + return; + } + if ((e = GM.pdh.PdhGetFormattedCounterArrayA(po.cpuTotal.Deref(), PDH_FMT_DOUBLE, bufSize, itemCount, buffer).Val) != 0) { po._rej(e); return; } + for(var i=0;i 0) + { + var usage = lines[0].split(':')[1]; + var bdown = usage.split(','); + + var tot = parseFloat(bdown[0].split('%')[0].trim()) + parseFloat(bdown[1].split('%')[0].trim()); + ret._res({total: tot, cpus: []}); + } + else + { + ret._rej('parse error'); + } + + return (ret); +} +function macos_memUtilization() +{ + var mem = { }; + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.stdin.write('top -l 1 | grep -E "^Phys"\nexit\n'); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + if (lines[0].length > 0) + { + var usage = lines[0].split(':')[1]; + var bdown = usage.split(','); + + mem.MemTotal = parseInt(bdown[0].trim().split(' ')[0]); + mem.MemFree = parseInt(bdown[1].trim().split(' ')[0]); + mem.percentFree = ((mem.MemFree / mem.MemTotal) * 100);//.toFixed(2); + mem.percentConsumed = (((mem.MemTotal - mem.MemFree) / mem.MemTotal) * 100);//.toFixed(2); + return (mem); + } + else + { + throw ('Parse Error'); + } +} + +switch(process.platform) +{ + case 'linux': + module.exports = { cpuUtilization: linux_cpuUtilization, memUtilization: linux_memUtilization }; + break; + case 'win32': + module.exports = { cpuUtilization: windows_cpuUtilization, memUtilization: windows_memUtilization }; + break; + case 'darwin': + module.exports = { cpuUtilization: macos_cpuUtilization, memUtilization: macos_memUtilization }; + break; +} + diff --git a/agents/modules_meshcore_min/identifiers.min.js b/agents/modules_meshcore_min/identifiers.min.js new file mode 100644 index 00000000..b2f733af --- /dev/null +++ b/agents/modules_meshcore_min/identifiers.min.js @@ -0,0 +1 @@ +function trimIdentifiers(b){for(var a in b){if(!b[a]||b[a]=="None"||b[a]==""){delete b[a]}}}function linux_identifiers(){var c={};var d={};var e={};if(!require("fs").existsSync("/sys/class/dmi/id")){throw ("this platform does not have DMI statistics")}var a=require("fs").readdirSync("/sys/class/dmi/id");for(var b in a){if(require("fs").statSync("/sys/class/dmi/id/"+a[b]).isFile()){d[a[b]]=require("fs").readFileSync("/sys/class/dmi/id/"+a[b]).toString().trim();if(d[a[b]]=="None"){delete d[a[b]]}}}c.bios_date=d.bios_date;c.bios_vendor=d.bios_vendor;c.bios_version=d.bios_version;c.board_name=d.board_name;c.board_serial=d.board_serial;c.board_vendor=d.board_vendor;c.board_version=d.board_version;c.product_uuid=d.product_uuid;e.identifiers=c;e.linux=d;trimIdentifiers(e.identifiers);return(e)}function windows_wmic_results(h){var e=h.trim().split("\r\n");var c=e[0].split(",");var a,b,d;var j;var g=[];for(a=1;a"){g=""}}if(j.startsWith("Signal level=")){f=j.slice(13,j.length-4)}else{if(j.startsWith("Quality=")){f=j.slice(8,10);var k=j.slice(11,13)}}}this.parent.parent.emit("accessPoint",new AccessPoint(g,e,f))}})}}}}}module.exports=WiFiScanner; \ No newline at end of file diff --git a/agents/modules_meshcore_min/win-console.min.js b/agents/modules_meshcore_min/win-console.min.js deleted file mode 100644 index e2197744..00000000 --- a/agents/modules_meshcore_min/win-console.min.js +++ /dev/null @@ -1 +0,0 @@ -var TrayIconFlags={NIF_MESSAGE:1,NIF_ICON:2,NIF_TIP:4,NIF_STATE:8,NIF_INFO:16,NIF_GUID:32,NIF_REALTIME:64,NIF_SHOWTIP:128,NIM_ADD:0,NIM_MODIFY:1,NIM_DELETE:2,NIM_SETFOCUS:3,NIM_SETVERSION:4};var NOTIFYICON_VERSION_4=4;var MessageTypes={WM_APP:32768,WM_USER:1024};function WindowsConsole(){if(process.platform=="win32"){this._ObjectID="win-console";this._Marshal=require("_GenericMarshal");this._kernel32=this._Marshal.CreateNativeProxy("kernel32.dll");this._user32=this._Marshal.CreateNativeProxy("user32.dll");this._kernel32.CreateMethod("GetConsoleWindow");this._kernel32.CreateMethod("GetCurrentThread");this._user32.CreateMethod("ShowWindow");this._user32.CreateMethod("LoadImageA");this._user32.CreateMethod({method:"GetMessageA",threadDispatch:1});this._shell32=this._Marshal.CreateNativeProxy("Shell32.dll");this._shell32.CreateMethod("Shell_NotifyIconA");this._handle=this._kernel32.GetConsoleWindow();this.minimize=function(){this._user32.ShowWindow(this._handle,6)};this.restore=function(){this._user32.ShowWindow(this._handle,9)};this.hide=function(){this._user32.ShowWindow(this._handle,0)};this.show=function(){this._user32.ShowWindow(this._handle,5)};this._loadicon=function(c){var b=this._user32.LoadImageA(0,this._Marshal.CreateVariable(c),1,0,0,16|32768|64);return(b)};this.SetTrayIcon=function a(h){var b=this._Marshal.CreateVariable(this._Marshal.PointerSize==4?508:528);b.toBuffer().writeUInt32LE(b._size,0);var n=TrayIconFlags.NIF_TIP|TrayIconFlags.NIF_MESSAGE;h.filter=MessageTypes.WM_APP+1;b.Deref(this._Marshal.PointerSize==4?16:24,4).toBuffer().writeUInt32LE(h.filter);if(!h.noBalloon){n|=TrayIconFlags.NIF_INFO}if(h.icon){n|=TrayIconFlags.NIF_ICON;var c=b.Deref(this._Marshal.PointerSize==4?20:32,this._Marshal.PointerSize);h.icon.pointerBuffer().copy(c.toBuffer())}b.Deref(this._Marshal.PointerSize*2,4).toBuffer().writeUInt32LE(1);b.Deref(this._Marshal.PointerSize==4?12:20,4).toBuffer().writeUInt32LE(n);b.Deref(this._Marshal.PointerSize==4?416:432,4).toBuffer().writeUInt32LE(NOTIFYICON_VERSION_4);var m=b.Deref(this._Marshal.PointerSize==4?24:40,128);var k=b.Deref(this._Marshal.PointerSize==4?160:176,256);var l=b.Deref(this._Marshal.PointerSize==4?420:436,64);if(h.szTip){Buffer.from(h.szTip).copy(m.toBuffer())}if(h.szInfo){Buffer.from(h.szInfo).copy(k.toBuffer())}if(h.szInfoTitle){Buffer.from(h.szInfoTitle).copy(l.toBuffer())}var d=require("win-message-pump");retVal={_ObjectID:"WindowsConsole.TrayIcon",MessagePump:new d(h)};var j=require("events").inherits(retVal);j.createEvent("ToastClicked");j.createEvent("IconHover");j.createEvent("ToastDismissed");retVal.Options=h;retVal.MessagePump.TrayIcon=retVal;retVal.MessagePump.NotifyData=b;retVal.MessagePump.WindowsConsole=this;retVal.MessagePump.on("exit",function e(o){console.log("Pump Exited");if(this.TrayIcon){this.TrayIcon.remove()}});retVal.MessagePump.on("hwnd",function f(o){h.hwnd=o;o.pointerBuffer().copy(this.NotifyData.Deref(this.WindowsConsole._Marshal.PointerSize,this.WindowsConsole._Marshal.PointerSize).toBuffer());if(this.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_ADD,this.NotifyData).Val==0){}});retVal.MessagePump.on("message",function g(p){if(p.message==this.TrayIcon.Options.filter){var o=false;if(p.wparam==1&&p.lparam==1029){this.TrayIcon.emit("ToastClicked");o=true}if(p.wparam==1&&p.lparam==512){this.TrayIcon.emit("IconHover");o=true}if(this.TrayIcon.Options.balloonOnly&&p.wparam==1&&(p.lparam==1028||p.lparam==1029)){this.TrayIcon.emit("ToastDismissed");this.TrayIcon.remove();o=true}}});retVal.remove=function i(){this.MessagePump.WindowsConsole._shell32.Shell_NotifyIconA(TrayIconFlags.NIM_DELETE,this.MessagePump.NotifyData);this.MessagePump.stop();delete this.MessagePump.TrayIcon;delete this.MessagePump};return(retVal)}}}module.exports=new WindowsConsole(); \ No newline at end of file diff --git a/agents/modules_meshcore_min/win-info.min.js b/agents/modules_meshcore_min/win-info.min.js deleted file mode 100644 index ef3c8e5f..00000000 --- a/agents/modules_meshcore_min/win-info.min.js +++ /dev/null @@ -1 +0,0 @@ -var promise=require("promise");function qfe(){var a=require("child_process").execFile(process.env.windir+"\\System32\\wbem\\wmic.exe",["wmic","qfe","list","full","/FORMAT:CSV"]);a.stdout.str="";a.stdout.on("data",function(i){this.str+=i.toString()});a.stderr.str="";a.stderr.on("data",function(i){this.str+=i.toString()});a.waitExit();var e=a.stdout.str.trim().split("\r\n");var d=e[0].split(",");var b,c;var h;var g=[];for(b=1;b0){n=this.chunk.shift();this.terminal._WriteBuffer(n);n.flush()}})}else{this.terminal._WriteBuffer(l);m()}return(true)},"final":function(l){var m=this.terminal._stop();m.__flush=l;m.then(function(){this.__flush()})}});this._stream.terminal=this;this._stream._promise=new promise(function(m,l){this._res=m;this._rej=l});this._stream._promise.terminal=this;return(this._stream)};this.Start=function d(h,g){return(this.StartEx(h,g,process.env.windir+"\\System32\\cmd.exe"))};this.StartPowerShell=function f(h,g){if(require("os").arch()=="x64"){return(this.StartEx(h,g,process.env.windir+"\\SysWow64\\WindowsPowerShell\\v1.0\\powershell.exe"))}else{return(this.StartEx(h,g,process.env.windir+"\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"))}};this._stop=function(){if(this.stopping){return(this.stopping)}this._ConsoleWinEventProc.removeAllListeners("GlobalCallback");this.stopping=new promise(function(i,h){this._res=i;this._rej=h});var g=this._kernel32.GetThreadId(this._user32.SetWinEventHook.async.thread()).Val;this._user32.PostThreadMessageA(g,WM_QUIT,0,0);this._stream.emit("end");return(this.stopping)};this._hookThread=function(){var i=new promise(function(k,j){this._res=k;this._rej=j});i.userArgs=[];for(var g in arguments){i.userArgs.push(arguments[g])}i.terminal=this;this._ConsoleWinEventProc=GM.GetGenericGlobalCallback(7);this._ConsoleWinEventProc.terminal=this;var h=this._user32.SetWinEventHook.async(EVENT_CONSOLE_CARET,EVENT_CONSOLE_END_APPLICATION,0,this._ConsoleWinEventProc,0,0,WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNPROCESS);h.ready=i;h.terminal=this;h.then(function(j){if(j.Val==0){this.ready._rej("Error calling SetWinEventHook")}else{this.terminal.hwinEventHook=j;this.ready._res();this.terminal._GetMessage()}});this._ConsoleWinEventProc.on("GlobalCallback",function(l,k,m,p,n,o,r){if(!this.terminal.hwinEventHook||this.terminal.hwinEventHook.Val!=l.Val){return}var j=null;switch(k.Val){case EVENT_CONSOLE_CARET:break;case EVENT_CONSOLE_UPDATE_REGION:if(!this.terminal.connected){this.terminal.connected=true;this.terminal._stream._promise._res()}if(this.terminal._scrollTimer==null){j=this.terminal._GetScreenBuffer(LOWORD(p.Val),HIWORD(p.Val),LOWORD(n.Val),HIWORD(n.Val));this.terminal._SendDataBuffer(j)}break;case EVENT_CONSOLE_UPDATE_SIMPLE:var q={data:[Buffer.alloc(1,LOWORD(n.Val))],attributes:[HIWORD(n.Val)],width:1,height:1,x:LOWORD(p.Val),y:HIWORD(p.Val)};this.terminal._SendDataBuffer(q);break;case EVENT_CONSOLE_UPDATE_SCROLL:this.terminal._SendScroll(p.Val,n.Val);break;case EVENT_CONSOLE_LAYOUT:break;case EVENT_CONSOLE_START_APPLICATION:break;case EVENT_CONSOLE_END_APPLICATION:if(p.Val==this.terminal._hProcessID){this.terminal._hProcess=null;this.terminal._stop().then(function(){console.log("STOPPED")})}break;default:console.log("Unknown event: "+k.Val);break}});return(i)};this._GetMessage=function(){if(this._user32.abort){console.log("aborting loop");return}this._user32.GetMessageA.async(this._user32.SetWinEventHook.async,MSG,0,0,0).then(function(g){if(g.Val!=0){if(g.Val==-1){}else{this.nativeProxy._user32.TranslateMessage.async(this.nativeProxy.user32.SetWinEventHook.async,MSG).then(function(){this.nativeProxy._user32.DispatchMessageA.async(this.nativeProxy.user32.SetWinEventHook.async,MSG).then(function(){this.nativeProxy.terminal._GetMessage()},console.log)},console.log)}}else{this.nativeProxy.UnhookWinEvent.async(this.nativeProxy.terminal._user32.SetWinEventHook.async,this.nativeProxy.terminal.hwinEventHook).then(function(){if(this.nativeProxy.terminal._hProcess==null){return}this.nativeProxy.terminal.stopping._res();if(this.nativeProxy.terminal._kernel32.TerminateProcess(this.nativeProxy.terminal._hProcess,1067).Val==0){var h=this.nativeProxy.terminal._kernel32.GetLastError().Val;console.log("Unable to kill Terminal Process, error: "+h)}this.nativeProxy.terminal.stopping=null},function(h){console.log("REJECTED_UnhookWinEvent: "+h)})}},function(g){console.log("REJECTED_GETMessage: "+g)})};this._WriteBuffer=function(g){for(var h=0;hm;++k){this._stream.push(Buffer.from("\r\n"))}var g=this._GetScreenBuffer(0,0,n-1,m-1);this._SendDataBuffer(g);this._scrollTimer=setTimeout(function(q,p,o){var i=q._GetScreenBuffer(0,0,p-1,o-1);q._SendDataBuffer(i);q._scrollTimer=null},250,this,n,m)};this.StartCommand=function e(g){if(this._kernel32.CreateProcessA(GM.CreateVariable(g),0,0,0,1,CREATE_NEW_PROCESS_GROUP,0,0,si,pi).Val==0){console.log("Error Spawning CMD");return}this._kernel32.CloseHandle(pi.Deref(GM.PointerSize,GM.PointerSize).Deref());this._hProcess=pi.Deref(0,GM.PointerSize).Deref();this._hProcessID=pi.Deref(GM.PointerSize==4?8:16,4).toBuffer().readUInt32LE()}}function LOWORD(a){return(a&65535)}function HIWORD(a){return((a>>16)&65535)}function GetEsc(b,a){return(Buffer.from("\x1B["+a.join(";")+b))}function MeshConsole(a){require("MeshAgent").SendCommand({action:"msg",type:"console",value:JSON.stringify(a)})}function TranslateLine(r,s,f,a){var m,l,e,q,j,c,n,k,d,p,h,b,g=[],o=[GetEsc("H",[s,r])];if(typeof a=="number"){a=[a]}for(m=0;m>2);d=(a[m]&112)>>4;d=((d&1)<<2)+(d&2)+((d&4)>>2);p=(a[m]&16384);h=(a[m]&8)>>3;b=(a[m]&128);if(p!=q){if(p!=0){g.push(7)}else{g.push(0);l=7;e=0;j=0;c=0}q=p}if(k!=l){g.push(k+30);l=k}if(d!=e){g.push(d+40);e=d}if(h!=j){g.push(2-h);j=h}if(b!=c){if(b==0){g.push(e+40)}else{g.push(e+100);c=b}}if(g.length>0){o.push(GetEsc("m",g));g=[]}n=a[m]}o.push(Buffer.from(String.fromCharCode(f[m])))}return Buffer.concat(o)}module.exports=new windows_terminal(); \ No newline at end of file diff --git a/db.js b/db.js index dfdb0b2a..92877a74 100644 --- a/db.js +++ b/db.js @@ -531,6 +531,7 @@ module.exports.CreateDB = function (parent, func) { } }; obj.GetAll = function (func) { obj.file.find({}).toArray(func); }; + obj.GetHash = function (id, func) { obj.file.find({ _id: id }).project({ _id: 0, hash: 1 }).toArray(func); }; obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }).project({ type: 0 }).toArray(func); }; obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, domain, type, id, func) { var x = { type: type, domain: domain, meshid: { $in: meshes } }; if (id) { x._id = id; } obj.file.find(x, { type: 0 }).toArray(func); }; obj.GetAllType = function (type, func) { obj.file.find({ type: type }).toArray(func); }; @@ -624,6 +625,7 @@ module.exports.CreateDB = function (parent, func) { } }; obj.GetAll = function (func) { obj.file.find({}, func); }; + obj.GetHash = function (id, func) { obj.file.find({ _id: id }, { _id: 0, hash: 1 }, func); }; obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }, { type: 0 }, func); }; obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, domain, type, id, func) { var x = { type: type, domain: domain, meshid: { $in: meshes } }; if (id) { x._id = id; } obj.file.find(x, { type: 0 }, func); }; obj.GetAllType = function (type, func) { obj.file.find({ type: type }, func); }; diff --git a/meshagent.js b/meshagent.js index e2581ed0..50815893 100644 --- a/meshagent.js +++ b/meshagent.js @@ -64,6 +64,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { db.Remove('if' + obj.dbNodeKey); // Remove interface information db.Remove('nt' + obj.dbNodeKey); // Remove notes db.Remove('lc' + obj.dbNodeKey); // Remove last connect time + db.Remove('si' + obj.dbNodeKey); // Remove system information db.RemoveSMBIOS(obj.dbNodeKey); // Remove SMBios data db.RemoveAllNodeEvents(obj.dbNodeKey); // Remove all events for this node db.removeAllPowerEventsForNode(obj.dbNodeKey); // Remove all power events for this node @@ -909,6 +910,11 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { try { obj.send(JSON.stringify({ action: 'amtPolicy', amtPolicy: completeIntelAmtPolicy(common.Clone(mesh.amt)) })); } catch (ex) { } } + // Fetch system information + db.GetHash('si' + obj.dbNodeKey, function (err, results) { + if ((results != null) && (results.length == 1)) { obj.send(JSON.stringify({ action: 'sysinfo', hash: results[0].hash })); } else { obj.send(JSON.stringify({ action: 'sysinfo' })); } + }); + // Do this if IP location is enabled on this domain TODO: Set IP location per device group? if (domain.iplocation == true) { // Check if we already have IP location information for this node @@ -1298,6 +1304,19 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { } break; } + case 'sysinfo': { + //console.log('sysinfo', obj.nodeid, JSON.stringify(command.data.hash)); + command.data._id = 'si' + obj.dbNodeKey; + db.Set(command.data); // Update system information in the database. + break; + } + case 'sysinfocheck': { + // Check system information update + db.GetHash('si' + obj.dbNodeKey, function (err, results) { + if ((results != null) && (results.length == 1)) { obj.send(JSON.stringify({ action: 'sysinfo', hash: results[0].hash })); } else { obj.send(JSON.stringify({ action: 'sysinfo' })); } + }); + break; + } default: { parent.agentStats.unknownAgentActionCount++; console.log('Unknown agent action (' + obj.remoteaddrport + '): ' + command.action + '.'); diff --git a/meshuser.js b/meshuser.js index fd2b9734..819babd5 100644 --- a/meshuser.js +++ b/meshuser.js @@ -1937,6 +1937,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use db.Remove('if' + node._id); // Remove interface information db.Remove('nt' + node._id); // Remove notes db.Remove('lc' + node._id); // Remove last connect time + db.Remove('si' + node._id); // Remove system information db.RemoveSMBIOS(node._id); // Remove SMBios data db.RemoveAllNodeEvents(node._id); // Remove all events for this node db.removeAllPowerEventsForNode(node._id); // Remove all power events for this node diff --git a/package.json b/package.json index 09243489..001441e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.3.9-g", + "version": "0.3.9-h", "keywords": [ "Remote Management", "Intel AMT", @@ -39,6 +39,7 @@ "ipcheck": "^0.1.0", "meshcentral": "*", "minimist": "^1.2.0", + "mongojs": "^2.6.0", "multiparty": "^4.2.1", "nedb": "^1.8.0", "node-forge": "^0.8.4",