AMT manager improvements.

Ylian Saint-Hilaire committed Oct 26, 2020 at 11:51 UTC 02a5d421b2dc7e3b1482b3606cad5d0695c459b1
1 file changed +109 -81
amtmanager.js
+109 -81
@@ -340,7 +340,7 @@ module.exports.CreateAmtManager = function (parent) {
340 }
341
342 // If there is no Intel AMT policy for this device, stop here.
343 - if (amtPolicy == 0) { dev.consoleMsg("Done."); removeAmtDevice(dev); return; }
343 + //if (amtPolicy == 0) { dev.consoleMsg("Done."); removeAmtDevice(dev); return; }
344
345 // Initiate the communication to Intel AMT
346 dev.consoleMsg("Checking Intel AMT state...");
@@ -371,19 +371,22 @@ module.exports.CreateAmtManager = function (parent) {
371 if ((dev.mpsConnection.tag.meiState.ProvisioningState == 2) && ((dev.mpsConnection.tag.meiState.Flags & 2) != 0)) {
372 // Deactivate CCM.
373 deactivateIntelAmtCCM(dev);
374 - } else {
374 + return;
375 + } //else {
376 // Already deactivated or in ACM
376 - dev.consoleMsg("Done."); // TODO: We need to at least clear CIRA
377 - removeAmtDevice(dev);
378 - }
379 - return;
377 + //dev.consoleMsg("Done."); // TODO: We need to at least clear CIRA
378 + //removeAmtDevice(dev);
379 + //}
380 + //return;
381 }
381 - // No Intel AMT policy, stop here
382 + /*
383 + // No Intel AMT policy, since this is CIRA-LMS, stop here.
384 if (dev.policy.amtPolicy == 0) {
385 dev.consoleMsg("Done.");
386 removeAmtDevice(dev);
387 return;
388 }
389 + */
390 }
391
392 // See if we need to try different credentials
@@ -762,6 +765,7 @@ module.exports.CreateAmtManager = function (parent) {
765 // Care should be take not to have many pending WSMAN called when performing clock sync.
766 function attemptSyncClock(dev, func) {
767 if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
768 + if (dev.policy.amtPolicy == 0) { func(dev); return; } // If there is no Intel AMT policy, skip this operation.
769 dev.taskCount = 1;
770 dev.taskCompleted = func;
771 dev.amtstack.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch(attemptSyncClockEx);
@@ -802,6 +806,7 @@ module.exports.CreateAmtManager = function (parent) {
806 // Check if Intel AMT TLS state is correct
807 function attemptTlsSync(dev, func) {
808 if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
809 + if (dev.policy.amtPolicy == 0) { func(dev); return; } // If there is no Intel AMT policy, skip this operation.
810 dev.taskCount = 1;
811 dev.taskCompleted = func;
812 // TODO: We only deal with certificates starting with Intel AMT 6 and beyond
@@ -973,6 +978,7 @@ module.exports.CreateAmtManager = function (parent) {
978 // We may want to work on an alternate version that does do priority if requested.
979 function attemptWifiSync(dev, func) {
980 if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
981 + if (dev.policy.amtPolicy == 0) { func(dev); return; } // If there is no Intel AMT policy, skip this operation.
982 if (dev.connType != 2) { func(dev); return; } // Only configure wireless over a CIRA-LMS link
983 if (parent.config.domains[dev.domainid].amtmanager.wifiprofiles == null) { func(dev); return; } // No server WIFI profiles set, skip this.
984 if ((dev.mpsConnection.tag.meiState == null) || (dev.mpsConnection.tag.meiState.net1 == null)) { func(dev); return; } // No WIFI on this device, skip this.
@@ -1080,6 +1086,7 @@ module.exports.CreateAmtManager = function (parent) {
1086 // Check if Intel AMT has the server root certificate
1087 function attemptRootCertSync(dev, func) {
1088 if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1089 + if (dev.policy.amtPolicy == 0) { func(dev); return; } // If there is no Intel AMT policy, skip this operation.
1090 if ((dev.connType != 2) || (dev.policy.ciraPolicy != 2) || (parent.mpsserver.server == null)) { func(dev); return; } // Server root certificate does not need to be present is CIRA is not needed
1091
1092 // Find the current TLS certificate & MeshCentral root certificate
@@ -1108,6 +1115,7 @@ module.exports.CreateAmtManager = function (parent) {
1115 //
1116
1117 // Check if Intel AMT has the server root certificate
1118 + // If deactivation policy is in effect, remove CIRA configuration
1119 function attemptCiraSync(dev, func) {
1120 if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1121 if ((dev.connType != 2) || ((dev.policy.ciraPolicy != 1) && (dev.policy.ciraPolicy != 2))) { func(dev); return; } // Only setup CIRA when LMS connection is used and a CIRA policy is enabled.
@@ -1116,94 +1124,113 @@ module.exports.CreateAmtManager = function (parent) {
1124 // TODO: We only deal with remote access starting with Intel AMT 6 and beyond
1125 dev.taskCount = 1;
1126 dev.taskCompleted = func;
1127 + dev.tryCount = 0;
1128 var requests = ['*AMT_EnvironmentDetectionSettingData', 'AMT_ManagementPresenceRemoteSAP', 'AMT_RemoteAccessCredentialContext', 'AMT_RemoteAccessPolicyAppliesToMPS', 'AMT_RemoteAccessPolicyRule', '*AMT_UserInitiatedConnectionService', 'AMT_MPSUsernamePassword'];
1129 if ((dev.aquired.majorver != null) && (dev.aquired.majorver > 11)) { requests.push('*IPS_HTTPProxyService', 'IPS_HTTPProxyAccessPoint'); }
1121 - dev.amtstack.BatchEnum(null, requests, function (stack, name, responses, status) {
1122 - const dev = stack.dev;
1123 - if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1124 - //dev.consoleMsg("Added server root certificate.");
1125 -
1126 - if ((dev.aquired.majorver != null) && (dev.aquired.majorver > 11) && (status == 400)) {
1127 - // Check if only the HTTP proxy objects failed
1128 - status = 200;
1129 - if (responses['IPS_HTTPProxyAccessPoint'].status == 400) { delete responses['IPS_HTTPProxyAccessPoint']; }
1130 - if (responses['IPS_HTTPProxyService'].status == 400) { delete responses['IPS_HTTPProxyService']; }
1131 - for (var i in responses) { if (responses[i].status != 200) { status = responses[i].status; } }
1132 - }
1133 - if (status != 200) { dev.consoleMsg("Failed to get CIRA state (" + status + ")."); removeAmtDevice(dev); return; }
1134 - if ((responses['AMT_UserInitiatedConnectionService'] == null) || (responses['AMT_UserInitiatedConnectionService'].response == null)) { dev.consoleMsg("Invalid CIRA state."); removeAmtDevice(dev); return; }
1135 -
1136 - dev.cira = {};
1137 - dev.cira.xxRemoteAccess = responses;
1138 - dev.cira.xxEnvironementDetection = responses['AMT_EnvironmentDetectionSettingData'].response;
1139 - dev.cira.xxEnvironementDetection['DetectionStrings'] = MakeToArray(dev.cira.xxEnvironementDetection['DetectionStrings']);
1140 - dev.cira.xxCiraServers = responses['AMT_ManagementPresenceRemoteSAP'].responses;
1141 - dev.cira.xxUserInitiatedCira = responses['AMT_UserInitiatedConnectionService'].response;
1142 - dev.cira.xxRemoteAccessCredentiaLinks = responses['AMT_RemoteAccessCredentialContext'].responses;
1143 - dev.cira.xxMPSUserPass = responses['AMT_MPSUsernamePassword'].responses;
1144 -
1145 - // Set CIRA initiation to BIOS & OS enabled
1146 - if (dev.cira.xxUserInitiatedCira['EnabledState'] != 32771) { // 32768: "Disabled", 32769: "BIOS enabled", 32770: "OS enable", 32771: "BIOS & OS enabled"
1147 - dev.amtstack.AMT_UserInitiatedConnectionService_RequestStateChange(32771, null, function (stack, name, responses, status) { }); // This is not a critical call.
1148 - }
1130 + dev.amtstack.BatchEnum(null, requests, attemptCiraSyncResponse);
1131 + }
1132
1150 - // Figure out policies attached to servers. Create a policy type to server table.
1151 - dev.cira.xxPolicies = { 'User': [], 'Alert': [], 'Periodic': [] };
1152 - for (var i in responses['AMT_RemoteAccessPolicyAppliesToMPS'].responses) {
1153 - var policy = responses['AMT_RemoteAccessPolicyAppliesToMPS'].responses[i];
1154 - var server = Clone(getItem(dev.cira.xxCiraServers, 'Name', getItem(policy['ManagedElement']['ReferenceParameters']['SelectorSet']['Selector'], '@Name', 'Name')['Value']));
1155 - server.MpsType = policy['MpsType']; // MpsType was added in Intel AMT 11.6
1156 - var ptype = (getItem(policy['PolicySet']['ReferenceParameters']['SelectorSet']['Selector'], '@Name', 'PolicyRuleName')['Value']).split(' ')[0];
1157 - dev.cira.xxPolicies[ptype].push(server);
1158 - }
1133 + function attemptCiraSyncResponse(stack, name, responses, status) {
1134 + const dev = stack.dev;
1135 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1136
1160 - // Fetch the server's CIRA settings
1161 - dev.cira.mpsPresent = null;
1162 - dev.cira.mpsPolicy = false;
1163 - if ((dev.policy.ciraPolicy == 2) && (parent.mpsserver.server != null)) { // parent.mpsserver.server is not null if the MPS server is listening for TCP/TLS connections
1164 - dev.cira.meshidx = dev.meshid.split('/')[2].replace(/\@/g, 'X').replace(/\$/g, 'X').substring(0, 16);
1165 - dev.cira.mpsName = parent.webserver.certificates.AmtMpsName;
1166 - var serverNameSplit = dev.cira.mpsName.split('.');
1167 - dev.cira.mpsPort = ((parent.args.mpsaliasport != null) ? parent.args.mpsaliasport : parent.args.mpsport);
1168 - dev.cira.mpsAddressFormat = 201; // 201 = FQDN, 3 = IPv4
1169 - dev.cira.mpsPass = getRandomAmtPassword();
1170 - if ((serverNameSplit.length == 4) && (parseInt(serverNameSplit[0]) == serverNameSplit[0]) && (parseInt(serverNameSplit[1]) == serverNameSplit[1]) && (parseInt(serverNameSplit[2]) == serverNameSplit[2]) && (parseInt(serverNameSplit[3]) == serverNameSplit[3])) { dev.cira.mpsAddressFormat = 3; }
1171 -
1172 - // Check if our server is already present
1173 - if (dev.cira.xxCiraServers.length > 0) {
1174 - for (var i = 0; i < dev.cira.xxCiraServers.length; i++) {
1175 - var mpsServer = dev.cira.xxCiraServers[i];
1176 - if ((mpsServer.AccessInfo == dev.cira.mpsName) && (mpsServer.Port == dev.cira.mpsPort) && (mpsServer.InfoFormat == dev.cira.mpsAddressFormat)) { dev.cira.mpsPresent = mpsServer['Name']; }
1177 - }
1178 - }
1137 + if ((dev.aquired.majorver != null) && (dev.aquired.majorver > 11) && (status == 400)) {
1138 + // Check if only the HTTP proxy objects failed
1139 + status = 200;
1140 + if (responses['IPS_HTTPProxyAccessPoint'].status == 400) { delete responses['IPS_HTTPProxyAccessPoint']; }
1141 + if (responses['IPS_HTTPProxyService'].status == 400) { delete responses['IPS_HTTPProxyService']; }
1142 + for (var i in responses) { if (responses[i].status != 200) { status = responses[i].status; } }
1143 + }
1144
1180 - // Check if our server is already present
1181 - if (dev.cira.xxPolicies['Periodic'].length > 0) {
1182 - var mpsServer = dev.cira.xxPolicies['Periodic'][0];
1183 - if ((mpsServer.AccessInfo == dev.cira.mpsName) && (mpsServer.Port == dev.cira.mpsPort) && (mpsServer.InfoFormat == dev.cira.mpsAddressFormat)) { dev.cira.mpsPolicy = true; }
1184 - }
1145 + // If batch enumeration was not succesful, try again.
1146 + if (status != 200) {
1147 + // If we failed to get the CIRA state, try again up to 5 times.
1148 + if (dev.tryCount <= 5) {
1149 + dev.tryCount++;
1150 + var requests = ['*AMT_EnvironmentDetectionSettingData', 'AMT_ManagementPresenceRemoteSAP', 'AMT_RemoteAccessCredentialContext', 'AMT_RemoteAccessPolicyAppliesToMPS', 'AMT_RemoteAccessPolicyRule', '*AMT_UserInitiatedConnectionService', 'AMT_MPSUsernamePassword'];
1151 + if ((dev.aquired.majorver != null) && (dev.aquired.majorver > 11)) { requests.push('*IPS_HTTPProxyService', 'IPS_HTTPProxyAccessPoint'); }
1152 + dev.amtstack.BatchEnum(null, requests, attemptCiraSyncResponse);
1153 + return;
1154 }
1155
1187 - // Remove all MPS policies that are not ours
1188 - if ((dev.cira.xxPolicies['User'] != null) && (dev.cira.xxPolicies['User'].length > 0)) { dev.consoleMsg("Removing CIRA user trigger."); dev.amtstack.Delete('AMT_RemoteAccessPolicyRule', { 'PolicyRuleName': 'User Initiated' }, function (stack, name, responses, status) { }); }
1189 - if ((dev.cira.xxPolicies['Alert'] != null) && (dev.cira.xxPolicies['Alert'].length > 0)) { dev.consoleMsg("Removing CIRA alert trigger."); dev.amtstack.Delete('AMT_RemoteAccessPolicyRule', { 'PolicyRuleName': 'Alert' }, function (stack, name, responses, status) { }); }
1190 - if ((dev.cira.xxPolicies['Periodic'] != null) && (dev.cira.xxPolicies['Periodic'].length > 0) && (dev.cira.mpsPolicy == false)) { dev.consoleMsg("Removing CIRA periodic trigger."); dev.amtstack.Delete('AMT_RemoteAccessPolicyRule', { 'PolicyRuleName': 'Periodic' }, function (stack, name, responses, status) { }); }
1156 + // We tried 5 times, give up.
1157 + dev.consoleMsg("Failed to get CIRA state (" + status + ").");
1158 + removeAmtDevice(dev);
1159 + return;
1160 + }
1161 +
1162 + if ((responses['AMT_UserInitiatedConnectionService'] == null) || (responses['AMT_UserInitiatedConnectionService'].response == null)) { dev.consoleMsg("Invalid CIRA state."); removeAmtDevice(dev); return; }
1163
1192 - // Remove all MPS servers that are not ours
1164 + dev.cira = {};
1165 + dev.cira.xxRemoteAccess = responses;
1166 + dev.cira.xxEnvironementDetection = responses['AMT_EnvironmentDetectionSettingData'].response;
1167 + dev.cira.xxEnvironementDetection['DetectionStrings'] = MakeToArray(dev.cira.xxEnvironementDetection['DetectionStrings']);
1168 + dev.cira.xxCiraServers = responses['AMT_ManagementPresenceRemoteSAP'].responses;
1169 + dev.cira.xxUserInitiatedCira = responses['AMT_UserInitiatedConnectionService'].response;
1170 + dev.cira.xxRemoteAccessCredentiaLinks = responses['AMT_RemoteAccessCredentialContext'].responses;
1171 + dev.cira.xxMPSUserPass = responses['AMT_MPSUsernamePassword'].responses;
1172 +
1173 + // Set CIRA initiation to BIOS & OS enabled
1174 + if (dev.cira.xxUserInitiatedCira['EnabledState'] != 32771) { // 32768: "Disabled", 32769: "BIOS enabled", 32770: "OS enable", 32771: "BIOS & OS enabled"
1175 + dev.amtstack.AMT_UserInitiatedConnectionService_RequestStateChange(32771, null, function (stack, name, responses, status) { }); // This is not a critical call.
1176 + }
1177 +
1178 + // Figure out policies attached to servers. Create a policy type to server table.
1179 + dev.cira.xxPolicies = { 'User': [], 'Alert': [], 'Periodic': [] };
1180 + for (var i in responses['AMT_RemoteAccessPolicyAppliesToMPS'].responses) {
1181 + var policy = responses['AMT_RemoteAccessPolicyAppliesToMPS'].responses[i];
1182 + var server = Clone(getItem(dev.cira.xxCiraServers, 'Name', getItem(policy['ManagedElement']['ReferenceParameters']['SelectorSet']['Selector'], '@Name', 'Name')['Value']));
1183 + server.MpsType = policy['MpsType']; // MpsType was added in Intel AMT 11.6
1184 + var ptype = (getItem(policy['PolicySet']['ReferenceParameters']['SelectorSet']['Selector'], '@Name', 'PolicyRuleName')['Value']).split(' ')[0];
1185 + dev.cira.xxPolicies[ptype].push(server);
1186 + }
1187 +
1188 + // Fetch the server's CIRA settings
1189 + dev.cira.mpsPresent = null;
1190 + dev.cira.mpsPolicy = false;
1191 + if ((dev.policy.ciraPolicy == 2) && (parent.mpsserver.server != null)) { // parent.mpsserver.server is not null if the MPS server is listening for TCP/TLS connections
1192 + dev.cira.meshidx = dev.meshid.split('/')[2].replace(/\@/g, 'X').replace(/\$/g, 'X').substring(0, 16);
1193 + dev.cira.mpsName = parent.webserver.certificates.AmtMpsName;
1194 + var serverNameSplit = dev.cira.mpsName.split('.');
1195 + dev.cira.mpsPort = ((parent.args.mpsaliasport != null) ? parent.args.mpsaliasport : parent.args.mpsport);
1196 + dev.cira.mpsAddressFormat = 201; // 201 = FQDN, 3 = IPv4
1197 + dev.cira.mpsPass = getRandomAmtPassword();
1198 + if ((serverNameSplit.length == 4) && (parseInt(serverNameSplit[0]) == serverNameSplit[0]) && (parseInt(serverNameSplit[1]) == serverNameSplit[1]) && (parseInt(serverNameSplit[2]) == serverNameSplit[2]) && (parseInt(serverNameSplit[3]) == serverNameSplit[3])) { dev.cira.mpsAddressFormat = 3; }
1199 +
1200 + // Check if our server is already present
1201 if (dev.cira.xxCiraServers.length > 0) {
1202 for (var i = 0; i < dev.cira.xxCiraServers.length; i++) {
1203 var mpsServer = dev.cira.xxCiraServers[i];
1196 - if ((mpsServer.AccessInfo != dev.cira.mpsName) || (mpsServer.Port != dev.cira.mpsPort) || (mpsServer.InfoFormat != dev.cira.mpsAddressFormat)) {
1197 - dev.consoleMsg("Removing MPS server.");
1198 - dev.amtstack.Delete('AMT_ManagementPresenceRemoteSAP', { 'Name': mpsServer['Name'] }, function (stack, name, responses, status) { });
1199 - }
1204 + if ((mpsServer.AccessInfo == dev.cira.mpsName) && (mpsServer.Port == dev.cira.mpsPort) && (mpsServer.InfoFormat == dev.cira.mpsAddressFormat)) { dev.cira.mpsPresent = mpsServer['Name']; }
1205 }
1206 }
1207
1203 - // If we need to setup CIRA, start by checking the MPS server
1204 - // parent.mpsserver.server is not null if the MPS server is listening for TCP/TLS connections
1205 - if ((dev.policy.ciraPolicy == 2) && (parent.mpsserver.server != null)) { addMpsServer(dev); } else { checkEnvironmentDetection(dev); }
1206 - });
1208 + // Check if our server is already present
1209 + if (dev.cira.xxPolicies['Periodic'].length > 0) {
1210 + var mpsServer = dev.cira.xxPolicies['Periodic'][0];
1211 + if ((mpsServer.AccessInfo == dev.cira.mpsName) && (mpsServer.Port == dev.cira.mpsPort) && (mpsServer.InfoFormat == dev.cira.mpsAddressFormat)) { dev.cira.mpsPolicy = true; }
1212 + }
1213 + }
1214 +
1215 + // Remove all MPS policies that are not ours
1216 + if ((dev.cira.xxPolicies['User'] != null) && (dev.cira.xxPolicies['User'].length > 0)) { dev.consoleMsg("Removing CIRA user trigger."); dev.amtstack.Delete('AMT_RemoteAccessPolicyRule', { 'PolicyRuleName': 'User Initiated' }, function (stack, name, responses, status) { }); }
1217 + if ((dev.cira.xxPolicies['Alert'] != null) && (dev.cira.xxPolicies['Alert'].length > 0)) { dev.consoleMsg("Removing CIRA alert trigger."); dev.amtstack.Delete('AMT_RemoteAccessPolicyRule', { 'PolicyRuleName': 'Alert' }, function (stack, name, responses, status) { }); }
1218 + if ((dev.cira.xxPolicies['Periodic'] != null) && (dev.cira.xxPolicies['Periodic'].length > 0) && (dev.cira.mpsPolicy == false)) { dev.consoleMsg("Removing CIRA periodic trigger."); dev.amtstack.Delete('AMT_RemoteAccessPolicyRule', { 'PolicyRuleName': 'Periodic' }, function (stack, name, responses, status) { }); }
1219 +
1220 + // Remove all MPS servers that are not ours
1221 + if (dev.cira.xxCiraServers.length > 0) {
1222 + for (var i = 0; i < dev.cira.xxCiraServers.length; i++) {
1223 + var mpsServer = dev.cira.xxCiraServers[i];
1224 + if ((mpsServer.AccessInfo != dev.cira.mpsName) || (mpsServer.Port != dev.cira.mpsPort) || (mpsServer.InfoFormat != dev.cira.mpsAddressFormat)) {
1225 + dev.consoleMsg("Removing MPS server.");
1226 + dev.amtstack.Delete('AMT_ManagementPresenceRemoteSAP', { 'Name': mpsServer['Name'] }, function (stack, name, responses, status) { });
1227 + }
1228 + }
1229 + }
1230 +
1231 + // If we need to setup CIRA, start by checking the MPS server
1232 + // parent.mpsserver.server is not null if the MPS server is listening for TCP/TLS connections
1233 + if ((dev.policy.ciraPolicy == 2) && (parent.mpsserver.server != null)) { addMpsServer(dev); } else { checkEnvironmentDetection(dev); }
1234 }
1235
1236 function addMpsServer(dev) {
@@ -1316,6 +1343,7 @@ module.exports.CreateAmtManager = function (parent) {
1343
1344 function attemptSettingsSync(dev, func) {
1345 if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
1346 + if (dev.policy.amtPolicy == 0) { func(dev); return; } // If there is no Intel AMT policy, skip this operation.
1347 dev.taskCount = 1;
1348 dev.taskCompleted = func;
1349