From cf36e4aceaab1b82311d1010a072bbd2882b14a6 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Fri, 2 Aug 2019 11:35:59 -0700 Subject: [PATCH] Added antivirus status. --- agents/meshcore.js | 18 +- agents/meshcore.min.js | 18 +- agents/modules_meshcore/win-info.js | 227 ++++++++++++++++++++ agents/modules_meshcore_min/win-info.min.js | 1 + meshagent.js | 5 + package.json | 2 +- views/default-min.handlebars | 2 +- views/default.handlebars | 38 +++- 8 files changed, 290 insertions(+), 21 deletions(-) create mode 100644 agents/modules_meshcore/win-info.js create mode 100644 agents/modules_meshcore_min/win-info.min.js diff --git a/agents/meshcore.js b/agents/meshcore.js index 75938549..29753fb9 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -1603,10 +1603,10 @@ 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.'; + 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.'; break; } - /* + /* case 'border': { if ((args['_'].length == 1) && (args['_'][0] == 'on')) { @@ -1624,7 +1624,10 @@ function createMeshCore(agent) } } break; - */ + */ + case 'av': + if (process.platform == 'win32') { response = JSON.stringify(require('win-info').av()); } 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'; } break; @@ -2170,7 +2173,7 @@ function createMeshCore(agent) // Update the server on more advanced stuff, like Intel ME and Network Settings meInfoStr = null; sendPeriodicServerUpdate(); - //if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes + if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes } } @@ -2235,6 +2238,13 @@ function createMeshCore(agent) // Update network information sendNetworkUpdateNagle(false); } + + if ((flags & 4) && (process.platform == 'win32')) { + // Update anti-virus information + var av = null; + try { av = require('win-info').av(); } catch (ex) { av = { product: 'Error', updated: false, enabled: false }; } + 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 75938549..29753fb9 100644 --- a/agents/meshcore.min.js +++ b/agents/meshcore.min.js @@ -1603,10 +1603,10 @@ 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.'; + 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.'; break; } - /* + /* case 'border': { if ((args['_'].length == 1) && (args['_'][0] == 'on')) { @@ -1624,7 +1624,10 @@ function createMeshCore(agent) } } break; - */ + */ + case 'av': + if (process.platform == 'win32') { response = JSON.stringify(require('win-info').av()); } 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'; } break; @@ -2170,7 +2173,7 @@ function createMeshCore(agent) // Update the server on more advanced stuff, like Intel ME and Network Settings meInfoStr = null; sendPeriodicServerUpdate(); - //if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes + if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes } } @@ -2235,6 +2238,13 @@ function createMeshCore(agent) // Update network information sendNetworkUpdateNagle(false); } + + if ((flags & 4) && (process.platform == 'win32')) { + // Update anti-virus information + var av = null; + try { av = require('win-info').av(); } catch (ex) { av = { product: 'Error', updated: false, enabled: false }; } + if ((meshCoreObj.av == null) || (JSON.stringify(meshCoreObj.av) != JSON.stringify(av))) { meshCoreObj.av = av; mesh.SendCommand(meshCoreObj); } + } } diff --git a/agents/modules_meshcore/win-info.js b/agents/modules_meshcore/win-info.js new file mode 100644 index 00000000..fae48adc --- /dev/null +++ b/agents/modules_meshcore/win-info.js @@ -0,0 +1,227 @@ +/* +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. +*/ + +var promise = require('promise'); + +function qfe() +{ + var child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', 'qfe', 'list', 'full', '/FORMAT:CSV']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + + var lines = child.stdout.str.trim().split('\r\n'); + var keys = lines[0].split(','); + var i, key; + 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]) { obj[keys[key]] = tokens[key]; } + } + result.push(obj); + } + return (result); +} +function av() +{ + var child = require('child_process').execFile(process.env['windir'] + '\\System32\\wbem\\wmic.exe', ['wmic', '/Namespace:\\\\root\\SecurityCenter2', 'Path', 'AntiVirusProduct', 'get', '/FORMAT:CSV']); + child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); }); + child.waitExit(); + + var lines = child.stdout.str.trim().split('\r\n'); + var keys = lines[0].split(','); + var i, key; + var tokens; + var result = []; + + for (i = 1; i < lines.length; ++i) + { + var obj = {}; + var status = {}; + tokens = lines[i].split(','); + for (key = 0; key < keys.length; ++key) + { + if (tokens[key] != undefined) { obj[keys[key].trim()] = tokens[key]; } + } + status.product = obj.displayName; + status.updated = (parseInt(obj.productState) & 0x10) == 0; + status.enabled = (parseInt(obj.productState) & 0x1000) == 0x1000; + result.push(status); + } + return (result); +} +function defrag(options) +{ + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + var path = ''; + + switch(require('os').arch()) + { + case 'x64': + if (require('_GenericMarshal').PointerSize == 4) + { + // 32 Bit App on 64 Bit Windows + ret._rej('Cannot defrag volume on 64 bit Windows from 32 bit application'); + return (ret); + } + else + { + // 64 Bit App + path = process.env['windir'] + '\\System32\\defrag.exe'; + } + break; + case 'ia32': + // 32 Bit App on 32 Bit Windows + path = process.env['windir'] + '\\System32\\defrag.exe'; + break; + default: + ret._rej(require('os').arch() + ' not supported'); + return (ret); + break; + } + + ret.child = require('child_process').execFile(process.env['windir'] + '\\System32\\defrag.exe', ['defrag', options.volume + ' /A']); + ret.child.promise = ret; + ret.child.promise.options = options; + ret.child.stdout.str = ''; ret.child.stdout.on('data', function (c) { this.str += c.toString(); }); + ret.child.stderr.str = ''; ret.child.stderr.on('data', function (c) { this.str += c.toString(); }); + ret.child.on('exit', function (code) + { + var lines = this.stdout.str.trim().split('\r\n'); + var obj = { volume: this.promise.options.volume }; + for (var i in lines) + { + var token = lines[i].split('='); + if(token.length == 2) + { + switch(token[0].trim().toLowerCase()) + { + case 'volume size': + obj['size'] = token[1]; + break; + case 'free space': + obj['free'] = token[1]; + break; + case 'total fragmented space': + obj['fragmented'] = token[1]; + break; + case 'largest free space size': + obj['largestFragment'] = token[1]; + break; + } + } + } + this.promise._res(obj); + }); + return (ret); +} +function regQuery(H, Path, Key) +{ + try + { + return(require('win-registry').QueryKey(H, Path, Key)); + } + catch(e) + { + return (null); + } +} +function pendingReboot() +{ + var tmp = null; + var ret = null; + var HKEY = require('win-registry').HKEY; + if(regQuery(HKEY.LocalMachine, 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing', 'RebootPending') !=null) + { + ret = 'Component Based Servicing'; + } + else if(regQuery(HKEY.LocalMachine, 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate', 'RebootRequired')) + { + ret = 'Windows Update'; + } + else if ((tmp=regQuery(HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager', 'PendingFileRenameOperations'))!=null && tmp != 0 && tmp != '') + { + ret = 'File Rename'; + } + else if (regQuery(HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName', 'ComputerName') != regQuery(HKEY.LocalMachine, 'SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName', 'ComputerName')) + { + ret = 'System Rename'; + } + return (ret); +} + +function installedApps() +{ + var promise = require('promise'); + var ret = new promise(function (a, r) { this._resolve = a; this._reject = r; }); + + var code = "\ + var reg = require('win-registry');\ + var result = [];\ + var val, tmp;\ + var items = reg.QueryKey(reg.HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall');\ + for (var key in items.subkeys)\ + {\ + val = {};\ + try\ + {\ + val.name = reg.QueryKey(reg.HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\\\\' + items.subkeys[key], 'DisplayName');\ + }\ + catch(e)\ + {\ + continue;\ + }\ + try\ + {\ + val.version = reg.QueryKey(reg.HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\\\\' + items.subkeys[key], 'DisplayVersion');\ + if (val.version == '') { delete val.version; }\ + }\ + catch(e)\ + {\ + }\ + try\ + {\ + val.location = reg.QueryKey(reg.HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\\\\' + items.subkeys[key], 'InstallLocation');\ + if (val.location == '') { delete val.location; }\ + }\ + catch(e)\ + {\ + }\ + result.push(val);\ + }\ + console.log(JSON.stringify(result,'', 1));process.exit();"; + + ret.child = require('child_process').execFile(process.execPath, [process.execPath.split('\\').pop().split('.exe')[0], '-exec "' + code + '"']); + ret.child.promise = ret; + ret.child.stdout.str = ''; ret.child.stdout.on('data', function (c) { this.str += c.toString(); }); + ret.child.on('exit', function (c) { this.promise._resolve(JSON.parse(this.stdout.str.trim())); }); + return (ret); +} + +if (process.platform == 'win32') +{ + module.exports = { qfe: qfe, av: av, defrag: defrag, pendingReboot: pendingReboot, installedApps: installedApps }; +} +else +{ + var not_supported = function () { throw (process.platform + ' not supported'); }; + module.exports = { qfe: not_supported, av: not_supported, defrag: not_supported, pendingReboot: not_supported, installedApps: not_supported }; +} \ 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 new file mode 100644 index 00000000..600d2f5e --- /dev/null +++ b/agents/modules_meshcore_min/win-info.min.js @@ -0,0 +1 @@ +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.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;b {{{title}}}
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file + {{{title}}}
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file diff --git a/views/default.handlebars b/views/default.handlebars index 814ae810..ac23e579 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -1933,6 +1933,7 @@ if (message.event.node.intelamt.uuid != null) { node.intelamt.uuid = message.event.node.intelamt.uuid; } if (message.event.node.intelamt.realm != null) { node.intelamt.realm = message.event.node.intelamt.realm; } } + if (message.event.node.av != null) { node.av = message.event.node.av; } node.namel = node.name.toLowerCase(); if (node.rname) { node.rnamel = node.rname.toLowerCase(); } else { node.rnamel = node.namel; } if (message.event.node.icon) { node.icon = message.event.node.icon; } @@ -4032,6 +4033,21 @@ // Operating system description if (node.osdesc) { x += addDeviceAttribute('Operating System', node.osdesc); } + // Antivirus + if (node.av && node.av.length > 0) { + var y = []; + for (var i in node.av) { + if (node.av[i].product) { + var avx = EscapeHtml(node.av[i].product); + if (node.av[i].enabled !== true) { avx += ' - Disabled'; } + if (node.av[i].updated !== true) { avx += ' - Out of date'; } + if ((node.av[i].enabled == true) && (node.av[i].updated == true)) { avx += ' - OK'; } + y.push(avx); + } + } + x += addDeviceAttribute('Antivirus', y.join('
')); + } + // Active Users if (node.users && node.conn && (node.users.length > 0) && (node.conn & 1)) { x += addDeviceAttribute('Active User' + ((node.users.length > 1)?'s':''), node.users.join(', ')); } @@ -5977,12 +5993,12 @@ if (event.etype == 'server') icon = 'si3'; if (event.etype == 'relay') icon = 'relayIcon16'; - var msg = event.msg.split('(R)').join('®'); + var msg = EscapeHtml(event.msg).split('(R)').join('®'); if (event.username) { if ((userinfo.siteadmin & 2) && (event.userid)) { - msg = '' + event.username + ' → ' + msg; + msg = '' + EscapeHtml(event.username) + ' → ' + msg; } else { - msg = event.username + ' → ' + msg; + msg = EscapeHtml(event.username) + ' → ' + msg; } } x += '
 ' + printTime(time) + ' - ' + msg + ' '; @@ -7364,19 +7380,19 @@ if (event.etype == 'server') icon = 'si3'; if (event.etype == 'relay') icon = 'relayIcon16'; - var msg = event.msg.split('(R)').join('®'); + var msg = EscapeHtml(event.msg).split('(R)').join('®'); if (event.nodeid) { var node = getNodeFromId(event.nodeid); if (node != null) { icon = 'si' + node.icon; - msg = '' + node.name + ' → ' + msg; + msg = '' + EscapeHtml(node.name) + ' → ' + msg; } } if (event.username) { if ((userinfo.siteadmin & 2) && (event.userid)) { - msg = '' + event.username + ' → ' + msg; + msg = '' + EscapeHtml(event.username) + ' → ' + msg; } else { - msg = event.username + ' → ' + msg; + msg = EscapeHtml(event.username) + ' → ' + msg; } } x += '
 ' + printTime(time) + ' - ' + msg + ' '; @@ -8070,19 +8086,19 @@ if (event.etype == 'server') icon = 'si3'; if (event.etype == 'relay') icon = 'relayIcon16'; - var msg = event.msg.split('(R)').join('®'); + var msg = EscapeHtml(event.msg).split('(R)').join('®'); if (event.nodeid) { var node = getNodeFromId(event.nodeid); if (node != null) { icon = 'si' + node.icon; - msg = '' + node.name + ' → ' + msg; + msg = '' + EscapeHtml(node.name) + ' → ' + msg; } } if (event.username && (event.username != currentUser.name)) { if ((userinfo.siteadmin & 2) && (event.userid)) { - msg = '' + event.username + ' → ' + msg; + msg = '' + EscapeHtml(event.username) + ' → ' + msg; } else { - msg = event.username + ' → ' + msg; + msg = EscapeHtml(event.username) + ' → ' + msg; } } x += '
 ' + printTime(time) + ' - ' + msg + ' ';