EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
amt-manage.js
Go to the documentation of this file.
1/*
2Copyright 2018-2021 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17/**
18* @fileoverview Intel(r) AMT Management
19* @author Ylian Saint-Hilaire
20* @version v0.1.0
21*/
22
23/**
24 * Construct a AmtStackCreateService object, this ia the main Intel AMT communication stack.
25 * @constructor
26 */
27function AmtManager(agent, db, isdebug) {
28 var sendConsole = function (msg) { agent.SendCommand({ 'action': 'msg', 'type': 'console', 'value': msg }); }
29 var debug = function (msg) { if (isdebug) { sendConsole('amt-manager: ' + msg + '<br />'); } }
30 var amtMei = null, amtMeiState = 0;
31 var amtLms = null, amtLmsState = 0;
32 var amtGetVersionResult = null;
33 var obj = this;
34 var mestate;
35 var trustedHashes = null;;
36
37 require('events').EventEmitter.call(obj, true)
38 .createEvent('stateChange_LMS')
39 .createEvent('portBinding_LMS');
40 obj._lmsstate = 0;
41 obj._mapping = [];
42
43 obj.on('newListener', function (name, callback) {
44 if (name == 'portBinding_LMS') { callback.call(this, this._mapping); }
45 });
46
47 Object.defineProperty(obj, 'lmsstate',
48 {
49 get: function () { return (this._lmsstate); },
50 set: function (value) { if (this._lmsstate != value) { this._lmsstate = value; this.emit('stateChange_LMS', value); } }
51 });
52
53 obj.state = 0;
54 obj.onStateChange = null;
55 obj.setDebug = function (x) { isdebug = x; }
56
57 // Try to load up the MEI module
58 var rebindToMeiRetrys = 0;
59 obj.reset = function () {
60 ++rebindToMeiRetrys;
61 obj.amtMei = null, amtMei = null, amtMeiState = 0, amtLms = null, amtLmsState = 0, obj.state = 0, obj.lmsstate = 0;
62 //debug('Binding to MEI');
63 try {
64 var amtMeiLib = require('amt-mei');
65 obj.amtMei = amtMei = new amtMeiLib();
66 amtMei.on('error', function (e) { debug('MEI error'); amtMei = null; amtMeiState = -1; obj.state = -1; if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); } });
67 amtMei.getVersion(function (result) {
68 if (result == null) {
69 obj.state = amtMeiState = -1;
70 if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); }
71 if (rebindToMeiRetrys < 10) { setTimeout(obj.reset, 10000); }
72 } else {
73 amtGetVersionResult = result;
74 obj.state = amtMeiState = 2;
75 rebindToMeiRetrys = 0;
76 if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); }
77 //debug('MEI binded');
78 obj.lmsreset();
79 }
80 });
81 } catch (ex) { debug("MEI exception: " + ex); amtMei = null; amtMeiState = -1; obj.state = -1; }
82 }
83
84 // Get Intel MEI State in a flexible way
85 // Flags: 1 = Versions, 2 = OsAdmin, 4 = Hashes, 8 = Network
86 var getMeiStateCache = {}; // Some MEI calls will only be made once and cached here.
87 obj.getMeiState = function(flags, func) {
88 if ((amtMei == null) || (amtMeiState < 2)) { if (func != null) { func(null); } return; }
89 try {
90 var amtMeiTmpState = { 'core-ver': 1, OsHostname: require('os').hostname(), Flags: 0 }; // Flags: 1=EHBC, 2=CCM, 4=ACM
91 if (getMeiStateCache.MeiVersion != null) { amtMeiTmpState.MeiVersion = getMeiStateCache.MeiVersion; } else { amtMei.getProtocolVersion(function (result) { if (result != null) { getMeiStateCache.MeiVersion = amtMeiTmpState.MeiVersion = result; } }); }
92 if ((flags & 1) != 0) {
93 if (getMeiStateCache.Versions != null) {
94 amtMeiTmpState.Versions = getMeiStateCache.Versions;
95 } else {
96 amtMei.getVersion(function (result) { if (result) { getMeiStateCache.Versions = amtMeiTmpState.Versions = {}; for (var version in result.Versions) { amtMeiTmpState.Versions[result.Versions[version].Description] = result.Versions[version].Version; } } });
97 }
98 }
99 amtMei.getProvisioningMode(function (result) { if (result) { amtMeiTmpState.ProvisioningMode = result.mode; } });
100 amtMei.getProvisioningState(function (result) { if (result) { amtMeiTmpState.ProvisioningState = result.state; if (result.state != 2) { amtMei.stopConfiguration(function () { }); } } }); // 0: "Not Activated (Pre)", 1: "Not Activated (In)", 2: "Activated". Make sure to stop remote configuration if needed.
101 amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } });
102 amtMei.getControlMode(function (result) { if (result != null) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } } }); // Flag 2 = CCM, 4 = ACM
103 //amtMei.getMACAddresses(function (result) { if (result) { amtMeiTmpState.mac = result; } });
104 if ((flags & 8) != 0) {
105 amtMei.getLanInterfaceSettings(0, function (result) {
106 if (result) {
107 amtMeiTmpState.net0 = result;
108 var fqdn = null, interfaces = require('os').networkInterfaces(); // Look for the DNS suffix for the Intel AMT Ethernet interface
109 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; } } }
110 }
111 });
112 amtMei.getLanInterfaceSettings(1, function (result) { if (result) { amtMeiTmpState.net1 = result; } });
113 }
114 if (getMeiStateCache.UUID != null) { amtMeiTmpState.UUID = getMeiStateCache.UUID; } else { amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { getMeiStateCache.UUID = amtMeiTmpState.UUID = result.uuid; } }); }
115 if ((flags & 2) != 0) { amtMei.getLocalSystemAccount(function (x) { if ((x != null) && x.user && x.pass) { amtMeiTmpState.OsAdmin = { user: x.user, pass: x.pass }; } }); }
116 amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.DnsSuffix = result; } if ((flags & 4) == 0) { if (func != null) { func(amtMeiTmpState); } } });
117 if ((flags & 4) != 0) {
118 amtMei.getHashHandles(function (handles) {
119 if ((handles != null) && (handles.length > 0)) { amtMeiTmpState.Hashes = []; } else { func(amtMeiTmpState); }
120 var exitOnCount = handles.length;
121 for (var i = 0; i < handles.length; ++i) { this.getCertHashEntry(handles[i], function (hashresult) { amtMeiTmpState.Hashes.push(hashresult); if (--exitOnCount == 0) { if (func != null) { func(amtMeiTmpState); } } }); }
122 });
123 }
124 } catch (e) { if (func != null) { func(null); } return; }
125 }
126
127 // Called on MicroLMS Intel AMT user notification
128 var handleAmtNotification = function (notifyMsg) {
129 if ((notifyMsg == null) || (notifyMsg.Body == null) || (notifyMsg.Body.MessageID == null) || (notifyMsg.Body.MessageArguments == null)) return null;
130 var amtMessage = notifyMsg.Body.MessageID, amtMessageArg = notifyMsg.Body.MessageArguments[0], notify = null;
131
132 switch (amtMessage) {
133 case 'iAMT0050': { if (amtMessageArg == '48') { notify = "Intel&reg; AMT Serial-over-LAN connected"; } else if (amtMessageArg == '49') { notify = "Intel&reg; AMT Serial-over-LAN disconnected"; } break; } // SOL
134 case 'iAMT0052': { if (amtMessageArg == '1') { notify = "Intel&reg; AMT KVM connected"; } else if (amtMessageArg == '2') { notify = "Intel&reg; AMT KVM disconnected"; } break; } // KVM
135 default: { break; }
136 }
137
138 // Sent to the entire group, no sessionid or userid specified.
139 if (notify != null) { agent.SendCommand({ 'action': 'msg', 'type': 'notify', 'value': notify, 'tag': 'general', 'amtMessage': amtMessage }); }
140 }
141
142 // Launch LMS
143 obj.lmsreset = function () {
144 //debug('Binding to LMS');
145 obj.lmsstate = 0;
146 try {
147 var lme_heci = require('amt-lme');
148 obj.lmsstate = amtLmsState = 1;
149 amtLms = new lme_heci();
150 amtLms.on('error', function (e) { amtLmsState = 0; obj.lmsstate = 0; amtLms = null; debug("LMS error: " + e); });
151 amtLms.on('connect', function () { amtLmsState = 2; obj.lmsstate = 2; debug("LMS connected"); });
152 amtLms.on('bind', function (map) { obj._mapping = map; obj.emit('portBinding_LMS', map); });
153 amtLms.on('notify', function (data, options, code) { handleAmtNotification(data); });
154 } catch (ex) {
155 require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: "ex: " + ex });
156 amtLmsState = -1; obj.lmsstate = -1; amtLms = null;
157 }
158 }
159
160 // Start host based ACM activation with TLS
161 obj.startConfigurationHBased = function startConfigurationHBased(certHash, hostVpn, dnsSuffixList, func) {
162 if ((amtMei == null) || (amtMeiState < 2)) { if (func != null) { func({ status: -100 }); } return; }
163 amtMei.startConfigurationHBased(certHash, hostVpn, dnsSuffixList, func);
164 }
165
166}
167
168module.exports = AmtManager;