diff --git a/MeshCentralServer.njsproj b/MeshCentralServer.njsproj index af52c4fa..a62f2e11 100644 --- a/MeshCentralServer.njsproj +++ b/MeshCentralServer.njsproj @@ -35,9 +35,9 @@ - + @@ -63,6 +63,7 @@ + diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index 5f6a8d4a..2279702f 100644 Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ diff --git a/agents/MeshCmd64-signed.exe b/agents/MeshCmd64-signed.exe index 14e57f47..2a0e402d 100644 Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ diff --git a/agents/meshcmd.js b/agents/meshcmd.js index 05026e42..e8dec629 100644 --- a/agents/meshcmd.js +++ b/agents/meshcmd.js @@ -2722,7 +2722,7 @@ function getMeiState(flags, func) { try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { func(null); return; } amtMei.on('error', function (e) { func(null); return; }); try { - var amtMeiTmpState = { OsHostname: require('os').hostname(), Flags: 0 }; // Flags: 1=EHBC, 2=CCM, 4=ACM + var amtMeiTmpState = { 'core-ver': 1, 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; } } }); } amtMei.getProvisioningMode(function (result) { if (result) { amtMeiTmpState.ProvisioningMode = result.mode; } }); diff --git a/agents/meshcore.js b/agents/meshcore.js index 620534e4..5b454dfb 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -1198,14 +1198,16 @@ function handleServerCommand(data) { } if (data.action == 'close') { try { apftunnel.disconnect(); } catch (e) { } apftunnel = null; } // Close the CIRA-LMS connection if (data.action == 'startTlsHostConfig') { // Request start of host based TLS ACM activation - amt.startConfigurationHBased(Buffer.from(data.hash, 'hex'), data.hostVpn, data.dnsSuffixList, function (response) { - apftunnel.sendStartTlsHostConfigResponse(response); - }); + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { if (apftunnel) apftunnel.sendMeiDeactivationState(1); return; } + amtMei.on('error', function (e) { if (apftunnel) apftunnel.sendStartTlsHostConfigResponse({ state: -104 }); }); + amtMei.startConfigurationHBased(Buffer.from(data.hash, 'hex'), data.hostVpn, data.dnsSuffixList, function (response) { apftunnel.sendStartTlsHostConfigResponse(response); }); } if (data.action == 'stopConfiguration') { // Request Intel AMT stop configuration. - amt.stopConfiguration(function (response) { - apftunnel.sendStopConfigurationResponse(response); - }); + var amtMeiModule, amtMei; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { if (apftunnel) apftunnel.sendMeiDeactivationState(1); return; } + amtMei.on('error', function (e) { if (apftunnel) apftunnel.sendStopConfigurationResponse({ state: -104 }); }); + amtMei.stopConfiguration(function (status) { apftunnel.sendStopConfigurationResponse(status); }); } } apftunnel.onChannelClosed = function () { addAmtEvent('LMS tunnel closed.'); apftunnel = null; } @@ -1232,7 +1234,7 @@ function handleServerCommand(data) { break; } case 'coredump': - // Set the current agent coredump situation. + // Set the current agent coredump situation.s if (data.value === true) { if (process.platform == 'win32') { // TODO: This replace() below is not ideal, would be better to remove the .exe at the end instead of replace. diff --git a/agents/modules_meshcore/amt-manage.js b/agents/modules_meshcore/amt-manage.js index 8fb38542..63af1289 100644 --- a/agents/modules_meshcore/amt-manage.js +++ b/agents/modules_meshcore/amt-manage.js @@ -87,7 +87,7 @@ function AmtManager(agent, db, isdebug) { 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 + var amtMeiTmpState = { 'core-ver': 1, OsHostname: require('os').hostname(), Flags: 0 }; // Flags: 1=EHBC, 2=CCM, 4=ACM 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) { diff --git a/amtmanager.js b/amtmanager.js index 747f3870..6be15300 100644 --- a/amtmanager.js +++ b/amtmanager.js @@ -242,9 +242,18 @@ module.exports.CreateAmtManager = function (parent) { deactivateIntelAmtCCMEx(dev, jsondata.value); break; case 'meiState': - if (dev.pendingUpdatedMeiState != 1) break; - delete dev.pendingUpdatedMeiState; - attemptInitialContact(dev); + if (dev.acmactivate == 1) { + // Continue ACM activation + dev.consoleMsg("Got new Intel AMT MEI state. Holding 40 seconds prior to ACM activation..."); + delete dev.acmactivate; + var continueAcmFunc = function continueAcm() { if (isAmtDeviceValid(continueAcm.dev)) { activateIntelAmtAcmEx0(continueAcm.dev); } } + continueAcmFunc.dev = dev; + setTimeout(continueAcmFunc, 40000); + } else { + if (dev.pendingUpdatedMeiState != 1) break; + delete dev.pendingUpdatedMeiState; + attemptInitialContact(dev); + } break; case 'startTlsHostConfig': if (dev.acmTlsInfo == null) break; @@ -256,10 +265,14 @@ module.exports.CreateAmtManager = function (parent) { break; case 'stopConfiguration': if (dev.acmactivate != 1) break; - delete dev.acmactivate; - if (jsondata.value == 3) { activateIntelAmtAcmEx0(dev); } // Intel AMT was already not in in-provisioning state, keep going right away. - else if (jsondata.value == 0) { dev.consoleMsg("Cleared in-provisioning state. Holding 20 seconds prior to ACM activation..."); setTimeout(function () { activateIntelAmtAcmEx0(dev); }, 20000); } - else { dev.consoleMsg("Unknown stopConfiguration() state of " + jsondata.value + ". Continuing with ACM activation..."); activateIntelAmtAcmEx0(dev); } + if (jsondata.value == 3) { delete dev.acmactivate; activateIntelAmtAcmEx0(dev); } // Intel AMT was already not in in-provisioning state, keep going right away. + else if (jsondata.value == 0) { + dev.consoleMsg("Cleared in-provisioning state. Holding 30 seconds prior to getting Intel AMT MEI state..."); + var askStateFunc = function askState() { if (isAmtDeviceValid(askState.dev)) { askState.dev.controlMsg({ action: 'mestate' }); } } + askStateFunc.dev = dev; + setTimeout(askStateFunc, 30000); + } + else { dev.consoleMsg("Unknown stopConfiguration() state of " + jsondata.value + ". Continuing with ACM activation..."); delete dev.acmactivate; activateIntelAmtAcmEx0(dev); } break; } } @@ -1813,23 +1826,31 @@ module.exports.CreateAmtManager = function (parent) { // Attempt Intel AMT TLS ACM activation function activateIntelAmtTlsAcm(dev, password, acminfo) { - // Generate a random Intel AMT password if needed - if ((password == null) || (password == '')) { password = getRandomAmtPassword(); } - dev.temp = { pass: password, acminfo: acminfo }; + // Check if MeshAgent/MeshCMD can support the startConfigurationhostB() call. + if ((dev.mpsConnection != null) && (dev.mpsConnection.tag != null) && (dev.mpsConnection.tag.meiState != null) && (typeof dev.mpsConnection.tag.meiState['core-ver'] == 'number') && (dev.mpsConnection.tag.meiState['core-ver'] > 0)) { + // Generate a random Intel AMT password if needed + if ((password == null) || (password == '')) { password = getRandomAmtPassword(); } + dev.temp = { pass: password, acminfo: acminfo }; - // Get our ACM activation certificate chain - var acmTlsInfo = parent.certificateOperations.getAcmCertChain(parent.config.domains[dev.domainid], dev.temp.acminfo.fqdn, dev.temp.acminfo.hash); - if (acmTlsInfo.error == 1) { dev.consoleMsg(acmTlsInfo.errorText); removeAmtDevice(dev, 44); return; } - dev.acmTlsInfo = acmTlsInfo; + // Get our ACM activation certificate chain + var acmTlsInfo = parent.certificateOperations.getAcmCertChain(parent.config.domains[dev.domainid], dev.temp.acminfo.fqdn, dev.temp.acminfo.hash); + if (acmTlsInfo.error == 1) { dev.consoleMsg(acmTlsInfo.errorText); removeAmtDevice(dev, 44); return; } + dev.acmTlsInfo = acmTlsInfo; - // Send the MEI command to enable TLS connections - dev.consoleMsg("Performing TLS ACM activation..."); - dev.controlMsg({ action: 'startTlsHostConfig', hash: acmTlsInfo.hash, hostVpn: false, dnsSuffixList: null }); + // Send the MEI command to enable TLS connections + dev.consoleMsg("Performing TLS ACM activation..."); + dev.controlMsg({ action: 'startTlsHostConfig', hash: acmTlsInfo.hash, hostVpn: false, dnsSuffixList: null }); + } else { + // MeshCore or MeshCMD is to old + dev.consoleMsg("This software is to old to support ACM activation, pleasse update and try again."); + removeAmtDevice(dev); + } } // Attempt Intel AMT TLS ACM activation after startConfiguration() is called on remote device function activateIntelAmtTlsAcmEx(dev, startConfigData) { - console.log('activateIntelAmtTlsAcmEx'); + console.log('activateIntelAmtTlsAcmEx', dev.mpsConnection.tag.meiState.OsAdmin.user, dev.mpsConnection.tag.meiState.OsAdmin.pass); + // Setup the WSMAN stack, no TLS var comm = CreateWsmanComm(dev.nodeid, 16993, 'admin', '', 1, { cert: dev.acmTlsInfo.certs, key: dev.acmTlsInfo.signkey }, dev.mpsConnection); // TLS with client certificate chain and key. // TODO: Intel AMT leaf TLS cert need to SHA256 hash to "startConfigData.hash" @@ -1843,25 +1864,39 @@ module.exports.CreateAmtManager = function (parent) { console.log('activateIntelAmtTlsAcmEx1', status, responses); const dev = stack.dev; if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request. - if (status != 200) { dev.consoleMsg("Failed to get Intel AMT state."); removeAmtDevice(dev, 45); return; } - - // TODO!!! + if (status != 200) { + dev.consoleMsg("Failed to perform ACM TLS connection, falling back to legacy host-based activation."); + activateIntelAmtAcm(dev); // Falling back to legacy WSMAN ACM activation, start by refreshing $$OsAdmin username and password. + } else { + // TODO!!! + } } // Attempt Intel AMT ACM activation function activateIntelAmtAcm(dev, password, acminfo) { - // Generate a random Intel AMT password if needed - if ((password == null) || (password == '')) { password = getRandomAmtPassword(); } - dev.temp = { pass: password, acminfo: acminfo }; - dev.acmactivate = 1; + // Check if MeshAgent/MeshCMD can support the stopConfiguration() call. + if ((dev.mpsConnection != null) && (dev.mpsConnection.tag != null) && (dev.mpsConnection.tag.meiState != null) && (typeof dev.mpsConnection.tag.meiState['core-ver'] == 'number') && (dev.mpsConnection.tag.meiState['core-ver'] > 0)) { + // Generate a random Intel AMT password if needed + if (acminfo != null) { + if ((password == null) || (password == '')) { password = getRandomAmtPassword(); } + dev.temp = { pass: password, acminfo: acminfo }; + } + dev.acmactivate = 1; - // Send the MEI command to stop configuration. - // If Intel AMT is "in-provisioning" mode, the WSMAN ACM activation will not work, so we need to do this first. - dev.consoleMsg("Getting ready for ACM activation..."); - dev.controlMsg({ action: 'stopConfiguration' }); + // Send the MEI command to stop configuration. + // If Intel AMT is "in-provisioning" mode, the WSMAN ACM activation will not work, so we need to do this first. + dev.consoleMsg("Getting ready for ACM activation..."); + dev.controlMsg({ action: 'stopConfiguration' }); + } else { + // MeshCore or MeshCMD is to old + dev.consoleMsg("This software is to old to support ACM activation, pleasse update and try again."); + removeAmtDevice(dev); + } } function activateIntelAmtAcmEx0(dev) { + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request. + // Setup the WSMAN stack, no TLS var comm = CreateWsmanComm(dev.nodeid, 16992, dev.mpsConnection.tag.meiState.OsAdmin.user, dev.mpsConnection.tag.meiState.OsAdmin.pass, 0, null, dev.mpsConnection); // No TLS var wsstack = WsmanStackCreateService(comm); diff --git a/meshcentral.js b/meshcentral.js index 5ef6ccf6..b746e1fc 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -454,7 +454,7 @@ function CreateMeshCentralServer(config, args) { if (error != null) { // This is an un-expected restart console.log(error); - console.log('ERROR: MeshCentral failed with critical error, check MeshErrors.txt. Restarting in 5 seconds...'); + console.log('ERROR: MeshCentral failed with critical error, check mesherrors.txt. Restarting in 5 seconds...'); setTimeout(function () { obj.launchChildServer(startArgs); }, 5000); } }