Added Intel AMT automated CCM password reset.

Ylian Saint-Hilaire committed Oct 21, 2020 at 13:04 UTC be06076694c7d3dc88acf8f61c50d83c89ce3b92
3 files changed +34 -37
amtmanager.js
+29 -31
@@ -249,10 +249,14 @@ module.exports.CreateAmtManager = function(parent) {
249 // Fetch Intel AMT setup policy
250 // mesh.amt.type: 0 = No Policy, 1 = Deactivate CCM, 2 = Manage in CCM, 3 = Manage in ACM
251 // mesh.amt.cirasetup: 0 = No Change, 1 = Remove CIRA, 2 = Setup CIRA
252 - var amtPolicy = 0, ciraPolicy = 0;
253 - if (mesh.amt != null) { if (mesh.amt.type) { amtPolicy = mesh.amt.type; } if (mesh.amt.cirasetup) { ciraPolicy = mesh.amt.cirasetup; } }
252 + var amtPolicy = 0, ciraPolicy = 0, badPass = 0;
253 + if (mesh.amt != null) {
254 + if (mesh.amt.type) { amtPolicy = mesh.amt.type; }
255 + if (mesh.amt.cirasetup) { ciraPolicy = mesh.amt.cirasetup; }
256 + if (mesh.amt.badpass) { badPass = mesh.amt.badpass; }
257 + }
258 if (amtPolicy < 2) { ciraPolicy = 0; }
255 - dev.policy = { amtPolicy: amtPolicy, ciraPolicy: ciraPolicy }
259 + dev.policy = { amtPolicy: amtPolicy, ciraPolicy: ciraPolicy, badPass: badPass };
260
261 // If there is no Intel AMT policy for this device, stop here.
262 if (amtPolicy == 0) { dev.consoleMsg("Done."); removeAmtDevice(dev); return; }
@@ -300,7 +304,7 @@ module.exports.CreateAmtManager = function(parent) {
304 }
305 }
306
303 - // If we ran out of credentials to try, give up here.
307 + // See if we need to try different credentials
308 if ((dev.acctry == null) && ((typeof dev.intelamt.user != 'string') || (typeof dev.intelamt.pass != 'string'))) {
309 if ((obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > 0)) { dev.acctry = 0; } else { removeAmtDevice(dev); return; }
310 }
@@ -474,9 +478,17 @@ module.exports.CreateAmtManager = function(parent) {
478 if ((dev.acctry == null) && (obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > 0)) { dev.acctry = 0; attemptInitialContact(dev); return; }
479 if ((dev.acctry != null) && (obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > (dev.acctry + 1))) { dev.acctry++; attemptInitialContact(dev); return; }
480
477 - // We are unable to authenticate to this device, clear Intel AMT credentials.
481 + // If this devics is in CCM mode and we have a bad password reset policy, do it now.
482 + if ((dev.connType == 2) && (dev.policy.badPass == 1) && (dev.mpsConnection != null) && (dev.mpsConnection.tag != null) && (dev.mpsConnection.tag.meiState != null) && (dev.mpsConnection.tag.meiState.Flags != null) && ((dev.mpsConnection.tag.meiState.Flags & 2) != 0)) {
483 + deactivateIntelAmtCCM(dev);
484 + return;
485 + }
486 +
487 + // We are unable to authenticate to this device
488 dev.consoleMsg("Unable to connect.");
479 - ClearDeviceCredentials(dev);
489 +
490 + // Set an error that we can't login to this device
491 + //ClearDeviceCredentials(dev);
492 }
493 //console.log(dev.nodeid, dev.name, dev.host, status, 'Bad response');
494 removeAmtDevice(dev);
@@ -690,28 +702,10 @@ module.exports.CreateAmtManager = function(parent) {
702 // Check if Intel AMT TLS state is correct
703 function attemptTlsSync(dev, func) {
704 if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
693 -
694 - // Refetch Intel AMT setup policy
695 - // mesh.amt.type: 0 = No Policy, 1 = Deactivate CCM, 2 = Manage in CCM, 3 = Manage in ACM
696 - // mesh.amt.cirasetup: 0 = No Change, 1 = Remove CIRA, 2 = Setup CIRA
697 - const mesh = parent.webserver.meshes[dev.meshid];
698 - if (mesh == null) { dev.consoleMsg("Unable to find device group."); removeAmtDevice(dev); return; }
699 - var amtPolicy = 0, ciraPolicy = 0;
700 - if (mesh.amt != null) { if (mesh.amt.type) { amtPolicy = mesh.amt.type; } if (mesh.amt.cirasetup) { ciraPolicy = mesh.amt.cirasetup; } }
701 - if (amtPolicy < 2) { ciraPolicy = 0; }
702 - dev.policy = { amtPolicy: amtPolicy, ciraPolicy: ciraPolicy }
703 -
704 - if (amtPolicy < 2) {
705 - // No policy or deactivation, do nothing.
706 - dev.consoleMsg("No server policy for Intel AMT");
707 - func(dev);
708 - } else {
709 - // Manage in CCM or ACM
710 - dev.taskCount = 1;
711 - dev.taskCompleted = func;
712 - // TODO: We only deal with certificates starting with Intel AMT 6 and beyond
713 - dev.amtstack.BatchEnum(null, ['AMT_PublicKeyCertificate', 'AMT_PublicPrivateKeyPair', 'AMT_TLSSettingData', 'AMT_TLSCredentialContext'], attemptTlsSyncEx);
714 - }
705 + dev.taskCount = 1;
706 + dev.taskCompleted = func;
707 + // TODO: We only deal with certificates starting with Intel AMT 6 and beyond
708 + dev.amtstack.BatchEnum(null, ['AMT_PublicKeyCertificate', 'AMT_PublicPrivateKeyPair', 'AMT_TLSSettingData', 'AMT_TLSCredentialContext'], attemptTlsSyncEx);
709 }
710
711 function attemptTlsSyncEx(stack, name, responses, status) {
@@ -1402,11 +1396,14 @@ module.exports.CreateAmtManager = function(parent) {
1396 dev.aquired.pass = dev.temp.pass;
1397 dev.aquired.lastContact = Date.now();
1398 dev.aquired.tls = 0;
1399 + dev.intelamt.user = 'admin';
1400 + dev.intelamt.pass = dev.temp.pass;
1401 + delete dev.acctry;
1402 UpdateDevice(dev);
1403
1404 // Success, switch to managing this device
1405 obj.parent.mpsserver.SendJsonControl(dev.mpsConnection, { action: 'mestate' }); // Request an MEI state refresh
1409 - dev.consoleMsg("Succesfully activated Intel AMT in CCM mode, holding 10 seconds...");
1406 + dev.consoleMsg("Succesfully activated in CCM mode, holding 10 seconds...");
1407
1408 // Wait 8 seconds before attempting to manage this device in CCM
1409 var f = function doManage() { if (isAmtDeviceValid(dev)) { attemptInitialContact(doManage.dev); } }
@@ -1437,17 +1434,18 @@ module.exports.CreateAmtManager = function(parent) {
1434 removeAmtDevice(dev);
1435 } else {
1436 // Wait 20 seconds before attempting any operation on this device
1440 - dev.consoleMsg("Deactivation successful, holding for 20 seconds...");
1437 + dev.consoleMsg("Deactivation successful, holding for 1 minute...");
1438 var f = function askMeiState() {
1439 askMeiState.dev.pendingUpdatedMeiState = 1;
1440 askMeiState.dev.controlMsg({ action: 'mestate' });
1441 }
1442 f.dev = dev;
1446 - setTimeout(f, 20000);
1443 + setTimeout(f, 60000);
1444 }
1445 }
1446 }
1447
1448 +
1449 //
1450 // General Methods
1451 //
meshuser.js
+2 -2
@@ -3308,6 +3308,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3308 if (common.validateInt(command.amtpolicy.cirasetup, 0, 2) == false) break; // Check the amtpolicy.cirasetup
3309 } else if (command.amtpolicy.type === 3) {
3310 if (common.validateString(command.amtpolicy.password, 0, 32) == false) break; // Check the amtpolicy.password
3311 + if ((command.amtpolicy.badpass != null) && common.validateInt(command.amtpolicy.badpass, 0, 1) == false) break; // Check the amtpolicy.badpass
3312 if (common.validateInt(command.amtpolicy.cirasetup, 0, 2) == false) break; // Check the amtpolicy.cirasetup
3313 }
3314 mesh = parent.meshes[command.meshid];
@@ -3322,8 +3323,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3323 // Perform the Intel AMT policy change
3324 change = 'Intel AMT policy change';
3325 var amtpolicy = { type: command.amtpolicy.type };
3325 - if (command.amtpolicy.type === 2) { amtpolicy = { type: command.amtpolicy.type, password: command.amtpolicy.password, badpass: command.amtpolicy.badpass, cirasetup: command.amtpolicy.cirasetup }; }
3326 - else if (command.amtpolicy.type === 3) { amtpolicy = { type: command.amtpolicy.type, password: command.amtpolicy.password, cirasetup: command.amtpolicy.cirasetup }; }
3326 + if ((command.amtpolicy.type === 2) || (command.amtpolicy.type === 3)) { amtpolicy = { type: command.amtpolicy.type, password: command.amtpolicy.password, badpass: command.amtpolicy.badpass, cirasetup: command.amtpolicy.cirasetup }; }
3327 mesh.amt = amtpolicy;
3328 db.Set(mesh);
3329 var amtpolicy2 = Object.assign({}, amtpolicy); // Shallow clone
views/default.handlebars
+3 -4
@@ -9592,7 +9592,7 @@
9592 if (ptype >= 2) {
9593 x = addHtmlValue("Password*", '<input id=dp20amtpolicypass type=password style=width:230px maxlength=32 onchange=dp20amtValidatePolicy() onkeyup=dp20amtValidatePolicy() autocomplete=off />')
9594 x += addHtmlValue("Password*", '<input id=dp20amtpolicypass2 type=password style=width:230px maxlength=32 onchange=dp20amtValidatePolicy() onkeyup=dp20amtValidatePolicy() autocomplete=off />')
9595 - if ((ptype == 2) && (currentMesh.mtype == 2)) { x += addHtmlValue("Password mismatch", '<select id=dp20amtbadpass style=width:230px><option value=0>' + "Do nothing" + '</option><option value=1>' + "Reactivate Intel&reg; AMT" + '</option></select>'); }
9595 + x += addHtmlValue("Password mismatch", '<select id=dp20amtbadpass style=width:230px><option value=0>' + "Do nothing" + '</option><option value=1>' + "Reactivate Intel&reg; AMT" + '</option></select>');
9596 if ((features & 0x400) == 0) { x += addHtmlValue('<span title="' + "Client Initiated Remote Access" + '">' + "CIRA" + '</span>', '<select id=dp20amtcira style=width:230px><option value=0>' + "Don't configure" + '</option><option value=1>' + "Don't connect to server" + '</option><option value=2>' + "Connect to server" + '</option></select>'); }
9597 x += '<br/><span style="font-size:10px">' + "* Leave blank to assign a random password to each device." + '</span><br/>';
9598 if (currentMesh.mtype == 2) {
@@ -9620,11 +9620,10 @@
9620 function p20editMeshAmtEx() {
9621 var ptype = parseInt(Q('dp20amtpolicy').value), amtpolicy = { type: ptype };
9622 if (ptype == 2) {
9623 - amtpolicy = { type: ptype, password: Q('dp20amtpolicypass').value };
9624 - if (currentMesh.mtype == 2) { amtpolicy.badpass = parseInt(Q('dp20amtbadpass').value); }
9623 + amtpolicy = { type: ptype, password: Q('dp20amtpolicypass').value, badpass: parseInt(Q('dp20amtbadpass').value) };
9624 if ((features & 0x400) == 0) { amtpolicy.cirasetup = parseInt(Q('dp20amtcira').value); } else { amtpolicy.cirasetup = 1; }
9625 } else if (ptype == 3) {
9627 - amtpolicy = { type: ptype, password: Q('dp20amtpolicypass').value };
9626 + amtpolicy = { type: ptype, password: Q('dp20amtpolicypass').value, badpass: parseInt(Q('dp20amtbadpass').value) };
9627 if ((features & 0x400) == 0) { amtpolicy.cirasetup = parseInt(Q('dp20amtcira').value); } else { amtpolicy.cirasetup = 1; }
9628 }
9629 meshserver.send({ action: 'meshamtpolicy', meshid: currentMesh._id, amtpolicy: amtpolicy });