mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			162 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
Copyright 2018-2020 Intel Corporation
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
/**
 | 
						|
* @fileoverview Intel(r) AMT Management
 | 
						|
* @author Ylian Saint-Hilaire
 | 
						|
* @version v0.1.0
 | 
						|
*/
 | 
						|
 | 
						|
/**
 | 
						|
 * Construct a AmtStackCreateService object, this ia the main Intel AMT communication stack.
 | 
						|
 * @constructor
 | 
						|
 */
 | 
						|
function AmtManager(agent, db, isdebug) {
 | 
						|
    var sendConsole = function (msg) { agent.SendCommand({ 'action': 'msg', 'type': 'console', 'value': msg }); }
 | 
						|
    var debug = function (msg) { if (isdebug) { sendConsole('amt-manager: ' + msg + '<br />'); } }
 | 
						|
    var amtMei = null, amtMeiState = 0;
 | 
						|
    var amtLms = null, amtLmsState = 0;
 | 
						|
    var amtGetVersionResult = null;
 | 
						|
    var obj = this;
 | 
						|
    var mestate;
 | 
						|
    var trustedHashes = null;;
 | 
						|
 | 
						|
    require('events').EventEmitter.call(obj, true)
 | 
						|
        .createEvent('stateChange_LMS')
 | 
						|
        .createEvent('portBinding_LMS');
 | 
						|
    obj._lmsstate = 0;
 | 
						|
    obj._mapping = [];
 | 
						|
 | 
						|
    obj.on('newListener', function (name, callback) {
 | 
						|
        if (name == 'portBinding_LMS') { callback.call(this, this._mapping); }
 | 
						|
    });
 | 
						|
 | 
						|
    Object.defineProperty(obj, 'lmsstate',
 | 
						|
        {
 | 
						|
            get: function () { return (this._lmsstate); },
 | 
						|
            set: function (value) { if (this._lmsstate != value) { this._lmsstate = value; this.emit('stateChange_LMS', value); } }
 | 
						|
        });
 | 
						|
 | 
						|
    obj.state = 0;
 | 
						|
    obj.onStateChange = null;
 | 
						|
    obj.setDebug = function (x) { isdebug = x; }
 | 
						|
 | 
						|
    // Try to load up the MEI module
 | 
						|
    var rebindToMeiRetrys = 0;
 | 
						|
    obj.reset = function () {
 | 
						|
        ++rebindToMeiRetrys;
 | 
						|
        amtMei = null, amtMeiState = 0, amtLms = null, amtLmsState = 0, obj.state = 0, obj.lmsstate = 0;
 | 
						|
        //debug('Binding to MEI');
 | 
						|
        try {
 | 
						|
            var amtMeiLib = require('amt-mei');
 | 
						|
            amtMei = new amtMeiLib();
 | 
						|
            amtMei.on('error', function (e) { debug('MEI error'); amtMei = null; amtMeiState = -1; obj.state = -1; if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); } });
 | 
						|
            amtMei.getVersion(function (result) {
 | 
						|
                if (result == null) {
 | 
						|
                    obj.state = amtMeiState = -1;
 | 
						|
                    if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); }
 | 
						|
                    if (rebindToMeiRetrys < 10) { setTimeout(obj.reset, 10000); }
 | 
						|
                } else {
 | 
						|
                    amtGetVersionResult = result;
 | 
						|
                    obj.state = amtMeiState = 2;
 | 
						|
                    rebindToMeiRetrys = 0;
 | 
						|
                    if (obj.onStateChange != null) { obj.onStateChange(amtMeiState); }
 | 
						|
                    //debug('MEI binded');
 | 
						|
                    obj.lmsreset();
 | 
						|
                }
 | 
						|
            });
 | 
						|
        } catch (ex) { debug("MEI exception: " + ex); amtMei = null; amtMeiState = -1; obj.state = -1; }
 | 
						|
    }
 | 
						|
 | 
						|
    // Get Intel MEI State in a flexible way
 | 
						|
    // Flags: 1 = Versions, 2 = OsAdmin, 4 = Hashes, 8 = Network
 | 
						|
    var getMeiStateCache = {}; // Some MEI calls will only be made once and cached here.
 | 
						|
    obj.getMeiState = function(flags, func) {
 | 
						|
        if ((amtMei == null) || (amtMeiState < 2)) { if (func != null) { func(null); } return; }
 | 
						|
        try {
 | 
						|
            var amtMeiTmpState = { OsHostname: require('os').hostname(), Flags: 0 }; // Flags: 1=EHBC, 2=CCM, 4=ACM
 | 
						|
            if (getMeiStateCache.MeiVersion != null) { amtMeiTmpState.MeiVersion = getMeiStateCache.MeiVersion; } else { amtMei.getProtocolVersion(function (result) { if (result != null) { getMeiStateCache.MeiVersion = amtMeiTmpState.MeiVersion = result; } }); }
 | 
						|
            if ((flags & 1) != 0) {
 | 
						|
                if (getMeiStateCache.Versions != null) {
 | 
						|
                    amtMeiTmpState.Versions = getMeiStateCache.Versions;
 | 
						|
                } else {
 | 
						|
                    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; } } });
 | 
						|
                }
 | 
						|
            }
 | 
						|
            amtMei.getProvisioningMode(function (result) { if (result) { amtMeiTmpState.ProvisioningMode = result.mode; } });
 | 
						|
            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.
 | 
						|
            amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } });
 | 
						|
            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
 | 
						|
            //amtMei.getMACAddresses(function (result) { if (result) { amtMeiTmpState.mac = result; } });
 | 
						|
            if ((flags & 8) != 0) {
 | 
						|
                amtMei.getLanInterfaceSettings(0, function (result) {
 | 
						|
                    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 == 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; } });
 | 
						|
            }
 | 
						|
            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; } }); }
 | 
						|
            if ((flags & 2) != 0) { amtMei.getLocalSystemAccount(function (x) { if ((x != null) && x.user && x.pass) { amtMeiTmpState.OsAdmin = { user: x.user, pass: x.pass }; } }); }
 | 
						|
            amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.DnsSuffix = result; } if ((flags & 4) == 0) { if (func != null) { func(amtMeiTmpState); } } });
 | 
						|
            if ((flags & 4) != 0) {
 | 
						|
                amtMei.getHashHandles(function (handles) {
 | 
						|
                    if ((handles != null) && (handles.length > 0)) { amtMeiTmpState.Hashes = []; } else { func(amtMeiTmpState); }
 | 
						|
                    var exitOnCount = handles.length;
 | 
						|
                    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); } } }); }
 | 
						|
                });
 | 
						|
            }
 | 
						|
        } catch (e) { if (func != null) { func(null); } return; }
 | 
						|
    }
 | 
						|
 | 
						|
    // Called on MicroLMS Intel AMT user notification
 | 
						|
    var handleAmtNotification = function (notifyMsg) {
 | 
						|
        if ((notifyMsg == null) || (notifyMsg.Body == null) || (notifyMsg.Body.MessageID == null) || (notifyMsg.Body.MessageArguments == null)) return null;
 | 
						|
        var amtMessage = notifyMsg.Body.MessageID, amtMessageArg = notifyMsg.Body.MessageArguments[0], notify = null;
 | 
						|
 | 
						|
        switch (amtMessage) {
 | 
						|
            case 'iAMT0050': { if (amtMessageArg == '48') { notify = "Intel® AMT Serial-over-LAN connected"; } else if (amtMessageArg == '49') { notify = "Intel® AMT Serial-over-LAN disconnected"; } break; } // SOL
 | 
						|
            case 'iAMT0052': { if (amtMessageArg == '1') { notify = "Intel® AMT KVM connected"; } else if (amtMessageArg == '2') { notify = "Intel® AMT KVM disconnected"; } break; } // KVM
 | 
						|
            default: { break; }
 | 
						|
        }
 | 
						|
 | 
						|
        // Sent to the entire group, no sessionid or userid specified.
 | 
						|
        if (notify != null) { agent.SendCommand({ 'action': 'msg', 'type': 'notify', 'value': notify, 'tag': 'general', 'amtMessage': amtMessage }); }
 | 
						|
    }
 | 
						|
 | 
						|
    // Launch LMS
 | 
						|
    obj.lmsreset = function () {
 | 
						|
        //debug('Binding to LMS');
 | 
						|
        obj.lmsstate = 0;
 | 
						|
        try {
 | 
						|
            var lme_heci = require('amt-lme');
 | 
						|
            obj.lmsstate = amtLmsState = 1;
 | 
						|
            amtLms = new lme_heci();
 | 
						|
            amtLms.on('error', function (e) { amtLmsState = 0; obj.lmsstate = 0; amtLms = null; debug("LMS error: " + e); });
 | 
						|
            amtLms.on('connect', function () { amtLmsState = 2; obj.lmsstate = 2; debug("LMS connected"); });
 | 
						|
            amtLms.on('bind', function (map) { obj._mapping = map; obj.emit('portBinding_LMS', map); });
 | 
						|
            amtLms.on('notify', function (data, options, code) { handleAmtNotification(data); });
 | 
						|
        } catch (ex) {
 | 
						|
            require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: "ex: " + ex });
 | 
						|
            amtLmsState = -1; obj.lmsstate = -1; amtLms = null;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
module.exports = AmtManager;
 |