Intel AMT manager overhall, many improvements.

Ylian Saint-Hilaire committed Oct 15, 2020 at 16:08 UTC 15210298231fb19d88048b85bdf8be6ad26094d6
6 files changed +315 -256
amt/amt-wsman-comm.js
+8 -8
@@ -26,7 +26,7 @@ limitations under the License.
26 "use strict";
27
28 // Construct a WSMAN stack communication object
29 -var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraConnection) {
29 +var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, mpsConnection) {
30 //console.log('CreateWsmanComm', host, port, user, pass, tls, tlsoptions);
31
32 var obj = {};
@@ -59,7 +59,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
59 obj.pass = pass;
60 obj.xtls = tls;
61 obj.xtlsoptions = tlsoptions;
62 - obj.ciraConnection = ciraConnection; // This can be a CIRA or APF server, if null, local sockets are used as transport.
62 + obj.mpsConnection = mpsConnection; // Link to a MPS connection, this can be CIRA, Relay or LMS. If null, local sockets are used as transport.
63 obj.xtlsFingerprint;
64 obj.xtlsCertificate = null;
65 obj.xtlsCheck = 0; // 0 = No TLS, 1 = CA Checked, 2 = Pinned, 3 = Untrusted
@@ -197,10 +197,10 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
197 obj.socketState = 1;
198 obj.kerberosDone = 0;
199
200 - if (obj.ciraConnection != null) {
200 + if (obj.mpsConnection != null) {
201 if (obj.xtls != 1) {
202 // Setup a new channel using the CIRA/Relay/LMS connection
203 - obj.socket = obj.ciraConnection.SetupChannel(obj.port);
203 + obj.socket = obj.mpsConnection.SetupChannel(obj.port);
204 if (obj.socket == null) { obj.xxOnSocketClosed(); return; }
205
206 // Connect without TLS
@@ -221,7 +221,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
221 }
222 } else {
223 // Setup a new channel using the CIRA/Relay/LMS connection
224 - obj.cirasocket = obj.ciraConnection.SetupChannel(obj.port);
224 + obj.cirasocket = obj.mpsConnection.SetupChannel(obj.port);
225 if (obj.cirasocket == null) { obj.xxOnSocketClosed(); return; }
226
227 // Connect with TLS
@@ -425,7 +425,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
425 if (isNaN(s)) s = 500;
426 if (s == 401 && ++(obj.authcounter) < 3) {
427 obj.challengeParams = obj.parseDigest(header['www-authenticate']); // Set the digest parameters, after this, the socket will close and we will auto-retry
428 - if (obj.ciraConnection == null) { obj.socket.end(); } else { obj.socket.close(); }
428 + if (obj.mpsConnection == null) { obj.socket.end(); } else { obj.socket.close(); }
429 } else {
430 var r = obj.pendingAjaxCall.shift();
431 if (r == null || r.length < 1) { console.log("pendingAjaxCall error, " + r); return; }
@@ -443,7 +443,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
443 obj.socketState = 0;
444 if (obj.socket != null) {
445 try {
446 - if (obj.ciraConnection == null) {
446 + if (obj.mpsConnection == null) {
447 obj.socket.destroy();
448 } else {
449 if (obj.cirasocket != null) { obj.cirasocket.close(); } else { obj.socket.close(); }
@@ -461,7 +461,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, ciraCon
461 obj.xxOnSocketTimeout = function () {
462 if (obj.socket != null) {
463 try {
464 - if (obj.ciraConnection == null) {
464 + if (obj.mpsConnection == null) {
465 obj.socket.destroy();
466 } else {
467 if (obj.cirasocket != null) { obj.cirasocket.close(); } else { obj.socket.close(); }
amtmanager.js
+296 -237
@@ -11,64 +11,142 @@
11 /*jshint strict:false */
12 /*jshint -W097 */
13 /*jshint esversion: 6 */
14 -"use strict";
15 -
14 +'use strict';
15
16 module.exports.CreateAmtManager = function(parent) {
17 var obj = {};
18 obj.parent = parent;
20 - obj.amtDevices = {}; // Nodeid --> dev
21 - obj.activeLocalConnections = {}; // Host --> dev
22 - obj.amtAdminAccounts = [];
19 + obj.amtDevices = {}; // Nodeid --> [ dev ]
20 + obj.activeLocalConnections = {}; // Host --> [ dev ]
21 + obj.amtAdminAccounts = {}; // DomainId -> [ { user, pass } ]
22
23 // WSMAN stack
24 const CreateWsmanComm = require('./amt/amt-wsman-comm');
25 const WsmanStackCreateService = require('./amt/amt-wsman');
26 const AmtStackCreateService = require('./amt/amt');
27 + const ConnectionTypeStrings = { 0: "CIRA", 1: "Relay", 2: "LMS", 3: "Local" };
28 +
29 + // Load the Intel AMT admin accounts credentials for each domain
30 + if ((parent.config != null) && (parent.config.domains != null)) {
31 + for (var domainid in parent.config.domains) {
32 + var domain = parent.config.domains[domainid];
33 + if ((typeof domain.amtmanager == 'object') && (Array.isArray(domain.amtmanager.amtadminaccount) == true)) {
34 + for (var i in domain.amtmanager.amtadminaccount) {
35 + var c = domain.amtmanager.amtadminaccount[i], c2 = { user: 'admin' };
36 + if (typeof c.user == 'string') { c2.user = c.user; }
37 + if (typeof c.pass == 'string') {
38 + c2.pass = c.pass;
39 + if (obj.amtAdminAccounts[domainid] == null) { obj.amtAdminAccounts[domainid] = []; }
40 + obj.amtAdminAccounts[domainid].push(c2);
41 + }
42 + }
43 + }
44 +
45 + }
46 + }
47 +
48 + // Check if an Intel AMT device is being managed
49 + function isAmtDeviceValid(dev) {
50 + var devices = obj.amtDevices[dev.nodeid];
51 + if (devices == null) return false;
52 + return (devices.indexOf(dev) >= 0)
53 + }
54 +
55 + // Add an Intel AMT managed device
56 + function addAmtDevice(dev) {
57 + var devices = obj.amtDevices[dev.nodeid];
58 + if (devices == null) { obj.amtDevices[dev.nodeid] = [dev]; return true; }
59 + if (devices.indexOf(dev) >= 0) { return false; } // This device is already in the list
60 + devices.push(dev); // Add the device to the list
61 + return true;
62 + }
63 +
64 + // Remove an Intel AMT managed device
65 + function removeAmtDevice(dev) {
66 + // Find the device in the list
67 + var devices = obj.amtDevices[dev.nodeid];
68 + if (devices == null) return false;
69 + var i = devices.indexOf(dev);
70 + if (i == -1) return false;
71 +
72 + // Clean up this device
73 + if (dev.amtstack != null) { dev.amtstack.wsman.comm.FailAllError = 999; delete dev.amtstack; } // Disconnect any active connections.
74 + if (dev.polltimer != null) { clearInterval(dev.polltimer); delete dev.polltimer; }
75 +
76 + // Remove the device from the list
77 + devices.splice(i, 1);
78 + if (devices.length == 0) { delete obj.amtDevices[dev.nodeid]; } else { obj.amtDevices[dev.nodeid] = devices; }
79 + return true;
80 + }
81 +
82 + // Remove all Intel AMT devices for a given nodeid
83 + function removeDevice(nodeid) {
84 + // Find the devices in the list
85 + var devices = obj.amtDevices[nodeid];
86 + if (devices == null) return false;
87 +
88 + for (var i in devices) {
89 + // Clean up this device
90 + var dev = devices[i];
91 + if (dev.amtstack != null) { dev.amtstack.wsman.comm.FailAllError = 999; delete dev.amtstack; } // Disconnect any active connections.
92 + if (dev.polltimer != null) { clearInterval(dev.polltimer); delete dev.polltimer; }
93 + }
94 +
95 + // Remove all devices
96 + delete obj.amtDevices[nodeid];
97 + return true;
98 + }
99 +
100 + // Start Intel AMT management
101 + obj.startAmtManagement = function (nodeid, connType, connection) {
102 + //if (connType == 3) return; // DEBUG
103 + var devices = obj.amtDevices[nodeid], dev = null;
104 + if (devices != null) { for (var i in devices) { if ((devices[i].mpsConnection == connection) || (devices[i].host == connection)) { dev = devices[i]; } } }
105 + if (dev != null) return false; // We are already managing this device on this connection
106 + dev = { nodeid: nodeid, connType: connType };
107 + if (typeof connection == 'string') { dev.host = connection; }
108 + if (typeof connection == 'object') { dev.mpsConnection = connection; }
109 + parent.debug('amt', "Start Management", nodeid, connType);
110 + addAmtDevice(dev);
111 + fetchIntelAmtInformation(dev);
112 + }
113 +
114 + // Stop Intel AMT management
115 + obj.stopAmtManagement = function (nodeid, connType, connection) {
116 + var devices = obj.amtDevices[nodeid], dev = null;
117 + if (devices != null) { for (var i in devices) { if ((devices[i].mpsConnection == connection) || (devices[i].host == connection)) { dev = devices[i]; } } }
118 + if (dev == null) return false; // We are not managing this device on this connection
119 + parent.debug('amt', "Stop Management", nodeid, connType);
120 + return removeAmtDevice(dev);
121 + }
122
29 - // Load the Intel AMT admin accounts
30 - if ((typeof parent.args.amtmanager == 'object') && (Array.isArray(parent.args.amtmanager.amtadminaccount) == true)) {
31 - for (var i in parent.args.amtmanager.amtadminaccount) {
32 - var c = parent.args.amtmanager.amtadminaccount[i], c2 = { user: 'admin' };
33 - if (typeof c.user == 'string') { c2.user = c.user; }
34 - if (typeof c.pass == 'string') { c2.pass = c.pass; obj.amtAdminAccounts.push(c2); }
123 + // Get a string status of the managed devices
124 + obj.getStatusString = function () {
125 + var r = '';
126 + for (var nodeid in obj.amtDevices) {
127 + var devices = obj.amtDevices[nodeid];
128 + r += devices[0].nodeid + ', ' + devices[0].name + '\r\n';
129 + for (var i in devices) {
130 + var dev = devices[i];
131 + var items = [];
132 + if (dev.state == 1) { items.push('Connected'); } else { items.push('Trying'); }
133 + items.push(ConnectionTypeStrings[dev.connType]);
134 + if (dev.connType == 3) { items.push(dev.host); }
135 + if (dev.polltimer != null) { items.push('Polling Power'); }
136 + r += ' ' + items.join(', ') + '\r\n';
137 + }
138 }
139 + if (r == '') { r = "No managed Intel AMT devices"; }
140 + return r;
141 }
142
143 // Subscribe to server events
144 parent.AddEventDispatch(['*'], obj);
145
146 // Handle server events
42 - // TODO: Only manage devices with connections to this server. In a multi-server setup, we don't want multiple managers talking to the same device.
147 + // Make sure to only manage devices with connections to this server. In a multi-server setup, we don't want multiple managers talking to the same device.
148 obj.HandleEvent = function (source, event, ids, id) {
149 switch (event.action) {
45 - case 'nodeconnect': { // React to nodes connecting and disconnecting
46 - // See if we have an existing device we manage
47 - var dev = obj.amtDevices[event.nodeid];
48 -
49 - // If the connection type we are using is not longer valid, remove our managed device.
50 - if ((dev != null) && (dev.conntype != null) && ((dev.conntype & event.conn) == 0)) { removeDevice(event.nodeid); dev = null; }
51 -
52 - // Debug line, to only manage CIRA/Relay connections
53 - //if ((event.conn & 10) == 0) return;
54 -
55 - // Create or update a managed device
56 - if ((event.conn & 14) != 0) { // connectType: Bitmask, 1 = MeshAgent, 2 = Intel AMT CIRA, 4 = Intel AMT local, 8 = Intel AMT Relay, 16 = MQTT
57 - // We have an OOB connection to Intel AMT, update our information
58 - if (dev == null) {
59 - obj.amtDevices[event.nodeid] = dev = { conn: event.conn }; fetchIntelAmtInformation(event.nodeid);
60 - } else {
61 - dev.conn = event.conn;
62 - }
63 - } else if (((event.conn & 1) != 0) && (parent.webserver != null)) {
64 - // We have an agent connection without CIRA/Local/Relay, check if this agent supports Intel AMT
65 - var agent = parent.webserver.wsagents[event.nodeid];
66 - if ((agent != null) && (agent.agentInfo != null) && (parent.meshAgentsArchitectureNumbers[agent.agentInfo.agentId].amt == true)) {
67 - // We could turn on LMS relay at this point.
68 - }
69 - }
70 - break;
71 - }
150 case 'removenode': { // React to node being removed
151 removeDevice(event.nodeid);
152 break;
@@ -77,27 +155,13 @@ module.exports.CreateAmtManager = function(parent) {
155 if (Array.isArray(event.nodeids)) { for (var i in event.nodeids) { performPowerAction(event.nodeids[i], 2); } }
156 break;
157 }
80 - case 'changenode': { // React to changes in a node
158 + case 'changenode': { // React to changes in a device
159 + var devices = obj.amtDevices[event.nodeid];
160 + if (devices = null) break; // We are not managing this device
161 if (event.amtchange === 1) {
82 - // A change occured in the Intel AMT credentials, we need to reset the connection
83 - removeDevice(event.nodeid);
84 -
85 - // Check if the agent is connected
86 - var constate = parent.GetConnectivityState(event.nodeid);
87 - if (constate == null) return; // No OOB connectivity, exit now.
88 -
89 - if ((constate & 14) != 0) { // connectType: Bitmask, 1 = MeshAgent, 2 = Intel AMT CIRA, 4 = Intel AMT local, 8 = Intel AMT Relay, 16 = MQTT
90 - // We have an OOB connection to Intel AMT, update our information
91 - var dev = obj.amtDevices[event.nodeid];
92 - if (dev == null) { obj.amtDevices[event.nodeid] = dev = { conn: constate }; fetchIntelAmtInformation(event.nodeid); } else { dev.conn = constate; }
93 - } else if (((event.conn & 1) != 0) && (parent.webserver != null)) {
94 - // We have an agent connection without OOB, check if this agent supports Intel AMT
95 - var agent = parent.webserver.wsagents[event.nodeid];
96 - if ((agent == null) || (agent.agentInfo == null) || (parent.meshAgentsArchitectureNumbers[agent.agentInfo.agentId].amt == false)) { removeDevice(event.nodeid); return; }
97 - var dev = obj.amtDevices[event.nodeid];
98 - if (dev == null) { obj.amtDevices[event.nodeid] = dev = { conn: constate }; fetchIntelAmtInformation(event.nodeid); } else { dev.conn = constate; }
99 - }
162 + // TODO
163 } else {
164 + /*
165 var dev = obj.amtDevices[event.nodeid];
166 if (dev != null) {
167 var amtchange = 0;
@@ -108,90 +172,24 @@ module.exports.CreateAmtManager = function(parent) {
172 if ((dev.conn & 4) != 0) { removeDevice(dev.nodeid); return; } // We are going to wait for the AMT scanned to find this device again.
173 }
174 }
175 + */
176 }
177 break;
178 }
179 }
180 }
181
117 - // Remove a device
118 - function removeDevice(nodeid) {
119 - const dev = obj.amtDevices[nodeid];
120 - if (dev == null) return;
121 - if (dev.amtstack != null) { dev.amtstack.wsman.comm.FailAllError = 999; delete dev.amtstack; } // Disconnect any active connections.
122 - if (dev.polltimer != null) { clearInterval(dev.polltimer); delete dev.polltimer; }
123 - delete obj.amtDevices[nodeid];
124 - }
125 -
126 - // Get the current power state of a device
127 - function fetchPowerState(dev) {
128 - dev = obj.amtDevices[dev.nodeid];
129 - if ((dev == null) || (dev.amtstack == null)) return;
130 -
131 - // Check if the agent is connected
132 - var constate = parent.GetConnectivityState(dev.nodeid);
133 - if ((constate == null) || (constate.connectivity & 1)) return; // If there is no connectivity or the agent is connected, skip trying to poll power state.
134 -
135 - // Fetch the power state
136 - dev.amtstack.BatchEnum(null, ['CIM_ServiceAvailableToElement'], function (stack, name, responses, status) {
137 - const dev = stack.dev;
138 - if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this response.
139 -
140 - if ((status != 200) || (responses['CIM_ServiceAvailableToElement'] == null) || (responses['CIM_ServiceAvailableToElement'].responses == null) || (responses['CIM_ServiceAvailableToElement'].responses.length < 1)) return; // If the polling fails, just skip it.
141 - var powerstate = responses['CIM_ServiceAvailableToElement'].responses[0].PowerState;
142 - if ((powerstate == 2) && (dev.aquired.majorver > 9)) {
143 - // Device is powered on and Intel AMT 10+, poll the OS power state.
144 - dev.amtstack.Get('IPS_PowerManagementService', function (stack, name, response, status) {
145 - const dev = stack.dev;
146 - if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this response.
147 - if (status != 200) return;
148 -
149 - // Convert the OS power state
150 - var meshPowerState = -1;
151 - if (response.Body.OSPowerSavingState == 2) { meshPowerState = 1; } // Fully powered (S0);
152 - else if (response.Body.OSPowerSavingState == 3) { meshPowerState = 2; } // Modern standby (We are going to call this S1);
153 -
154 - // Set OS power state
155 - if (meshPowerState >= 0) { parent.SetConnectivityState(dev.meshid, dev.nodeid, Date.now(), 4, meshPowerState); }
156 - });
157 - } else {
158 - // Convert the power state
159 - // AMT power: 1 = Other, 2 = On, 3 = Sleep-Light, 4 = Sleep-Deep, 5 = Power Cycle (Off-Soft), 6 = Off-Hard, 7 = Hibernate (Off-Soft), 8 = Off-Soft, 9 = Power Cycle (Off-Hard), 10 = Master Bus Reset, 11 = Diagnostic Interrupt (NMI), 12 = Off-Soft Graceful, 13 = Off-Hard Graceful, 14 = Master Bus Reset Graceful, 15 = Power Cycle (Off- oft Graceful), 16 = Power Cycle (Off - Hard Graceful), 17 = Diagnostic Interrupt (INIT)
160 - // Mesh power: 0 = Unknown, 1 = S0 power on, 2 = S1 Sleep, 3 = S2 Sleep, 4 = S3 Sleep, 5 = S4 Hibernate, 6 = S5 Soft-Off, 7 = Present
161 - var meshPowerState = -1, powerConversionTable = [-1, -1, 1, 2, 3, 6, 6, 5, 6];
162 - if (powerstate < powerConversionTable.length) { meshPowerState = powerConversionTable[powerstate]; } else { powerstate = 6; }
163 -
164 - // Set power state
165 - if (meshPowerState >= 0) { parent.SetConnectivityState(dev.meshid, dev.nodeid, Date.now(), 4, meshPowerState); }
166 - }
167 - });
168 - }
169 -
170 - // Perform a power action: 2 = Power up, 5 = Power cycle, 8 = Power down, 10 = Reset
171 - function performPowerAction(nodeid, action) {
172 - var dev = obj.amtDevices[nodeid];
173 - if ((dev == null) || (dev.amtstack == null)) return;
174 - try { dev.amtstack.RequestPowerStateChange(action, performPowerActionResponse); } catch (ex) { }
175 - }
176 -
177 - // Response to Intel AMT power action
178 - function performPowerActionResponse(stack, name, responses, status) {
179 - //console.log('performPowerActionResponse', status);
180 - }
181 -
182 // Update information about a device
183 - function fetchIntelAmtInformation(nodeid) {
184 - parent.db.Get(nodeid, function (err, nodes) {
185 - if ((nodes == null) || (nodes.length != 1)) { removeDevice(nodeid); return; }
183 + function fetchIntelAmtInformation(dev) {
184 + parent.db.Get(dev.nodeid, function (err, nodes) {
185 + if ((nodes == null) || (nodes.length != 1)) { removeAmtDevice(dev); return; }
186 const node = nodes[0];
187 - if ((node.intelamt == null) || (node.meshid == null)) { removeDevice(nodeid); return; }
187 + if ((node.intelamt == null) || (node.meshid == null)) { removeAmtDevice(dev); return; }
188 const mesh = parent.webserver.meshes[node.meshid];
189 - if (mesh == null) { removeDevice(nodeid); return; }
190 - const dev = obj.amtDevices[nodeid];
189 + if (mesh == null) { removeAmtDevice(dev); return; }
190 if (dev == null) { return; }
191 dev.name = node.name;
193 - dev.nodeid = node._id;
194 - if (node.host) { dev.host = node.host.toLowerCase(); }
192 + //if (node.host) { dev.host = node.host.toLowerCase(); }
193 dev.meshid = node.meshid;
194 dev.intelamt = node.intelamt;
195 attemptInitialContact(dev);
@@ -200,125 +198,124 @@ module.exports.CreateAmtManager = function(parent) {
198
199 // Attempt to perform initial contact with Intel AMT
200 function attemptInitialContact(dev) {
203 - if (dev == null) return;
204 - //console.log('attemptInitialContact', dev.name);
201 + parent.debug('amt', "Attempt Initial Contact", dev.name, dev.connType);
202
203 if ((dev.acctry == null) && ((typeof dev.intelamt.user != 'string') || (typeof dev.intelamt.pass != 'string'))) {
207 - if (obj.amtAdminAccounts.length > 0) { dev.acctry = 0; } else { return; }
204 + if ((obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > 0)) { dev.acctry = 0; } else { return; }
205 }
206
210 - // Handle the case where the Intel AMT CIRA is connected (conn & 2)
211 - // In this connection type, we look at the port bindings to see if we need to do TLS or not.
212 - if ((dev.conn & 2) != 0) {
213 - // Check to see if CIRA is connected on this server.
214 - var ciraconn = parent.mpsserver.GetConnectionToNode(dev.nodeid, null, 0); // Select the CIRA connection
215 - if ((ciraconn == null) || (ciraconn.tag == null) || (ciraconn.tag.boundPorts == null)) { removeDevice(dev.nodeid); return; } // CIRA connection is not on this server, no need to deal with this device anymore.
216 -
217 - // See what user/pass to try.
218 - var user = null, pass = null;
219 - if (dev.acctry == null) { user = dev.intelamt.user; pass = dev.intelamt.pass; } else { user = obj.amtAdminAccounts[dev.acctry].user; pass = obj.amtAdminAccounts[dev.acctry].pass; }
220 -
221 - // See if we need to perform TLS or not. We prefer not to do TLS within CIRA.
222 - var dotls = -1;
223 - if (ciraconn.tag.boundPorts.indexOf('16992')) { dotls = 0; }
224 - else if (ciraconn.tag.boundPorts.indexOf('16993')) { dotls = 1; }
225 - if (dotls == -1) { removeDevice(dev.nodeid); return; } // The Intel AMT ports are not open, not a device we can deal with.
226 -
227 - // Connect now
228 - //console.log('CIRA-Connect', (dotls == 1)?"TLS":"NoTLS", dev.name, dev.host, user, pass);
229 - var comm;
230 - if (dotls == 1) {
231 - comm = CreateWsmanComm(dev.nodeid, 16993, user, pass, 1, null, ciraconn); // Perform TLS
232 - comm.xtlsFingerprint = 0; // Perform no certificate checking
233 - } else {
234 - comm = CreateWsmanComm(dev.nodeid, 16992, user, pass, 0, null, ciraconn); // No TLS
235 - }
236 - var wsstack = WsmanStackCreateService(comm);
237 - dev.amtstack = AmtStackCreateService(wsstack);
238 - dev.amtstack.dev = dev;
239 - obj.activeLocalConnections[dev.host] = dev;
240 - dev.amtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], attemptLocalConnectResponse);
241 - dev.conntype = 2; // CIRA
242 -
243 - return; // If CIRA is connected, don't try any other methods.
244 - }
207 + switch (dev.connType) {
208 + case 0: // CIRA
209 + // Handle the case where the Intel AMT CIRA is connected (connType 0)
210 + // In this connection type, we look at the port bindings to see if we need to do TLS or not.
211
246 - // Handle the case where the Intel AMT relay is connected (conn & 8)
247 - if ((dev.conn & 8) != 0) {
248 - // Check to see if CIRA is connected on this server.
249 - var ciraconn = parent.mpsserver.GetConnectionToNode(dev.nodeid, null, 1); // Select a relay connection
250 - if ((ciraconn == null) || (ciraconn.tag == null) || (ciraconn.tag.boundPorts == null)) { removeDevice(dev.nodeid); return; } // CIRA connection is not on this server, no need to deal with this device anymore.
251 -
252 - // See what user/pass to try.
253 - var user = null, pass = null;
254 - if (dev.acctry == null) { user = dev.intelamt.user; pass = dev.intelamt.pass; } else { user = obj.amtAdminAccounts[dev.acctry].user; pass = obj.amtAdminAccounts[dev.acctry].pass; }
255 -
256 - // Connect now
257 - var comm;
258 - if (dev.tlsfail !== true) {
259 - //console.log('Relay-Connect', "TLS", dev.name, dev.host, user, pass);
260 - comm = CreateWsmanComm(dev.nodeid, 16993, user, pass, 1, null, ciraconn); // Perform TLS
261 - comm.xtlsFingerprint = 0; // Perform no certificate checking
262 - } else {
263 - //console.log('Relay-Connect', "NoTLS", dev.name, dev.host, user, pass);
264 - comm = CreateWsmanComm(dev.nodeid, 16992, user, pass, 0, null, ciraconn); // No TLS
265 - }
266 - var wsstack = WsmanStackCreateService(comm);
267 - dev.amtstack = AmtStackCreateService(wsstack);
268 - dev.amtstack.dev = dev;
269 - obj.activeLocalConnections[dev.host] = dev;
270 - dev.amtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], attemptLocalConnectResponse);
271 - dev.conntype = 8; // Relay
272 -
273 - return; // If relay is connected, don't try any other methods.
274 - }
212 + // Check to see if CIRA is connected on this server.
213 + var ciraconn = dev.mpsConnection;
214 + if ((ciraconn == null) || (ciraconn.tag == null) || (ciraconn.tag.boundPorts == null)) { removeAmtDevice(dev); return; } // CIRA connection is not on this server, no need to deal with this device anymore.
215
276 - // Handle the case where the Intel AMT local scanner found the device (conn & 4)
277 - if (((dev.conn & 4) != 0) && (typeof dev.host == 'string')) {
278 - // Since we don't allow two or more connections to the same host, check if a pending connection is active.
279 - if (obj.activeLocalConnections[dev.host] != null) {
280 - // Active connection, hold and try later.
281 - var tryAgainFunc = function tryAgainFunc() { if (obj.amtDevices[tryAgainFunc.dev.nodeid] != null) { attemptInitialContact(tryAgainFunc.dev); } }
282 - tryAgainFunc.dev = dev;
283 - setTimeout(tryAgainFunc, 5000);
284 - } else {
285 - // No active connections, see what user/pass to try.
216 + // See what user/pass to try.
217 var user = null, pass = null;
287 - if (dev.acctry == null) { user = dev.intelamt.user; pass = dev.intelamt.pass; } else { user = obj.amtAdminAccounts[dev.acctry].user; pass = obj.amtAdminAccounts[dev.acctry].pass; }
218 + if (dev.acctry == null) { user = dev.intelamt.user; pass = dev.intelamt.pass; } else { user = obj.amtAdminAccounts[dev.domainid][dev.acctry].user; pass = obj.amtAdminAccounts[dev.domainid][dev.acctry].pass; }
219 +
220 + // See if we need to perform TLS or not. We prefer not to do TLS within CIRA.
221 + var dotls = -1;
222 + if (ciraconn.tag.boundPorts.indexOf('16992')) { dotls = 0; }
223 + else if (ciraconn.tag.boundPorts.indexOf('16993')) { dotls = 1; }
224 + if (dotls == -1) { removeDevice(dev.nodeid); return; } // The Intel AMT ports are not open, not a device we can deal with.
225 +
226 + // Connect now
227 + parent.debug('amt', 'CIRA-Connect', (dotls == 1) ? "TLS" : "NoTLS", dev.name, user, pass);
228 + var comm;
229 + if (dotls == 1) {
230 + comm = CreateWsmanComm(dev.nodeid, 16993, user, pass, 1, null, ciraconn); // Perform TLS
231 + comm.xtlsFingerprint = 0; // Perform no certificate checking
232 + } else {
233 + comm = CreateWsmanComm(dev.nodeid, 16992, user, pass, 0, null, ciraconn); // No TLS
234 + }
235 + var wsstack = WsmanStackCreateService(comm);
236 + dev.amtstack = AmtStackCreateService(wsstack);
237 + dev.amtstack.dev = dev;
238 + obj.activeLocalConnections[dev.host] = dev;
239 + dev.amtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], attemptLocalConnectResponse);
240 + break;
241 + case 1:
242 + case 2:
243 + // Handle the case where the Intel AMT relay or LMS is connected (connType 1 or 2)
244 + // Check to see if CIRA is connected on this server.
245 + var ciraconn = dev.mpsConnection;
246 + if ((ciraconn == null) || (ciraconn.tag == null) || (ciraconn.tag.boundPorts == null)) { removeAmtDevice(dev); return; } // Relay connection not valid
247 +
248 + // See what user/pass to try.
249 + var user = null, pass = null;
250 + if (dev.acctry == null) { user = dev.intelamt.user; pass = dev.intelamt.pass; } else { user = obj.amtAdminAccounts[dev.domainid][dev.acctry].user; pass = obj.amtAdminAccounts[dev.domainid][dev.acctry].pass; }
251
252 // Connect now
253 var comm;
254 if (dev.tlsfail !== true) {
292 - //console.log('Direct-Connect', "TLS", dev.name, dev.host, user, pass);
293 - comm = CreateWsmanComm(dev.host, 16993, user, pass, 1); // Always try with TLS first
255 + parent.debug('amt', 'Relay-Connect', "TLS", dev.name, user, pass);
256 + comm = CreateWsmanComm(dev.nodeid, 16993, user, pass, 1, null, ciraconn); // Perform TLS
257 comm.xtlsFingerprint = 0; // Perform no certificate checking
258 } else {
296 - //console.log('Direct-Connect', "NoTLS", dev.name, dev.host, user, pass);
297 - comm = CreateWsmanComm(dev.host, 16992, user, pass, 0); // Try without TLS
259 + parent.debug('amt', 'Relay-Connect', "NoTLS", dev.name, user, pass);
260 + comm = CreateWsmanComm(dev.nodeid, 16992, user, pass, 0, null, ciraconn); // No TLS
261 }
262 var wsstack = WsmanStackCreateService(comm);
263 dev.amtstack = AmtStackCreateService(wsstack);
264 dev.amtstack.dev = dev;
265 obj.activeLocalConnections[dev.host] = dev;
266 dev.amtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], attemptLocalConnectResponse);
304 - dev.conntype = 1; // LOCAL
305 - }
267 + break;
268 + case 3:
269 + // Handle the case where the Intel AMT local scanner found the device (connType 3)
270 + parent.debug('amt', "Attempt Initial Local Contact", dev.name, dev.connType, dev.host);
271 + if (typeof dev.host != 'string') { removeAmtDevice(dev); return; } // Local connection not valid
272 +
273 + // Since we don't allow two or more connections to the same host, check if a pending connection is active.
274 + if (obj.activeLocalConnections[dev.host] != null) {
275 + // Active connection, hold and try later.
276 + var tryAgainFunc = function tryAgainFunc() { if (obj.amtDevices[tryAgainFunc.dev.nodeid] != null) { attemptInitialContact(tryAgainFunc.dev); } }
277 + tryAgainFunc.dev = dev;
278 + setTimeout(tryAgainFunc, 5000);
279 + } else {
280 + // No active connections, see what user/pass to try.
281 + var user = null, pass = null;
282 + if (dev.acctry == null) { user = dev.intelamt.user; pass = dev.intelamt.pass; } else { user = obj.amtAdminAccounts[dev.domainid][dev.acctry].user; pass = obj.amtAdminAccounts[dev.domainid][dev.acctry].pass; }
283 +
284 + // Connect now
285 + var comm;
286 + if (dev.tlsfail !== true) {
287 + parent.debug('amt', 'Direct-Connect', "TLS", dev.name, dev.host, user, pass);
288 + comm = CreateWsmanComm(dev.host, 16993, user, pass, 1); // Always try with TLS first
289 + comm.xtlsFingerprint = 0; // Perform no certificate checking
290 + } else {
291 + parent.debug('amt', 'Direct-Connect', "NoTLS", dev.name, dev.host, user, pass);
292 + comm = CreateWsmanComm(dev.host, 16992, user, pass, 0); // Try without TLS
293 + }
294 + var wsstack = WsmanStackCreateService(comm);
295 + dev.amtstack = AmtStackCreateService(wsstack);
296 + dev.amtstack.dev = dev;
297 + obj.activeLocalConnections[dev.host] = dev;
298 + dev.amtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], attemptLocalConnectResponse);
299 + dev.conntype = 1; // LOCAL
300 + }
301 + break;
302 }
303 }
304
305 function attemptLocalConnectResponse(stack, name, responses, status) {
310 - //console.log('attemptLocalConnectResponse', status, stack.dev.name);
306 + const dev = stack.dev;
307 + parent.debug('amt', "Initial Contact Response", dev.name, status);
308
312 - // Release active connection to this host.
313 - delete obj.activeLocalConnections[stack.wsman.comm.host];
309 + // If this is a local connection device, release active connection to this host.
310 + if (dev.connType == 3) { delete obj.activeLocalConnections[dev.host]; }
311
312 // Check if the device still exists
316 - const dev = stack.dev;
317 - if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this response.
313 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
314
315 // Check the response
316 if ((status == 200) && (responses['AMT_GeneralSettings'] != null) && (responses['IPS_HostBasedSetupService'] != null) && (responses['IPS_HostBasedSetupService'].response != null) && (responses['IPS_HostBasedSetupService'].response != null) && (stack.wsman.comm.digestRealm == responses['AMT_GeneralSettings'].response.DigestRealm)) {
317 // Everything looks good
318 + dev.state = 1;
319 if (dev.aquired == null) { dev.aquired = {}; }
320 dev.aquired.controlMode = responses['IPS_HostBasedSetupService'].response.CurrentControlMode; // 1 = CCM, 2 = ACM
321 var verSplit = stack.wsman.comm.amtVersion.split('.');
@@ -327,20 +324,21 @@ module.exports.CreateAmtManager = function(parent) {
324 dev.aquired.user = stack.wsman.comm.user;
325 dev.aquired.pass = stack.wsman.comm.pass;
326 dev.aquired.lastContact = Date.now();
330 - if (dev.conntype == 1) { dev.aquired.tls = stack.wsman.comm.xtls; } // Only set the TLS state if on local mode. When using CIRA, this is auto-detected.
327 + 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.
328 if (stack.wsman.comm.xtls == 1) { dev.aquired.hash = stack.wsman.comm.xtlsCertificate.fingerprint.split(':').join('').toLowerCase(); } else { delete dev.aquired.hash; }
332 - //console.log(dev.nodeid, dev.name, dev.host, dev.aquired);
329 UpdateDevice(dev);
330
331 // Perform Intel AMT clock sync
332 attemptSyncClock(dev, function () {
333 attemptFetchHardwareInventory(dev); // See if we need to get hardware inventory
334
339 - // Start power polling
340 - var ppfunc = function powerPoleFunction() { fetchPowerState(powerPoleFunction.dev); }
341 - ppfunc.dev = dev;
342 - dev.polltimer = new setTimeout(ppfunc, 290000); // Poll for power state every 4 minutes 50 seconds.
343 - fetchPowerState(dev);
335 + if (dev.connType != 2) {
336 + // Start power polling if not connected to LMS
337 + var ppfunc = function powerPoleFunction() { fetchPowerState(powerPoleFunction.dev); }
338 + ppfunc.dev = dev;
339 + dev.polltimer = new setTimeout(ppfunc, 290000); // Poll for power state every 4 minutes 50 seconds.
340 + fetchPowerState(dev);
341 + }
342 });
343 } else {
344 // We got a bad response
@@ -349,20 +347,20 @@ module.exports.CreateAmtManager = function(parent) {
347 dev.tlsfail = true; attemptInitialContact(dev); return;
348 } else if (status == 401) {
349 // Authentication error, see if we can use alternative credentials
352 - if ((dev.acctry == null) && (obj.amtAdminAccounts.length > 0)) { dev.acctry = 0; attemptInitialContact(dev); return; }
353 - if ((dev.acctry != null) && (obj.amtAdminAccounts.length > (dev.acctry + 1))) { dev.acctry++; attemptInitialContact(dev); return; }
350 + if ((dev.acctry == null) && (obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > 0)) { dev.acctry = 0; attemptInitialContact(dev); return; }
351 + if ((dev.acctry != null) && (obj.amtAdminAccounts[dev.domainid] != null) && (obj.amtAdminAccounts[dev.domainid].length > (dev.acctry + 1))) { dev.acctry++; attemptInitialContact(dev); return; }
352
353 // We are unable to authenticate to this device, clear Intel AMT credentials.
354 ClearDeviceCredentials(dev);
355 }
356 //console.log(dev.nodeid, dev.name, dev.host, status, 'Bad response');
359 - removeDevice(dev.nodeid);
357 + removeAmtDevice(dev);
358 }
359 }
360
361 // Change the current core information string and event it
362 function UpdateDevice(dev) {
365 - if (obj.amtDevices[dev.nodeid] == null) return false; // Device no longer exists, ignore this request.
363 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
364
365 // Check that the mesh exists
366 const mesh = parent.webserver.meshes[dev.meshid];
@@ -412,7 +410,7 @@ module.exports.CreateAmtManager = function(parent) {
410
411 // Change the current core information string and event it
412 function ClearDeviceCredentials(dev) {
415 - if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this request.
413 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
414
415 // Check that the mesh exists
416 const mesh = parent.webserver.meshes[dev.meshid];
@@ -446,10 +444,71 @@ module.exports.CreateAmtManager = function(parent) {
444 });
445 }
446
447 + // Get the current power state of a device
448 + function fetchPowerState(dev) {
449 + if (isAmtDeviceValid(dev) == false) return;
450 +
451 + // Check if the agent is connected
452 + var constate = parent.GetConnectivityState(dev.nodeid);
453 + if ((constate == null) || (constate.connectivity & 1)) return; // If there is no connectivity or the agent is connected, skip trying to poll power state.
454 +
455 + // Fetch the power state
456 + dev.amtstack.BatchEnum(null, ['CIM_ServiceAvailableToElement'], function (stack, name, responses, status) {
457 + const dev = stack.dev;
458 + if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this response.
459 +
460 + if ((status != 200) || (responses['CIM_ServiceAvailableToElement'] == null) || (responses['CIM_ServiceAvailableToElement'].responses == null) || (responses['CIM_ServiceAvailableToElement'].responses.length < 1)) return; // If the polling fails, just skip it.
461 + var powerstate = responses['CIM_ServiceAvailableToElement'].responses[0].PowerState;
462 + if ((powerstate == 2) && (dev.aquired.majorver > 9)) {
463 + // Device is powered on and Intel AMT 10+, poll the OS power state.
464 + dev.amtstack.Get('IPS_PowerManagementService', function (stack, name, response, status) {
465 + const dev = stack.dev;
466 + if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this response.
467 + if (status != 200) return;
468 +
469 + // Convert the OS power state
470 + var meshPowerState = -1;
471 + if (response.Body.OSPowerSavingState == 2) { meshPowerState = 1; } // Fully powered (S0);
472 + else if (response.Body.OSPowerSavingState == 3) { meshPowerState = 2; } // Modern standby (We are going to call this S1);
473 +
474 + // Set OS power state
475 + if (meshPowerState >= 0) { parent.SetConnectivityState(dev.meshid, dev.nodeid, Date.now(), 4, meshPowerState); }
476 + });
477 + } else {
478 + // Convert the power state
479 + // AMT power: 1 = Other, 2 = On, 3 = Sleep-Light, 4 = Sleep-Deep, 5 = Power Cycle (Off-Soft), 6 = Off-Hard, 7 = Hibernate (Off-Soft), 8 = Off-Soft, 9 = Power Cycle (Off-Hard), 10 = Master Bus Reset, 11 = Diagnostic Interrupt (NMI), 12 = Off-Soft Graceful, 13 = Off-Hard Graceful, 14 = Master Bus Reset Graceful, 15 = Power Cycle (Off- oft Graceful), 16 = Power Cycle (Off - Hard Graceful), 17 = Diagnostic Interrupt (INIT)
480 + // Mesh power: 0 = Unknown, 1 = S0 power on, 2 = S1 Sleep, 3 = S2 Sleep, 4 = S3 Sleep, 5 = S4 Hibernate, 6 = S5 Soft-Off, 7 = Present
481 + var meshPowerState = -1, powerConversionTable = [-1, -1, 1, 2, 3, 6, 6, 5, 6];
482 + if (powerstate < powerConversionTable.length) { meshPowerState = powerConversionTable[powerstate]; } else { powerstate = 6; }
483 +
484 + // Set power state
485 + if (meshPowerState >= 0) { parent.SetConnectivityState(dev.meshid, dev.nodeid, Date.now(), 4, meshPowerState); }
486 + }
487 + });
488 + }
489 +
490 + // Perform a power action: 2 = Power up, 5 = Power cycle, 8 = Power down, 10 = Reset
491 + function performPowerAction(nodeid, action) {
492 + var devices = obj.amtDevices[nodeid];
493 + if (devices == null) return;
494 + for (var i in devices) {
495 + var dev = devices[i];
496 + if (dev.amtstack != null) {
497 + // TODO: Check if the device passed initial connection
498 + try { dev.amtstack.RequestPowerStateChange(action, performPowerActionResponse); } catch (ex) { }
499 + }
500 + }
501 + }
502 +
503 + // Response to Intel AMT power action
504 + function performPowerActionResponse(stack, name, responses, status) {
505 + //console.log('performPowerActionResponse', status);
506 + }
507 +
508 // Attempt to sync the Intel AMT clock if needed, call func back when done.
509 // Care should be take not to have many pending WSMAN called when performing clock sync.
510 function attemptSyncClock(dev, func) {
452 - if (obj.amtDevices[dev.nodeid] == null) return false; // Device no longer exists, ignore this request.
511 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
512 dev.clockSyncCompleted = func;
513 dev.amtstack.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch(attemptSyncClockEx);
514 }
@@ -457,7 +516,7 @@ module.exports.CreateAmtManager = function(parent) {
516 // Intel AMT clock query response
517 function attemptSyncClockEx(stack, name, response, status) {
518 const dev = stack.dev;
460 - if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this response.
519 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
520 if (status != 200) { removeDevice(dev.nodeid); }
521
522 // Compute how much drift between Intel AMT and our clock.
@@ -475,7 +534,7 @@ module.exports.CreateAmtManager = function(parent) {
534 // Intel AMT clock set response
535 function attemptSyncClockSet(stack, name, responses, status) {
536 const dev = stack.dev;
478 - if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this response.
537 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
538 if (status != 200) { removeDevice(dev.nodeid); }
539 if (dev.clockSyncCompleted != null) { var f = dev.clockSyncCompleted; delete dev.clockSyncCompleted; f(); }
540 }
@@ -494,7 +553,7 @@ module.exports.CreateAmtManager = function(parent) {
553
554 function attemptFetchNetworkResponse(stack, name, responses, status) {
555 const dev = stack.dev;
497 - if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this response.
556 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
557 if (status != 200) return;
558
559 //console.log(JSON.stringify(responses, null, 2));
@@ -565,7 +624,7 @@ module.exports.CreateAmtManager = function(parent) {
624
625 function attemptFetchHardwareInventoryResponse(stack, name, responses, status) {
626 const dev = stack.dev;
568 - if (obj.amtDevices[dev.nodeid] == null) return; // Device no longer exists, ignore this response.
627 + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request.
628 if (status != 200) return;
629
630 // Extract basic data
amtscanner.js
+3
@@ -179,6 +179,7 @@ module.exports.CreateAmtScanner = function (parent) {
179 // More than 2 minutes without a response, mark the node as unknown state
180 scaninfo.state = 0;
181 obj.parent.ClearConnectivityState(scaninfo.nodeinfo.meshid, scaninfo.nodeinfo._id, 4); // Clear connectivity state
182 + if (obj.parent.amtManager != null) { obj.parent.amtManager.stopAmtManagement(scaninfo.nodeinfo._id, 3, scaninfo.nodeinfo.host); }
183 } else if ((scaninfo.tcp == null) && ((scaninfo.state == 0) || isNaN(delta) || (delta > PeriodicScanTime))) {
184 // More than 30 seconds without a response, try TCP detection
185 obj.checkTcpPresence(host, (doc.intelamt.tls == 1) ? 16993 : 16992, scaninfo, function (tag, result, version) {
@@ -189,6 +190,7 @@ module.exports.CreateAmtScanner = function (parent) {
190 tag.state = 1;
191 obj.parent.SetConnectivityState(tag.nodeinfo.meshid, tag.nodeinfo._id, tag.lastpong, 4, 7); // Report power state as "present" (7).
192 if (version != null) { obj.changeAmtState(tag.nodeinfo._id, version, 2, tag.nodeinfo.intelamt.tls); }
193 + if (obj.parent.amtManager != null) { obj.parent.amtManager.startAmtManagement(tag.nodeinfo._id, 3, tag.nodeinfo.host); }
194 }
195 });
196 }
@@ -285,6 +287,7 @@ module.exports.CreateAmtScanner = function (parent) {
287 scaninfo.nodeinfo.intelamt.state = provisioningState;
288 obj.parent.SetConnectivityState(scaninfo.nodeinfo.meshid, scaninfo.nodeinfo._id, scaninfo.lastpong, 4, 7); // Report power state as "present" (7).
289 obj.changeAmtState(scaninfo.nodeinfo._id, scaninfo.nodeinfo.intelamt.ver, provisioningState, scaninfo.nodeinfo.intelamt.tls);
290 + if (obj.parent.amtManager != null) { obj.parent.amtManager.startAmtManagement(scaninfo.nodeinfo._id, 3, scaninfo.nodeinfo.host); }
291 }
292 }
293 };
meshcentral.js
+1 -1
@@ -1334,7 +1334,7 @@ function CreateMeshCentralServer(config, args) {
1334 }
1335
1336 // Setup the Intel AMT manager
1337 - if ((obj.args.amtmanager == true) || (typeof obj.args.amtmanager == 'object')) {
1337 + if (obj.args.amtmanager == true) {
1338 obj.amtManager = require('./amtmanager.js').CreateAmtManager(obj);
1339 }
1340
meshuser.js
+1 -6
@@ -886,12 +886,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
886 break;
887 }
888 case 'amtmanager': {
889 - if (parent.parent.amtManager == null) { r = 'Intel AMT Manager not active.'; break; }
890 - for (var nodeid in parent.parent.amtManager.amtDevices) {
891 - var dev = parent.parent.amtManager.amtDevices[nodeid];
892 - r += (dev.conn + ', \"' + dev.name + '\"\r\n');
893 - }
894 - if (r == '') { r = 'Not current managing any devices.'; }
889 + if (parent.parent.amtManager == null) { r = 'Intel AMT Manager not active.'; } else { r = parent.parent.amtManager.getStatusString(); }
890 break;
891 }
892 case 'certhashes': {
mpsserver.js
+6 -4
@@ -151,7 +151,6 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
151
152 // Add this connection to the connections list
153 if (connections == null) { obj.ciraConnections[socket.tag.nodeid] = [socket]; } else { obj.ciraConnections[socket.tag.nodeid].push(socket); }
154 - if ((socket.tag.connType != 0) && (socket.tag.connType != 1)) return; // If not a CIRA or Relay connection, we don't indicate a connection state change
154
155 // Update connectivity state
156 // Report the new state of a CIRA/Relay/LMS connection after a short delay. This is to wait for the connection to have the bounded ports setup before we advertise this new connection.
@@ -166,10 +165,10 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
165 } else if (setConnFunc.socket.tag.connType == 1) {
166 // Intel AMT Relay connection. This connection does not give any information about the remote device's power state.
167 obj.parent.SetConnectivityState(setConnFunc.socket.tag.meshid, setConnFunc.socket.tag.nodeid, setConnFunc.socket.tag.connectTime, 8, 0); // 0 = Unknown
169 - } else if (setConnFunc.socket.tag.connType == 2) {
170 - // Intel AMT LMS connection. We don't notify of these connections except telling the Intel AMT manager about them.
171 - // TODO: Notify AMT manager
168 }
169 + // Intel AMT LMS connection (connType == 2), we don't notify of these connections except telling the Intel AMT manager about them.
170 + // If the AMT manager is present, start management of this device
171 + if (obj.parent.amtManager != null) { obj.parent.amtManager.startAmtManagement(setConnFunc.socket.tag.nodeid, setConnFunc.socket.tag.connType, setConnFunc.socket); }
172 }
173 }
174 f.socket = socket;
@@ -178,6 +177,9 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
177
178 // Remove a CIRA connection from the connection list
179 function removeCiraConnection(socket) {
180 + // If the AMT manager is present, stop management of this device
181 + if (obj.parent.amtManager != null) { obj.parent.amtManager.stopAmtManagement(socket.tag.nodeid, socket.tag.connType, socket); }
182 +
183 // Remove the connection from the list if present.
184 const ciraArray = obj.ciraConnections[socket.tag.nodeid];
185 if (ciraArray == null) return;