From a905bba83ce12e2b38382ca2eb730fa5c4fe9ef3 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Mon, 2 Nov 2020 00:44:07 -0800 Subject: [PATCH] Improved meshcore Intel AMT handling. --- MeshCentralServer.njsproj | 10 +- agents/meshcore.js | 212 +++++++++----------------- agents/modules_meshcore/amt-lme.js | 5 +- agents/modules_meshcore/amt-manage.js | 18 ++- meshagent.js | 23 ++- 5 files changed, 96 insertions(+), 172 deletions(-) diff --git a/MeshCentralServer.njsproj b/MeshCentralServer.njsproj index 28d4dbe8..0310d6a4 100644 --- a/MeshCentralServer.njsproj +++ b/MeshCentralServer.njsproj @@ -25,17 +25,16 @@ + - - @@ -53,15 +52,10 @@ + - - - - - - diff --git a/agents/meshcore.js b/agents/meshcore.js index 90df7d99..804c8733 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -389,9 +389,27 @@ function createMeshCore(agent) { // MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent. var meshCoreObj = { action: 'coreinfo', value: (require('MeshAgent').coreHash ? ('MeshCore CRC-' + crc32c(require('MeshAgent').coreHash)) : ('MeshCore v6')), caps: 14, root: require('user-sessions').isRoot() }; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript, 32 = Temporary Agent, 64 = Recovery Agent - // Get the operating system description string - try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; }); } catch (e) { } + try { require('os').name().then(function (v) { meshCoreObj.osdesc = v; meshCoreObjChanged(); }); } catch (e) { } + + // Setup logged in user monitoring (THIS IS BROKEN IN WIN7) + try { + var userSession = require('user-sessions'); + userSession.on('changed', function onUserSessionChanged() { + userSession.enumerateUsers().then(function (users) { + var u = [], a = users.Active; + 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. + } + meshCoreObj.users = u; + meshCoreObjChanged(); + }); + }); + userSession.emit('changed'); + //userSession.on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); }); + //userSession.on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); }); + } catch (e) { } var meshServerConnectionState = 0; var tunnels = {}; @@ -447,17 +465,10 @@ function createMeshCore(agent) { // Check if this computer supports a desktop try { - if ((process.platform == 'win32') || (process.platform == 'darwin') || (require('monitor-info').kvm_x11_support)) - { - meshCoreObj.caps |= 1; - } - else if(process.platform == 'linux' || process.platform == 'freebsd') - { - require('monitor-info').on('kvmSupportDetected', function (value) - { - meshCoreObj.caps |= 1; - mesh.SendCommand(meshCoreObj); - }); + 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') { + require('monitor-info').on('kvmSupportDetected', function (value) { meshCoreObj.caps |= 1; meshCoreObjChanged(); }); } } catch (e) { } } @@ -498,31 +509,9 @@ function createMeshCore(agent) { { var amtmodule = require('amt-manage'); amt = new amtmodule(mesh, db, false); - amt.on('portBinding_LMS', function (map) - { - var j = { action: 'lmsinfo', value: { ports: map.keys() } }; - mesh.SendCommand(j); - }); - amt.on('stateChange_LMS', function (v) - { - if (!meshCoreObj.intelamt) { meshCoreObj.intelamt = {}; } - switch(v) - { - case 0: - meshCoreObj.intelamt.microlms = 'DISABLED'; - break; - case 1: - meshCoreObj.intelamt.microlms = 'CONNECTING'; - break; - case 2: - meshCoreObj.intelamt.microlms = 'CONNECTED'; - break; - default: - break; - } - mesh.SendCommand(meshCoreObj); - }); - amt.onStateChange = function (state) { if (state == 2) { sendPeriodicServerUpdate(1); } } + amt.on('portBinding_LMS', function (map) { mesh.SendCommand({ action: 'lmsinfo', value: { ports: map.keys() } }); }); + amt.on('stateChange_LMS', function (v) { if (!meshCoreObj.intelamt) { meshCoreObj.intelamt = {}; } meshCoreObj.intelamt.microlms = v; meshCoreObjChanged(); }); // 0 = Disabled, 1 = Connecting, 2 = Connected + amt.onStateChange = function (state) { if (state == 2) { sendPeriodicServerUpdate(1); } } // MEI State amt.reset(); } } @@ -2590,7 +2579,7 @@ function createMeshCore(agent) { var response = null; switch (cmd) { case 'help': { // Displays available commands - var fin = '', f = '', availcommands = '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,sendcaps,openurl,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,wallpaper,agentmsg'; + var fin = '', f = '', availcommands = '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'; } if (amt != null) { availcommands += ',amt,amtconfig,amtevents'; } if (process.platform != 'freebsd') { availcommands += ',vm';} @@ -2610,6 +2599,10 @@ function createMeshCore(agent) { response = JSON.stringify(meshCoreObj, null, 2); break; } + case 'coreinfoupdate': { + sendPeriodicServerUpdate(); + break; + } case 'agentmsg': { if (args['_'].length == 0) { response = "Proper usage:\r\n agentmsg add \"[message]\" [iconIndex]\r\n agentmsg remove [index]\r\n agentmsg list"; // Display usage @@ -3211,26 +3204,6 @@ function createMeshCore(agent) { } break; } - case 'sendcaps': { // Send capability flags to the server - if (args['_'].length == 0) { - response = 'Proper usage: sendcaps (number)'; // Display correct command usage - } else { - meshCoreObj.caps = parseInt(args['_'][0]); - mesh.SendCommand(meshCoreObj); - response = JSON.stringify(meshCoreObj); - } - break; - } - case 'sendosdesc': { // Send OS description - if (args['_'].length > 0) { - meshCoreObj.osdesc = args['_'][0]; - mesh.SendCommand(meshCoreObj); - response = JSON.stringify(meshCoreObj); - } else { - response = 'Proper usage: sendosdesc [os description]'; // Display correct command usage - } - break; - } case 'args': { // Displays parsed command arguments response = 'args ' + objToString(args, 0, ' ', true); break; @@ -3669,13 +3642,10 @@ function createMeshCore(agent) { var oldNodeId = db.Get('OldNodeId'); if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); } - // Update the server with basic info, logged in users and more. - mesh.SendCommand(meshCoreObj); - // Send SMBios tables if present if (SMBiosTablesRaw != null) { mesh.SendCommand({ action: 'smbios', value: SMBiosTablesRaw }); } - // Update the server on more advanced stuff, like Intel ME and Network Settings + // Update the server on with basic info, logged in users and more advanced stuff, like Intel ME and Network Settings meInfoStr = null; sendPeriodicServerUpdate(); if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes @@ -3710,103 +3680,57 @@ function createMeshCore(agent) { } // Called periodically to check if we need to send updates to the server - function sendPeriodicServerUpdate(flags) { + function sendPeriodicServerUpdate(flags, force) { if (meshServerConnectionState == 0) return; // Not connected to server, do nothing. if (!flags) { flags = 0xFFFFFFFF; } - if ((flags & 1) && (amt != null)) { - // If we have a connected MEI, get Intel ME information - amt.getMeiState(11, function (meinfo) { - try { - if (meinfo == null) return; - var intelamt = {}; - if (amt != null) - { - switch(amt.lmsstate) - { - case 0: intelamt.microlms = 'DISABLED'; break; - case 1: intelamt.microlms = 'CONNECTING'; break; - case 2: intelamt.microlms = 'CONNECTED'; break; - default: intelamt.microlms = 'unknown'; break; - } - } - var p = false; - if ((meinfo.Versions != null) && (meinfo.Versions.AMT != null)) { intelamt.ver = meinfo.Versions.AMT; p = true; if (meinfo.Versions.Sku != null) { intelamt.sku = parseInt(meinfo.Versions.Sku); } } - if (meinfo.ProvisioningState != null) { intelamt.state = meinfo.ProvisioningState; p = true; } - if (meinfo.Flags != null) { intelamt.flags = meinfo.Flags; p = true; } - if (meinfo.OsHostname != null) { intelamt.host = meinfo.OsHostname; p = true; } - if (meinfo.UUID != null) { intelamt.uuid = meinfo.UUID; p = true; } - if ((meinfo.ProvisioningState == 0) && (meinfo.net0 != null) && (meinfo.net0.enabled == 1)) { // If not activated, look to see if we have wired net working. - // Not activated and we have wired ethernet, look for the trusted DNS - var dns = meinfo.DNS; - if (dns == null) { - // Trusted DNS not set, let's look for the OS network DNS suffix - var interfaces = require('os').networkInterfaces(); - for (var i in interfaces) { - for (var j in interfaces[i]) { - if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { dns = interfaces[i][j].fqdn; } - } - } - } - if (intelamt.dns != dns) { intelamt.dns = dns; p = true; } - } else { if (intelamt.dns != null) { delete intelamt.dns; p = true; } } - if (p == true) { - var meInfoStr = JSON.stringify(intelamt); - if (meInfoStr != lastMeInfo) { - meshCoreObj.intelamt = intelamt; - mesh.SendCommand(meshCoreObj); - lastMeInfo = meInfoStr; - } - } - } catch (e) { } + // If we have a connected MEI, get Intel ME information + if ((flags & 1) && (amt != null) && (amt.state == 2)) { + delete meshCoreObj.intelamt; + amt.getMeiState(9, function (meinfo) { + meshCoreObj.intelamt = meinfo; + meshCoreObj.intelamt.microlms = amt.lmsstate; + meshCoreObjChanged(); }); } - if (flags & 2) { - // Update network information - sendNetworkUpdateNagle(false); + // Update network information + if (flags & 2) { sendNetworkUpdateNagle(false); } + + // Update anti-virus information + 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 } - if ((flags & 4) && (process.platform == 'win32')) { - // Update anti-virus information - // Windows Command: "wmic /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct get /FORMAT:CSV" - var av, pr; - try { av = require('win-info').av(); } catch (e) { av = null; } // Antivirus - //if (process.platform == 'win32') { try { pr = require('win-info').pendingReboot(); } catch (e) { pr = null; } } // Pending reboot - if ((meshCoreObj.av == null) || (JSON.stringify(meshCoreObj.av) != JSON.stringify(av))) { meshCoreObj.av = av; mesh.SendCommand(meshCoreObj); } + // Send available data right now + if (force) { + meshCoreObj = sortObjRec(meshCoreObj); + var x = JSON.stringify(meshCoreObj); + if (x != LastPeriodicServerUpdate) { LastPeriodicServerUpdate = x; mesh.SendCommand(meshCoreObj); } } } + // Once we are done collecting all the data, send to server if needed + var LastPeriodicServerUpdate = null; + var PeriodicServerUpdateNagleTimer = null; + function meshCoreObjChanged() { if (PeriodicServerUpdateNagleTimer == null) { PeriodicServerUpdateNagleTimer = setTimeout(meshCoreObjChangedEx, 500); } } + function meshCoreObjChangedEx() { + PeriodicServerUpdateNagleTimer = null; + meshCoreObj = sortObjRec(meshCoreObj); + var x = JSON.stringify(meshCoreObj); + if (x != LastPeriodicServerUpdate) { LastPeriodicServerUpdate = x; mesh.SendCommand(meshCoreObj); } + } + + function sortObjRec(o) { if (typeof o != 'object') return o; for (var i in o) { if (typeof o[i] == 'object') { o[i] = sortObjRec(o[i]); } } return sortObj(o); } + function sortObj(o) { return Object.keys(o).sort().reduce(function (result, key) { result[key] = o[key]; return result; }, {}); } + // Starting function obj.start = function () { // Setup the mesh agent event handlers mesh.AddCommandHandler(handleServerCommand); mesh.AddConnectHandler(handleServerConnection); - - // Parse input arguments - //var args = parseArgs(process.argv); - //console.log(args); - - //resetMicroLms(); - - // Setup logged in user monitoring (THIS IS BROKEN IN WIN7) - try { - var userSession = require('user-sessions'); - userSession.on('changed', function onUserSessionChanged() { - userSession.enumerateUsers().then(function (users) { - var u = [], a = users.Active; - 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. - } - meshCoreObj.users = u; - mesh.SendCommand(meshCoreObj); - }); - }); - userSession.emit('changed'); - //userSession.on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); }); - //userSession.on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); }); - } catch (e) { } } obj.stop = function () { diff --git a/agents/modules_meshcore/amt-lme.js b/agents/modules_meshcore/amt-lme.js index d27ce0f9..2a9a4342 100644 --- a/agents/modules_meshcore/amt-lme.js +++ b/agents/modules_meshcore/amt-lme.js @@ -17,7 +17,8 @@ limitations under the License. var MemoryStream = require('MemoryStream'); var lme_id = 0; // Our next channel identifier var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging. -var xmlParser = require('amt-xml'); +var xmlParser = null; +try { xmlParser = require('amt-xml'); } catch (ex) { } // Documented in: https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/HTMLDocuments/MPSDocuments/Intel%20AMT%20Port%20Forwarding%20Protocol%20Reference%20Manual.pdf var APF_DISCONNECT = 1; @@ -302,7 +303,7 @@ function lme_heci(options) { if ((httpData != null) || (channel.data.length >= 8000)) { // Parse the WSMAN var notify = null; - try { notify = xmlParser.ParseWsman(httpData); } catch (e) { } + if (xmlParser != null) { try { notify = xmlParser.ParseWsman(httpData); } catch (e) { } } // Event the http data if (notify != null) { this.LMS.emit('notify', notify, channel.options, _lmsNotifyToCode(notify)); } diff --git a/agents/modules_meshcore/amt-manage.js b/agents/modules_meshcore/amt-manage.js index fbd1c2a1..2827fff3 100644 --- a/agents/modules_meshcore/amt-manage.js +++ b/agents/modules_meshcore/amt-manage.js @@ -83,12 +83,19 @@ function AmtManager(agent, db, isdebug) { // Get Intel MEI State in a flexible way // Flags: 1 = Versions, 2 = OsAdmin, 4 = Hashes, 8 = Network + var getMeiStateCache = {}; // Some MEI calls will only be made once and cached here. obj.getMeiState = function(flags, func) { if ((amtMei == null) || (amtMeiState < 2)) { if (func != null) { func(null); } return; } try { var amtMeiTmpState = { OsHostname: require('os').hostname(), Flags: 0 }; // Flags: 1=EHBC, 2=CCM, 4=ACM - amtMei.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } }); - if ((flags & 1) != 0) { amtMei.getVersion(function (result) { if (result) { amtMeiTmpState.Versions = {}; for (var version in result.Versions) { amtMeiTmpState.Versions[result.Versions[version].Description] = result.Versions[version].Version; } } }); } + if (getMeiStateCache.MeiVersion != null) { amtMeiTmpState.MeiVersion = getMeiStateCache.MeiVersion; } else { amtMei.getProtocolVersion(function (result) { if (result != null) { getMeiStateCache.MeiVersion = amtMeiTmpState.MeiVersion = result; } }); } + if ((flags & 1) != 0) { + if (getMeiStateCache.Versions != null) { + amtMeiTmpState.Versions = getMeiStateCache.Versions; + } else { + amtMei.getVersion(function (result) { if (result) { getMeiStateCache.Versions = 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; } }); // 0: "Not Activated (Pre)", 1: "Not Activated (In)", 2: "Activated" amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } }); @@ -104,7 +111,7 @@ function AmtManager(agent, db, isdebug) { }); amtMei.getLanInterfaceSettings(1, function (result) { if (result) { amtMeiTmpState.net1 = result; } }); } - amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { amtMeiTmpState.UUID = result.uuid; } }); + if (getMeiStateCache.UUID != null) { amtMeiTmpState.UUID = getMeiStateCache.UUID; } else { amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { getMeiStateCache.UUID = amtMeiTmpState.UUID = result.uuid; } }); } if ((flags & 2) != 0) { amtMei.getLocalSystemAccount(function (x) { if ((x != null) && x.user && x.pass) { amtMeiTmpState.OsAdmin = { user: x.user, pass: x.pass }; } }); } amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.DnsSuffix = result; } if ((flags & 4) == 0) { if (func != null) { func(amtMeiTmpState); } } }); if ((flags & 4) != 0) { @@ -144,7 +151,10 @@ function AmtManager(agent, db, isdebug) { amtLms.on('connect', function () { amtLmsState = 2; obj.lmsstate = 2; debug("LMS connected"); }); amtLms.on('bind', function (map) { obj._mapping = map; obj.emit('portBinding_LMS', map); }); amtLms.on('notify', function (data, options, code) { handleAmtNotification(data); }); - } catch (e) { amtLmsState = -1; obj.lmsstate = -1; amtLms = null; } + } catch (ex) { + require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: "ex: " + ex }); + amtLmsState = -1; obj.lmsstate = -1; amtLms = null; + } } } diff --git a/meshagent.js b/meshagent.js index e66d42a4..cf113534 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1135,7 +1135,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { case 'coreinfo': { // Sent by the agent to update agent information - // TODO: Check that this does not include outdates Intel AMT information ChangeAgentCoreInfo(command); break; } @@ -1442,8 +1441,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if (device.agent) { var changes = [], change = 0, log = 0; - //if (command.users) { console.log(command.users); } - // Check if anything changes if (command.name && (typeof command.name == 'string') && (command.name != device.name)) { change = 1; log = 1; device.name = command.name; changes.push('name'); } if ((command.caps != null) && (device.agent.core != command.value)) { if ((command.value == null) && (device.agent.core != null)) { delete device.agent.core; } else { device.agent.core = command.value; } change = 1; } // Don't save this as an event to the db. @@ -1453,18 +1450,16 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if (device.ip != obj.remoteaddr) { device.ip = obj.remoteaddr; change = 1; } if (command.intelamt) { if (!device.intelamt) { device.intelamt = {}; } - if ((command.intelamt.ver != null) && (typeof command.intelamt.ver == 'string') && (command.intelamt.ver.length < 12) && (device.intelamt.ver != command.intelamt.ver)) { changes.push('AMT version'); device.intelamt.ver = command.intelamt.ver; change = 1; log = 1; } - if ((command.intelamt.sku != null) && (typeof command.intelamt.sku == 'number') && (device.intelamt.sku !== command.intelamt.sku)) { changes.push('AMT SKU'); device.intelamt.sku = command.intelamt.sku; change = 1; log = 1; } - if ((command.intelamt.state != null) && (typeof command.intelamt.state == 'number') && (device.intelamt.state != command.intelamt.state)) { changes.push('AMT state'); console.log('agent', device.intelamt.state, command.intelamt.state); device.intelamt.state = command.intelamt.state; change = 1; log = 1; } - if ((command.intelamt.flags != null) && (typeof command.intelamt.flags == 'number') && (device.intelamt.flags != command.intelamt.flags)) { - if (device.intelamt.flags) { changes.push('AMT flags (' + device.intelamt.flags + ' --> ' + command.intelamt.flags + ')'); } else { changes.push('AMT flags (' + command.intelamt.flags + ')'); } - device.intelamt.flags = command.intelamt.flags; change = 1; log = 1; + if ((command.intelamt.Versions != null) && (typeof command.intelamt.Versions == 'object')) { + if ((command.intelamt.Versions.AMT != null) && (typeof command.intelamt.Versions.AMT == 'string') && (command.intelamt.Versions.AMT.length < 12) && (device.intelamt.ver != command.intelamt.Versions.AMT)) { changes.push('AMT version'); device.intelamt.ver = command.intelamt.Versions.AMT; change = 1; log = 1; } + if ((command.intelamt.Versions.Sku != null) && (typeof command.intelamt.Versions.Sku == 'string')) { var sku = parseInt(command.intelamt.Versions.Sku); if (device.intelamt.sku !== command.intelamt.sku) { device.intelamt.sku = sku; change = 1; log = 1; } } } - if ((command.intelamt.realm != null) && (typeof command.intelamt.realm == 'string') && (device.intelamt.realm != command.intelamt.realm)) { changes.push('AMT realm'); device.intelamt.realm = command.intelamt.realm; change = 1; log = 1; } - //if ((command.intelamt.host != null) && (typeof command.intelamt.host == 'string') && (device.intelamt.host != command.intelamt.host)) { changes.push('AMT host'); device.intelamt.host = command.intelamt.host; change = 1; log = 1; } - if ((command.intelamt.uuid != null) && (typeof command.intelamt.uuid == 'string') && (device.intelamt.uuid != command.intelamt.uuid)) { changes.push('AMT uuid'); device.intelamt.uuid = command.intelamt.uuid; change = 1; log = 1; } - if ((command.intelamt.user != null) && (typeof command.intelamt.user == 'string') && (device.intelamt.user != command.intelamt.user)) { changes.push('AMT user'); device.intelamt.user = command.intelamt.user; change = 1; log = 1; } - if ((command.intelamt.pass != null) && (typeof command.intelamt.pass == 'string') && (device.intelamt.pass != command.intelamt.pass)) { changes.push('AMT pass'); device.intelamt.pass = command.intelamt.pass; change = 1; log = 1; } + if ((command.intelamt.ProvisioningState != null) && (typeof command.intelamt.ProvisioningState == 'number') && (device.intelamt.state != command.intelamt.ProvisioningState)) { changes.push('AMT state'); device.intelamt.state = command.intelamt.ProvisioningState; change = 1; log = 1; } + if ((command.intelamt.Flags != null) && (typeof command.intelamt.Flags == 'number') && (device.intelamt.flags != command.intelamt.Flags)) { + if (device.intelamt.flags) { changes.push('AMT flags (' + device.intelamt.flags + ' --> ' + command.intelamt.Flags + ')'); } else { changes.push('AMT flags (' + command.intelamt.Flags + ')'); } + device.intelamt.flags = command.intelamt.Flags; change = 1; log = 1; + } + if ((command.intelamt.UUID != null) && (typeof command.intelamt.UUID == 'string') && (device.intelamt.uuid != command.intelamt.UUID)) { changes.push('AMT uuid'); device.intelamt.uuid = command.intelamt.UUID; change = 1; log = 1; } } if (command.av) { if (!device.av) { device.av = []; }