Intel AMT configuration now automated thru agent.

This commit is contained in:
Ylian Saint-Hilaire 2020-10-21 15:36:07 -07:00
parent 5e9dedccbe
commit b04d1b7d4a
7 changed files with 8652 additions and 854 deletions

3924
agents/meshcore-bad.js Normal file

File diff suppressed because it is too large Load Diff

3903
agents/meshcore-old.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -400,7 +400,6 @@ function createMeshCore(agent) {
var networkMonitor = null;
var amtscanner = null;
var nextTunnelIndex = 1;
var amtPolicy = null;
var apftunnel = null;
var tunnelUserCount = { terminal: {}, files: {}, tcp: {}, udp: {}, msg: {} }; // List of userid->count sessions for terminal, files and TCP/UDP routing
@ -538,7 +537,6 @@ function createMeshCore(agent) {
mesh.SendCommand(meshCoreObj);
});
amt.onStateChange = function (state) { if (state == 2) { sendPeriodicServerUpdate(1); } }
if (amtPolicy != null) { amt.setPolicy(amtPolicy); }
amt.start();
}
}
@ -1075,11 +1073,39 @@ function createMeshCore(agent) {
if (data.url) { mesh.SendCommand({ action: 'openUrl', url: data.url, sessionid: data.sessionid, success: (openUserDesktopUrl(data.url) != null) }); }
break;
}
case 'amtPolicy': {
// Store the latest Intel AMT policy
amtPolicy = data.amtPolicy;
if (data.amtPolicy != null) { db.Put('amtPolicy', JSON.stringify(data.amtPolicy)); } else { db.Put('amtPolicy', null); }
if (amt != null) { amt.setPolicy(amtPolicy, true); }
case 'amtconfig': {
// Perform Intel AMT activation and/or configuration
if ((apftunnel != null) || (amt == null)) break;
getMeiState(15, function (state) {
if ((apftunnel != null) || (amt == null)) return;
if ((state == null) || (state.ProvisioningState == null)) return;
if ((state.UUID == null) || (state.UUID.length != 36)) return; // Bad UUID
var apfarg = {
mpsurl: mesh.ServerUrl.replace('agent.ashx', 'apf.ashx'),
mpsuser: Buffer.from(mesh.ServerInfo.MeshID, 'hex').toString('base64').substring(0, 16), // TODO: User a server provided encrypted cookie for CIRA-LMS login
mpspass: Buffer.from(mesh.ServerInfo.MeshID, 'hex').toString('base64').substring(0, 16),
mpskeepalive: 60000,
clientname: state.OsHostname,
clientaddress: '127.0.0.1',
clientuuid: state.UUID,
conntype: 2, // 0 = CIRA, 1 = Relay, 2 = LMS. The correct value is 2 since we are performing an LMS relay, other values for testing.
meiState: state // MEI state will be passed to MPS server
};
apftunnel = require('apfclient')({ debug: false }, apfarg);
apftunnel.onJsonControl = function (data) {
//if (data.action == 'console') { require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: data.msg }); } // Display a console message (DEBUG)
if (data.action == 'mestate') { getMeiState(15, function (state) { apftunnel.updateMeiState(state); }); } // Update the MEI state
if (data.action == 'deactivate') { // Request CCM deactivation
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.sendMeiDeactivationState(1); });
amtMei.unprovision(1, function (status) { if (apftunnel) apftunnel.sendMeiDeactivationState(status); }); // 0 = Success
}
if (data.action == 'close') { try { apftunnel.disconnect(); } catch (e) { } apftunnel = null; } // Close the CIRA-LMS connection
}
apftunnel.onChannelClosed = function () { apftunnel = null; }
try { apftunnel.connect(); } catch (ex) { }
});
break;
}
case 'getScript': {
@ -2563,7 +2589,7 @@ function createMeshCore(agent) {
var response = null;
switch (cmd) {
case 'help': { // Displays available commands
var fin = '', f = '', availcommands = 'amtconfig,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,amt,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,sendcaps,openurl,amtreset,amtccm,amtacm,amtdeactivate,amtpolicy,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,scanamt,wallpaper,agentmsg';
var fin = '', f = '', availcommands = 'amtconfig,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,amt,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,sendcaps,openurl,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,scanamt,wallpaper,agentmsg';
if (process.platform == 'win32') { availcommands += ',safemode,wpfhwacceleration,uac'; }
if (process.platform != 'freebsd') { availcommands += ',vm';}
if (require('MeshAgent').maxKvmTileSize != null) { availcommands += ',kvmmode'; }
@ -3037,40 +3063,6 @@ function createMeshCore(agent) {
}
break;
}
case 'amtreset': {
if (amt != null) { amt.reset(); response = 'Done.'; }
break;
}
case 'amtlmsreset': {
if (amt != null) { amt.lmsreset(); response = 'Done.'; }
break;
}
case 'amtccm': {
if (amt == null) { response = 'Intel AMT not supported.'; } else {
if (args['_'].length != 1) { response = 'Proper usage: amtccm (adminPassword)'; } // Display usage
else { amt.setPolicy({ type: 0 }); amt.activeToCCM(args['_'][0]); }
}
break;
}
case 'amtacm': {
if (amt == null) { response = 'Intel AMT not supported.'; } else {
amt.setPolicy({ type: 0 });
amt.getAmtInfo(function (meinfo) { amt.activeToACM(meinfo); });
}
break;
}
case 'amtdeactivate': {
if (amt == null) { response = 'Intel AMT not supported.'; } else { amt.setPolicy({ type: 0 }); amt.deactivateCCM(); }
break;
}
case 'amtpolicy': {
if (amtPolicy == null) {
response = 'No Intel(R) AMT policy.';
} else {
response = JSON.stringify(amtPolicy);
}
break;
}
case 'openurl': {
if (args['_'].length != 1) { response = 'Proper usage: openurl (url)'; } // Display usage
else { if (openUserDesktopUrl(args['_'][0]) == null) { response = 'Failed.'; } else { response = 'Success.'; } }
@ -3566,7 +3558,7 @@ function createMeshCore(agent) {
if (data.action == 'mestate') { getMeiState(15, function (state) { apftunnel.updateMeiState(state); }); } // Update the MEI state
if (data.action == 'deactivate') { // Request CCM deactivation
var amtMeiModule, amtMei;
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { apftunnel.sendMeiDeactivationState(1); break; }
try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { apftunnel.sendMeiDeactivationState(1); return; }
amtMei.on('error', function (e) { apftunnel.sendMeiDeactivationState(1); });
amtMei.unprovision(1, function (status) { apftunnel.sendMeiDeactivationState(status); }); // 0 = Success
}
@ -3861,7 +3853,7 @@ function createMeshCore(agent) {
if (result) {
amtMeiTmpState.net0 = result;
var fqdn = null, interfaces = require('os').networkInterfaces(); // Look for the DNS suffix for the Intel AMT Ethernet interface
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 != '')) { amtMeiTmpState.OsDnsSuffix = interfaces[i][j].fqdn; } } }
for (var i in interfaces) { for (var j in interfaces[i]) { if ((interfaces[i][j].mac == result.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { amtMeiTmpState.OsDnsSuffix = interfaces[i][j].fqdn; } } }
}
});
amtMei.getLanInterfaceSettings(1, function (result) { if (result) { amtMeiTmpState.net1 = result; } });

View File

@ -259,14 +259,29 @@ module.exports.CreateAmtManager = function(parent) {
if (amtPolicy < 2) { ciraPolicy = 0; }
dev.policy = { amtPolicy: amtPolicy, ciraPolicy: ciraPolicy, badPass: badPass, password: password };
// Setup the monitored device
dev.name = node.name;
dev.meshid = node.meshid;
dev.intelamt = node.intelamt;
// Check if the status of Intel AMT sent by the agents matched what we have in the database
if ((dev.connType == 2) && (dev.mpsConnection != null) && (dev.mpsConnection.tag != null) && (dev.mpsConnection.tag.meiState != null)) {
dev.aquired = {};
if (typeof dev.mpsConnection.tag.meiState['ProvisioningState'] == 'number') {
dev.intelamt.state = dev.aquired.state = dev.mpsConnection.tag.meiState['ProvisioningState'];
}
if (typeof dev.mpsConnection.tag.meiState['Flags'] == 'number') {
const flags = dev.intelamt.flags = dev.mpsConnection.tag.meiState['Flags'];
if (flags & 2) { dev.aquired.controlMode = 1; } // CCM
if (flags & 4) { dev.aquired.controlMode = 2; } // ACM
}
UpdateDevice(dev);
}
// If there is no Intel AMT policy for this device, stop here.
if (amtPolicy == 0) { dev.consoleMsg("Done."); removeAmtDevice(dev); return; }
// Setup the monitored device
dev.name = node.name;
//if (node.host) { dev.host = node.host.toLowerCase(); }
dev.meshid = node.meshid;
dev.intelamt = node.intelamt;
// Initiate the communication to Intel AMT
dev.consoleMsg("Checking Intel AMT state...");
attemptInitialContact(dev);
});
@ -435,8 +450,8 @@ module.exports.CreateAmtManager = function(parent) {
var verSplit = stack.wsman.comm.amtVersion.split('.');
if (verSplit.length >= 3) { dev.aquired.version = verSplit[0] + '.' + verSplit[1] + '.' + verSplit[2]; dev.aquired.majorver = parseInt(verSplit[0]); dev.aquired.minorver = parseInt(verSplit[1]); }
dev.aquired.realm = stack.wsman.comm.digestRealm;
dev.aquired.user = stack.wsman.comm.user;
dev.aquired.pass = stack.wsman.comm.pass;
dev.aquired.user = dev.intelamt.user = stack.wsman.comm.user;
dev.aquired.pass = dev.intelamt.pass = stack.wsman.comm.pass;
dev.aquired.lastContact = Date.now();
if ((dev.connType == 1) || (dev.connType == 3)) { dev.aquired.tls = stack.wsman.comm.xtls; } // Only set the TLS state if in relay or local mode. When using CIRA, this is auto-detected.
if (stack.wsman.comm.xtls == 1) { dev.aquired.hash = stack.wsman.comm.xtlsCertificate.fingerprint.split(':').join('').toLowerCase(); } else { delete dev.aquired.hash; }
@ -512,19 +527,17 @@ module.exports.CreateAmtManager = function(parent) {
// Change the current core information string and event it
function UpdateDevice(dev) {
if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
// Check that the mesh exists
const mesh = parent.webserver.meshes[dev.meshid];
if (mesh == null) { removeAmtDevice(dev); return false; }
if (mesh == null) { removeAmtDevice(dev); console.log('y3'); return false; }
// Get the node and change it if needed
parent.db.Get(dev.nodeid, function (err, nodes) {
if ((nodes == null) || (nodes.length != 1)) { return false; }
if ((nodes == null) || (nodes.length != 1)) { console.log('y1'); return false; }
const device = nodes[0];
var changes = [], change = 0, log = 0;
var domain = parent.config.domains[device.domain];
if (domain == null) { return false; }
if (domain == null) { console.log('y2'); return false; }
// Check if anything changes
if (device.intelamt == null) { device.intelamt = {}; }
@ -535,7 +548,7 @@ module.exports.CreateAmtManager = function(parent) {
if (dev.aquired.realm && (typeof dev.aquired.realm == 'string') && (dev.aquired.realm != device.intelamt.realm)) { change = 1; log = 1; device.intelamt.realm = dev.aquired.realm; changes.push('AMT realm'); }
if (dev.aquired.hash && (typeof dev.aquired.hash == 'string') && (dev.aquired.hash != device.intelamt.hash)) { change = 1; log = 1; device.intelamt.hash = dev.aquired.hash; changes.push('AMT hash'); }
if (dev.aquired.tls && (typeof dev.aquired.tls == 'number') && (dev.aquired.tls != device.intelamt.tls)) { change = 1; log = 1; device.intelamt.tls = dev.aquired.tls; changes.push('AMT TLS'); }
if (device.intelamt.state != 2) { change = 1; log = 1; device.intelamt.state = 2; changes.push('AMT state'); }
if ((dev.aquired.state != null) && (typeof dev.aquired.state == 'number') && (dev.aquired.state != device.intelamt.state)) { change = 1; log = 1; device.intelamt.state = dev.aquired.state; changes.push('AMT state'); }
// Update Intel AMT flags if needed
// dev.aquired.controlMode // 1 = CCM, 2 = ACM
@ -544,7 +557,10 @@ module.exports.CreateAmtManager = function(parent) {
if (typeof device.intelamt.flags == 'number') { flags = device.intelamt.flags; }
if (dev.aquired.controlMode == 1) { if ((flags & 4) != 0) { flags -= 4; } if ((flags & 2) == 0) { flags += 2; } } // CCM
if (dev.aquired.controlMode == 2) { if ((flags & 4) == 0) { flags += 4; } if ((flags & 2) != 0) { flags -= 2; } } // ACM
if (device.intelamt.flags != flags) { change = 1; log = 1; device.intelamt.flags = flags; changes.push('AMT flags'); }
if (device.intelamt.flags != flags) {
console.log('ChangeFlags', flags);
change = 1; log = 1; device.intelamt.flags = flags; changes.push('AMT flags');
}
// If there are changes, event the new device
if (change == 1) {
@ -1104,13 +1120,8 @@ module.exports.CreateAmtManager = function(parent) {
// If this device does not have KVM, ignore the response. This can happen for Intel Standard Manageability (Intel(R) SM).
if ((responses['CIM_KVMRedirectionSAP'] == null) || (responses['CIM_KVMRedirectionSAP'].status == 400)) { responses['CIM_KVMRedirectionSAP'] = null; }
// Check redirection services
var redir = (responses['AMT_RedirectionService'].response['ListenerEnabled'] == true);
var sol = ((responses['AMT_RedirectionService'].response['EnabledState'] & 2) != 0);
var ider = ((responses['AMT_RedirectionService'].response['EnabledState'] & 1) != 0);
// Enable SOL & IDER
if (responses['AMT_RedirectionService'].response['EnabledState'] != 32771) {
if ((responses['AMT_RedirectionService'].response['EnabledState'] != 32771) || (responses['AMT_RedirectionService'].response['ListenerEnabled'] == false)) {
dev.redirObj = responses['AMT_RedirectionService'].response;
dev.redirObj['ListenerEnabled'] = true;
dev.redirObj['EnabledState'] = 32771;
@ -1402,12 +1413,11 @@ module.exports.CreateAmtManager = function(parent) {
dev.aquired.host = dev.mpsConnection.tag.meiState.OsHostname + '.' + dev.mpsConnection.tag.meiState.OsDnsSuffix;
}
dev.aquired.realm = dev.amtstack.wsman.comm.digestRealm;
dev.aquired.user = 'admin';
dev.aquired.pass = dev.temp.pass;
dev.intelamt.user = dev.aquired.user = 'admin';
dev.intelamt.pass = dev.aquired.pass = dev.temp.pass;
dev.intelamt.tls = dev.aquired.tls = 0;
dev.aquired.lastContact = Date.now();
dev.aquired.tls = 0;
dev.intelamt.user = 'admin';
dev.intelamt.pass = dev.temp.pass;
dev.aquired.state = 2; // Activated
delete dev.acctry;
UpdateDevice(dev);
@ -1438,6 +1448,14 @@ module.exports.CreateAmtManager = function(parent) {
dev.consoleMsg("Failed to deactivate Intel AMT CCM.");
removeAmtDevice(dev);
} else {
// Update the device
dev.aquired = {};
dev.aquired.controlMode = 0; // 1 = CCM, 2 = ACM
dev.aquired.state = 0; // Not activated
delete dev.acctry;
delete dev.amtstack;
UpdateDevice(dev);
if (dev.policy.amtPolicy == 1) { // CCM deactivation policy, we are done.
dev.consoleMsg("Deactivation successful.");
dev.consoleMsg("Done.");

View File

@ -192,7 +192,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
obj.sendBinary(common.ShortToStr(10) + common.ShortToStr(0) + argument.hash + argument.core, function () { parent.parent.taskLimiter.completed(taskid); }); // MeshCommand_CoreModule, start core update
parent.agentStats.updatingCoreCount++;
parent.parent.debug('agent', "Updating core " + argument.name);
agentCoreIsStable();
} else {
// This agent is probably disconnected, nothing to do.
parent.parent.taskLimiter.completed(taskid);
@ -898,40 +897,11 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
}
}
// Take a basic Intel AMT policy and add all server information to it, making it ready to send to this agent.
/*
function completeIntelAmtPolicy(amtPolicy) {
var r = amtPolicy;
if (amtPolicy == null) return null;
if (amtPolicy.type == 2) {
// CCM - Add server root certificate
if (parent.parent.certificates.rootex == null) { parent.parent.certificates.rootex = parent.parent.certificates.root.cert.split('-----BEGIN CERTIFICATE-----').join('').split('-----END CERTIFICATE-----').join('').split('\r').join('').split('\n').join(''); }
r.rootcert = parent.parent.certificates.rootex;
if ((amtPolicy.cirasetup == 2) && (parent.parent.mpsserver != null) && (parent.parent.certificates.AmtMpsName != null) && (args.lanonly != true) && (args.mpsport != 0)) {
// Add server CIRA settings
r.ciraserver = {
name: parent.parent.certificates.AmtMpsName,
port: (typeof args.mpsaliasport == 'number' ? args.mpsaliasport : args.mpsport),
user: obj.meshid.replace(/\@/g, 'X').replace(/\$/g, 'X').substring(0, 16),
pass: args.mpspass ? args.mpspass : 'A@xew9rt', // If the MPS password is not set, just use anything. TODO: Use the password as an agent identifier?
home: ['sdlwerulis3wpj95dfj'] // Use a random FQDN to not have any home network.
};
if (Array.isArray(args.ciralocalfqdn)) { r.ciraserver.home = args.ciralocalfqdn; }
}
} else if ((amtPolicy.type == 3) && (domain.amtacmactivation.acmmatch)) {
// ACM - In this mode, don't send much to Intel AMT. Just indicate ACM policy and let the agent try activation when possible.
r = { type: 3, match: domain.amtacmactivation.acmmatch };
}
return r;
}
*/
// Send Intel AMT policy
// Indicate to the agent that we want to reconfigure Intel AMT
obj.sendUpdatedIntelAmtPolicy = function (policy) {
if (obj.agentExeInfo && (obj.agentExeInfo.amt == true)) { // Only send Intel AMT policy to agents what could have AMT.
// TODO
//if (policy == null) { var mesh = parent.meshes[obj.dbMeshKey]; if (mesh == null) return; policy = mesh.amt; }
//if (policy != null) { try { obj.send(JSON.stringify({ action: 'amtPolicy', amtPolicy: completeIntelAmtPolicy(common.Clone(policy)) })); } catch (ex) { } }
if (policy == null) { var mesh = parent.meshes[obj.dbMeshKey]; if (mesh == null) return; policy = mesh.amt; }
if ((policy != null) && (policy.type != 0)) { try { obj.send(JSON.stringify({ action: 'amtconfig' })); } catch (ex) { } }
}
}
@ -983,12 +953,10 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
}
});
// Send Intel AMT policy
/*
if (obj.agentExeInfo && (obj.agentExeInfo.amt == true) && (mesh.amt != null)) { // Only send Intel AMT policy to agents what could have AMT.
try { obj.send(JSON.stringify({ action: 'amtPolicy', amtPolicy: completeIntelAmtPolicy(common.Clone(mesh.amt)) })); } catch (ex) { }
// Indicate that we want to check the Intel AMT configuration
if (obj.agentExeInfo && (obj.agentExeInfo.amt == true) && (mesh.amt != null) && (mesh.amt.type != 0)) { // Only send yo agents what could have AMT and if the policy is not empty.
try { obj.send(JSON.stringify({ action: 'amtconfig' })); } catch (ex) { }
}
*/
// Fetch system information
db.GetHash('si' + obj.dbNodeKey, function (err, results) {

File diff suppressed because it is too large Load Diff

View File

@ -5674,8 +5674,8 @@
str += (', v' + EscapeHtml(node.intelamt.ver));
}
if (node.intelamt.tls == 1) { str += ', <span title="' + "Intel&reg; AMT is setup with TLS network security" + '">' + "TLS" + '</span>'; }
if (node.intelamt.state == 2) {
if (node.intelamt.tls == 1) { str += ', <span title="' + "Intel&reg; AMT is setup with TLS network security" + '">' + "TLS" + '</span>'; }
if (node.intelamt.user == null || node.intelamt.user == '') {
if ((meshrights & 4) != 0) {
str += ', <i style=color:#FF0000;cursor:pointer title="' + "Edit Intel&reg; AMT credentials" + '" onclick=editDeviceAmtSettings("' + node._id + '")>' + "No Credentials" + '</i>';