From 8d45bcdde92e419f760421b7b6e1a5438ee812a3 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Thu, 27 Sep 2018 16:17:05 -0700 Subject: [PATCH] Improved MEI/SMBios in meshcore.js --- agents/meshcore.js | 113 ++++++++++++++++++++++++--------------------- db.js | 8 ++-- meshagent.js | 11 +++++ meshuser.js | 3 +- 4 files changed, 78 insertions(+), 57 deletions(-) diff --git a/agents/meshcore.js b/agents/meshcore.js index 947e0d37..af8dca97 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -73,7 +73,6 @@ function createMeshCore(agent) { var fs = require('fs'); var rtc = require('ILibWebRTC'); var processManager = require('process-manager'); - var SMBiosTables = require('smbios'); var amtMei = null, amtLms = null, amtLmsState = 0; var amtMeiConnected = 0, amtMeiTmpState = null; var wifiScannerLib = null; @@ -81,7 +80,25 @@ function createMeshCore(agent) { var networkMonitor = null; var amtscanner = null; var nextTunnelIndex = 1; - + + // If we are running in Duktape, agent will be null + if (agent == null) { + // Running in native agent, Import libraries + db = require('SimpleDataStore').Shared(); + sha = require('SHA256Stream'); + mesh = require('MeshAgent'); + childProcess = require('child_process'); + 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)) { obj.meshCoreCapabilities |= 1; } } catch (ex) { } + } + } else { + // Running in nodejs + obj.meshCoreInfo += '-NodeJS'; + obj.meshCoreCapabilities = 8; + mesh = agent.getMeshApi(); + } + // Get the operating system description string var osDesc = null; try { require('os').name().then(function (v) { osDesc = v; if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "coreinfo", "value": obj.meshCoreInfo, "osdesc": osDesc }); } }); } catch (ex) { } @@ -118,15 +135,29 @@ function createMeshCore(agent) { amtscanner = new AMTScannerModule(); //amtscanner.on('found', function (data) { if (typeof data != 'string') { data = JSON.stringify(data, null, " "); } sendConsoleText(data); }); } catch (ex) { amtscanner = null; } - - // Try to load up the MEI module - try { - var amtMeiLib = require('amt-mei'); - amtMei = new amtMeiLib(); - amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; }); - amtMeiConnected = 2; - sendPeriodicServerUpdate(1); - } catch (ex) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; } + + // Fetch the SMBios Tables + var SMBiosTables = null; + var SMBiosTablesRaw = null; + require('smbios').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 AMT is present, try to connect MEI + if (SMBiosTables.amtInfo && (SMBiosTables.amtInfo.AMT == true)) { + // Try to load up the MEI module + try { + var amtMeiLib = require('amt-mei'); + amtMei = new amtMeiLib(); + amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; }); + amtMeiConnected = 2; + sendPeriodicServerUpdate(1); + } catch (ex) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; } + } + } + }); // Try to load up the WIFI scanner try { @@ -135,24 +166,6 @@ function createMeshCore(agent) { wifiScanner.on('accessPoint', function (data) { sendConsoleText(JSON.stringify(data)); }); } catch (ex) { wifiScannerLib = null; wifiScanner = null; } - // If we are running in Duktape, agent will be null - if (agent == null) { - // Running in native agent, Import libraries - db = require('SimpleDataStore').Shared(); - sha = require('SHA256Stream'); - mesh = require('MeshAgent'); - childProcess = require('child_process'); - 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)) { obj.meshCoreCapabilities |= 1; } } catch (ex) { } - } - } else { - // Running in nodejs - obj.meshCoreInfo += '-NodeJS'; - obj.meshCoreCapabilities = 8; - mesh = agent.getMeshApi(); - } - // Get our location (lat/long) using our public IP address var getIpLocationDataExInProgress = false; var getIpLocationDataExCounts = [0, 0]; @@ -972,31 +985,22 @@ function createMeshCore(agent) { break; } case 'smbios': { - if (SMBiosTables != null) { - SMBiosTables.get(function (data) { - if (data == null) { sendConsoleText('Unable to get SM BIOS data.', sessionid); return; } - sendConsoleText(objToString(SMBiosTables.parse(data), 0, ' ', true), sessionid); - }); - } else { response = 'SM BIOS module not available.'; } + if (SMBiosTables == null) { response = 'SMBios tables not available.'; } else { response = objToString(SMBiosTables, 0, ' ', true); } break; } case 'rawsmbios': { - if (SMBiosTables != null) { - SMBiosTables.get(function (data) { - if (data == null) { sendConsoleText('Unable to get SM BIOS data.', sessionid); return; } - var out = ''; - for (var i in data) { - var header = false; - for (var j in data[i]) { - if (data[i][j].length > 0) { - if (header == false) { out += ('Table type #' + i + ((SMBiosTables.smTableTypes[i] == null) ? '' : (', ' + SMBiosTables.smTableTypes[i]))) + '\r\n'; header = true; } - out += (' ' + data[i][j].toString('hex')) + '\r\n'; - } + if (SMBiosTablesRaw == null) { response = 'SMBios tables not available.'; } else { + response = ''; + for (var i in SMBiosTablesRaw) { + var header = false; + 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'; } } - sendConsoleText(out, sessionid); - }); - } else { response = 'SM BIOS module not available.'; } + } + } break; } case 'eval': { // Eval JavaScript @@ -1358,11 +1362,14 @@ function createMeshCore(agent) { var oldNodeId = db.Get('OldNodeId'); if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); } - // Update the server wtih basic info + // Update the server with basic info var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities }; if (osDesc != null) { r.osdesc = osDesc; } mesh.SendCommand(r); + // Send SMBios tables if present + if (SMBiosTablesRaw != null) { mesh.SendCommand({ "action": "smbios", "value": SMBiosTablesRaw }); } + // Update list of logged in users if (obj.loggedInUsers != null) { mesh.SendCommand({ "action": "coreinfo", "v": { "users": obj.loggedInUsers } }); } @@ -1422,9 +1429,9 @@ function createMeshCore(agent) { try { amtMeiTmpState = { Flags: 0 }; // Flags: 1=EHBC, 2=CCM, 4=ACM amtMei.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } }); - amtMei.getVersion(function (val) { amtMeiTmpState.Versions = {}; for (var version in val.Versions) { amtMeiTmpState.Versions[val.Versions[version].Description] = val.Versions[version].Version; } }); - amtMei.getProvisioningMode(function (result) { amtMeiTmpState.ProvisioningMode = result.mode; }); - amtMei.getProvisioningState(function (result) { amtMeiTmpState.ProvisioningState = result.state; }); + amtMei.getVersion(function (result) { if (result) { amtMeiTmpState.Versions = {}; for (var version in result.Versions) { amtMeiTmpState.Versions[result.Versions[version].Description] = result.Versions[version].Version; } } }); + amtMei.getProvisioningMode(function (result) { if (result) { amtMeiTmpState.ProvisioningMode = result.mode; } }); + amtMei.getProvisioningState(function (result) { if (result) { amtMeiTmpState.ProvisioningState = result.state; } }); amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } }); amtMei.getControlMode(function (result) { if (result != null) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } } }); amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { amtMeiTmpState.UUID = result.uuid; } }); diff --git a/db.js b/db.js index 55a4c807..9e4c9abb 100644 --- a/db.js +++ b/db.js @@ -129,9 +129,11 @@ module.exports.CreateDB = function (parent) { obj.file.count({ type: 'user' }, function (err, userCount) { obj.file.count({ type: 'ifinfo' }, function (err, nodeInterfaceCount) { obj.file.count({ type: 'note' }, function (err, noteCount) { - obj.file.count({ type: 'lastconnect' }, function (err, nodeLastConnectCount) { - obj.file.count({ }, function (err, totalCount) { - func({ nodes: nodeCount, meshes: meshCount, powerEvents: powerCount, users: userCount, nodeInterfaces: nodeInterfaceCount, notes: noteCount, connectEvent: nodeLastConnectCount, total: totalCount }); + obj.file.count({ type: 'smbios' }, function (err, nodeSmbiosCount) { + obj.file.count({ type: 'lastconnect' }, function (err, nodeLastConnectCount) { + obj.file.count({ }, function (err, totalCount) { + func({ nodes: nodeCount, meshes: meshCount, powerEvents: powerCount, users: userCount, nodeInterfaces: nodeInterfaceCount, notes: noteCount, connectEvent: nodeLastConnectCount, smbios: nodeSmbiosCount, total: totalCount }); + }); }); }); }); diff --git a/meshagent.js b/meshagent.js index 702e3e11..dcc80006 100644 --- a/meshagent.js +++ b/meshagent.js @@ -69,6 +69,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { obj.db.Remove('if' + obj.dbNodeKey); // Remove interface information obj.db.Remove('nt' + obj.dbNodeKey); // Remove notes obj.db.Remove('lc' + obj.dbNodeKey); // Remove last connect time + obj.db.Remove('sm' + obj.dbNodeKey); // Remove SMBios data obj.db.RemoveNode(obj.dbNodeKey); // Remove all entries with node:id // Event node deletion @@ -522,6 +523,16 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { { // Sent by the agent to update agent information ChangeAgentCoreInfo(command); + break; + } + case 'smbios': + { + // The RAW SMBios table of this computer + obj.db.Set({ _id: 'sm' + obj.dbNodeKey, type: 'smbios', domain: domain.id, time: Date.now(), smbios: command.value }); + + // Event the node interface information change (This is a lot of traffic, probably don't need this). + //obj.parent.parent.DispatchEvent(['*', obj.meshid], obj, { action: 'smBiosChange', nodeid: obj.dbNodeKey, domain: domain.id, smbios: command.value, nolog: 1 }); + break; } case 'netinfo': diff --git a/meshuser.js b/meshuser.js index ba6ed0f2..c9696732 100644 --- a/meshuser.js +++ b/meshuser.js @@ -131,7 +131,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) { if (obj.parent.parent.platform != 'win32') { stats.cpuavg = os.loadavg(); } // else { stats.cpuavg = [ 0.2435345, 0.523234234, 0.6435345345 ]; } var serverStats = { "User Accounts": Object.keys(obj.parent.users).length, "Device Groups": Object.keys(obj.parent.meshes).length, "Connected Agents": Object.keys(obj.parent.wsagents).length, "Connected Users": Object.keys(obj.parent.wssessions2).length }; if (obj.parent.parent.mpsserver != null) { serverStats['Connected Intel® AMT'] = Object.keys(obj.parent.parent.mpsserver.ciraConnections).length; } - stats.values = { "Server State": serverStats, "Database": { "Records": data.total, "Users": data.users, "Device Groups": data.meshes, "Devices": data.nodes, "Device NetInfo": data.nodeInterfaces, "Device Power Event": data.powerEvents, "Notes": data.notes, "Connection Records": data.connectEvents } } + stats.values = { "Server State": serverStats, "Database": { "Records": data.total, "Users": data.users, "Device Groups": data.meshes, "Devices": data.nodes, "Device NetInfo": data.nodeInterfaces, "Device Power Event": data.powerEvents, "Notes": data.notes, "Connection Records": data.connectEvents, "SMBios": data.smbios } } try { ws.send(JSON.stringify(stats)); } catch (ex) { } }); } @@ -865,6 +865,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) { obj.db.Remove('if' + node._id); // Remove interface information obj.db.Remove('nt' + node._id); // Remove notes obj.db.Remove('lc' + node._id); // Remove last connect time + obj.db.Remove('sm' + node._id); // Remove SMBios data obj.db.RemoveNode(node._id); // Remove all entries with node:id // Event node deletion