AMT stack and AMT password trials improvements.
Ylian Saint-Hilaire committed
Apr 5, 2021 at 14:01 UTC
3f6856cedc82664e508ed94487768a7a8da43673
2 files changed
+61
-34
amt/amt-wsman-comm.js
+11
-8
@@ -252,7 +252,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, mpsConn
252
obj.socket.setTimeout(60000); // Set socket idle timeout
253
obj.socket.on('error', function (ex) { obj.xtlsMethod = 1 - obj.xtlsMethod; });
254
obj.socket.on('close', obj.xxOnSocketClosed);
255
- obj.socket.on('timeout', obj.xxOnSocketTimeout);
255
+ obj.socket.on('timeout', obj.destroy);
256
257
// Decrypted tunnel from TLS communcation to be forwarded to websocket
258
obj.socket.on('data', function (data) { try { obj.xxOnSocketData(data.toString('binary')); } catch (e) { } }); // AMT/TLS ---> WS
@@ -272,7 +272,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, mpsConn
272
obj.socket.setTimeout(60000); // Set socket idle timeout
273
obj.socket.on('data', obj.xxOnSocketData);
274
obj.socket.on('close', obj.xxOnSocketClosed);
275
- obj.socket.on('timeout', obj.xxOnSocketTimeout);
275
+ obj.socket.on('timeout', obj.destroy);
276
obj.socket.on('error', obj.xxOnSocketClosed);
277
obj.socket.connect(obj.port, obj.host, obj.xxOnSocketConnected);
278
} else {
@@ -289,7 +289,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, mpsConn
289
obj.socket.setTimeout(60000); // Set socket idle timeout
290
obj.socket.on('data', obj.xxOnSocketData);
291
obj.socket.on('close', obj.xxOnSocketClosed);
292
- obj.socket.on('timeout', obj.xxOnSocketTimeout);
292
+ obj.socket.on('timeout', obj.destroy);
293
obj.socket.on('error', function (ex) { if (ex.message && ex.message.indexOf('sslv3 alert bad record mac') >= 0) { obj.xtlsMethod = 1 - obj.xtlsMethod; } });
294
}
295
obj.socket.setNoDelay(true); // Disable nagle. We will encode each WSMAN request as a single send block and want to send it at once. This may help Intel AMT handle pipelining?
@@ -452,6 +452,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, mpsConn
452
//obj.Debug("xxOnSocketClosed");
453
obj.socketState = 0;
454
if (obj.socket != null) {
455
+ if (obj.socket.removeAllListeners) { obj.socket.removeAllListeners(); }
456
try {
457
if (obj.mpsConnection == null) {
458
obj.socket.destroy();
@@ -468,17 +469,19 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, mpsConn
469
}
470
}
471
471
- obj.xxOnSocketTimeout = function () {
472
+ obj.destroy = function () {
473
if (obj.socket != null) {
474
+ if (obj.socket.removeAllListeners) { obj.socket.removeAllListeners(); }
475
try {
476
if (obj.mpsConnection == null) {
477
obj.socket.destroy();
478
} else {
477
- if (obj.cirasocket != null) { obj.cirasocket.close(); } else { obj.socket.close(); }
479
+ if (obj.cirasocket != null) { obj.cirasocket.close(); } else { obj.socket.close(); }
480
}
481
} catch (ex) { }
480
- obj.socket = null;
481
- obj.cirasocket = null;
482
+ delete obj.socket;
483
+ delete obj.cirasocket;
484
+ obj.socketState = 0;
485
}
486
}
487
@@ -492,7 +495,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, mpsConn
495
obj.CancelAllQueries = function (s) {
496
obj.FailAllError = s;
497
while (obj.PendingAjax.length > 0) { var x = obj.PendingAjax.shift(); x[1](null, s, x[2]); }
495
- if (obj.socket != null) { obj.socket.end(); obj.socket = null; obj.socketState = 0; }
498
+ obj.destroy();
499
}
500
501
// Private method
amtmanager.js
+50
-26
@@ -127,7 +127,7 @@ module.exports.CreateAmtManager = function (parent) {
127
if (dev.taskid != null) { obj.parent.taskLimiter.completed(dev.taskid); delete dev.taskLimiter; }
128
129
// Clean up this device
130
- if (dev.amtstack != null) { dev.amtstack.wsman.comm.FailAllError = 999; delete dev.amtstack; } // Disconnect any active connections.
130
+ if (dev.amtstack != null) { dev.amtstack.CancelAllQueries(999); delete dev.amtstack.dev; delete dev.amtstack; }
131
if (dev.polltimer != null) { clearInterval(dev.polltimer); delete dev.polltimer; }
132
133
// Remove the device from the list
@@ -419,7 +419,14 @@ module.exports.CreateAmtManager = function (parent) {
419
420
// Attempt to perform initial contact with Intel AMT
421
function attemptInitialContact(dev) {
422
- delete dev.amtstack; // If there is a WSMAn stack setup, clean it up now.
422
+ // If there is a WSMAN stack setup, clean it up now.
423
+ if (dev.amtstack != null) {
424
+ dev.amtstack.CancelAllQueries(999);
425
+ delete dev.amtstack.dev;
426
+ delete dev.amtstack;
427
+ }
428
+
429
+ delete dev.amtstack;
430
parent.debug('amt', dev.name, "Attempt Initial Contact", ["CIRA", "CIRA-Relay", "CIRA-LMS", "Local"][dev.connType]);
431
432
// Check Intel AMT policy when CIRA-LMS connection is in use.
@@ -445,11 +452,42 @@ module.exports.CreateAmtManager = function (parent) {
452
}
453
}
454
448
- // See if we need to try different credentials
449
- if ((dev.acctry == null) && ((typeof dev.intelamt.user != 'string') || (typeof dev.intelamt.pass != 'string'))) {
450
- if ((obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > 0)) { dev.acctry = 0; } else { removeAmtDevice(dev, 8); return; }
455
+ // See what username/password we need to try
456
+ if (dev.acctry == null) {
457
+ dev.acctry = [];
458
+
459
+ // Add the know Intel AMT password for this device if available
460
+ if ((typeof dev.intelamt.user == 'string') && (typeof dev.intelamt.pass == 'string')) { dev.acctry.push([dev.intelamt.user, dev.intelamt.pass]); }
461
+
462
+ // Add the policy password as an alternative
463
+ if ((typeof dev.policy.password == 'string') && (dev.policy.password != '')) { dev.acctry.push(['admin', dev.policy.password]); }
464
+
465
+ // Add any configured admin account as alternatives
466
+ if (obj.amtAdminAccounts[dev.domainid] != null) { for (var i in obj.amtAdminAccounts[dev.domainid]) { dev.acctry.push([obj.amtAdminAccounts[dev.domainid][i].user, obj.amtAdminAccounts[dev.domainid][i].pass]); } }
467
+
468
+ // Add any previous passwords for the device UUID as alternative
469
+ if ((parent.amtPasswords != null) && (dev.mpsConnection != null) && (dev.mpsConnection.tag != null) && (dev.mpsConnection.tag.meiState != null) && (dev.mpsConnection.tag.meiState.UUID != null) && (parent.amtPasswords[dev.mpsConnection.tag.meiState.UUID] != null)) {
470
+ for (var i in parent.amtPasswords[dev.mpsConnection.tag.meiState.UUID]) {
471
+ dev.acctry.push(['admin', parent.amtPasswords[dev.mpsConnection.tag.meiState.UUID][i]]);
472
+ }
473
+ }
474
+
475
+ // Remove any duplicates user/passwords
476
+ var acctry2 = [];
477
+ for (var i = 0; i < dev.acctry.length; i++) {
478
+ var found = false;
479
+ for (var j = 0; j < acctry2.length; j++) { if ((dev.acctry[i][0] == acctry2[j][0]) && (dev.acctry[i][1] == acctry2[j][1])) { found = true; } }
480
+ if (found == false) { acctry2.push(dev.acctry[i]); }
481
+ }
482
+ dev.acctry = acctry2;
483
+
484
+ // If we have passwords to try, try the first one now.
485
+ if (dev.acctry.length == 0) { removeAmtDevice(dev, 8); return; }
486
}
487
488
+ if ((dev.acctry == null) || (dev.acctry.length == 0)) { removeAmtDevice(dev, 9); return; } // No Intel AMT credentials to try
489
+ var user = dev.acctry[0][0], pass = dev.acctry[0][1]; // Try the first user/pass in the list
490
+
491
switch (dev.connType) {
492
case 0: // CIRA
493
// Handle the case where the Intel AMT CIRA is connected (connType 0)
@@ -459,12 +497,6 @@ module.exports.CreateAmtManager = function (parent) {
497
var ciraconn = dev.mpsConnection;
498
if ((ciraconn == null) || (ciraconn.tag == null) || (ciraconn.tag.boundPorts == null)) { removeAmtDevice(dev, 9); return; } // CIRA connection is not on this server, no need to deal with this device anymore.
499
462
- // See what user/pass to try.
463
- var user = null, pass = null;
464
- if (dev.acctry == null) { user = dev.intelamt.user; pass = dev.intelamt.pass; }
465
- else if (dev.acctry == 'policy') { user = 'admin'; pass = dev.policy.password; }
466
- else if (typeof dev.acctry == 'number') { user = obj.amtAdminAccounts[dev.domainid][dev.acctry].user; pass = obj.amtAdminAccounts[dev.domainid][dev.acctry].pass; }
467
-
500
// See if we need to perform TLS or not. We prefer not to do TLS within CIRA.
501
var dotls = -1;
502
if (ciraconn.tag.boundPorts.indexOf('16992')) { dotls = 0; }
@@ -492,12 +524,6 @@ module.exports.CreateAmtManager = function (parent) {
524
var ciraconn = dev.mpsConnection;
525
if ((ciraconn == null) || (ciraconn.tag == null) || (ciraconn.tag.boundPorts == null)) { removeAmtDevice(dev, 11); return; } // Relay connection not valid
526
495
- // See what user/pass to try.
496
- var user = null, pass = null;
497
- if (dev.acctry == null) { user = dev.intelamt.user; pass = dev.intelamt.pass; }
498
- else if (dev.acctry == 'policy') { user = 'admin'; pass = dev.policy.password; }
499
- else if (typeof dev.acctry == 'number') { user = obj.amtAdminAccounts[dev.domainid][dev.acctry].user; pass = obj.amtAdminAccounts[dev.domainid][dev.acctry].pass; }
500
-
527
// Connect now
528
var comm;
529
if (dev.tlsfail !== true) {
@@ -530,12 +556,6 @@ module.exports.CreateAmtManager = function (parent) {
556
} else {
557
// No active connections
558
533
- // See what user/pass to try.
534
- var user = null, pass = null;
535
- if (dev.acctry == null) { user = dev.intelamt.user; pass = dev.intelamt.pass; }
536
- else if (dev.acctry == 'policy') { user = 'admin'; pass = dev.policy.password; }
537
- else if (typeof dev.acctry == 'number') { user = obj.amtAdminAccounts[dev.domainid][dev.acctry].user; pass = obj.amtAdminAccounts[dev.domainid][dev.acctry].pass; }
538
-
559
// Connect now
560
var comm;
561
if (dev.tlsfail !== true) {
@@ -631,9 +651,13 @@ module.exports.CreateAmtManager = function (parent) {
651
dev.tlsfail = true; attemptInitialContact(dev); return;
652
} else if (status == 401) {
653
// Authentication error, see if we can use alternative credentials
634
- if ((dev.acctry == null) && (typeof dev.policy.password == 'string') && (dev.policy.password != '')) { dev.acctry = 'policy'; attemptInitialContact(dev); return; }
635
- if (((dev.acctry == null) || (dev.acctry == 'policy')) && (obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > 0)) { dev.acctry = 0; attemptInitialContact(dev); return; }
636
- if ((dev.acctry != null) && (obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > (dev.acctry + 1))) { dev.acctry++; attemptInitialContact(dev); return; }
654
+ if (dev.acctry != null) {
655
+ // Remove the first password from the trial list since it did not work.
656
+ if (dev.acctry.length > 0) { dev.acctry.shift(); }
657
+
658
+ // We have another password to try, hold 20 second and try the next user/password.
659
+ if (dev.acctry.length > 0) { setTimeout(function () { if (isAmtDeviceValid(dev)) { attemptInitialContact(dev); } }, 20000); return; }
660
+ }
661
662
// If this devics is in CCM mode and we have a bad password reset policy, do it now.
663
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)) {