Added Intel AMT automated CCM password reset.

This commit is contained in:
Ylian Saint-Hilaire 2020-10-21 13:04:36 -07:00
parent cd2091990f
commit 12d9b38822
3 changed files with 34 additions and 37 deletions

View File

@ -249,10 +249,14 @@ module.exports.CreateAmtManager = function(parent) {
// Fetch Intel AMT setup policy
// mesh.amt.type: 0 = No Policy, 1 = Deactivate CCM, 2 = Manage in CCM, 3 = Manage in ACM
// mesh.amt.cirasetup: 0 = No Change, 1 = Remove CIRA, 2 = Setup CIRA
var amtPolicy = 0, ciraPolicy = 0;
if (mesh.amt != null) { if (mesh.amt.type) { amtPolicy = mesh.amt.type; } if (mesh.amt.cirasetup) { ciraPolicy = mesh.amt.cirasetup; } }
var amtPolicy = 0, ciraPolicy = 0, badPass = 0;
if (mesh.amt != null) {
if (mesh.amt.type) { amtPolicy = mesh.amt.type; }
if (mesh.amt.cirasetup) { ciraPolicy = mesh.amt.cirasetup; }
if (mesh.amt.badpass) { badPass = mesh.amt.badpass; }
}
if (amtPolicy < 2) { ciraPolicy = 0; }
dev.policy = { amtPolicy: amtPolicy, ciraPolicy: ciraPolicy }
dev.policy = { amtPolicy: amtPolicy, ciraPolicy: ciraPolicy, badPass: badPass };
// If there is no Intel AMT policy for this device, stop here.
if (amtPolicy == 0) { dev.consoleMsg("Done."); removeAmtDevice(dev); return; }
@ -300,7 +304,7 @@ module.exports.CreateAmtManager = function(parent) {
}
}
// If we ran out of credentials to try, give up here.
// See if we need to try different credentials
if ((dev.acctry == null) && ((typeof dev.intelamt.user != 'string') || (typeof dev.intelamt.pass != 'string'))) {
if ((obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > 0)) { dev.acctry = 0; } else { removeAmtDevice(dev); return; }
}
@ -474,9 +478,17 @@ module.exports.CreateAmtManager = function(parent) {
if ((dev.acctry == null) && (obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > 0)) { dev.acctry = 0; attemptInitialContact(dev); return; }
if ((dev.acctry != null) && (obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > (dev.acctry + 1))) { dev.acctry++; attemptInitialContact(dev); return; }
// We are unable to authenticate to this device, clear Intel AMT credentials.
// If this devics is in CCM mode and we have a bad password reset policy, do it now.
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)) {
deactivateIntelAmtCCM(dev);
return;
}
// We are unable to authenticate to this device
dev.consoleMsg("Unable to connect.");
ClearDeviceCredentials(dev);
// Set an error that we can't login to this device
//ClearDeviceCredentials(dev);
}
//console.log(dev.nodeid, dev.name, dev.host, status, 'Bad response');
removeAmtDevice(dev);
@ -690,29 +702,11 @@ module.exports.CreateAmtManager = function(parent) {
// Check if Intel AMT TLS state is correct
function attemptTlsSync(dev, func) {
if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
// Refetch Intel AMT setup policy
// mesh.amt.type: 0 = No Policy, 1 = Deactivate CCM, 2 = Manage in CCM, 3 = Manage in ACM
// mesh.amt.cirasetup: 0 = No Change, 1 = Remove CIRA, 2 = Setup CIRA
const mesh = parent.webserver.meshes[dev.meshid];
if (mesh == null) { dev.consoleMsg("Unable to find device group."); removeAmtDevice(dev); return; }
var amtPolicy = 0, ciraPolicy = 0;
if (mesh.amt != null) { if (mesh.amt.type) { amtPolicy = mesh.amt.type; } if (mesh.amt.cirasetup) { ciraPolicy = mesh.amt.cirasetup; } }
if (amtPolicy < 2) { ciraPolicy = 0; }
dev.policy = { amtPolicy: amtPolicy, ciraPolicy: ciraPolicy }
if (amtPolicy < 2) {
// No policy or deactivation, do nothing.
dev.consoleMsg("No server policy for Intel AMT");
func(dev);
} else {
// Manage in CCM or ACM
dev.taskCount = 1;
dev.taskCompleted = func;
// TODO: We only deal with certificates starting with Intel AMT 6 and beyond
dev.amtstack.BatchEnum(null, ['AMT_PublicKeyCertificate', 'AMT_PublicPrivateKeyPair', 'AMT_TLSSettingData', 'AMT_TLSCredentialContext'], attemptTlsSyncEx);
}
}
function attemptTlsSyncEx(stack, name, responses, status) {
const dev = stack.dev;
@ -1402,11 +1396,14 @@ module.exports.CreateAmtManager = function(parent) {
dev.aquired.pass = dev.temp.pass;
dev.aquired.lastContact = Date.now();
dev.aquired.tls = 0;
dev.intelamt.user = 'admin';
dev.intelamt.pass = dev.temp.pass;
delete dev.acctry;
UpdateDevice(dev);
// Success, switch to managing this device
obj.parent.mpsserver.SendJsonControl(dev.mpsConnection, { action: 'mestate' }); // Request an MEI state refresh
dev.consoleMsg("Succesfully activated Intel AMT in CCM mode, holding 10 seconds...");
dev.consoleMsg("Succesfully activated in CCM mode, holding 10 seconds...");
// Wait 8 seconds before attempting to manage this device in CCM
var f = function doManage() { if (isAmtDeviceValid(dev)) { attemptInitialContact(doManage.dev); } }
@ -1437,17 +1434,18 @@ module.exports.CreateAmtManager = function(parent) {
removeAmtDevice(dev);
} else {
// Wait 20 seconds before attempting any operation on this device
dev.consoleMsg("Deactivation successful, holding for 20 seconds...");
dev.consoleMsg("Deactivation successful, holding for 1 minute...");
var f = function askMeiState() {
askMeiState.dev.pendingUpdatedMeiState = 1;
askMeiState.dev.controlMsg({ action: 'mestate' });
}
f.dev = dev;
setTimeout(f, 20000);
setTimeout(f, 60000);
}
}
}
//
// General Methods
//

View File

@ -3308,6 +3308,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if (common.validateInt(command.amtpolicy.cirasetup, 0, 2) == false) break; // Check the amtpolicy.cirasetup
} else if (command.amtpolicy.type === 3) {
if (common.validateString(command.amtpolicy.password, 0, 32) == false) break; // Check the amtpolicy.password
if ((command.amtpolicy.badpass != null) && common.validateInt(command.amtpolicy.badpass, 0, 1) == false) break; // Check the amtpolicy.badpass
if (common.validateInt(command.amtpolicy.cirasetup, 0, 2) == false) break; // Check the amtpolicy.cirasetup
}
mesh = parent.meshes[command.meshid];
@ -3322,8 +3323,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Perform the Intel AMT policy change
change = 'Intel AMT policy change';
var amtpolicy = { type: command.amtpolicy.type };
if (command.amtpolicy.type === 2) { amtpolicy = { type: command.amtpolicy.type, password: command.amtpolicy.password, badpass: command.amtpolicy.badpass, cirasetup: command.amtpolicy.cirasetup }; }
else if (command.amtpolicy.type === 3) { amtpolicy = { type: command.amtpolicy.type, password: command.amtpolicy.password, cirasetup: command.amtpolicy.cirasetup }; }
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 }; }
mesh.amt = amtpolicy;
db.Set(mesh);
var amtpolicy2 = Object.assign({}, amtpolicy); // Shallow clone

View File

@ -9592,7 +9592,7 @@
if (ptype >= 2) {
x = addHtmlValue("Password*", '<input id=dp20amtpolicypass type=password style=width:230px maxlength=32 onchange=dp20amtValidatePolicy() onkeyup=dp20amtValidatePolicy() autocomplete=off />')
x += addHtmlValue("Password*", '<input id=dp20amtpolicypass2 type=password style=width:230px maxlength=32 onchange=dp20amtValidatePolicy() onkeyup=dp20amtValidatePolicy() autocomplete=off />')
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>'); }
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>');
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>'); }
x += '<br/><span style="font-size:10px">' + "* Leave blank to assign a random password to each device." + '</span><br/>';
if (currentMesh.mtype == 2) {
@ -9620,11 +9620,10 @@
function p20editMeshAmtEx() {
var ptype = parseInt(Q('dp20amtpolicy').value), amtpolicy = { type: ptype };
if (ptype == 2) {
amtpolicy = { type: ptype, password: Q('dp20amtpolicypass').value };
if (currentMesh.mtype == 2) { amtpolicy.badpass = parseInt(Q('dp20amtbadpass').value); }
amtpolicy = { type: ptype, password: Q('dp20amtpolicypass').value, badpass: parseInt(Q('dp20amtbadpass').value) };
if ((features & 0x400) == 0) { amtpolicy.cirasetup = parseInt(Q('dp20amtcira').value); } else { amtpolicy.cirasetup = 1; }
} else if (ptype == 3) {
amtpolicy = { type: ptype, password: Q('dp20amtpolicypass').value };
amtpolicy = { type: ptype, password: Q('dp20amtpolicypass').value, badpass: parseInt(Q('dp20amtbadpass').value) };
if ((features & 0x400) == 0) { amtpolicy.cirasetup = parseInt(Q('dp20amtcira').value); } else { amtpolicy.cirasetup = 1; }
}
meshserver.send({ action: 'meshamtpolicy', meshid: currentMesh._id, amtpolicy: amtpolicy });